summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2002-05-28 23:47:02 +0000
committerKeith Seitz <keiths@redhat.com>2002-05-28 23:47:02 +0000
commit9102d64fc2e0d586430ee78205f979a79a3cc01b (patch)
treea1d84a52034520345137ba9c2735d5e6477faf7e
parent0d49dda2de4c1fd23c87348f08a022bfd3ee3334 (diff)
downloadbinutils-gdb-9102d64fc2e0d586430ee78205f979a79a3cc01b.tar.gz
Initial check-in of interpreter support from Apple. (Slightly massaged and
modified by me.)
-rw-r--r--gdb/ChangeLog46
-rw-r--r--gdb/Makefile.in38
-rw-r--r--gdb/defs.h1
-rw-r--r--gdb/event-loop.c20
-rw-r--r--gdb/event-top.c53
-rw-r--r--gdb/event-top.h2
-rw-r--r--gdb/main.c6
-rw-r--r--gdb/mi/mi-cmds.c2
-rw-r--r--gdb/mi/mi-cmds.h6
-rw-r--r--gdb/mi/mi-main.c187
-rw-r--r--gdb/top.c55
-rw-r--r--gdb/wrapper.c26
-rw-r--r--gdb/wrapper.h6
13 files changed, 268 insertions, 180 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 35913de558f..6745068e53b 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 da4e25e27b9..64b76f01623 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) \
diff --git a/gdb/defs.h b/gdb/defs.h
index ab66d731182..a83b6e93737 100644
--- a/gdb/defs.h
+++ b/gdb/defs.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 4e42d7e2b62..f0984878665 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 b472694a347..878e769611a 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 24044a57bab..d8c0a963989 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);
diff --git a/gdb/main.c b/gdb/main.c
index 7ef8647c65a..78852115d65 100644
--- a/gdb/main.c
+++ b/gdb/main.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 233d06bded2..0d50d13826f 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 88775e6f961..8c650fc91e1 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 bd8cd67081d..1e9baed91e4 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);
}
diff --git a/gdb/top.c b/gdb/top.c
index 4749c381809..b4026c1895b 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -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 6c9c6d60cef..4d390088032 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 977a77d04cd..85072743f90 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 */