summaryrefslogtreecommitdiffstats
path: root/contrib/gdb/gdb/mi
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gdb/gdb/mi')
-rw-r--r--contrib/gdb/gdb/mi/mi-cmd-break.c5
-rw-r--r--contrib/gdb/gdb/mi/mi-cmd-disas.c368
-rw-r--r--contrib/gdb/gdb/mi/mi-cmd-env.c259
-rw-r--r--contrib/gdb/gdb/mi/mi-cmd-file.c67
-rw-r--r--contrib/gdb/gdb/mi/mi-cmd-stack.c106
-rw-r--r--contrib/gdb/gdb/mi/mi-cmd-var.c87
-rw-r--r--contrib/gdb/gdb/mi/mi-cmds.c266
-rw-r--r--contrib/gdb/gdb/mi/mi-cmds.h53
-rw-r--r--contrib/gdb/gdb/mi/mi-console.c27
-rw-r--r--contrib/gdb/gdb/mi/mi-console.h4
-rw-r--r--contrib/gdb/gdb/mi/mi-getopt.c16
-rw-r--r--contrib/gdb/gdb/mi/mi-getopt.h20
-rw-r--r--contrib/gdb/gdb/mi/mi-interp.c406
-rw-r--r--contrib/gdb/gdb/mi/mi-main.c437
-rw-r--r--contrib/gdb/gdb/mi/mi-main.h33
-rw-r--r--contrib/gdb/gdb/mi/mi-out.c115
-rw-r--r--contrib/gdb/gdb/mi/mi-out.h3
-rw-r--r--contrib/gdb/gdb/mi/mi-parse.c14
-rw-r--r--contrib/gdb/gdb/mi/mi-symbol-cmds.c67
19 files changed, 1458 insertions, 895 deletions
diff --git a/contrib/gdb/gdb/mi/mi-cmd-break.c b/contrib/gdb/gdb/mi/mi-cmd-break.c
index 5061392..5d15aa9 100644
--- a/contrib/gdb/gdb/mi/mi-cmd-break.c
+++ b/contrib/gdb/gdb/mi/mi-cmd-break.c
@@ -29,11 +29,6 @@
#include "gdb-events.h"
#include "gdb.h"
-/* Convenience macro for allocting typesafe memory. */
-
-#undef XMALLOC
-#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
-
enum
{
FROM_TTY = 0
diff --git a/contrib/gdb/gdb/mi/mi-cmd-disas.c b/contrib/gdb/gdb/mi/mi-cmd-disas.c
index 7596c06..168ca17 100644
--- a/contrib/gdb/gdb/mi/mi-cmd-disas.c
+++ b/contrib/gdb/gdb/mi/mi-cmd-disas.c
@@ -24,67 +24,9 @@
#include "value.h"
#include "mi-cmds.h"
#include "mi-getopt.h"
+#include "gdb_string.h"
#include "ui-out.h"
-
-static int gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, unsigned int len,
- disassemble_info * info);
-static int compare_lines (const PTR mle1p, const PTR mle2p);
-
-/* Disassemble functions. FIXME: these do not really belong here. We
- should get rid of all the duplicate code in gdb that does the same
- thing: disassemble_command() and the gdbtk variation. */
-
-/* This Structure is used in mi_cmd_disassemble.
- We need a different sort of line table from the normal one cuz we can't
- depend upon implicit line-end pc's for lines to do the
- reordering in this function. */
-
-struct dis_line_entry
- {
- int line;
- CORE_ADDR start_pc;
- CORE_ADDR end_pc;
- };
-
-/* This variable determines where memory used for disassembly is read from. */
-int gdb_disassemble_from_exec = -1;
-
-/* This is the memory_read_func for gdb_disassemble when we are
- disassembling from the exec file. */
-static int
-gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr,
- unsigned int len, disassemble_info * info)
-{
- extern struct target_ops exec_ops;
- int res;
-
- errno = 0;
- res = xfer_memory (memaddr, myaddr, len, 0, 0, &exec_ops);
-
- if (res == len)
- return 0;
- else if (errno == 0)
- return EIO;
- else
- return errno;
-}
-
-static int
-compare_lines (const PTR mle1p, const PTR mle2p)
-{
- struct dis_line_entry *mle1, *mle2;
- int val;
-
- mle1 = (struct dis_line_entry *) mle1p;
- mle2 = (struct dis_line_entry *) mle2p;
-
- val = mle1->line - mle2->line;
-
- if (val != 0)
- return val;
-
- return mle1->start_pc - mle2->start_pc;
-}
+#include "disasm.h"
/* The arguments to be passed on the command line and parsed here are:
@@ -106,30 +48,15 @@ compare_lines (const PTR mle1p, const PTR mle2p)
MODE: 0 or 1 for disassembly only, or mixed source and disassembly,
respectively. */
-
enum mi_cmd_result
mi_cmd_disassemble (char *command, char **argv, int argc)
{
- CORE_ADDR pc;
+ enum mi_cmd_result retval;
CORE_ADDR start;
int mixed_source_and_assembly;
- int num_displayed;
- static disassemble_info di;
- static int di_initialized;
-
struct symtab *s;
- /* To collect the instruction outputted from opcodes. */
- static struct ui_stream *stb = NULL;
-
- /* parts of the symbolic representation of the address */
- int line;
- int offset;
- int unmapped;
- char *filename = NULL;
- char *name = NULL;
-
/* Which options have we processed ... */
int file_seen = 0;
int line_seen = 0;
@@ -148,11 +75,10 @@ mi_cmd_disassemble (char *command, char **argv, int argc)
int optind = 0;
char *optarg;
enum opt
- {
- FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT
- };
- static struct mi_opt opts[] =
{
+ FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT
+ };
+ static struct mi_opt opts[] = {
{"f", FILE_OPT, 1},
{"l", LINE_OPT, 1},
{"n", NUM_OPT, 1},
@@ -201,16 +127,19 @@ mi_cmd_disassemble (char *command, char **argv, int argc)
if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen)
|| (line_seen && file_seen && !num_seen && !start_seen && !end_seen)
- || (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
- error ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode.");
+ || (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
+ error
+ ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode.");
if (argc != 1)
- error ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode.");
+ error
+ ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode.");
mixed_source_and_assembly = atoi (argv[0]);
if ((mixed_source_and_assembly != 0) && (mixed_source_and_assembly != 1))
error ("mi_cmd_disassemble: Mixed_mode argument must be 0 or 1.");
+
/* We must get the function beginning and end where line_num is
contained. */
@@ -225,275 +154,10 @@ mi_cmd_disassemble (char *command, char **argv, int argc)
error ("mi_cmd_disassemble: No function contains specified address");
}
- if (!di_initialized)
- {
- /* We don't add a cleanup for this, because the allocation of
- the stream is done once only for each gdb run, and we need to
- keep it around until the end. Hopefully there won't be any
- errors in the init code below, that make this function bail
- out. */
- stb = ui_out_stream_new (uiout);
- INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
- (fprintf_ftype) fprintf_unfiltered);
- di.flavour = bfd_target_unknown_flavour;
- di.memory_error_func = dis_asm_memory_error;
- di.print_address_func = dis_asm_print_address;
- di_initialized = 1;
- }
-
- di.mach = TARGET_PRINT_INSN_INFO->mach;
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- di.endian = BFD_ENDIAN_BIG;
- else
- di.endian = BFD_ENDIAN_LITTLE;
-
- /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
- determine whether or not to do disassembly from target memory or from the
- exec file:
-
- If we're debugging a local process, read target memory, instead of the
- exec file. This makes disassembly of functions in shared libs work
- correctly. Also, read target memory if we are debugging native threads.
-
- Else, we're debugging a remote process, and should disassemble from the
- exec file for speed. However, this is no good if the target modifies its
- code (for relocation, or whatever).
- */
-
- if (gdb_disassemble_from_exec == -1)
- {
- if (strcmp (target_shortname, "child") == 0
- || strcmp (target_shortname, "procfs") == 0
- || strcmp (target_shortname, "vxprocess") == 0
- || strstr (target_shortname, "-threads") != NULL)
- gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */
- else
- gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */
- }
-
- if (gdb_disassemble_from_exec)
- di.read_memory_func = gdb_dis_asm_read_memory;
- else
- di.read_memory_func = dis_asm_read_memory;
-
- /* If just doing straight assembly, all we need to do is disassemble
- everything between low and high. If doing mixed source/assembly,
- we've got a totally different path to follow. */
-
- if (mixed_source_and_assembly)
- {
- /* Come here for mixed source/assembly */
- /* The idea here is to present a source-O-centric view of a
- function to the user. This means that things are presented
- in source order, with (possibly) out of order assembly
- immediately following. */
- struct symtab *symtab;
- struct linetable_entry *le;
- int nlines;
- int newlines;
- struct dis_line_entry *mle;
- struct symtab_and_line sal;
- int i;
- int out_of_order;
- int next_line;
-
- /* Assume symtab is valid for whole PC range */
- symtab = find_pc_symtab (low);
-
- if (!symtab || !symtab->linetable)
- goto assembly_only;
-
- /* First, convert the linetable to a bunch of my_line_entry's. */
-
- le = symtab->linetable->item;
- nlines = symtab->linetable->nitems;
-
- if (nlines <= 0)
- goto assembly_only;
-
- mle = (struct dis_line_entry *) alloca (nlines * sizeof (struct dis_line_entry));
-
- out_of_order = 0;
-
- /* Copy linetable entries for this function into our data
- structure, creating end_pc's and setting out_of_order as
- appropriate. */
-
- /* First, skip all the preceding functions. */
-
- for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
-
- /* Now, copy all entries before the end of this function. */
-
- newlines = 0;
- for (; i < nlines - 1 && le[i].pc < high; i++)
- {
- if (le[i].line == le[i + 1].line
- && le[i].pc == le[i + 1].pc)
- continue; /* Ignore duplicates */
-
- /* Skip any end-of-function markers. */
- if (le[i].line == 0)
- continue;
-
- mle[newlines].line = le[i].line;
- if (le[i].line > le[i + 1].line)
- out_of_order = 1;
- mle[newlines].start_pc = le[i].pc;
- mle[newlines].end_pc = le[i + 1].pc;
- newlines++;
- }
-
- /* If we're on the last line, and it's part of the function,
- then we need to get the end pc in a special way. */
-
- if (i == nlines - 1
- && le[i].pc < high)
- {
- mle[newlines].line = le[i].line;
- mle[newlines].start_pc = le[i].pc;
- sal = find_pc_line (le[i].pc, 0);
- mle[newlines].end_pc = sal.end;
- newlines++;
- }
-
- /* Now, sort mle by line #s (and, then by addresses within
- lines). */
-
- if (out_of_order)
- qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
-
- /* Now, for each line entry, emit the specified lines (unless
- they have been emitted before), followed by the assembly code
- for that line. */
-
- next_line = 0; /* Force out first line */
- ui_out_list_begin (uiout, "asm_insns");
- num_displayed = 0;
- for (i = 0; i < newlines; i++)
- {
- int close_list = 1;
- /* Print out everything from next_line to the current line. */
- if (mle[i].line >= next_line)
- {
- if (next_line != 0)
- {
- /* Just one line to print. */
- if (next_line == mle[i].line)
- {
- ui_out_tuple_begin (uiout, "src_and_asm_line");
- print_source_lines (symtab, next_line, mle[i].line + 1, 0);
- }
- else
- {
- /* Several source lines w/o asm instructions associated. */
- for (; next_line < mle[i].line; next_line++)
- {
- ui_out_tuple_begin (uiout, "src_and_asm_line");
- print_source_lines (symtab, next_line, mle[i].line + 1, 0);
- ui_out_list_begin (uiout, "line_asm_insn");
- ui_out_list_end (uiout);
- ui_out_tuple_end (uiout);
- }
- /* Print the last line and leave list open for
- asm instructions to be added. */
- ui_out_tuple_begin (uiout, "src_and_asm_line");
- print_source_lines (symtab, next_line, mle[i].line + 1, 0);
- }
- }
- else
- {
- ui_out_tuple_begin (uiout, "src_and_asm_line");
- print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
- }
-
- next_line = mle[i].line + 1;
- ui_out_list_begin (uiout, "line_asm_insn");
- if (i + 1 < newlines && mle[i + 1].line <= mle[i].line)
- close_list = 0;
- }
- for (pc = mle[i].start_pc; pc < mle[i].end_pc;)
- {
- QUIT;
- if (how_many >= 0)
- {
- if (num_displayed >= how_many)
- break;
- else
- num_displayed++;
- }
- ui_out_tuple_begin (uiout, NULL);
- ui_out_field_core_addr (uiout, "address", pc);
-
- if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped))
- {
- /* We don't care now about line, filename and
- unmapped, but we might in the future. */
- ui_out_field_string (uiout, "func-name", name);
- ui_out_field_int (uiout, "offset", offset);
- }
- if (filename != NULL)
- xfree (filename);
- if (name != NULL)
- xfree (name);
-
- ui_file_rewind (stb->stream);
- pc += (*tm_print_insn) (pc, &di);
- ui_out_field_stream (uiout, "inst", stb);
- ui_file_rewind (stb->stream);
- ui_out_tuple_end (uiout);
- }
- if (close_list)
- {
- ui_out_list_end (uiout);
- ui_out_tuple_end (uiout);
- close_list = 0;
- }
- if (how_many >= 0)
- if (num_displayed >= how_many)
- break;
- }
- ui_out_list_end (uiout);
- }
- else
- {
- assembly_only:
- ui_out_list_begin (uiout, "asm_insns");
- num_displayed = 0;
- for (pc = low; pc < high;)
- {
- QUIT;
- if (how_many >= 0)
- {
- if (num_displayed >= how_many)
- break;
- else
- num_displayed++;
- }
- ui_out_tuple_begin (uiout, NULL);
- ui_out_field_core_addr (uiout, "address", pc);
-
- if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped))
- {
- /* We don't care now about line, filename and
- unmapped. But we might in the future. */
- ui_out_field_string (uiout, "func-name", name);
- ui_out_field_int (uiout, "offset", offset);
- }
- if (filename != NULL)
- xfree (filename);
- if (name != NULL)
- xfree (name);
-
- ui_file_rewind (stb->stream);
- pc += (*tm_print_insn) (pc, &di);
- ui_out_field_stream (uiout, "inst", stb);
- ui_file_rewind (stb->stream);
- ui_out_tuple_end (uiout);
- }
- ui_out_list_end (uiout);
- }
- gdb_flush (gdb_stdout);
+ gdb_disassembly (uiout,
+ file_string,
+ line_num,
+ mixed_source_and_assembly, how_many, low, high);
return MI_CMD_DONE;
}
diff --git a/contrib/gdb/gdb/mi/mi-cmd-env.c b/contrib/gdb/gdb/mi/mi-cmd-env.c
new file mode 100644
index 0000000..439c719
--- /dev/null
+++ b/contrib/gdb/gdb/mi/mi-cmd-env.c
@@ -0,0 +1,259 @@
+/* MI Command Set - environment commands.
+
+ Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ Contributed by Red Hat Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "value.h"
+#include "mi-out.h"
+#include "mi-cmds.h"
+#include "mi-getopt.h"
+#include "symtab.h"
+#include "target.h"
+#include "environ.h"
+#include "command.h"
+#include "ui-out.h"
+#include "top.h"
+
+#include "gdb_string.h"
+#include "gdb_stat.h"
+
+static void env_mod_path (char *dirname, char **which_path);
+extern void _initialize_mi_cmd_env (void);
+
+static const char path_var_name[] = "PATH";
+static char *orig_path = NULL;
+
+/* The following is copied from mi-main.c so for m1 and below we can
+ perform old behavior and use cli commands. If ARGS is non-null,
+ append it to the CMD. */
+static void
+env_execute_cli_command (const char *cmd, const char *args)
+{
+ if (cmd != 0)
+ {
+ struct cleanup *old_cleanups;
+ char *run;
+ if (args != NULL)
+ xasprintf (&run, "%s %s", cmd, args);
+ else
+ run = xstrdup (cmd);
+ old_cleanups = make_cleanup (xfree, run);
+ execute_command ( /*ui */ run, 0 /*from_tty */ );
+ do_cleanups (old_cleanups);
+ return;
+ }
+}
+
+
+/* Print working directory. */
+enum mi_cmd_result
+mi_cmd_env_pwd (char *command, char **argv, int argc)
+{
+ if (argc > 0)
+ error ("mi_cmd_env_pwd: No arguments required");
+
+ if (mi_version (uiout) < 2)
+ {
+ env_execute_cli_command ("pwd", NULL);
+ return MI_CMD_DONE;
+ }
+
+ /* Otherwise the mi level is 2 or higher. */
+
+ getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
+ ui_out_field_string (uiout, "cwd", gdb_dirbuf);
+
+ return MI_CMD_DONE;
+}
+
+/* Change working directory. */
+enum mi_cmd_result
+mi_cmd_env_cd (char *command, char **argv, int argc)
+{
+ if (argc == 0 || argc > 1)
+ error ("mi_cmd_env_cd: Usage DIRECTORY");
+
+ env_execute_cli_command ("cd", argv[0]);
+
+ return MI_CMD_DONE;
+}
+
+static void
+env_mod_path (char *dirname, char **which_path)
+{
+ if (dirname == 0 || dirname[0] == '\0')
+ return;
+
+ /* Call add_path with last arg 0 to indicate not to parse for
+ separator characters. */
+ add_path (dirname, which_path, 0);
+}
+
+/* Add one or more directories to start of executable search path. */
+enum mi_cmd_result
+mi_cmd_env_path (char *command, char **argv, int argc)
+{
+ char *exec_path;
+ char *env;
+ int reset = 0;
+ int optind = 0;
+ int i;
+ char *optarg;
+ enum opt
+ {
+ RESET_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"r", RESET_OPT, 0},
+ 0
+ };
+
+ dont_repeat ();
+
+ if (mi_version (uiout) < 2)
+ {
+ for (i = argc - 1; i >= 0; --i)
+ env_execute_cli_command ("path", argv[i]);
+ return MI_CMD_DONE;
+ }
+
+ /* Otherwise the mi level is 2 or higher. */
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_env_path", argc, argv, opts,
+ &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case RESET_OPT:
+ reset = 1;
+ break;
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+
+ if (reset)
+ {
+ /* Reset implies resetting to original path first. */
+ exec_path = xstrdup (orig_path);
+ }
+ else
+ {
+ /* Otherwise, get current path to modify. */
+ env = get_in_environ (inferior_environ, path_var_name);
+
+ /* Can be null if path is not set. */
+ if (!env)
+ env = "";
+ exec_path = xstrdup (env);
+ }
+
+ for (i = argc - 1; i >= 0; --i)
+ env_mod_path (argv[i], &exec_path);
+
+ set_in_environ (inferior_environ, path_var_name, exec_path);
+ xfree (exec_path);
+ env = get_in_environ (inferior_environ, path_var_name);
+ ui_out_field_string (uiout, "path", env);
+
+ return MI_CMD_DONE;
+}
+
+/* Add zero or more directories to the front of the source path. */
+enum mi_cmd_result
+mi_cmd_env_dir (char *command, char **argv, int argc)
+{
+ int i;
+ int optind = 0;
+ int reset = 0;
+ char *optarg;
+ enum opt
+ {
+ RESET_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"r", RESET_OPT, 0},
+ 0
+ };
+
+ dont_repeat ();
+
+ if (mi_version (uiout) < 2)
+ {
+ for (i = argc - 1; i >= 0; --i)
+ env_execute_cli_command ("dir", argv[i]);
+ return MI_CMD_DONE;
+ }
+
+ /* Otherwise mi level is 2 or higher. */
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_env_dir", argc, argv, opts,
+ &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case RESET_OPT:
+ reset = 1;
+ break;
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+ if (reset)
+ {
+ /* Reset means setting to default path first. */
+ xfree (source_path);
+ init_source_path ();
+ }
+
+ for (i = argc - 1; i >= 0; --i)
+ env_mod_path (argv[i], &source_path);
+ init_last_source_visited ();
+
+ ui_out_field_string (uiout, "source-path", source_path);
+ forget_cached_source_info ();
+
+ return MI_CMD_DONE;
+}
+
+void
+_initialize_mi_cmd_env (void)
+{
+ char *env;
+
+ /* We want original execution path to reset to, if desired later. */
+ env = get_in_environ (inferior_environ, path_var_name);
+
+ /* Can be null if path is not set. */
+ if (!env)
+ env = "";
+ orig_path = xstrdup (env);
+}
diff --git a/contrib/gdb/gdb/mi/mi-cmd-file.c b/contrib/gdb/gdb/mi/mi-cmd-file.c
new file mode 100644
index 0000000..eb1d67a
--- /dev/null
+++ b/contrib/gdb/gdb/mi/mi-cmd-file.c
@@ -0,0 +1,67 @@
+/* MI Command Set - breakpoint and watchpoint commands.
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "mi-cmds.h"
+#include "mi-getopt.h"
+#include "ui-out.h"
+#include "symtab.h"
+#include "source.h"
+
+/* Return to the client the absolute path and line number of the
+ current file being executed. */
+
+enum mi_cmd_result
+mi_cmd_file_list_exec_source_file(char *command, char **argv, int argc)
+{
+ struct symtab_and_line st;
+ int optind = 0;
+ char *optarg;
+
+ if ( !mi_valid_noargs("mi_cmd_file_list_exec_source_file", argc, argv) )
+ error ("mi_cmd_file_list_exec_source_file: Usage: No args");
+
+
+ /* Set the default file and line, also get them */
+ set_default_source_symtab_and_line();
+ st = get_current_source_symtab_and_line();
+
+ /* We should always get a symtab.
+ Apparently, filename does not need to be tested for NULL.
+ The documentation in symtab.h suggests it will always be correct */
+ if (!st.symtab)
+ error ("mi_cmd_file_list_exec_source_file: No symtab");
+
+ /* Extract the fullname if it is not known yet */
+ if (st.symtab->fullname == NULL)
+ symtab_to_filename (st.symtab);
+
+ /* We may not be able to open the file (not available). */
+ if (st.symtab->fullname == NULL)
+ error ("mi_cmd_file_list_exec_source_file: File not found");
+
+ /* Print to the user the line, filename and fullname */
+ ui_out_field_int (uiout, "line", st.line);
+ ui_out_field_string (uiout, "file", st.symtab->filename);
+ ui_out_field_string (uiout, "fullname", st.symtab->fullname);
+
+ return MI_CMD_DONE;
+}
diff --git a/contrib/gdb/gdb/mi/mi-cmd-stack.c b/contrib/gdb/gdb/mi/mi-cmd-stack.c
index 0e4bdf4..7db9ffb 100644
--- a/contrib/gdb/gdb/mi/mi-cmd-stack.c
+++ b/contrib/gdb/gdb/mi/mi-cmd-stack.c
@@ -1,5 +1,5 @@
/* MI Command Set - stack commands.
- Copyright 2000, 2002 Free Software Foundation, Inc.
+ Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
@@ -26,11 +26,10 @@
#include "mi-cmds.h"
#include "ui-out.h"
#include "symtab.h"
-
-/* FIXME: these should go in some .h file but stack.c doesn't have a
- corresponding .h file. These wrappers will be obsolete anyway, once
- we pull the plug on the sanitization. */
-extern void select_frame_command_wrapper (char *, int);
+#include "block.h"
+#include "stack.h"
+#include "dictionary.h"
+#include "gdb_string.h"
static void list_args_or_locals (int locals, int values, struct frame_info *fi);
@@ -45,6 +44,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
int frame_low;
int frame_high;
int i;
+ struct cleanup *cleanup_stack;
struct frame_info *fi;
if (!target_has_stack)
@@ -76,7 +76,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
if (fi == NULL)
error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
- ui_out_list_begin (uiout, "stack");
+ cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "stack");
/* Now let;s print the frames up to frame_high, or until there are
frames in the stack. */
@@ -95,7 +95,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
0 /* args */ );
}
- ui_out_list_end (uiout);
+ do_cleanups (cleanup_stack);
if (i < frame_high)
error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
@@ -138,10 +138,26 @@ mi_cmd_stack_info_depth (char *command, char **argv, int argc)
enum mi_cmd_result
mi_cmd_stack_list_locals (char *command, char **argv, int argc)
{
+ struct frame_info *frame;
+ enum print_values print_values;
+
if (argc != 1)
error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES");
- list_args_or_locals (1, atoi (argv[0]), selected_frame);
+ frame = get_selected_frame ();
+
+ if (strcmp (argv[0], "0") == 0
+ || strcmp (argv[0], "--no-values") == 0)
+ print_values = PRINT_NO_VALUES;
+ else if (strcmp (argv[0], "1") == 0
+ || strcmp (argv[0], "--all-values") == 0)
+ print_values = PRINT_ALL_VALUES;
+ else if (strcmp (argv[0], "2") == 0
+ || strcmp (argv[0], "--simple-values") == 0)
+ print_values = PRINT_SIMPLE_VALUES;
+ else
+ error ("Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"--all-values\", 2 or \"--simple-values\"");
+ list_args_or_locals (1, print_values, frame);
return MI_CMD_DONE;
}
@@ -155,6 +171,7 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
int frame_high;
int i;
struct frame_info *fi;
+ struct cleanup *cleanup_stack_args;
if (argc < 1 || argc > 3 || argc == 2)
error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]");
@@ -182,7 +199,7 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
if (fi == NULL)
error ("mi_cmd_stack_list_args: Not enough frames in stack.");
- ui_out_list_begin (uiout, "stack-args");
+ cleanup_stack_args = make_cleanup_ui_out_list_begin_end (uiout, "stack-args");
/* Now let's print the frames up to frame_high, or until there are
frames in the stack. */
@@ -190,14 +207,15 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
fi && (i <= frame_high || frame_high == -1);
i++, fi = get_prev_frame (fi))
{
+ struct cleanup *cleanup_frame;
QUIT;
- ui_out_tuple_begin (uiout, "frame");
+ cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
ui_out_field_int (uiout, "level", i);
list_args_or_locals (0, atoi (argv[0]), fi);
- ui_out_tuple_end (uiout);
+ do_cleanups (cleanup_frame);
}
- ui_out_list_end (uiout);
+ do_cleanups (cleanup_stack_args);
if (i < frame_high)
error ("mi_cmd_stack_list_args: Not enough frames in stack.");
@@ -213,18 +231,21 @@ list_args_or_locals (int locals, int values, struct frame_info *fi)
{
struct block *block;
struct symbol *sym;
- int i, nsyms;
+ struct dict_iterator iter;
+ int nsyms;
+ struct cleanup *cleanup_list;
static struct ui_stream *stb = NULL;
+ struct type *type;
stb = ui_out_stream_new (uiout);
- block = get_frame_block (fi);
+ block = get_frame_block (fi, 0);
- ui_out_list_begin (uiout, locals ? "locals" : "args");
+ cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args");
while (block != 0)
{
- ALL_BLOCK_SYMBOLS (block, i, sym)
+ ALL_BLOCK_SYMBOLS (block, iter, sym)
{
int print_me = 0;
@@ -248,6 +269,7 @@ list_args_or_locals (int locals, int values, struct frame_info *fi)
case LOC_REGPARM_ADDR: /* indirect register arg */
case LOC_LOCAL_ARG: /* stack arg */
case LOC_BASEREG_ARG: /* basereg arg */
+ case LOC_COMPUTED_ARG: /* arg with computed location */
if (!locals)
print_me = 1;
break;
@@ -256,29 +278,47 @@ list_args_or_locals (int locals, int values, struct frame_info *fi)
case LOC_BASEREG: /* basereg local */
case LOC_STATIC: /* static */
case LOC_REGISTER: /* register */
+ case LOC_COMPUTED: /* computed location */
if (locals)
print_me = 1;
break;
}
if (print_me)
{
- if (values)
- ui_out_tuple_begin (uiout, NULL);
- ui_out_field_string (uiout, "name", SYMBOL_NAME (sym));
+ struct cleanup *cleanup_tuple = NULL;
+ struct symbol *sym2;
+ if (values != PRINT_NO_VALUES)
+ cleanup_tuple =
+ make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym));
- if (values)
- {
- struct symbol *sym2;
- if (!locals)
- sym2 = lookup_symbol (SYMBOL_NAME (sym),
- block, VAR_NAMESPACE,
- (int *) NULL,
- (struct symtab **) NULL);
- else
+ if (!locals)
+ sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym),
+ block, VAR_DOMAIN,
+ (int *) NULL,
+ (struct symtab **) NULL);
+ else
sym2 = sym;
+ switch (values)
+ {
+ case PRINT_SIMPLE_VALUES:
+ type = check_typedef (sym2->type);
+ type_print (sym2->type, "", stb->stream, -1);
+ ui_out_field_stream (uiout, "type", stb);
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
+ {
+ print_variable_value (sym2, fi, stb->stream);
+ ui_out_field_stream (uiout, "value", stb);
+ }
+ do_cleanups (cleanup_tuple);
+ break;
+ case PRINT_ALL_VALUES:
print_variable_value (sym2, fi, stb->stream);
ui_out_field_stream (uiout, "value", stb);
- ui_out_tuple_end (uiout);
+ do_cleanups (cleanup_tuple);
+ break;
}
}
}
@@ -287,7 +327,7 @@ list_args_or_locals (int locals, int values, struct frame_info *fi)
else
block = BLOCK_SUPERBLOCK (block);
}
- ui_out_list_end (uiout);
+ do_cleanups (cleanup_list);
ui_out_stream_delete (stb);
}
@@ -302,8 +342,8 @@ mi_cmd_stack_select_frame (char *command, char **argv, int argc)
/* with no args, don't change frame */
if (argc == 0)
- select_frame_command_wrapper (0, 1 /* not used */ );
+ select_frame_command (0, 1 /* not used */ );
else
- select_frame_command_wrapper (argv[0], 1 /* not used */ );
+ select_frame_command (argv[0], 1 /* not used */ );
return MI_CMD_DONE;
}
diff --git a/contrib/gdb/gdb/mi/mi-cmd-var.c b/contrib/gdb/gdb/mi/mi-cmd-var.c
index 0c84064..709ed30 100644
--- a/contrib/gdb/gdb/mi/mi-cmd-var.c
+++ b/contrib/gdb/gdb/mi/mi-cmd-var.c
@@ -1,5 +1,7 @@
/* MI Command Set - varobj commands.
- Copyright 2000 Free Software Foundation, Inc.
+
+ Copyright 2000, 2002, 2004 Free Software Foundation, Inc.
+
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
@@ -26,11 +28,7 @@
#include "varobj.h"
#include "value.h"
#include <ctype.h>
-
-/* Convenience macro for allocting typesafe memory. */
-
-#undef XMALLOC
-#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
+#include "gdb_string.h"
extern int varobjdebug; /* defined in varobj.c */
@@ -83,7 +81,7 @@ mi_cmd_var_create (char *command, char **argv, int argc)
else
{
var_type = USE_SPECIFIED_FRAME;
- frameaddr = parse_and_eval_address (frame);
+ frameaddr = string_to_core_addr (frame);
}
if (varobjdebug)
@@ -191,15 +189,15 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
len = strlen (formspec);
- if (STREQN (formspec, "natural", len))
+ if (strncmp (formspec, "natural", len) == 0)
format = FORMAT_NATURAL;
- else if (STREQN (formspec, "binary", len))
+ else if (strncmp (formspec, "binary", len) == 0)
format = FORMAT_BINARY;
- else if (STREQN (formspec, "decimal", len))
+ else if (strncmp (formspec, "decimal", len) == 0)
format = FORMAT_DECIMAL;
- else if (STREQN (formspec, "hexadecimal", len))
+ else if (strncmp (formspec, "hexadecimal", len) == 0)
format = FORMAT_HEXADECIMAL;
- else if (STREQN (formspec, "octal", len))
+ else if (strncmp (formspec, "octal", len) == 0)
format = FORMAT_OCTAL;
else
error ("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\"");
@@ -256,39 +254,58 @@ mi_cmd_var_list_children (char *command, char **argv, int argc)
struct varobj *var;
struct varobj **childlist;
struct varobj **cc;
+ struct cleanup *cleanup_children;
int numchild;
char *type;
+ enum print_values print_values;
- if (argc != 1)
- error ("mi_cmd_var_list_children: Usage: NAME.");
+ if (argc != 1 && argc != 2)
+ error ("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME");
/* Get varobj handle, if a valid var obj name was specified */
- var = varobj_get_handle (argv[0]);
+ if (argc == 1) var = varobj_get_handle (argv[0]);
+ else var = varobj_get_handle (argv[1]);
if (var == NULL)
- error ("mi_cmd_var_list_children: Variable object not found");
+ error ("Variable object not found");
numchild = varobj_list_children (var, &childlist);
ui_out_field_int (uiout, "numchild", numchild);
+ if (argc == 2)
+ if (strcmp (argv[0], "0") == 0
+ || strcmp (argv[0], "--no-values") == 0)
+ print_values = PRINT_NO_VALUES;
+ else if (strcmp (argv[0], "1") == 0
+ || strcmp (argv[0], "--all-values") == 0)
+ print_values = PRINT_ALL_VALUES;
+ else
+ error ("Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"--all-values\"");
+ else print_values = PRINT_NO_VALUES;
if (numchild <= 0)
return MI_CMD_DONE;
- ui_out_tuple_begin (uiout, "children");
+ if (mi_version (uiout) == 1)
+ cleanup_children = make_cleanup_ui_out_tuple_begin_end (uiout, "children");
+ else
+ cleanup_children = make_cleanup_ui_out_list_begin_end (uiout, "children");
cc = childlist;
while (*cc != NULL)
{
- ui_out_tuple_begin (uiout, "child");
+ struct cleanup *cleanup_child;
+ cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child");
ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
ui_out_field_string (uiout, "exp", varobj_get_expression (*cc));
ui_out_field_int (uiout, "numchild", varobj_get_num_children (*cc));
+ if (print_values)
+ ui_out_field_string (uiout, "value", varobj_get_value (*cc));
type = varobj_get_type (*cc);
/* C++ pseudo-variables (public, private, protected) do not have a type */
if (type)
ui_out_field_string (uiout, "type", varobj_get_type (*cc));
- ui_out_tuple_end (uiout);
+ do_cleanups (cleanup_child);
cc++;
}
- ui_out_tuple_end (uiout);
+ do_cleanups (cleanup_children);
xfree (childlist);
return MI_CMD_DONE;
}
@@ -407,6 +424,7 @@ mi_cmd_var_update (char *command, char **argv, int argc)
struct varobj *var;
struct varobj **rootlist;
struct varobj **cr;
+ struct cleanup *cleanup;
char *name;
int nv;
@@ -421,10 +439,13 @@ mi_cmd_var_update (char *command, char **argv, int argc)
if ((*name == '*') && (*(name + 1) == '\0'))
{
nv = varobj_list (&rootlist);
- ui_out_tuple_begin (uiout, "changelist");
+ if (mi_version (uiout) <= 1)
+ cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "changelist");
+ else
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changelist");
if (nv <= 0)
{
- ui_out_tuple_end (uiout);
+ do_cleanups (cleanup);
return MI_CMD_DONE;
}
cr = rootlist;
@@ -434,7 +455,7 @@ mi_cmd_var_update (char *command, char **argv, int argc)
cr++;
}
xfree (rootlist);
- ui_out_tuple_end (uiout);
+ do_cleanups (cleanup);
}
else
{
@@ -443,9 +464,12 @@ mi_cmd_var_update (char *command, char **argv, int argc)
if (var == NULL)
error ("mi_cmd_var_update: Variable object not found");
- ui_out_tuple_begin (uiout, "changelist");
+ if (mi_version (uiout) <= 1)
+ cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "changelist");
+ else
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changelist");
varobj_update_one (var);
- ui_out_tuple_end (uiout);
+ do_cleanups (cleanup);
}
return MI_CMD_DONE;
}
@@ -459,6 +483,7 @@ varobj_update_one (struct varobj *var)
{
struct varobj **changelist;
struct varobj **cc;
+ struct cleanup *cleanup = NULL;
int nc;
nc = varobj_update (&var, &changelist);
@@ -471,17 +496,25 @@ varobj_update_one (struct varobj *var)
return 1;
else if (nc == -1)
{
+ if (mi_version (uiout) > 1)
+ cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
ui_out_field_string (uiout, "name", varobj_get_objname(var));
ui_out_field_string (uiout, "in_scope", "false");
+ if (mi_version (uiout) > 1)
+ do_cleanups (cleanup);
return -1;
}
else if (nc == -2)
{
+ if (mi_version (uiout) > 1)
+ cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
ui_out_field_string (uiout, "name", varobj_get_objname (var));
ui_out_field_string (uiout, "in_scope", "true");
ui_out_field_string (uiout, "new_type", varobj_get_type(var));
ui_out_field_int (uiout, "new_num_children",
varobj_get_num_children(var));
+ if (mi_version (uiout) > 1)
+ do_cleanups (cleanup);
}
else
{
@@ -489,9 +522,13 @@ varobj_update_one (struct varobj *var)
cc = changelist;
while (*cc != NULL)
{
+ if (mi_version (uiout) > 1)
+ cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
ui_out_field_string (uiout, "in_scope", "true");
ui_out_field_string (uiout, "type_changed", "false");
+ if (mi_version (uiout) > 1)
+ do_cleanups (cleanup);
cc++;
}
xfree (changelist);
diff --git a/contrib/gdb/gdb/mi/mi-cmds.c b/contrib/gdb/gdb/mi/mi-cmds.c
index 233d06b..0dfc217 100644
--- a/contrib/gdb/gdb/mi/mi-cmds.c
+++ b/contrib/gdb/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.
@@ -32,134 +34,138 @@ static void build_table (struct mi_cmd *commands);
struct mi_cmd mi_cmds[] =
{
- {"break-after", "ignore %s", 0},
- {"break-catch", 0, 0},
- {"break-commands", 0, 0},
- {"break-condition", "cond %s", 0},
- {"break-delete", "delete breakpoint %s", 0},
- {"break-disable", "disable breakpoint %s", 0},
- {"break-enable", "enable breakpoint %s", 0},
- {"break-info", "info break %s", 0},
- {"break-insert", 0, 0, mi_cmd_break_insert},
- {"break-list", "info break", 0},
- {"break-watch", 0, 0, mi_cmd_break_watch},
- {"data-disassemble", 0, 0, mi_cmd_disassemble},
- {"data-evaluate-expression", 0, 0, mi_cmd_data_evaluate_expression},
- {"data-list-changed-registers", 0, 0, mi_cmd_data_list_changed_registers},
- {"data-list-register-names", 0, 0, mi_cmd_data_list_register_names},
- {"data-list-register-values", 0, 0, mi_cmd_data_list_register_values},
- {"data-read-memory", 0, 0, mi_cmd_data_read_memory},
- {"data-write-memory", 0, 0, mi_cmd_data_write_memory},
- {"data-write-register-values", 0, 0, mi_cmd_data_write_register_values},
- {"display-delete", 0, 0},
- {"display-disable", 0, 0},
- {"display-enable", 0, 0},
- {"display-insert", 0, 0},
- {"display-list", 0, 0},
- {"environment-cd", "cd %s", 0},
- {"environment-directory", "dir %s", 0},
- {"environment-path", "path %s", 0},
- {"environment-pwd", "pwd", 0},
- {"exec-abort", 0, 0},
- {"exec-arguments", "set args %s", 0},
- {"exec-continue", 0, mi_cmd_exec_continue},
- {"exec-finish", 0, mi_cmd_exec_finish},
- {"exec-interrupt", 0, mi_cmd_exec_interrupt},
- {"exec-next", 0, mi_cmd_exec_next},
- {"exec-next-instruction", 0, mi_cmd_exec_next_instruction},
- {"exec-return", 0, mi_cmd_exec_return},
- {"exec-run", 0, mi_cmd_exec_run},
- {"exec-show-arguments", 0, 0},
- {"exec-signal", 0, 0},
- {"exec-step", 0, mi_cmd_exec_step},
- {"exec-step-instruction", 0, mi_cmd_exec_step_instruction},
- {"exec-until", 0, mi_cmd_exec_until},
- {"file-clear", 0, 0},
- {"file-exec-and-symbols", "file %s", 0},
- {"file-exec-file", "exec-file %s", 0},
- {"file-list-exec-sections", 0, 0},
- {"file-list-exec-source-files", 0, 0},
- {"file-list-shared-libraries", 0, 0},
- {"file-list-symbol-files", 0, 0},
- {"file-symbol-file", "symbol-file %s", 0},
- {"gdb-complete", 0, 0},
- {"gdb-exit", 0, 0, mi_cmd_gdb_exit},
- {"gdb-set", "set %s", 0},
- {"gdb-show", "show %s", 0},
- {"gdb-source", 0, 0},
- {"gdb-version", "show version", 0},
- {"kod-info", 0, 0},
- {"kod-list", 0, 0},
- {"kod-list-object-types", 0, 0},
- {"kod-show", 0, 0},
- {"overlay-auto", 0, 0},
- {"overlay-list-mapping-state", 0, 0},
- {"overlay-list-overlays", 0, 0},
- {"overlay-map", 0, 0},
- {"overlay-off", 0, 0},
- {"overlay-on", 0, 0},
- {"overlay-unmap", 0, 0},
- {"signal-handle", 0, 0},
- {"signal-list-handle-actions", 0, 0},
- {"signal-list-signal-types", 0, 0},
- {"stack-info-depth", 0, 0, mi_cmd_stack_info_depth},
- {"stack-info-frame", 0, 0},
- {"stack-list-arguments", 0, 0, mi_cmd_stack_list_args},
- {"stack-list-exception-handlers", 0, 0},
- {"stack-list-frames", 0, 0, mi_cmd_stack_list_frames},
- {"stack-list-locals", 0, 0, mi_cmd_stack_list_locals},
- {"stack-select-frame", 0, 0, mi_cmd_stack_select_frame},
- {"symbol-info-address", 0, 0},
- {"symbol-info-file", 0, 0},
- {"symbol-info-function", 0, 0},
- {"symbol-info-line", 0, 0},
- {"symbol-info-symbol", 0, 0},
- {"symbol-list-functions", 0, 0},
- {"symbol-list-types", 0, 0},
- {"symbol-list-variables", 0, 0},
- {"symbol-locate", 0, 0},
- {"symbol-type", 0, 0},
- {"target-attach", 0, 0},
- {"target-compare-sections", 0, 0},
- {"target-detach", "detach", 0},
- {"target-download", 0, mi_cmd_target_download},
- {"target-exec-status", 0, 0},
- {"target-list-available-targets", 0, 0},
- {"target-list-current-targets", 0, 0},
- {"target-list-parameters", 0, 0},
- {"target-select", 0, mi_cmd_target_select},
- {"thread-info", 0, 0},
- {"thread-list-all-threads", 0, 0},
- {"thread-list-ids", 0, 0, mi_cmd_thread_list_ids},
- {"thread-select", 0, 0, mi_cmd_thread_select},
- {"trace-actions", 0, 0},
- {"trace-delete", 0, 0},
- {"trace-disable", 0, 0},
- {"trace-dump", 0, 0},
- {"trace-enable", 0, 0},
- {"trace-exists", 0, 0},
- {"trace-find", 0, 0},
- {"trace-frame-number", 0, 0},
- {"trace-info", 0, 0},
- {"trace-insert", 0, 0},
- {"trace-list", 0, 0},
- {"trace-pass-count", 0, 0},
- {"trace-save", 0, 0},
- {"trace-start", 0, 0},
- {"trace-stop", 0, 0},
- {"var-assign", 0, 0, mi_cmd_var_assign},
- {"var-create", 0, 0, mi_cmd_var_create},
- {"var-delete", 0, 0, mi_cmd_var_delete},
- {"var-evaluate-expression", 0, 0, mi_cmd_var_evaluate_expression},
- {"var-info-expression", 0, 0, mi_cmd_var_info_expression},
- {"var-info-num-children", 0, 0, mi_cmd_var_info_num_children},
- {"var-info-type", 0, 0, mi_cmd_var_info_type},
- {"var-list-children", 0, 0, mi_cmd_var_list_children},
- {"var-set-format", 0, 0, mi_cmd_var_set_format},
- {"var-show-attributes", 0, 0, mi_cmd_var_show_attributes},
- {"var-show-format", 0, 0, mi_cmd_var_show_format},
- {"var-update", 0, 0, mi_cmd_var_update},
- {0,}
+ { "break-after", { "ignore", 1 }, NULL, NULL },
+ { "break-catch", { NULL, 0 }, NULL, NULL },
+ { "break-commands", { NULL, 0 }, NULL, NULL },
+ { "break-condition", { "cond", 1 }, NULL, NULL },
+ { "break-delete", { "delete breakpoint", 1 }, NULL, NULL },
+ { "break-disable", { "disable breakpoint", 1 }, NULL, NULL },
+ { "break-enable", { "enable breakpoint", 1 }, NULL, NULL },
+ { "break-info", { "info break", 1 }, NULL, NULL },
+ { "break-insert", { NULL, 0 }, 0, mi_cmd_break_insert},
+ { "break-list", { "info break", }, NULL, NULL },
+ { "break-watch", { NULL, 0 }, 0, mi_cmd_break_watch},
+ { "data-disassemble", { NULL, 0 }, 0, mi_cmd_disassemble},
+ { "data-evaluate-expression", { NULL, 0 }, 0, mi_cmd_data_evaluate_expression},
+ { "data-list-changed-registers", { NULL, 0 }, 0, mi_cmd_data_list_changed_registers},
+ { "data-list-register-names", { NULL, 0 }, 0, mi_cmd_data_list_register_names},
+ { "data-list-register-values", { NULL, 0 }, 0, mi_cmd_data_list_register_values},
+ { "data-read-memory", { NULL, 0 }, 0, mi_cmd_data_read_memory},
+ { "data-write-memory", { NULL, 0 }, 0, mi_cmd_data_write_memory},
+ { "data-write-register-values", { NULL, 0 }, 0, mi_cmd_data_write_register_values},
+ { "display-delete", { NULL, 0 }, NULL, NULL },
+ { "display-disable", { NULL, 0 }, NULL, NULL },
+ { "display-enable", { NULL, 0 }, NULL, NULL },
+ { "display-insert", { NULL, 0 }, NULL, NULL },
+ { "display-list", { NULL, 0 }, NULL, NULL },
+ { "environment-cd", { NULL, 0 }, 0, mi_cmd_env_cd},
+ { "environment-directory", { NULL, 0 }, 0, mi_cmd_env_dir},
+ { "environment-path", { NULL, 0 }, 0, mi_cmd_env_path},
+ { "environment-pwd", { NULL, 0 }, 0, mi_cmd_env_pwd},
+ { "exec-abort", { NULL, 0 }, NULL, NULL },
+ { "exec-arguments", { "set args", 1 }, NULL, NULL },
+ { "exec-continue", { NULL, 0 }, mi_cmd_exec_continue},
+ { "exec-finish", { NULL, 0 }, mi_cmd_exec_finish},
+ { "exec-interrupt", { NULL, 0 }, mi_cmd_exec_interrupt},
+ { "exec-next", { NULL, 0 }, mi_cmd_exec_next},
+ { "exec-next-instruction", { NULL, 0 }, mi_cmd_exec_next_instruction},
+ { "exec-return", { NULL, 0 }, mi_cmd_exec_return},
+ { "exec-run", { NULL, 0 }, mi_cmd_exec_run},
+ { "exec-show-arguments", { NULL, 0 }, NULL, NULL },
+ { "exec-signal", { NULL, 0 }, NULL, NULL },
+ { "exec-step", { NULL, 0 }, mi_cmd_exec_step},
+ { "exec-step-instruction", { NULL, 0 }, mi_cmd_exec_step_instruction},
+ { "exec-until", { NULL, 0 }, mi_cmd_exec_until},
+ { "file-clear", { NULL, 0 }, NULL, NULL },
+ { "file-exec-and-symbols", { "file", 1 }, NULL, NULL },
+ { "file-exec-file", { "exec-file", 1 }, NULL, NULL },
+ { "file-list-exec-sections", { NULL, 0 }, NULL, NULL },
+ { "file-list-exec-source-file", { NULL, 0 }, 0, mi_cmd_file_list_exec_source_file},
+ { "file-list-exec-source-files", { NULL, 0 }, NULL, NULL },
+ { "file-list-shared-libraries", { NULL, 0 }, NULL, NULL },
+ { "file-list-symbol-files", { NULL, 0 }, NULL, NULL },
+ { "file-symbol-file", { "symbol-file", 1 }, NULL, NULL },
+ { "gdb-complete", { NULL, 0 }, NULL, NULL },
+ { "gdb-exit", { NULL, 0 }, 0, mi_cmd_gdb_exit},
+ { "gdb-set", { "set", 1 }, NULL, NULL },
+ { "gdb-show", { "show", 1 }, NULL, NULL },
+ { "gdb-source", { NULL, 0 }, NULL, NULL },
+ { "gdb-version", { "show version", 0 }, 0 },
+ { "interpreter-exec", { NULL, 0 }, 0, mi_cmd_interpreter_exec},
+ { "kod-info", { NULL, 0 }, NULL, NULL },
+ { "kod-list", { NULL, 0 }, NULL, NULL },
+ { "kod-list-object-types", { NULL, 0 }, NULL, NULL },
+ { "kod-show", { NULL, 0 }, NULL, NULL },
+ { "overlay-auto", { NULL, 0 }, NULL, NULL },
+ { "overlay-list-mapping-state", { NULL, 0 }, NULL, NULL },
+ { "overlay-list-overlays", { NULL, 0 }, NULL, NULL },
+ { "overlay-map", { NULL, 0 }, NULL, NULL },
+ { "overlay-off", { NULL, 0 }, NULL, NULL },
+ { "overlay-on", { NULL, 0 }, NULL, NULL },
+ { "overlay-unmap", { NULL, 0 }, NULL, NULL },
+ { "signal-handle", { NULL, 0 }, NULL, NULL },
+ { "signal-list-handle-actions", { NULL, 0 }, NULL, NULL },
+ { "signal-list-signal-types", { NULL, 0 }, NULL, NULL },
+ { "stack-info-depth", { NULL, 0 }, 0, mi_cmd_stack_info_depth},
+ { "stack-info-frame", { NULL, 0 }, NULL, NULL },
+ { "stack-list-arguments", { NULL, 0 }, 0, mi_cmd_stack_list_args},
+ { "stack-list-exception-handlers", { NULL, 0 }, NULL, NULL },
+ { "stack-list-frames", { NULL, 0 }, 0, mi_cmd_stack_list_frames},
+ { "stack-list-locals", { NULL, 0 }, 0, mi_cmd_stack_list_locals},
+ { "stack-select-frame", { NULL, 0 }, 0, mi_cmd_stack_select_frame},
+ { "symbol-info-address", { NULL, 0 }, NULL, NULL },
+ { "symbol-info-file", { NULL, 0 }, NULL, NULL },
+ { "symbol-info-function", { NULL, 0 }, NULL, NULL },
+ { "symbol-info-line", { NULL, 0 }, NULL, NULL },
+ { "symbol-info-symbol", { NULL, 0 }, NULL, NULL },
+ { "symbol-list-functions", { NULL, 0 }, NULL, NULL },
+ { "symbol-list-lines", { NULL, 0 }, 0, mi_cmd_symbol_list_lines},
+ { "symbol-list-types", { NULL, 0 }, NULL, NULL },
+ { "symbol-list-variables", { NULL, 0 }, NULL, NULL },
+ { "symbol-locate", { NULL, 0 }, NULL, NULL },
+ { "symbol-type", { NULL, 0 }, NULL, NULL },
+ { "target-attach", { NULL, 0 }, NULL, NULL },
+ { "target-compare-sections", { NULL, 0 }, NULL, NULL },
+ { "target-detach", { "detach", 0 }, 0 },
+ { "target-disconnect", { "disconnect", 0 }, 0 },
+ { "target-download", { NULL, 0 }, mi_cmd_target_download},
+ { "target-exec-status", { NULL, 0 }, NULL, NULL },
+ { "target-list-available-targets", { NULL, 0 }, NULL, NULL },
+ { "target-list-current-targets", { NULL, 0 }, NULL, NULL },
+ { "target-list-parameters", { NULL, 0 }, NULL, NULL },
+ { "target-select", { NULL, 0 }, mi_cmd_target_select},
+ { "thread-info", { NULL, 0 }, NULL, NULL },
+ { "thread-list-all-threads", { NULL, 0 }, NULL, NULL },
+ { "thread-list-ids", { NULL, 0 }, 0, mi_cmd_thread_list_ids},
+ { "thread-select", { NULL, 0 }, 0, mi_cmd_thread_select},
+ { "trace-actions", { NULL, 0 }, NULL, NULL },
+ { "trace-delete", { NULL, 0 }, NULL, NULL },
+ { "trace-disable", { NULL, 0 }, NULL, NULL },
+ { "trace-dump", { NULL, 0 }, NULL, NULL },
+ { "trace-enable", { NULL, 0 }, NULL, NULL },
+ { "trace-exists", { NULL, 0 }, NULL, NULL },
+ { "trace-find", { NULL, 0 }, NULL, NULL },
+ { "trace-frame-number", { NULL, 0 }, NULL, NULL },
+ { "trace-info", { NULL, 0 }, NULL, NULL },
+ { "trace-insert", { NULL, 0 }, NULL, NULL },
+ { "trace-list", { NULL, 0 }, NULL, NULL },
+ { "trace-pass-count", { NULL, 0 }, NULL, NULL },
+ { "trace-save", { NULL, 0 }, NULL, NULL },
+ { "trace-start", { NULL, 0 }, NULL, NULL },
+ { "trace-stop", { NULL, 0 }, NULL, NULL },
+ { "var-assign", { NULL, 0 }, 0, mi_cmd_var_assign},
+ { "var-create", { NULL, 0 }, 0, mi_cmd_var_create},
+ { "var-delete", { NULL, 0 }, 0, mi_cmd_var_delete},
+ { "var-evaluate-expression", { NULL, 0 }, 0, mi_cmd_var_evaluate_expression},
+ { "var-info-expression", { NULL, 0 }, 0, mi_cmd_var_info_expression},
+ { "var-info-num-children", { NULL, 0 }, 0, mi_cmd_var_info_num_children},
+ { "var-info-type", { NULL, 0 }, 0, mi_cmd_var_info_type},
+ { "var-list-children", { NULL, 0 }, 0, mi_cmd_var_list_children},
+ { "var-set-format", { NULL, 0 }, 0, mi_cmd_var_set_format},
+ { "var-show-attributes", { NULL, 0 }, 0, mi_cmd_var_show_attributes},
+ { "var-show-format", { NULL, 0 }, 0, mi_cmd_var_show_format},
+ { "var-update", { NULL, 0 }, 0, mi_cmd_var_update},
+ { NULL, }
};
/* Pointer to the mi command table (built at run time) */
diff --git a/contrib/gdb/gdb/mi/mi-cmds.h b/contrib/gdb/gdb/mi/mi-cmds.h
index 88775e6..5453059 100644
--- a/contrib/gdb/gdb/mi/mi-cmds.h
+++ b/contrib/gdb/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, 2004 Free Software Foundation, Inc.
+
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
@@ -46,6 +48,12 @@ enum mi_cmd_result
MI_CMD_QUIET
};
+enum print_values {
+ PRINT_NO_VALUES,
+ PRINT_ALL_VALUES,
+ PRINT_SIMPLE_VALUES
+};
+
typedef enum mi_cmd_result (mi_cmd_argv_ftype) (char *command, char **argv, int argc);
/* Older MI commands have this interface. Retained until all old
@@ -64,6 +72,10 @@ extern mi_cmd_argv_ftype mi_cmd_data_list_changed_registers;
extern mi_cmd_argv_ftype mi_cmd_data_read_memory;
extern mi_cmd_argv_ftype mi_cmd_data_write_memory;
extern mi_cmd_argv_ftype mi_cmd_data_write_register_values;
+extern mi_cmd_argv_ftype mi_cmd_env_cd;
+extern mi_cmd_argv_ftype mi_cmd_env_dir;
+extern mi_cmd_argv_ftype mi_cmd_env_path;
+extern mi_cmd_argv_ftype mi_cmd_env_pwd;
extern mi_cmd_args_ftype mi_cmd_exec_continue;
extern mi_cmd_args_ftype mi_cmd_exec_finish;
extern mi_cmd_args_ftype mi_cmd_exec_next;
@@ -74,12 +86,15 @@ extern mi_cmd_args_ftype mi_cmd_exec_step;
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_file_list_exec_source_file;
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;
extern mi_cmd_argv_ftype mi_cmd_stack_list_locals;
extern mi_cmd_argv_ftype mi_cmd_stack_select_frame;
+extern mi_cmd_argv_ftype mi_cmd_symbol_list_lines;
extern mi_cmd_args_ftype mi_cmd_target_download;
extern mi_cmd_args_ftype mi_cmd_target_select;
extern mi_cmd_argv_ftype mi_cmd_thread_list_ids;
@@ -99,18 +114,26 @@ extern mi_cmd_argv_ftype mi_cmd_var_update;
/* Description of a single command. */
+struct mi_cli
+{
+ /* Corresponding CLI command. If ARGS_P is non-zero, the MI
+ command's argument list is appended to the CLI command. */
+ const char *cmd;
+ int args_p;
+};
+
struct mi_cmd
- {
- /* official name of the command */
- const char *name;
- /* If non-null, the corresponding CLI command that can be used to
- implement this MI command */
- const char *cli;
- /* If non-null, the function implementing the MI command */
- mi_cmd_args_ftype *args_func;
- /* If non-null, the function implementing the MI command */
- mi_cmd_argv_ftype *argv_func;
- };
+{
+ /* official name of the command. */
+ const char *name;
+ /* The corresponding CLI command that can be used to implement this
+ MI command (if cli.lhs is non NULL). */
+ struct mi_cli cli;
+ /* If non-null, the function implementing the MI command. */
+ mi_cmd_args_ftype *args_func;
+ /* If non-null, the function implementing the MI command. */
+ mi_cmd_argv_ftype *argv_func;
+};
/* Lookup a command in the mi comand table */
@@ -122,4 +145,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/contrib/gdb/gdb/mi/mi-console.c b/contrib/gdb/gdb/mi/mi-console.c
index 5824f83..aca0086 100644
--- a/contrib/gdb/gdb/mi/mi-console.c
+++ b/contrib/gdb/gdb/mi/mi-console.c
@@ -1,5 +1,7 @@
/* MI Console code.
- Copyright 2000, 2001 Free Software Foundation, Inc.
+
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
@@ -23,11 +25,6 @@
#include "mi-console.h"
#include "gdb_string.h"
-/* Convenience macro for allocting typesafe memory. */
-
-#undef XMALLOC
-#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
-
/* MI-console: send output to std-out but correcty encapsulated */
static ui_file_fputs_ftype mi_console_file_fputs;
@@ -40,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);
@@ -54,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);
@@ -99,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/contrib/gdb/gdb/mi/mi-console.h b/contrib/gdb/gdb/mi/mi-console.h
index 6bd03cb..bc6c008 100644
--- a/contrib/gdb/gdb/mi/mi-console.h
+++ b/contrib/gdb/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/contrib/gdb/gdb/mi/mi-getopt.c b/contrib/gdb/gdb/mi/mi-getopt.c
index 59ccdf3..3f2a902 100644
--- a/contrib/gdb/gdb/mi/mi-getopt.c
+++ b/contrib/gdb/gdb/mi/mi-getopt.c
@@ -74,3 +74,19 @@ mi_getopt (const char *prefix,
}
error ("%s: Unknown option ``%s''", prefix, arg + 1);
}
+
+int
+mi_valid_noargs (const char *prefix, int argc, char **argv)
+{
+ int optind = 0;
+ char *optarg;
+ static struct mi_opt opts[] =
+ {
+ 0
+ };
+
+ if (mi_getopt (prefix, argc, argv, opts, &optind, &optarg) == -1)
+ return 1;
+ else
+ return 0;
+}
diff --git a/contrib/gdb/gdb/mi/mi-getopt.h b/contrib/gdb/gdb/mi/mi-getopt.h
index 6b31adf..17d66fb 100644
--- a/contrib/gdb/gdb/mi/mi-getopt.h
+++ b/contrib/gdb/gdb/mi/mi-getopt.h
@@ -57,4 +57,24 @@ struct mi_opt
struct mi_opt;
+/* mi_valid_noargs
+
+ Determines if ARGC/ARGV are a valid set of parameters to satisfy
+ an MI function that is not supposed to recieve any arguments.
+
+ An MI function that should not recieve arguments can still be
+ passed parameters after the special option '--' such as below.
+
+ Example: The MI function -exec-run takes no args.
+ However, the client may pass '-exec-run -- -a ...'
+ See PR-783
+
+ PREFIX is passed to mi_getopt for an error message.
+
+ This function Returns 1 if the parameter pair ARGC/ARGV are valid
+ for an MI function that takes no arguments. Otherwise, it returns 0
+ and the appropriate error message is displayed by mi_getopt. */
+
+extern int mi_valid_noargs (const char *prefix, int argc, char **argv);
+
#endif
diff --git a/contrib/gdb/gdb/mi/mi-interp.c b/contrib/gdb/gdb/mi/mi-interp.c
new file mode 100644
index 0000000..08201ca
--- /dev/null
+++ b/contrib/gdb/gdb/mi/mi-interp.c
@@ -0,0 +1,406 @@
+/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
+
+ Copyright 2002, 2003, 2003 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "interps.h"
+#include "event-top.h"
+#include "event-loop.h"
+#include "inferior.h"
+#include "ui-out.h"
+#include "top.h"
+
+#include "mi-main.h"
+#include "mi-cmds.h"
+#include "mi-out.h"
+#include "mi-console.h"
+
+struct mi_interp
+{
+ /* MI's output channels */
+ struct ui_file *out;
+ struct ui_file *err;
+ struct ui_file *log;
+ struct ui_file *targ;
+ struct ui_file *event_channel;
+
+ /* This is the interpreter for the mi... */
+ struct interp *mi2_interp;
+ struct interp *mi1_interp;
+ struct interp *mi_interp;
+};
+
+/* These are the interpreter setup, etc. functions for the MI interpreter */
+static void mi_execute_command_wrapper (char *cmd);
+static void mi_command_loop (int mi_version);
+static char *mi_input (char *);
+
+/* These are hooks that we put in place while doing interpreter_exec
+ so we can report interesting things that happened "behind the mi's
+ back" in this command */
+static int mi_interp_query_hook (const char *ctlstr, va_list ap);
+
+static void mi3_command_loop (void);
+static void mi2_command_loop (void);
+static void mi1_command_loop (void);
+
+static void mi_insert_notify_hooks (void);
+static void mi_remove_notify_hooks (void);
+
+static void *
+mi_interpreter_init (void)
+{
+ struct mi_interp *mi = XMALLOC (struct mi_interp);
+
+ /* Why is this a part of the mi architecture? */
+
+ mi_setup_architecture_data ();
+
+ /* HACK: We need to 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. So we set up output channels for
+ this now, and swap them in when we are run. */
+
+ raw_stdout = stdio_fileopen (stdout);
+
+ /* Create MI channels */
+ mi->out = mi_console_file_new (raw_stdout, "~", '"');
+ mi->err = mi_console_file_new (raw_stdout, "&", '"');
+ mi->log = mi->err;
+ mi->targ = mi_console_file_new (raw_stdout, "@", '"');
+ mi->event_channel = mi_console_file_new (raw_stdout, "=", 0);
+
+ return mi;
+}
+
+static int
+mi_interpreter_resume (void *data)
+{
+ struct mi_interp *mi = data;
+ /* As per hack note in mi_interpreter_init, swap in the output channels... */
+
+ gdb_setup_readline ();
+
+ 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: This is a total hack for now. PB's use of the MI implicitly
+ relies on a bug in the async support which allows asynchronous
+ commands to leak through the commmand loop. The bug involves
+ (but is not limited to) the fact that sync_execution was
+ erroneously initialized to 0. Duplicate by initializing it
+ thus here... */
+ sync_execution = 0;
+ }
+
+ gdb_stdout = mi->out;
+ /* Route error and log output through the MI */
+ gdb_stderr = mi->err;
+ gdb_stdlog = mi->log;
+ /* Route target output through the MI. */
+ gdb_stdtarg = mi->targ;
+
+ /* Replace all the hooks that we know about. There really needs to
+ be a better way of doing this... */
+ clear_interpreter_hooks ();
+
+ show_load_progress = mi_load_progress;
+
+ /* If we're _the_ interpreter, take control. */
+ if (current_interp_named_p (INTERP_MI1))
+ command_loop_hook = mi1_command_loop;
+ else if (current_interp_named_p (INTERP_MI2))
+ command_loop_hook = mi2_command_loop;
+ else if (current_interp_named_p (INTERP_MI3))
+ command_loop_hook = mi3_command_loop;
+ else
+ command_loop_hook = mi2_command_loop;
+
+ return 1;
+}
+
+static int
+mi_interpreter_suspend (void *data)
+{
+ gdb_disable_readline ();
+ return 1;
+}
+
+static int
+mi_interpreter_exec (void *data, const char *command)
+{
+ char *tmp = alloca (strlen (command) + 1);
+ strcpy (tmp, command);
+ mi_execute_command_wrapper (tmp);
+ return 1;
+}
+
+/* Never display the default gdb prompt in mi case. */
+static int
+mi_interpreter_prompt_p (void *data)
+{
+ return 0;
+}
+
+static void
+mi_interpreter_exec_continuation (struct continuation_arg *arg)
+{
+ bpstat_do_actions (&stop_bpstat);
+ if (!target_executing)
+ {
+ fputs_unfiltered ("*stopped", raw_stdout);
+ mi_out_put (uiout, raw_stdout);
+ fputs_unfiltered ("\n", raw_stdout);
+ fputs_unfiltered ("(gdb) \n", raw_stdout);
+ gdb_flush (raw_stdout);
+ do_exec_cleanups (ALL_CLEANUPS);
+ }
+ else if (target_can_async_p ())
+ {
+ add_continuation (mi_interpreter_exec_continuation, NULL);
+ }
+}
+
+enum mi_cmd_result
+mi_cmd_interpreter_exec (char *command, char **argv, int argc)
+{
+ struct interp *interp_to_use;
+ enum mi_cmd_result result = MI_CMD_DONE;
+ int i;
+ struct interp_procs *procs;
+
+ if (argc < 2)
+ {
+ xasprintf (&mi_error_message,
+ "mi_cmd_interpreter_exec: Usage: -interpreter-exec interp command");
+ return MI_CMD_ERROR;
+ }
+
+ interp_to_use = interp_lookup (argv[0]);
+ if (interp_to_use == NULL)
+ {
+ xasprintf (&mi_error_message,
+ "mi_cmd_interpreter_exec: could not find interpreter \"%s\"",
+ argv[0]);
+ return MI_CMD_ERROR;
+ }
+
+ if (!interp_exec_p (interp_to_use))
+ {
+ xasprintf (&mi_error_message,
+ "mi_cmd_interpreter_exec: interpreter \"%s\" does not support command execution",
+ argv[0]);
+ return MI_CMD_ERROR;
+ }
+
+ /* Insert the MI out hooks, making sure to also call the interpreter's hooks
+ if it has any. */
+ /* KRS: We shouldn't need this... Events should be installed and they should
+ just ALWAYS fire something out down the MI channel... */
+ mi_insert_notify_hooks ();
+
+ /* Now run the code... */
+
+ for (i = 1; i < argc; i++)
+ {
+ char *buff = NULL;
+ /* Do this in a cleaner way... We want to force execution to be
+ asynchronous for commands that run the target. */
+ if (target_can_async_p () && (strcmp (argv[0], "console") == 0))
+ {
+ int len = strlen (argv[i]);
+ buff = xmalloc (len + 2);
+ memcpy (buff, argv[i], len);
+ buff[len] = '&';
+ buff[len + 1] = '\0';
+ }
+
+ /* We had to set sync_execution = 0 for the mi (well really for Project
+ Builder's use of the mi - particularly so interrupting would work.
+ But for console commands to work, we need to initialize it to 1 -
+ since that is what the cli expects - before running the command,
+ and then set it back to 0 when we are done. */
+ sync_execution = 1;
+ if (interp_exec (interp_to_use, argv[i]) < 0)
+ {
+ mi_error_last_message ();
+ result = MI_CMD_ERROR;
+ break;
+ }
+ xfree (buff);
+ do_exec_error_cleanups (ALL_CLEANUPS);
+ sync_execution = 0;
+ }
+
+ mi_remove_notify_hooks ();
+
+ /* Okay, now let's see if the command set the inferior going...
+ Tricky point - have to do this AFTER resetting the interpreter, since
+ changing the interpreter will clear out all the continuations for
+ that interpreter... */
+
+ if (target_can_async_p () && target_executing)
+ {
+ fputs_unfiltered ("^running\n", raw_stdout);
+ add_continuation (mi_interpreter_exec_continuation, NULL);
+ }
+
+ return result;
+}
+
+/*
+ * mi_insert_notify_hooks - This inserts a number of hooks that are meant to produce
+ * async-notify ("=") MI messages while running commands in another interpreter
+ * using mi_interpreter_exec. The canonical use for this is to allow access to
+ * the gdb CLI interpreter from within the MI, while still producing MI style output
+ * when actions in the CLI command change gdb's state.
+*/
+
+static void
+mi_insert_notify_hooks (void)
+{
+ query_hook = mi_interp_query_hook;
+}
+
+static void
+mi_remove_notify_hooks (void)
+{
+ query_hook = NULL;
+}
+
+static int
+mi_interp_query_hook (const char *ctlstr, va_list ap)
+{
+ return 1;
+}
+
+static void
+mi_execute_command_wrapper (char *cmd)
+{
+ mi_execute_command (cmd, stdin == instream);
+}
+
+static void
+mi1_command_loop (void)
+{
+ mi_command_loop (1);
+}
+
+static void
+mi2_command_loop (void)
+{
+ mi_command_loop (2);
+}
+
+static void
+mi3_command_loop (void)
+{
+ mi_command_loop (3);
+}
+
+static void
+mi_command_loop (int mi_version)
+{
+#if 0
+ /* 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;
+#endif
+ /* 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 char *
+mi_input (char *buf)
+{
+ return gdb_readline (NULL);
+}
+
+extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
+
+void
+_initialize_mi_interp (void)
+{
+ static const struct interp_procs procs =
+ {
+ mi_interpreter_init, /* init_proc */
+ mi_interpreter_resume, /* resume_proc */
+ mi_interpreter_suspend, /* suspend_proc */
+ mi_interpreter_exec, /* exec_proc */
+ mi_interpreter_prompt_p /* prompt_proc_p */
+ };
+
+ /* The various interpreter levels. */
+ interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs));
+ interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs));
+ interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs));
+
+ /* "mi" selects the most recent released version. "mi2" was
+ released as part of GDB 6.0. */
+ interp_add (interp_new (INTERP_MI, NULL, mi_out_new (2), &procs));
+}
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);
}
diff --git a/contrib/gdb/gdb/mi/mi-main.h b/contrib/gdb/gdb/mi/mi-main.h
new file mode 100644
index 0000000..8e504c6
--- /dev/null
+++ b/contrib/gdb/gdb/mi/mi-main.h
@@ -0,0 +1,33 @@
+/* MI Internal Functions for GDB, the GNU debugger.
+
+ Copyright 2003 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef MI_MAIN_H
+#define MI_MAIN_H
+
+extern void mi_setup_architecture_data (void);
+
+extern 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);
+#endif
+
diff --git a/contrib/gdb/gdb/mi/mi-out.c b/contrib/gdb/gdb/mi/mi-out.c
index a92ccbe..2be9d17 100644
--- a/contrib/gdb/gdb/mi/mi-out.c
+++ b/contrib/gdb/gdb/mi/mi-out.c
@@ -1,5 +1,7 @@
/* MI Command Set - output generating routines.
- Copyright 2000 Free Software Foundation, Inc.
+
+ Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
@@ -23,12 +25,6 @@
#include "ui-out.h"
#include "mi-out.h"
-/* Convenience macro for allocting typesafe memory. */
-
-#ifndef XMALLOC
-#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
-#endif
-
struct ui_out_data
{
int suppress_field_separator;
@@ -36,6 +32,7 @@ struct ui_out_data
int mi_version;
struct ui_file *buffer;
};
+typedef struct ui_out_data mi_out_data;
/* These are the MI output functions */
@@ -89,6 +86,7 @@ struct ui_out_impl mi_ui_out_impl =
mi_message,
mi_wrap_hint,
mi_flush,
+ NULL,
1, /* Needs MI hacks. */
};
@@ -100,9 +98,6 @@ static void mi_open (struct ui_out *uiout, const char *name,
enum ui_out_type type);
static void mi_close (struct ui_out *uiout, enum ui_out_type type);
-static void out_field_fmt (struct ui_out *uiout, int fldno, char *fldname,
- char *format,...);
-
/* Mark beginning of a table */
void
@@ -111,16 +106,8 @@ mi_table_begin (struct ui_out *uiout,
int nr_rows,
const char *tblid)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
mi_open (uiout, tblid, ui_out_type_tuple);
- if (data->mi_version == 0)
- {
- if (nr_rows == 0)
- data->suppress_output = 1;
- else
- mi_open (uiout, "hdr", ui_out_type_list);
- return;
- }
mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/,
"nr_rows", nr_rows);
mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/,
@@ -133,13 +120,11 @@ mi_table_begin (struct ui_out *uiout,
void
mi_table_body (struct ui_out *uiout)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
return;
/* close the table header line if there were any headers */
mi_close (uiout, ui_out_type_list);
- if (data->mi_version == 0)
- return;
mi_open (uiout, "body", ui_out_type_list);
}
@@ -148,13 +133,8 @@ mi_table_body (struct ui_out *uiout)
void
mi_table_end (struct ui_out *uiout)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
data->suppress_output = 0;
- if (data->mi_version == 0)
- {
- mi_close (uiout, ui_out_type_tuple);
- return;
- }
mi_close (uiout, ui_out_type_list); /* body */
mi_close (uiout, ui_out_type_tuple);
}
@@ -166,14 +146,9 @@ mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
const char *col_name,
const char *colhdr)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
return;
- if (data->mi_version == 0)
- {
- mi_field_string (uiout, 0, width, alignment, 0, colhdr);
- return;
- }
mi_open (uiout, NULL, ui_out_type_tuple);
mi_field_int (uiout, 0, 0, 0, "width", width);
mi_field_int (uiout, 0, 0, 0, "alignment", alignment);
@@ -190,7 +165,7 @@ mi_begin (struct ui_out *uiout,
int level,
const char *id)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
return;
mi_open (uiout, id, type);
@@ -203,7 +178,7 @@ mi_end (struct ui_out *uiout,
enum ui_out_type type,
int level)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
return;
mi_close (uiout, type);
@@ -216,7 +191,7 @@ mi_field_int (struct ui_out *uiout, int fldno, int width,
enum ui_align alignment, const char *fldname, int value)
{
char buffer[20]; /* FIXME: how many chars long a %d can become? */
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
return;
@@ -230,7 +205,7 @@ void
mi_field_skip (struct ui_out *uiout, int fldno, int width,
enum ui_align alignment, const char *fldname)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
return;
mi_field_string (uiout, fldno, width, alignment, fldname, "");
@@ -247,7 +222,7 @@ mi_field_string (struct ui_out *uiout,
const char *fldname,
const char *string)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
return;
field_separator (uiout);
@@ -268,7 +243,7 @@ mi_field_fmt (struct ui_out *uiout, int fldno,
const char *format,
va_list args)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
return;
field_separator (uiout);
@@ -306,43 +281,18 @@ mi_wrap_hint (struct ui_out *uiout, char *identstring)
void
mi_flush (struct ui_out *uiout)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
gdb_flush (data->buffer);
}
/* local functions */
-/* Like mi_field_fmt, but takes a variable number of args
- and makes a va_list and does not insert a separator */
-
-/* VARARGS */
-static void
-out_field_fmt (struct ui_out *uiout, int fldno, char *fldname,
- char *format,...)
-{
- struct ui_out_data *data = ui_out_data (uiout);
- va_list args;
-
- field_separator (uiout);
- if (fldname)
- fprintf_unfiltered (data->buffer, "%s=\"", fldname);
- else
- fputs_unfiltered ("\"", data->buffer);
-
- va_start (args, format);
- vfprintf_unfiltered (data->buffer, format, args);
-
- fputs_unfiltered ("\"", data->buffer);
-
- va_end (args);
-}
-
/* access to ui_out format private members */
static void
field_separator (struct ui_out *uiout)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
if (data->suppress_field_separator)
data->suppress_field_separator = 0;
else
@@ -354,7 +304,7 @@ mi_open (struct ui_out *uiout,
const char *name,
enum ui_out_type type)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
field_separator (uiout);
data->suppress_field_separator = 1;
if (name)
@@ -365,10 +315,7 @@ mi_open (struct ui_out *uiout,
fputc_unfiltered ('{', data->buffer);
break;
case ui_out_type_list:
- if (data->mi_version == 0)
- fputc_unfiltered ('{', data->buffer);
- else
- fputc_unfiltered ('[', data->buffer);
+ fputc_unfiltered ('[', data->buffer);
break;
default:
internal_error (__FILE__, __LINE__, "bad switch");
@@ -379,17 +326,14 @@ static void
mi_close (struct ui_out *uiout,
enum ui_out_type type)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
switch (type)
{
case ui_out_type_tuple:
fputc_unfiltered ('}', data->buffer);
break;
case ui_out_type_list:
- if (data->mi_version == 0)
- fputc_unfiltered ('}', data->buffer);
- else
- fputc_unfiltered (']', data->buffer);
+ fputc_unfiltered (']', data->buffer);
break;
default:
internal_error (__FILE__, __LINE__, "bad switch");
@@ -402,7 +346,7 @@ mi_close (struct ui_out *uiout,
void
mi_out_buffered (struct ui_out *uiout, char *string)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
fprintf_unfiltered (data->buffer, "%s", string);
}
@@ -411,7 +355,7 @@ mi_out_buffered (struct ui_out *uiout, char *string)
void
mi_out_rewind (struct ui_out *uiout)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
ui_file_rewind (data->buffer);
}
@@ -427,18 +371,27 @@ void
mi_out_put (struct ui_out *uiout,
struct ui_file *stream)
{
- struct ui_out_data *data = ui_out_data (uiout);
+ mi_out_data *data = ui_out_data (uiout);
ui_file_put (data->buffer, do_write, stream);
ui_file_rewind (data->buffer);
}
+/* Current MI version. */
+
+int
+mi_version (struct ui_out *uiout)
+{
+ mi_out_data *data = ui_out_data (uiout);
+ return data->mi_version;
+}
+
/* initalize private members at startup */
struct ui_out *
mi_out_new (int mi_version)
{
int flags = 0;
- struct ui_out_data *data = XMALLOC (struct ui_out_data);
+ mi_out_data *data = XMALLOC (mi_out_data);
data->suppress_field_separator = 0;
data->suppress_output = 0;
data->mi_version = mi_version;
diff --git a/contrib/gdb/gdb/mi/mi-out.h b/contrib/gdb/gdb/mi/mi-out.h
index 1ae693f..817f2eb 100644
--- a/contrib/gdb/gdb/mi/mi-out.h
+++ b/contrib/gdb/gdb/mi/mi-out.h
@@ -30,4 +30,7 @@ extern void mi_out_put (struct ui_out *uiout, struct ui_file *stream);
extern void mi_out_rewind (struct ui_out *uiout);
extern void mi_out_buffered (struct ui_out *uiout, char *string);
+/* Return the version number of the current MI. */
+extern int mi_version (struct ui_out *uiout);
+
#endif /* MI_OUT_H */
diff --git a/contrib/gdb/gdb/mi/mi-parse.c b/contrib/gdb/gdb/mi/mi-parse.c
index 2ed49b8..a0ff889 100644
--- a/contrib/gdb/gdb/mi/mi-parse.c
+++ b/contrib/gdb/gdb/mi/mi-parse.c
@@ -1,5 +1,7 @@
/* MI Command Set - MI parser.
- Copyright 2000, 2001 Free Software Foundation, Inc.
+
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
@@ -26,9 +28,6 @@
#include <ctype.h>
#include "gdb_string.h"
-#undef XMALLOC
-#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
-
static void
mi_parse_argv (char *args, struct mi_parse *parse)
{
@@ -223,7 +222,7 @@ mi_parse (char *cmd)
/* For CLI and old ARGS commands, also return the remainder of the
command line as a single string. */
if (parse->cmd->args_func != NULL
- || parse->cmd->cli != NULL)
+ || parse->cmd->cli.cmd != NULL)
{
parse->args = xstrdup (chp);
}
@@ -232,8 +231,3 @@ mi_parse (char *cmd)
parse->op = MI_COMMAND;
return parse;
}
-
-void
-_initialize_mi_parse (void)
-{
-}
diff --git a/contrib/gdb/gdb/mi/mi-symbol-cmds.c b/contrib/gdb/gdb/mi/mi-symbol-cmds.c
new file mode 100644
index 0000000..1d86d21
--- /dev/null
+++ b/contrib/gdb/gdb/mi/mi-symbol-cmds.c
@@ -0,0 +1,67 @@
+/* MI Command Set - symbol commands.
+ Copyright 2003 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "mi-cmds.h"
+#include "symtab.h"
+#include "ui-out.h"
+
+/* SYMBOL-LIST-LINES:
+
+ Print the list of all pc addresses and lines of code for
+ the provided (full or base) source file name. The entries
+ are sorted in ascending PC order. */
+
+enum mi_cmd_result
+mi_cmd_symbol_list_lines (char *command, char **argv, int argc)
+{
+ char *filename;
+ struct symtab *s;
+ int i;
+ struct cleanup *cleanup_stack, *cleanup_tuple;
+
+ if (argc != 1)
+ error ("mi_cmd_symbol_list_lines: Usage: SOURCE_FILENAME");
+
+ filename = argv[0];
+ s = lookup_symtab (filename);
+
+ if (s == NULL)
+ error ("mi_cmd_symbol_list_lines: Unknown source file name.");
+
+ /* Now, dump the associated line table. The pc addresses are already
+ sorted by increasing values in the symbol table, so no need to
+ perform any other sorting. */
+
+ cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "lines");
+
+ if (LINETABLE (s) != NULL && LINETABLE (s)->nitems > 0)
+ for (i = 0; i < LINETABLE (s)->nitems; i++)
+ {
+ cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_field_core_addr (uiout, "pc", LINETABLE (s)->item[i].pc);
+ ui_out_field_int (uiout, "line", LINETABLE (s)->item[i].line);
+ do_cleanups (cleanup_tuple);
+ }
+
+ do_cleanups (cleanup_stack);
+
+ return MI_CMD_DONE;
+}
OpenPOWER on IntegriCloud