diff options
Diffstat (limited to 'contrib/gdb/gdb/mi/mi-main.c')
-rw-r--r-- | contrib/gdb/gdb/mi/mi-main.c | 437 |
1 files changed, 202 insertions, 235 deletions
diff --git a/contrib/gdb/gdb/mi/mi-main.c b/contrib/gdb/gdb/mi/mi-main.c index 3a59fc8..c46bf63 100644 --- a/contrib/gdb/gdb/mi/mi-main.c +++ b/contrib/gdb/gdb/mi/mi-main.c @@ -1,5 +1,8 @@ /* MI Command Set. - Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + + Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, + Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. @@ -33,25 +36,47 @@ #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() */ -#include "value.h" /* for write_register_bytes() */ +#include "value.h" /* for deprecated_write_register_bytes() */ #include "regcache.h" #include "gdb.h" +#include "frame.h" +#include "mi-main.h" + #include <ctype.h> #include <sys/time.h> -/* Convenience macro for allocting typesafe memory. */ - -#undef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) - enum { FROM_TTY = 0 }; +/* Enumerations of the actions that may result from calling + captured_mi_execute_command */ + +enum captured_mi_execute_command_actions + { + EXECUTE_COMMAND_DISPLAY_PROMPT, + EXECUTE_COMMAND_SUPRESS_PROMPT, + EXECUTE_COMMAND_DISPLAY_ERROR + }; + +/* This structure is used to pass information from captured_mi_execute_command + to mi_execute_command. */ +struct captured_mi_execute_command_args +{ + /* This return result of the MI command (output) */ + enum mi_cmd_result rc; + + /* What action to perform when the call is finished (output) */ + enum captured_mi_execute_command_actions action; + + /* The command context to be executed (input) */ + struct mi_parse *command; +}; int mi_debug_p; struct ui_file *raw_stdout; @@ -59,33 +84,30 @@ 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 void mi_execute_cli_command (const char *cmd, int args_p, + const 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); - -/* 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 - we pull the plug on the sanitization. */ -extern void interrupt_target_command_wrapper (char *, int); -extern void return_command_wrapper (char *, int); + +/* 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", 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 @@ -161,17 +183,17 @@ mi_cmd_exec_return (char *args, int from_tty) if (*args) /* Call return_command with from_tty argument equal to 0 so as to avoid being queried. */ - return_command_wrapper (args, 0); + return_command (args, 0); else /* Call return_command with from_tty argument equal to 0 so as to avoid being queried. */ - return_command_wrapper (NULL, 0); + return_command (NULL, 0); /* Because we have called return_command with from_tty = 0, we need to print the frame here. */ - show_and_print_stack_frame (selected_frame, - selected_frame_level, - LOC_AND_ADDRESS); + print_stack_frame (deprecated_selected_frame, + frame_relative_level (deprecated_selected_frame), + LOC_AND_ADDRESS); return MI_CMD_DONE; } @@ -197,7 +219,7 @@ mi_cmd_exec_interrupt (char *args, int from_tty) "mi_cmd_exec_interrupt: Inferior not executing."); return MI_CMD_ERROR; } - interrupt_target_command_wrapper (args, from_tty); + interrupt_target_command (args, from_tty); if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("^done", raw_stdout); @@ -226,8 +248,12 @@ mi_cmd_thread_select (char *command, char **argv, int argc) else rc = gdb_thread_select (uiout, argv[0]); - if (rc == GDB_RC_FAIL) + /* RC is enum gdb_rc if it is successful (>=0) + enum return_reason if not (<0). */ + if ((int) rc < 0 && (enum return_reason) rc == RETURN_ERROR) return MI_CMD_CAUGHT_ERROR; + else if ((int) rc >= 0 && rc == GDB_RC_FAIL) + return MI_CMD_ERROR; else return MI_CMD_DONE; } @@ -257,6 +283,7 @@ mi_cmd_data_list_register_names (char *command, char **argv, int argc) { int regnum, numregs; int i; + struct cleanup *cleanup; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of @@ -266,7 +293,7 @@ mi_cmd_data_list_register_names (char *command, char **argv, int argc) numregs = NUM_REGS + NUM_PSEUDO_REGS; - ui_out_list_begin (uiout, "register-names"); + cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-names"); if (argc == 0) /* No args, just do all the regs */ { @@ -288,6 +315,7 @@ mi_cmd_data_list_register_names (char *command, char **argv, int argc) regnum = atoi (argv[i]); if (regnum < 0 || regnum >= numregs) { + do_cleanups (cleanup); xasprintf (&mi_error_message, "bad register number"); return MI_CMD_ERROR; } @@ -297,7 +325,7 @@ mi_cmd_data_list_register_names (char *command, char **argv, int argc) else ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum)); } - ui_out_list_end (uiout); + do_cleanups (cleanup); return MI_CMD_DONE; } @@ -306,6 +334,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) { int regnum, numregs, changed; int i; + struct cleanup *cleanup; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of @@ -315,7 +344,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) numregs = NUM_REGS; - ui_out_list_begin (uiout, "changed-registers"); + cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changed-registers"); if (argc == 0) /* No args, just do all the regs */ { @@ -329,6 +358,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) changed = register_changed_p (regnum); if (changed < 0) { + do_cleanups (cleanup); xasprintf (&mi_error_message, "mi_cmd_data_list_changed_registers: Unable to read register contents."); return MI_CMD_ERROR; @@ -351,6 +381,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) changed = register_changed_p (regnum); if (changed < 0) { + do_cleanups (cleanup); xasprintf (&mi_error_message, "mi_cmd_data_list_register_change: Unable to read register contents."); return MI_CMD_ERROR; @@ -360,30 +391,31 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc) } else { + do_cleanups (cleanup); xasprintf (&mi_error_message, "bad register number"); return MI_CMD_ERROR; } } - ui_out_list_end (uiout); + do_cleanups (cleanup); return MI_CMD_DONE; } static int register_changed_p (int regnum) { - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; - if (read_relative_register_raw_bytes (regnum, raw_buffer)) + if (! frame_register_read (deprecated_selected_frame, regnum, raw_buffer)) return -1; - if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, - REGISTER_RAW_SIZE (regnum)) == 0) + if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (regnum)) == 0) return 0; /* Found a changed register. Return 1. */ - memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, - REGISTER_RAW_SIZE (regnum)); + memcpy (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer, + DEPRECATED_REGISTER_RAW_SIZE (regnum)); return 1; } @@ -400,6 +432,7 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) { int regnum, numregs, format, result; int i; + struct cleanup *list_cleanup, *tuple_cleanup; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of @@ -425,7 +458,7 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) return MI_CMD_ERROR; } - ui_out_list_begin (uiout, "register-values"); + list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values"); if (argc == 1) /* No args, beside the format: do all the regs */ { @@ -436,12 +469,15 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) if (REGISTER_NAME (regnum) == NULL || *(REGISTER_NAME (regnum)) == '\0') continue; - ui_out_tuple_begin (uiout, NULL); + tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_int (uiout, "number", regnum); result = get_register (regnum, format); if (result == -1) - return MI_CMD_ERROR; - ui_out_tuple_end (uiout); + { + do_cleanups (list_cleanup); + return MI_CMD_ERROR; + } + do_cleanups (tuple_cleanup); } } @@ -455,20 +491,24 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) && REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\000') { - ui_out_tuple_begin (uiout, NULL); + tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_int (uiout, "number", regnum); result = get_register (regnum, format); if (result == -1) - return MI_CMD_ERROR; - ui_out_tuple_end (uiout); + { + do_cleanups (list_cleanup); + return MI_CMD_ERROR; + } + do_cleanups (tuple_cleanup); } else { + do_cleanups (list_cleanup); xasprintf (&mi_error_message, "bad register number"); return MI_CMD_ERROR; } } - ui_out_list_end (uiout); + do_cleanups (list_cleanup); return MI_CMD_DONE; } @@ -476,9 +516,12 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc) static int get_register (int regnum, int format) { - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); - char *virtual_buffer = alloca (MAX_REGISTER_VIRTUAL_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; + char virtual_buffer[MAX_REGISTER_SIZE]; int optim; + int realnum; + CORE_ADDR addr; + enum lval_type lval; static struct ui_stream *stb = NULL; stb = ui_out_stream_new (uiout); @@ -486,12 +529,9 @@ get_register (int regnum, int format) if (format == 'N') format = 0; - /* read_relative_register_raw_bytes returns a virtual frame pointer - (FRAME_FP (selected_frame)) if regnum == FP_REGNUM instead - of the real contents of the register. To get around this, - use get_saved_register instead. */ - get_saved_register (raw_buffer, &optim, (CORE_ADDR *) NULL, selected_frame, - regnum, (enum lval_type *) NULL); + frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr, + &realnum, raw_buffer); + if (optim) { xasprintf (&mi_error_message, "Optimized out"); @@ -500,13 +540,15 @@ get_register (int regnum, int format) /* Convert raw data to virtual format if necessary. */ - if (REGISTER_CONVERTIBLE (regnum)) + if (DEPRECATED_REGISTER_CONVERTIBLE_P () + && DEPRECATED_REGISTER_CONVERTIBLE (regnum)) { - REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum), + DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, + register_type (current_gdbarch, regnum), raw_buffer, virtual_buffer); } else - memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum)); + memcpy (virtual_buffer, raw_buffer, DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); if (format == 'r') { @@ -515,10 +557,10 @@ get_register (int regnum, int format) strcpy (buf, "0x"); ptr = buf + 2; - for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++) + for (j = 0; j < DEPRECATED_REGISTER_RAW_SIZE (regnum); j++) { - register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j - : REGISTER_RAW_SIZE (regnum) - 1 - j; + int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j + : DEPRECATED_REGISTER_RAW_SIZE (regnum) - 1 - j; sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]); ptr += 2; } @@ -527,7 +569,7 @@ get_register (int regnum, int format) } else { - val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0, 0, + val_print (register_type (current_gdbarch, regnum), virtual_buffer, 0, 0, stb->stream, format, 1, 0, Val_pretty_default); ui_out_field_stream (uiout, "value", stb); ui_out_stream_delete (stb); @@ -600,11 +642,11 @@ mi_cmd_data_write_register_values (char *command, char **argv, int argc) /* Get the value as a number */ value = parse_and_eval_address (argv[i + 1]); /* Get the value into an array */ - buffer = xmalloc (REGISTER_SIZE); + buffer = xmalloc (DEPRECATED_REGISTER_SIZE); old_chain = make_cleanup (xfree, buffer); - store_signed_integer (buffer, REGISTER_SIZE, value); + store_signed_integer (buffer, DEPRECATED_REGISTER_SIZE, value); /* Write it down */ - write_register_bytes (REGISTER_BYTE (regnum), buffer, REGISTER_RAW_SIZE (regnum)); + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (regnum), buffer, DEPRECATED_REGISTER_RAW_SIZE (regnum)); /* Free the buffer. */ do_cleanups (old_chain); } @@ -887,19 +929,22 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc) /* Build the result as a two dimentional table. */ { struct ui_stream *stream = ui_out_stream_new (uiout); + struct cleanup *cleanup_list_memory; int row; int row_byte; - ui_out_list_begin (uiout, "memory"); + cleanup_list_memory = make_cleanup_ui_out_list_begin_end (uiout, "memory"); for (row = 0, row_byte = 0; row < nr_rows; row++, row_byte += nr_cols * word_size) { int col; int col_byte; - ui_out_tuple_begin (uiout, NULL); + struct cleanup *cleanup_tuple; + struct cleanup *cleanup_list_data; + cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_core_addr (uiout, "addr", addr + row_byte); /* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */ - ui_out_list_begin (uiout, "data"); + cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data"); for (col = 0, col_byte = row_byte; col < nr_cols; col++, col_byte += word_size) @@ -916,7 +961,7 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc) ui_out_field_stream (uiout, NULL, stream); } } - ui_out_list_end (uiout); + do_cleanups (cleanup_list_data); if (aschar) { int byte; @@ -936,10 +981,10 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc) } ui_out_field_stream (uiout, "ascii", stream); } - ui_out_tuple_end (uiout); + do_cleanups (cleanup_tuple); } ui_out_stream_delete (stream); - ui_out_list_end (uiout); + do_cleanups (cleanup_list_memory); } do_cleanups (cleanups); return MI_CMD_DONE; @@ -1034,15 +1079,19 @@ mi_cmd_data_write_memory (char *command, char **argv, int argc) return MI_CMD_DONE; } -/* Execute a command within a safe environment. Return >0 for - ok. Return <0 for supress prompt. Return 0 to have the error - extracted from error_last_message(). */ +/* Execute a command within a safe environment. + Return <0 for error; >=0 for ok. + + args->action will tell mi_execute_command what action + to perfrom after the given command has executed (display/supress + prompt, display error). */ static int -captured_mi_execute_command (void *data) +captured_mi_execute_command (struct ui_out *uiout, void *data) { - struct mi_parse *context = data; - enum mi_cmd_result rc; + struct captured_mi_execute_command_args *args = + (struct captured_mi_execute_command_args *) data; + struct mi_parse *context = args->command; switch (context->op) { @@ -1057,11 +1106,18 @@ captured_mi_execute_command (void *data) condition expression, each function should return an indication of what action is required and then switch on that. */ - rc = mi_cmd_execute (context); + args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; + args->rc = mi_cmd_execute (context); + if (!target_can_async_p () || !target_executing) { - /* print the result if there were no errors */ - if (rc == MI_CMD_DONE) + /* 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); fputs_unfiltered ("^done", raw_stdout); @@ -1069,7 +1125,7 @@ captured_mi_execute_command (void *data) mi_out_rewind (uiout); fputs_unfiltered ("\n", raw_stdout); } - else if (rc == MI_CMD_ERROR) + else if (args->rc == MI_CMD_ERROR) { if (mi_error_message) { @@ -1081,18 +1137,22 @@ captured_mi_execute_command (void *data) } mi_out_rewind (uiout); } - else if (rc == MI_CMD_CAUGHT_ERROR) + else if (args->rc == MI_CMD_CAUGHT_ERROR) { mi_out_rewind (uiout); - return 0; + args->action = EXECUTE_COMMAND_DISPLAY_ERROR; + return 1; } else mi_out_rewind (uiout); } else if (sync_execution) - /* Don't print the prompt. We are executing the target in - synchronous mode. */ - return -1; + { + /* Don't print the prompt. We are executing the target in + synchronous mode. */ + args->action = EXECUTE_COMMAND_SUPRESS_PROMPT; + return 1; + } break; case CLI_COMMAND: @@ -1101,19 +1161,28 @@ captured_mi_execute_command (void *data) mi commands */ /* echo the command on the console. */ fprintf_unfiltered (gdb_stdlog, "%s\n", context->command); - /* 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); + mi_execute_cli_command (context->command, 0, NULL); + + /* If we changed interpreters, DON'T print out anything. */ + if (current_interp_named_p (INTERP_MI) + || current_interp_named_p (INTERP_MI1) + || current_interp_named_p (INTERP_MI2) + || current_interp_named_p (INTERP_MI3)) + { + /* 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; } + return 1; } @@ -1122,6 +1191,9 @@ void 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; /* This is to handle EOF (^D). We just quit gdb. */ /* FIXME: we should call some API function here. */ @@ -1132,18 +1204,20 @@ mi_execute_command (char *cmd, int from_tty) if (command != NULL) { - /* FIXME: cagney/1999-11-04: Can this use of catch_errors either + /* FIXME: cagney/1999-11-04: Can this use of catch_exceptions either be pushed even further down or even eliminated? */ - int rc = catch_errors (captured_mi_execute_command, command, "", - RETURN_MASK_ALL); - if (rc < 0) + args.command = command; + result = catch_exceptions (uiout, captured_mi_execute_command, &args, "", + RETURN_MASK_ALL); + + if (args.action == EXECUTE_COMMAND_SUPRESS_PROMPT) { /* The command is executing synchronously. Bail out early suppressing the finished prompt. */ mi_parse_free (command); return; } - if (rc == 0) + if (args.action == EXECUTE_COMMAND_DISPLAY_ERROR || result < 0) { char *msg = error_last_message (); struct cleanup *cleanup = make_cleanup (xfree, msg); @@ -1206,12 +1280,13 @@ mi_cmd_execute (struct mi_parse *parse) return parse->cmd->args_func (parse->args, 0 /*from_tty */ ); return parse->cmd->argv_func (parse->command, parse->argv, parse->argc); } - else if (parse->cmd->cli != 0) + else if (parse->cmd->cli.cmd != 0) { /* FIXME: DELETE THIS. */ /* The operation is still implemented by a cli command */ /* Must be a synchronous one */ - mi_execute_cli_command (parse->cmd->cli, parse->args); + mi_execute_cli_command (parse->cmd->cli.cmd, parse->cmd->cli.args_p, + parse->args); return MI_CMD_DONE; } else @@ -1227,28 +1302,25 @@ 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 */ void -mi_execute_cli_command (const char *cli, char *args) +mi_execute_cli_command (const char *cmd, int args_p, const char *args) { - if (cli != 0) + if (cmd != 0) { struct cleanup *old_cleanups; char *run; - xasprintf (&run, cli, args); + if (args_p) + xasprintf (&run, "%s %s", cmd, args); + else + run = xstrdup (cmd); if (mi_debug_p) /* FIXME: gdb_???? */ fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n", - cli, run); + cmd, run); old_cleanups = make_cleanup (xfree, run); execute_command ( /*ui */ run, 0 /*from_tty */ ); do_cleanups (old_cleanups); @@ -1335,13 +1407,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, @@ -1353,7 +1419,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; @@ -1373,17 +1440,18 @@ mi_load_progress (const char *section_name, strcmp (previous_sect_name, section_name) : 1); if (new_section) { + struct cleanup *cleanup_tuple; xfree (previous_sect_name); previous_sect_name = xstrdup (section_name); if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("+download", raw_stdout); - ui_out_tuple_begin (uiout, NULL); + cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "section", section_name); ui_out_field_int (uiout, "section-size", total_section); ui_out_field_int (uiout, "total-size", grand_total); - ui_out_tuple_end (uiout); + do_cleanups (cleanup_tuple); mi_out_put (uiout, raw_stdout); fputs_unfiltered ("\n", raw_stdout); gdb_flush (raw_stdout); @@ -1392,136 +1460,35 @@ mi_load_progress (const char *section_name, if (delta.tv_sec >= update_threshold.tv_sec && delta.tv_usec >= update_threshold.tv_usec) { + struct cleanup *cleanup_tuple; last_update.tv_sec = time_now.tv_sec; last_update.tv_usec = time_now.tv_usec; if (last_async_command) fputs_unfiltered (last_async_command, raw_stdout); fputs_unfiltered ("+download", raw_stdout); - ui_out_tuple_begin (uiout, NULL); + cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "section", section_name); ui_out_field_int (uiout, "section-sent", sent_so_far); ui_out_field_int (uiout, "section-size", total_section); ui_out_field_int (uiout, "total-sent", total_sent); ui_out_field_int (uiout, "total-size", grand_total); - ui_out_tuple_end (uiout); + do_cleanups (cleanup_tuple); mi_out_put (uiout, raw_stdout); fputs_unfiltered ("\n", raw_stdout); gdb_flush (raw_stdout); } } -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) +void +mi_setup_architecture_data (void) { - /* Eventually this will contain code that takes control of the - console. */ + old_regs = xmalloc ((NUM_REGS + NUM_PSEUDO_REGS) * MAX_REGISTER_SIZE + 1); + memset (old_regs, 0, (NUM_REGS + NUM_PSEUDO_REGS) * MAX_REGISTER_SIZE + 1); } 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, 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? */ + DEPRECATED_REGISTER_GDBARCH_SWAP (old_regs); + deprecated_register_gdbarch_swap (NULL, 0, mi_setup_architecture_data); } |