5 #include <readline/readline.h>
6 #include <readline/history.h>
12 #define fatal(fmt...) fatal_func (__FILE__, __LINE__, __PRETTY_FUNCTION__, fmt)
13 #define gdb_assert assert
14 #define gdb_assert_not_reached(msg) fatal ("%s", (msg))
17 static ATTRIBUTE_NORETURN void
18 fatal_func (const char *file, int line, const char *func, const char *fmt, ...)
22 fprintf (stderr, "%s:%d:%s:", file, line, func);
24 vfprintf (stderr, fmt, ap);
32 xstrdup (const char *s)
36 gdb_assert (s != NULL);
38 gdb_assert (retval != NULL);
47 gdb_assert (size != 0);
49 gdb_assert (p != NULL);
54 xrealloc (void *p, size_t size)
57 return xmalloc (size);
58 gdb_assert (size != 0);
59 p = realloc (p, size);
60 gdb_assert (p != NULL);
71 xstrprintf (const char *fmt, ...)
78 i = vasprintf (&retval, fmt, ap);
81 gdb_assert (i == strlen (retval));
86 console_cb (const char *str, void *data)
91 static ATTRIBUTE_UNUSED void
92 to_gdb_cb (const char *str, void *data)
94 printf ("to_gdb: %s\n", str);
97 static ATTRIBUTE_UNUSED void
98 from_gdb_cb (const char *str, void *data)
100 printf ("from_gdb: %s\n", str);
104 h_disconnect (int rc, void *arg)
112 history_save (int rc, void *arg)
114 const char *history_filename = arg;
116 write_history (history_filename);
120 quit_command (mi_h *h, const char *cmd)
126 default_command (mi_h *h, const char *cmd)
130 mi_send (h, "-interpreter-exec console \"%s\"\n", cmd);
134 mi_output *rec, *res;
136 res = mi_get_response_blk (h);
137 gdb_assert (res != NULL);
139 for (rec = res; rec != NULL; rec = rec->next)
146 /* We do not get MI_CL_DONE here, wait for MI_CL_STOPPED. */
153 gdb_assert (rec->c->type == t_const);
154 puts (rec->c->v.cstr);
157 fatal ("mi_get_rrecord == MI_CL_??? (%d)", rec->tclass);
160 mi_free_output (res);
164 static const struct cmd
167 void (*func) (mi_h *h, const char *cmd);
170 { "q", quit_command },
171 { "qu", quit_command },
172 { "qui", quit_command },
173 { "quit", quit_command },
177 executecommand (mi_h *h, const char *cmd)
179 const char *start, *end, *cs;
180 const struct cmd *cmdp;
183 while (isspace (*cs))
186 while (isalnum (*cs))
190 for (cmdp = cmds; cmdp < &cmds[LENGTH (cmds)]; cmdp++)
191 if (strlen (cmdp->name) == end - start
192 && strncmp (cmd, cmdp->name, end - start) == 0)
193 return cmdp->func (h, cmd);
195 return default_command (h, cmd);
199 gdb_done (mi_h *h, const char *command)
203 mi_send (h, "%s\n", command);
204 res = mi_get_response_blk (h);
205 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
207 mi_free_output (res);
211 gdb_set_string (mi_h *h, const char *setting, const char *value)
213 char *cmd = xstrprintf ("-gdb-set %s %s", setting, value);
220 gdb_set_bool (mi_h *h, const char *setting, bool value)
222 gdb_set_string (h, setting, value ? "on" : "off");
226 gdb_show_string (mi_h *h, const char *setting)
231 mi_send (h, "-gdb-show %s\n", setting);
232 res = mi_get_response_blk (h);
233 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
234 && res->c != NULL && res->c->next == NULL
235 && res->c->type == t_const && strcmp (res->c->var, "value") == 0);
236 retval = xstrdup (res->c->v.cstr);
237 mi_free_output (res);
242 gdb_show_int (mi_h *h, const char *setting)
244 char *string = gdb_show_string (h, setting);
250 retval = l = strtol (string, &end, 10);
251 gdb_assert (errno == 0 && (end == NULL || *end == '\0') && retval == l);
257 gdb_show_bool (mi_h *h, const char *setting)
259 char *string = gdb_show_string (h, setting);
262 retval = strcmp (string, "on") == 0;
263 gdb_assert (retval || strcmp (string, "off") == 0);
268 static mi_h *completion_entry_function_h;
270 static char **completion_entry_function_data;
271 static size_t completion_entry_function_data_used;
272 static size_t completion_entry_function_data_allocated;
275 completion_entry_function_console_cb (const char *str, void *data)
277 int line_start = (intptr_t) data;
281 if (completion_entry_function_data_used
282 == completion_entry_function_data_allocated)
284 if (completion_entry_function_data_allocated > 0)
285 completion_entry_function_data_allocated *= 2;
287 completion_entry_function_data_allocated = 0x100;
288 completion_entry_function_data = xrealloc (completion_entry_function_data,
289 (sizeof (*completion_entry_function_data)
290 * completion_entry_function_data_allocated));
293 cs = strchr (str, '\n');
294 if (cs == NULL || cs[1] != '\0')
295 fatal ("Invalid GDB data: %s", str);
297 if (strncmp (rl_line_buffer, str, rl_point) != 0)
298 fatal ("Completion GDB data do not match, have \"%.*s\", got \"%.*s\".",
299 (int) rl_point, rl_line_buffer, (int) (cs - str), str);
301 s = xmalloc (cs - str - line_start + 1);
302 memcpy (s, &str[line_start], cs - str - line_start);
303 s[cs - str - line_start] = '\0';
304 completion_entry_function_data[completion_entry_function_data_used++] = s;
308 completion_entry_function (const char *text, int matches)
310 mi_h *h = completion_entry_function_h;
312 gdb_assert (matches >= 0);
318 while (completion_entry_function_data_used)
319 xfree (completion_entry_function_data
320 [--completion_entry_function_data_used]);
321 xfree (completion_entry_function_data);
322 completion_entry_function_data = NULL;
323 completion_entry_function_data_used = 0;
324 completion_entry_function_data_allocated = 0;
326 gdb_assert (rl_point >= 0);
327 gdb_assert (strlen (rl_line_buffer) >= rl_point);
328 gdb_assert (strlen (text) <= rl_point);
329 line_start = rl_point - strlen (text);
330 gdb_assert (strncmp (text, &rl_line_buffer[line_start],
331 strlen (text)) == 0);
332 mi_send (h, "-interpreter-exec console \"complete %.*s\"\n",
333 (int) rl_point, rl_line_buffer);
335 mi_set_console_cb (h, completion_entry_function_console_cb,
336 (void *) (intptr_t) line_start);
337 res = mi_get_response_blk (h);
338 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
340 mi_free_output (res);
341 mi_set_console_cb (h, console_cb, NULL);
344 if (matches < completion_entry_function_data_used)
345 return xstrdup (completion_entry_function_data[matches]);
346 else if (matches == completion_entry_function_data_used)
349 gdb_assert_not_reached ("too many matches");
353 main (int argc, char **argv)
357 const char *ex[argc], *arg_file = NULL, *arg_core = NULL, *arg_pid = NULL;
358 unsigned ex_count = 0, ex_used = 0;
360 setbuf (stdout, NULL);
362 while (*++argv != NULL)
364 if (strcmp (*argv, "-ex") == 0 && argv[1] != NULL)
365 ex[ex_count++] = *++argv;
366 else if (strcmp (*argv, "-c") == 0 && argv[1] != NULL)
368 else if (strncmp (*argv, "--core=", strlen ("--core=")) == 0)
369 arg_core = xstrdup (&(*argv)[strlen ("--core=")]);
370 else if (strcmp (*argv, "-p") == 0 && argv[1] != NULL)
372 else if (strncmp (*argv, "--pid=", strlen ("--pid=")) == 0)
373 arg_pid = xstrdup (&(*argv)[strlen ("--pid=")]);
374 else if (arg_file == NULL)
376 else if (arg_core == NULL && arg_pid == NULL)
380 strtol (*argv, &end, 0);
381 if (isdigit ((*argv)[0]) && (end == NULL || *end == '\0'))
387 fatal (_("Excess command line argument: %s"), *argv);
389 if (arg_core != NULL && arg_pid != NULL)
390 fatal (_("Can't attach to process and specify a core file "
391 "at the same time."));
393 mi_set_workaround (MI_PSYM_SEARCH, 0);
395 h = mi_connect_local ();
397 fatal ("Cannot connect to GDB");
399 on_exit (h_disconnect, h);
401 mi_set_console_cb (h, console_cb, NULL);
402 // mi_set_to_gdb_cb (h, to_gdb_cb, NULL);
403 // mi_set_from_gdb_cb (h, from_gdb_cb, NULL);
405 completion_entry_function_h = h;
406 rl_completion_entry_function = completion_entry_function;
407 rl_readline_name = "gdb";
409 if (gdb_show_bool (h, "history save"))
411 int history_size = gdb_show_int (h, "history size");
412 char *history_filename = gdb_show_string (h, "history filename");
414 gdb_set_bool (h, "history save", false);
415 stifle_history (history_size);
416 read_history (history_filename);
417 on_exit (history_save, history_filename);
418 /* Do not free HISTORY_FILENAME. */
423 if (ex_used < ex_count)
424 cmd = xstrdup (ex[ex_used++]);
425 else if (arg_file != NULL)
427 cmd = xstrprintf ("file %s", arg_file);
430 else if (arg_core != NULL)
432 cmd = xstrprintf ("core-file %s", arg_core);
435 else if (arg_pid != NULL)
437 cmd = xstrprintf ("attach %s", arg_pid);
442 cmd = readline ("(gdb) ");
444 cmd = xstrdup ("quit");
448 executecommand (h, cmd);