xref: /openbsd/gnu/usr.bin/binutils/gdb/mi/mi-interp.c (revision 11efff7f)
1 /* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
2 
3    Copyright 2002, 2003, 2003 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21 
22 #include "defs.h"
23 #include "gdb_string.h"
24 #include "interps.h"
25 #include "event-top.h"
26 #include "event-loop.h"
27 #include "inferior.h"
28 #include "ui-out.h"
29 #include "top.h"
30 
31 #include "mi-main.h"
32 #include "mi-cmds.h"
33 #include "mi-out.h"
34 #include "mi-console.h"
35 
36 struct mi_interp
37 {
38   /* MI's output channels */
39   struct ui_file *out;
40   struct ui_file *err;
41   struct ui_file *log;
42   struct ui_file *targ;
43   struct ui_file *event_channel;
44 
45   /* This is the interpreter for the mi... */
46   struct interp *mi2_interp;
47   struct interp *mi1_interp;
48   struct interp *mi_interp;
49 };
50 
51 /* These are the interpreter setup, etc. functions for the MI interpreter */
52 static void mi_execute_command_wrapper (char *cmd);
53 static void mi_command_loop (int mi_version);
54 
55 /* These are hooks that we put in place while doing interpreter_exec
56    so we can report interesting things that happened "behind the mi's
57    back" in this command */
58 static int mi_interp_query_hook (const char *ctlstr, va_list ap);
59 
60 static void mi3_command_loop (void);
61 static void mi2_command_loop (void);
62 static void mi1_command_loop (void);
63 
64 static void mi_insert_notify_hooks (void);
65 static void mi_remove_notify_hooks (void);
66 
67 static void *
mi_interpreter_init(void)68 mi_interpreter_init (void)
69 {
70   struct mi_interp *mi = XMALLOC (struct mi_interp);
71 
72   /* Why is this a part of the mi architecture? */
73 
74   mi_setup_architecture_data ();
75 
76   /* HACK: We need to force stdout/stderr to point at the console.  This avoids
77      any potential side effects caused by legacy code that is still
78      using the TUI / fputs_unfiltered_hook.  So we set up output channels for
79      this now, and swap them in when we are run. */
80 
81   raw_stdout = stdio_fileopen (stdout);
82 
83   /* Create MI channels */
84   mi->out = mi_console_file_new (raw_stdout, "~", '"');
85   mi->err = mi_console_file_new (raw_stdout, "&", '"');
86   mi->log = mi->err;
87   mi->targ = mi_console_file_new (raw_stdout, "@", '"');
88   mi->event_channel = mi_console_file_new (raw_stdout, "=", 0);
89 
90   return mi;
91 }
92 
93 static int
mi_interpreter_resume(void * data)94 mi_interpreter_resume (void *data)
95 {
96   struct mi_interp *mi = data;
97   /* As per hack note in mi_interpreter_init, swap in the output channels... */
98 
99   gdb_setup_readline ();
100 
101   /* These overwrite some of the initialization done in
102      _intialize_event_loop.  */
103   call_readline = gdb_readline2;
104   input_handler = mi_execute_command_wrapper;
105   add_file_handler (input_fd, stdin_event_handler, 0);
106   async_command_editing_p = 0;
107   /* FIXME: This is a total hack for now.  PB's use of the MI
108      implicitly relies on a bug in the async support which allows
109      asynchronous commands to leak through the commmand loop.  The bug
110      involves (but is not limited to) the fact that sync_execution was
111      erroneously initialized to 0.  Duplicate by initializing it thus
112      here...  */
113   sync_execution = 0;
114 
115   gdb_stdout = mi->out;
116   /* Route error and log output through the MI */
117   gdb_stderr = mi->err;
118   gdb_stdlog = mi->log;
119   /* Route target output through the MI. */
120   gdb_stdtarg = mi->targ;
121 
122   /* Replace all the hooks that we know about.  There really needs to
123      be a better way of doing this... */
124   clear_interpreter_hooks ();
125 
126   deprecated_show_load_progress = mi_load_progress;
127 
128   /* If we're _the_ interpreter, take control. */
129   if (current_interp_named_p (INTERP_MI1))
130     deprecated_command_loop_hook = mi1_command_loop;
131   else if (current_interp_named_p (INTERP_MI2))
132     deprecated_command_loop_hook = mi2_command_loop;
133   else if (current_interp_named_p (INTERP_MI3))
134     deprecated_command_loop_hook = mi3_command_loop;
135   else
136     deprecated_command_loop_hook = mi2_command_loop;
137 
138   return 1;
139 }
140 
141 static int
mi_interpreter_suspend(void * data)142 mi_interpreter_suspend (void *data)
143 {
144   gdb_disable_readline ();
145   return 1;
146 }
147 
148 static int
mi_interpreter_exec(void * data,const char * command)149 mi_interpreter_exec (void *data, const char *command)
150 {
151   char *tmp = alloca (strlen (command) + 1);
152   strcpy (tmp, command);
153   mi_execute_command_wrapper (tmp);
154   return 1;
155 }
156 
157 /* Never display the default gdb prompt in mi case.  */
158 static int
mi_interpreter_prompt_p(void * data)159 mi_interpreter_prompt_p (void *data)
160 {
161   return 0;
162 }
163 
164 static void
mi_interpreter_exec_continuation(struct continuation_arg * arg)165 mi_interpreter_exec_continuation (struct continuation_arg *arg)
166 {
167   bpstat_do_actions (&stop_bpstat);
168   if (!target_executing)
169     {
170       fputs_unfiltered ("*stopped", raw_stdout);
171       mi_out_put (uiout, raw_stdout);
172       fputs_unfiltered ("\n", raw_stdout);
173       fputs_unfiltered ("(gdb) \n", raw_stdout);
174       gdb_flush (raw_stdout);
175       do_exec_cleanups (ALL_CLEANUPS);
176     }
177   else if (target_can_async_p ())
178     {
179       add_continuation (mi_interpreter_exec_continuation, NULL);
180     }
181 }
182 
183 enum mi_cmd_result
mi_cmd_interpreter_exec(char * command,char ** argv,int argc)184 mi_cmd_interpreter_exec (char *command, char **argv, int argc)
185 {
186   struct interp *interp_to_use;
187   enum mi_cmd_result result = MI_CMD_DONE;
188   int i;
189   struct interp_procs *procs;
190 
191   if (argc < 2)
192     {
193       mi_error_message = xstrprintf ("mi_cmd_interpreter_exec: Usage: -interpreter-exec interp command");
194       return MI_CMD_ERROR;
195     }
196 
197   interp_to_use = interp_lookup (argv[0]);
198   if (interp_to_use == NULL)
199     {
200       mi_error_message = xstrprintf ("mi_cmd_interpreter_exec: could not find interpreter \"%s\"", argv[0]);
201       return MI_CMD_ERROR;
202     }
203 
204   if (!interp_exec_p (interp_to_use))
205     {
206       mi_error_message = xstrprintf ("mi_cmd_interpreter_exec: interpreter \"%s\" does not support command execution",
207 				     argv[0]);
208       return MI_CMD_ERROR;
209     }
210 
211   /* Insert the MI out hooks, making sure to also call the interpreter's hooks
212      if it has any. */
213   /* KRS: We shouldn't need this... Events should be installed and they should
214      just ALWAYS fire something out down the MI channel... */
215   mi_insert_notify_hooks ();
216 
217   /* Now run the code... */
218 
219   for (i = 1; i < argc; i++)
220     {
221       char *buff = NULL;
222       /* Do this in a cleaner way...  We want to force execution to be
223          asynchronous for commands that run the target.  */
224       if (target_can_async_p () && (strcmp (argv[0], "console") == 0))
225 	{
226 	  int len = strlen (argv[i]);
227 	  buff = xmalloc (len + 2);
228 	  memcpy (buff, argv[i], len);
229 	  buff[len] = '&';
230 	  buff[len + 1] = '\0';
231 	}
232 
233       /* We had to set sync_execution = 0 for the mi (well really for Project
234          Builder's use of the mi - particularly so interrupting would work.
235          But for console commands to work, we need to initialize it to 1 -
236          since that is what the cli expects - before running the command,
237          and then set it back to 0 when we are done. */
238       sync_execution = 1;
239       if (interp_exec (interp_to_use, argv[i]) < 0)
240 	{
241 	  mi_error_message = error_last_message ();
242 	  result = MI_CMD_ERROR;
243 	  break;
244 	}
245       xfree (buff);
246       do_exec_error_cleanups (ALL_CLEANUPS);
247       sync_execution = 0;
248     }
249 
250   mi_remove_notify_hooks ();
251 
252   /* Okay, now let's see if the command set the inferior going...
253      Tricky point - have to do this AFTER resetting the interpreter, since
254      changing the interpreter will clear out all the continuations for
255      that interpreter... */
256 
257   if (target_can_async_p () && target_executing)
258     {
259       fputs_unfiltered ("^running\n", raw_stdout);
260       add_continuation (mi_interpreter_exec_continuation, NULL);
261     }
262 
263   return result;
264 }
265 
266 /*
267  * mi_insert_notify_hooks - This inserts a number of hooks that are meant to produce
268  * async-notify ("=") MI messages while running commands in another interpreter
269  * using mi_interpreter_exec.  The canonical use for this is to allow access to
270  * the gdb CLI interpreter from within the MI, while still producing MI style output
271  * when actions in the CLI command change gdb's state.
272 */
273 
274 static void
mi_insert_notify_hooks(void)275 mi_insert_notify_hooks (void)
276 {
277   deprecated_query_hook = mi_interp_query_hook;
278 }
279 
280 static void
mi_remove_notify_hooks(void)281 mi_remove_notify_hooks (void)
282 {
283   deprecated_query_hook = NULL;
284 }
285 
286 static int
mi_interp_query_hook(const char * ctlstr,va_list ap)287 mi_interp_query_hook (const char *ctlstr, va_list ap)
288 {
289   return 1;
290 }
291 
292 static void
mi_execute_command_wrapper(char * cmd)293 mi_execute_command_wrapper (char *cmd)
294 {
295   mi_execute_command (cmd, stdin == instream);
296 }
297 
298 static void
mi1_command_loop(void)299 mi1_command_loop (void)
300 {
301   mi_command_loop (1);
302 }
303 
304 static void
mi2_command_loop(void)305 mi2_command_loop (void)
306 {
307   mi_command_loop (2);
308 }
309 
310 static void
mi3_command_loop(void)311 mi3_command_loop (void)
312 {
313   mi_command_loop (3);
314 }
315 
316 static void
mi_command_loop(int mi_version)317 mi_command_loop (int mi_version)
318 {
319 #if 0
320   /* HACK: Force stdout/stderr to point at the console.  This avoids
321      any potential side effects caused by legacy code that is still
322      using the TUI / fputs_unfiltered_hook */
323   raw_stdout = stdio_fileopen (stdout);
324   /* Route normal output through the MIx */
325   gdb_stdout = mi_console_file_new (raw_stdout, "~", '"');
326   /* Route error and log output through the MI */
327   gdb_stderr = mi_console_file_new (raw_stdout, "&", '"');
328   gdb_stdlog = gdb_stderr;
329   /* Route target output through the MI. */
330   gdb_stdtarg = mi_console_file_new (raw_stdout, "@", '"');
331   /* HACK: Poke the ui_out table directly.  Should we be creating a
332      mi_out object wired up to the above gdb_stdout / gdb_stderr? */
333   uiout = mi_out_new (mi_version);
334   /* HACK: Override any other interpreter hooks.  We need to create a
335      real event table and pass in that. */
336   deprecated_init_ui_hook = 0;
337   /* deprecated_command_loop_hook = 0; */
338   deprecated_print_frame_info_listing_hook = 0;
339   deprecated_query_hook = 0;
340   deprecated_warning_hook = 0;
341   deprecated_create_breakpoint_hook = 0;
342   deprecated_delete_breakpoint_hook = 0;
343   deprecated_modify_breakpoint_hook = 0;
344   deprecated_interactive_hook = 0;
345   deprecated_registers_changed_hook = 0;
346   deprecated_readline_begin_hook = 0;
347   deprecated_readline_hook = 0;
348   deprecated_readline_end_hook = 0;
349   deprecated_register_changed_hook = 0;
350   deprecated_memory_changed_hook = 0;
351   deprecated_context_hook = 0;
352   deprecated_target_wait_hook = 0;
353   deprecated_call_command_hook = 0;
354   deprecated_error_hook = 0;
355   deprecated_error_begin_hook = 0;
356   deprecated_show_load_progress = mi_load_progress;
357 #endif
358   /* Turn off 8 bit strings in quoted output.  Any character with the
359      high bit set is printed using C's octal format. */
360   sevenbit_strings = 1;
361   /* Tell the world that we're alive */
362   fputs_unfiltered ("(gdb) \n", raw_stdout);
363   gdb_flush (raw_stdout);
364   start_event_loop ();
365 }
366 
367 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
368 
369 void
_initialize_mi_interp(void)370 _initialize_mi_interp (void)
371 {
372   static const struct interp_procs procs =
373   {
374     mi_interpreter_init,	/* init_proc */
375     mi_interpreter_resume,	/* resume_proc */
376     mi_interpreter_suspend,	/* suspend_proc */
377     mi_interpreter_exec,	/* exec_proc */
378     mi_interpreter_prompt_p	/* prompt_proc_p */
379   };
380 
381   /* The various interpreter levels.  */
382   interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs));
383   interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs));
384   interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs));
385 
386   /* "mi" selects the most recent released version.  "mi2" was
387      released as part of GDB 6.0.  */
388   interp_add (interp_new (INTERP_MI, NULL, mi_out_new (2), &procs));
389 }
390