5 #include <readline/readline.h>
6 #include <readline/history.h>
13 #define fatal(fmt...) fatal_func (__FILE__, __LINE__, __PRETTY_FUNCTION__, fmt)
14 #define gdb_assert assert
15 #define gdb_assert_not_reached(msg) fatal ("%s", (msg))
18 static ATTRIBUTE_NORETURN void
19 fatal_func (const char *file, int line, const char *func, const char *fmt, ...)
23 fprintf (stderr, "%s:%d:%s:", file, line, func);
25 vfprintf (stderr, fmt, ap);
33 xstrdup (const char *s)
37 gdb_assert (s != NULL);
39 gdb_assert (retval != NULL);
48 gdb_assert (size != 0);
50 gdb_assert (p != NULL);
55 xrealloc (void *p, size_t size)
58 return xmalloc (size);
59 gdb_assert (size != 0);
60 p = realloc (p, size);
61 gdb_assert (p != NULL);
72 xstrprintf (const char *fmt, ...)
79 i = vasprintf (&retval, fmt, ap);
82 gdb_assert (i == strlen (retval));
86 static jmp_buf gdb_readline_jmp_buf;
89 gdb_readline_sigint_handler (int signum)
91 gdb_assert (signum == SIGINT);
92 longjmp (gdb_readline_jmp_buf, 1);
96 gdb_readline (const char *prompt)
99 sighandler_t saved_handler;
103 i = sigprocmask (SIG_SETMASK, NULL, &mask);
105 saved_handler = signal (SIGINT, gdb_readline_sigint_handler);
106 if (setjmp (gdb_readline_jmp_buf) != 0)
108 rl_free_line_state ();
109 rl_cleanup_after_signal ();
111 /* GDB prints this. */
114 i = sigprocmask (SIG_SETMASK, &mask, NULL);
117 retval = readline (prompt);
118 saved_handler = signal (SIGINT, saved_handler);
119 gdb_assert (saved_handler == gdb_readline_sigint_handler);
123 static int console_cb_rows, console_cb_columns, console_cb_row, console_cb_column;
124 static bool console_cb_drop;
127 console_cb (const char *str, void *data)
133 if (console_cb_rows == 0)
145 cs = strchr (str, '\n');
147 cs = &str[strlen (str)];
148 columns = min (cs - str, console_cb_columns - console_cb_column);
151 size = fwrite (str, 1, columns, stdout);
152 gdb_assert (size == columns);
154 console_cb_column += columns;
159 else if (console_cb_column < console_cb_columns)
160 gdb_assert_not_reached ("we should not get here");
163 console_cb_column = 0;
164 if (console_cb_row < console_cb_rows - 1)
166 answer = gdb_readline (_("---Type <return> to continue, "
167 "or q <return> to quit---"));
168 for (cs = answer; isspace (*cs); cs++);
173 console_cb_drop = true;
182 time_out_cb (void *data)
184 fatal ("GDB response has timed out");
189 static ATTRIBUTE_UNUSED void
190 to_gdb_cb (const char *str, void *data)
192 printf ("to_gdb: %s\n", str);
195 static ATTRIBUTE_UNUSED void
196 from_gdb_cb (const char *str, void *data)
198 printf ("from_gdb: %s\n", str);
202 h_disconnect (int rc, void *arg)
210 history_save (int rc, void *arg)
212 const char *history_filename = arg;
214 write_history (history_filename);
218 default_command (mi_h *h, const char *cmd)
222 gdb_assert (strchr (cmd, '\n') == 0);
223 mi_send (h, "-interpreter-exec console \"%s\"\n", cmd);
227 mi_output *rec, *res;
229 res = mi_get_response_blk (h);
230 gdb_assert (res != NULL);
232 for (rec = res; rec != NULL; rec = rec->next)
239 /* We do not get MI_CL_DONE here, wait for MI_CL_STOPPED. */
246 gdb_assert (rec->c->type == t_const);
247 puts (rec->c->v.cstr);
250 fatal ("mi_get_rrecord == MI_CL_??? (%d)", rec->tclass);
253 mi_free_output (res);
258 quit_command (mi_h *h, const char *cmd)
264 mi_escape (const char *cs)
266 char *d, *retval = xmalloc (strlen (cs) * 2 + 1);
271 if (*cs == '"' || *cs == '\\')
280 gdb_done (mi_h *h, const char *command)
284 mi_send (h, "%s\n", command);
285 res = mi_get_response_blk (h);
286 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
288 mi_free_output (res);
292 commands_command_console_cb (const char *str, void *data)
294 char **strptr = data;
296 gdb_assert (*strptr == NULL);
297 *strptr = xstrdup (str);
301 commands_command (mi_h *h, const char *cmd_param)
303 char *cmd = xstrdup ("");
309 if (*cmd_param == '\0')
311 mi_set_console_cb (h, commands_command_console_cb, &bpnum);
312 gdb_done (h, "output $bpnum");
313 mi_set_console_cb (h, console_cb, NULL);
314 gdb_assert (bpnum != NULL);
318 printf (_("Type commands for breakpoint(s) %s, one per line.\n"
319 "End with a line saying just \"end\".\n"), cmd_param);
324 char *prompt, *data, *data2, *start, *end;
328 prompt = xstrprintf ("%*s>", (int) nesting);
329 data = gdb_readline (prompt);
332 data = xstrdup ("end");
334 for (start = data; isspace (*start); start++);
335 for (end = data + strlen (data); end > start && isspace (end[-1]); end--);
336 data2 = xmalloc (end - start + 1);
337 memcpy (data2, start, end - start);
338 data2[end - start] = '\0';
339 if (strcmp (data2, "python") == 0)
341 if (strcmp (data2, "end") == 0)
343 for (end = data2; *end && !isspace (*end); end++);
346 /* Here is a bug in GDB, it does not recognize command shortcuts. */
347 if (strcmp (data2, "while") == 0 || strcmp (data2, "if") == 0
348 || strcmp (data2, "commands") == 0
349 || strcmp (data2, "while-stepping") == 0
350 || strcmp (data2, "stepping") == 0 || strcmp (data2, "ws") == 0)
358 data2 = mi_escape (data);
360 data2_len = strlen (data2);
361 cmd = xrealloc (cmd, cmd_len + 2 + data2_len + 2);
363 cmd[cmd_len + 1] = '"';
364 memcpy (&cmd[cmd_len + 2], data2, data2_len);
365 cmd[cmd_len + 2 + data2_len] = '"';
366 cmd[cmd_len + 2 + data2_len + 1] = '\0';
367 cmd_len += 2 + data2_len + 1;
371 mi_send (h, "-break-commands %s%s\n", cmd_param, cmd);
375 res = mi_get_response_blk (h);
376 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
378 mi_free_output (res);
381 static const struct cmd
385 void (*func) (mi_h *h, const char *cmd);
388 { "quit", 1, quit_command },
389 { "commands", 4, commands_command },
393 executecommand (mi_h *h, const char *cmd)
395 const char *start, *end, *cs;
396 const struct cmd *cmdp;
399 while (isspace (*cs))
402 while (isalnum (*cs))
405 while (isspace (*cs))
408 for (cmdp = cmds; cmdp < &cmds[LENGTH (cmds)]; cmdp++)
409 if (cmdp->min_shortcut <= end - start && end - start <= strlen (cmdp->name)
410 && strncmp (start, cmdp->name, end - start) == 0)
411 return cmdp->func (h, cs);
413 return default_command (h, cmd);
417 gdb_set_string (mi_h *h, const char *setting, const char *value)
419 char *cmd = xstrprintf ("-gdb-set %s %s", setting, value);
426 gdb_set_bool (mi_h *h, const char *setting, bool value)
428 gdb_set_string (h, setting, value ? "on" : "off");
432 gdb_show_string (mi_h *h, const char *setting)
437 mi_send (h, "-gdb-show %s\n", setting);
438 res = mi_get_response_blk (h);
439 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
440 && res->c != NULL && res->c->next == NULL
441 && res->c->type == t_const && strcmp (res->c->var, "value") == 0);
442 retval = xstrdup (res->c->v.cstr);
443 mi_free_output (res);
448 gdb_show_int (mi_h *h, const char *setting)
450 char *string = gdb_show_string (h, setting);
456 retval = l = strtol (string, &end, 10);
457 gdb_assert (errno == 0 && (end == NULL || *end == '\0') && retval == l);
463 gdb_show_bool (mi_h *h, const char *setting)
465 char *string = gdb_show_string (h, setting);
468 retval = strcmp (string, "on") == 0;
469 gdb_assert (retval || strcmp (string, "off") == 0);
474 static mi_h *completion_entry_function_h;
476 static char **completion_entry_function_data;
477 static size_t completion_entry_function_data_used;
478 static size_t completion_entry_function_data_allocated;
481 completion_entry_function_console_cb (const char *str, void *data)
483 int line_start = (intptr_t) data;
487 if (completion_entry_function_data_used
488 == completion_entry_function_data_allocated)
490 if (completion_entry_function_data_allocated > 0)
491 completion_entry_function_data_allocated *= 2;
493 completion_entry_function_data_allocated = 0x100;
494 completion_entry_function_data = xrealloc (completion_entry_function_data,
495 (sizeof (*completion_entry_function_data)
496 * completion_entry_function_data_allocated));
499 cs = strchr (str, '\n');
500 if (cs == NULL || cs[1] != '\0')
501 fatal ("Invalid GDB data: %s", str);
503 if (strncmp (rl_line_buffer, str, rl_point) != 0)
504 fatal ("Completion GDB data do not match, have \"%.*s\", got \"%.*s\".",
505 (int) rl_point, rl_line_buffer, (int) (cs - str), str);
507 s = xmalloc (cs - str - line_start + 1);
508 memcpy (s, &str[line_start], cs - str - line_start);
509 s[cs - str - line_start] = '\0';
510 completion_entry_function_data[completion_entry_function_data_used++] = s;
514 completion_entry_function (const char *text, int matches)
516 mi_h *h = completion_entry_function_h;
518 gdb_assert (matches >= 0);
524 while (completion_entry_function_data_used)
525 xfree (completion_entry_function_data
526 [--completion_entry_function_data_used]);
527 xfree (completion_entry_function_data);
528 completion_entry_function_data = NULL;
529 completion_entry_function_data_used = 0;
530 completion_entry_function_data_allocated = 0;
532 gdb_assert (rl_point >= 0);
533 gdb_assert (strlen (rl_line_buffer) >= rl_point);
534 gdb_assert (strlen (text) <= rl_point);
535 line_start = rl_point - strlen (text);
536 gdb_assert (strncmp (text, &rl_line_buffer[line_start],
537 strlen (text)) == 0);
538 mi_send (h, "-interpreter-exec console \"complete %.*s\"\n",
539 (int) rl_point, rl_line_buffer);
541 mi_set_console_cb (h, completion_entry_function_console_cb,
542 (void *) (intptr_t) line_start);
543 res = mi_get_response_blk (h);
544 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
546 mi_free_output (res);
547 mi_set_console_cb (h, console_cb, NULL);
550 if (matches < completion_entry_function_data_used)
551 return xstrdup (completion_entry_function_data[matches]);
552 else if (matches == completion_entry_function_data_used)
555 gdb_assert_not_reached ("too many matches");
558 extern char **mi_gdb_argv;
559 extern void (*mi_gdb_start_hook) (mi_h *h);
564 on_exit (h_disconnect, h);
565 mi_set_console_cb (h, console_cb, NULL);
566 mi_set_time_out_cb (h, time_out_cb, NULL);
568 // mi_set_to_gdb_cb (h, to_gdb_cb, NULL);
569 // mi_set_from_gdb_cb (h, from_gdb_cb, NULL);
573 main (int argc, char **argv)
578 setbuf (stdout, NULL);
580 mi_gdb_argv = xmalloc ((argc + 2) * sizeof (*mi_gdb_argv));
581 memcpy (&mi_gdb_argv[2], &argv[1], argc * sizeof (*mi_gdb_argv));
582 mi_gdb_argv[0] = "gdb";
583 mi_gdb_argv[1] = "--interpreter=mi";
585 mi_gdb_start_hook = start_hook;
587 h = mi_connect_local ();
589 fatal ("Cannot connect to GDB");
591 /* First eat the prompt. Then run empty command so that additional results
592 from -ex or -x during mi_connect_local are flushed. */
593 res = mi_get_response_blk (h);
594 gdb_assert (res == NULL);
595 default_command (h, "echo");
597 completion_entry_function_h = h;
598 rl_completion_entry_function = completion_entry_function;
599 rl_readline_name = "gdb";
601 if (gdb_show_bool (h, "history save"))
603 int history_size = gdb_show_int (h, "history size");
604 char *history_filename = gdb_show_string (h, "history filename");
606 gdb_set_bool (h, "history save", false);
607 stifle_history (history_size);
608 read_history (history_filename);
609 on_exit (history_save, history_filename);
610 /* Do not free HISTORY_FILENAME. */
617 prompt = gdb_show_string (h, "prompt");
618 cmd = gdb_readline (prompt);
621 /* FIXME: -ex commands do not have pagination set. */
622 if (!gdb_show_bool (h, "pagination"))
625 rl_get_screen_size (&console_cb_rows, &console_cb_columns);
626 console_cb_drop = false;
627 console_cb_row = console_cb_column = 0;
630 cmd = xstrdup ("quit");
634 executecommand (h, cmd);