5 #include <readline/readline.h>
6 #include <readline/history.h>
12 #define gdb_assert assert
14 static ATTRIBUTE_NORETURN void
15 fatal (const char *fmt, ...)
20 vfprintf (stderr, fmt, ap);
27 xstrdup (const char *s)
31 gdb_assert (s != NULL);
33 gdb_assert (retval != NULL);
44 xstrprintf (const char *fmt, ...)
51 i = vasprintf (&retval, fmt, ap);
54 gdb_assert (i == strlen (retval));
59 console_cb (const char *str, void *data)
64 static ATTRIBUTE_UNUSED void
65 to_gdb_cb (const char *str, void *data)
67 printf ("to_gdb: %s\n", str);
70 static ATTRIBUTE_UNUSED void
71 from_gdb_cb (const char *str, void *data)
73 printf ("from_gdb: %s\n", str);
77 h_disconnect (int rc, void *arg)
85 history_save (int rc, void *arg)
87 const char *history_filename = arg;
89 write_history (history_filename);
93 quit_command (mi_h *h, const char *cmd)
99 default_command (mi_h *h, const char *cmd)
103 mi_send (h, "-interpreter-exec console \"%s\"\n", cmd);
107 mi_output *rec, *res;
109 res = mi_get_response_blk (h);
110 gdb_assert (res != NULL);
112 for (rec = res; rec != NULL; rec = rec->next)
119 /* We do not get MI_CL_DONE here, wait for MI_CL_STOPPED. */
125 gdb_assert (rec->c->type == t_const);
126 puts (rec->c->v.cstr);
129 fatal ("mi_get_rrecord == MI_CL_??? (%d)", rec->tclass);
132 mi_free_output (res);
136 static const struct cmd
139 void (*func) (mi_h *h, const char *cmd);
142 { "q", quit_command },
143 { "qu", quit_command },
144 { "qui", quit_command },
145 { "quit", quit_command },
149 executecommand (mi_h *h, const char *cmd)
151 const char *start, *end, *cs;
152 const struct cmd *cmdp;
155 while (isspace (*cs))
158 while (isalnum (*cs))
162 for (cmdp = cmds; cmdp < &cmds[LENGTH (cmds)]; cmdp++)
163 if (strlen (cmdp->name) == end - start
164 && strncmp (cmd, cmdp->name, end - start) == 0)
165 return cmdp->func (h, cmd);
167 return default_command (h, cmd);
171 gdb_done (mi_h *h, const char *command)
175 mi_send (h, "%s\n", command);
176 res = mi_get_response_blk (h);
177 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
179 mi_free_output (res);
183 gdb_set_string (mi_h *h, const char *setting, const char *value)
185 char *cmd = xstrprintf ("-gdb-set %s %s", setting, value);
192 gdb_set_bool (mi_h *h, const char *setting, bool value)
194 gdb_set_string (h, setting, value ? "on" : "off");
198 gdb_show_string (mi_h *h, const char *setting)
203 mi_send (h, "-gdb-show %s\n", setting);
204 res = mi_get_response_blk (h);
205 gdb_assert (res != NULL && res->next == NULL && res->tclass == MI_CL_DONE
206 && res->c != NULL && res->c->next == NULL
207 && res->c->type == t_const && strcmp (res->c->var, "value") == 0);
208 retval = xstrdup (res->c->v.cstr);
209 mi_free_output (res);
214 gdb_show_int (mi_h *h, const char *setting)
216 char *string = gdb_show_string (h, setting);
222 retval = l = strtol (string, &end, 10);
223 gdb_assert (errno == 0 && (end == NULL || *end == '\0') && retval == l);
229 gdb_show_bool (mi_h *h, const char *setting)
231 char *string = gdb_show_string (h, setting);
234 retval = strcmp (string, "on") == 0;
235 gdb_assert (retval || strcmp (string, "off") == 0);
241 main (int argc, char **argv)
245 const char *ex[argc];
246 unsigned ex_count = 0, ex_used = 0;
248 setbuf (stdout, NULL);
250 while (*++argv != NULL)
252 if (strcmp (*argv, "-ex") == 0 && argv[1] != NULL)
253 ex[ex_count++] = *++argv;
255 fatal ("Unknown parameter: %s", *argv);
258 mi_set_workaround (MI_PSYM_SEARCH, 0);
260 h = mi_connect_local ();
262 fatal ("Cannot connect to GDB");
264 on_exit (h_disconnect, h);
266 mi_set_console_cb (h, console_cb, NULL);
267 // mi_set_to_gdb_cb (h, to_gdb_cb, NULL);
268 // mi_set_from_gdb_cb (h, from_gdb_cb, NULL);
270 if (gdb_show_bool (h, "history save"))
272 int history_size = gdb_show_int (h, "history size");
273 char *history_filename = gdb_show_string (h, "history filename");
275 gdb_set_bool (h, "history save", false);
276 stifle_history (history_size);
277 read_history (history_filename);
278 on_exit (history_save, history_filename);
279 /* Do not free HISTORY_FILENAME. */
284 if (ex_used < ex_count)
286 cmd = xstrdup (ex[ex_used++]);
287 printf ("(gdb) %s\n", cmd);
291 cmd = readline ("(gdb) ");
293 cmd = xstrdup ("quit");
297 executecommand (h, cmd);