Initial check-in of interpreter support from Apple. (Slightly massaged and

modified by me.)
This commit is contained in:
Keith Seitz
2002-05-28 23:47:02 +00:00
parent 0d49dda2de
commit 9102d64fc2
13 changed files with 268 additions and 180 deletions

View File

@@ -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.

View File

@@ -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) \

View File

@@ -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. */

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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},

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}

View File

@@ -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 */