diff options
author | Keith Seitz <keiths@redhat.com> | 2002-05-28 23:47:02 +0000 |
---|---|---|
committer | Keith Seitz <keiths@redhat.com> | 2002-05-28 23:47:02 +0000 |
commit | 9102d64fc2e0d586430ee78205f979a79a3cc01b (patch) | |
tree | a1d84a52034520345137ba9c2735d5e6477faf7e | |
parent | 0d49dda2de4c1fd23c87348f08a022bfd3ee3334 (diff) | |
download | gdb-9102d64fc2e0d586430ee78205f979a79a3cc01b.zip gdb-9102d64fc2e0d586430ee78205f979a79a3cc01b.tar.gz gdb-9102d64fc2e0d586430ee78205f979a79a3cc01b.tar.bz2 |
Initial check-in of interpreter support from Apple. (Slightly massaged and
modified by me.)
-rw-r--r-- | gdb/ChangeLog | 46 | ||||
-rw-r--r-- | gdb/Makefile.in | 38 | ||||
-rw-r--r-- | gdb/defs.h | 1 | ||||
-rw-r--r-- | gdb/event-loop.c | 20 | ||||
-rw-r--r-- | gdb/event-top.c | 53 | ||||
-rw-r--r-- | gdb/event-top.h | 2 | ||||
-rw-r--r-- | gdb/main.c | 6 | ||||
-rw-r--r-- | gdb/mi/mi-cmds.c | 2 | ||||
-rw-r--r-- | gdb/mi/mi-cmds.h | 6 | ||||
-rw-r--r-- | gdb/mi/mi-main.c | 187 | ||||
-rw-r--r-- | gdb/top.c | 55 | ||||
-rw-r--r-- | gdb/wrapper.c | 26 | ||||
-rw-r--r-- | gdb/wrapper.h | 6 |
13 files changed, 268 insertions, 180 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 35913de..6745068 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,49 @@ +2002-05-28 Keith Seitz <keiths@redhat.com> + + * cli/cli-interp.c: New file. Almost entirely from Apple's + sources. Collected and moved here. + * mi/mi-interp.c: Ditto. + * mi/mi-events.c: Ditto. + * mi/mi.h: New file. + * Makefile.in: Add new files. + Update dependencies on interps.h. + * defs.h (selected_frame_level_changed_hook): Add declaration. + * wrapper.c (captured_execute_command): New function. + (do_captured_execute_command): New function. + * wrapper.h (captured_execute_command): Declare. + * top.c (catcher): If the caught command changes the uiout on us, + try to do something sane, like using the current interpreter's + uiout. + * mi/mi-main.c (captured_execute_command): Use catch_exception + instead of catch_errors. + (mi_execute_command_wrapper): Remove. Using catch_errors now. + (mi_input): Make global. + (mi_load_progress): Ditto. + Use interpreter functions instead of interpreter_p. + (mi_command_loop): Moved to mi-interp.c + (mi0_command_loop): Ditto. + (mi1_command_loop): Ditto. + (mi_init_ui): Remove. + (_initialize_mi_main): Remove. No longer needed. + + From Jim Ingham <jingham@apple.com>: + * event-loop.c (start_event_loop): Poll the interpreter's event loop + as well as gdb... + * event-top.c (gdb_setup_readline, gdb_disable_readline): New functions, + used by console & mi to grab & relinquish control of the readline input. + * event-top.h (gdb_setup_readline, gdb_disable_readline): Declare. + * main.c (captured_main): Copy the interpreter name, since we will + eventually use it as a set variable. + * top.c (gdb_init): Use the interpreter mechanism to startup the stdin + handling. + * interps.c: New file. (Originally called interpreter.c by Apple) + * interps.h: New file. (Originally called interpreter.h by Apple) + * mi/mi-cmds.c, mi/mi-cmds.h: Add mi commands -interpreter-set and + -interpreter-exec. + * mi/mi-main.c: Add the interpreter functions. + (mi_execute_command): Don't print the prompt if the command return + is MI_CMD_QUIET. + 2002-05-28 Jason Thorpe <thorpej@wasabisystems.com> * ppcnbsd-nat.c: Rewrite. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index da4e25e..64b76f0 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -137,11 +137,11 @@ INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC) # CLI sub directory definitons # SUBDIR_CLI_OBS = \ - cli-dump.o \ - cli-decode.o cli-script.o cli-cmds.o cli-setshow.o cli-utils.o + cli-dump.o cli-decode.o \ + cli-interp.o cli-script.o cli-cmds.o cli-setshow.o cli-utils.o SUBDIR_CLI_SRCS = \ - cli/cli-dump.c \ - cli/cli-decode.c cli/cli-script.c cli/cli-cmds.c cli/cli-setshow.c \ + cli/cli-dump.c cli/cli-decode.c \ + cli/cli-interp.c cli/cli-script.c cli/cli-cmds.c cli/cli-setshow.c \ cli/cli-utils.c SUBDIR_CLI_DEPS = SUBDIR_CLI_INITS = \ @@ -159,13 +159,13 @@ SUBDIR_CLI_UNINSTALL= SUBDIR_MI_OBS = \ mi-out.o mi-console.o \ mi-cmds.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \ - mi-cmd-disas.o \ + mi-cmd-disas.o mi-events.o mi-interp.o \ mi-main.o mi-parse.o mi-getopt.o SUBDIR_MI_SRCS = \ mi/mi-out.c mi/mi-console.c \ mi/mi-cmds.c \ mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \ - mi/mi-cmd-disas.c \ + mi/mi-cmd-disas.c mi/mi-events.c mi/mi-interp.c \ mi/mi-main.c mi/mi-parse.c mi/mi-getopt.c SUBDIR_MI_DEPS = SUBDIR_MI_INITS = \ @@ -533,7 +533,7 @@ SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \ findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c osabi.c \ inf-loop.c infcmd.c inflow.c infrun.c language.c \ kod.c kod-cisco.c \ - ui-out.c cli-out.c \ + ui-out.c cli-out.c interps.c \ varobj.c wrapper.c \ jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \ m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \ @@ -637,6 +637,7 @@ gdbthread_h = gdbthread.h $(breakpoint_h) gdbtypes_h = gdbtypes.h inf_loop_h = inf-loop.h inferior_h = inferior.h $(breakpoint_h) +interps_h = interps.h language_h = language.h linespec_h = linespec.h macroexp_h = macroexp.h @@ -736,7 +737,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \ dbxread.o coffread.o elfread.o \ dwarfread.o dwarf2read.o mipsread.o stabsread.o corefile.o \ c-lang.o ch-exp.o ch-lang.o f-lang.o \ - ui-out.o cli-out.o \ + ui-out.o cli-out.o interps.o \ varobj.o wrapper.o \ jv-lang.o jv-valprint.o jv-typeprint.o \ m2-lang.o p-lang.o p-typeprint.o p-valprint.o \ @@ -1450,7 +1451,7 @@ event-loop.o: event-loop.c $(defs_h) $(top_h) $(event_loop_h) $(event_top_h) event-top.o: event-top.c $(top_h) $(readline_headers) \ $(defs_h) $(inferior_h) $(event_loop_h) $(event_top_h) $(terminal_h) \ - $(gdbcmd_h) $(target_h) $(cli_decode_h) + $(gdbcmd_h) $(target_h) $(cli_decode_h) $(interps_h) inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(inf_loop_h) $(event_loop_h) \ $(event_top_h) @@ -2184,7 +2185,7 @@ top.o: top.c $(top_h) $(bfd_h) $(getopt_h) $(readline_headers) $(call_cmds_h) \ $(defs_h) $(gdbcmd_h) $(inferior_h) $(language_h) \ $(remote_utils_h) $(gdb_string_h) $(event_loop_h) $(event_top_h) \ $(completer_h) $(version_h) $(ui_out_h) $(doublest_h) \ - $(serial_h) + $(serial_h) $(interps_h) typeprint.o: typeprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \ $(gdbcore_h) $(gdbtypes_h) $(language_h) $(symtab_h) $(target_h) \ @@ -2279,8 +2280,9 @@ p-exp.tab.o: p-exp.tab.c $(defs_h) $(expression_h) $(gdbtypes_h) \ gdb-events.o: gdb-events.c $(gdb_events_h) $(defs_h) $(gdbcmd_h) ui-out.o: ui-out.c $(defs_h) $(ui_out_h) $(expression_h) $(language_h) -cli-out.o: cli-out.c $(defs_h) $(ui_out_h) $(cli_out_h) - +cli-out.o: cli-out.c $(defs_h) $(ui_out_h) $(cli_out_h) $(interps_h) +inters.o: interps.c $(defs_h) $(gdbcmd_h) $(ui_out_h) $(event_loop_h) \ + $(event_top_h) $(interps_h) $(gdb_h) $(wrapper_h) varobj.o: varobj.c $(defs_h) $(frame_h) $(value_h) \ $(language_h) $(valprint_h) $(varobj_h) $(wrapper_h) @@ -2306,6 +2308,10 @@ cli-dump.o: $(srcdir)/cli/cli-dump.c $(defs_h) $(gdb_string_h) $(command_h) \ $(value_h) $(gdbcmd_h) $(completer_h) $(cli_dump_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-dump.c +cli-interp.o: $(srcdir)/cli/cli-interp.c $(defs_h) $(interps_h) \ + $(wrapper_h) $(event_top_h) $(ui_out_h) $(cli_out_h) + $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-interp.c + cli-setshow.o: $(srcdir)/cli/cli-setshow.c $(cli_setshow_h) \ $(cli_decode_h) $(cli_cmds_h) $(defs_h) \ $(value_h) $(ui_out_h) @@ -2325,6 +2331,7 @@ cli-utils.o: $(srcdir)/cli/cli-utils.c $(cli_utils_h) $(defs_h) # Need to explicitly specify the compile rule as make will do nothing # or try to compile the object file into the mi directory. +mi_h = $(srcdir)/mi/mi.h mi_cmds_h = $(srcdir)/mi/mi-cmds.h mi_out_h = $(srcdir)/mi/mi-out.h mi_parse_h = $(srcdir)/mi/mi-parse.h @@ -2346,6 +2353,13 @@ mi-cmd-break.o: $(srcdir)/mi/mi-cmd-break.c $(defs_h) $(mi_cmds_h) \ mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c $(defs_h) $(mi_cmds_h) \ $(ui_out_h) $(value_h) $(target_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-disas.c +mi-events.o: $(srcdir)/mi/mi-events.c $(defs_h) $(ui_out_h) $(interps_h) \ + $(gdb_h) $(breakpoint_h) $(mi_h) + $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-events.c +mi-interp.o: $(srcdir)/mi/mi-interp.c $(defs_h) $(interps_h) \ + $(event_top_h) $(event_loop_h) $(inferior_h) $(ui_out_h) \ + $(top_h) $(mi_h) $(mi_cmds_h) $(mi_out_h) $(mi_console_h) + $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-interp.c mi-main.o: $(srcdir)/mi/mi-main.c $(defs_h) $(top_h) $(mi_cmds_h) $(ui_out_h) \ $(mi_console_h) $(mi_getopt_h) $(event_loop_h) $(event_top_h) \ $(mi_getopt_h) $(regcache_h) $(gdb_h) $(target_h) \ @@ -1143,6 +1143,7 @@ extern void (*error_begin_hook) (void); extern int (*ui_load_progress_hook) (const char *section, unsigned long num); +extern void (*selected_frame_level_changed_hook) (int level); /* Inhibit window interface if non-zero. */ diff --git a/gdb/event-loop.c b/gdb/event-loop.c index 4e42d7e..f098487 100644 --- a/gdb/event-loop.c +++ b/gdb/event-loop.c @@ -22,6 +22,7 @@ #include "defs.h" #include "event-loop.h" #include "event-top.h" +#include "interps.h" #ifdef HAVE_POLL #if defined (HAVE_POLL_H) @@ -393,10 +394,23 @@ start_event_loop (void) longer any event sources registered. */ while (1) { - int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL); - if (result < 0) + int gdb_result, interp_result; + + gdb_result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL); + if (gdb_result < 0) break; - if (result == 0) + + interp_result = catch_errors (interpreter_do_one_event, 0, "", RETURN_MASK_ALL); + if (interp_result < 0) + { + /* FIXME - kill the interpreter */ + } + + /* If we long-jumped out of do_one_event, we probably + didn't get around to resetting the prompt, which leaves + readline in a messed-up state. Reset it here. */ + + if (gdb_result == 0) { /* FIXME: this should really be a call to a hook that is interface specific, because interfaces can display the diff --git a/gdb/event-top.c b/gdb/event-top.c index b472694..878e769 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -26,6 +26,7 @@ #include "terminal.h" /* for job_control */ #include "event-loop.h" #include "event-top.h" +#include "interps.h" #include <signal.h> /* For dont_repeat() */ @@ -252,7 +253,7 @@ display_gdb_prompt (char *new_prompt) /* When an alternative interpreter has been installed, do not display the comand prompt. */ - if (interpreter_p) + if (gdb_interpreter_display_prompt (new_prompt)) return; if (target_executing && sync_execution) @@ -1111,14 +1112,31 @@ set_async_prompt (char *args, int from_tty, struct cmd_list_element *c) PROMPT (0) = savestring (new_async_prompt, strlen (new_async_prompt)); } +void +_initialize_event_loop (void) +{ + /* Tell gdb to use the cli_command_loop as the main loop. */ + if (event_loop_p && command_loop_hook == NULL) + command_loop_hook = cli_command_loop; +} + /* Set things up for readline to be invoked via the alternate interface, i.e. via a callback function (rl_callback_read_char), and hook up instream to the event loop. */ void -_initialize_event_loop (void) +gdb_setup_readline (void) { + /* This function is a noop for the async case. The assumption is that + the async setup is ALL done in gdb_init, and we would only mess it up + here. The async stuff should really go away over time. */ + if (event_loop_p) { + gdb_stdout = stdio_fileopen (stdout); + gdb_stderr = stdio_fileopen (stderr); + gdb_stdlog = gdb_stderr; /* for moment */ + gdb_stdtarg = gdb_stderr; /* for moment */ + /* If the input stream is connected to a terminal, turn on editing. */ if (ISATTY (instream)) @@ -1151,9 +1169,6 @@ _initialize_event_loop (void) register it with the event loop. */ input_fd = fileno (instream); - /* Tell gdb to use the cli_command_loop as the main loop. */ - command_loop_hook = cli_command_loop; - /* Now we need to create the event sources for the input file descriptor. */ /* At this point in time, this is the only event source that we @@ -1164,3 +1179,31 @@ _initialize_event_loop (void) add_file_handler (input_fd, stdin_event_handler, 0); } } + +/* Disable command input through the standard CLI channels. Used in + the suspend proc for interpreters that use the standard gdb readline + interface, like the cli & the mi. */ + +void +gdb_disable_readline (void) +{ + if (event_loop_p) + { + /* FIXME - It is too heavyweight to delete and remake these + every time you run an interpreter that needs readline. + It is probably better to have the interpreters cache these, + which in turn means that this needs to be moved into interpreter + specific code. */ + +#if 0 + ui_file_delete (gdb_stdout); + ui_file_delete (gdb_stderr); + gdb_stdlog = NULL; + gdb_stdtarg = NULL; +#endif + + rl_callback_handler_remove (); + delete_file_handler (input_fd); + } +} + diff --git a/gdb/event-top.h b/gdb/event-top.h index 24044a5..d8c0a96 100644 --- a/gdb/event-top.h +++ b/gdb/event-top.h @@ -71,6 +71,8 @@ struct prompts FIXME: these should really go into top.h. */ extern void display_gdb_prompt (char *new_prompt); +void gdb_setup_readline (void); +void gdb_disable_readline (void); extern void async_init_signals (void); extern void set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c); @@ -51,7 +51,9 @@ int display_space; processes UI events asynchronously. */ int event_loop_p = 1; -/* Has an interpreter been specified and if so, which. */ +/* Has an interpreter been specified and if so, which. + This will be used as a set command variable, so it should + always be malloc'ed - since do_setshow_command will free it. */ char *interpreter_p; /* Whether this is the command line version or not */ @@ -354,7 +356,7 @@ extern int gdbtk_test (char *); } #endif /* GDBTK */ case 'i': - interpreter_p = optarg; + interpreter_p = xstrdup (optarg); break; case 'd': dirarg[ndir++] = optarg; diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 233d06b..0d50d13 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -88,6 +88,8 @@ struct mi_cmd mi_cmds[] = {"gdb-show", "show %s", 0}, {"gdb-source", 0, 0}, {"gdb-version", "show version", 0}, + {"interpreter-set", 0, 0, mi_cmd_interpreter_set}, + {"interpreter-exec", 0, 0, mi_cmd_interpreter_exec}, {"kod-info", 0, 0}, {"kod-list", 0, 0}, {"kod-list-object-types", 0, 0}, diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index 88775e6..8c650fc 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -27,7 +27,7 @@ enum mi_cmd_result { /* Report the command as ``done''. Display both the ``NNN^done'' - message and the completion prompt. */ + message and the completion prompt. */ MI_CMD_DONE = 0, /* The command is still running in the forground. Main loop should display the completion prompt. */ @@ -75,6 +75,8 @@ extern mi_cmd_args_ftype mi_cmd_exec_step_instruction; extern mi_cmd_args_ftype mi_cmd_exec_until; extern mi_cmd_args_ftype mi_cmd_exec_interrupt; extern mi_cmd_argv_ftype mi_cmd_gdb_exit; +extern mi_cmd_argv_ftype mi_cmd_interpreter_set; +extern mi_cmd_argv_ftype mi_cmd_interpreter_exec; extern mi_cmd_argv_ftype mi_cmd_stack_info_depth; extern mi_cmd_argv_ftype mi_cmd_stack_list_args; extern mi_cmd_argv_ftype mi_cmd_stack_list_frames; @@ -122,4 +124,6 @@ extern int mi_debug_p; /* Raw console output - FIXME: should this be a parameter? */ extern struct ui_file *raw_stdout; +extern char *mi_error_message; +void mi_execute_command (char *cmd, int from_tty); #endif diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index bd8cd67..1e9baed 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -33,6 +33,7 @@ #include "mi-console.h" #include "ui-out.h" #include "mi-out.h" +#include "interps.h" #include "event-loop.h" #include "event-top.h" #include "gdbcore.h" /* for write_memory() */ @@ -77,27 +78,25 @@ struct ui_file *raw_stdout; /* The token of the last asynchronous command */ static char *last_async_command; static char *previous_async_command; -static char *mi_error_message; +char *mi_error_message; static char *old_regs; extern void _initialize_mi_main (void); -static char *mi_input (char *); -static void mi_execute_command (char *cmd, int from_tty); +void mi_execute_command (char *cmd, int from_tty); static enum mi_cmd_result mi_cmd_execute (struct mi_parse *parse); static void mi_execute_cli_command (const char *cli, char *args); static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty); -static void mi_execute_command_wrapper (char *cmd); void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg); static int register_changed_p (int regnum); static int get_register (int regnum, int format); -static void mi_load_progress (const char *section_name, - unsigned long sent_so_far, - unsigned long total_section, - unsigned long total_sent, - unsigned long grand_total); +void mi_load_progress (const char *section_name, + unsigned long sent_so_far, + unsigned long total_section, + unsigned long total_sent, + unsigned long grand_total); /* FIXME: these should go in some .h file, but infcmd.c doesn't have a corresponding .h file. These wrappers will be obsolete anyway, once @@ -1080,7 +1079,12 @@ captured_mi_execute_command (struct ui_out *uiout, void *data) if (!target_can_async_p () || !target_executing) { - /* print the result if there were no errors */ + /* print the result if there were no errors + + Remember that on the way out of executing a command, you have + to directly use the mi_interp's uiout, since the command could + have reset the interpreter, in which case the current uiout + will most likely crash in the mi_out_* routines. */ if (args->rc == MI_CMD_DONE) { fputs_unfiltered (context->token, raw_stdout); @@ -1128,15 +1132,21 @@ captured_mi_execute_command (struct ui_out *uiout, void *data) /* FIXME: If the command string has something that looks like a format spec (e.g. %s) we will get a core dump */ mi_execute_cli_command ("%s", context->command); - /* print the result */ - /* FIXME: Check for errors here. */ - fputs_unfiltered (context->token, raw_stdout); - fputs_unfiltered ("^done", raw_stdout); - mi_out_put (uiout, raw_stdout); - mi_out_rewind (uiout); - fputs_unfiltered ("\n", raw_stdout); - args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; - args->rc = MI_CMD_DONE; + + /* If we changed interpreters, DON'T print out anything. */ + if (gdb_current_interpreter_is_named (GDB_INTERPRETER_MI) + || gdb_current_interpreter_is_named (GDB_INTERPRETER_MI0)) + { + /* print the result */ + /* FIXME: Check for errors here. */ + fputs_unfiltered (context->token, raw_stdout); + fputs_unfiltered ("^done", raw_stdout); + mi_out_put (uiout, raw_stdout); + mi_out_rewind (uiout); + fputs_unfiltered ("\n", raw_stdout); + args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; + args->rc = MI_CMD_DONE; + } break; } @@ -1151,7 +1161,7 @@ mi_execute_command (char *cmd, int from_tty) struct mi_parse *command; struct captured_mi_execute_command_args args; struct ui_out *saved_uiout = uiout; - int result, rc; + int result; /* This is to handle EOF (^D). We just quit gdb. */ /* FIXME: we should call some API function here. */ @@ -1189,10 +1199,13 @@ mi_execute_command (char *cmd, int from_tty) mi_parse_free (command); } - fputs_unfiltered ("(gdb) \n", raw_stdout); - gdb_flush (raw_stdout); - /* print any buffered hook code */ - /* ..... */ + if (args.rc != MI_CMD_QUIET) + { + fputs_unfiltered ("(gdb) \n", raw_stdout); + gdb_flush (raw_stdout); + /* print any buffered hook code */ + /* ..... */ + } } static enum mi_cmd_result @@ -1259,12 +1272,6 @@ mi_cmd_execute (struct mi_parse *parse) } } -static void -mi_execute_command_wrapper (char *cmd) -{ - mi_execute_command (cmd, stdin == instream); -} - /* FIXME: This is just a hack so we can get some extra commands going. We don't want to channel things through the CLI, but call libgdb directly */ /* Use only for synchronous commands */ @@ -1367,13 +1374,7 @@ mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg) do_exec_cleanups (ALL_CLEANUPS); } -static char * -mi_input (char *buf) -{ - return gdb_readline (NULL); -} - -static void +void mi_load_progress (const char *section_name, unsigned long sent_so_far, unsigned long total_section, @@ -1385,7 +1386,8 @@ mi_load_progress (const char *section_name, static char *previous_sect_name = NULL; int new_section; - if (!interpreter_p || strncmp (interpreter_p, "mi", 2) != 0) + if (!gdb_current_interpreter_is_named (GDB_INTERPRETER_MI) + && !gdb_current_interpreter_is_named (GDB_INTERPRETER_MI0)) return; update_threshold.tv_sec = 0; @@ -1442,118 +1444,17 @@ mi_load_progress (const char *section_name, } } -static void -mi_command_loop (int mi_version) -{ - /* HACK: Force stdout/stderr to point at the console. This avoids - any potential side effects caused by legacy code that is still - using the TUI / fputs_unfiltered_hook */ - raw_stdout = stdio_fileopen (stdout); - /* Route normal output through the MIx */ - gdb_stdout = mi_console_file_new (raw_stdout, "~"); - /* Route error and log output through the MI */ - gdb_stderr = mi_console_file_new (raw_stdout, "&"); - gdb_stdlog = gdb_stderr; - /* Route target output through the MI. */ - gdb_stdtarg = mi_console_file_new (raw_stdout, "@"); - - /* HACK: Poke the ui_out table directly. Should we be creating a - mi_out object wired up to the above gdb_stdout / gdb_stderr? */ - uiout = mi_out_new (mi_version); - - /* HACK: Override any other interpreter hooks. We need to create a - real event table and pass in that. */ - init_ui_hook = 0; - /* command_loop_hook = 0; */ - print_frame_info_listing_hook = 0; - query_hook = 0; - warning_hook = 0; - create_breakpoint_hook = 0; - delete_breakpoint_hook = 0; - modify_breakpoint_hook = 0; - interactive_hook = 0; - registers_changed_hook = 0; - readline_begin_hook = 0; - readline_hook = 0; - readline_end_hook = 0; - register_changed_hook = 0; - memory_changed_hook = 0; - context_hook = 0; - target_wait_hook = 0; - call_command_hook = 0; - error_hook = 0; - error_begin_hook = 0; - show_load_progress = mi_load_progress; - - /* Turn off 8 bit strings in quoted output. Any character with the - high bit set is printed using C's octal format. */ - sevenbit_strings = 1; - - /* Tell the world that we're alive */ - fputs_unfiltered ("(gdb) \n", raw_stdout); - gdb_flush (raw_stdout); - - if (!event_loop_p) - simplified_command_loop (mi_input, mi_execute_command); - else - start_event_loop (); -} - -static void -mi0_command_loop (void) -{ - mi_command_loop (0); -} - -static void -mi1_command_loop (void) -{ - mi_command_loop (1); -} - -static void -setup_architecture_data (void) +void +mi_setup_architecture_data (void) { /* don't trust REGISTER_BYTES to be zero. */ old_regs = xmalloc (REGISTER_BYTES + 1); memset (old_regs, 0, REGISTER_BYTES + 1); } -static void -mi_init_ui (char *arg0) -{ - /* Eventually this will contain code that takes control of the - console. */ -} - void -_initialize_mi_main (void) +mi_register_gdbarch_swap (void) { - if (interpreter_p == NULL) - return; - - /* If we're _the_ interpreter, take control. */ - if (strcmp (interpreter_p, "mi0") == 0) - command_loop_hook = mi0_command_loop; - else if (strcmp (interpreter_p, "mi") == 0 - || strcmp (interpreter_p, "mi1") == 0) - command_loop_hook = mi1_command_loop; - else - return; - - init_ui_hook = mi_init_ui; - setup_architecture_data (); register_gdbarch_swap (&old_regs, sizeof (old_regs), NULL); - register_gdbarch_swap (NULL, 0, setup_architecture_data); - if (event_loop_p) - { - /* These overwrite some of the initialization done in - _intialize_event_loop. */ - call_readline = gdb_readline2; - input_handler = mi_execute_command_wrapper; - add_file_handler (input_fd, stdin_event_handler, 0); - async_command_editing_p = 0; - } - /* FIXME: Should we notify main that we are here as a possible - interpreter? */ + register_gdbarch_swap (NULL, 0, mi_setup_architecture_data); } @@ -63,6 +63,7 @@ #include <ctype.h> #include "ui-out.h" #include "cli-out.h" +#include "interps.h" /* Default command line prompt. This is overriden in some configs. */ @@ -386,6 +387,7 @@ catcher (catch_exceptions_ftype *func, char *saved_error_pre_print; char *saved_quit_pre_print; struct ui_out *saved_uiout; + struct gdb_interpreter *saved_interp; /* Return value from SIGSETJMP(): enum return_reason if error or quit caught, 0 otherwise. */ @@ -408,6 +410,7 @@ catcher (catch_exceptions_ftype *func, /* Override the global ``struct ui_out'' builder. */ saved_uiout = uiout; + saved_interp = gdb_current_interpreter (); uiout = func_uiout; /* Prevent error/quit during FUNC from calling cleanups established @@ -438,7 +441,24 @@ catcher (catch_exceptions_ftype *func, restore_cleanups (saved_cleanup_chain); - uiout = saved_uiout; + /* + cases: + 1. interp1 calls using uiout1 + 2. interp1 calls using uiout1 calls using uiout2 + 3. interp1 calls using uiout1 calls interp2 using uiout2 + 4. more? + is it enough to note that the interpreter has changed and + reset saved_uiout + */ + if (gdb_current_interpreter () == saved_interp) + uiout = saved_uiout; + else + { + /* We've changed interpreters under this call. + Reset uiout to the current interpreter's uiout + and hope for the best. */ + uiout = gdb_interpreter_ui_out (NULL); + } if (mask & RETURN_MASK_QUIT) quit_pre_print = saved_quit_pre_print; @@ -2088,17 +2108,26 @@ gdb_init (char *argv0) init_ui_hook (argv0); /* Install the default UI */ - if (!init_ui_hook) - { - uiout = cli_out_new (gdb_stdout); + /* All the interpreters should have had a look at things by now. + Initialize the selected interpreter. */ + { + struct gdb_interpreter *interp; + if (interpreter_p == NULL) + interpreter_p = xstrdup (GDB_INTERPRETER_CONSOLE); - /* All the interpreters should have had a look at things by now. - Initialize the selected interpreter. */ - if (interpreter_p) - { - fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n", - interpreter_p); - exit (1); - } - } + interp = gdb_lookup_interpreter (interpreter_p); + + if (interp == NULL) + { + fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n", + interpreter_p); + exit (1); + } + if (!gdb_set_interpreter (interp)) + { + fprintf_unfiltered (gdb_stderr, "Interpreter `%s' failed to initialize.\n", + interpreter_p); + exit (1); + } + } } diff --git a/gdb/wrapper.c b/gdb/wrapper.c index 6c9c6d6..4d39008 100644 --- a/gdb/wrapper.c +++ b/gdb/wrapper.c @@ -19,8 +19,9 @@ #include "defs.h" #include "value.h" #include "wrapper.h" +#include "top.h" /* for execute_command */ -/* Use this struct to pass arguments to wrapper routines. We assume +/* use this struct to pass arguments to wrapper routines. We assume (arbitrarily) that no gdb function takes more than ten arguments. */ struct gdb_wrapper_arguments { @@ -51,6 +52,12 @@ struct captured_value_struct_elt_args struct value **result_ptr; }; +struct captured_execute_command_args +{ + char *command; + int from_tty; +}; + static int wrap_parse_exp_1 (char *); static int wrap_evaluate_expression (char *); @@ -331,3 +338,20 @@ do_captured_value_struct_elt (struct ui_out *uiout, void *data) return GDB_RC_OK; } +static int +do_captured_execute_command (struct ui_out *uiout, void *data) +{ + struct captured_execute_command_args *args = data; + execute_command (args->command, args->from_tty); + return GDB_RC_OK; +} + +enum gdb_rc +gdb_execute_command (struct ui_out *uiout, char *command, int from_tty) +{ + struct captured_execute_command_args args; + args.command = command; + args.from_tty = from_tty; + return catch_exceptions (uiout, do_captured_execute_command, &args, + NULL, RETURN_MASK_ALL); +} diff --git a/gdb/wrapper.h b/gdb/wrapper.h index 977a77d..8507274 100644 --- a/gdb/wrapper.h +++ b/gdb/wrapper.h @@ -21,6 +21,10 @@ #include "gdb.h" struct value; +struct block; +struct expression; +struct ui_out; +struct type; /* Use this struct to pass arguments to wrapper routines. */ struct gdb_wrapper_arguments; @@ -46,4 +50,6 @@ extern int gdb_value_ind (struct value *val, struct value ** rval); extern int gdb_parse_and_eval_type (char *, int, struct type **); +extern enum gdb_rc gdb_execute_command (struct ui_out *uiout, char *command, + int from_tty); #endif /* WRAPPER_H */ |