summaryrefslogtreecommitdiff
path: root/gdb/mi/mi-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/mi/mi-main.c')
-rw-r--r--gdb/mi/mi-main.c187
1 files changed, 143 insertions, 44 deletions
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 1e9baed91e4..bd8cd67081d 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -33,7 +33,6 @@
#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() */
@@ -78,25 +77,27 @@ struct ui_file *raw_stdout;
/* The token of the last asynchronous command */
static char *last_async_command;
static char *previous_async_command;
-char *mi_error_message;
+static char *mi_error_message;
static char *old_regs;
extern void _initialize_mi_main (void);
-void mi_execute_command (char *cmd, int from_tty);
+static char *mi_input (char *);
+static 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);
-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);
+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);
/* 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
@@ -1079,12 +1080,7 @@ 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
-
- 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. */
+ /* print the result if there were no errors */
if (args->rc == MI_CMD_DONE)
{
fputs_unfiltered (context->token, raw_stdout);
@@ -1132,21 +1128,15 @@ 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);
-
- /* 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;
- }
+ /* 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;
}
@@ -1161,7 +1151,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;
+ int result, rc;
/* This is to handle EOF (^D). We just quit gdb. */
/* FIXME: we should call some API function here. */
@@ -1199,13 +1189,10 @@ mi_execute_command (char *cmd, int from_tty)
mi_parse_free (command);
}
- if (args.rc != MI_CMD_QUIET)
- {
- fputs_unfiltered ("(gdb) \n", raw_stdout);
- gdb_flush (raw_stdout);
- /* print any buffered hook code */
- /* ..... */
- }
+ fputs_unfiltered ("(gdb) \n", raw_stdout);
+ gdb_flush (raw_stdout);
+ /* print any buffered hook code */
+ /* ..... */
}
static enum mi_cmd_result
@@ -1272,6 +1259,12 @@ 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 */
@@ -1374,7 +1367,13 @@ mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg)
do_exec_cleanups (ALL_CLEANUPS);
}
-void
+static char *
+mi_input (char *buf)
+{
+ return gdb_readline (NULL);
+}
+
+static void
mi_load_progress (const char *section_name,
unsigned long sent_so_far,
unsigned long total_section,
@@ -1386,8 +1385,7 @@ mi_load_progress (const char *section_name,
static char *previous_sect_name = NULL;
int new_section;
- if (!gdb_current_interpreter_is_named (GDB_INTERPRETER_MI)
- && !gdb_current_interpreter_is_named (GDB_INTERPRETER_MI0))
+ if (!interpreter_p || strncmp (interpreter_p, "mi", 2) != 0)
return;
update_threshold.tv_sec = 0;
@@ -1444,17 +1442,118 @@ mi_load_progress (const char *section_name,
}
}
-void
-mi_setup_architecture_data (void)
+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)
{
/* 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
-mi_register_gdbarch_swap (void)
+_initialize_mi_main (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, mi_setup_architecture_data);
+ 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? */
}