From 80a2f61f2cc79e25cf106f44fa958218cffc0bb8 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Thu, 6 Feb 2003 01:19:12 +0000 Subject: 2003-02-05 Jim Ingham Keith Seitz Elena Zannoni Andrew Cagney * Makefile.in (SUBDIR_CLI_OBS): Add "cli-interp.o". (SUBDIR_CLI_SRCS): Add "cli/cli-interp.c". (SUBDIR_MI_OBS): Add "mi-interp.o". (SUBDIR_MI_SRCS): Add "mi/mi-interp.c". (SFILES): Add "interps.c". (COMMON_OBS): Add "interps.o". (interps_h, mi_main_h): Define. (interps.o, cli-interp.o, mi-interp.o): Add dependencies. (mi-main.o, main.o, event-top.o): Update dependencies. * cli/cli-interp.c: New file. * interps.h, interps.c: New files. * top.c: (gdb_init): Don't install the default interpreter, handed by captured_main. * main.c: Include "interps.h". (interpreter_p): Note that it should malloc'ed. (captured_command_loop): Call current_interp_command_loop. (captured_main): Initialize interpreter_p to INTERP_CONSOLE. Use xfree and xstrdup when updating interpreter_p. Install the default interpreter. Add hack to stop mi1's copyright notice being encoded. * event-top.h (gdb_setup_readline): Declare. (gdb_disable_readline): Declare. * event-top.c: Include "interps.h". (display_gdb_prompt): Call current_interp_display_prompt_p. (gdb_setup_readline): Initialize gdb_stdout, gdb_stderr, gdb_stdlog, and gdb_stdtarg. (_initialize_event_loop): Don't call gdb_setup_readline. * cli-out.c (cli_out_set_stream): New function. * cli-out.h (cli_out_set_stream): Declare. --- gdb/mi/ChangeLog | 31 ++++++++- gdb/mi/mi-cmds.c | 7 +- gdb/mi/mi-cmds.h | 11 ++- gdb/mi/mi-console.c | 18 +++-- gdb/mi/mi-console.h | 4 +- gdb/mi/mi-main.c | 193 +++++++++++----------------------------------------- 6 files changed, 102 insertions(+), 162 deletions(-) (limited to 'gdb/mi') diff --git a/gdb/mi/ChangeLog b/gdb/mi/ChangeLog index 58a1ce95af9..e79398c15a7 100644 --- a/gdb/mi/ChangeLog +++ b/gdb/mi/ChangeLog @@ -1,3 +1,33 @@ +2003-02-04 Jim Ingham + Keith Seitz + Elena Zannoni + Andrew Cagney + + * mi-main.h: New file. + * mi-interp.c: New file. + * mi-main.c: Include "interps.h". + (mi_error_message): Make global. + (mi_input): Delete static function, moved to "mi-interp.c". + (mi_execute_command, mi_execute_command_wrapper): Ditto. + (mi_command_loop, mi1_command_loop, mi2_command_loop): Ditto. + (mi_load_progress): Make non-static. + (mi_error_last_message): New function. + (captured_mi_execute_command): If the interpreter changed, don't + print anything. + (mi_load_progress): Use current_interp_named_p. + (mi_init_ui): Delete function. + (_initialize_mi_main): Don't install the mi interpreter, handled + by "mi-interp.c". + (mi_exec_async_cli_cmd_continuation): Make static. + * mi-console.h (mi_console_file_new): Add `quote' parameter. + * mi-console.c (struct mi_console_file): Add `quote'. + (mi_console_file_new): Add `quote' parameter. Initialize `quote'. + (mi_console_raw_packet): Only quote the output when `quote'. + * mi-cmds.h (mi_cmd_interpreter_exec): Declare. + (mi_error_message, mi_error_last_message): Declare. + (mi_execute_command): Declare. + * mi-cmds.c: Add `interpreter-exec' command. + 2003-02-04 Andrew Cagney From Keith Seitz : @@ -144,7 +174,6 @@ 2002-07-29 Andrew Cagney - * mi-cmd-var.c: Include "gdb_string.h". * mi-cmd-disas.c: Ditto. diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 699937d0ff2..5a0bf50754e 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -1,5 +1,7 @@ -/* MI Command Set. - Copyright 2000, 2001 Free Software Foundation, Inc. +/* MI Command Set for GDB, the GNU debugger. + + Copyright 2000, 2001, 2003 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -88,6 +90,7 @@ struct mi_cmd mi_cmds[] = {"gdb-show", "show %s", 0}, {"gdb-source", 0, 0}, {"gdb-version", "show version", 0}, + {"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 f4fe64d279e..3eb6153694e 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -1,5 +1,7 @@ -/* MI Command Set. - Copyright 2000 Free Software Foundation, Inc. +/* MI Command Set for GDB, the GNU debugger. + + Copyright 2000, 2003 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -79,6 +81,7 @@ 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_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; @@ -126,4 +129,8 @@ 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; +extern void mi_error_last_message (void); +extern void mi_execute_command (char *cmd, int from_tty); + #endif diff --git a/gdb/mi/mi-console.c b/gdb/mi/mi-console.c index c1b6e9f7b33..aca008640fd 100644 --- a/gdb/mi/mi-console.c +++ b/gdb/mi/mi-console.c @@ -37,13 +37,14 @@ struct mi_console_file struct ui_file *raw; struct ui_file *buffer; const char *prefix; + char quote; }; int mi_console_file_magic; struct ui_file * mi_console_file_new (struct ui_file *raw, - const char *prefix) + const char *prefix, char quote) { struct ui_file *ui_file = ui_file_new (); struct mi_console_file *mi_console = XMALLOC (struct mi_console_file); @@ -51,6 +52,7 @@ mi_console_file_new (struct ui_file *raw, mi_console->raw = raw; mi_console->buffer = mem_fileopen (); mi_console->prefix = prefix; + mi_console->quote = quote; set_ui_file_fputs (ui_file, mi_console_file_fputs); set_ui_file_flush (ui_file, mi_console_file_flush); set_ui_file_data (ui_file, mi_console, mi_console_file_delete); @@ -96,9 +98,17 @@ mi_console_raw_packet (void *data, if (length_buf > 0) { fputs_unfiltered (mi_console->prefix, mi_console->raw); - fputs_unfiltered ("\"", mi_console->raw); - fputstrn_unfiltered (buf, length_buf, '"', mi_console->raw); - fputs_unfiltered ("\"\n", mi_console->raw); + if (mi_console->quote) + { + fputs_unfiltered ("\"", mi_console->raw); + fputstrn_unfiltered (buf, length_buf, mi_console->quote, mi_console->raw); + fputs_unfiltered ("\"\n", mi_console->raw); + } + else + { + fputstrn_unfiltered (buf, length_buf, 0, mi_console->raw); + fputs_unfiltered ("\n", mi_console->raw); + } gdb_flush (mi_console->raw); } } diff --git a/gdb/mi/mi-console.h b/gdb/mi/mi-console.h index 6bd03cbd924..bc6c0085398 100644 --- a/gdb/mi/mi-console.h +++ b/gdb/mi/mi-console.h @@ -22,6 +22,8 @@ #ifndef MI_CONSOLE_H #define MI_CONSOLE_H -extern struct ui_file *mi_console_file_new (struct ui_file *raw, const char *prefix); +extern struct ui_file *mi_console_file_new (struct ui_file *raw, + const char *prefix, + char quote); #endif diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 96030b71ab6..8a54108bca4 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() */ @@ -79,27 +80,29 @@ 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); 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 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); + +/* A helper function which will set mi_error_message to + error_last_message. */ +void +mi_error_last_message (void) +{ + char *s = error_last_message (); + xasprintf (&mi_error_message, s); + xfree (s); +} /* Command implementations. FIXME: Is this libgdb? No. This is the MI layer that calls libgdb. Any operation used in the below should be @@ -1098,7 +1101,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); @@ -1146,15 +1154,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 (current_interp_named_p (INTERP_MI) + || current_interp_named_p (INTERP_MI1)) + { + /* 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; } @@ -1169,7 +1183,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. */ @@ -1277,12 +1291,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 */ @@ -1385,13 +1393,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, @@ -1403,7 +1405,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 (!current_interp_named_p (INTERP_MI) + && !current_interp_named_p (INTERP_MI1)) return; update_threshold.tv_sec = 0; @@ -1462,131 +1465,17 @@ mi_load_progress (const char *section_name, } } -static void -mi_command_loop (int mi_version) -{ - if (mi_version <= 1) - { - /* 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 -mi1_command_loop (void) -{ - mi_command_loop (1); -} - -static void -mi2_command_loop (void) -{ - mi_command_loop (2); -} - -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) -{ - if (strlen (interpreter_p) <= 2 || - interpreter_p[2] > '1') - { - /* 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, "~"); - } -} - void _initialize_mi_main (void) { - if (interpreter_p == NULL) - return; - - /* If we're _the_ interpreter, take control. */ - if (strcmp (interpreter_p, "mi") == 0) - command_loop_hook = mi2_command_loop; - else if (strcmp (interpreter_p, "mi1") == 0) - command_loop_hook = mi1_command_loop; - else if (strcmp (interpreter_p, "mi2") == 0) - command_loop_hook = mi2_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); } -- cgit v1.2.1