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 * 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 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 142 mi_interpreter_suspend (void *data) 143 { 144 gdb_disable_readline (); 145 return 1; 146 } 147 148 static int 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 159 mi_interpreter_prompt_p (void *data) 160 { 161 return 0; 162 } 163 164 static void 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 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 275 mi_insert_notify_hooks (void) 276 { 277 deprecated_query_hook = mi_interp_query_hook; 278 } 279 280 static void 281 mi_remove_notify_hooks (void) 282 { 283 deprecated_query_hook = NULL; 284 } 285 286 static int 287 mi_interp_query_hook (const char *ctlstr, va_list ap) 288 { 289 return 1; 290 } 291 292 static void 293 mi_execute_command_wrapper (char *cmd) 294 { 295 mi_execute_command (cmd, stdin == instream); 296 } 297 298 static void 299 mi1_command_loop (void) 300 { 301 mi_command_loop (1); 302 } 303 304 static void 305 mi2_command_loop (void) 306 { 307 mi_command_loop (2); 308 } 309 310 static void 311 mi3_command_loop (void) 312 { 313 mi_command_loop (3); 314 } 315 316 static void 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 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