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)
92 time_out_cb (void *data)
94 fatal ("GDB response has timed out");
99 static ATTRIBUTE_UNUSED void
100 to_gdb_cb (const char *str, void *data)
102 printf ("to_gdb: %s\n", str);
105 static ATTRIBUTE_UNUSED void
106 from_gdb_cb (const char *str, void *data)
108 printf ("from_gdb: %s\n", str);
112 h_disconnect (int rc, void *arg)
120 history_save (int rc, void *arg)
122 const char *history_filename = arg;
124 write_history (history_filename);
128 default_command (mi_h *h, const char *cmd)
132 gdb_assert (strchr (cmd, '\n') == 0);
133 mi_send (h, "-interpreter-exec console \"%s\"\n", cmd);
137 mi_output *rec, *res;
139 res = mi_get_response_blk (h);
140 gdb_assert (res != NULL);
142 for (rec = res; rec != NULL; rec = rec->next)
149 /* We do not get MI_CL_DONE here, wait for MI_CL_STOPPED. */
156 gdb_assert (rec->c->type == t_const);
157 puts (rec->c->v.cstr);
160 fatal ("mi_get_rrecord == MI_CL_??? (%d)", rec->tclass);
163 mi_free_output (res);
168 quit_command (mi_h *h, const char *cmd)
174 mi_escape (const char *cs)
176 char *d, *retval = xmalloc (strlen (cs) * 2 + 1);
181 if (*cs == '"' || *cs == '\\')
190 gdb_done (mi_h *h, const char *command)
194 mi_send (h, "%s\n", command);
195 res = mi_get_response_blk (h);
196 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
198 mi_free_output (res);
202 commands_command_console_cb (const char *str, void *data)
204 char **strptr = data;
206 gdb_assert (*strptr == NULL);
207 *strptr = xstrdup (str);
211 commands_command (mi_h *h, const char *cmd_param)
213 char *cmd = xstrdup ("");
219 if (*cmd_param == '\0')
221 mi_set_console_cb (h, commands_command_console_cb, &bpnum);
222 gdb_done (h, "output $bpnum");
223 mi_set_console_cb (h, console_cb, NULL);
224 gdb_assert (bpnum != NULL);
228 printf (_("Type commands for breakpoint(s) %s, one per line.\n"
229 "End with a line saying just \"end\".\n"), cmd_param);
234 char *prompt, *data, *data2, *start, *end;
238 prompt = xstrprintf ("%*s>", (int) nesting);
239 data = readline (prompt);
242 data = xstrdup ("end");
244 for (start = data; isspace (*start); start++);
245 for (end = data + strlen (data); end > start && isspace (end[-1]); end--);
246 data2 = xmalloc (end - start + 1);
247 memcpy (data2, start, end - start);
248 data2[end - start] = '\0';
249 if (strcmp (data2, "python") == 0)
251 if (strcmp (data2, "end") == 0)
253 for (end = data2; *end && !isspace (*end); end++);
256 /* Here is a bug in GDB, it does not recognize command shortcuts. */
257 if (strcmp (data2, "while") == 0 || strcmp (data2, "if") == 0
258 || strcmp (data2, "commands") == 0
259 || strcmp (data2, "while-stepping") == 0
260 || strcmp (data2, "stepping") == 0 || strcmp (data2, "ws") == 0)
268 data2 = mi_escape (data);
270 data2_len = strlen (data2);
271 cmd = xrealloc (cmd, cmd_len + 2 + data2_len + 2);
273 cmd[cmd_len + 1] = '"';
274 memcpy (&cmd[cmd_len + 2], data2, data2_len);
275 cmd[cmd_len + 2 + data2_len] = '"';
276 cmd[cmd_len + 2 + data2_len + 1] = '\0';
277 cmd_len += 2 + data2_len + 1;
281 mi_send (h, "-break-commands %s%s\n", cmd_param, cmd);
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);
291 static const struct cmd
295 void (*func) (mi_h *h, const char *cmd);
298 { "quit", 1, quit_command },
299 { "commands", 4, commands_command },
303 executecommand (mi_h *h, const char *cmd)
305 const char *start, *end, *cs;
306 const struct cmd *cmdp;
309 while (isspace (*cs))
312 while (isalnum (*cs))
315 while (isspace (*cs))
318 for (cmdp = cmds; cmdp < &cmds[LENGTH (cmds)]; cmdp++)
319 if (cmdp->min_shortcut <= end - start && end - start <= strlen (cmdp->name)
320 && strncmp (start, cmdp->name, end - start) == 0)
321 return cmdp->func (h, cs);
323 return default_command (h, cmd);
327 gdb_set_string (mi_h *h, const char *setting, const char *value)
329 char *cmd = xstrprintf ("-gdb-set %s %s", setting, value);
336 gdb_set_bool (mi_h *h, const char *setting, bool value)
338 gdb_set_string (h, setting, value ? "on" : "off");
342 gdb_show_string (mi_h *h, const char *setting)
347 mi_send (h, "-gdb-show %s\n", setting);
348 res = mi_get_response_blk (h);
349 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
350 && res->c != NULL && res->c->next == NULL
351 && res->c->type == t_const && strcmp (res->c->var, "value") == 0);
352 retval = xstrdup (res->c->v.cstr);
353 mi_free_output (res);
358 gdb_show_int (mi_h *h, const char *setting)
360 char *string = gdb_show_string (h, setting);
366 retval = l = strtol (string, &end, 10);
367 gdb_assert (errno == 0 && (end == NULL || *end == '\0') && retval == l);
373 gdb_show_bool (mi_h *h, const char *setting)
375 char *string = gdb_show_string (h, setting);
378 retval = strcmp (string, "on") == 0;
379 gdb_assert (retval || strcmp (string, "off") == 0);
384 static mi_h *completion_entry_function_h;
386 static char **completion_entry_function_data;
387 static size_t completion_entry_function_data_used;
388 static size_t completion_entry_function_data_allocated;
391 completion_entry_function_console_cb (const char *str, void *data)
393 int line_start = (intptr_t) data;
397 if (completion_entry_function_data_used
398 == completion_entry_function_data_allocated)
400 if (completion_entry_function_data_allocated > 0)
401 completion_entry_function_data_allocated *= 2;
403 completion_entry_function_data_allocated = 0x100;
404 completion_entry_function_data = xrealloc (completion_entry_function_data,
405 (sizeof (*completion_entry_function_data)
406 * completion_entry_function_data_allocated));
409 cs = strchr (str, '\n');
410 if (cs == NULL || cs[1] != '\0')
411 fatal ("Invalid GDB data: %s", str);
413 if (strncmp (rl_line_buffer, str, rl_point) != 0)
414 fatal ("Completion GDB data do not match, have \"%.*s\", got \"%.*s\".",
415 (int) rl_point, rl_line_buffer, (int) (cs - str), str);
417 s = xmalloc (cs - str - line_start + 1);
418 memcpy (s, &str[line_start], cs - str - line_start);
419 s[cs - str - line_start] = '\0';
420 completion_entry_function_data[completion_entry_function_data_used++] = s;
424 completion_entry_function (const char *text, int matches)
426 mi_h *h = completion_entry_function_h;
428 gdb_assert (matches >= 0);
434 while (completion_entry_function_data_used)
435 xfree (completion_entry_function_data
436 [--completion_entry_function_data_used]);
437 xfree (completion_entry_function_data);
438 completion_entry_function_data = NULL;
439 completion_entry_function_data_used = 0;
440 completion_entry_function_data_allocated = 0;
442 gdb_assert (rl_point >= 0);
443 gdb_assert (strlen (rl_line_buffer) >= rl_point);
444 gdb_assert (strlen (text) <= rl_point);
445 line_start = rl_point - strlen (text);
446 gdb_assert (strncmp (text, &rl_line_buffer[line_start],
447 strlen (text)) == 0);
448 mi_send (h, "-interpreter-exec console \"complete %.*s\"\n",
449 (int) rl_point, rl_line_buffer);
451 mi_set_console_cb (h, completion_entry_function_console_cb,
452 (void *) (intptr_t) line_start);
453 res = mi_get_response_blk (h);
454 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
456 mi_free_output (res);
457 mi_set_console_cb (h, console_cb, NULL);
460 if (matches < completion_entry_function_data_used)
461 return xstrdup (completion_entry_function_data[matches]);
462 else if (matches == completion_entry_function_data_used)
465 gdb_assert_not_reached ("too many matches");
468 extern char **mi_gdb_argv;
469 extern void (*mi_gdb_start_hook) (mi_h *h);
474 on_exit (h_disconnect, h);
475 mi_set_console_cb (h, console_cb, NULL);
476 mi_set_time_out_cb (h, time_out_cb, NULL);
478 // mi_set_to_gdb_cb (h, to_gdb_cb, NULL);
479 // mi_set_from_gdb_cb (h, from_gdb_cb, NULL);
483 main (int argc, char **argv)
488 setbuf (stdout, NULL);
490 mi_gdb_argv = xmalloc ((argc + 2) * sizeof (*mi_gdb_argv));
491 memcpy (&mi_gdb_argv[2], &argv[1], argc * sizeof (*mi_gdb_argv));
492 mi_gdb_argv[0] = "gdb";
493 mi_gdb_argv[1] = "--interpreter=mi";
495 mi_gdb_start_hook = start_hook;
497 h = mi_connect_local ();
499 fatal ("Cannot connect to GDB");
501 /* First eat the prompt. Then run empty command so that additional results
502 from -ex or -x during mi_connect_local are flushed. */
503 res = mi_get_response_blk (h);
504 gdb_assert (res == NULL);
505 default_command (h, "echo");
507 completion_entry_function_h = h;
508 rl_completion_entry_function = completion_entry_function;
509 rl_readline_name = "gdb";
511 if (gdb_show_bool (h, "history save"))
513 int history_size = gdb_show_int (h, "history size");
514 char *history_filename = gdb_show_string (h, "history filename");
516 gdb_set_bool (h, "history save", false);
517 stifle_history (history_size);
518 read_history (history_filename);
519 on_exit (history_save, history_filename);
520 /* Do not free HISTORY_FILENAME. */
527 prompt = gdb_show_string (h, "prompt");
528 cmd = readline (prompt);
532 cmd = xstrdup ("quit");
536 executecommand (h, cmd);