/* MI Command Set.
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005 Free Software
+ Foundation, Inc.
+
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
#include "target.h"
#include "inferior.h"
#include "gdb_string.h"
+#include "exceptions.h"
#include "top.h"
#include "gdbthread.h"
#include "mi-cmds.h"
#include "regcache.h"
#include "gdb.h"
#include "frame.h"
+#include "mi-main.h"
#include <ctype.h>
#include <sys/time.h>
enum captured_mi_execute_command_actions
{
EXECUTE_COMMAND_DISPLAY_PROMPT,
- EXECUTE_COMMAND_SUPRESS_PROMPT,
- EXECUTE_COMMAND_DISPLAY_ERROR
+ EXECUTE_COMMAND_SUPRESS_PROMPT
};
/* This structure is used to pass information from captured_mi_execute_command
extern void _initialize_mi_main (void);
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_exec_async_cli_cmd_continuation (struct continuation_arg *arg);
static int register_changed_p (int regnum);
static int get_register (int regnum, int format);
-/* 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
formalized. */
/* Because we have called return_command with from_tty = 0, we need
to print the frame here. */
- print_stack_frame (deprecated_selected_frame,
- frame_relative_level (deprecated_selected_frame),
- LOC_AND_ADDRESS);
+ print_stack_frame (get_selected_frame (NULL), 1, LOC_AND_ADDRESS);
return MI_CMD_DONE;
}
{
if (!target_executing)
{
- xasprintf (&mi_error_message,
- "mi_cmd_exec_interrupt: Inferior not executing.");
+ mi_error_message = xstrprintf ("mi_cmd_exec_interrupt: Inferior not executing.");
return MI_CMD_ERROR;
}
interrupt_target_command (args, from_tty);
if (argc != 1)
{
- xasprintf (&mi_error_message,
- "mi_cmd_thread_select: USAGE: threadnum.");
+ mi_error_message = xstrprintf ("mi_cmd_thread_select: USAGE: threadnum.");
return MI_CMD_ERROR;
}
else
- rc = gdb_thread_select (uiout, argv[0]);
+ rc = gdb_thread_select (uiout, argv[0], &mi_error_message);
/* 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;
+ return MI_CMD_ERROR;
else if ((int) rc >= 0 && rc == GDB_RC_FAIL)
return MI_CMD_ERROR;
else
if (argc != 0)
{
- xasprintf (&mi_error_message,
- "mi_cmd_thread_list_ids: No arguments required.");
+ mi_error_message = xstrprintf ("mi_cmd_thread_list_ids: No arguments required.");
return MI_CMD_ERROR;
}
else
- rc = gdb_list_thread_ids (uiout);
+ rc = gdb_list_thread_ids (uiout, &mi_error_message);
if (rc == GDB_RC_FAIL)
- return MI_CMD_CAUGHT_ERROR;
+ return MI_CMD_ERROR;
else
return MI_CMD_DONE;
}
if (regnum < 0 || regnum >= numregs)
{
do_cleanups (cleanup);
- xasprintf (&mi_error_message, "bad register number");
+ mi_error_message = xstrprintf ("bad register number");
return MI_CMD_ERROR;
}
if (REGISTER_NAME (regnum) == NULL
case, some entries of REGISTER_NAME will change depending upon
the particular processor being debugged. */
- numregs = NUM_REGS;
+ numregs = NUM_REGS + NUM_PSEUDO_REGS;
cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changed-registers");
if (changed < 0)
{
do_cleanups (cleanup);
- xasprintf (&mi_error_message,
- "mi_cmd_data_list_changed_registers: Unable to read register contents.");
+ mi_error_message = xstrprintf ("mi_cmd_data_list_changed_registers: Unable to read register contents.");
return MI_CMD_ERROR;
}
else if (changed)
if (changed < 0)
{
do_cleanups (cleanup);
- xasprintf (&mi_error_message,
- "mi_cmd_data_list_register_change: Unable to read register contents.");
+ mi_error_message = xstrprintf ("mi_cmd_data_list_register_change: Unable to read register contents.");
return MI_CMD_ERROR;
}
else if (changed)
else
{
do_cleanups (cleanup);
- xasprintf (&mi_error_message, "bad register number");
+ mi_error_message = xstrprintf ("bad register number");
return MI_CMD_ERROR;
}
}
static int
register_changed_p (int regnum)
{
- char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+ char raw_buffer[MAX_REGISTER_SIZE];
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,
+ register_size (current_gdbarch, 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,
+ register_size (current_gdbarch, regnum));
return 1;
}
case, some entries of REGISTER_NAME will change depending upon
the particular processor being debugged. */
- numregs = NUM_REGS;
+ numregs = NUM_REGS + NUM_PSEUDO_REGS;
if (argc == 0)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> [<regnum1>...<regnumN>]");
+ mi_error_message = xstrprintf ("mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> [<regnum1>...<regnumN>]");
return MI_CMD_ERROR;
}
if (!target_has_registers)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_list_register_values: No registers.");
+ mi_error_message = xstrprintf ("mi_cmd_data_list_register_values: No registers.");
return MI_CMD_ERROR;
}
else
{
do_cleanups (list_cleanup);
- xasprintf (&mi_error_message, "bad register number");
+ mi_error_message = xstrprintf ("bad register number");
return MI_CMD_ERROR;
}
}
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 buffer[MAX_REGISTER_SIZE];
int optim;
int realnum;
CORE_ADDR addr;
format = 0;
frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr,
- &realnum, raw_buffer);
+ &realnum, buffer);
if (optim)
{
- xasprintf (&mi_error_message, "Optimized out");
+ mi_error_message = xstrprintf ("Optimized out");
return -1;
}
- /* Convert raw data to virtual format if necessary. */
-
- if (REGISTER_CONVERTIBLE (regnum))
- {
- REGISTER_CONVERT_TO_VIRTUAL (regnum,
- register_type (current_gdbarch, regnum),
- raw_buffer, virtual_buffer);
- }
- else
- memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
-
if (format == 'r')
{
int j;
strcpy (buf, "0x");
ptr = buf + 2;
- for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
+ for (j = 0; j < register_size (current_gdbarch, regnum); j++)
{
- register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
- : REGISTER_RAW_SIZE (regnum) - 1 - j;
- sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]);
+ int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
+ : register_size (current_gdbarch, regnum) - 1 - j;
+ sprintf (ptr, "%02x", (unsigned char) buffer[idx]);
ptr += 2;
}
ui_out_field_string (uiout, "value", buf);
}
else
{
- val_print (register_type (current_gdbarch, regnum), virtual_buffer, 0, 0,
+ val_print (register_type (current_gdbarch, regnum), buffer, 0, 0,
stb->stream, format, 1, 0, Val_pretty_default);
ui_out_field_stream (uiout, "value", stb);
ui_out_stream_delete (stb);
case, some entries of REGISTER_NAME will change depending upon
the particular processor being debugged. */
- numregs = NUM_REGS;
+ numregs = NUM_REGS + NUM_PSEUDO_REGS;
if (argc == 0)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_write_register_values: Usage: -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]");
+ mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Usage: -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]");
return MI_CMD_ERROR;
}
if (!target_has_registers)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_write_register_values: No registers.");
+ mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No registers.");
return MI_CMD_ERROR;
}
if (!(argc - 1))
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_write_register_values: No regs and values specified.");
+ mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No regs and values specified.");
return MI_CMD_ERROR;
}
if ((argc - 1) % 2)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_write_register_values: Regs and vals are not in pairs.");
+ mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Regs and vals are not in pairs.");
return MI_CMD_ERROR;
}
/* 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 */
- deprecated_write_register_bytes (REGISTER_BYTE (regnum), buffer, REGISTER_RAW_SIZE (regnum));
+ deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (regnum), buffer, register_size (current_gdbarch, regnum));
/* Free the buffer. */
do_cleanups (old_chain);
}
else
{
- xasprintf (&mi_error_message, "bad register number");
+ mi_error_message = xstrprintf ("bad register number");
return MI_CMD_ERROR;
}
}
if (argc != 1)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_assign: Usage: -data-assign expression");
+ mi_error_message = xstrprintf ("mi_cmd_data_assign: Usage: -data-assign expression");
return MI_CMD_ERROR;
}
if (argc != 1)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_evaluate_expression: Usage: -data-evaluate-expression expression");
+ mi_error_message = xstrprintf ("mi_cmd_data_evaluate_expression: Usage: -data-evaluate-expression expression");
return MI_CMD_ERROR;
}
val = evaluate_expression (expr);
/* Print the result of the expression evaluation. */
- val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
- VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
+ val_print (value_type (val), value_contents (val),
+ value_embedded_offset (val), VALUE_ADDRESS (val),
stb->stream, 0, 0, 0, 0);
ui_out_field_stream (uiout, "value", stb);
char *run;
struct cleanup *old_cleanups = NULL;
- xasprintf (&run, "load %s", args);
+ run = xstrprintf ("load %s", args);
old_cleanups = make_cleanup (xfree, run);
execute_command (run, from_tty);
char *run;
struct cleanup *old_cleanups = NULL;
- xasprintf (&run, "target %s", args);
+ run = xstrprintf ("target %s", args);
old_cleanups = make_cleanup (xfree, run);
/* target-select is always synchronous. once the call has returned
if (argc < 5 || argc > 6)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR].");
+ mi_error_message = xstrprintf ("mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR].");
return MI_CMD_ERROR;
}
nr_rows = atol (argv[3]);
if (nr_rows <= 0)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_read_memory: invalid number of rows.");
+ mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of rows.");
return MI_CMD_ERROR;
}
/* number of bytes per row. */
nr_cols = atol (argv[4]);
if (nr_cols <= 0)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_read_memory: invalid number of columns.");
+ mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of columns.");
+ return MI_CMD_ERROR;
}
/* The un-printable character when printing ascii. */
if (argc == 6)
total_bytes = word_size * nr_rows * nr_cols;
mbuf = xcalloc (total_bytes, 1);
make_cleanup (xfree, mbuf);
- if (mbuf == NULL)
- {
- xasprintf (&mi_error_message,
- "mi_cmd_data_read_memory: out of memory.");
- return MI_CMD_ERROR;
- }
nr_bytes = 0;
while (nr_bytes < total_bytes)
{
if (argc != 4)
{
- xasprintf (&mi_error_message,
- "mi_cmd_data_write_memory: Usage: [-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE.");
+ mi_error_message = xstrprintf ("mi_cmd_data_write_memory: Usage: [-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE.");
return MI_CMD_ERROR;
}
to perfrom after the given command has executed (display/supress
prompt, display error). */
-static int
+static void
captured_mi_execute_command (struct ui_out *uiout, void *data)
{
struct captured_mi_execute_command_args *args =
}
mi_out_rewind (uiout);
}
- else if (args->rc == MI_CMD_CAUGHT_ERROR)
- {
- mi_out_rewind (uiout);
- args->action = EXECUTE_COMMAND_DISPLAY_ERROR;
- return 1;
- }
else
mi_out_rewind (uiout);
}
/* Don't print the prompt. We are executing the target in
synchronous mode. */
args->action = EXECUTE_COMMAND_SUPRESS_PROMPT;
- return 1;
+ return;
}
break;
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);
+ 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_MI1)
+ || current_interp_named_p (INTERP_MI2)
+ || current_interp_named_p (INTERP_MI3))
{
/* print the result */
/* FIXME: Check for errors here. */
}
- return 1;
+ return;
}
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. */
if (command != NULL)
{
+ struct exception result;
/* FIXME: cagney/1999-11-04: Can this use of catch_exceptions either
be pushed even further down or even eliminated? */
args.command = command;
- result = catch_exceptions (uiout, captured_mi_execute_command, &args, "",
- RETURN_MASK_ALL);
+ result = catch_exception (uiout, captured_mi_execute_command, &args,
+ RETURN_MASK_ALL);
+ exception_print (gdb_stderr, result);
if (args.action == EXECUTE_COMMAND_SUPRESS_PROMPT)
{
mi_parse_free (command);
return;
}
- if (args.action == EXECUTE_COMMAND_DISPLAY_ERROR || result < 0)
+ if (result.reason < 0)
{
- char *msg = error_last_message ();
- struct cleanup *cleanup = make_cleanup (xfree, msg);
/* The command execution failed and error() was called
somewhere */
fputs_unfiltered (command->token, raw_stdout);
fputs_unfiltered ("^error,msg=\"", raw_stdout);
- fputstr_unfiltered (msg, '"', raw_stdout);
+ fputstr_unfiltered (result.message, '"', raw_stdout);
fputs_unfiltered ("\"\n", raw_stdout);
}
mi_parse_free (command);
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
/* 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)
+ run = xstrprintf ("%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);
make_exec_cleanup (free, async_args);
strcpy (async_args, args);
strcat (async_args, "&");
- xasprintf (&run, "%s %s", mi, async_args);
+ run = xstrprintf ("%s %s", mi, async_args);
make_exec_cleanup (free, run);
add_continuation (mi_exec_async_cli_cmd_continuation, NULL);
old_cleanups = NULL;
}
else
{
- xasprintf (&run, "%s %s", mi, args);
+ run = xstrprintf ("%s %s", mi, args);
old_cleanups = make_cleanup (xfree, run);
}
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);
+ 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)
{
- register_gdbarch_swap (&old_regs, sizeof (old_regs), NULL);
- register_gdbarch_swap (NULL, 0, mi_setup_architecture_data);
+ DEPRECATED_REGISTER_GDBARCH_SWAP (old_regs);
+ deprecated_register_gdbarch_swap (NULL, 0, mi_setup_architecture_data);
}