forked from Imagelibrary/binutils-gdb
Initial check-in of interpreter support from Apple. (Slightly massaged and
modified by me.)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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
|
||||
|
||||
187
gdb/mi/mi-main.c
187
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);
|
||||
}
|
||||
|
||||
55
gdb/top.c
55
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user