OSDN Git Service

Add mi/ and testsuite/gdb.mi/ subdirectories.
authorcagney <cagney>
Wed, 23 Feb 2000 00:25:41 +0000 (00:25 +0000)
committercagney <cagney>
Wed, 23 Feb 2000 00:25:41 +0000 (00:25 +0000)
Add --enable-gdbmi option to configury.
Add mi rules to Makefile.in
Add mi conditional output to event-top.c infrun.c main.c top.c.
Add -i=mi option.

59 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/breakpoint.c
gdb/configure
gdb/configure.in
gdb/defs.h
gdb/event-top.c
gdb/infrun.c
gdb/main.c
gdb/mi/ChangeLog-mi [new file with mode: 0644]
gdb/mi/gdbmi.texinfo [new file with mode: 0644]
gdb/mi/mi-cmd-break.c [new file with mode: 0644]
gdb/mi/mi-cmd-disas.c [new file with mode: 0644]
gdb/mi/mi-cmd-stack.c [new file with mode: 0644]
gdb/mi/mi-cmd-var.c [new file with mode: 0644]
gdb/mi/mi-cmds.c [new file with mode: 0644]
gdb/mi/mi-cmds.h [new file with mode: 0644]
gdb/mi/mi-console.c [new file with mode: 0644]
gdb/mi/mi-console.h [new file with mode: 0644]
gdb/mi/mi-getopt.c [new file with mode: 0644]
gdb/mi/mi-getopt.h [new file with mode: 0644]
gdb/mi/mi-main.c [new file with mode: 0644]
gdb/mi/mi-out.c [new file with mode: 0644]
gdb/mi/mi-out.h [new file with mode: 0644]
gdb/mi/mi-parse.c [new file with mode: 0644]
gdb/mi/mi-parse.h [new file with mode: 0644]
gdb/testsuite/ChangeLog
gdb/testsuite/configure
gdb/testsuite/configure.in
gdb/testsuite/gdb.mi/ChangeLog-mi [new file with mode: 0644]
gdb/testsuite/gdb.mi/Makefile.in [new file with mode: 0644]
gdb/testsuite/gdb.mi/basics.c [new file with mode: 0644]
gdb/testsuite/gdb.mi/configure [new file with mode: 0755]
gdb/testsuite/gdb.mi/configure.in [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-basics.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-break.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-console.c [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-console.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-disassemble.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-eval.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-hack-cli.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-read-memory.c [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-read-memory.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-regs.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-return.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-simplerun.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-stack.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-stepi.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-until.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-var-block.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-var-child.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-var-cmd.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-var-display.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-watch.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/testcmds [new file with mode: 0644]
gdb/testsuite/gdb.mi/until.c [new file with mode: 0644]
gdb/testsuite/gdb.mi/var-cmd.c [new file with mode: 0644]
gdb/testsuite/lib/mi-support.exp [new file with mode: 0644]
gdb/top.c

index 27a49c5..268f112 100644 (file)
@@ -1,3 +1,36 @@
+Mon Feb 21 13:57:27 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * configure.in (CONFIG_INITS): Fix typo, was CONFIG_INIT.
+       (ENABLE_CFLAGS): Move initialization to start of file.
+       (enable-gdbmi): Add new configure option --enable-gdbmi.  When
+       selected and an ${srcdir}/mi directory is present enable MI
+       interface.
+
+       * configure: Regenerate.
+       
+       * Makefile.in (SUBDIR_MI_OBS, SUBDIR_MI_SRCS, SUBDIR_MI_DEPS,
+       SUBDIR_MI_INITS, SUBDIR_MI_LDFLAGS, SUBDIR_MI_CFLAGS): New macros.
+       (CONFIG_OBS, CONFIG_SRCS, CONFIG_DEPS, CONFIG_INITS,
+       CONFIG_LDFLAGS): New macros.  Initialized by autoconf via
+       @CONFIG...@.
+       (INTERNAL_LDFLAGS, CDEPS, LINTFILES, DEPFILES, SOURCES,
+       INIT_FILES): Use $(CONFIG_...) instead of @CONFIG...@.
+
+       * mi: New directory. MI interface to GDB.
+
+       * defs.h (interpreter_p): Declare when UI_OUT.
+       * top.c (gdb_init): When interpreter_p, check that the interpreter
+       was recognized by one of the linked in interpreters.
+       * main.c (interpreter_p): Define.
+       (captured_main): When UI_OUT, check for ``-i <interpreter>'' option.
+       * event-top.c (display_gdb_prompt): When interpreter_p, assume
+       interpreter displays prompt.
+
+       * breakpoint.c (print_it_typical, watchpoint_check,
+       print_one_breakpoint, mention): When MI include additional
+       target status information.
+       * infrun.c (print_stop_reason, normal_stop): Ditto.
+
 2000-02-22  Jim Blandy  <jimb@redhat.com>
 
        * gdbarch.sh: Make the `default' field really default to zero, as
index 2b244ad..3982eab 100644 (file)
@@ -141,6 +141,27 @@ TUI_DIR=tui
 TUI_SRC = $(srcdir)/$(TUI_DIR)
 TUI_CFLAGS= -I$(TUI_SRC)
 
+#
+# MI sub directory definitons
+#
+SUBDIR_MI_OBS = \
+       mi-out.o mi-console.o \
+       mi-cmds.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \
+       mi-cmd-disas.o \
+       mi-main.o mi-parse.o mi-getopt.o
+SUBDIR_MI_SRCS = \
+       mi/mi-out.c mi/mi-console.c \
+       mi/mi-cmds.c \
+       mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \
+       mi/mi-cmd-disas.c \
+       mi/mi-main.c mi/mi-parse.c mi/mi-getopt.c
+SUBDIR_MI_DEPS =
+SUBDIR_MI_INITS = \
+       mi/mi-cmds.c mi/mi-parse.c mi/mi-main.c
+SUBDIR_MI_LDFLAGS=
+SUBDIR_MI_CFLAGS= \
+       -DUI_OUT=1
+
 # Opcodes currently live in one of two places.  Either they are in the
 # opcode library, typically ../opcodes, or they are in a header file
 # in INCLUDE_DIR.
@@ -200,6 +221,11 @@ LIBGUI = @LIBGUI@
 GUI_CFLAGS_X = @GUI_CFLAGS_X@
 IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X)
 
+CONFIG_OBS= @CONFIG_OBS@
+CONFIG_SRCS= @CONFIG_SRCS@
+CONFIG_DEPS= @CONFIG_DEPS@
+CONFIG_INITS= @CONFIG_INITS@
+CONFIG_LDFLAGS = @CONFIG_LDFLAGS@
 ENABLE_CFLAGS= @ENABLE_CFLAGS@
 
 # -I. for config files.
@@ -240,7 +266,7 @@ INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS)
 # Profiling options need to go here to work.
 # I think it's perfectly reasonable for a user to set -pg in CFLAGS
 # and have it work; that's why CFLAGS is here.
-INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(LDFLAGS) @CONFIG_LDFLAGS@ @HLDFLAGS@
+INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(LDFLAGS) $(CONFIG_LDFLAGS) @HLDFLAGS@
 HLDENV = @HLDENV@
 
 # We are using our own version of REGEX now to be consistent across
@@ -265,7 +291,7 @@ CLIBS = $(SIM) $(BFD) $(READLINE) $(OPCODES) $(INTL) $(LIBIBERTY) \
        $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
        $(MMALLOC) $(LIBIBERTY) $(WIN32LIBS)
 CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \
-       $(OPCODES) $(MMALLOC) $(INTL_DEPS) $(LIBIBERTY) @CONFIG_DEPS@
+       $(OPCODES) $(MMALLOC) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS)
 
 ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
 ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
@@ -449,7 +475,7 @@ SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
        tui/tui-file.h tui/tui-file.c \
        ui-file.h ui-file.c
 
-LINTFILES = $(SFILES) $(YYFILES) @CONFIG_SRCS@ init.c
+LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
 # "system" headers.  Using these in dependencies is a rather personal
 # choice. (-rich, summer 1993)
@@ -551,9 +577,9 @@ POSSLIBS = gnu-regex.c gnu-regex.h
 # Makefile.in
 
 DEPFILES = $(TDEPFILES) $(XDEPFILES) $(SER_HARDWIRE) $(NATDEPFILES) \
-          $(REMOTE_OBS) $(SIM_OBS) @CONFIG_OBS@
+          $(REMOTE_OBS) $(SIM_OBS) $(CONFIG_OBS)
 
-SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) @CONFIG_SRCS@
+SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) $(CONFIG_SRCS)
 # Don't include YYFILES (*.tab.c) because we already include *.y in SFILES,
 # and it's more useful to see it in the .y file.
 TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_NO_SRCDIR) $(ALLDEPFILES) \
@@ -693,7 +719,7 @@ uninstall: force
 # tui-file.c.
 #
 
-INIT_FILES = $(OBS) $(TSOBS) $(SUBDIR_INIT_FILES) @CONFIG_INITS@
+INIT_FILES = $(OBS) $(TSOBS) $(CONFIG_INITS)
 init.c: $(INIT_FILES)
        @echo Making init.c
        @rm -f init.c-tmp init.l-tmp
@@ -1859,4 +1885,43 @@ varobj.o: varobj.c $(defs_h) $(frame_h) $(value_h) \
        $(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) $<
 wrapper.o: wrapper.c $(defs_h) $(frame_h) $(value_h) wrapper.h
 
+#
+# MI dependencies
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the mi directory.
+
+mi_cmds_h =    $(srcdir)/mi/mi-cmds.h
+mi_out_h =     $(srcdir)/mi/mi-out.h
+mi_parse_h =   $(srcdir)/mi/mi-parse.h
+mi_getopt_h =  $(srcdir)/mi/mi-getopt.h
+mi_console_h = $(srcdir)/mi/mi-console.h
+
+mi-cmds.o: $(srcdir)/mi/mi-cmds.c $(defs_h) $(top_h) $(mi_cmds_h) $(ui_out_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmds.c
+mi-cmd-var.o: $(srcdir)/mi/mi-cmd-var.c $(defs_h) $(top_h) $(mi_cmds_h) \
+               $(ui_out_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-var.c
+mi-cmd-stack.o: $(srcdir)/mi/mi-cmd-stack.c $(defs_h) $(top_h) $(mi_cmds_h) \
+               $(ui_out_h) $(frame_h) $(value_h) $(target_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-stack.c
+mi-cmd-break.o: $(srcdir)/mi/mi-cmd-break.c $(defs_h) $(mi_cmds_h) \
+               $(ui_out_h) $(mi_getopt_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-break.c
+mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c $(defs_h) $(mi_cmds_h) \
+               $(ui_out_h) $(value_h) $(target_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-disas.c
+mi-main.o: $(srcdir)/mi/mi-main.c $(defs_h) $(top_h) $(mi_cmds_h) $(ui_out_h) \
+               $(mi_console_h) $(mi_getopt_h) $(event_loop_h) $(event_top_h) \
+               $(mi_getopt_h)
+       $(CC) -c $(INTERNAL_WARN_CFLAGS) $(srcdir)/mi/mi-main.c
+mi-out.o: $(srcdir)/mi/mi-out.c $(defs_h) $(mi_out_h) $(ui_out_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-out.c
+mi-console.o: $(srcdir)/mi/mi-console.c $(mi_out_h) $(defs_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-console.c
+mi-parse.o: $(srcdir)/mi/mi-parse.c $(defs_h) $(mi_parse_h) $(mi_cmds_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-parse.c
+mi-getopt.o: $(srcdir)/mi/mi-getopt.c $(mi_getopt_h) $(defs_h)
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-getopt.c
+
 ### end of the gdb Makefile.in.
index 4b05949..2ad3a78 100644 (file)
@@ -1,22 +1,23 @@
 /* Everything about breakpoints, for GDB.
    Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
-             Free Software Foundation, Inc.
+   Free Software Foundation, Inc.
 
-This file is part of GDB.
+   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 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.
+   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.  */
+   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 <ctype.h>
@@ -38,9 +39,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "annotate.h"
 #include "symfile.h"
 #include "objfiles.h"
+#ifdef UI_OUT
+#include "ui-out.h"
+#endif
+
+#include "gdb-events.h"
 
 /* Prototypes for local functions. */
 
+static void until_break_command_continuation (struct continuation_arg *arg);
+
 static void
 catch_command_1 PARAMS ((char *, int, int));
 
@@ -63,7 +71,7 @@ static void
 enable_command PARAMS ((char *, int));
 
 static void
-map_breakpoint_numbers PARAMS ((char *,        void (*)(struct breakpoint *)));
+map_breakpoint_numbers PARAMS ((char *, void (*)(struct breakpoint *)));
 
 static void
 ignore_command PARAMS ((char *, int));
@@ -88,9 +96,14 @@ watch_command PARAMS ((char *, int));
 static int
 can_use_hardware_watchpoint PARAMS ((struct value *));
 
+static void break_at_finish_command PARAMS ((char *, int));
+static void break_at_finish_at_depth_command PARAMS ((char *, int));
+
 void
 tbreak_command PARAMS ((char *, int));
 
+static void tbreak_at_finish_command PARAMS ((char *, int));
+
 static void
 break_command_1 PARAMS ((char *, int, int));
 
@@ -98,7 +111,7 @@ static void
 mention PARAMS ((struct breakpoint *));
 
 struct breakpoint *
-set_raw_breakpoint PARAMS ((struct symtab_and_line));
+  set_raw_breakpoint PARAMS ((struct symtab_and_line));
 
 static void
 check_duplicates PARAMS ((CORE_ADDR, asection *));
@@ -113,7 +126,7 @@ static void
 breakpoint_1 PARAMS ((int, int));
 
 static bpstat
-bpstat_alloc PARAMS ((struct breakpoint *, bpstat));
+  bpstat_alloc PARAMS ((struct breakpoint *, bpstat));
 
 static int breakpoint_cond_eval PARAMS ((PTR));
 
@@ -127,39 +140,41 @@ static void
 condition_command PARAMS ((char *, int));
 
 static int
-get_number PARAMS ((char **));
+get_number_trailer PARAMS ((char **, int));
 
 void
 set_breakpoint_count PARAMS ((int));
 
 #if 0
 static struct breakpoint *
-create_temp_exception_breakpoint PARAMS ((CORE_ADDR));
+  create_temp_exception_breakpoint PARAMS ((CORE_ADDR));
 #endif
 
-typedef enum {
-  mark_inserted,
-  mark_uninserted
-} insertion_state_t;
+typedef enum
+  {
+    mark_inserted,
+    mark_uninserted
+  }
+insertion_state_t;
 
 static int
 remove_breakpoint PARAMS ((struct breakpoint *, insertion_state_t));
 
-static int print_it_normal PARAMS ((bpstat));
+static enum print_stop_action print_it_typical PARAMS ((bpstat));
+
+static enum print_stop_action print_bp_stop_message (bpstat bs);
 
-typedef struct {
-  enum exception_event_kind kind;
-  int enable;
-} args_for_catchpoint_enable;
+typedef struct
+  {
+    enum exception_event_kind kind;
+    int enable;
+  }
+args_for_catchpoint_enable;
 
 static int watchpoint_check PARAMS ((PTR));
 
 static int cover_target_enable_exception_callback PARAMS ((PTR));
 
-static int print_it_done PARAMS ((bpstat));
-
-static int print_it_noop PARAMS ((bpstat));
-
 static void maintenance_info_breakpoints PARAMS ((char *, int));
 
 #ifdef GET_LONGJMP_TARGET
@@ -182,6 +197,54 @@ static void awatch_command PARAMS ((char *, int));
 
 static void do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
 
+static void solib_load_unload_1 PARAMS ((char *hookname,
+                                        int tempflag,
+                                        char *dll_pathname,
+                                        char *cond_string,
+                                        enum bptype bp_kind));
+
+static void create_fork_vfork_event_catchpoint PARAMS ((int tempflag, 
+                                                       char *cond_string,
+                                                       enum bptype bp_kind));
+
+static void break_at_finish_at_depth_command_1 PARAMS ((char *arg, 
+                                                       int flag, 
+                                                       int from_tty));
+
+static void break_at_finish_command_1 PARAMS ((char *arg, 
+                                              int flag, 
+                                              int from_tty));
+
+static void stop_command PARAMS ((char *arg, int from_tty));
+
+static void stopin_command PARAMS ((char *arg, int from_tty));
+
+static void stopat_command PARAMS ((char *arg, int from_tty));
+
+static char *ep_find_event_name_end PARAMS ((char *arg));
+
+static char *ep_parse_optional_if_clause PARAMS ((char **arg));
+
+static char *ep_parse_optional_filename PARAMS ((char **arg));
+
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
+static void catch_exec_command_1 PARAMS ((char *arg, int tempflag, 
+                                         int from_tty));
+#endif
+
+static void create_exception_catchpoint 
+  PARAMS ((int tempflag, char *cond_string,
+          enum exception_event_kind ex_event,
+          struct symtab_and_line * sal));
+
+static void catch_exception_command_1 
+  PARAMS ((enum exception_event_kind ex_event,
+          char *arg, int tempflag, int from_tty));
+
+static void tcatch_command PARAMS ((char *arg, int from_tty));
+
+static void ep_skip_leading_whitespace PARAMS ((char **s));
+
 /* Prototypes for exported functions. */
 
 static void
@@ -194,17 +257,13 @@ do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
    if such is available. */
 static int can_use_hw_watchpoints;
 
-void delete_command PARAMS ((char *, int));
-
 void _initialize_breakpoint PARAMS ((void));
 
 void set_breakpoint_count PARAMS ((int));
 
-extern int addressprint;               /* Print machine addresses? */
+extern int addressprint;       /* Print machine addresses? */
 
-#if defined (GET_LONGJMP_TARGET) || defined (SOLIB_ADD)
 static int internal_breakpoint_number = -1;
-#endif
 
 /* Are we executing breakpoint commands?  */
 static int executing_breakpoint_commands;
@@ -213,12 +272,12 @@ static int executing_breakpoint_commands;
    ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current
    breakpoint.  */
 
-#define ALL_BREAKPOINTS(b)  for (b = breakpoint_chain; b; b = b->next)
+#define ALL_BREAKPOINTS(B)  for (B = breakpoint_chain; B; B = B->next)
 
-#define ALL_BREAKPOINTS_SAFE(b,tmp)    \
-       for (b = breakpoint_chain;      \
-            b? (tmp=b->next, 1): 0;    \
-            b = tmp)
+#define ALL_BREAKPOINTS_SAFE(B,TMP)    \
+       for (B = breakpoint_chain;      \
+            B ? (TMP=B->next, 1): 0;   \
+            B = TMP)
 
 /* True if SHIFT_INST_REGS defined, false otherwise.  */
 
@@ -228,7 +287,7 @@ int must_shift_inst_regs =
 #else
 0
 #endif
-;
+ ;
 
 /* True if breakpoint hit counts should be displayed in breakpoint info.  */
 
@@ -242,13 +301,13 @@ struct breakpoint *breakpoint_chain;
 
 int breakpoint_count;
 
-/* Pointer to current exception event record */ 
-static struct exception_event_record * current_exception_event;
+/* Pointer to current exception event record */
+static struct exception_event_record *current_exception_event;
 
 /* Indicator of whether exception catchpoints should be nuked
    between runs of a program */
 int exception_catchpoints_are_fragile = 0;
+
 /* Indicator of when exception catchpoints set-up should be
    reinitialized -- e.g. when program is re-run */
 int exception_support_initialized = 0;
@@ -345,12 +404,16 @@ int default_breakpoint_line;
 
    Currently the string can either be a number or "$" followed by the name
    of a convenience variable.  Making it an expression wouldn't work well
-   for map_breakpoint_numbers (e.g. "4 + 5 + 6").  */
+   for map_breakpoint_numbers (e.g. "4 + 5 + 6").
+   
+   TRAILER is a character which can be found after the number; most
+   commonly this is `-'.  If you don't want a trailer, use \0.  */ 
 static int
-get_number (pp)
+get_number_trailer (pp, trailer)
      char **pp;
+     int trailer;
 {
-  int retval;
+  int retval = 0;      /* default */
   char *p = *pp;
 
   if (p == NULL)
@@ -359,7 +422,7 @@ get_number (pp)
   else if (*p == '$')
     {
       /* Make a copy of the name, so we can null-terminate it
-        to pass to lookup_internalvar().  */
+         to pass to lookup_internalvar().  */
       char *varname;
       char *start = ++p;
       value_ptr val;
@@ -370,11 +433,13 @@ get_number (pp)
       strncpy (varname, start, p - start);
       varname[p - start] = '\0';
       val = value_of_internalvar (lookup_internalvar (varname));
-      if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_INT)
-       error (
-"Convenience variables used to specify breakpoints must have integer values."
-              );
-      retval = (int) value_as_long (val);
+      if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT)
+       retval = (int) value_as_long (val);
+      else
+       {
+         printf_filtered ("Convenience variable must have integer value.\n");
+         retval = 0;
+       }
     }
   else
     {
@@ -384,16 +449,116 @@ get_number (pp)
        ++p;
       if (p == *pp)
        /* There is no number here.  (e.g. "cond a == b").  */
-       error_no_arg ("breakpoint number");
-      retval = atoi (*pp);
+       {
+         /* Skip non-numeric token */
+         while (*p && !isspace((int) *p))
+           ++p;
+         /* Return zero, which caller must interpret as error. */
+         retval = 0;
+       }
+      else
+       retval = atoi (*pp);
+    }
+  if (!(isspace (*p) || *p == '\0' || *p == trailer))
+    {
+      /* Trailing junk: return 0 and let caller print error msg. */
+      while (!(isspace (*p) || *p == '\0' || *p == trailer))
+       ++p;
+      retval = 0;
     }
-  if (!(isspace (*p) || *p == '\0'))
-    error ("breakpoint number expected");
   while (isspace (*p))
     p++;
   *pp = p;
   return retval;
 }
+
+
+/* Like get_number_trailer, but don't allow a trailer.  */
+int
+get_number (pp)
+     char **pp;
+{
+  return get_number_trailer (pp, '\0');
+}
+
+/* Parse a number or a range.
+ * A number will be of the form handled by get_number.
+ * A range will be of the form <number1> - <number2>, and 
+ * will represent all the integers between number1 and number2,
+ * inclusive.
+ *
+ * While processing a range, this fuction is called iteratively;
+ * At each call it will return the next value in the range.
+ *
+ * At the beginning of parsing a range, the char pointer PP will
+ * be advanced past <number1> and left pointing at the '-' token.
+ * Subsequent calls will not advance the pointer until the range
+ * is completed.  The call that completes the range will advance
+ * pointer PP past <number2>.
+ */
+
+int 
+get_number_or_range (pp)
+     char **pp;
+{
+  static int last_retval, end_value;
+  static char *end_ptr;
+  static int in_range = 0;
+
+  if (**pp != '-')
+    {
+      /* Default case: pp is pointing either to a solo number, 
+        or to the first number of a range.  */
+      last_retval = get_number_trailer (pp, '-');
+      if (**pp == '-')
+       {
+         char **temp;
+
+         /* This is the start of a range (<number1> - <number2>).
+            Skip the '-', parse and remember the second number,
+            and also remember the end of the final token.  */
+
+         temp = &end_ptr; 
+         end_ptr = *pp + 1; 
+         while (isspace ((int) *end_ptr))
+           end_ptr++;  /* skip white space */
+         end_value = get_number (temp);
+         if (end_value < last_retval) 
+           {
+             error ("inverted range");
+           }
+         else if (end_value == last_retval)
+           {
+             /* degenerate range (number1 == number2).  Advance the
+                token pointer so that the range will be treated as a
+                single number.  */ 
+             *pp = end_ptr;
+           }
+         else
+           in_range = 1;
+       }
+    }
+  else if (! in_range)
+    error ("negative value");
+  else
+    {
+      /* pp points to the '-' that betokens a range.  All
+        number-parsing has already been done.  Return the next
+        integer value (one greater than the saved previous value).
+        Do not advance the token pointer 'pp' until the end of range
+        is reached.  */
+
+      if (++last_retval == end_value)
+       {
+         /* End of range reached; advance token pointer.  */
+         *pp = end_ptr;
+         in_range = 0;
+       }
+    }
+  return last_retval;
+}
+
+
 \f
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
@@ -411,38 +576,40 @@ condition_command (arg, from_tty)
 
   p = arg;
   bnum = get_number (&p);
+  if (bnum == 0)
+    error ("Bad breakpoint argument: '%s'", arg);
 
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
-      {
-       if (b->cond)
-         {
-           free ((PTR)b->cond);
-           b->cond = 0;
-         }
-       if (b->cond_string != NULL)
-         free ((PTR)b->cond_string);
+    {
+      if (b->cond)
+       {
+         free ((PTR) b->cond);
+         b->cond = 0;
+       }
+      if (b->cond_string != NULL)
+       free ((PTR) b->cond_string);
 
-       if (*p == 0)
-         {
-           b->cond = 0;
-           b->cond_string = NULL;
-           if (from_tty)
-             printf_filtered ("Breakpoint %d now unconditional.\n", bnum);
-         }
-       else
-         {
-           arg = p;
-           /* I don't know if it matters whether this is the string the user
-              typed in or the decompiled expression.  */
-           b->cond_string = savestring (arg, strlen (arg));
-           b->cond = parse_exp_1 (&arg, block_for_pc (b->address), 0);
-           if (*arg)
-             error ("Junk at end of expression");
-         }
-       breakpoints_changed ();
-       return;
-      }
+      if (*p == 0)
+       {
+         b->cond = 0;
+         b->cond_string = NULL;
+         if (from_tty)
+           printf_filtered ("Breakpoint %d now unconditional.\n", bnum);
+       }
+      else
+       {
+         arg = p;
+         /* I don't know if it matters whether this is the string the user
+            typed in or the decompiled expression.  */
+         b->cond_string = savestring (arg, strlen (arg));
+         b->cond = parse_exp_1 (&arg, block_for_pc (b->address), 0);
+         if (*arg)
+           error ("Junk at end of expression");
+       }
+      breakpoints_changed ();
+      return;
+    }
 
   error ("No breakpoint number %d.", bnum);
 }
@@ -467,20 +634,23 @@ commands_command (arg, from_tty)
 
   p = arg;
   bnum = get_number (&p);
+
   if (p && *p)
     error ("Unexpected extra arguments following breakpoint number.");
-      
+
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
-      {
-       char tmpbuf[128];
-       sprintf (tmpbuf, "Type commands for when breakpoint %d is hit, one per line.", bnum);
-       l = read_command_lines (tmpbuf, from_tty);
-       free_command_lines (&b->commands);
-       b->commands = l;
-       breakpoints_changed ();
-       return;
-      }
+    {
+      char tmpbuf[128];
+      sprintf (tmpbuf, 
+              "Type commands for when breakpoint %d is hit, one per line.", 
+              bnum);
+      l = read_command_lines (tmpbuf, from_tty);
+      free_command_lines (&b->commands);
+      b->commands = l;
+      breakpoints_changed ();
+      return;
+    }
   error ("No breakpoint number %d.", bnum);
 }
 \f
@@ -506,91 +676,92 @@ read_memory_nobpt (memaddr, myaddr, len)
   if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL)
     /* No breakpoints on this machine. */
     return target_read_memory (memaddr, myaddr, len);
-  
+
   ALL_BREAKPOINTS (b)
+  {
+    if (b->type == bp_none)
+      warning ("reading through apparently deleted breakpoint #%d?", 
+              b->number);
+
+    /* memory breakpoint? */
+    if (b->type == bp_watchpoint
+       || b->type == bp_hardware_watchpoint
+       || b->type == bp_read_watchpoint
+       || b->type == bp_access_watchpoint)
+      continue;
+    /* bp in memory? */
+    if (!b->inserted)
+      continue;
+    /* Addresses and length of the part of the breakpoint that
+       we need to copy.  */
+    /* XXXX The m68k, sh and h8300 have different local and remote
+       breakpoint values.  BREAKPOINT_FROM_PC still manages to
+       correctly determine the breakpoints memory address and size
+       for these targets. */
+    bp_addr = b->address;
+    bp_size = 0;
+    if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL)
+      continue;
+    if (bp_size == 0)
+      /* bp isn't valid */
+      continue;
+    if (bp_addr + bp_size <= memaddr)
+      /* The breakpoint is entirely before the chunk of memory we
+         are reading.  */
+      continue;
+    if (bp_addr >= memaddr + len)
+      /* The breakpoint is entirely after the chunk of memory we are
+         reading. */
+      continue;
+    /* Copy the breakpoint from the shadow contents, and recurse for
+       the things before and after.  */
     {
-      if (b->type == bp_none)
-        warning ("attempted to read through apparently deleted breakpoint #%d?\n", b->number);
+      /* Offset within shadow_contents.  */
+      int bptoffset = 0;
 
-      /* memory breakpoint? */
-      if (b->type == bp_watchpoint
-         || b->type == bp_hardware_watchpoint
-         || b->type == bp_read_watchpoint
-         || b->type == bp_access_watchpoint)
-       continue;
-      /* bp in memory? */
-      if (!b->inserted)
-       continue;
-      /* Addresses and length of the part of the breakpoint that
-        we need to copy.  */
-      /* XXXX The m68k, sh and h8300 have different local and remote
-        breakpoint values.  BREAKPOINT_FROM_PC still manages to
-        correctly determine the breakpoints memory address and size
-        for these targets. */
-      bp_addr = b->address;
-      bp_size = 0;
-      if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL)
-       continue;
-      if (bp_size == 0)
-       /* bp isn't valid */
-       continue;
-      if (bp_addr + bp_size <= memaddr)
-       /* The breakpoint is entirely before the chunk of memory we
-          are reading.  */
-       continue;
-      if (bp_addr >= memaddr + len)
-       /* The breakpoint is entirely after the chunk of memory we are
-          reading. */
-       continue;
-      /* Copy the breakpoint from the shadow contents, and recurse for
-        the things before and after.  */
-      {
-       /* Offset within shadow_contents.  */
-       int bptoffset = 0;
-         
-       if (bp_addr < memaddr)
-         {
-           /* Only copy the second part of the breakpoint.  */
-           bp_size -= memaddr - bp_addr;
-           bptoffset = memaddr - bp_addr;
-           bp_addr = memaddr;
-         }
-       
-       if (bp_addr + bp_size > memaddr + len)
-         {
-           /* Only copy the first part of the breakpoint.  */
-           bp_size -= (bp_addr + bp_size) - (memaddr + len);
-         }
-       
-       memcpy (myaddr + bp_addr - memaddr, 
-               b->shadow_contents + bptoffset, bp_size);
-       
-       if (bp_addr > memaddr)
-         {
-           /* Copy the section of memory before the breakpoint.  */
-           status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
-           if (status != 0)
-             return status;
-         }
-       
-       if (bp_addr + bp_size < memaddr + len)
-         {
-           /* Copy the section of memory after the breakpoint.  */
-           status = read_memory_nobpt
-             (bp_addr + bp_size,
-              myaddr + bp_addr + bp_size - memaddr,
-              memaddr + len - (bp_addr + bp_size));
-           if (status != 0)
-             return status;
-         }
-       return 0;
-      }
+      if (bp_addr < memaddr)
+       {
+         /* Only copy the second part of the breakpoint.  */
+         bp_size -= memaddr - bp_addr;
+         bptoffset = memaddr - bp_addr;
+         bp_addr = memaddr;
+       }
+
+      if (bp_addr + bp_size > memaddr + len)
+       {
+         /* Only copy the first part of the breakpoint.  */
+         bp_size -= (bp_addr + bp_size) - (memaddr + len);
+       }
+
+      memcpy (myaddr + bp_addr - memaddr,
+             b->shadow_contents + bptoffset, bp_size);
+
+      if (bp_addr > memaddr)
+       {
+         /* Copy the section of memory before the breakpoint.  */
+         status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
+         if (status != 0)
+           return status;
+       }
+
+      if (bp_addr + bp_size < memaddr + len)
+       {
+         /* Copy the section of memory after the breakpoint.  */
+         status = read_memory_nobpt
+           (bp_addr + bp_size,
+            myaddr + bp_addr + bp_size - memaddr,
+            memaddr + len - (bp_addr + bp_size));
+         if (status != 0)
+           return status;
+       }
+      return 0;
     }
+  }
   /* Nothing overlaps.  Just call read_memory_noerr.  */
   return target_read_memory (memaddr, myaddr, len);
 }
-
 \f
+
 /* insert_breakpoints is used when starting or continuing the program.
    remove_breakpoints is used when the program stops.
    Both return zero if successful,
@@ -600,6 +771,7 @@ int
 insert_breakpoints ()
 {
   register struct breakpoint *b, *temp;
+  int return_val = 0;  /* return success code. */
   int val = 0;
   int disabled_breaks = 0;
 
@@ -608,111 +780,117 @@ insert_breakpoints ()
 
 
   ALL_BREAKPOINTS_SAFE (b, temp)
-    {
-      if (b->type != bp_watchpoint
-         && b->type != bp_hardware_watchpoint
-         && b->type != bp_read_watchpoint
-         && b->type != bp_access_watchpoint
-         && b->type != bp_catch_fork
-         && b->type != bp_catch_vfork
-         && b->type != bp_catch_exec
-          && b->type != bp_catch_throw
-          && b->type != bp_catch_catch
-         && b->enable != disabled
-         && b->enable != shlib_disabled
-          && b->enable != call_disabled
-         && ! b->inserted
-         && ! b->duplicate)
-       {
-         if (b->type == bp_hardware_breakpoint)
-           val = target_insert_hw_breakpoint(b->address, b->shadow_contents);
-         else
-           {
-             /* Check to see if breakpoint is in an overlay section;
-                if so, we should set the breakpoint at the LMA address.
-                Only if the section is currently mapped should we ALSO
-                set a break at the VMA address. */
-             if (overlay_debugging && b->section &&
-                 section_is_overlay (b->section))
-               {
-                 CORE_ADDR addr;
-
-                 addr = overlay_unmapped_address (b->address, b->section);
-                 val = target_insert_breakpoint (addr, b->shadow_contents);
-                 /* This would be the time to check val, to see if the
-                    breakpoint write to the load address succeeded.  
-                    However, this might be an ordinary occurrance, eg. if 
-                    the unmapped overlay is in ROM.  */
-                 val = 0;      /* in case unmapped address failed */
-                 if (section_is_mapped (b->section))
-                   val = target_insert_breakpoint (b->address, 
-                                                   b->shadow_contents);
-               }
-             else /* ordinary (non-overlay) address */
-               val = target_insert_breakpoint(b->address, b->shadow_contents);
-           }
-         if (val)
-           {
-             /* Can't set the breakpoint.  */
+  {
+    if (b->enable == permanent)
+      /* Permanent breakpoints cannot be inserted or removed.  */
+      continue;
+    else if (b->type != bp_watchpoint
+       && b->type != bp_hardware_watchpoint
+       && b->type != bp_read_watchpoint
+       && b->type != bp_access_watchpoint
+       && b->type != bp_catch_fork
+       && b->type != bp_catch_vfork
+       && b->type != bp_catch_exec
+       && b->type != bp_catch_throw
+       && b->type != bp_catch_catch
+       && b->enable != disabled
+       && b->enable != shlib_disabled
+       && b->enable != call_disabled
+       && !b->inserted
+       && !b->duplicate)
+      {
+       if (b->type == bp_hardware_breakpoint)
+         val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
+       else
+         {
+           /* Check to see if breakpoint is in an overlay section;
+              if so, we should set the breakpoint at the LMA address.
+              Only if the section is currently mapped should we ALSO
+              set a break at the VMA address. */
+           if (overlay_debugging && b->section &&
+               section_is_overlay (b->section))
+             {
+               CORE_ADDR addr;
+
+               addr = overlay_unmapped_address (b->address, b->section);
+               val = target_insert_breakpoint (addr, b->shadow_contents);
+               /* This would be the time to check val, to see if the
+                  breakpoint write to the load address succeeded.  
+                  However, this might be an ordinary occurrance, eg. if 
+                  the unmapped overlay is in ROM.  */
+               val = 0;        /* in case unmapped address failed */
+               if (section_is_mapped (b->section))
+                 val = target_insert_breakpoint (b->address,
+                                                 b->shadow_contents);
+             }
+           else                /* ordinary (non-overlay) address */
+             val = target_insert_breakpoint (b->address, b->shadow_contents);
+         }
+       if (val)
+         {
+           /* Can't set the breakpoint.  */
 #if defined (DISABLE_UNSETTABLE_BREAK)
-             if (DISABLE_UNSETTABLE_BREAK (b->address))
-               {
-                  /* See also: disable_breakpoints_in_shlibs. */
-                 val = 0;
-                 b->enable = shlib_disabled;
-                 if (!disabled_breaks)
-                   {
-                     target_terminal_ours_for_output ();
-                     fprintf_unfiltered (gdb_stderr,
-                                         "Cannot insert breakpoint %d:\n", b->number);
-                     printf_filtered ("Temporarily disabling shared library breakpoints:\n");
-                   }
-                 disabled_breaks = 1;
-                 printf_filtered ("%d ", b->number);
-               }
-             else
+           if (DISABLE_UNSETTABLE_BREAK (b->address))
+             {
+               /* See also: disable_breakpoints_in_shlibs. */
+               val = 0;
+               b->enable = shlib_disabled;
+               if (!disabled_breaks)
+                 {
+                   target_terminal_ours_for_output ();
+                   warning ("Cannot insert breakpoint %d:", b->number);
+                   warning ("Temporarily disabling shared library breakpoints:");
+                 }
+               disabled_breaks = 1;
+               warning ("breakpoint #%d ", b->number);
+             }
+           else
 #endif
-               {
-                 target_terminal_ours_for_output ();
-                 fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number);
+             {
+               target_terminal_ours_for_output ();
+               warning ("Cannot insert breakpoint %d:", b->number);
 #ifdef ONE_PROCESS_WRITETEXT
-                 fprintf_unfiltered (gdb_stderr,
-                                     "The same program may be running in another process.\n");
+               warning ("The same program may be running in another process.");
 #endif
-                 memory_error (val, b->address);       /* which bombs us out */
-               }
-           }
-         else
-            b->inserted = 1;
-       }
+               memory_error (val, b->address);    /* which bombs us out */
+             }
+         }
+       else
+         b->inserted = 1;
+
+       if (val)
+         return_val = val;     /* remember failure */
+      }
     else if (ep_is_exception_catchpoint (b)
-             && b->enable != disabled
-             && b->enable != shlib_disabled
-             && b->enable != call_disabled
-             && ! b->inserted
-             && ! b->duplicate)
+            && b->enable != disabled
+            && b->enable != shlib_disabled
+            && b->enable != call_disabled
+            && !b->inserted
+            && !b->duplicate)
 
       {
-         /* If we get here, we must have a callback mechanism for exception
-            events -- with g++ style embedded label support, we insert
-            ordinary breakpoints and not catchpoints. */ 
-        sprintf (message, message1, b->number); /* Format possible error message */
-        val = target_insert_breakpoint(b->address, b->shadow_contents);
-        if (val)
-          {
-           /* Couldn't set breakpoint for some reason */ 
-           target_terminal_ours_for_output ();
-           fprintf_unfiltered (gdb_stderr,
-                        "Cannot insert catchpoint %d; disabling it\n", b->number);
-           b->enable = disabled;
-          }
-        else
-          {
-              /* Bp set, now make sure callbacks are enabled */ 
+       /* If we get here, we must have a callback mechanism for exception
+          events -- with g++ style embedded label support, we insert
+          ordinary breakpoints and not catchpoints. */
+       /* Format possible error message */
+       sprintf (message, message1, b->number);
+
+       val = target_insert_breakpoint (b->address, b->shadow_contents);
+       if (val)
+         {
+           /* Couldn't set breakpoint for some reason */
+           target_terminal_ours_for_output ();
+           warning ("Cannot insert catchpoint %d; disabling it.",
+                    b->number);
+           b->enable = disabled;
+         }
+       else
+         {
+           /* Bp set, now make sure callbacks are enabled */
            int val;
-           args_for_catchpoint_enable args;  
-           args.kind = b->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW;
+           args_for_catchpoint_enable args;
+           args.kind = b->type == bp_catch_catch ? 
+             EX_EVENT_CATCH : EX_EVENT_THROW;
            args.enable = 1;
            val = catch_errors (cover_target_enable_exception_callback,
                                &args,
@@ -721,141 +899,165 @@ insert_breakpoints ()
              {
                b->inserted = 1;
              }
-           /* Check if something went wrong; val == 0 can be ignored */ 
+           /* Check if something went wrong; val == 0 can be ignored */
            if (val == -1)
              {
-               /* something went wrong */ 
+               /* something went wrong */
                target_terminal_ours_for_output ();
-               fprintf_unfiltered (gdb_stderr, "Cannot insert catchpoint %d; disabling it\n", b->number);
+               warning ("Cannot insert catchpoint %d; disabling it.",
+                        b->number);
                b->enable = disabled;
              }
-          }
+         }
+
+       if (val)
+         return_val = val;     /* remember failure */
       }
 
-      else if ((b->type == bp_hardware_watchpoint ||
-               b->type == bp_read_watchpoint ||
-               b->type == bp_access_watchpoint)
-              && b->enable == enabled
-              && ! b->inserted
-              && ! b->duplicate)
-       {
-         struct frame_info *saved_frame;
-         int saved_level, within_current_scope;
-         value_ptr mark = value_mark ();
-         value_ptr v;
-
-         /* Save the current frame and level so we can restore it after
-            evaluating the watchpoint expression on its own frame.  */
-         saved_frame = selected_frame;
-         saved_level = selected_frame_level;
-
-         /* Determine if the watchpoint is within scope.  */
-         if (b->exp_valid_block == NULL)
-           within_current_scope = 1;
-         else
-           {
-             struct frame_info *fi;
-
-             /* There might be no current frame at this moment if we are
-                resuming from a step over a breakpoint.
-                Set up current frame before trying to find the watchpoint
-                frame.  */
-             get_current_frame ();
-             fi = find_frame_addr_in_frame_chain (b->watchpoint_frame);
-             within_current_scope = (fi != NULL);
-             if (within_current_scope)
-               select_frame (fi, -1);
-           }
-       
-         if (within_current_scope)
-           {
-             /* Evaluate the expression and cut the chain of values
-                produced off from the value chain.  */
-             v = evaluate_expression (b->exp);
-             value_release_to_mark (mark);
-           
-             b->val_chain = v;
-             b->inserted = 1;
-
-             /* Look at each value on the value chain.  */
-             for ( ; v; v=v->next)
-               {
-                 /* If it's a memory location, then we must watch it.  */
-                 if (v->lval == lval_memory)
-                   {
-                     int addr, len, type;
-                   
-                     addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-                     len = TYPE_LENGTH (VALUE_TYPE (v));
-                     type = 0;
-                     if (b->type == bp_read_watchpoint)
-                       type = 1;
-                     else if (b->type == bp_access_watchpoint)
-                       type = 2;
-
-                     val = target_insert_watchpoint (addr, len, type);
-                     if (val == -1)
-                       {
-                         b->inserted = 0;
-                         break;
-                       }
-                     val = 0;
-                   }
-               }
-             /* Failure to insert a watchpoint on any memory value in the
-                value chain brings us here.  */
-             if (!b->inserted)
-               warning ("Hardware watchpoint %d: Could not insert watchpoint\n",
+    else if ((b->type == bp_hardware_watchpoint ||
+             b->type == bp_read_watchpoint ||
+             b->type == bp_access_watchpoint)
+            && b->enable == enabled
+            && !b->inserted
+            && !b->duplicate)
+      {
+       struct frame_info *saved_frame;
+       int saved_level, within_current_scope;
+       value_ptr mark = value_mark ();
+       value_ptr v;
+
+       /* Save the current frame and level so we can restore it after
+          evaluating the watchpoint expression on its own frame.  */
+       saved_frame = selected_frame;
+       saved_level = selected_frame_level;
+
+       /* Determine if the watchpoint is within scope.  */
+       if (b->exp_valid_block == NULL)
+         within_current_scope = 1;
+       else
+         {
+           struct frame_info *fi;
+
+           /* There might be no current frame at this moment if we are
+              resuming from a step over a breakpoint.
+              Set up current frame before trying to find the watchpoint
+              frame.  */
+           get_current_frame ();
+           fi = find_frame_addr_in_frame_chain (b->watchpoint_frame);
+           within_current_scope = (fi != NULL);
+           if (within_current_scope)
+             select_frame (fi, -1);
+         }
+
+       if (within_current_scope)
+         {
+           /* Evaluate the expression and cut the chain of values
+              produced off from the value chain.
+
+              Make sure the value returned isn't lazy; we use
+              laziness to determine what memory GDB actually needed
+              in order to compute the value of the expression.  */
+           v = evaluate_expression (b->exp);
+           VALUE_CONTENTS(v);
+           value_release_to_mark (mark);
+
+           b->val_chain = v;
+           b->inserted = 1;
+
+           /* Look at each value on the value chain.  */
+           for (; v; v = v->next)
+             {
+               /* If it's a memory location, and GDB actually needed
+                   its contents to evaluate the expression, then we
+                   must watch it.  */
+               if (VALUE_LVAL (v) == lval_memory
+                   && ! VALUE_LAZY (v))
+                 {
+                   CORE_ADDR addr;
+                   int len, type;
+
+                   addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                   len = TYPE_LENGTH (VALUE_TYPE (v));
+                   type   = hw_write;
+                   if (b->type == bp_read_watchpoint)
+                     type = hw_read;
+                   else if (b->type == bp_access_watchpoint)
+                     type = hw_access;
+
+                   val = target_insert_watchpoint (addr, len, type);
+                   if (val == -1)
+                     {
+                       b->inserted = 0;
+                       break;
+                     }
+                   val = 0;
+                 }
+             }
+           /* Failure to insert a watchpoint on any memory value in the
+              value chain brings us here.  */
+           if (!b->inserted)
+             {
+               remove_breakpoint (b, mark_uninserted);
+               warning ("Could not insert hardware watchpoint %d.",
                         b->number);
-           }
-         else
-           {
-             printf_filtered ("\
-Hardware watchpoint %d deleted because the program has left the block in\n\
-which its expression is valid.\n", b->number);
-             if (b->related_breakpoint)
-               b->related_breakpoint->disposition = del_at_next_stop;
-             b->disposition = del_at_next_stop;
-           }
+               val = -1;
+             }               
+         }
+       else
+         {
+           printf_filtered ("Hardware watchpoint %d deleted", b->number);
+           printf_filtered ("because the program has left the block \n");
+           printf_filtered ("in which its expression is valid.\n");
+           if (b->related_breakpoint)
+             b->related_breakpoint->disposition = del_at_next_stop;
+           b->disposition = del_at_next_stop;
+         }
 
-         /* Restore the frame and level.  */
-         if ((saved_frame != selected_frame) ||
-             (saved_level != selected_frame_level))
-           select_and_print_frame (saved_frame, saved_level);
-       } 
-      else if ((b->type == bp_catch_fork
-                || b->type == bp_catch_vfork
-                || b->type == bp_catch_exec)
-               && b->enable == enabled
-               && ! b->inserted
-               && ! b->duplicate)
-       {
-         val = -1;
-          switch (b->type)
-            {
-           case bp_catch_fork :
-             val = target_insert_fork_catchpoint (inferior_pid);
-             break;
-           case bp_catch_vfork :
-             val = target_insert_vfork_catchpoint (inferior_pid);
-             break;
-           case bp_catch_exec :
-             val = target_insert_exec_catchpoint (inferior_pid);
-             break;
-            }
-          if (val < 0)
-            {
-              target_terminal_ours_for_output ();
-              fprintf_unfiltered (gdb_stderr, "Cannot insert catchpoint %d:\n", b->number);
-            }
-          else
-            b->inserted = 1;
-        }
-    }
-  if (disabled_breaks)
-    printf_filtered ("\n");
+       /* Restore the frame and level.  */
+       if ((saved_frame != selected_frame) ||
+           (saved_level != selected_frame_level))
+         select_and_print_frame (saved_frame, saved_level);
+
+       if (val)
+         return_val = val;     /* remember failure */
+      }
+    else if ((b->type == bp_catch_fork
+             || b->type == bp_catch_vfork
+             || b->type == bp_catch_exec)
+            && b->enable == enabled
+            && !b->inserted
+            && !b->duplicate)
+      {
+       val = -1;
+       switch (b->type)
+         {
+         case bp_catch_fork:
+           val = target_insert_fork_catchpoint (inferior_pid);
+           break;
+         case bp_catch_vfork:
+           val = target_insert_vfork_catchpoint (inferior_pid);
+           break;
+         case bp_catch_exec:
+           val = target_insert_exec_catchpoint (inferior_pid);
+           break;
+         default:
+           warning ("Internal error, %s line %d.", __FILE__, __LINE__);
+           break;
+         }
+       if (val < 0)
+         {
+           target_terminal_ours_for_output ();
+           warning ("Cannot insert catchpoint %d.", b->number);
+         }
+       else
+         b->inserted = 1;
+
+       if (val)
+         return_val = val;     /* remember failure */
+      }
+  }
 
-  return val;
+  return return_val;
 }
 
 
@@ -866,42 +1068,43 @@ remove_breakpoints ()
   int val;
 
   ALL_BREAKPOINTS (b)
-    {
-      if (b->inserted)
-       {
-         val = remove_breakpoint (b, mark_uninserted);
-         if (val != 0)
-           return val;
-       }
-    }
-  return 0;
-}
+  {
+    if (b->inserted)
+      {
+       val = remove_breakpoint (b, mark_uninserted);
+       if (val != 0)
+         return val;
+      }
+  }
+  return 0;
+}
 
 int
 reattach_breakpoints (pid)
-  int  pid;
+     int pid;
 {
   register struct breakpoint *b;
   int val;
-  int  saved_inferior_pid = inferior_pid;
+  int saved_inferior_pid = inferior_pid;
 
-  inferior_pid = pid;  /* Because remove_breakpoint will use this global. */
+  /* FIXME: use a cleanup, to insure that inferior_pid gets replaced! */
+  inferior_pid = pid;  /* Because remove_breakpoint will use this global. */
   ALL_BREAKPOINTS (b)
-    {
-      if (b->inserted)
-       {
-          remove_breakpoint (b, mark_inserted);
-          if (b->type == bp_hardware_breakpoint)
-            val = target_insert_hw_breakpoint(b->address, b->shadow_contents);
-          else
-            val = target_insert_breakpoint(b->address, b->shadow_contents);
-         if (val != 0)
-            {
-              inferior_pid = saved_inferior_pid;
-              return val;
-            }
-        }
-    }
+  {
+    if (b->inserted)
+      {
+       remove_breakpoint (b, mark_inserted);
+       if (b->type == bp_hardware_breakpoint)
+         val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
+       else
+         val = target_insert_breakpoint (b->address, b->shadow_contents);
+       if (val != 0)
+         {
+           inferior_pid = saved_inferior_pid;
+           return val;
+         }
+      }
+  }
   inferior_pid = saved_inferior_pid;
   return 0;
 }
@@ -909,8 +1112,8 @@ reattach_breakpoints (pid)
 void
 update_breakpoints_after_exec ()
 {
-  struct breakpoint *  b;
-  struct breakpoint *  temp;
+  struct breakpoint *b;
+  struct breakpoint *temp;
 
   /* Doing this first prevents the badness of having delete_breakpoint()
      write a breakpoint's current "shadow contents" to lift the bp.  That
@@ -918,124 +1121,134 @@ update_breakpoints_after_exec ()
   mark_breakpoints_out ();
 
   ALL_BREAKPOINTS_SAFE (b, temp)
-    {
-      /* Solib breakpoints must be explicitly reset after an exec(). */
-      if (b->type == bp_shlib_event)
-        {
-          delete_breakpoint (b);
-          continue;
-        }
-
-      /* Step-resume breakpoints are meaningless after an exec(). */
-      if (b->type == bp_step_resume)
-        {
-          delete_breakpoint (b);
-          continue;
-        }
-
-      /* Ditto the sigtramp handler breakpoints. */
-      if (b->type == bp_through_sigtramp)
-        {
-          delete_breakpoint (b);
-          continue;
-        }
-
-      /* Ditto the exception-handling catchpoints. */
-      if ((b->type == bp_catch_catch) || (b->type == bp_catch_throw))
-        {
-          delete_breakpoint (b);
-          continue;
-        }
-
-      /* Don't delete an exec catchpoint, because else the inferior
-         won't stop when it ought!
-
-         Similarly, we probably ought to keep vfork catchpoints, 'cause
-         on this target, we may not be able to stop when the vfork is seen,
-         but only when the subsequent exec is seen.  (And because deleting
-         fork catchpoints here but not vfork catchpoints will seem mysterious
-         to users, keep those too.)
-
-         ??rehrauer: Let's hope that merely clearing out this catchpoint's
-         target address field, if any, is sufficient to have it be reset
-         automagically.  Certainly on HP-UX that's true. */
-      if ((b->type == bp_catch_exec) ||
-          (b->type == bp_catch_vfork) ||
-          (b->type == bp_catch_fork))
-        {
-          b->address = (CORE_ADDR) NULL;
-          continue;
-        }
-
-      /* bp_finish is a special case.  The only way we ought to be able
-         to see one of these when an exec() has happened, is if the user
-         caught a vfork, and then said "finish".  Ordinarily a finish just
-         carries them to the call-site of the current callee, by setting
-         a temporary bp there and resuming.  But in this case, the finish
-         will carry them entirely through the vfork & exec.
-
-         We don't want to allow a bp_finish to remain inserted now.  But
-         we can't safely delete it, 'cause finish_command has a handle to
-         the bp on a bpstat, and will later want to delete it.  There's a
-         chance (and I've seen it happen) that if we delete the bp_finish
-         here, that its storage will get reused by the time finish_command
-         gets 'round to deleting the "use to be a bp_finish" breakpoint.
-         We really must allow finish_command to delete a bp_finish.
-
-         In the absense of a general solution for the "how do we know it's
-         safe to delete something others may have handles to?" problem, what
-         we'll do here is just uninsert the bp_finish, and let finish_command
-         delete it.
-
-         (We know the bp_finish is "doomed" in the sense that it's momentary,
-         and will be deleted as soon as finish_command sees the inferior stopped.
-         So it doesn't matter that the bp's address is probably bogus in the
-         new a.out, unlike e.g., the solib breakpoints.)  */
-      if (b->type == bp_finish)
-        {
-          continue;
-        }
-
-      /* Without a symbolic address, we have little hope of the
-         pre-exec() address meaning the same thing in the post-exec()
-         a.out. */
-      if (b->addr_string == NULL)
-        {
-          delete_breakpoint (b);
-          continue;
-        }
+  {
+    /* Solib breakpoints must be explicitly reset after an exec(). */
+    if (b->type == bp_shlib_event)
+      {
+       delete_breakpoint (b);
+       continue;
+      }
 
-      /* If this breakpoint has survived the above battery of checks, then
-         it must have a symbolic address.  Be sure that it gets reevaluated
-         to a target address, rather than reusing the old evaluation.  */
-      b->address = (CORE_ADDR) NULL;
-    }
+    /* Thread event breakpoints must be set anew after an exec().  */
+    if (b->type == bp_thread_event)
+      {
+       delete_breakpoint (b);
+       continue;
+      }
+
+    /* Step-resume breakpoints are meaningless after an exec(). */
+    if (b->type == bp_step_resume)
+      {
+       delete_breakpoint (b);
+       continue;
+      }
+
+    /* Ditto the sigtramp handler breakpoints. */
+    if (b->type == bp_through_sigtramp)
+      {
+       delete_breakpoint (b);
+       continue;
+      }
+
+    /* Ditto the exception-handling catchpoints. */
+    if ((b->type == bp_catch_catch) || (b->type == bp_catch_throw))
+      {
+       delete_breakpoint (b);
+       continue;
+      }
+
+    /* Don't delete an exec catchpoint, because else the inferior
+       won't stop when it ought!
+
+       Similarly, we probably ought to keep vfork catchpoints, 'cause
+       on this target, we may not be able to stop when the vfork is
+       seen, but only when the subsequent exec is seen.  (And because
+       deleting fork catchpoints here but not vfork catchpoints will
+       seem mysterious to users, keep those too.)
+
+       ??rehrauer: Let's hope that merely clearing out this catchpoint's
+       target address field, if any, is sufficient to have it be reset
+       automagically.  Certainly on HP-UX that's true. */
+    if ((b->type == bp_catch_exec) ||
+       (b->type == bp_catch_vfork) ||
+       (b->type == bp_catch_fork))
+      {
+       b->address = (CORE_ADDR) NULL;
+       continue;
+      }
+
+    /* bp_finish is a special case.  The only way we ought to be able
+       to see one of these when an exec() has happened, is if the user
+       caught a vfork, and then said "finish".  Ordinarily a finish just
+       carries them to the call-site of the current callee, by setting
+       a temporary bp there and resuming.  But in this case, the finish
+       will carry them entirely through the vfork & exec.
+
+       We don't want to allow a bp_finish to remain inserted now.  But
+       we can't safely delete it, 'cause finish_command has a handle to
+       the bp on a bpstat, and will later want to delete it.  There's a
+       chance (and I've seen it happen) that if we delete the bp_finish
+       here, that its storage will get reused by the time finish_command
+       gets 'round to deleting the "use to be a bp_finish" breakpoint.
+       We really must allow finish_command to delete a bp_finish.
+
+       In the absense of a general solution for the "how do we know
+       it's safe to delete something others may have handles to?"
+       problem, what we'll do here is just uninsert the bp_finish, and
+       let finish_command delete it.
+
+       (We know the bp_finish is "doomed" in the sense that it's
+       momentary, and will be deleted as soon as finish_command sees
+       the inferior stopped.  So it doesn't matter that the bp's
+       address is probably bogus in the new a.out, unlike e.g., the
+       solib breakpoints.)  */
+
+    if (b->type == bp_finish)
+      {
+       continue;
+      }
+
+    /* Without a symbolic address, we have little hope of the
+       pre-exec() address meaning the same thing in the post-exec()
+       a.out. */
+    if (b->addr_string == NULL)
+      {
+       delete_breakpoint (b);
+       continue;
+      }
+
+    /* If this breakpoint has survived the above battery of checks, then
+       it must have a symbolic address.  Be sure that it gets reevaluated
+       to a target address, rather than reusing the old evaluation.  */
+    b->address = (CORE_ADDR) NULL;
+  }
 }
 
 int
 detach_breakpoints (pid)
-  int  pid;
+     int pid;
 {
   register struct breakpoint *b;
   int val;
-  int  saved_inferior_pid = inferior_pid;
+  int saved_inferior_pid = inferior_pid;
+
   if (pid == inferior_pid)
     error ("Cannot detach breakpoints of inferior_pid");
-  inferior_pid = pid;  /* Because remove_breakpoint will use this global. */
+
+  /* FIXME: use a cleanup, to insure that inferior_pid gets replaced! */
+  inferior_pid = pid;  /* Because remove_breakpoint will use this global. */
   ALL_BREAKPOINTS (b)
-    {
-      if (b->inserted)
-        {
-          val = remove_breakpoint (b, mark_inserted);
-          if (val != 0)
-            {
-              inferior_pid = saved_inferior_pid;
-              return val;
-            }
-        }
-    }
+  {
+    if (b->inserted)
+      {
+       val = remove_breakpoint (b, mark_inserted);
+       if (val != 0)
+         {
+           inferior_pid = saved_inferior_pid;
+           return val;
+         }
+      }
+  }
   inferior_pid = saved_inferior_pid;
   return 0;
 }
@@ -1043,12 +1256,17 @@ detach_breakpoints (pid)
 static int
 remove_breakpoint (b, is)
      struct breakpoint *b;
-     insertion_state_t  is;
+     insertion_state_t is;
 {
   int val;
-  
+
+  if (b->enable == permanent)
+    /* Permanent breakpoints cannot be inserted or removed.  */
+    return 0;
+
   if (b->type == bp_none)
-    warning ("attempted to remove apparently deleted breakpoint #%d?\n", b->number);
+    warning ("attempted to remove apparently deleted breakpoint #%d?", 
+            b->number);
 
   if (b->type != bp_watchpoint
       && b->type != bp_hardware_watchpoint
@@ -1059,17 +1277,16 @@ remove_breakpoint (b, is)
       && b->type != bp_catch_exec
       && b->type != bp_catch_catch
       && b->type != bp_catch_throw)
-      
     {
       if (b->type == bp_hardware_breakpoint)
-        val = target_remove_hw_breakpoint(b->address, b->shadow_contents);
+       val = target_remove_hw_breakpoint (b->address, b->shadow_contents);
       else
        {
          /* Check to see if breakpoint is in an overlay section;
             if so, we should remove the breakpoint at the LMA address.
             If that is not equal to the raw address, then we should 
             presumable remove the breakpoint there as well.  */
-         if (overlay_debugging && b->section && 
+         if (overlay_debugging && b->section &&
              section_is_overlay (b->section))
            {
              CORE_ADDR addr;
@@ -1077,46 +1294,48 @@ remove_breakpoint (b, is)
              addr = overlay_unmapped_address (b->address, b->section);
              val = target_remove_breakpoint (addr, b->shadow_contents);
              /* This would be the time to check val, to see if the
-                shadow breakpoint write to the load address succeeded.  
-                However, this might be an ordinary occurrance, eg. if 
-                the unmapped overlay is in ROM.  */
-             val = 0;  /* in case unmapped address failed */
+                shadow breakpoint write to the load address succeeded.  
+                However, this might be an ordinary occurrance, eg. if 
+                the unmapped overlay is in ROM.  */
+             val = 0;          /* in case unmapped address failed */
              if (section_is_mapped (b->section))
-               val = target_remove_breakpoint (b->address, 
+               val = target_remove_breakpoint (b->address,
                                                b->shadow_contents);
            }
-         else /* ordinary (non-overlay) address */
-           val = target_remove_breakpoint(b->address, b->shadow_contents);
+         else                  /* ordinary (non-overlay) address */
+           val = target_remove_breakpoint (b->address, b->shadow_contents);
        }
       if (val)
        return val;
       b->inserted = (is == mark_inserted);
     }
   else if ((b->type == bp_hardware_watchpoint ||
-            b->type == bp_read_watchpoint ||
-           b->type == bp_access_watchpoint)
+           b->type == bp_read_watchpoint ||
+           b->type == bp_access_watchpoint)
           && b->enable == enabled
-          && ! b->duplicate)
+          && !b->duplicate)
     {
       value_ptr v, n;
-      
+
       b->inserted = (is == mark_inserted);
       /* Walk down the saved value chain.  */
       for (v = b->val_chain; v; v = v->next)
        {
          /* For each memory reference remove the watchpoint
             at that address.  */
-         if (v->lval == lval_memory)
+         if (VALUE_LVAL (v) == lval_memory
+             && ! VALUE_LAZY (v))
            {
-             int addr, len, type;
-             
+             CORE_ADDR addr;
+             int len, type;
+
              addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
              len = TYPE_LENGTH (VALUE_TYPE (v));
-             type = 0;
+             type   = hw_write;
              if (b->type == bp_read_watchpoint)
-               type = 1;
+               type = hw_read;
              else if (b->type == bp_access_watchpoint)
-               type = 2;
+               type = hw_access;
 
              val = target_remove_watchpoint (addr, len, type);
              if (val == -1)
@@ -1126,11 +1345,11 @@ remove_breakpoint (b, is)
        }
       /* Failure to remove any of the hardware watchpoints comes here.  */
       if ((is == mark_uninserted) && (b->inserted))
-       warning ("Hardware watchpoint %d: Could not remove watchpoint\n",
+       warning ("Could not remove hardware watchpoint %d.",
                 b->number);
-      
+
       /* Free the saved value chain.  We will construct a new one
-        the next time the watchpoint is inserted.  */
+         the next time the watchpoint is inserted.  */
       for (v = b->val_chain; v; v = n)
        {
          n = v->next;
@@ -1139,49 +1358,52 @@ remove_breakpoint (b, is)
       b->val_chain = NULL;
     }
   else if ((b->type == bp_catch_fork ||
-            b->type == bp_catch_vfork ||
-           b->type == bp_catch_exec)
+           b->type == bp_catch_vfork ||
+           b->type == bp_catch_exec)
           && b->enable == enabled
-          && ! b->duplicate)
+          && !b->duplicate)
     {
       val = -1;
       switch (b->type)
-        {
-          case bp_catch_fork:
-            val = target_remove_fork_catchpoint (inferior_pid);
-            break;
-          case bp_catch_vfork :
-            val = target_remove_vfork_catchpoint (inferior_pid);
-            break;
-          case bp_catch_exec :
-            val = target_remove_exec_catchpoint (inferior_pid);
-            break;
-        }
+       {
+       case bp_catch_fork:
+         val = target_remove_fork_catchpoint (inferior_pid);
+         break;
+       case bp_catch_vfork:
+         val = target_remove_vfork_catchpoint (inferior_pid);
+         break;
+       case bp_catch_exec:
+         val = target_remove_exec_catchpoint (inferior_pid);
+         break;
+       default:
+         warning ("Internal error, %s line %d.", __FILE__, __LINE__);
+         break;
+       }
       if (val)
        return val;
       b->inserted = (is == mark_inserted);
     }
   else if ((b->type == bp_catch_catch ||
-            b->type == bp_catch_throw)
-           && b->enable == enabled
-           && ! b->duplicate)
+           b->type == bp_catch_throw)
+          && b->enable == enabled
+          && !b->duplicate)
     {
 
-      val = target_remove_breakpoint(b->address, b->shadow_contents);
+      val = target_remove_breakpoint (b->address, b->shadow_contents);
       if (val)
-        return val;
+       return val;
       b->inserted = (is == mark_inserted);
     }
   else if (ep_is_exception_catchpoint (b)
-           && b->inserted /* sometimes previous insert doesn't happen */ 
-           && b->enable == enabled
-           && ! b->duplicate)
+          && b->inserted       /* sometimes previous insert doesn't happen */
+          && b->enable == enabled
+          && !b->duplicate)
     {
 
-      val = target_remove_breakpoint(b->address, b->shadow_contents);
+      val = target_remove_breakpoint (b->address, b->shadow_contents);
       if (val)
-          return val;
-      
+       return val;
+
       b->inserted = (is == mark_inserted);
     }
 
@@ -1199,103 +1421,115 @@ mark_breakpoints_out ()
     b->inserted = 0;
 }
 
-/* Clear the "inserted" flag in all breakpoints and delete any breakpoints
-   which should go away between runs of the program.
+/* Clear the "inserted" flag in all breakpoints and delete any
+   breakpoints which should go away between runs of the program.
 
    Plus other such housekeeping that has to be done for breakpoints
    between runs.
 
-   Note: this function gets called at the end of a run (by generic_mourn_inferior)
-   and when a run begins (by init_wait_for_inferior). */ 
+   Note: this function gets called at the end of a run (by
+   generic_mourn_inferior) and when a run begins (by
+   init_wait_for_inferior). */
 
 
 
 void
 breakpoint_init_inferior (context)
-  enum inf_context context;
+     enum inf_context context;
 {
   register struct breakpoint *b, *temp;
   static int warning_needed = 0;
 
   ALL_BREAKPOINTS_SAFE (b, temp)
-    {
-      b->inserted = 0;
+  {
+    b->inserted = 0;
 
-      switch (b->type)
-       {
-       case bp_call_dummy:
-       case bp_watchpoint_scope:
+    switch (b->type)
+      {
+      case bp_call_dummy:
+      case bp_watchpoint_scope:
 
-         /* If the call dummy breakpoint is at the entry point it will
-            cause problems when the inferior is rerun, so we better
-            get rid of it. 
+       /* If the call dummy breakpoint is at the entry point it will
+          cause problems when the inferior is rerun, so we better
+          get rid of it. 
 
-            Also get rid of scope breakpoints.  */
-         delete_breakpoint (b);
-         break;
+          Also get rid of scope breakpoints.  */
+       delete_breakpoint (b);
+       break;
 
-       case bp_watchpoint:
-       case bp_hardware_watchpoint:
-       case bp_read_watchpoint:
-       case bp_access_watchpoint:
+      case bp_watchpoint:
+      case bp_hardware_watchpoint:
+      case bp_read_watchpoint:
+      case bp_access_watchpoint:
 
-         /* Likewise for watchpoints on local expressions.  */
-         if (b->exp_valid_block != NULL)
+       /* Likewise for watchpoints on local expressions.  */
+       if (b->exp_valid_block != NULL)
+         delete_breakpoint (b);
+       break;
+      default:
+       /* Likewise for exception catchpoints in dynamic-linked
+          executables where required */
+       if (ep_is_exception_catchpoint (b) &&
+           exception_catchpoints_are_fragile)
+         {
+           warning_needed = 1;
            delete_breakpoint (b);
-         break;
-       default:
-         /* Likewise for exception catchpoints in dynamic-linked
-         executables where required */
-         if (ep_is_exception_catchpoint (b) &&
-            exception_catchpoints_are_fragile)
-          {
-            warning_needed = 1;
-            delete_breakpoint (b);
-          }
-          break;
-       }
-    }
+         }
+       break;
+      }
+  }
 
   if (exception_catchpoints_are_fragile)
     exception_support_initialized = 0;
 
-  /* Don't issue the warning unless it's really needed... */ 
+  /* Don't issue the warning unless it's really needed... */
   if (warning_needed && (context != inf_exited))
     {
-      warning ("Exception catchpoints from last run were deleted, you must reinsert them explicitly");
+      warning ("Exception catchpoints from last run were deleted.");
+      warning ("You must reinsert them explicitly.");
       warning_needed = 0;
-    }  
+    }
 }
 
-/* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at PC.
-   When continuing from a location with a breakpoint,
-   we actually single step once before calling insert_breakpoints.  */
+/* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint
+   exists at PC.  It returns ordinary_breakpoint_here if it's an
+   ordinary breakpoint, or permanent_breakpoint_here if it's a
+   permanent breakpoint.
+   - When continuing from a location with an ordinary breakpoint, we
+     actually single step once before calling insert_breakpoints.
+   - When continuing from a localion with a permanent breakpoint, we
+     need to use the `SKIP_PERMANENT_BREAKPOINT' macro, provided by
+     the target, to advance the PC past the breakpoint.  */
 
-int
+enum breakpoint_here
 breakpoint_here_p (pc)
      CORE_ADDR pc;
 {
   register struct breakpoint *b;
+  int any_breakpoint_here = 0;
 
   ALL_BREAKPOINTS (b)
-    if (b->enable == enabled
-       && b->enable != shlib_disabled
-       && b->enable != call_disabled
+    if ((b->enable == enabled
+        || b->enable == permanent)
        && b->address == pc)    /* bp is enabled and matches pc */
       {
-        if (overlay_debugging &&
+       if (overlay_debugging &&
            section_is_overlay (b->section) &&
            !section_is_mapped (b->section))
          continue;             /* unmapped overlay -- can't be a match */
-        else
-         return 1;
+       else if (b->enable == permanent)
+         return permanent_breakpoint_here;
+       else
+         any_breakpoint_here = 1;
       }
 
-  return 0;
+  return any_breakpoint_here ? ordinary_breakpoint_here : 0;
 }
 
-/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(), but it
-   only returns true if there is actually a breakpoint inserted at PC.  */
+
+/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(),
+   but it only returns true if there is actually a breakpoint inserted
+   at PC.  */
 
 int
 breakpoint_inserted_here_p (pc)
@@ -1306,50 +1540,48 @@ breakpoint_inserted_here_p (pc)
   ALL_BREAKPOINTS (b)
     if (b->inserted
        && b->address == pc)    /* bp is inserted and matches pc */
-      {
-        if (overlay_debugging &&
-           section_is_overlay (b->section) &&
-           !section_is_mapped (b->section))
-         continue;             /* unmapped overlay -- can't be a match */
-        else
-         return 1;
-      }
+    {
+      if (overlay_debugging &&
+         section_is_overlay (b->section) &&
+         !section_is_mapped (b->section))
+       continue;               /* unmapped overlay -- can't be a match */
+      else
+       return 1;
+    }
 
   return 0;
 }
 
-/* Return nonzero if FRAME is a dummy frame.  We can't use PC_IN_CALL_DUMMY
-   because figuring out the saved SP would take too much time, at least using
-   get_saved_register on the 68k.  This means that for this function to
-   work right a port must use the bp_call_dummy breakpoint.  */
+/* Return nonzero if FRAME is a dummy frame.  We can't use
+   PC_IN_CALL_DUMMY because figuring out the saved SP would take too
+   much time, at least using get_saved_register on the 68k.  This
+   means that for this function to work right a port must use the
+   bp_call_dummy breakpoint.  */
 
 int
 frame_in_dummy (frame)
      struct frame_info *frame;
 {
-#ifdef CALL_DUMMY
-#ifdef USE_GENERIC_DUMMY_FRAMES 
-  return generic_pc_in_call_dummy (frame->pc, frame->frame);
-#else
   struct breakpoint *b;
 
-  ALL_BREAKPOINTS (b)
-    {
-      static ULONGEST dummy[] = CALL_DUMMY;
+  if (!CALL_DUMMY_P)
+    return 0;
 
-      if (b->type == bp_call_dummy
-         && b->frame == frame->frame
+  if (USE_GENERIC_DUMMY_FRAMES)
+    return generic_pc_in_call_dummy (frame->pc, frame->frame, frame->frame);
 
-         /* We need to check the PC as well as the frame on the sparc,
-            for signals.exp in the testsuite.  */
-         && (frame->pc
-             >= (b->address
-                 - sizeof (dummy) / sizeof (LONGEST) * REGISTER_SIZE))
-         && frame->pc <= b->address)
-       return 1;
-    }
-#endif /* GENERIC_DUMMY_FRAMES */
-#endif /* CALL_DUMMY */
+  ALL_BREAKPOINTS (b)
+  {
+    if (b->type == bp_call_dummy
+       && b->frame == frame->frame
+    /* We need to check the PC as well as the frame on the sparc,
+       for signals.exp in the testsuite.  */
+       && (frame->pc
+           >= (b->address
+             - SIZEOF_CALL_DUMMY_WORDS / sizeof (LONGEST) * REGISTER_SIZE))
+       && frame->pc <= b->address)
+      return 1;
+  }
   return 0;
 }
 
@@ -1372,25 +1604,25 @@ breakpoint_thread_match (pc, pid)
        && b->enable != call_disabled
        && b->address == pc
        && (b->thread == -1 || b->thread == thread))
-      {
-        if (overlay_debugging &&
-           section_is_overlay (b->section) &&
-           !section_is_mapped (b->section))
-         continue;             /* unmapped overlay -- can't be a match */
-        else
-         return 1;
-      }
+    {
+      if (overlay_debugging &&
+         section_is_overlay (b->section) &&
+         !section_is_mapped (b->section))
+       continue;               /* unmapped overlay -- can't be a match */
+      else
+       return 1;
+    }
 
   return 0;
 }
-
 \f
+
 /* bpstat stuff.  External routines' interfaces are documented
    in breakpoint.h.  */
 
 int
 ep_is_catchpoint (ep)
-  struct breakpoint *  ep;
+     struct breakpoint *ep;
 {
   return
     (ep->type == bp_catch_load)
@@ -1402,13 +1634,13 @@ ep_is_catchpoint (ep)
     || (ep->type == bp_catch_throw)
 
 
-    /* ??rehrauer: Add more kinds here, as are implemented... */
+  /* ??rehrauer: Add more kinds here, as are implemented... */
     ;
 }
+
 int
 ep_is_shlib_catchpoint (ep)
-  struct breakpoint *  ep;
+     struct breakpoint *ep;
 {
   return
     (ep->type == bp_catch_load)
@@ -1418,7 +1650,7 @@ ep_is_shlib_catchpoint (ep)
 
 int
 ep_is_exception_catchpoint (ep)
-  struct breakpoint *  ep;
+     struct breakpoint *ep;
 {
   return
     (ep->type == bp_catch_catch)
@@ -1444,7 +1676,7 @@ bpstat_clear (bsp)
       q = p->next;
       if (p->old_val != NULL)
        value_free (p->old_val);
-      free ((PTR)p);
+      free ((PTR) p);
       p = q;
     }
   *bsp = NULL;
@@ -1482,15 +1714,18 @@ bpstat_copy (bs)
 /* Find the bpstat associated with this breakpoint */
 
 bpstat
-bpstat_find_breakpoint(bsp, breakpoint)
+bpstat_find_breakpoint (bsp, breakpoint)
      bpstat bsp;
      struct breakpoint *breakpoint;
 {
-  if (bsp == NULL) return NULL;
+  if (bsp == NULL)
+    return NULL;
 
-  for (;bsp != NULL; bsp = bsp->next) {
-    if (bsp->breakpoint_at == breakpoint) return bsp;
-  }
+  for (; bsp != NULL; bsp = bsp->next)
+    {
+      if (bsp->breakpoint_at == breakpoint)
+       return bsp;
+    }
   return NULL;
 }
 
@@ -1504,7 +1739,7 @@ bpstat_find_breakpoint(bsp, breakpoint)
    See wait_for_inferior's use of this function.  */
 struct breakpoint *
 bpstat_find_step_resume_breakpoint (bsp)
-  bpstat  bsp;
+     bpstat bsp;
 {
   if (bsp == NULL)
     error ("Internal error (bpstat_find_step_resume_breakpoint)");
@@ -1512,8 +1747,8 @@ bpstat_find_step_resume_breakpoint (bsp)
   for (; bsp != NULL; bsp = bsp->next)
     {
       if ((bsp->breakpoint_at != NULL) &&
-          (bsp->breakpoint_at->type == bp_step_resume))
-        return bsp->breakpoint_at;
+         (bsp->breakpoint_at->type == bp_step_resume))
+       return bsp->breakpoint_at;
     }
 
   error ("Internal error (no step_resume breakpoint found)");
@@ -1541,7 +1776,7 @@ bpstat_num (bsp)
       if (b == NULL)
        return -1;              /* breakpoint that's been deleted since */
       else
-        return b->number;      /* We have its number */
+       return b->number;       /* We have its number */
     }
 }
 
@@ -1631,221 +1866,400 @@ top:
   discard_cleanups (old_chain);
 }
 
-/* This is the normal print_it function for a bpstat.  In the future,
+/* This is the normal print function for a bpstat.  In the future,
    much of this logic could (should?) be moved to bpstat_stop_status,
-   by having it set different print_it functions.
-
-   Current scheme: When we stop, bpstat_print() is called.
-   It loops through the bpstat list of things causing this stop,
-   calling the print_it function for each one. The default
-   print_it function, used for breakpoints, is print_it_normal().
-   (Also see print_it_noop() and print_it_done()).
-   
-   Return values from this routine (used by bpstat_print() to
-   decide what to do):
-   1: Means we printed something, and we do *not* desire that
-      something to be followed by a location.
-   0: Means we printed something, and we *do*  desire that
-      something to be followed by a location.
-   -1: Means we printed nothing.  */
-
-static int
-print_it_normal (bs)
+   by having it set different print_it values.
+
+   Current scheme: When we stop, bpstat_print() is called.  It loops
+   through the bpstat list of things causing this stop, calling the
+   print_bp_stop_message function on each one. The behavior of the
+   print_bp_stop_message function depends on the print_it field of
+   bpstat. If such field so indicates, call this function here.
+
+   Return values from this routine (ultimately used by bpstat_print()
+   and normal_stop() to decide what to do): 
+   PRINT_NOTHING: Means we already printed all we needed to print,
+   don't print anything else.
+   PRINT_SRC_ONLY: Means we printed something, and we do *not* desire
+   that something to be followed by a location.
+   PRINT_SCR_AND_LOC: Means we printed something, and we *do* desire
+   that something to be followed by a location.
+   PRINT_UNKNOWN: Means we printed nothing or we need to do some more
+   analysis.  */
+
+static enum print_stop_action
+print_it_typical (bs)
      bpstat bs;
 {
+#ifdef UI_OUT
+  struct cleanup *old_chain;
+  struct ui_stream *stb;
+  stb = ui_out_stream_new (uiout);
+  old_chain = make_cleanup ((make_cleanup_func) ui_out_stream_delete, stb);
+#endif /* UI_OUT */
   /* bs->breakpoint_at can be NULL if it was a momentary breakpoint
      which has since been deleted.  */
-  if (bs->breakpoint_at == NULL
-      || (bs->breakpoint_at->type != bp_breakpoint
-          && bs->breakpoint_at->type != bp_catch_load
-          && bs->breakpoint_at->type != bp_catch_unload
-          && bs->breakpoint_at->type != bp_catch_fork
-          && bs->breakpoint_at->type != bp_catch_vfork
-          && bs->breakpoint_at->type != bp_catch_exec
-          && bs->breakpoint_at->type != bp_catch_catch
-          && bs->breakpoint_at->type != bp_catch_throw
-         && bs->breakpoint_at->type != bp_hardware_breakpoint
-         && bs->breakpoint_at->type != bp_watchpoint
-         && bs->breakpoint_at->type != bp_read_watchpoint
-         && bs->breakpoint_at->type != bp_access_watchpoint
-         && bs->breakpoint_at->type != bp_hardware_watchpoint))
-    return -1;
+  if (bs->breakpoint_at == NULL)
+    return PRINT_UNKNOWN;
 
-  if (ep_is_shlib_catchpoint (bs->breakpoint_at))
+  switch (bs->breakpoint_at->type)
     {
+    case bp_breakpoint:
+    case bp_hardware_breakpoint:
+#ifdef UI_OUT
+      annotate_breakpoint (bs->breakpoint_at->number);
+      ui_out_text (uiout, "\nBreakpoint ");
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "breakpoint-hit");
+      ui_out_field_int (uiout, "bkptno", bs->breakpoint_at->number);
+      ui_out_text (uiout, ", ");
+      return PRINT_SRC_AND_LOC;
+#else
+      /* I think the user probably only wants to see one breakpoint
+         number, not all of them.  */
+      annotate_breakpoint (bs->breakpoint_at->number);
+      printf_filtered ("\nBreakpoint %d, ", bs->breakpoint_at->number);
+      return PRINT_SRC_AND_LOC;
+#endif
+      break;
+
+    case bp_shlib_event:
+      /* Did we stop because the user set the stop_on_solib_events
+        variable?  (If so, we report this as a generic, "Stopped due
+        to shlib event" message.) */
+      printf_filtered ("Stopped due to shared library event\n");
+      return PRINT_NOTHING;
+      break;
+
+    case bp_thread_event:
+      /* Not sure how we will get here. 
+        GDB should not stop for these breakpoints.  */
+      printf_filtered ("Thread Event Breakpoint: gdb should not stop!\n");
+      return PRINT_NOTHING;
+      break;
+
+    case bp_catch_load:
       annotate_catchpoint (bs->breakpoint_at->number);
       printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
-      if (bs->breakpoint_at->type == bp_catch_load)
-        printf_filtered ("loaded");
-      else if (bs->breakpoint_at->type == bp_catch_unload)
-        printf_filtered ("unloaded");
+      printf_filtered ("loaded");
       printf_filtered (" %s), ", bs->breakpoint_at->triggered_dll_pathname);
-      return 0;
-    }
-  else if (bs->breakpoint_at->type == bp_catch_fork ||
-      bs->breakpoint_at->type == bp_catch_vfork)
-    {
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case bp_catch_unload:
       annotate_catchpoint (bs->breakpoint_at->number);
       printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
-      if (bs->breakpoint_at->type == bp_catch_fork)
-        printf_filtered ("forked");
-      else if (bs->breakpoint_at->type == bp_catch_vfork)
-        printf_filtered ("vforked");
-      printf_filtered (" process %d), ", bs->breakpoint_at->forked_inferior_pid);
-      return 0;
-    }
-  else if (bs->breakpoint_at->type == bp_catch_exec)
-    {
+      printf_filtered ("unloaded");
+      printf_filtered (" %s), ", bs->breakpoint_at->triggered_dll_pathname);
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case bp_catch_fork:
       annotate_catchpoint (bs->breakpoint_at->number);
-      printf_filtered ("\nCatchpoint %d (exec'd %s), ",
-                       bs->breakpoint_at->number,
-                       bs->breakpoint_at->exec_pathname);
-      return 0;
-    }
- else if (bs->breakpoint_at->type == bp_catch_catch)
-    {
-      if (current_exception_event && (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH))
-        {
-          annotate_catchpoint (bs->breakpoint_at->number);
-          printf_filtered ("\nCatchpoint %d (exception caught), ", bs->breakpoint_at->number);
-          printf_filtered ("throw location ");
-          if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
-                printf_filtered ("%s:%d",
-                                 CURRENT_EXCEPTION_THROW_FILE,
-                                 CURRENT_EXCEPTION_THROW_LINE);
-          else
-            printf_filtered ("unknown");
-          
-          printf_filtered (", catch location ");
-          if (CURRENT_EXCEPTION_CATCH_PC  && CURRENT_EXCEPTION_CATCH_LINE)
-            printf_filtered ("%s:%d",
-                             CURRENT_EXCEPTION_CATCH_FILE,
-                             CURRENT_EXCEPTION_CATCH_LINE);
-          else
-            printf_filtered ("unknown");
-          
-          printf_filtered ("\n");
-          return 1;   /* don't bother to print location frame info */ 
-        }
-      else
-        {
-          return -1;  /* really throw, some other bpstat will handle it */
-        }
-    }
-  else if (bs->breakpoint_at->type == bp_catch_throw)
-    {
-      if (current_exception_event && (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW))
-        {
-          annotate_catchpoint (bs->breakpoint_at->number);
-          printf_filtered ("\nCatchpoint %d (exception thrown), ", bs->breakpoint_at->number);
-          printf_filtered ("throw location ");
-          if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
-                printf_filtered ("%s:%d",
-                                 CURRENT_EXCEPTION_THROW_FILE,
-                                 CURRENT_EXCEPTION_THROW_LINE);
-          else
-            printf_filtered ("unknown");
-          
-          printf_filtered (", catch location ");
-          if (CURRENT_EXCEPTION_CATCH_PC  && CURRENT_EXCEPTION_CATCH_LINE)
-            printf_filtered ("%s:%d",
-                             CURRENT_EXCEPTION_CATCH_FILE,
-                             CURRENT_EXCEPTION_CATCH_LINE);
-          else
-            printf_filtered ("unknown");
-          
-          printf_filtered ("\n");
-          return 1;   /* don't bother to print location frame info */ 
-        }
-      else
-        {
-          return -1;  /* really catch, some other bpstat willhandle it */
-        }
-    }
+      printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+      printf_filtered ("forked");
+      printf_filtered (" process %d), ", 
+                      bs->breakpoint_at->forked_inferior_pid);
+      return PRINT_SRC_AND_LOC;
+      break;
 
-  else if (bs->breakpoint_at->type == bp_breakpoint ||
-      bs->breakpoint_at->type == bp_hardware_breakpoint)
-    {
-      /* I think the user probably only wants to see one breakpoint
-        number, not all of them.  */
-      annotate_breakpoint (bs->breakpoint_at->number);
-      printf_filtered ("\nBreakpoint %d, ", bs->breakpoint_at->number);
-      return 0;
-    }
-  else if ((bs->old_val != NULL) &&
-       (bs->breakpoint_at->type == bp_watchpoint ||
-        bs->breakpoint_at->type == bp_access_watchpoint ||
-        bs->breakpoint_at->type == bp_hardware_watchpoint))
-    {
-      annotate_watchpoint (bs->breakpoint_at->number);
-      mention (bs->breakpoint_at);
-      printf_filtered ("\nOld value = ");
-      value_print (bs->old_val, gdb_stdout, 0, Val_pretty_default);
-      printf_filtered ("\nNew value = ");
-      value_print (bs->breakpoint_at->val, gdb_stdout, 0,
-                  Val_pretty_default);
-      printf_filtered ("\n");
-      value_free (bs->old_val);
-      bs->old_val = NULL;
-      /* More than one watchpoint may have been triggered.  */
-      return -1;
-    }
-  else if (bs->breakpoint_at->type == bp_access_watchpoint ||
-          bs->breakpoint_at->type == bp_read_watchpoint)
-    {
-      mention (bs->breakpoint_at);
-      printf_filtered ("\nValue = ");
-      value_print (bs->breakpoint_at->val, gdb_stdout, 0,
-                   Val_pretty_default);
-      printf_filtered ("\n");
-      return -1;
-    }
-  /* We can't deal with it.  Maybe another member of the bpstat chain can.  */
-  return -1;
-}
-
-/* Print a message indicating what happened.
-   This is called from normal_stop().
-   The input to this routine is the head of the bpstat list - a list
-   of the eventpoints that caused this stop.
-   This routine calls the "print_it" routine(s) associated
-   with these eventpoints. This will print (for example)
-   the "Breakpoint n," part of the output.
-   The return value of this routine is one of:
-
-   -1: Means we printed nothing
-   0: Means we printed something, and expect subsequent
-      code to print the location. An example is 
-      "Breakpoint 1, " which should be followed by
-      the location.
-   1 : Means we printed something, but there is no need
-       to also print the location part of the message.
-       An example is the catch/throw messages, which
-       don't require a location appended to the end.  */ 
+    case bp_catch_vfork:
+      annotate_catchpoint (bs->breakpoint_at->number);
+      printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+      printf_filtered ("vforked");
+      printf_filtered (" process %d), ", 
+                      bs->breakpoint_at->forked_inferior_pid);
+      return PRINT_SRC_AND_LOC;
+      break;
 
-int
-bpstat_print (bs)
-     bpstat bs;
-{
-  int val;
-  
-  if (bs == NULL)
-    return -1;
+    case bp_catch_exec:
+      annotate_catchpoint (bs->breakpoint_at->number);
+      printf_filtered ("\nCatchpoint %d (exec'd %s), ",
+                      bs->breakpoint_at->number,
+                      bs->breakpoint_at->exec_pathname);
+      return PRINT_SRC_AND_LOC;
+      break;
 
-  val = (*bs->print_it) (bs);
-  if (val >= 0)
-    return val;
-  
-  /* Maybe another breakpoint in the chain caused us to stop.
-     (Currently all watchpoints go on the bpstat whether hit or
-     not.  That probably could (should) be changed, provided care is taken
-     with respect to bpstat_explains_signal).  */
-  if (bs->next)
-    return bpstat_print (bs->next);
+    case bp_catch_catch:
+      if (current_exception_event && 
+         (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH))
+       {
+         annotate_catchpoint (bs->breakpoint_at->number);
+         printf_filtered ("\nCatchpoint %d (exception caught), ", 
+                          bs->breakpoint_at->number);
+         printf_filtered ("throw location ");
+         if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
+           printf_filtered ("%s:%d",
+                            CURRENT_EXCEPTION_THROW_FILE,
+                            CURRENT_EXCEPTION_THROW_LINE);
+         else
+           printf_filtered ("unknown");
 
-  /* We reached the end of the chain without printing anything.  */
-  return -1;
-}
+         printf_filtered (", catch location ");
+         if (CURRENT_EXCEPTION_CATCH_PC && CURRENT_EXCEPTION_CATCH_LINE)
+           printf_filtered ("%s:%d",
+                            CURRENT_EXCEPTION_CATCH_FILE,
+                            CURRENT_EXCEPTION_CATCH_LINE);
+         else
+           printf_filtered ("unknown");
+
+         printf_filtered ("\n");
+         /* don't bother to print location frame info */
+         return PRINT_SRC_ONLY;
+       }
+      else
+       {
+         /* really throw, some other bpstat will handle it */
+         return PRINT_UNKNOWN; 
+       }
+      break;
+
+    case bp_catch_throw:
+      if (current_exception_event && 
+         (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW))
+       {
+         annotate_catchpoint (bs->breakpoint_at->number);
+         printf_filtered ("\nCatchpoint %d (exception thrown), ",
+                          bs->breakpoint_at->number);
+         printf_filtered ("throw location ");
+         if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
+           printf_filtered ("%s:%d",
+                            CURRENT_EXCEPTION_THROW_FILE,
+                            CURRENT_EXCEPTION_THROW_LINE);
+         else
+           printf_filtered ("unknown");
+
+         printf_filtered (", catch location ");
+         if (CURRENT_EXCEPTION_CATCH_PC && CURRENT_EXCEPTION_CATCH_LINE)
+           printf_filtered ("%s:%d",
+                            CURRENT_EXCEPTION_CATCH_FILE,
+                            CURRENT_EXCEPTION_CATCH_LINE);
+         else
+           printf_filtered ("unknown");
+
+         printf_filtered ("\n");
+         /* don't bother to print location frame info */
+         return PRINT_SRC_ONLY; 
+       }
+      else
+       {
+         /* really catch, some other bpstat will handle it */
+         return PRINT_UNKNOWN; 
+       }
+      break;
+
+    case bp_watchpoint:
+    case bp_hardware_watchpoint:
+      if (bs->old_val != NULL)
+       {
+         annotate_watchpoint (bs->breakpoint_at->number);
+#ifdef UI_OUT
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_field_string (uiout, "reason", "watchpoint-trigger");
+         mention (bs->breakpoint_at);
+         ui_out_list_begin (uiout, "value");
+         ui_out_text (uiout, "\nOld value = ");
+         value_print (bs->old_val, stb->stream, 0, Val_pretty_default);
+         ui_out_field_stream (uiout, "old", stb);
+         ui_out_text (uiout, "\nNew value = ");
+         value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default);
+         ui_out_field_stream (uiout, "new", stb);
+         ui_out_list_end (uiout);
+         ui_out_text (uiout, "\n");
+#else
+         mention (bs->breakpoint_at);
+         printf_filtered ("\nOld value = ");
+         value_print (bs->old_val, gdb_stdout, 0, Val_pretty_default);
+         printf_filtered ("\nNew value = ");
+         value_print (bs->breakpoint_at->val, gdb_stdout, 0,
+                      Val_pretty_default);
+         printf_filtered ("\n");
+#endif
+         value_free (bs->old_val);
+         bs->old_val = NULL;
+       }
+      /* More than one watchpoint may have been triggered.  */
+      return PRINT_UNKNOWN;
+      break;
+
+    case bp_read_watchpoint:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "read-watchpoint-trigger");
+      mention (bs->breakpoint_at);
+      ui_out_list_begin (uiout, "value");
+      ui_out_text (uiout, "\nValue = ");
+      value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default);
+      ui_out_field_stream (uiout, "value", stb);
+      ui_out_list_end (uiout);
+      ui_out_text (uiout, "\n");
+#else
+      mention (bs->breakpoint_at);
+      printf_filtered ("\nValue = ");
+      value_print (bs->breakpoint_at->val, gdb_stdout, 0,
+                  Val_pretty_default);
+      printf_filtered ("\n");
+#endif
+      return PRINT_UNKNOWN;
+      break;
+
+    case bp_access_watchpoint:
+#ifdef UI_OUT
+      if (bs->old_val != NULL)     
+       {
+         annotate_watchpoint (bs->breakpoint_at->number);
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
+         mention (bs->breakpoint_at);
+         ui_out_list_begin (uiout, "value");
+         ui_out_text (uiout, "\nOld value = ");
+         value_print (bs->old_val, stb->stream, 0, Val_pretty_default);
+         ui_out_field_stream (uiout, "old", stb);
+         value_free (bs->old_val);
+         bs->old_val = NULL;
+         ui_out_text (uiout, "\nNew value = ");
+       }
+      else 
+       {
+         mention (bs->breakpoint_at);
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_list_begin (uiout, "value");
+         ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
+         ui_out_text (uiout, "\nValue = ");
+       }
+      value_print (bs->breakpoint_at->val, stb->stream, 0,Val_pretty_default);
+      ui_out_field_stream (uiout, "new", stb);
+      ui_out_list_end (uiout);
+      ui_out_text (uiout, "\n");
+#else
+      if (bs->old_val != NULL)     
+       {
+         annotate_watchpoint (bs->breakpoint_at->number);
+         mention (bs->breakpoint_at);
+         printf_filtered ("\nOld value = ");
+         value_print (bs->old_val, gdb_stdout, 0, Val_pretty_default);
+         value_free (bs->old_val);
+         bs->old_val = NULL;
+         printf_filtered ("\nNew value = ");
+       }
+      else 
+       {
+         mention (bs->breakpoint_at);
+         printf_filtered ("\nValue = ");
+       }
+      value_print (bs->breakpoint_at->val, gdb_stdout, 0,
+                  Val_pretty_default);
+      printf_filtered ("\n");
+#endif
+      return PRINT_UNKNOWN;
+      break;
+
+    /* Fall through, we don't deal with these types of breakpoints
+       here. */
+
+    case bp_finish:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "function-finished");
+#endif
+      return PRINT_UNKNOWN;
+      break;
+
+    case bp_until:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "location-reached");
+#endif
+      return PRINT_UNKNOWN;
+      break;
+
+    case bp_none:
+    case bp_longjmp:
+    case bp_longjmp_resume:
+    case bp_step_resume:
+    case bp_through_sigtramp:
+    case bp_watchpoint_scope:
+    case bp_call_dummy:
+    default:
+      return PRINT_UNKNOWN;
+    }
+}
+
+/* Generic routine for printing messages indicating why we
+   stopped. The behavior of this function depends on the value
+   'print_it' in the bpstat structure.  Under some circumstances we
+   may decide not to print anything here and delegate the task to
+   normal_stop(). */
+
+static enum print_stop_action
+print_bp_stop_message (bpstat bs)
+{
+  switch (bs->print_it)
+    {
+    case print_it_noop:
+      /* Nothing should be printed for this bpstat entry. */
+      return PRINT_UNKNOWN;
+      break;
+
+    case print_it_done:
+      /* We still want to print the frame, but we already printed the
+         relevant messages. */
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case print_it_normal:
+      /* Normal case, we handle everything in print_it_typical. */
+      return print_it_typical (bs);
+      break;
+    default:
+      internal_error ("print_bp_stop_message: unrecognized enum value");
+      break;
+    }
+}
+
+/* Print a message indicating what happened.  This is called from
+   normal_stop().  The input to this routine is the head of the bpstat
+   list - a list of the eventpoints that caused this stop.  This
+   routine calls the generic print routine for printing a message
+   about reasons for stopping.  This will print (for example) the
+   "Breakpoint n," part of the output.  The return value of this
+   routine is one of:
+
+   PRINT_UNKNOWN: Means we printed nothing
+   PRINT_SRC_AND_LOC: Means we printed something, and expect subsequent
+   code to print the location. An example is 
+   "Breakpoint 1, " which should be followed by
+   the location.
+   PRINT_SRC_ONLY: Means we printed something, but there is no need
+   to also print the location part of the message.
+   An example is the catch/throw messages, which
+   don't require a location appended to the end.  
+   PRINT_NOTHING: We have done some printing and we don't need any 
+   further info to be printed.*/
+
+enum print_stop_action
+bpstat_print (bs)
+     bpstat bs;
+{
+  int val;
+
+  /* Maybe another breakpoint in the chain caused us to stop.
+     (Currently all watchpoints go on the bpstat whether hit or not.
+     That probably could (should) be changed, provided care is taken
+     with respect to bpstat_explains_signal).  */
+  for (; bs; bs = bs->next)
+    {
+      val = print_bp_stop_message (bs);
+      if (val == PRINT_SRC_ONLY 
+         || val == PRINT_SRC_AND_LOC 
+         || val == PRINT_NOTHING)
+       return val;
+    }
+
+  /* We reached the end of the chain, or we got a null BS to start
+     with and nothing was printed. */
+  return PRINT_UNKNOWN;
+}
 
 /* Evaluate the expression EXP and return 1 if value is zero.
    This is used inside a catch_errors to evaluate the breakpoint condition. 
@@ -1857,7 +2271,7 @@ breakpoint_cond_eval (exp)
      PTR exp;
 {
   value_ptr mark = value_mark ();
-  int i = !value_true (evaluate_expression ((struct expression *)exp));
+  int i = !value_true (evaluate_expression ((struct expression *) exp));
   value_free_to_mark (mark);
   return i;
 }
@@ -1867,7 +2281,7 @@ breakpoint_cond_eval (exp)
 static bpstat
 bpstat_alloc (b, cbs)
      register struct breakpoint *b;
-     bpstat cbs;                       /* Current "bs" value */
+     bpstat cbs;               /* Current "bs" value */
 {
   bpstat bs;
 
@@ -1911,9 +2325,9 @@ watchpoint_check (p)
   else
     {
       /* There is no current frame at this moment.  If we're going to have
-        any chance of handling watchpoints on local variables, we'll need
-        the frame chain (so we can determine if we're in scope).  */
-      reinit_frame_cache();
+         any chance of handling watchpoints on local variables, we'll need
+         the frame chain (so we can determine if we're in scope).  */
+      reinit_frame_cache ();
       fr = find_frame_addr_in_frame_chain (b->watchpoint_frame);
       within_current_scope = (fr != NULL);
       if (within_current_scope)
@@ -1922,13 +2336,13 @@ watchpoint_check (p)
           the user.  */
        select_frame (fr, -1);
     }
-      
+
   if (within_current_scope)
     {
       /* We use value_{,free_to_}mark because it could be a
          *long* time before we return to the command level and
-        call free_all_values.  We can't call free_all_values because
-        we might be in the middle of evaluating a function call.  */
+         call free_all_values.  We can't call free_all_values because
+         we might be in the middle of evaluating a function call.  */
 
       value_ptr mark = value_mark ();
       value_ptr new_val = evaluate_expression (bs->breakpoint_at->exp);
@@ -1952,16 +2366,30 @@ watchpoint_check (p)
   else
     {
       /* This seems like the only logical thing to do because
-        if we temporarily ignored the watchpoint, then when
-        we reenter the block in which it is valid it contains
-        garbage (in the case of a function, it may have two
-        garbage values, one before and one after the prologue).
-        So we can't even detect the first assignment to it and
-        watch after that (since the garbage may or may not equal
-        the first value assigned).  */
+         if we temporarily ignored the watchpoint, then when
+         we reenter the block in which it is valid it contains
+         garbage (in the case of a function, it may have two
+         garbage values, one before and one after the prologue).
+         So we can't even detect the first assignment to it and
+         watch after that (since the garbage may or may not equal
+         the first value assigned).  */
+      /* We print all the stop information in print_it_typical(), but
+        in this case, by the time we call print_it_typical() this bp
+        will be deleted already. So we have no choice but print the
+        information here. */
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "watchpoint-scope");
+      ui_out_text (uiout, "\nWatchpoint ");
+      ui_out_field_int (uiout, "wpnum", bs->breakpoint_at->number);
+      ui_out_text (uiout, " deleted because the program has left the block in\n\
+which its expression is valid.\n");     
+#else
       printf_filtered ("\
 Watchpoint %d deleted because the program has left the block in\n\
 which its expression is valid.\n", bs->breakpoint_at->number);
+#endif 
+
       if (b->related_breakpoint)
        b->related_breakpoint->disposition = del_at_next_stop;
       b->disposition = del_at_next_stop;
@@ -1970,40 +2398,6 @@ which its expression is valid.\n", bs->breakpoint_at->number);
     }
 }
 
-/* This is used when everything which needs to be printed has
-   already been printed.  But we still want to print the frame.  */
-
-/* Background: When we stop, bpstat_print() is called.
-   It loops through the bpstat list of things causing this stop,
-   calling the print_it function for each one. The default
-   print_it function, used for breakpoints, is print_it_normal().
-   Also see print_it_noop() and print_it_done() are the other 
-   two possibilities. See comments in bpstat_print() and
-   in header of print_it_normal() for more detail.  */
-
-static int
-print_it_done (bs)
-     bpstat bs;
-{
-  return 0;
-}
-
-/* This is used when nothing should be printed for this bpstat entry.  */
-/* Background: When we stop, bpstat_print() is called.
-   It loops through the bpstat list of things causing this stop,
-   calling the print_it function for each one. The default
-   print_it function, used for breakpoints, is print_it_normal().
-   Also see print_it_noop() and print_it_done() are the other 
-   two possibilities. See comments in bpstat_print() and
-   in header of print_it_normal() for more detail.  */
-
-static int
-print_it_noop (bs)
-     bpstat bs;
-{
-  return -1;
-}
-
 /* Get a bpstat associated with having just stopped at address *PC
    and frame address CORE_ADDRESS.  Update *PC to point at the
    breakpoint (if we hit a breakpoint).  NOT_A_BREAKPOINT is nonzero
@@ -2013,16 +2407,16 @@ print_it_noop (bs)
 /* Determine whether we stopped at a breakpoint, etc, or whether we
    don't understand this stop.  Result is a chain of bpstat's such that:
 
-       if we don't understand the stop, the result is a null pointer.
+   if we don't understand the stop, the result is a null pointer.
 
-       if we understand why we stopped, the result is not null.
+   if we understand why we stopped, the result is not null.
 
-       Each element of the chain refers to a particular breakpoint or
-       watchpoint at which we have stopped.  (We may have stopped for
-       several reasons concurrently.)
+   Each element of the chain refers to a particular breakpoint or
+   watchpoint at which we have stopped.  (We may have stopped for
+   several reasons concurrently.)
 
-       Each element of the chain has valid next, breakpoint_at,
-       commands, FIXME??? fields.  */
+   Each element of the chain has valid next, breakpoint_at,
+   commands, FIXME??? fields.  */
 
 bpstat
 bpstat_stop_status (pc, not_a_breakpoint)
@@ -2038,95 +2432,157 @@ bpstat_stop_status (pc, not_a_breakpoint)
   /* Pointer to the last thing in the chain currently.  */
   bpstat bs = root_bs;
   static char message1[] =
-            "Error evaluating expression for watchpoint %d\n";
-  char message[sizeof (message1) + 30 /* slop */];
+  "Error evaluating expression for watchpoint %d\n";
+  char message[sizeof (message1) + 30 /* slop */ ];
 
   /* Get the address where the breakpoint would have been.  */
-  bp_addr = *pc - DECR_PC_AFTER_BREAK;
+  bp_addr = *pc - (not_a_breakpoint && !SOFTWARE_SINGLE_STEP_P ? 
+                   0 : DECR_PC_AFTER_BREAK);
 
   ALL_BREAKPOINTS_SAFE (b, temp)
-    {
-      if (b->enable == disabled
-         || b->enable == shlib_disabled
-          || b->enable == call_disabled)
-       continue;
-
-      if (b->type != bp_watchpoint
-         && b->type != bp_hardware_watchpoint
-          && b->type != bp_read_watchpoint
-          && b->type != bp_access_watchpoint
-         && b->type != bp_hardware_breakpoint
-          && b->type != bp_catch_fork
-          && b->type != bp_catch_vfork
-          && b->type != bp_catch_exec
-          && b->type != bp_catch_catch
-          && b->type != bp_catch_throw)         /* a non-watchpoint bp */
-       if (b->address != bp_addr ||            /* address doesn't match or */
-           (overlay_debugging &&               /* overlay doesn't match */
-            section_is_overlay (b->section) &&
-            !section_is_mapped (b->section)))
-         continue;
-
-      if (b->type == bp_hardware_breakpoint
-         && b->address != (*pc - DECR_PC_AFTER_HW_BREAK))
+  {
+    if (b->enable == disabled
+       || b->enable == shlib_disabled
+       || b->enable == call_disabled)
+      continue;
+
+    if (b->type != bp_watchpoint
+       && b->type != bp_hardware_watchpoint
+       && b->type != bp_read_watchpoint
+       && b->type != bp_access_watchpoint
+       && b->type != bp_hardware_breakpoint
+       && b->type != bp_catch_fork
+       && b->type != bp_catch_vfork
+       && b->type != bp_catch_exec
+       && b->type != bp_catch_catch
+       && b->type != bp_catch_throw)   /* a non-watchpoint bp */
+      if (b->address != bp_addr ||     /* address doesn't match or */
+         (overlay_debugging && /* overlay doesn't match */
+          section_is_overlay (b->section) &&
+          !section_is_mapped (b->section)))
        continue;
 
-      if (b->type != bp_watchpoint
-         && b->type != bp_hardware_watchpoint
-         && b->type != bp_read_watchpoint
-         && b->type != bp_access_watchpoint
-         && not_a_breakpoint)
-       continue;
+    if (b->type == bp_hardware_breakpoint
+       && b->address != (*pc - DECR_PC_AFTER_HW_BREAK))
+      continue;
 
-      /* Is this a catchpoint of a load or unload?  If so, did we
-         get a load or unload of the specified library?  If not,
-         ignore it. */
-      if ((b->type == bp_catch_load)
+    /* Is this a catchpoint of a load or unload?  If so, did we
+       get a load or unload of the specified library?  If not,
+       ignore it. */
+    if ((b->type == bp_catch_load)
 #if defined(SOLIB_HAVE_LOAD_EVENT)
-          && (!SOLIB_HAVE_LOAD_EVENT(inferior_pid)
-              || ((b->dll_pathname != NULL)
-                  && (strcmp (b->dll_pathname, SOLIB_LOADED_LIBRARY_PATHNAME(inferior_pid)) != 0)))
+       && (!SOLIB_HAVE_LOAD_EVENT (inferior_pid)
+           || ((b->dll_pathname != NULL)
+               && (strcmp (b->dll_pathname, 
+                           SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid)) 
+                   != 0)))
 #endif
-                 )
-        continue;
-      if ((b->type == bp_catch_unload)
+      )
+      continue;
+
+    if ((b->type == bp_catch_unload)
 #if defined(SOLIB_HAVE_UNLOAD_EVENT)
-          && (!SOLIB_HAVE_UNLOAD_EVENT(inferior_pid)
-              || ((b->dll_pathname != NULL)
-                  && (strcmp (b->dll_pathname, SOLIB_UNLOADED_LIBRARY_PATHNAME(inferior_pid)) != 0)))
+       && (!SOLIB_HAVE_UNLOAD_EVENT (inferior_pid)
+           || ((b->dll_pathname != NULL)
+               && (strcmp (b->dll_pathname, 
+                           SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid)) 
+                   != 0)))
 #endif
-         )
-        continue;
-      if ((b->type == bp_catch_fork)
-          && ! target_has_forked (inferior_pid, &b->forked_inferior_pid))
-          continue;
-      if ((b->type == bp_catch_vfork)
-          && ! target_has_vforked (inferior_pid, &b->forked_inferior_pid))
-          continue;
-      if ((b->type == bp_catch_exec)
-         && ! target_has_execd (inferior_pid, &b->exec_pathname))
-       continue;
+      )
+      continue;
 
-      if (ep_is_exception_catchpoint (b) &&
-          !(current_exception_event = target_get_current_exception_event ()))
-        continue;
+    if ((b->type == bp_catch_fork)
+       && !target_has_forked (inferior_pid, &b->forked_inferior_pid))
+      continue;
 
-      /* Come here if it's a watchpoint, or if the break address matches */
+    if ((b->type == bp_catch_vfork)
+       && !target_has_vforked (inferior_pid, &b->forked_inferior_pid))
+      continue;
 
-      bs = bpstat_alloc (b, bs);       /* Alloc a bpstat to explain stop */
+    if ((b->type == bp_catch_exec)
+       && !target_has_execd (inferior_pid, &b->exec_pathname))
+      continue;
 
-      /* Watchpoints may change this, if not found to have triggered. */
-      bs->stop = 1;
-      bs->print = 1;
+    if (ep_is_exception_catchpoint (b) &&
+       !(current_exception_event = target_get_current_exception_event ()))
+      continue;
 
-      sprintf (message, message1, b->number);
-      if (b->type == bp_watchpoint || b->type == bp_hardware_watchpoint)
-       {
-         switch (catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL))
+    /* Come here if it's a watchpoint, or if the break address matches */
+
+    bs = bpstat_alloc (b, bs); /* Alloc a bpstat to explain stop */
+
+    /* Watchpoints may change this, if not found to have triggered. */
+    bs->stop = 1;
+    bs->print = 1;
+
+    sprintf (message, message1, b->number);
+    if (b->type == bp_watchpoint ||
+       b->type == bp_hardware_watchpoint)
+      {
+       switch (catch_errors (watchpoint_check, bs, message, 
+                             RETURN_MASK_ALL))
+         {
+         case WP_DELETED:
+           /* We've already printed what needs to be printed.  */
+           /* Actually this is superfluous, because by the time we
+               call print_it_typical() the wp will be already deleted,
+               and the function will return immediately. */
+           bs->print_it = print_it_done;
+           /* Stop.  */
+           break;
+         case WP_VALUE_CHANGED:
+           /* Stop.  */
+           ++(b->hit_count);
+           break;
+         case WP_VALUE_NOT_CHANGED:
+           /* Don't stop.  */
+           bs->print_it = print_it_noop;
+           bs->stop = 0;
+           continue;
+         default:
+           /* Can't happen.  */
+           /* FALLTHROUGH */
+         case 0:
+           /* Error from catch_errors.  */
+           printf_filtered ("Watchpoint %d deleted.\n", b->number);
+           if (b->related_breakpoint)
+             b->related_breakpoint->disposition = del_at_next_stop;
+           b->disposition = del_at_next_stop;
+           /* We've already printed what needs to be printed.  */
+           bs->print_it = print_it_done;
+
+           /* Stop.  */
+           break;
+         }
+      }
+    else if (b->type == bp_read_watchpoint || 
+            b->type == bp_access_watchpoint)
+      {
+       CORE_ADDR addr;
+       value_ptr v;
+       int found = 0;
+
+       addr = target_stopped_data_address ();
+       if (addr == 0)
+         continue;
+       for (v = b->val_chain; v; v = v->next)
+         {
+           if (VALUE_LVAL (v) == lval_memory
+               && ! VALUE_LAZY (v))
+             {
+               CORE_ADDR vaddr;
+
+               vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+               /* Exact match not required.  Within range is sufficient.  
+                */
+               if (addr >= vaddr &&
+                   addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
+                 found = 1;
+             }
+         }
+       if (found)
+         switch (catch_errors (watchpoint_check, bs, message,
+                               RETURN_MASK_ALL))
            {
            case WP_DELETED:
              /* We've already printed what needs to be printed.  */
@@ -2134,19 +2590,12 @@ bpstat_stop_status (pc, not_a_breakpoint)
              /* Stop.  */
              break;
            case WP_VALUE_CHANGED:
+           case WP_VALUE_NOT_CHANGED:
              /* Stop.  */
              ++(b->hit_count);
              break;
-           case WP_VALUE_NOT_CHANGED:
-             /* Don't stop.  */
-             bs->print_it = print_it_noop;
-             bs->stop = 0;
-             /* Don't consider this a hit.  */
-             --(b->hit_count);
-             continue;
            default:
              /* Can't happen.  */
-             /* FALLTHROUGH */
            case 0:
              /* Error from catch_errors.  */
              printf_filtered ("Watchpoint %d deleted.\n", b->number);
@@ -2155,126 +2604,89 @@ bpstat_stop_status (pc, not_a_breakpoint)
              b->disposition = del_at_next_stop;
              /* We've already printed what needs to be printed.  */
              bs->print_it = print_it_done;
-
-             /* Stop.  */
              break;
            }
-       }
-      else if (b->type == bp_read_watchpoint || b->type == bp_access_watchpoint)
-        {
-         CORE_ADDR addr;
-         value_ptr v;
-          int found = 0;
-
-         addr = target_stopped_data_address();
-         if (addr == 0) continue;
-          for (v = b->val_chain; v; v = v->next)
-            {
-              if (v->lval == lval_memory)
-                {
-                  CORE_ADDR vaddr;
-
-                  vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-                 if (addr == vaddr)
-                   found = 1;
-                }
-            }
-         if (found) 
-           switch (catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL))
-             {
-                case WP_DELETED:
-                  /* We've already printed what needs to be printed.  */
-                  bs->print_it = print_it_done;
-                  /* Stop.  */
-                  break;
-                case WP_VALUE_CHANGED:
-                case WP_VALUE_NOT_CHANGED:
-                  /* Stop.  */
-                 ++(b->hit_count);
-                  break;
-                default:
-                  /* Can't happen.  */
-                case 0:
-                  /* Error from catch_errors.  */
-                  printf_filtered ("Watchpoint %d deleted.\n", b->number);
-                 if (b->related_breakpoint)
-                   b->related_breakpoint->disposition = del_at_next_stop;
-                 b->disposition = del_at_next_stop;
-                  /* We've already printed what needs to be printed.  */
-                  bs->print_it = print_it_done;
-                  break;
-             }
-        }
-      else 
-        {
-          /* By definition, an encountered breakpoint is a triggered
-             breakpoint. */
-          ++(b->hit_count);
-
-         real_breakpoint = 1;
-        }
-
-      if (b->frame && b->frame != (get_current_frame ())->frame &&
-          (b->type == bp_step_resume && 
-           (INNER_THAN (get_current_frame ()->frame, b->frame))))
-       bs->stop = 0;
-      else
-       {
-         int value_is_zero = 0;
+       else    /* found == 0 */
+         {
+           /* This is a case where some watchpoint(s) triggered,
+              but not at the address of this watchpoint (FOUND
+              was left zero).  So don't print anything for this
+              watchpoint.  */
+           bs->print_it = print_it_noop;
+           bs->stop = 0;
+            continue;
+         }
+      }
+    else
+      {
+       /* By definition, an encountered breakpoint is a triggered
+          breakpoint. */
+       ++(b->hit_count);
 
-         if (b->cond)
-           {
-             /* Need to select the frame, with all that implies
-                so that the conditions will have the right context.  */
-             select_frame (get_current_frame (), 0);
-             value_is_zero
-               = catch_errors (breakpoint_cond_eval, (b->cond),
-                               "Error in testing breakpoint condition:\n",
-                               RETURN_MASK_ALL);
-                               /* FIXME-someday, should give breakpoint # */
-             free_all_values ();
-           }
-         if (b->cond && value_is_zero)
-           {
-             bs->stop = 0;
-             /* Don't consider this a hit.  */
-             --(b->hit_count);
-           }
-         else if (b->ignore_count > 0)
-           {
-             b->ignore_count--;
-             bs->stop = 0;
-           }
-         else
-           {
-             /* We will stop here */
-             if (b->disposition == disable)
-               b->enable = disabled;
-             bs->commands = b->commands;
-             if (b->silent)
+       real_breakpoint = 1;
+      }
+
+    if (b->frame &&
+       b->frame != (get_current_frame ())->frame)
+      bs->stop = 0;
+    else
+      {
+       int value_is_zero = 0;
+
+       if (b->cond)
+         {
+           /* Need to select the frame, with all that implies
+              so that the conditions will have the right context.  */
+           select_frame (get_current_frame (), 0);
+           value_is_zero
+             = catch_errors (breakpoint_cond_eval, (b->cond),
+                             "Error in testing breakpoint condition:\n",
+                             RETURN_MASK_ALL);
+           /* FIXME-someday, should give breakpoint # */
+           free_all_values ();
+         }
+       if (b->cond && value_is_zero)
+         {
+           bs->stop = 0;
+           /* Don't consider this a hit.  */
+           --(b->hit_count);
+         }
+       else if (b->ignore_count > 0)
+         {
+           b->ignore_count--;
+           annotate_ignore_count_change ();
+           bs->stop = 0;
+         }
+       else
+         {
+           /* We will stop here */
+           if (b->disposition == disable)
+             b->enable = disabled;
+           bs->commands = b->commands;
+           if (b->silent)
+             bs->print = 0;
+           if (bs->commands &&
+               (STREQ ("silent", bs->commands->line) ||
+                (xdb_commands && STREQ ("Q", bs->commands->line))))
+             {
+               bs->commands = bs->commands->next;
                bs->print = 0;
-             if (bs->commands &&
-                 (STREQ ("silent", bs->commands->line) ||
-                  (xdb_commands && STREQ ("Q", bs->commands->line))))
-               {
-                 bs->commands = bs->commands->next;
-                 bs->print = 0;
-               }
-           }
-       }
-      /* Print nothing for this entry if we dont stop or if we dont print.  */
-      if (bs->stop == 0 || bs->print == 0)
-       bs->print_it = print_it_noop;
-    }
+             }
+         }
+      }
+    /* Print nothing for this entry if we dont stop or if we dont print.  */
+    if (bs->stop == 0 || bs->print == 0)
+      bs->print_it = print_it_noop;
+  }
 
   bs->next = NULL;             /* Terminate the chain */
   bs = root_bs->next;          /* Re-grab the head of the chain */
 
   if (real_breakpoint && bs)
     {
-      if (bs->breakpoint_at->type == bp_hardware_breakpoint) 
+      if (bs->breakpoint_at->type == bp_hardware_breakpoint)
        {
-         if (DECR_PC_AFTER_HW_BREAK != 0) 
+         if (DECR_PC_AFTER_HW_BREAK != 0)
            {
              *pc = *pc - DECR_PC_AFTER_HW_BREAK;
              write_pc (*pc);
@@ -2286,7 +2698,7 @@ bpstat_stop_status (pc, not_a_breakpoint)
            {
              *pc = bp_addr;
 #if defined (SHIFT_INST_REGS)
-             SHIFT_INST_REGS();
+             SHIFT_INST_REGS ();
 #else /* No SHIFT_INST_REGS.  */
              write_pc (bp_addr);
 #endif /* No SHIFT_INST_REGS.  */
@@ -2296,7 +2708,7 @@ bpstat_stop_status (pc, not_a_breakpoint)
 
   /* The value of a hardware watchpoint hasn't changed, but the
      intermediate memory locations we are watching may have.  */
-  if (bs && ! bs->stop &&
+  if (bs && !bs->stop &&
       (bs->breakpoint_at->type == bp_hardware_watchpoint ||
        bs->breakpoint_at->type == bp_read_watchpoint ||
        bs->breakpoint_at->type == bp_access_watchpoint))
@@ -2313,45 +2725,46 @@ bpstat_what (bs)
      bpstat bs;
 {
   /* Classify each bpstat as one of the following.  */
-  enum class {
-    /* This bpstat element has no effect on the main_action.  */
-    no_effect = 0,
+  enum class
+    {
+      /* This bpstat element has no effect on the main_action.  */
+      no_effect = 0,
+
+      /* There was a watchpoint, stop but don't print.  */
+      wp_silent,
 
-    /* There was a watchpoint, stop but don't print.  */
-    wp_silent,
+      /* There was a watchpoint, stop and print.  */
+      wp_noisy,
 
-    /* There was a watchpoint, stop and print.  */
-    wp_noisy,
+      /* There was a breakpoint but we're not stopping.  */
+      bp_nostop,
 
-    /* There was a breakpoint but we're not stopping.  */
-    bp_nostop,
+      /* There was a breakpoint, stop but don't print.  */
+      bp_silent,
 
-    /* There was a breakpoint, stop but don't print.  */
-    bp_silent,
+      /* There was a breakpoint, stop and print.  */
+      bp_noisy,
 
-    /* There was a breakpoint, stop and print.  */
-    bp_noisy,
+      /* We hit the longjmp breakpoint.  */
+      long_jump,
 
-    /* We hit the longjmp breakpoint.  */
-    long_jump,
+      /* We hit the longjmp_resume breakpoint.  */
+      long_resume,
 
-    /* We hit the longjmp_resume breakpoint.  */
-    long_resume,
+      /* We hit the step_resume breakpoint.  */
+      step_resume,
 
-    /* We hit the step_resume breakpoint.  */
-    step_resume,
+      /* We hit the through_sigtramp breakpoint.  */
+      through_sig,
 
-    /* We hit the through_sigtramp breakpoint.  */
-    through_sig,
+      /* We hit the shared library event breakpoint.  */
+      shlib_event,
 
-    /* We hit the shared library event breakpoint.  */
-    shlib_event,
+      /* We caught a shared library event.  */
+      catch_shlib_event,
 
-    /* We caught a shared library event.  */
-    catch_shlib_event,
-    /* This is just used to count how many enums there are.  */
-    class_last
+      /* This is just used to count how many enums there are.  */
+      class_last
     };
 
   /* Here is the table which drives this routine.  So that we can
@@ -2379,8 +2792,34 @@ bpstat_what (bs)
      as bp_silent and wp_noisy is the same as bp_noisy.  That is because
      after stopping, the check for whether to step over a breakpoint
      (BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without
-     reference to how we stopped.  We retain separate wp_silent and bp_silent
-     codes in case we want to change that someday.  */
+     reference to how we stopped.  We retain separate wp_silent and
+     bp_silent codes in case we want to change that someday. 
+
+     Another possibly interesting property of this table is that
+     there's a partial ordering, priority-like, of the actions.  Once
+     you've decided that some action is appropriate, you'll never go
+     back and decide something of a lower priority is better.  The
+     ordering is:
+
+     kc   < clr sgl shl slr sn sr ss ts
+     sgl  < clrs shl shlr slr sn sr ss ts
+     slr  < err shl shlr sn sr ss ts
+     clr  < clrs err shl shlr sn sr ss ts
+     clrs < err shl shlr sn sr ss ts
+     ss   < shl shlr sn sr ts
+     sn   < shl shlr sr ts
+     sr   < shl shlr ts
+     shl  < shlr
+     ts   < 
+     shlr <
+
+     What I think this means is that we don't need a damned table
+     here.  If you just put the rows and columns in the right order,
+     it'd look awfully regular.  We could simply walk the bpstat list
+     and choose the highest priority action we find, with a little
+     logic to handle the 'err' cases, and the CLEAR_LONGJMP_RESUME/
+     CLEAR_LONGJMP_RESUME_SINGLE distinction (which breakpoint.h says
+     is messy anyway).  */
 
   /* step_resume entries: a step resume breakpoint overrides another
      breakpoint of signal handling (see comment in wait_for_inferior
@@ -2389,24 +2828,36 @@ bpstat_what (bs)
      one of those and a step_resume_breakpoint is probably very rare (?).  */
 
   static const enum bpstat_what_main_action
-    table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
-      {
-       /*                              old action */
-        /*       kc    ss    sn    sgl    slr   clr    clrs   sr    ts   shl   shlr
-         */
-/*no_effect*/   {kc,   ss,   sn,   sgl,   slr,  clr,   clrs,  sr,   ts,  shl,  shlr},
-/*wp_silent*/   {ss,   ss,   sn,   ss,    ss,   ss,    ss,    sr,   ts,  shl,  shlr},
-/*wp_noisy*/    {sn,   sn,   sn,   sn,    sn,   sn,    sn,    sr,   ts,  shl,  shlr},
-/*bp_nostop*/   {sgl,  ss,   sn,   sgl,   slr,  clrs,  clrs,  sr,   ts,  shl,  shlr},
-/*bp_silent*/   {ss,   ss,   sn,   ss,    ss,   ss,    ss,    sr,   ts,  shl,  shlr},
-/*bp_noisy*/    {sn,   sn,   sn,   sn,    sn,   sn,    sn,    sr,   ts,  shl,  shlr},
-/*long_jump*/   {slr,  ss,   sn,   slr,   err,  err,   err,   sr,   ts,  shl,  shlr},
-/*long_resume*/ {clr,  ss,   sn,   clrs,  err,  err,   err,   sr,   ts,  shl,  shlr},
-/*step_resume*/ {sr,   sr,   sr,   sr,    sr,   sr,    sr,    sr,   ts,  shl,  shlr},
-/*through_sig*/ {ts,   ts,   ts,   ts,    ts,   ts,    ts,    ts,   ts,  shl,  shlr},
-/*shlib*/       {shl,  shl,  shl,  shl,   shl,  shl,   shl,   shl,  ts,  shl,  shlr},
-/*catch_shlib*/ {shlr, shlr, shlr, shlr,  shlr, shlr,  shlr,  shlr, ts,  shlr, shlr}
-              };
+    table[(int) class_last][(int) BPSTAT_WHAT_LAST] =
+  {
+  /*                              old action */
+  /*       kc    ss    sn    sgl    slr   clr    clrs   sr    ts   shl   shlr
+   */
+/*no_effect */
+    {kc, ss, sn, sgl, slr, clr, clrs, sr, ts, shl, shlr},
+/*wp_silent */
+    {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr},
+/*wp_noisy */
+    {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
+/*bp_nostop */
+    {sgl, ss, sn, sgl, slr, clrs, clrs, sr, ts, shl, shlr},
+/*bp_silent */
+    {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr},
+/*bp_noisy */
+    {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
+/*long_jump */
+    {slr, ss, sn, slr, err, err, err, sr, ts, shl, shlr},
+/*long_resume */
+    {clr, ss, sn, clrs, err, err, err, sr, ts, shl, shlr},
+/*step_resume */
+    {sr, sr, sr, sr, sr, sr, sr, sr, ts, shl, shlr},
+/*through_sig */
+    {ts, ts, ts, ts, ts, ts, ts, ts, ts, shl, shlr},
+/*shlib */
+    {shl, shl, shl, shl, shl, shl, shl, shl, ts, shl, shlr},
+/*catch_shlib */
+    {shlr, shlr, shlr, shlr, shlr, shlr, shlr, shlr, ts, shlr, shlr}
+  };
 
 #undef kc
 #undef ss
@@ -2462,8 +2913,8 @@ bpstat_what (bs)
                bs_class = wp_silent;
            }
          else
-           /* There was a watchpoint, but we're not stopping.  This requires
-              no further action.  */
+           /* There was a watchpoint, but we're not stopping. 
+              This requires no further action.  */
            bs_class = no_effect;
          break;
        case bp_longjmp:
@@ -2490,51 +2941,54 @@ bpstat_what (bs)
        case bp_shlib_event:
          bs_class = shlib_event;
          break;
-        case bp_catch_load:
-        case bp_catch_unload:
-          /* Only if this catchpoint triggered should we cause the
-             step-out-of-dld behaviour.  Otherwise, we ignore this
-             catchpoint.  */
-          if (bs->stop)
-            bs_class = catch_shlib_event;
-          else
-            bs_class = no_effect;
-          break;
-        case bp_catch_fork:
-        case bp_catch_vfork:
+       case bp_thread_event:
+         bs_class = bp_nostop;
+         break;
+       case bp_catch_load:
+       case bp_catch_unload:
+         /* Only if this catchpoint triggered should we cause the
+            step-out-of-dld behaviour.  Otherwise, we ignore this
+            catchpoint.  */
+         if (bs->stop)
+           bs_class = catch_shlib_event;
+         else
+           bs_class = no_effect;
+         break;
+       case bp_catch_fork:
+       case bp_catch_vfork:
        case bp_catch_exec:
-          if (bs->stop)
-            {
-              if (bs->print)
-                bs_class = bp_noisy;
-              else
-                bs_class = bp_silent;
-            }
-          else
-            /* There was a catchpoint, but we're not stopping.  This requires
-               no further action.  */
-            bs_class = no_effect;
-          break;
-        case bp_catch_catch:
-          if (!bs->stop || CURRENT_EXCEPTION_KIND != EX_EVENT_CATCH)
-            bs_class = bp_nostop;
-          else if (bs->stop)
-            bs_class = bs->print ? bp_noisy : bp_silent;
-          break;
-        case bp_catch_throw:
-          if (!bs->stop || CURRENT_EXCEPTION_KIND != EX_EVENT_THROW)
-            bs_class = bp_nostop;
-          else if (bs->stop)
-            bs_class = bs->print ? bp_noisy : bp_silent;
-          break;
+         if (bs->stop)
+           {
+             if (bs->print)
+               bs_class = bp_noisy;
+             else
+               bs_class = bp_silent;
+           }
+         else
+           /* There was a catchpoint, but we're not stopping.  
+              This requires no further action.  */
+           bs_class = no_effect;
+         break;
+       case bp_catch_catch:
+         if (!bs->stop || CURRENT_EXCEPTION_KIND != EX_EVENT_CATCH)
+           bs_class = bp_nostop;
+         else if (bs->stop)
+           bs_class = bs->print ? bp_noisy : bp_silent;
+         break;
+       case bp_catch_throw:
+         if (!bs->stop || CURRENT_EXCEPTION_KIND != EX_EVENT_THROW)
+           bs_class = bp_nostop;
+         else if (bs->stop)
+           bs_class = bs->print ? bp_noisy : bp_silent;
+         break;
        case bp_call_dummy:
-         /* Make sure the action is stop (silent or noisy), so infrun.c
-            pops the dummy frame.  */
+         /* Make sure the action is stop (silent or noisy),
+            so infrun.c pops the dummy frame.  */
          bs_class = bp_silent;
          retval.call_dummy = 1;
          break;
        }
-      current_action = table[(int)bs_class][(int)current_action];
+      current_action = table[(int) bs_class][(int) current_action];
     }
   retval.main_action = current_action;
   return retval;
@@ -2544,13 +2998,13 @@ bpstat_what (bs)
    without hardware support).  This isn't related to a specific bpstat,
    just to things like whether watchpoints are set.  */
 
-int 
+int
 bpstat_should_step ()
 {
   struct breakpoint *b;
   ALL_BREAKPOINTS (b)
     if (b->enable == enabled && b->type == bp_watchpoint)
-      return 1;
+    return 1;
   return 0;
 }
 
@@ -2561,49 +3015,50 @@ bpstat_have_active_hw_watchpoints ()
   struct breakpoint *b;
   ALL_BREAKPOINTS (b)
     if ((b->enable == enabled) &&
-        (b->inserted) &&
-        ((b->type == bp_hardware_watchpoint) ||
-         (b->type == bp_read_watchpoint) ||
-         (b->type == bp_access_watchpoint)))
-      return 1;
+       (b->inserted) &&
+       ((b->type == bp_hardware_watchpoint) ||
+        (b->type == bp_read_watchpoint) ||
+        (b->type == bp_access_watchpoint)))
+    return 1;
   return 0;
 }
-
 \f
+
 /* Given a bpstat that records zero or more triggered eventpoints, this
    function returns another bpstat which contains only the catchpoints
    on that first list, if any. */
 void
 bpstat_get_triggered_catchpoints (ep_list, cp_list)
-  bpstat  ep_list;
-  bpstat *  cp_list;
-{
-  struct bpstats  root_bs[1];
-  bpstat  bs = root_bs;
-  struct breakpoint *  ep;
-  char *  dll_pathname;
+     bpstat ep_list;
+     bpstat *cp_list;
+{
+  struct bpstats root_bs[1];
+  bpstat bs = root_bs;
+  struct breakpoint *ep;
+  char *dll_pathname;
+
   bpstat_clear (cp_list);
   root_bs->next = NULL;
-  for (; ep_list != NULL; ep_list = ep_list->next )
+
+  for (; ep_list != NULL; ep_list = ep_list->next)
     {
       /* Is this eventpoint a catchpoint?  If not, ignore it. */
       ep = ep_list->breakpoint_at;
       if (ep == NULL)
-        break;
-      if ((ep->type != bp_catch_load) && 
-          (ep->type != bp_catch_unload) &&
-          (ep->type != bp_catch_catch) &&
-          (ep->type != bp_catch_throw))   /* pai: (temp) ADD fork/vfork here!!  */
-        continue;
+       break;
+      if ((ep->type != bp_catch_load) &&
+         (ep->type != bp_catch_unload) &&
+         (ep->type != bp_catch_catch) &&
+         (ep->type != bp_catch_throw))         
+       /* pai: (temp) ADD fork/vfork here!!  */
+       continue;
+
       /* Yes; add it to the list. */
       bs = bpstat_alloc (ep, bs);
       *bs = *ep_list;
       bs->next = NULL;
       bs = root_bs->next;
+
 #if defined(SOLIB_ADD)
       /* Also, for each triggered catchpoint, tag it with the name of
          the library that caused this trigger.  (We copy the name now,
@@ -2611,88 +3066,513 @@ bpstat_get_triggered_catchpoints (ep_list, cp_list)
          catchpoint triggers.  Clients who may wish to know the name
          later must get it from the catchpoint itself.) */
       if (ep->triggered_dll_pathname != NULL)
-        free (ep->triggered_dll_pathname);
+       free (ep->triggered_dll_pathname);
       if (ep->type == bp_catch_load)
-        dll_pathname = SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid);
+       dll_pathname = SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid);
       else
-        dll_pathname = SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid);
+       dll_pathname = SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid);
 #else
       dll_pathname = NULL;
 #endif
       if (dll_pathname)
        {
-         ep->triggered_dll_pathname = (char *) xmalloc (strlen (dll_pathname) + 1);
+         ep->triggered_dll_pathname = (char *) 
+           xmalloc (strlen (dll_pathname) + 1);
          strcpy (ep->triggered_dll_pathname, dll_pathname);
        }
       else
        ep->triggered_dll_pathname = NULL;
     }
-  *cp_list = bs;
+
+  *cp_list = bs;
+}
+
+/* Print B to gdb_stdout. */
+static void
+print_one_breakpoint (struct breakpoint *b,
+                     CORE_ADDR *last_addr)
+{
+  register struct command_line *l;
+  register struct symbol *sym;
+  struct ep_type_description
+    {
+      enum bptype type;
+      char *description;
+    };
+  static struct ep_type_description bptypes[] =
+  {
+    {bp_none, "?deleted?"},
+    {bp_breakpoint, "breakpoint"},
+    {bp_hardware_breakpoint, "hw breakpoint"},
+    {bp_until, "until"},
+    {bp_finish, "finish"},
+    {bp_watchpoint, "watchpoint"},
+    {bp_hardware_watchpoint, "hw watchpoint"},
+    {bp_read_watchpoint, "read watchpoint"},
+    {bp_access_watchpoint, "acc watchpoint"},
+    {bp_longjmp, "longjmp"},
+    {bp_longjmp_resume, "longjmp resume"},
+    {bp_step_resume, "step resume"},
+    {bp_through_sigtramp, "sigtramp"},
+    {bp_watchpoint_scope, "watchpoint scope"},
+    {bp_call_dummy, "call dummy"},
+    {bp_shlib_event, "shlib events"},
+    {bp_thread_event, "thread events"},
+    {bp_catch_load, "catch load"},
+    {bp_catch_unload, "catch unload"},
+    {bp_catch_fork, "catch fork"},
+    {bp_catch_vfork, "catch vfork"},
+    {bp_catch_exec, "catch exec"},
+    {bp_catch_catch, "catch catch"},
+    {bp_catch_throw, "catch throw"}
+  };
+  
+  static char *bpdisps[] =
+  {"del", "dstp", "dis", "keep"};
+  static char bpenables[] = "nynny";
+  char wrap_indent[80];
+#ifdef UI_OUT
+  struct ui_stream *stb = ui_out_stream_new (uiout);
+  struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
+#endif
+
+  annotate_record ();
+#ifdef UI_OUT
+  ui_out_list_begin (uiout, "bkpt");
+#endif
+
+  /* 1 */
+  annotate_field (0);
+#ifdef UI_OUT
+  ui_out_field_int (uiout, "number", b->number);
+#else
+  printf_filtered ("%-3d ", b->number);
+#endif
+
+  /* 2 */
+  annotate_field (1);
+  if (((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
+      || ((int) b->type != bptypes[(int) b->type].type))
+    internal_error ("bptypes table does not describe type #%d.",
+                   (int) b->type);
+#ifdef UI_OUT
+  ui_out_field_string (uiout, "type", bptypes[(int) b->type].description);
+#else
+  printf_filtered ("%-14s ", bptypes[(int) b->type].description);
+#endif
+
+  /* 3 */
+  annotate_field (2);
+#ifdef UI_OUT
+  ui_out_field_string (uiout, "disp", bpdisps[(int) b->disposition]);
+#else
+  printf_filtered ("%-4s ", bpdisps[(int) b->disposition]);
+#endif
+
+  /* 4 */
+  annotate_field (3);
+#ifdef UI_OUT
+  ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int) b->enable]);
+  ui_out_spaces (uiout, 2);
+#else
+  printf_filtered ("%-3c ", bpenables[(int) b->enable]);
+#endif
+  
+  /* 5 and 6 */
+  strcpy (wrap_indent, "                           ");
+  if (addressprint)
+    strcat (wrap_indent, "           ");
+  switch (b->type)
+    {
+    case bp_none:
+      internal_error ("print_one_breakpoint: bp_none encountered\n");
+      break;
+
+    case bp_watchpoint:
+    case bp_hardware_watchpoint:
+    case bp_read_watchpoint:
+    case bp_access_watchpoint:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "what", stb);
+#else
+      annotate_field (5);
+      print_expression (b->exp, gdb_stdout);
+#endif
+      break;
+      
+    case bp_catch_load:
+    case bp_catch_unload:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      if (b->dll_pathname == NULL)
+       {
+         ui_out_field_string (uiout, "what", "<any library>");
+         ui_out_spaces (uiout, 1);
+       }
+      else
+       {
+         ui_out_text (uiout, "library \"");
+         ui_out_field_string (uiout, "what", b->dll_pathname);
+         ui_out_text (uiout, "\" ");
+       }
+#else
+      annotate_field (5);
+      if (b->dll_pathname == NULL)
+       printf_filtered ("<any library> ");
+      else
+       printf_filtered ("library \"%s\" ", b->dll_pathname);
+#endif
+      break;
+      
+    case bp_catch_fork:
+    case bp_catch_vfork:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      if (b->forked_inferior_pid != 0)
+       {
+         ui_out_text (uiout, "process ");
+         ui_out_field_int (uiout, "what", b->forked_inferior_pid);
+         ui_out_spaces (uiout, 1);
+       }
+#else
+      annotate_field (5);
+      if (b->forked_inferior_pid != 0)
+       printf_filtered ("process %d ", b->forked_inferior_pid);
+      break;
+#endif
+      
+    case bp_catch_exec:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      if (b->exec_pathname != NULL)
+       {
+         ui_out_text (uiout, "program \"");
+         ui_out_field_string (uiout, "what", b->exec_pathname);
+         ui_out_text (uiout, "\" ");
+       }
+#else
+      annotate_field (5);
+      if (b->exec_pathname != NULL)
+       printf_filtered ("program \"%s\" ", b->exec_pathname);
+#endif
+      break;
+
+    case bp_catch_catch:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      ui_out_field_string (uiout, "what", "exception catch");
+      ui_out_spaces (uiout, 1);
+#else
+      annotate_field (5);
+      printf_filtered ("exception catch ");
+#endif
+      break;
+
+    case bp_catch_throw:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      ui_out_field_string (uiout, "what", "exception throw");
+      ui_out_spaces (uiout, 1);
+#else
+      annotate_field (5);
+      printf_filtered ("exception throw ");
+#endif
+      break;
+      
+    case bp_breakpoint:
+    case bp_hardware_breakpoint:
+    case bp_until:
+    case bp_finish:
+    case bp_longjmp:
+    case bp_longjmp_resume:
+    case bp_step_resume:
+    case bp_through_sigtramp:
+    case bp_watchpoint_scope:
+    case bp_call_dummy:
+    case bp_shlib_event:
+    case bp_thread_event:
+#ifdef UI_OUT
+      if (addressprint)
+       {
+         annotate_field (4);
+         ui_out_field_core_addr (uiout, "addr", b->address);
+       }
+      annotate_field (5);
+      *last_addr = b->address;
+      if (b->source_file)
+       {
+         sym = find_pc_sect_function (b->address, b->section);
+         if (sym)
+           {
+             ui_out_text (uiout, "in ");
+             ui_out_field_string (uiout, "func",
+                                  SYMBOL_SOURCE_NAME (sym));
+             ui_out_wrap_hint (uiout, wrap_indent);
+             ui_out_text (uiout, " at ");
+           }
+         ui_out_field_string (uiout, "file", b->source_file);
+         ui_out_text (uiout, ":");
+         ui_out_field_int (uiout, "line", b->line_number);
+       }
+      else
+       {
+         print_address_symbolic (b->address, stb->stream, demangle, "");
+         ui_out_field_stream (uiout, "at", stb);
+       }
+#else
+      if (addressprint)
+       {
+         annotate_field (4);
+         /* FIXME-32x64: need a print_address_numeric with
+            field width */
+         printf_filtered
+           ("%s ",
+            local_hex_string_custom
+            ((unsigned long) b->address, "08l"));
+       }
+      annotate_field (5);
+      *last_addr = b->address;
+      if (b->source_file)
+       {
+         sym = find_pc_sect_function (b->address, b->section);
+         if (sym)
+           {
+             fputs_filtered ("in ", gdb_stdout);
+             fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
+             wrap_here (wrap_indent);
+             fputs_filtered (" at ", gdb_stdout);
+           }
+         fputs_filtered (b->source_file, gdb_stdout);
+         printf_filtered (":%d", b->line_number);
+       }
+      else
+       print_address_symbolic (b->address, gdb_stdout, demangle, " ");
+#endif
+      break;
+    }
+  
+  if (b->thread != -1)
+    {
+#ifdef UI_OUT
+      /* FIXME: This seems to be redundant and lost here; see the
+        "stop only in" line a little further down. */
+      ui_out_text (uiout, " thread ");
+      ui_out_field_int (uiout, "thread", b->thread);
+#else
+      printf_filtered (" thread %d", b->thread);
+#endif
+    }
+  
+#ifdef UI_OUT
+  ui_out_text (uiout, "\n");
+#else
+  printf_filtered ("\n");
+#endif
+  
+  if (b->frame)
+    {
+      annotate_field (6);
+#ifdef UI_OUT
+      ui_out_text (uiout, "\tstop only in stack frame at ");
+      ui_out_field_core_addr (uiout, "frame", b->frame);
+      ui_out_text (uiout, "\n");
+#else
+      printf_filtered ("\tstop only in stack frame at ");
+      print_address_numeric (b->frame, 1, gdb_stdout);
+      printf_filtered ("\n");
+#endif
+    }
+  
+  if (b->cond)
+    {
+      annotate_field (7);
+#ifdef UI_OUT
+      ui_out_text (uiout, "\tstop only if ");
+      print_expression (b->cond, stb->stream);
+      ui_out_field_stream (uiout, "cond", stb);
+      ui_out_text (uiout, "\n");
+#else
+      printf_filtered ("\tstop only if ");
+      print_expression (b->cond, gdb_stdout);
+      printf_filtered ("\n");
+#endif
+    }
+  
+  if (b->thread != -1)
+    {
+      /* FIXME should make an annotation for this */
+#ifdef UI_OUT
+      ui_out_text (uiout, "\tstop only in thread ");
+      ui_out_field_int (uiout, "thread", b->thread);
+      ui_out_text (uiout, "\n");
+#else
+      printf_filtered ("\tstop only in thread %d\n", b->thread);
+#endif
+    }
+  
+  if (show_breakpoint_hit_counts && b->hit_count)
+    {
+      /* FIXME should make an annotation for this */
+#ifdef UI_OUT
+      if (ep_is_catchpoint (b))
+       ui_out_text (uiout, "\tcatchpoint");
+      else
+       ui_out_text (uiout, "\tbreakpoint");
+      ui_out_text (uiout, " already hit ");
+      ui_out_field_int (uiout, "times", b->hit_count);
+      if (b->hit_count == 1)
+       ui_out_text (uiout, " time\n");
+      else
+       ui_out_text (uiout, " times\n");
+#else
+      if (ep_is_catchpoint (b))
+       printf_filtered ("\tcatchpoint");
+      else
+       printf_filtered ("\tbreakpoint");
+      printf_filtered (" already hit %d time%s\n",
+                      b->hit_count, (b->hit_count == 1 ? "" : "s"));
+#endif
+    }
+  
+#ifdef UI_OUT
+  /* Output the count also if it is zero, but only if this is
+     mi. FIXME: Should have a better test for this. */
+  if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+    if (show_breakpoint_hit_counts && b->hit_count == 0)
+      ui_out_field_int (uiout, "times", b->hit_count);
+#endif
+
+  if (b->ignore_count)
+    {
+      annotate_field (8);
+#ifdef UI_OUT
+      ui_out_text (uiout, "\tignore next ");
+      ui_out_field_int (uiout, "ignore", b->ignore_count);
+      ui_out_text (uiout, " hits\n");
+#else
+      printf_filtered ("\tignore next %d hits\n", b->ignore_count);
+#endif
+    }
+  
+  if ((l = b->commands))
+    {
+      annotate_field (9);
+#ifdef UI_OUT
+      ui_out_list_begin (uiout, "script");
+      print_command_lines (uiout, l, 4);
+      ui_out_list_end (uiout);
+#else
+      while (l)
+       {
+         print_command_line (l, 4, gdb_stdout);
+         l = l->next;
+       }
+#endif
+    }
+#ifdef UI_OUT
+  ui_out_list_end (uiout);
+  do_cleanups (old_chain);
+#endif
+}
+
+struct captured_breakpoint_query_args
+  {
+    int bnum;
+  };
+
+static int
+do_captured_breakpoint_query (void *data)
+{
+  struct captured_breakpoint_query_args *args = data;
+  register struct breakpoint *b;
+  CORE_ADDR dummy_addr = 0;
+  ALL_BREAKPOINTS (b)
+    {
+      if (args->bnum == b->number)
+       {
+         print_one_breakpoint (b, &dummy_addr);
+         return GDB_RC_OK;
+       }
+    }
+  return GDB_RC_NONE;
+}
+
+enum gdb_rc
+gdb_breakpoint_query (/* output object, */ int bnum)
+{
+  struct captured_breakpoint_query_args args;
+  args.bnum = bnum;
+  /* For the moment we don't trust print_one_breakpoint() to not throw
+     an error. */
+  return catch_errors (do_captured_breakpoint_query, &args,
+                      NULL, RETURN_MASK_ALL);
 }
 
 /* Print information on breakpoint number BNUM, or -1 if all.
    If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS
    is nonzero, process only watchpoints.  */
 
-typedef struct {
-  enum bptype  type;
-  char *  description;
-} ep_type_description_t;
-
 static void
 breakpoint_1 (bnum, allflag)
      int bnum;
      int allflag;
 {
   register struct breakpoint *b;
-  register struct command_line *l;
-  register struct symbol *sym;
-  CORE_ADDR last_addr = (CORE_ADDR)-1;
+  CORE_ADDR last_addr = (CORE_ADDR) -1;
   int found_a_breakpoint = 0;
-  static ep_type_description_t  bptypes[] =
-  {
-    {bp_none,                "?deleted?"},
-    {bp_breakpoint,          "breakpoint"},
-    {bp_hardware_breakpoint, "hw breakpoint"},
-    {bp_until,               "until"},
-    {bp_finish,              "finish"},
-    {bp_watchpoint,          "watchpoint"},
-    {bp_hardware_watchpoint, "hw watchpoint"},
-    {bp_read_watchpoint,     "read watchpoint"},
-    {bp_access_watchpoint,   "acc watchpoint"},
-    {bp_longjmp,             "longjmp"},
-    {bp_longjmp_resume,      "longjmp resume"},
-    {bp_step_resume,         "step resume"},
-    {bp_through_sigtramp,    "sigtramp"},
-    {bp_watchpoint_scope,    "watchpoint scope"},
-    {bp_call_dummy,          "call dummy"},
-    {bp_shlib_event,         "shlib events"},
-    {bp_catch_load,          "catch load"},
-    {bp_catch_unload,        "catch unload"},
-    {bp_catch_fork,          "catch fork"},
-    {bp_catch_vfork,         "catch vfork"},
-    {bp_catch_exec,          "catch exec"},
-    {bp_catch_catch,         "catch catch"},
-    {bp_catch_throw,         "catch throw"}
-   };
-
-  static char *bpdisps[] = {"del", "dstp", "dis", "keep"};
-  static char bpenables[] = "nyn";
-  char wrap_indent[80];
+  
+#ifdef UI_OUT
+  if (addressprint)
+    ui_out_table_begin (uiout, 6, "BreakpointTable");
+  else
+    ui_out_table_begin (uiout, 5, "BreakpointTable");
+#endif /* UI_OUT */
 
   ALL_BREAKPOINTS (b)
     if (bnum == -1
        || bnum == b->number)
       {
-/*  We only print out user settable breakpoints unless the allflag is set. */
+       /* We only print out user settable breakpoints unless the
+          allflag is set. */
        if (!allflag
            && b->type != bp_breakpoint
-            && b->type != bp_catch_load
-            && b->type != bp_catch_unload
-            && b->type != bp_catch_fork
-            && b->type != bp_catch_vfork
-            && b->type != bp_catch_exec
+           && b->type != bp_catch_load
+           && b->type != bp_catch_unload
+           && b->type != bp_catch_fork
+           && b->type != bp_catch_vfork
+           && b->type != bp_catch_exec
            && b->type != bp_catch_catch
            && b->type != bp_catch_throw
            && b->type != bp_hardware_breakpoint
@@ -2701,220 +3581,78 @@ breakpoint_1 (bnum, allflag)
            && b->type != bp_access_watchpoint
            && b->type != bp_hardware_watchpoint)
          continue;
-
+       
        if (!found_a_breakpoint++)
          {
-            annotate_breakpoints_headers ();
-  
-            annotate_field (0);
-            printf_filtered ("Num ");
-            annotate_field (1);
-            printf_filtered ("Type           ");
-            annotate_field (2);
-            printf_filtered ("Disp ");
-            annotate_field (3);
-            printf_filtered ("Enb ");
-            if (addressprint)
-              {
-                annotate_field (4);
-                printf_filtered ("Address    ");
-              }
-            annotate_field (5);
-            printf_filtered ("What\n");
-  
-            annotate_breakpoints_table ();
-          }
-  
-        annotate_record ();
-        annotate_field (0);
-        printf_filtered ("%-3d ", b->number);
-        annotate_field (1);
-        if ((int)b->type > (sizeof(bptypes)/sizeof(bptypes[0])))
-          error ("bptypes table does not describe type #%d.", (int)b->type);
-        if ((int)b->type != bptypes[(int)b->type].type)
-          error ("bptypes table does not describe type #%d?", (int)b->type);
-        printf_filtered ("%-14s ", bptypes[(int)b->type].description);
-        annotate_field (2);
-        printf_filtered ("%-4s ", bpdisps[(int)b->disposition]);
-        annotate_field (3);
-       printf_filtered ("%-3c ", bpenables[(int)b->enable]);
-
-       strcpy (wrap_indent, "                           ");
-       if (addressprint)
-         strcat (wrap_indent, "           ");
-       switch (b->type)
-         {
-         case bp_watchpoint:
-         case bp_hardware_watchpoint:
-         case bp_read_watchpoint:
-         case bp_access_watchpoint:
-           /* Field 4, the address, is omitted (which makes the columns
-              not line up too nicely with the headers, but the effect
-              is relatively readable).  */
-           annotate_field (5);
-           print_expression (b->exp, gdb_stdout);
-           break;
-          case bp_catch_load:
-          case bp_catch_unload:
-            /* Field 4, the address, is omitted (which makes the columns
-               not line up too nicely with the headers, but the effect
-               is relatively readable).  */
-            annotate_field (5);
-            if (b->dll_pathname == NULL)
-              printf_filtered ("<any library> ");
-            else
-              printf_filtered ("library \"%s\" ", b->dll_pathname);
-            break;
-
-          case bp_catch_fork:
-          case bp_catch_vfork:
-           /* Field 4, the address, is omitted (which makes the columns
-              not line up too nicely with the headers, but the effect
-              is relatively readable).  */
-           annotate_field (5);
-           if (b->forked_inferior_pid != 0)
-             printf_filtered ("process %d ", b->forked_inferior_pid);
-            break;
-
-          case bp_catch_exec:
-           /* Field 4, the address, is omitted (which makes the columns
-              not line up too nicely with the headers, but the effect
-              is relatively readable).  */
-           annotate_field (5);
-           if (b->exec_pathname != NULL)
-             printf_filtered ("program \"%s\" ", b->exec_pathname);
-            break;
-          case bp_catch_catch:
-           /* Field 4, the address, is omitted (which makes the columns
-              not line up too nicely with the headers, but the effect
-              is relatively readable).  */
-           annotate_field (5);
-            printf_filtered ("exception catch ");
-            break;
-          case bp_catch_throw:
-           /* Field 4, the address, is omitted (which makes the columns
-              not line up too nicely with the headers, but the effect
-              is relatively readable).  */
-           annotate_field (5);
-            printf_filtered ("exception throw ");
-            break;
-
-         case bp_breakpoint:
-         case bp_hardware_breakpoint:
-         case bp_until:
-         case bp_finish:
-         case bp_longjmp:
-         case bp_longjmp_resume:
-         case bp_step_resume:
-         case bp_through_sigtramp:
-         case bp_watchpoint_scope:
-         case bp_call_dummy:
-         case bp_shlib_event:
+           annotate_breakpoints_headers ();
+#ifdef UI_OUT
+           annotate_field (0);
+           ui_out_table_header (uiout, 3, ui_left, "Num");     /* 1 */
+           annotate_field (1);
+           ui_out_table_header (uiout, 14, ui_left, "Type");   /* 2 */
+           annotate_field (2);
+           ui_out_table_header (uiout, 4, ui_left, "Disp");    /* 3 */
+           annotate_field (3);
+           ui_out_table_header (uiout, 3, ui_left, "Enb");     /* 4 */
            if (addressprint)
              {
-               annotate_field (4);
-               /* FIXME-32x64: need a print_address_numeric with
-                   field width */
-               printf_filtered
-                 ("%s ",
-                  local_hex_string_custom
-                  ((unsigned long) b->address, "08l"));
+               annotate_field (4);
+               ui_out_table_header (uiout, 10, ui_left, "Address");    /* 5 */
              }
-
            annotate_field (5);
-
-           last_addr = b->address;
-           if (b->source_file)
-             {
-               sym = find_pc_sect_function (b->address, b->section);
-               if (sym)
-                 {
-                   fputs_filtered ("in ", gdb_stdout);
-                   fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
-                   wrap_here (wrap_indent);
-                   fputs_filtered (" at ", gdb_stdout);
-                 }
-               fputs_filtered (b->source_file, gdb_stdout);
-               printf_filtered (":%d", b->line_number);
-             }
-           else
-             print_address_symbolic (b->address, gdb_stdout, demangle, " ");
-           break;
-         }
-
-        if (b->thread != -1)
-            printf_filtered (" thread %d", b->thread );
-
-       printf_filtered ("\n");
-
-       if (b->frame)
-         {
-            annotate_field (6);
-
-           printf_filtered ("\tstop only in stack frame at ");
-           print_address_numeric (b->frame, 1, gdb_stdout);
-           printf_filtered ("\n");
-         }
-
-       if (b->cond)
-         {
-            annotate_field (7);
-
-           printf_filtered ("\tstop only if ");
-           print_expression (b->cond, gdb_stdout);
-           printf_filtered ("\n");
-         }
-
-       if (b->thread != -1)
-         {
-           /* FIXME should make an annotation for this */
-           printf_filtered ("\tstop only in thread %d\n", b->thread);
-         }
-
-        if (show_breakpoint_hit_counts && b->hit_count)
-         {
-           /* FIXME should make an annotation for this */
-            if (ep_is_catchpoint (b))
-              printf_filtered ("\tcatchpoint");
-            else
-              printf_filtered ("\tbreakpoint");
-            printf_filtered (" already hit %d time%s\n",
-                             b->hit_count, (b->hit_count == 1 ? "" : "s"));
-         }
-
-       if (b->ignore_count)
-         {
-            annotate_field (8);
-
-           printf_filtered ("\tignore next %d hits\n", b->ignore_count);
-         }
-
-       if ((l = b->commands))
-         {
-            annotate_field (9);
-
-           while (l)
+           ui_out_table_header (uiout, 40, ui_noalign, "What");        /* 6 */
+           ui_out_table_body (uiout);
+#else
+           annotate_field (0);
+           printf_filtered ("Num ");
+           annotate_field (1);
+           printf_filtered ("Type           ");
+           annotate_field (2);
+           printf_filtered ("Disp ");
+           annotate_field (3);
+           printf_filtered ("Enb ");
+           if (addressprint)
              {
-               print_command_line (l, 4);
-               l = l->next;
+               annotate_field (4);
+               printf_filtered ("Address    ");
              }
+           annotate_field (5);
+           printf_filtered ("What\n");
+#endif /* UI_OUT */
+           annotate_breakpoints_table ();
          }
+       
+       print_one_breakpoint (b, &last_addr);
       }
-
+  
   if (!found_a_breakpoint)
     {
+#ifdef UI_OUT
+      if (bnum == -1)
+       ui_out_message (uiout, 0, "No breakpoints or watchpoints.\n");
+      else
+       ui_out_message (uiout, 0, "No breakpoint or watchpoint number %d.\n",
+                       bnum);
+#else
       if (bnum == -1)
-        printf_filtered ("No breakpoints or watchpoints.\n");
+       printf_filtered ("No breakpoints or watchpoints.\n");
       else
-        printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum);
+       printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum);
+#endif /* UI_OUT */
     }
   else
-    /* Compare against (CORE_ADDR)-1 in case some compiler decides
-       that a comparison of an unsigned with -1 is always false.  */
-    if (last_addr != (CORE_ADDR)-1)
-      set_next_address (last_addr);
+    {
+      /* Compare against (CORE_ADDR)-1 in case some compiler decides
+        that a comparison of an unsigned with -1 is always false.  */
+      if (last_addr != (CORE_ADDR) -1)
+       set_next_address (last_addr);
+    }
 
+#ifdef UI_OUT
+  ui_out_table_end (uiout);
+#endif /* UI_OUT */
+  /* FIXME? Should this be moved up so that it is only called when
+     there have been breakpoints? */
   annotate_breakpoints_table_end ();
 }
 
@@ -2932,10 +3670,8 @@ breakpoints_info (bnum_exp, from_tty)
   breakpoint_1 (bnum, 0);
 }
 
-#if MAINTENANCE_CMDS
-
 /* ARGSUSED */
-void
+static void
 maintenance_info_breakpoints (bnum_exp, from_tty)
      char *bnum_exp;
      int from_tty;
@@ -2948,8 +3684,6 @@ maintenance_info_breakpoints (bnum_exp, from_tty)
   breakpoint_1 (bnum, 1);
 }
 
-#endif
-
 /* Print a message describing any breakpoints set at PC.  */
 
 static void
@@ -2962,25 +3696,28 @@ describe_other_breakpoints (pc, section)
 
   ALL_BREAKPOINTS (b)
     if (b->address == pc)
-      if (overlay_debugging == 0 ||
-         b->section == section)
-       others++;
+    if (overlay_debugging == 0 ||
+       b->section == section)
+      others++;
   if (others > 0)
     {
       printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : "");
       ALL_BREAKPOINTS (b)
        if (b->address == pc)
-         if (overlay_debugging == 0 ||
-             b->section == section)
-           {
-             others--;
-             printf_filtered
-               ("%d%s%s ",
-                b->number,
-                ((b->enable == disabled || b->enable == shlib_disabled || b->enable == call_disabled)
-                 ? " (disabled)" : ""),
-                (others > 1) ? "," : ((others == 1) ? " and" : ""));
-           }
+       if (overlay_debugging == 0 ||
+           b->section == section)
+         {
+           others--;
+           printf_filtered
+             ("%d%s%s ",
+              b->number,
+              ((b->enable == disabled || 
+                b->enable == shlib_disabled || 
+                b->enable == call_disabled) ? " (disabled)" 
+               : b->enable == permanent ? " (permanent)"
+               : ""),
+              (others > 1) ? "," : ((others == 1) ? " and" : ""));
+         }
       printf_filtered ("also set at pc ");
       print_address_numeric (pc, 1, gdb_stdout);
       printf_filtered (".\n");
@@ -3005,7 +3742,9 @@ set_default_breakpoint (valid, addr, symtab, line)
 
 /* Rescan breakpoints at address ADDRESS,
    marking the first one as "first" and any others as "duplicates".
-   This is so that the bpt instruction is only inserted once.  */
+   This is so that the bpt instruction is only inserted once.
+   If we have a permanent breakpoint at ADDRESS, make that one
+   the official one, and the rest as duplicates.  */
 
 static void
 check_duplicates (address, section)
@@ -3014,6 +3753,7 @@ check_duplicates (address, section)
 {
   register struct breakpoint *b;
   register int count = 0;
+  struct breakpoint *perm_bp = 0;
 
   if (address == 0)            /* Watchpoints are uninteresting */
     return;
@@ -3024,10 +3764,45 @@ check_duplicates (address, section)
        && b->enable != call_disabled
        && b->address == address
        && (overlay_debugging == 0 || b->section == section))
-      {
-       count++;
-       b->duplicate = count > 1;
-      }
+    {
+      /* Have we found a permanent breakpoint?  */
+      if (b->enable == permanent)
+       {
+         perm_bp = b;
+         break;
+       }
+       
+      count++;
+      b->duplicate = count > 1;
+    }
+
+  /* If we found a permanent breakpoint at this address, go over the
+     list again and declare all the other breakpoints there to be the
+     duplicates.  */
+  if (perm_bp)
+    {
+      perm_bp->duplicate = 0;
+
+      /* Permanent breakpoint should always be inserted.  */
+      if (! perm_bp->inserted)
+       internal_error ("allegedly permanent breakpoint is not "
+                       "actually inserted");
+
+      ALL_BREAKPOINTS (b)
+       if (b != perm_bp)
+         {
+           if (b->inserted)
+             internal_error ("another breakpoint was inserted on top of "
+                             "a permanent breakpoint");
+
+           if (b->enable != disabled
+               && b->enable != shlib_disabled
+               && b->enable != call_disabled
+               && b->address == address
+               && (overlay_debugging == 0 || b->section == section))
+             b->duplicate = 1;
+         }
+    }
 }
 
 /* Low level routine to set a breakpoint.
@@ -3090,6 +3865,18 @@ set_raw_breakpoint (sal)
   return b;
 }
 
+
+/* Note that the breakpoint object B describes a permanent breakpoint
+   instruction, hard-wired into the inferior's code.  */
+void
+make_breakpoint_permanent (struct breakpoint *b)
+{
+  b->enable = permanent;
+
+  /* By definition, permanent breakpoints are already present in the code.  */
+  b->inserted = 1;
+}
+
 #ifdef GET_LONGJMP_TARGET
 
 static void
@@ -3099,12 +3886,13 @@ create_longjmp_breakpoint (func_name)
   struct symtab_and_line sal;
   struct breakpoint *b;
 
-  INIT_SAL (&sal);     /* initialize to zeroes */
+  INIT_SAL (&sal);             /* initialize to zeroes */
   if (func_name != NULL)
     {
       struct minimal_symbol *m;
 
-      m = lookup_minimal_symbol_text (func_name, NULL, (struct objfile *)NULL);
+      m = lookup_minimal_symbol_text (func_name, NULL, 
+                                     (struct objfile *) NULL);
       if (m)
        sal.pc = SYMBOL_VALUE_ADDRESS (m);
       else
@@ -3112,48 +3900,85 @@ create_longjmp_breakpoint (func_name)
     }
   sal.section = find_pc_overlay (sal.pc);
   b = set_raw_breakpoint (sal);
-  if (!b) return;
+  if (!b)
+    return;
 
   b->type = func_name != NULL ? bp_longjmp : bp_longjmp_resume;
   b->disposition = donttouch;
   b->enable = disabled;
   b->silent = 1;
   if (func_name)
-    b->addr_string = strsave(func_name);
+    b->addr_string = strsave (func_name);
   b->number = internal_breakpoint_number--;
 }
 
-#endif /* #ifdef GET_LONGJMP_TARGET */
+#endif /* #ifdef GET_LONGJMP_TARGET */
 
-/* Call this routine when stepping and nexting to enable a breakpoint if we do
-   a longjmp().  When we hit that breakpoint, call
+/* Call this routine when stepping and nexting to enable a breakpoint
+   if we do a longjmp().  When we hit that breakpoint, call
    set_longjmp_resume_breakpoint() to figure out where we are going. */
 
 void
-enable_longjmp_breakpoint()
+enable_longjmp_breakpoint ()
 {
   register struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
     if (b->type == bp_longjmp)
-      {
-       b->enable = enabled;
-       check_duplicates (b->address, b->section);
-      }
+    {
+      b->enable = enabled;
+      check_duplicates (b->address, b->section);
+    }
 }
 
 void
-disable_longjmp_breakpoint()
+disable_longjmp_breakpoint ()
 {
   register struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
-    if (   b->type == bp_longjmp
+    if (b->type == bp_longjmp
        || b->type == bp_longjmp_resume)
-      {
-       b->enable = disabled;
-       check_duplicates (b->address, b->section);
-      }
+    {
+      b->enable = disabled;
+      check_duplicates (b->address, b->section);
+    }
+}
+
+struct breakpoint *
+create_thread_event_breakpoint (address)
+     CORE_ADDR address;
+{
+  struct breakpoint *b;
+  struct symtab_and_line sal;
+  char addr_string[80];                /* Surely an addr can't be longer than that. */
+
+  INIT_SAL (&sal);             /* initialize to zeroes */
+  sal.pc = address;
+  sal.section = find_pc_overlay (sal.pc);
+  if ((b = set_raw_breakpoint (sal)) == NULL)
+    return NULL;
+  
+  b->number = internal_breakpoint_number--;
+  b->disposition = donttouch;
+  b->type = bp_thread_event;   /* XXX: do we need a new type? 
+                                  bp_thread_event */
+  b->enable = enabled;
+  /* addr_string has to be used or breakpoint_re_set will delete me.  */
+  sprintf (addr_string, "*0x%s", paddr (b->address));
+  b->addr_string = strsave (addr_string);
+
+  return b;
+}
+
+void
+remove_thread_event_breakpoints (void)
+{
+  struct breakpoint *b, *temp;
+
+  ALL_BREAKPOINTS_SAFE (b, temp)
+    if (b->type == bp_thread_event)
+      delete_breakpoint (b);
 }
 
 #ifdef SOLIB_ADD
@@ -3164,59 +3989,61 @@ remove_solib_event_breakpoints ()
 
   ALL_BREAKPOINTS_SAFE (b, temp)
     if (b->type == bp_shlib_event)
-      delete_breakpoint (b);
+    delete_breakpoint (b);
 }
 
-void
+struct breakpoint *
 create_solib_event_breakpoint (address)
      CORE_ADDR address;
 {
   struct breakpoint *b;
   struct symtab_and_line sal;
 
-  INIT_SAL (&sal);     /* initialize to zeroes */
+  INIT_SAL (&sal);             /* initialize to zeroes */
   sal.pc = address;
   sal.section = find_pc_overlay (sal.pc);
   b = set_raw_breakpoint (sal);
   b->number = internal_breakpoint_number--;
   b->disposition = donttouch;
   b->type = bp_shlib_event;
+
+  return b;
 }
 
+/* Disable any breakpoints that are on code in shared libraries.  Only
+   apply to enabled breakpoints, disabled ones can just stay disabled.  */
+
 void
 disable_breakpoints_in_shlibs (silent)
      int silent;
 {
-  struct breakpoint *  b;
-  int  disabled_shlib_breaks = 0;
+  struct breakpoint *b;
+  int disabled_shlib_breaks = 0;
 
   /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */
   ALL_BREAKPOINTS (b)
-    {
+  {
 #if defined (PC_SOLIB)
-      if (((b->type == bp_breakpoint) ||
-           (b->type == bp_hardware_breakpoint)) &&
-          (b->enable != shlib_disabled) &&
-          (b->enable != call_disabled) &&
-          ! b->duplicate &&
-          PC_SOLIB (b->address))
-        {
-          b->enable = shlib_disabled;
-         if (!silent)
-           {
-             if (!disabled_shlib_breaks)
-               {
-                 target_terminal_ours_for_output ();
-                 printf_filtered ("Temporarily disabling shared library breakpoints:\n");
-               }
-             disabled_shlib_breaks = 1;
-             printf_filtered ("%d ", b->number);
-           }
-        }
+    if (((b->type == bp_breakpoint) ||
+        (b->type == bp_hardware_breakpoint)) &&
+       b->enable == enabled &&
+       !b->duplicate &&
+       PC_SOLIB (b->address))
+      {
+       b->enable = shlib_disabled;
+       if (!silent)
+         {
+           if (!disabled_shlib_breaks)
+             {
+               target_terminal_ours_for_output ();
+               warning ("Temporarily disabling shared library breakpoints:");
+             }
+           disabled_shlib_breaks = 1;
+           warning ("breakpoint #%d ", b->number);
+         }
+      }
 #endif
-    }
-  if (disabled_shlib_breaks && !silent)
-    printf_filtered ("\n");
+  }
 }
 
 /* Try to reenable any breakpoints in shared libraries.  */
@@ -3227,41 +4054,39 @@ re_enable_breakpoints_in_shlibs ()
 
   ALL_BREAKPOINTS (b)
     if (b->enable == shlib_disabled)
-      {
-       char buf[1];
+    {
+      char buf[1];
 
-       /* Do not reenable the breakpoint if the shared library
-          is still not mapped in.  */
-       if (target_read_memory (b->address, buf, 1) == 0)
-         b->enable = enabled;
-      }
+      /* Do not reenable the breakpoint if the shared library
+         is still not mapped in.  */
+      if (target_read_memory (b->address, buf, 1) == 0)
+       b->enable = enabled;
+    }
 }
 
 #endif
 
 static void
-create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, cond_string, bp_kind)
-  char *  hookname;
-  int  tempflag;
-  char *  dll_pathname;
-  char *  cond_string;
-  enum bptype  bp_kind;
-{
-  struct breakpoint *  b;
+solib_load_unload_1 (hookname, tempflag, dll_pathname, cond_string, bp_kind)
+     char *hookname;
+     int tempflag;
+     char *dll_pathname;
+     char *cond_string;
+     enum bptype bp_kind;
+{
+  struct breakpoint *b;
   struct symtabs_and_lines sals;
-  struct symtab_and_line  sal;
-  struct cleanup *  old_chain;
-  struct cleanup *  canonical_strings_chain = NULL;
-  int  i;
-  char *  addr_start = hookname;
-  char *  addr_end = NULL;
-  char **  canonical = (char **) NULL;
-  int  thread = -1;  /* All threads. */
+  struct cleanup *old_chain;
+  struct cleanup *canonical_strings_chain = NULL;
+  char *addr_start = hookname;
+  char *addr_end = NULL;
+  char **canonical = (char **) NULL;
+  int thread = -1;             /* All threads. */
+
   /* Set a breakpoint on the specified hook. */
   sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical);
   addr_end = hookname;
+
   if (sals.nelts == 0)
     {
       warning ("Unable to set a breakpoint on dynamic linker callback.");
@@ -3271,43 +4096,44 @@ create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, con
     }
   if (sals.nelts != 1)
     {
-      warning ("Unable to set unique breakpoint on dynamic linker callback.");
+      warning ("Unable to set unique breakpoint on dynamic linker callback.");
       warning ("GDB will be unable to track shl_load/shl_unload calls");
       return;
     }
 
-  /* Make sure that all storage allocated in decode_line_1 gets freed in case
-     the following errors out.  */
+  /* Make sure that all storage allocated in decode_line_1 gets freed
+     in case the following errors out.  */
   old_chain = make_cleanup (free, sals.sals);
-  if (canonical != (char **)NULL)
+  if (canonical != (char **) NULL)
     {
       make_cleanup (free, canonical);
       canonical_strings_chain = make_cleanup (null_cleanup, 0);
       if (canonical[0] != NULL)
-        make_cleanup (free, canonical[0]);
+       make_cleanup (free, canonical[0]);
     }
+
   resolve_sal_pc (&sals.sals[0]);
+
   /* Remove the canonical strings from the cleanup, they are needed below.  */
-  if (canonical != (char **)NULL)
+  if (canonical != (char **) NULL)
     discard_cleanups (canonical_strings_chain);
+
   b = set_raw_breakpoint (sals.sals[0]);
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
   b->cond = NULL;
-  b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+  b->cond_string = (cond_string == NULL) ? 
+    NULL : savestring (cond_string, strlen (cond_string));
   b->thread = thread;
-  if (canonical != (char **)NULL && canonical[0] != NULL)
+
+  if (canonical != (char **) NULL && canonical[0] != NULL)
     b->addr_string = canonical[0];
   else if (addr_start)
     b->addr_string = savestring (addr_start, addr_end - addr_start);
+
   b->enable = enabled;
   b->disposition = tempflag ? del : donttouch;
+
   if (dll_pathname == NULL)
     b->dll_pathname = NULL;
   else
@@ -3316,96 +4142,93 @@ create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, con
       strcpy (b->dll_pathname, dll_pathname);
     }
   b->type = bp_kind;
+
   mention (b);
   do_cleanups (old_chain);
 }
 
 void
-create_solib_load_event_breakpoint (hookname, tempflag, dll_pathname, cond_string)
-  char *  hookname;
-  int  tempflag;
-  char *  dll_pathname;
-  char *  cond_string;
+create_solib_load_event_breakpoint (hookname, tempflag, 
+                                   dll_pathname, cond_string)
+     char *hookname;
+     int tempflag;
+     char *dll_pathname;
+     char *cond_string;
 {
-  create_solib_load_unload_event_breakpoint (hookname,
-                                             tempflag,
-                                             dll_pathname,
-                                             cond_string,
-                                             bp_catch_load);
+  solib_load_unload_1 (hookname, tempflag, dll_pathname, 
+                      cond_string, bp_catch_load);
 }
 
 void
-create_solib_unload_event_breakpoint (hookname, tempflag, dll_pathname, cond_string)
-  char *  hookname;
-  int  tempflag;
-  char *  dll_pathname;
-  char *  cond_string;
+create_solib_unload_event_breakpoint (hookname, tempflag, 
+                                     dll_pathname, cond_string)
+     char *hookname;
+     int tempflag;
+     char *dll_pathname;
+     char *cond_string;
 {
-  create_solib_load_unload_event_breakpoint (hookname,
-                                             tempflag,
-                                             dll_pathname,
-                                             cond_string,
-                                             bp_catch_unload);
+  solib_load_unload_1 (hookname,tempflag, dll_pathname, 
+                      cond_string, bp_catch_unload);
 }
 
 static void
 create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_kind)
-  int  tempflag;
-  char *  cond_string;
-  enum bptype  bp_kind;
-{
-  struct symtab_and_line  sal;
-  struct breakpoint *  b;
-  int  thread = -1;  /* All threads. */
-  INIT_SAL(&sal);
+     int tempflag;
+     char *cond_string;
+     enum bptype bp_kind;
+{
+  struct symtab_and_line sal;
+  struct breakpoint *b;
+  int thread = -1;             /* All threads. */
+
+  INIT_SAL (&sal);
   sal.pc = 0;
   sal.symtab = NULL;
   sal.line = 0;
+
   b = set_raw_breakpoint (sal);
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
   b->cond = NULL;
-  b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+  b->cond_string = (cond_string == NULL) ? 
+    NULL : savestring (cond_string, strlen (cond_string));
   b->thread = thread;
   b->addr_string = NULL;
   b->enable = enabled;
   b->disposition = tempflag ? del : donttouch;
   b->forked_inferior_pid = 0;
+
   b->type = bp_kind;
+
   mention (b);
 }
 
 void
 create_fork_event_catchpoint (tempflag, cond_string)
-  int  tempflag;
-  char *  cond_string;
+     int tempflag;
+     char *cond_string;
 {
   create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork);
 }
+
 void
 create_vfork_event_catchpoint (tempflag, cond_string)
-  int  tempflag;
-  char *  cond_string;
+     int tempflag;
+     char *cond_string;
 {
   create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_vfork);
 }
 
 void
 create_exec_event_catchpoint (tempflag, cond_string)
-  int  tempflag;
-  char *  cond_string;
+     int tempflag;
+     char *cond_string;
 {
-  struct symtab_and_line  sal;
-  struct breakpoint *  b;
-  int  thread = -1;  /* All threads. */
+  struct symtab_and_line sal;
+  struct breakpoint *b;
+  int thread = -1;             /* All threads. */
 
-  INIT_SAL(&sal);
+  INIT_SAL (&sal);
   sal.pc = 0;
   sal.symtab = NULL;
   sal.line = 0;
@@ -3414,7 +4237,8 @@ create_exec_event_catchpoint (tempflag, cond_string)
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
   b->cond = NULL;
-  b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+  b->cond_string = (cond_string == NULL) ?
+    NULL : savestring (cond_string, strlen (cond_string));
   b->thread = thread;
   b->addr_string = NULL;
   b->enable = enabled;
@@ -3426,52 +4250,53 @@ create_exec_event_catchpoint (tempflag, cond_string)
 }
 
 static int
-hw_breakpoint_used_count()
+hw_breakpoint_used_count ()
 {
   register struct breakpoint *b;
   int i = 0;
 
   ALL_BREAKPOINTS (b)
-    {
-      if (b->type == bp_hardware_breakpoint && b->enable == enabled)
-       i++;
-    }
+  {
+    if (b->type == bp_hardware_breakpoint && b->enable == enabled)
+      i++;
+  }
 
   return i;
 }
 
 static int
-hw_watchpoint_used_count(type, other_type_used)
-    enum bptype type;
-    int *other_type_used;
+hw_watchpoint_used_count (type, other_type_used)
+     enum bptype type;
+     int *other_type_used;
 {
   register struct breakpoint *b;
   int i = 0;
 
   *other_type_used = 0;
   ALL_BREAKPOINTS (b)
-    {
-      if (b->enable == enabled)
-       {
-          if (b->type == type) i++;
-          else if ((b->type == bp_hardware_watchpoint ||
-              b->type == bp_read_watchpoint ||
-              b->type == bp_access_watchpoint)
-              && b->enable == enabled)
-           *other_type_used = 1;
-        }
-    }
+  {
+    if (b->enable == enabled)
+      {
+       if (b->type == type)
+         i++;
+       else if ((b->type == bp_hardware_watchpoint ||
+                 b->type == bp_read_watchpoint ||
+                 b->type == bp_access_watchpoint)
+                && b->enable == enabled)
+         *other_type_used = 1;
+      }
+  }
   return i;
 }
 
-/* Call this after hitting the longjmp() breakpoint.  Use this to set a new
-   breakpoint at the target of the jmp_buf.
+/* Call this after hitting the longjmp() breakpoint.  Use this to set
+   a new breakpoint at the target of the jmp_buf.
 
-   FIXME - This ought to be done by setting a temporary breakpoint that gets
-   deleted automatically... */
+   FIXME - This ought to be done by setting a temporary breakpoint
+   that gets deleted automatically... */
 
 void
-set_longjmp_resume_breakpoint(pc, frame)
+set_longjmp_resume_breakpoint (pc, frame)
      CORE_ADDR pc;
      struct frame_info *frame;
 {
@@ -3479,56 +4304,56 @@ set_longjmp_resume_breakpoint(pc, frame)
 
   ALL_BREAKPOINTS (b)
     if (b->type == bp_longjmp_resume)
-      {
-       b->address = pc;
-       b->enable = enabled;
-       if (frame != NULL)
-         b->frame = frame->frame;
-       else
-         b->frame = 0;
-       check_duplicates (b->address, b->section);
-       return;
-      }
+    {
+      b->address = pc;
+      b->enable = enabled;
+      if (frame != NULL)
+       b->frame = frame->frame;
+      else
+       b->frame = 0;
+      check_duplicates (b->address, b->section);
+      return;
+    }
 }
 
 void
 disable_watchpoints_before_interactive_call_start ()
 {
-  struct breakpoint *  b;
+  struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
-    {
-      if (((b->type == bp_watchpoint)
-           || (b->type == bp_hardware_watchpoint)
-           || (b->type == bp_read_watchpoint)
-           || (b->type == bp_access_watchpoint)
-           || ep_is_exception_catchpoint (b))
-          && (b->enable == enabled))
-        {
-          b->enable = call_disabled;
-          check_duplicates (b->address, b->section);
-        }
-    }
+  {
+    if (((b->type == bp_watchpoint)
+        || (b->type == bp_hardware_watchpoint)
+        || (b->type == bp_read_watchpoint)
+        || (b->type == bp_access_watchpoint)
+        || ep_is_exception_catchpoint (b))
+       && (b->enable == enabled))
+      {
+       b->enable = call_disabled;
+       check_duplicates (b->address, b->section);
+      }
+  }
 }
 
 void
 enable_watchpoints_after_interactive_call_stop ()
 {
-  struct breakpoint *  b;
+  struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
-    {
-      if (((b->type == bp_watchpoint)
-           || (b->type == bp_hardware_watchpoint)
-           || (b->type == bp_read_watchpoint)
-           || (b->type == bp_access_watchpoint)
-           || ep_is_exception_catchpoint (b))
-          && (b->enable == call_disabled))
-        {
-          b->enable = enabled;
-          check_duplicates (b->address, b->section);
-        }
-    }
+  {
+    if (((b->type == bp_watchpoint)
+        || (b->type == bp_hardware_watchpoint)
+        || (b->type == bp_read_watchpoint)
+        || (b->type == bp_access_watchpoint)
+        || ep_is_exception_catchpoint (b))
+       && (b->enable == call_disabled))
+      {
+       b->enable = enabled;
+       check_duplicates (b->address, b->section);
+      }
+  }
 }
 
 
@@ -3557,8 +4382,8 @@ set_momentary_breakpoint (sal, frame, type)
 
   return b;
 }
-
 \f
+
 /* Tell the user we have just set a breakpoint B.  */
 
 static void
@@ -3566,6 +4391,13 @@ mention (b)
      struct breakpoint *b;
 {
   int say_where = 0;
+#ifdef UI_OUT
+  struct cleanup *old_chain;
+  struct ui_stream *stb;
+
+  stb = ui_out_stream_new (uiout);
+  old_chain = make_cleanup ((make_cleanup_func) ui_out_stream_delete, stb);
+#endif /* UI_OUT */
 
   /* FIXME: This is misplaced; mention() is called by things (like hitting a
      watchpoint) other than breakpoint creation.  It should be possible to
@@ -3574,12 +4406,33 @@ mention (b)
      delete_breakpoint_hook and so on.  */
   if (create_breakpoint_hook)
     create_breakpoint_hook (b);
+  breakpoint_create_event (b->number);
 
   switch (b->type)
     {
     case bp_none:
       printf_filtered ("(apparently deleted?) Eventpoint %d: ", b->number);
       break;
+#ifdef UI_OUT
+    case bp_watchpoint:
+      ui_out_text (uiout, "Watchpoint ");
+      ui_out_list_begin (uiout, "wpt");
+      ui_out_field_int (uiout, "number", b->number);
+      ui_out_text (uiout, ": ");
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "exp", stb);
+      ui_out_list_end (uiout);
+      break;
+    case bp_hardware_watchpoint:
+      ui_out_text (uiout, "Hardware watchpoint ");
+      ui_out_list_begin (uiout, "wpt");
+      ui_out_field_int (uiout, "number", b->number);
+      ui_out_text (uiout, ": ");
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "exp", stb);
+      ui_out_list_end (uiout);
+      break;
+#else
     case bp_watchpoint:
       printf_filtered ("Watchpoint %d: ", b->number);
       print_expression (b->exp, gdb_stdout);
@@ -3588,44 +4441,82 @@ mention (b)
       printf_filtered ("Hardware watchpoint %d: ", b->number);
       print_expression (b->exp, gdb_stdout);
       break;
+#endif
+#ifdef UI_OUT
+    case bp_read_watchpoint:
+      ui_out_text (uiout, "Hardware read watchpoint ");
+      ui_out_list_begin (uiout, "hw-rwpt");
+      ui_out_field_int (uiout, "number", b->number);
+      ui_out_text (uiout, ": ");
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "exp", stb);
+      ui_out_list_end (uiout);
+      break;
+    case bp_access_watchpoint:
+      ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
+      ui_out_list_begin (uiout, "hw-awpt");
+      ui_out_field_int (uiout, "number", b->number);
+      ui_out_text (uiout, ": ");
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "exp", stb);
+      ui_out_list_end (uiout);
+      break;
+#else
     case bp_read_watchpoint:
       printf_filtered ("Hardware read watchpoint %d: ", b->number);
       print_expression (b->exp, gdb_stdout);
       break;
     case bp_access_watchpoint:
-      printf_filtered ("Hardware access (read/write) watchpoint %d: ",b->number);
+      printf_filtered ("Hardware access (read/write) watchpoint %d: ", 
+                      b->number);
       print_expression (b->exp, gdb_stdout);
       break;
+#endif
     case bp_breakpoint:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       {
+         say_where = 0;
+         break;
+       }
+#endif
       printf_filtered ("Breakpoint %d", b->number);
       say_where = 1;
       break;
     case bp_hardware_breakpoint:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       {
+         say_where = 0;
+         break;
+       }
+#endif
       printf_filtered ("Hardware assisted breakpoint %d", b->number);
       say_where = 1;
       break;
     case bp_catch_load:
     case bp_catch_unload:
       printf_filtered ("Catchpoint %d (%s %s)",
-                       b->number,
-                       (b->type == bp_catch_load) ? "load" : "unload",
-                       (b->dll_pathname != NULL) ? b->dll_pathname : "<any library>");
+                      b->number,
+                      (b->type == bp_catch_load) ? "load" : "unload",
+                      (b->dll_pathname != NULL) ? 
+                      b->dll_pathname : "<any library>");
       break;
     case bp_catch_fork:
     case bp_catch_vfork:
       printf_filtered ("Catchpoint %d (%s)",
-                       b->number,
-                       (b->type == bp_catch_fork) ? "fork" : "vfork");
+                      b->number,
+                      (b->type == bp_catch_fork) ? "fork" : "vfork");
       break;
     case bp_catch_exec:
       printf_filtered ("Catchpoint %d (exec)",
-                       b->number);
+                      b->number);
       break;
     case bp_catch_catch:
     case bp_catch_throw:
       printf_filtered ("Catchpoint %d (%s)",
-                       b->number,
-                       (b->type == bp_catch_catch) ? "catch" : "throw");
+                      b->number,
+                      (b->type == bp_catch_catch) ? "catch" : "throw");
       break;
 
     case bp_until:
@@ -3637,6 +4528,7 @@ mention (b)
     case bp_call_dummy:
     case bp_watchpoint_scope:
     case bp_shlib_event:
+    case bp_thread_event:
       break;
     }
   if (say_where)
@@ -3649,114 +4541,149 @@ mention (b)
       if (b->source_file)
        printf_filtered (": file %s, line %d.",
                         b->source_file, b->line_number);
-      TUIDO(((TuiOpaqueFuncPtr)tui_vAllSetHasBreakAt, b, 1));
-      TUIDO(((TuiOpaqueFuncPtr)tuiUpdateAllExecInfos));
+      TUIDO (((TuiOpaqueFuncPtr) tui_vAllSetHasBreakAt, b, 1));
+      TUIDO (((TuiOpaqueFuncPtr) tuiUpdateAllExecInfos));
     }
+#ifdef UI_OUT
+  do_cleanups (old_chain);
+#endif
+#ifdef UI_OUT
+  if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+    return;
+#endif
   printf_filtered ("\n");
 }
-
 \f
-/* Set a breakpoint according to ARG (function, linenum or *address)
-   flag: first bit  : 0 non-temporary, 1 temporary.
-        second bit : 0 normal breakpoint, 1 hardware breakpoint. */
 
-static void
-break_command_1 (arg, flag, from_tty)
-     char *arg;
-     int flag, from_tty;
-{
-  int tempflag, hardwareflag;
-  struct symtabs_and_lines sals;
-  struct symtab_and_line sal;
-  register struct expression *cond = 0;
-  register struct breakpoint *b;
+/* Add SALS.nelts breakpoints to the breakpoint table.  For each
+   SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i],
+   COND[i] and COND_STRING[i] values.
 
-  /* Pointers in arg to the start, and one past the end, of the condition.  */
-  char *cond_start = NULL;
-  char *cond_end = NULL;
-  /* Pointers in arg to the start, and one past the end,
-     of the address part.  */
-  char *addr_start = NULL;
-  char *addr_end = NULL;
-  struct cleanup *old_chain;
-  struct cleanup *canonical_strings_chain = NULL;
-  char **canonical = (char **)NULL;
-  int i;
-  int thread;
+   NOTE: If the function succeeds, the caller is expected to cleanup
+   the arrays ADDR_STRING, COND_STRING, COND and SALS (but not the
+   array contents).  If the function fails (error() is called), the
+   caller is expected to cleanups both the ADDR_STRING, COND_STRING,
+   COND and SALS arrays and each of those arrays contents. */
 
-  hardwareflag = flag & BP_HARDWAREFLAG;
-  tempflag = flag & BP_TEMPFLAG;
+static void
+create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
+                   struct expression **cond, char **cond_string,
+                   enum bptype type, enum bpdisp disposition,
+                   int thread, int ignore_count, int from_tty)
+{
+  if (type == bp_hardware_breakpoint)
+    {
+      int i = hw_breakpoint_used_count ();
+      int target_resources_ok = 
+       TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint, 
+                                           i + sals.nelts, 0);
+      if (target_resources_ok == 0)
+       error ("No hardware breakpoint support in the target.");
+      else if (target_resources_ok < 0)
+       error ("Hardware breakpoints used exceeds limit.");
+    }
 
-  sals.sals = NULL;
-  sals.nelts = 0;
+  /* Now set all the breakpoints.  */
+  {
+    int i;
+    for (i = 0; i < sals.nelts; i++)
+      {
+       struct breakpoint *b;
+       struct symtab_and_line sal = sals.sals[i];
 
-  INIT_SAL (&sal);     /* initialize to zeroes */
+       if (from_tty)
+         describe_other_breakpoints (sal.pc, sal.section);
+       
+       b = set_raw_breakpoint (sal);
+       set_breakpoint_count (breakpoint_count + 1);
+       b->number = breakpoint_count;
+       b->type = type;
+       b->cond = cond[i];
+       b->thread = thread;
+       b->addr_string = addr_string[i];
+       b->cond_string = cond_string[i];
+       b->ignore_count = ignore_count;
+       b->enable = enabled;
+       b->disposition = disposition;
+       mention (b);
+      }
+  }    
+}
 
-  /* If no arg given, or if first arg is 'if ', use the default breakpoint. */
+/* Parse ARG which is assumed to be a SAL specification possibly
+   followed by conditionals.  On return, SALS contains an array of SAL
+   addresses found. ADDR_STRING contains a vector of (canonical)
+   address strings. ARG points to the end of the SAL. */
 
-  if (!arg || (arg[0] == 'i' && arg[1] == 'f' 
-              && (arg[2] == ' ' || arg[2] == '\t')))
+void
+parse_breakpoint_sals (char **address,
+                      struct symtabs_and_lines *sals,
+                      char ***addr_string)
+{
+  char *addr_start = *address;
+  *addr_string = NULL;
+  /* If no arg given, or if first arg is 'if ', use the default
+     breakpoint. */
+  if ((*address) == NULL
+      || (strncmp ((*address), "if", 2) == 0 && isspace ((*address)[2])))
     {
       if (default_breakpoint_valid)
        {
-         sals.sals = (struct symtab_and_line *) 
+         struct symtab_and_line sal;
+         INIT_SAL (&sal);              /* initialize to zeroes */
+         sals->sals = (struct symtab_and_line *)
            xmalloc (sizeof (struct symtab_and_line));
          sal.pc = default_breakpoint_address;
          sal.line = default_breakpoint_line;
          sal.symtab = default_breakpoint_symtab;
-         sal.section  = find_pc_overlay (sal.pc);
-         sals.sals[0] = sal;
-         sals.nelts = 1;
+         sal.section = find_pc_overlay (sal.pc);
+         sals->sals[0] = sal;
+         sals->nelts = 1;
        }
       else
        error ("No default breakpoint address now.");
     }
   else
     {
-      addr_start = arg;
-
       /* Force almost all breakpoints to be in terms of the
-        current_source_symtab (which is decode_line_1's default).  This
-        should produce the results we want almost all of the time while
-        leaving default_breakpoint_* alone.  */
+         current_source_symtab (which is decode_line_1's default).  This
+         should produce the results we want almost all of the time while
+         leaving default_breakpoint_* alone.  */
       if (default_breakpoint_valid
          && (!current_source_symtab
-             || (arg && (*arg == '+' || *arg == '-'))))
-       sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
-                             default_breakpoint_line, &canonical);
+             || (strchr ("+-", (*address)[0]) != NULL)))
+       *sals = decode_line_1 (address, 1, default_breakpoint_symtab,
+                              default_breakpoint_line, addr_string);
       else
-       sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0, &canonical);
-
-      addr_end = arg;
+       *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string);
     }
-  
-  if (! sals.nelts) 
-    return;
-
-  /* Make sure that all storage allocated in decode_line_1 gets freed in case
-     the following `for' loop errors out.  */
-  old_chain = make_cleanup (free, sals.sals);
-  if (canonical != (char **)NULL)
+  /* For any SAL that didn't have a canonical string, fill one in. */
+  if (sals->nelts > 0 && *addr_string == NULL)
+    *addr_string = xcalloc (sals->nelts, sizeof (char **));
+  if (addr_start != (*address))
     {
-      make_cleanup (free, canonical);
-      canonical_strings_chain = make_cleanup (null_cleanup, 0);
-      for (i = 0; i < sals.nelts; i++)
+      int i;
+      for (i = 0; i < sals->nelts; i++)
        {
-         if (canonical[i] != NULL)
-           make_cleanup (free, canonical[i]);
+         /* Add the string if not present. */
+         if ((*addr_string)[i] == NULL)
+           (*addr_string)[i] = savestring (addr_start, (*address) - addr_start);
        }
     }
+}
 
-  thread = -1;                 /* No specific thread yet */
 
-  /* Resolve all line numbers to PC's, and verify that conditions
-     can be parsed, before setting any breakpoints.  */
-  for (i = 0; i < sals.nelts; i++)
-    {
-      char *tok, *end_tok;
-      int toklen;
+/* Convert each SAL into a real PC.  Verify that the PC can be
+   inserted as a breakpoint.  If it can't throw an error. */
 
-      resolve_sal_pc (&sals.sals[i]);
+void
+breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
+                      char *address)
+{    
+  int i;
+  for (i = 0; i < sals->nelts; i++)
+    {
+      resolve_sal_pc (&sals->sals[i]);
 
       /* It's possible for the PC to be nonzero, but still an illegal
          value on some targets.
@@ -3771,15 +4698,100 @@ break_command_1 (arg, flag, from_tty)
 
          Give the target a chance to bless sals.sals[i].pc before we
          try to make a breakpoint for it. */
-      if (PC_REQUIRES_RUN_BEFORE_USE(sals.sals[i].pc))
-        {
-          error ("Cannot break on %s without a running program.", addr_start);
-        }
-      
-      tok = arg;
+      if (PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
+       {
+         if (address == NULL)
+           error ("Cannot break without a running program.");
+         else
+           error ("Cannot break on %s without a running program.", 
+                  address);
+       }
+    }
+}
+
+/* Set a breakpoint according to ARG (function, linenum or *address)
+   flag: first bit  : 0 non-temporary, 1 temporary.
+   second bit : 0 normal breakpoint, 1 hardware breakpoint. */
+
+static void
+break_command_1 (arg, flag, from_tty)
+     char *arg;
+     int flag, from_tty;
+{
+  int tempflag, hardwareflag;
+  struct symtabs_and_lines sals;
+  register struct expression **cond = 0;
+  /* Pointers in arg to the start, and one past the end, of the
+     condition.  */
+  char **cond_string = (char **) NULL;
+  char *addr_start = arg;
+  char **addr_string;
+  struct cleanup *old_chain;
+  struct cleanup *breakpoint_chain = NULL;
+  int i;
+  int thread = -1;
+  int ignore_count = 0;
+
+  hardwareflag = flag & BP_HARDWAREFLAG;
+  tempflag = flag & BP_TEMPFLAG;
+
+  sals.sals = NULL;
+  sals.nelts = 0;
+  addr_string = NULL;
+  parse_breakpoint_sals (&arg, &sals, &addr_string);
 
+  if (!sals.nelts)
+    return;
+
+  /* Create a chain of things that always need to be cleaned up. */
+  old_chain = make_cleanup (null_cleanup, 0);
+
+  /* Make sure that all storage allocated to SALS gets freed.  */
+  make_cleanup (free, sals.sals);
+
+  /* Cleanup the addr_string array but not its contents. */
+  make_cleanup (free, addr_string);
+
+  /* Allocate space for all the cond expressions. */
+  cond = xcalloc (sals.nelts, sizeof (struct expression *));
+  make_cleanup (free, cond);
+
+  /* Allocate space for all the cond strings. */
+  cond_string = xcalloc (sals.nelts, sizeof (char **));
+  make_cleanup (free, cond_string);
+
+  /* ----------------------------- SNIP -----------------------------
+     Anything added to the cleanup chain beyond this point is assumed
+     to be part of a breakpoint.  If the breakpoint create succeeds
+     then the memory is not reclaimed. */
+  breakpoint_chain = make_cleanup (null_cleanup, 0);
+
+  /* Mark the contents of the addr_string for cleanup.  These go on
+     the breakpoint_chain and only occure if the breakpoint create
+     fails. */
+  for (i = 0; i < sals.nelts; i++)
+    {
+      if (addr_string[i] != NULL)
+       make_cleanup (free, addr_string[i]);
+    }
+
+  /* Resolve all line numbers to PC's and verify that the addresses
+     are ok for the target.  */
+  breakpoint_sals_to_pc (&sals, addr_start);
+
+  /* Verify that condition can be parsed, before setting any
+     breakpoints.  Allocate a separate condition expression for each
+     breakpoint. */
+  thread = -1;                 /* No specific thread yet */
+  for (i = 0; i < sals.nelts; i++)
+    {
+      char *tok = arg;
       while (tok && *tok)
        {
+         char *end_tok;
+         int toklen;
+         char *cond_start = NULL;
+         char *cond_end = NULL;
          while (*tok == ' ' || *tok == '\t')
            tok++;
 
@@ -3793,8 +4805,11 @@ break_command_1 (arg, flag, from_tty)
          if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
            {
              tok = cond_start = end_tok + 1;
-             cond = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+             cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+             make_cleanup (free, cond[i]);
              cond_end = tok;
+             cond_string[i] = savestring (cond_start, cond_end - cond_start);
+             make_cleanup (free, cond_string[i]);
            }
          else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
            {
@@ -3812,60 +4827,149 @@ break_command_1 (arg, flag, from_tty)
            error ("Junk at end of arguments.");
        }
     }
-  if (hardwareflag)
-    {
-      int i, target_resources_ok;
 
-      i = hw_breakpoint_used_count ();  
-      target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
-               bp_hardware_breakpoint, i + sals.nelts, 0);
-      if (target_resources_ok == 0)
-       error ("No hardware breakpoint support in the target.");
-      else if (target_resources_ok < 0)
-        error ("Hardware breakpoints used exceeds limit.");
+  create_breakpoints (sals, addr_string, cond, cond_string,
+                     hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
+                     tempflag ? del : donttouch,
+                     thread, ignore_count, from_tty);
+
+  if (sals.nelts > 1)
+    {
+      warning ("Multiple breakpoints were set.");
+      warning ("Use the \"delete\" command to delete unwanted breakpoints.");
     }
+  /* That's it. Discard the cleanups for data inserted into the
+     breakpoint. */
+  discard_cleanups (breakpoint_chain);
+  /* But cleanup everything else. */
+  do_cleanups (old_chain);
+}
 
-  /* Remove the canonical strings from the cleanup, they are needed below.  */
-  if (canonical != (char **)NULL)
-    discard_cleanups (canonical_strings_chain);
+/* Set a breakpoint of TYPE/DISPOSITION according to ARG (function,
+   linenum or *address) with COND and IGNORE_COUNT. */
 
-  /* Now set all the breakpoints.  */
+struct captured_breakpoint_args
+  {
+    char *address;
+    char *condition;
+    int hardwareflag;
+    int tempflag;
+    int thread;
+    int ignore_count;
+  };
+
+static int
+do_captured_breakpoint (void *data)
+{
+  struct captured_breakpoint_args *args = data;
+  struct symtabs_and_lines sals;
+  register struct expression **cond;
+  struct cleanup *old_chain;
+  struct cleanup *breakpoint_chain = NULL;
+  int i;
+  char **addr_string;
+  char **cond_string;
+
+  char *address_end;
+
+  /* Parse the source and lines spec.  Delay check that the expression
+     didn't contain trailing garbage until after cleanups are in
+     place. */
+  sals.sals = NULL;
+  sals.nelts = 0;
+  address_end = args->address;
+  addr_string = NULL;
+  parse_breakpoint_sals (&address_end, &sals, &addr_string);
+
+  if (!sals.nelts)
+    return GDB_RC_NONE;
+
+  /* Create a chain of things at always need to be cleaned up. */
+  old_chain = make_cleanup (null_cleanup, 0);
+
+  /* Always have a addr_string array, even if it is empty. */
+  make_cleanup (free, addr_string);
+
+  /* Make sure that all storage allocated to SALS gets freed.  */
+  make_cleanup (free, sals.sals);
+
+  /* Allocate space for all the cond expressions. */
+  cond = xcalloc (sals.nelts, sizeof (struct expression *));
+  make_cleanup (free, cond);
+
+  /* Allocate space for all the cond strings. */
+  cond_string = xcalloc (sals.nelts, sizeof (char **));
+  make_cleanup (free, cond_string);
+
+  /* ----------------------------- SNIP -----------------------------
+     Anything added to the cleanup chain beyond this point is assumed
+     to be part of a breakpoint.  If the breakpoint create goes
+     through then that memory is not cleaned up. */
+  breakpoint_chain = make_cleanup (null_cleanup, 0);
+
+  /* Mark the contents of the addr_string for cleanup.  These go on
+     the breakpoint_chain and only occure if the breakpoint create
+     fails. */
   for (i = 0; i < sals.nelts; i++)
     {
-      sal = sals.sals[i];
+      if (addr_string[i] != NULL)
+       make_cleanup (free, addr_string[i]);
+    }
 
-      if (from_tty)
-       describe_other_breakpoints (sal.pc, sal.section);
+  /* Wait until now before checking for garbage at the end of the
+     address. That way cleanups can take care of freeing any
+     memory. */
+  if (*address_end != '\0')
+    error ("Garbage %s following breakpoint address", address_end);
 
-      b = set_raw_breakpoint (sal);
-      set_breakpoint_count (breakpoint_count + 1);
-      b->number = breakpoint_count;
-      b->type = hardwareflag ? bp_hardware_breakpoint : bp_breakpoint;
-      b->cond = cond;
-      b->thread = thread;
-
-      /* If a canonical line spec is needed use that instead of the
-        command string.  */
-      if (canonical != (char **)NULL && canonical[i] != NULL)
-       b->addr_string = canonical[i];
-      else if (addr_start)
-       b->addr_string = savestring (addr_start, addr_end - addr_start);
-      if (cond_start)
-       b->cond_string = savestring (cond_start, cond_end - cond_start);
-                                    
-      b->enable = enabled;
-      b->disposition = tempflag ? del : donttouch;
-      mention (b);
-    }
+  /* Resolve all line numbers to PC's.  */
+  breakpoint_sals_to_pc (&sals, args->address);
 
-  if (sals.nelts > 1)
+  /* Verify that conditions can be parsed, before setting any
+     breakpoints.  */
+  for (i = 0; i < sals.nelts; i++)
     {
-      printf_filtered ("Multiple breakpoints were set.\n");
-      printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+      if (args->condition != NULL)
+       {
+         char *tok = args->condition;
+         cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+         if (*tok != '\0')
+           error ("Garbage %s follows condition", tok);
+         make_cleanup (free, cond[i]);
+         cond_string[i] = xstrdup (args->condition);
+       }
     }
+
+  create_breakpoints (sals, addr_string, cond, cond_string,
+                     args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
+                     args->tempflag ? del : donttouch,
+                     args->thread, args->ignore_count, 0/*from-tty*/);
+
+  /* That's it. Discard the cleanups for data inserted into the
+     breakpoint. */
+  discard_cleanups (breakpoint_chain);
+  /* But cleanup everything else. */
   do_cleanups (old_chain);
+  return GDB_RC_OK;
+}
+
+enum gdb_rc
+gdb_breakpoint (char *address, char *condition,
+               int hardwareflag, int tempflag,
+               int thread, int ignore_count)
+{
+  struct captured_breakpoint_args args;
+  args.address = address;
+  args.condition = condition;
+  args.hardwareflag = hardwareflag;
+  args.tempflag = tempflag;
+  args.thread = thread;
+  args.ignore_count = ignore_count;
+  return catch_errors (do_captured_breakpoint, &args,
+                      NULL, RETURN_MASK_ALL);
 }
 
+
 static void
 break_at_finish_at_depth_command_1 (arg, flag, from_tty)
      char *arg;
@@ -3921,18 +5025,18 @@ break_at_finish_at_depth_command_1 (arg, flag, from_tty)
   if (if_arg)
     {
       extra_args = arg;
-      extra_args_len = strlen (arg); 
+      extra_args_len = strlen (arg);
     }
 
   if (selected_pc)
     {
-      if (find_pc_partial_function(selected_pc, (char **)NULL, &low, &high))
+      if (find_pc_partial_function (selected_pc, (char **) NULL, &low, &high))
        {
          addr_string = (char *) xmalloc (26 + extra_args_len);
          if (extra_args_len)
-           sprintf (addr_string, "*0x%x %s", high, extra_args);
+           sprintf (addr_string, "*0x%s %s", paddr_nz (high), extra_args);
          else
-           sprintf (addr_string, "*0x%x", high);
+           sprintf (addr_string, "*0x%s", paddr_nz (high));
          break_command_1 (addr_string, flag, from_tty);
          free (addr_string);
        }
@@ -3967,7 +5071,7 @@ break_at_finish_command_1 (arg, flag, from_tty)
          if (selected_frame)
            {
              addr_string = (char *) xmalloc (15);
-             sprintf (addr_string, "*0x%x", selected_frame->pc);
+             sprintf (addr_string, "*0x%s", paddr_nz (selected_frame->pc));
              if (arg)
                if_arg = 1;
            }
@@ -3986,51 +5090,50 @@ break_at_finish_command_1 (arg, flag, from_tty)
   if (if_arg)
     {
       extra_args = arg;
-      extra_args_len = strlen (arg); 
+      extra_args_len = strlen (arg);
+    }
+  else if (arg)
+    {
+      /* get the stuff after the function name or address */
+      extra_args = strchr (arg, ' ');
+      if (extra_args)
+       {
+         extra_args++;
+         extra_args_len = strlen (extra_args);
+       }
     }
-  else
-    if (arg)
-      {
-       /* get the stuff after the function name or address */
-       extra_args = strchr (arg, ' ');
-        if (extra_args)
-         {
-           extra_args++;
-           extra_args_len = strlen (extra_args);
-          }
-      }
 
   sals.sals = NULL;
   sals.nelts = 0;
 
-  beg_addr_string = addr_string;  
-  sals = decode_line_1 (&addr_string, 1, (struct symtab *)NULL, 0, 
-                       (char ***)NULL);
+  beg_addr_string = addr_string;
+  sals = decode_line_1 (&addr_string, 1, (struct symtab *) NULL, 0,
+                       (char ***) NULL);
 
   free (beg_addr_string);
   old_chain = make_cleanup (free, sals.sals);
   for (i = 0; (i < sals.nelts); i++)
     {
       sal = sals.sals[i];
-      if (find_pc_partial_function (sal.pc, (char **)NULL, &low, &high))
+      if (find_pc_partial_function (sal.pc, (char **) NULL, &low, &high))
        {
          break_string = (char *) xmalloc (extra_args_len + 26);
          if (extra_args_len)
-           sprintf (break_string, "*0x%x %s", high, extra_args);
+           sprintf (break_string, "*0x%s %s", paddr_nz (high), extra_args);
          else
-           sprintf (break_string, "*0x%x", high);
+           sprintf (break_string, "*0x%s", paddr_nz (high));
          break_command_1 (break_string, flag, from_tty);
-         free(break_string);
+         free (break_string);
        }
       else
        error ("No function contains the specified address");
     }
   if (sals.nelts > 1)
     {
-      printf_filtered ("Multiple breakpoints were set.\n");
-      printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+      warning ("Multiple breakpoints were set.\n");
+      warning ("Use the \"delete\" command to delete unwanted breakpoints.");
     }
-  do_cleanups(old_chain);
+  do_cleanups (old_chain);
 }
 
 
@@ -4053,14 +5156,14 @@ resolve_sal_pc (sal)
   if (sal->section == 0 && sal->symtab != NULL)
     {
       struct blockvector *bv;
-      struct block       *b;
-      struct symbol      *sym;
-      int                 index;
+      struct block *b;
+      struct symbol *sym;
+      int index;
 
-      bv  = blockvector_for_pc_sect (sal->pc, 0, &index, sal->symtab);
+      bv = blockvector_for_pc_sect (sal->pc, 0, &index, sal->symtab);
       if (bv != NULL)
        {
-         b   = BLOCKVECTOR_BLOCK (bv, index);
+         b = BLOCKVECTOR_BLOCK (bv, index);
          sym = block_function (b);
          if (sym != NULL)
            {
@@ -4070,11 +5173,11 @@ resolve_sal_pc (sal)
          else
            {
              /* It really is worthwhile to have the section, so we'll just
-                have to look harder. This case can be executed if we have 
-                line numbers but no functions (as can happen in assembly 
-                source).  */
+                have to look harder. This case can be executed if we have 
+                line numbers but no functions (as can happen in assembly 
+                source).  */
 
-             struct minimal_symbol *msym; 
+             struct minimal_symbol *msym;
 
              msym = lookup_minimal_symbol_by_pc (sal->pc);
              if (msym)
@@ -4092,7 +5195,7 @@ break_command (arg, from_tty)
   break_command_1 (arg, 0, from_tty);
 }
 
-void
+static void
 break_at_finish_command (arg, from_tty)
      char *arg;
      int from_tty;
@@ -4100,7 +5203,7 @@ break_at_finish_command (arg, from_tty)
   break_at_finish_command_1 (arg, 0, from_tty);
 }
 
-void
+static void
 break_at_finish_at_depth_command (arg, from_tty)
      char *arg;
      int from_tty;
@@ -4116,7 +5219,7 @@ tbreak_command (arg, from_tty)
   break_command_1 (arg, BP_TEMPFLAG, from_tty);
 }
 
-void
+static void
 tbreak_at_finish_command (arg, from_tty)
      char *arg;
      int from_tty;
@@ -4157,30 +5260,30 @@ stopin_command (arg, from_tty)
 {
   int badInput = 0;
 
-  if (arg == (char *)NULL)
+  if (arg == (char *) NULL)
     badInput = 1;
   else if (*arg != '*')
     {
       char *argptr = arg;
       int hasColon = 0;
 
-      /* look for a ':'.  If this is a line number specification, then say
-        it is bad, otherwise, it should be an address or function/method
-        name */
+      /* look for a ':'.  If this is a line number specification, then
+         say it is bad, otherwise, it should be an address or
+         function/method name */
       while (*argptr && !hasColon)
-        {
-          hasColon = (*argptr == ':');
-          argptr++;
-        }
+       {
+         hasColon = (*argptr == ':');
+         argptr++;
+       }
 
       if (hasColon)
-        badInput = (*argptr != ':'); /* Not a class::method */
+       badInput = (*argptr != ':');    /* Not a class::method */
       else
-        badInput = isdigit(*arg); /* a simple line number */
+       badInput = isdigit (*arg);      /* a simple line number */
     }
 
   if (badInput)
-    printf_filtered("Usage: stop in <function | address>\n");
+    printf_filtered ("Usage: stop in <function | address>\n");
   else
     break_command_1 (arg, 0, from_tty);
 }
@@ -4192,7 +5295,7 @@ stopat_command (arg, from_tty)
 {
   int badInput = 0;
 
-  if (arg == (char *)NULL || *arg == '*') /* no line number */
+  if (arg == (char *) NULL || *arg == '*')     /* no line number */
     badInput = 1;
   else
     {
@@ -4200,27 +5303,29 @@ stopat_command (arg, from_tty)
       int hasColon = 0;
 
       /* look for a ':'.  If there is a '::' then get out, otherwise
-        it is probably a line number. */
+         it is probably a line number. */
       while (*argptr && !hasColon)
-        {
-          hasColon = (*argptr == ':');
-          argptr++;
-        }
+       {
+         hasColon = (*argptr == ':');
+         argptr++;
+       }
 
       if (hasColon)
-        badInput = (*argptr == ':'); /* we have class::method */
+       badInput = (*argptr == ':');    /* we have class::method */
       else
-        badInput = !isdigit(*arg); /* not a line number */
+       badInput = !isdigit (*arg);     /* not a line number */
     }
 
   if (badInput)
-    printf_filtered("Usage: stop at <line>\n");
+    printf_filtered ("Usage: stop at <line>\n");
   else
     break_command_1 (arg, 0, from_tty);
 }
 
 /* ARGSUSED */
-/* accessflag:  0: watch write, 1: watch read, 2: watch access(read or write) */
+/* accessflag:  hw_write:  watch write, 
+                hw_read:   watch read, 
+               hw_access: watch access (read or write) */
 static void
 watch_command_1 (arg, accessflag, from_tty)
      char *arg;
@@ -4245,8 +5350,8 @@ watch_command_1 (arg, accessflag, from_tty)
   enum bptype bp_type;
   int mem_cnt = 0;
 
-  INIT_SAL (&sal);     /* initialize to zeroes */
-  
+  INIT_SAL (&sal);             /* initialize to zeroes */
+
   /* Parse arguments.  */
   innermost_block = NULL;
   exp_start = arg;
@@ -4275,27 +5380,33 @@ watch_command_1 (arg, accessflag, from_tty)
       cond_end = tok;
     }
   if (*tok)
-    error("Junk at end of command.");
+    error ("Junk at end of command.");
 
-  if (accessflag == 1) bp_type = bp_read_watchpoint;
-  else if (accessflag == 2) bp_type = bp_access_watchpoint;
-  else bp_type = bp_hardware_watchpoint;
+  if (accessflag == hw_read)
+    bp_type = bp_read_watchpoint;
+  else if (accessflag == hw_access)
+    bp_type = bp_access_watchpoint;
+  else
+    bp_type = bp_hardware_watchpoint;
 
   mem_cnt = can_use_hardware_watchpoint (val);
   if (mem_cnt == 0 && bp_type != bp_hardware_watchpoint)
     error ("Expression cannot be implemented with read/access watchpoint.");
-  if (mem_cnt != 0) { 
-    i = hw_watchpoint_used_count (bp_type, &other_type_used);
-    target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT(
-               bp_type, i + mem_cnt, other_type_used);
-    if (target_resources_ok == 0 && bp_type != bp_hardware_watchpoint)
-      error ("Target does not have this type of hardware watchpoint support.");
-    if (target_resources_ok < 0 && bp_type != bp_hardware_watchpoint)
-      error ("Target resources have been allocated for other types of watchpoints.");
-  }
+  if (mem_cnt != 0)
+    {
+      i = hw_watchpoint_used_count (bp_type, &other_type_used);
+      target_resources_ok = 
+       TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_type, i + mem_cnt, 
+                                           other_type_used);
+      if (target_resources_ok == 0 && bp_type != bp_hardware_watchpoint)
+       error ("Target does not support this type of hardware watchpoint.");
+
+      if (target_resources_ok < 0 && bp_type != bp_hardware_watchpoint)
+       error ("Target can only support one kind of HW watchpoint at a time.");
+    }
 
 #if defined(HPUXHPPA)
- /*  On HP-UX if you set a h/w
 /*  On HP-UX if you set a h/w
      watchpoint before the "run" command, the inferior dies with a e.g.,
      SIGILL once you start it.  I initially believed this was due to a
      bad interaction between page protection traps and the initial
@@ -4309,13 +5420,13 @@ watch_command_1 (arg, accessflag, from_tty)
      Until I figure out what's happening, I'm disallowing watches altogether
      before the "run" or "attach" command.  We'll tell the user they must
      set watches after getting the program started. */
-  if (! target_has_execution)
+  if (!target_has_execution)
     {
       warning ("can't do that without a running program; try \"break main\", \"run\" first");
       return;
     }
 #endif /* HPUXHPPA */
-  
+
   /* Now set up the breakpoint.  */
   b = set_raw_breakpoint (sal);
   set_breakpoint_count (breakpoint_count + 1);
@@ -4330,7 +5441,7 @@ watch_command_1 (arg, accessflag, from_tty)
     b->cond_string = savestring (cond_start, cond_end - cond_start);
   else
     b->cond_string = 0;
-         
+
   frame = block_innermost_frame (exp_valid_block);
   if (frame)
     {
@@ -4338,7 +5449,7 @@ watch_command_1 (arg, accessflag, from_tty)
       b->watchpoint_frame = frame->frame;
     }
   else
-    b->watchpoint_frame = (CORE_ADDR)0;
+    b->watchpoint_frame = (CORE_ADDR) 0;
 
   if (mem_cnt && target_resources_ok > 0)
     b->type = bp_type;
@@ -4356,7 +5467,7 @@ watch_command_1 (arg, accessflag, from_tty)
          struct symtab_and_line scope_sal;
 
          INIT_SAL (&scope_sal);        /* initialize to zeroes */
-         scope_sal.pc      = get_frame_pc (prev_frame);
+         scope_sal.pc = get_frame_pc (prev_frame);
          scope_sal.section = find_pc_overlay (scope_sal.pc);
 
          scope_breakpoint = set_raw_breakpoint (scope_sal);
@@ -4389,8 +5500,13 @@ watch_command_1 (arg, accessflag, from_tty)
    in hardware return zero.  */
 
 #if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
-#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_size) \
-    ((byte_size) <= (REGISTER_SIZE))
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(BYTE_SIZE) \
+    ((BYTE_SIZE) <= (REGISTER_SIZE))
+#endif
+
+#if !defined(TARGET_REGION_OK_FOR_HW_WATCHPOINT)
+#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(ADDR,LEN) \
+     TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(LEN)
 #endif
 
 static int
@@ -4400,22 +5516,54 @@ can_use_hardware_watchpoint (v)
   int found_memory_cnt = 0;
 
   /* Did the user specifically forbid us to use hardware watchpoints? */
-  if (! can_use_hw_watchpoints)
+  if (!can_use_hw_watchpoints)
     return 0;
-       
-  /* Make sure all the intermediate values are in memory.  Also make sure
-     we found at least one memory expression.  Guards against watch 0x12345,
-     which is meaningless, but could cause errors if one tries to insert a 
-     hardware watchpoint for the constant expression.  */
-  for ( ; v; v = v->next)
+
+  /* Make sure that the value of the expression depends only upon
+     memory contents, and values computed from them within GDB.  If we
+     find any register references or function calls, we can't use a
+     hardware watchpoint.
+
+     The idea here is that evaluating an expression generates a series
+     of values, one holding the value of every subexpression.  (The
+     expression a*b+c has five subexpressions: a, b, a*b, c, and
+     a*b+c.)  GDB's values hold almost enough information to establish
+     the criteria given above --- they identify memory lvalues,
+     register lvalues, computed values, etcetera.  So we can evaluate
+     the expression, and then scan the chain of values that leaves
+     behind to decide whether we can detect any possible change to the
+     expression's final value using only hardware watchpoints.
+
+     However, I don't think that the values returned by inferior
+     function calls are special in any way.  So this function may not
+     notice that an expression involving an inferior function call
+     can't be watched with hardware watchpoints.  FIXME.  */
+  for (; v; v = v->next)
     {
-      if (v->lval == lval_memory)
+      if (VALUE_LVAL (v) == lval_memory)
        {
-         if (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (TYPE_LENGTH (VALUE_TYPE (v))))
-           found_memory_cnt++;
-        }
+         if (VALUE_LAZY (v))
+           /* A lazy memory lvalue is one that GDB never needed to fetch;
+              we either just used its address (e.g., `a' in `a.b') or
+              we never needed it at all (e.g., `a' in `a,b').  */
+           ;
+         else
+           {
+             /* Ahh, memory we actually used!  Check if we can cover
+                 it with hardware watchpoints.  */
+             CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+             int       len   = TYPE_LENGTH (VALUE_TYPE (v));
+
+             if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
+               return 0;
+             else
+               found_memory_cnt++;
+           }
+       }
       else if (v->lval != not_lval && v->modifiable == 0)
-       return 0;
+       return 0;       /* ??? What does this represent? */
+      else if (v->lval == lval_register)
+       return 0;       /* cannot watch a register with a HW watchpoint */
     }
 
   /* The expression itself looks suitable for using a hardware
@@ -4423,31 +5571,74 @@ can_use_hardware_watchpoint (v)
   return found_memory_cnt;
 }
 
-static void watch_command (arg, from_tty)
+#ifdef UI_OUT
+void
+watch_command_wrapper (arg, from_tty)
      char *arg;
      int from_tty;
 {
-  watch_command_1 (arg, 0, from_tty);
+  watch_command (arg, from_tty);
 }
-
-static void rwatch_command (arg, from_tty)
+#endif
+static void
+watch_command (arg, from_tty)
      char *arg;
      int from_tty;
 {
-  watch_command_1 (arg, 1, from_tty);
+  watch_command_1 (arg, hw_write, from_tty);
 }
 
-static void awatch_command (arg, from_tty)
+#ifdef UI_OUT
+void
+rwatch_command_wrapper (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  rwatch_command (arg, from_tty);
+}
+#endif
+static void
+rwatch_command (arg, from_tty)
      char *arg;
      int from_tty;
 {
-  watch_command_1 (arg, 2, from_tty);
+  watch_command_1 (arg, hw_read, from_tty);
 }
 
+#ifdef UI_OUT
+void
+awatch_command_wrapper (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  awatch_command (arg, from_tty);
+}
+#endif
+static void
+awatch_command (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  watch_command_1 (arg, hw_access, from_tty);
+}
 \f
-/* Helper routine for the until_command routine in infcmd.c.  Here
+
+/* Helper routines for the until_command routine in infcmd.c.  Here
    because it uses the mechanisms of breakpoints.  */
 
+/* This function is called by fetch_inferior_event via the
+   cmd_continuation pointer, to complete the until command. It takes
+   care of cleaning up the temporary breakpoints set up by the until
+   command. */
+static void
+until_break_command_continuation (struct continuation_arg *arg)
+{
+  struct cleanup *cleanups;
+
+  cleanups = (struct cleanup *) arg->data;
+  do_exec_cleanups (cleanups);
+}
+
 /* ARGSUSED */
 void
 until_break_command (arg, from_tty)
@@ -4459,45 +5650,79 @@ until_break_command (arg, from_tty)
   struct frame_info *prev_frame = get_prev_frame (selected_frame);
   struct breakpoint *breakpoint;
   struct cleanup *old_chain;
+  struct continuation_arg *arg1;
+
 
   clear_proceed_status ();
 
   /* Set a breakpoint where the user wants it and at return from
      this function */
-  
+
   if (default_breakpoint_valid)
     sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
-                         default_breakpoint_line, (char ***)NULL);
+                         default_breakpoint_line, (char ***) NULL);
   else
-    sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0, (char ***)NULL);
-  
+    sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 
+                         0, (char ***) NULL);
+
   if (sals.nelts != 1)
     error ("Couldn't get information on specified line.");
-  
+
   sal = sals.sals[0];
-  free ((PTR)sals.sals);               /* malloc'd, so freed */
-  
+  free ((PTR) sals.sals);      /* malloc'd, so freed */
+
   if (*arg)
     error ("Junk at end of arguments.");
-  
+
   resolve_sal_pc (&sal);
-  
+
   breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
-  
-  old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+
+  if (!event_loop_p || !target_can_async_p ())
+    old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, 
+                             breakpoint);
+  else
+    old_chain = make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+
+  /* If we are running asynchronously, and the target supports async
+     execution, we are not waiting for the target to stop, in the call
+     tp proceed, below. This means that we cannot delete the
+     brekpoints until the target has actually stopped. The only place
+     where we get a chance to do that is in fetch_inferior_event, so
+     we must set things up for that. */
+
+  if (event_loop_p && target_can_async_p ())
+    {
+      /* In this case the arg for the continuation is just the point
+         in the exec_cleanups chain from where to start doing
+         cleanups, because all the continuation does is the cleanups in
+         the exec_cleanup_chain. */
+      arg1 =
+       (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+      arg1->next = NULL;
+      arg1->data = (PTR) old_chain;
+
+      add_continuation (until_break_command_continuation, arg1);
+    }
 
   /* Keep within the current frame */
-  
+
   if (prev_frame)
     {
       sal = find_pc_line (prev_frame->pc, 0);
       sal.pc = prev_frame->pc;
       breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
-      make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+      if (!event_loop_p || !target_can_async_p ())
+       make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+      else
+       make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
     }
-  
+
   proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
-  do_cleanups(old_chain);
+  /* Do the cleanups now, anly if we are not running asynchronously,
+     of if we are, but the target is still synchronous. */
+  if (!event_loop_p || !target_can_async_p ())
+    do_cleanups (old_chain);
 }
 \f
 #if 0
@@ -4531,6 +5756,7 @@ struct sal_chain
   struct symtab_and_line sal;
 };
 
+#if 0
 /* Not really used -- invocation in handle_gnu_4_16_catch_command
    had been commented out in the v.4.16 sources, and stays
    disabled there now because "catch NAME" syntax isn't allowed.
@@ -4541,7 +5767,7 @@ struct sal_chain
 static struct symtabs_and_lines
 map_catch_names (args, function)
      char *args;
-     int (*function)();
+     int (*function) ();
 {
   register char *p = args;
   register char *p1;
@@ -4579,7 +5805,7 @@ map_catch_names (args, function)
       if (function (p))
        {
          struct sal_chain *next = (struct sal_chain *)
-           alloca (sizeof (struct sal_chain));
+         alloca (sizeof (struct sal_chain));
          next->next = sal_chain;
          next->sal = get_catch_sal (p);
          sal_chain = next;
@@ -4591,9 +5817,11 @@ map_catch_names (args, function)
     win:
 #endif
       p = p1;
-      while (*p == ' ' || *p == '\t') p++;
+      while (*p == ' ' || *p == '\t')
+       p++;
     }
 }
+#endif
 
 /* This shares a lot of code with `print_frame_label_vars' from stack.c.  */
 
@@ -4667,9 +5895,10 @@ get_catch_sals (this_level_only)
                  if (SYMBOL_CLASS (sym) == LOC_LABEL)
                    {
                      struct sal_chain *next = (struct sal_chain *)
-                       alloca (sizeof (struct sal_chain));
+                     alloca (sizeof (struct sal_chain));
                      next->next = sal_chain;
-                     next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0);
+                     next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 
+                                               0);
                      sal_chain = next;
                    }
                }
@@ -4683,8 +5912,8 @@ get_catch_sals (this_level_only)
        break;
 
       /* After handling the function's top-level block, stop.
-        Don't continue to its superblock, the block of
-        per-file symbols.  */
+         Don't continue to its superblock, the block of
+         per-file symbols.  */
       if (BLOCK_FUNCTION (block))
        break;
       block = BLOCK_SUPERBLOCK (block);
@@ -4711,165 +5940,180 @@ get_catch_sals (this_level_only)
 
 static void
 ep_skip_leading_whitespace (s)
-    char **  s;
+     char **s;
 {
-   if ((s == NULL) || (*s == NULL))
-       return;
-   while (isspace(**s))
-       *s += 1;
+  if ((s == NULL) || (*s == NULL))
+    return;
+  while (isspace (**s))
+    *s += 1;
 }
+
 /* This function examines a string, and attempts to find a token
    that might be an event name in the leading characters.  If a
    possible match is found, a pointer to the last character of
    the token is returned.  Else, NULL is returned. */
+
 static char *
 ep_find_event_name_end (arg)
-  char *  arg;
+     char *arg;
 {
-  char *  s = arg;
-  char *  event_name_end = NULL;
+  char *s = arg;
+  char *event_name_end = NULL;
+
   /* If we could depend upon the presense of strrpbrk, we'd use that... */
   if (arg == NULL)
     return NULL;
+
   /* We break out of the loop when we find a token delimiter.
-   Basically, we're looking for alphanumerics and underscores;
-   anything else delimites the token. */
+     Basically, we're looking for alphanumerics and underscores;
+     anything else delimites the token. */
   while (*s != '\0')
     {
-      if (! isalnum(*s) && (*s != '_'))
-        break;
+      if (!isalnum (*s) && (*s != '_'))
+       break;
       event_name_end = s;
       s++;
     }
+
   return event_name_end;
 }
 
+
 /* This function attempts to parse an optional "if <cond>" clause
    from the arg string.  If one is not found, it returns NULL.
+
    Else, it returns a pointer to the condition string.  (It does not
    attempt to evaluate the string against a particular block.)  And,
    it updates arg to point to the first character following the parsed
    if clause in the arg string. */
+
 static char *
 ep_parse_optional_if_clause (arg)
-  char **  arg;
+     char **arg;
 {
-  char *  cond_string;
-  if (((*arg)[0] != 'i') || ((*arg)[1] != 'f') || !isspace((*arg)[2]))
+  char *cond_string;
+
+  if (((*arg)[0] != 'i') || ((*arg)[1] != 'f') || !isspace ((*arg)[2]))
     return NULL;
+
   /* Skip the "if" keyword. */
   (*arg) += 2;
+
   /* Skip any extra leading whitespace, and record the start of the
      condition string. */
   ep_skip_leading_whitespace (arg);
   cond_string = *arg;
+
   /* Assume that the condition occupies the remainder of the arg string. */
   (*arg) += strlen (cond_string);
+
   return cond_string;
 }
+
 /* This function attempts to parse an optional filename from the arg
    string.  If one is not found, it returns NULL.
+
    Else, it returns a pointer to the parsed filename.  (This function
    makes no attempt to verify that a file of that name exists, or is
    accessible.)  And, it updates arg to point to the first character
    following the parsed filename in the arg string.
+
    Note that clients needing to preserve the returned filename for
    future access should copy it to their own buffers. */
 static char *
 ep_parse_optional_filename (arg)
-  char **  arg;
+     char **arg;
 {
-  static char  filename [1024];
-  char *  arg_p = *arg;
-  int  i;
-  char  c;
+  static char filename[1024];
+  char *arg_p = *arg;
+  int i;
+  char c;
+
   if ((*arg_p == '\0') || isspace (*arg_p))
     return NULL;
-  for (i=0; ; i++)
+
+  for (i = 0;; i++)
     {
       c = *arg_p;
       if (isspace (c))
-        c = '\0';
+       c = '\0';
       filename[i] = c;
       if (c == '\0')
-        break;
+       break;
       arg_p++;
     }
   *arg = arg_p;
+
   return filename;
 }
+
 /* Commands to deal with catching events, such as signals, exceptions,
    process start/exit, etc.  */
-typedef enum {catch_fork, catch_vfork} catch_fork_kind;
+
+typedef enum
+{
+  catch_fork, catch_vfork
+}
+catch_fork_kind;
+
+#if defined(CHILD_INSERT_FORK_CATCHPOINT) || defined(CHILD_INSERT_VFORK_CATCHPOINT)
+static void catch_fork_command_1 PARAMS ((catch_fork_kind fork_kind, 
+                                         char *arg, 
+                                         int tempflag, 
+                                         int from_tty));
+
 static void
 catch_fork_command_1 (fork_kind, arg, tempflag, from_tty)
-  catch_fork_kind  fork_kind;
-  char *  arg;
-  int  tempflag;
-  int  from_tty;
+     catch_fork_kind fork_kind;
+     char *arg;
+     int tempflag;
+     int from_tty;
 {
-  char *  cond_string = NULL;
+  char *cond_string = NULL;
+
   ep_skip_leading_whitespace (&arg);
+
   /* The allowed syntax is:
-        catch [v]fork
-        catch [v]fork if <cond>
+     catch [v]fork
+     catch [v]fork if <cond>
+
      First, check if there's an if clause. */
   cond_string = ep_parse_optional_if_clause (&arg);
+
   if ((*arg != '\0') && !isspace (*arg))
     error ("Junk at end of arguments.");
+
   /* If this target supports it, create a fork or vfork catchpoint
      and enable reporting of such events. */
-  switch (fork_kind) {
-    case catch_fork :
+  switch (fork_kind)
+    {
+    case catch_fork:
       create_fork_event_catchpoint (tempflag, cond_string);
       break;
-    case catch_vfork :
+    case catch_vfork:
       create_vfork_event_catchpoint (tempflag, cond_string);
       break;
-    default :
+    default:
       error ("unsupported or unknown fork kind; cannot catch it");
       break;
-  }
+    }
 }
+#endif
 
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
 static void
 catch_exec_command_1 (arg, tempflag, from_tty)
-  char *  arg;
-  int  tempflag;
-  int  from_tty;
+     char *arg;
+     int tempflag;
+     int from_tty;
 {
-  char *  cond_string = NULL;
+  char *cond_string = NULL;
 
   ep_skip_leading_whitespace (&arg);
 
   /* The allowed syntax is:
-        catch exec
-        catch exec if <cond>
+     catch exec
+     catch exec if <cond>
 
      First, check if there's an if clause. */
   cond_string = ep_parse_optional_if_clause (&arg);
@@ -4881,34 +6125,35 @@ catch_exec_command_1 (arg, tempflag, from_tty)
      and enable reporting of such events. */
   create_exec_event_catchpoint (tempflag, cond_string);
 }
+#endif
+
 #if defined(SOLIB_ADD)
 static void
 catch_load_command_1 (arg, tempflag, from_tty)
-  char *  arg;
-  int  tempflag;
-  int  from_tty;
+     char *arg;
+     int tempflag;
+     int from_tty;
 {
-  char *  dll_pathname = NULL;
-  char *  cond_string = NULL;
+  char *dll_pathname = NULL;
+  char *cond_string = NULL;
+
   ep_skip_leading_whitespace (&arg);
+
   /* The allowed syntax is:
-        catch load
-        catch load if <cond>
-        catch load <filename>
-        catch load <filename> if <cond>
+     catch load
+     catch load if <cond>
+     catch load <filename>
+     catch load <filename> if <cond>
+
      The user is not allowed to specify the <filename> after an
      if clause.
+
      We'll ignore the pathological case of a file named "if".
+
      First, check if there's an if clause.  If so, then there
      cannot be a filename. */
   cond_string = ep_parse_optional_if_clause (&arg);
+
   /* If there was an if clause, then there cannot be a filename.
      Else, there might be a filename and an if clause. */
   if (cond_string == NULL)
@@ -4917,42 +6162,43 @@ catch_load_command_1 (arg, tempflag, from_tty)
       ep_skip_leading_whitespace (&arg);
       cond_string = ep_parse_optional_if_clause (&arg);
     }
+
   if ((*arg != '\0') && !isspace (*arg))
     error ("Junk at end of arguments.");
+
   /* Create a load breakpoint that only triggers when a load of
      the specified dll (or any dll, if no pathname was specified)
      occurs. */
-  SOLIB_CREATE_CATCH_LOAD_HOOK (inferior_pid, tempflag, dll_pathname, cond_string);
+  SOLIB_CREATE_CATCH_LOAD_HOOK (inferior_pid, tempflag, 
+                               dll_pathname, cond_string);
 }
+
 static void
 catch_unload_command_1 (arg, tempflag, from_tty)
-  char *  arg;
-  int  tempflag;
-  int  from_tty;
+     char *arg;
+     int tempflag;
+     int from_tty;
 {
-  char *  dll_pathname = NULL;
-  char *  cond_string = NULL;
+  char *dll_pathname = NULL;
+  char *cond_string = NULL;
+
   ep_skip_leading_whitespace (&arg);
+
   /* The allowed syntax is:
-        catch unload
-        catch unload if <cond>
-        catch unload <filename>
-        catch unload <filename> if <cond>
+     catch unload
+     catch unload if <cond>
+     catch unload <filename>
+     catch unload <filename> if <cond>
+
      The user is not allowed to specify the <filename> after an
      if clause.
+
      We'll ignore the pathological case of a file named "if".
+
      First, check if there's an if clause.  If so, then there
      cannot be a filename. */
   cond_string = ep_parse_optional_if_clause (&arg);
+
   /* If there was an if clause, then there cannot be a filename.
      Else, there might be a filename and an if clause. */
   if (cond_string == NULL)
@@ -4961,75 +6207,76 @@ catch_unload_command_1 (arg, tempflag, from_tty)
       ep_skip_leading_whitespace (&arg);
       cond_string = ep_parse_optional_if_clause (&arg);
     }
+
   if ((*arg != '\0') && !isspace (*arg))
     error ("Junk at end of arguments.");
+
   /* Create an unload breakpoint that only triggers when an unload of
      the specified dll (or any dll, if no pathname was specified)
      occurs. */
-  SOLIB_CREATE_CATCH_UNLOAD_HOOK (inferior_pid, tempflag, dll_pathname, cond_string);
+  SOLIB_CREATE_CATCH_UNLOAD_HOOK (inferior_pid, tempflag, 
+                                 dll_pathname, cond_string);
 }
 #endif /* SOLIB_ADD */
 
 /* Commands to deal with catching exceptions.  */
 
 /* Set a breakpoint at the specified callback routine for an
-   exception event callback */ 
+   exception event callback */
 
 static void
 create_exception_catchpoint (tempflag, cond_string, ex_event, sal)
-  int tempflag;
-  char * cond_string;
-  enum exception_event_kind ex_event;
-  struct symtab_and_line * sal;
+     int tempflag;
+     char *cond_string;
+     enum exception_event_kind ex_event;
+     struct symtab_and_line *sal;
 {
-  struct breakpoint *  b;
-  int  i;
-  int  thread = -1;  /* All threads. */
+  struct breakpoint *b;
+  int thread = -1;             /* All threads. */
 
-  if (!sal) /* no exception support? */
+  if (!sal)                    /* no exception support? */
     return;
 
   b = set_raw_breakpoint (*sal);
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
   b->cond = NULL;
-  b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+  b->cond_string = (cond_string == NULL) ? 
+    NULL : savestring (cond_string, strlen (cond_string));
   b->thread = thread;
   b->addr_string = NULL;
   b->enable = enabled;
   b->disposition = tempflag ? del : donttouch;
   switch (ex_event)
     {
-      case EX_EVENT_THROW:
-        b->type = bp_catch_throw;
-        break;
-      case EX_EVENT_CATCH:
-        b->type = bp_catch_catch;
-        break;
-      default: /* error condition */ 
-        b->type = bp_none;
-        b->enable = disabled;
-        error ("Internal error -- invalid catchpoint kind");
+    case EX_EVENT_THROW:
+      b->type = bp_catch_throw;
+      break;
+    case EX_EVENT_CATCH:
+      b->type = bp_catch_catch;
+      break;
+    default:                   /* error condition */
+      b->type = bp_none;
+      b->enable = disabled;
+      error ("Internal error -- invalid catchpoint kind");
     }
   mention (b);
 }
 
-/* Deal with "catch catch" and "catch throw" commands */ 
+/* Deal with "catch catch" and "catch throw" commands */
 
 static void
 catch_exception_command_1 (ex_event, arg, tempflag, from_tty)
-  enum exception_event_kind ex_event;
-  char *  arg;
-  int  tempflag;
-  int  from_tty;
+     enum exception_event_kind ex_event;
+     char *arg;
+     int tempflag;
+     int from_tty;
 {
-  char * cond_string = NULL;
-  struct symtab_and_line * sal = NULL;
-  
+  char *cond_string = NULL;
+  struct symtab_and_line *sal = NULL;
+
   ep_skip_leading_whitespace (&arg);
-  
+
   cond_string = ep_parse_optional_if_clause (&arg);
 
   if ((*arg != '\0') && !isspace (*arg))
@@ -5042,31 +6289,31 @@ catch_exception_command_1 (ex_event, arg, tempflag, from_tty)
   /* See if we can find a callback routine */
   sal = target_enable_exception_callback (ex_event, 1);
 
-  if (sal) 
+  if (sal)
     {
       /* We have callbacks from the runtime system for exceptions.
-         Set a breakpoint on the sal found, if no errors */ 
+         Set a breakpoint on the sal found, if no errors */
       if (sal != (struct symtab_and_line *) -1)
-        create_exception_catchpoint (tempflag, cond_string, ex_event, sal);
+       create_exception_catchpoint (tempflag, cond_string, ex_event, sal);
       else
-        return; /* something went wrong with setting up callbacks */ 
+       return;         /* something went wrong with setting up callbacks */
     }
-  else  
+  else
     {
       /* No callbacks from runtime system for exceptions.
          Try GNU C++ exception breakpoints using labels in debug info. */
       if (ex_event == EX_EVENT_CATCH)
-        {
-          handle_gnu_4_16_catch_command (arg, tempflag, from_tty);
-        }
+       {
+         handle_gnu_4_16_catch_command (arg, tempflag, from_tty);
+       }
       else if (ex_event == EX_EVENT_THROW)
-        {
-          /* Set a breakpoint on __raise_exception () */
-          
-          fprintf_filtered (gdb_stderr, "Unsupported with this platform/compiler combination.\n");
-          fprintf_filtered (gdb_stderr, "Perhaps you can achieve the effect you want by setting\n");
-          fprintf_filtered (gdb_stderr, "a breakpoint on __raise_exception().\n");
-        }
+       {
+         /* Set a breakpoint on __raise_exception () */
+
+         warning ("Unsupported with this platform/compiler combination.");
+         warning ("Perhaps you can achieve the effect you want by setting");
+         warning ("a breakpoint on __raise_exception().");
+       }
     }
 }
 
@@ -5075,7 +6322,7 @@ catch_exception_command_1 (ex_event, arg, tempflag, from_tty)
 
 static int
 cover_target_enable_exception_callback (arg)
-  PTR arg;
+     PTR arg;
 {
   args_for_catchpoint_enable *args = arg;
   struct symtab_and_line *sal;
@@ -5085,7 +6332,7 @@ cover_target_enable_exception_callback (arg)
   else if (sal == (struct symtab_and_line *) -1)
     return -1;
   else
-    return 1; /*is valid*/
+    return 1;                  /*is valid */
 }
 
 
@@ -5098,7 +6345,7 @@ cover_target_enable_exception_callback (arg)
    Note: Only the "catch" flavour of GDB 4.16 is handled here.  The
    "catch NAME" is now no longer allowed in catch_command_1().  Also,
    there was no code in GDB 4.16 for "catch throw". 
-  
+
    Called from catch_exception_command_1 () */
 
 
@@ -5118,12 +6365,12 @@ handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
   char *save_arg;
   int i;
 
-  INIT_SAL (&sal);     /* initialize to zeroes */
+  INIT_SAL (&sal);             /* initialize to zeroes */
 
   /* If no arg given, or if first arg is 'if ', all active catch clauses
      are breakpointed. */
 
-  if (!arg || (arg[0] == 'i' && arg[1] == 'f' 
+  if (!arg || (arg[0] == 'i' && arg[1] == 'f'
               && (arg[2] == ' ' || arg[2] == '\t')))
     {
       /* Grab all active catch clauses.  */
@@ -5138,26 +6385,26 @@ handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
       /* Not sure why this code has been disabled. I'm leaving
          it disabled.  We can never come here now anyway
          since we don't allow the "catch NAME" syntax.
-         pai/1997-07-11 */ 
+         pai/1997-07-11 */
 
       /* This isn't used; I don't know what it was for.  */
       sals = map_catch_names (arg, catch_breakpoint);
 #endif
     }
 
-  if (! sals.nelts) 
+  if (!sals.nelts)
     return;
 
   save_arg = arg;
   for (i = 0; i < sals.nelts; i++)
     {
       resolve_sal_pc (&sals.sals[i]);
-      
+
       while (arg && *arg)
        {
          if (arg[0] == 'i' && arg[1] == 'f'
              && (arg[2] == ' ' || arg[2] == '\t'))
-           cond = parse_exp_1 ((arg += 2, &arg), 
+           cond = parse_exp_1 ((arg += 2, &arg),
                                block_for_pc (sals.sals[i].pc), 0);
          else
            error ("Junk at end of arguments.");
@@ -5175,12 +6422,13 @@ handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
       b = set_raw_breakpoint (sal);
       set_breakpoint_count (breakpoint_count + 1);
       b->number = breakpoint_count;
-      b->type = bp_breakpoint; /* Important -- this is an ordinary breakpoint.
-                                  For platforms with callback support for exceptions,
-                                  create_exception_catchpoint() will create special
-                                  bp types (bp_catch_catch and bp_catch_throw), and
-                                  there is code in insert_breakpoints() and elsewhere
-                                  that depends on that. */
+
+      /* Important -- this is an ordinary breakpoint.  For platforms
+        with callback support for exceptions,
+        create_exception_catchpoint() will create special bp types
+        (bp_catch_catch and bp_catch_throw), and there is code in
+        insert_breakpoints() and elsewhere that depends on that. */
+      b->type = bp_breakpoint; 
 
       b->cond = cond;
       b->enable = enabled;
@@ -5191,10 +6439,10 @@ handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
 
   if (sals.nelts > 1)
     {
-      printf_unfiltered ("Multiple breakpoints were set.\n");
-      printf_unfiltered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+      warning ("Multiple breakpoints were set.");
+      warning ("Use the \"delete\" command to delete unwanted breakpoints.");
     }
-  free ((PTR)sals.sals);
+  free ((PTR) sals.sals);
 }
 
 #if 0
@@ -5202,12 +6450,12 @@ handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
    just to placate infrun */
 static struct breakpoint *
 create_temp_exception_breakpoint (pc)
-  CORE_ADDR pc;
+     CORE_ADDR pc;
 {
   struct symtab_and_line sal;
   struct breakpoint *b;
 
-  INIT_SAL(&sal);
+  INIT_SAL (&sal);
   sal.pc = pc;
   sal.symtab = NULL;
   sal.line = 0;
@@ -5227,27 +6475,27 @@ create_temp_exception_breakpoint (pc)
 
 static void
 catch_command_1 (arg, tempflag, from_tty)
-  char *arg;
-  int tempflag;
-  int from_tty;
+     char *arg;
+     int tempflag;
+     int from_tty;
 {
+
   /* The first argument may be an event name, such as "start" or "load".
      If so, then handle it as such.  If it doesn't match an event name,
      then attempt to interpret it as an exception name.  (This latter is
      the v4.16-and-earlier GDB meaning of the "catch" command.)
+
      First, try to find the bounds of what might be an event name. */
-  char *  arg1_start = arg;
-  char *  arg1_end;
-  int  arg1_length;
+  char *arg1_start = arg;
+  char *arg1_end;
+  int arg1_length;
+
   if (arg1_start == NULL)
     {
-      /* Old behaviour was to use pre-v-4.16 syntax */ 
+      /* Old behaviour was to use pre-v-4.16 syntax */
       /* catch_throw_command_1 (arg1_start, tempflag, from_tty); */
       /* return; */
-      /* Now, this is not allowed */ 
+      /* Now, this is not allowed */
       error ("Catch requires an event name.");
 
     }
@@ -5255,7 +6503,7 @@ catch_command_1 (arg, tempflag, from_tty)
   if (arg1_end == NULL)
     error ("catch requires an event");
   arg1_length = arg1_end + 1 - arg1_start;
+
   /* Try to match what we found against known event names. */
   if (strncmp (arg1_start, "signal", arg1_length) == 0)
     {
@@ -5263,11 +6511,13 @@ catch_command_1 (arg, tempflag, from_tty)
     }
   else if (strncmp (arg1_start, "catch", arg1_length) == 0)
     {
-      catch_exception_command_1 (EX_EVENT_CATCH, arg1_end+1, tempflag, from_tty); 
+      catch_exception_command_1 (EX_EVENT_CATCH, arg1_end + 1, 
+                                tempflag, from_tty);
     }
   else if (strncmp (arg1_start, "throw", arg1_length) == 0)
     {
-      catch_exception_command_1 (EX_EVENT_THROW, arg1_end+1, tempflag, from_tty);
+      catch_exception_command_1 (EX_EVENT_THROW, arg1_end + 1, 
+                                tempflag, from_tty);
     }
   else if (strncmp (arg1_start, "thread_start", arg1_length) == 0)
     {
@@ -5292,7 +6542,7 @@ catch_command_1 (arg, tempflag, from_tty)
   else if (strncmp (arg1_start, "fork", arg1_length) == 0)
     {
 #if defined(CHILD_INSERT_FORK_CATCHPOINT)
-      catch_fork_command_1 (catch_fork, arg1_end+1, tempflag, from_tty);
+      catch_fork_command_1 (catch_fork, arg1_end + 1, tempflag, from_tty);
 #else
       error ("Catch of fork not yet implemented");
 #endif
@@ -5300,7 +6550,7 @@ catch_command_1 (arg, tempflag, from_tty)
   else if (strncmp (arg1_start, "vfork", arg1_length) == 0)
     {
 #if defined(CHILD_INSERT_VFORK_CATCHPOINT)
-      catch_fork_command_1 (catch_vfork, arg1_end+1, tempflag, from_tty);
+      catch_fork_command_1 (catch_vfork, arg1_end + 1, tempflag, from_tty);
 #else
       error ("Catch of vfork not yet implemented");
 #endif
@@ -5308,7 +6558,7 @@ catch_command_1 (arg, tempflag, from_tty)
   else if (strncmp (arg1_start, "exec", arg1_length) == 0)
     {
 #if defined(CHILD_INSERT_EXEC_CATCHPOINT)
-      catch_exec_command_1 (arg1_end+1, tempflag, from_tty);
+      catch_exec_command_1 (arg1_end + 1, tempflag, from_tty);
 #else
       error ("Catch of exec not yet implemented");
 #endif
@@ -5316,7 +6566,7 @@ catch_command_1 (arg, tempflag, from_tty)
   else if (strncmp (arg1_start, "load", arg1_length) == 0)
     {
 #if defined(SOLIB_ADD)
-      catch_load_command_1 (arg1_end+1, tempflag, from_tty);
+      catch_load_command_1 (arg1_end + 1, tempflag, from_tty);
 #else
       error ("Catch of load not implemented");
 #endif
@@ -5324,7 +6574,7 @@ catch_command_1 (arg, tempflag, from_tty)
   else if (strncmp (arg1_start, "unload", arg1_length) == 0)
     {
 #if defined(SOLIB_ADD)
-      catch_unload_command_1 (arg1_end+1, tempflag, from_tty);
+      catch_unload_command_1 (arg1_end + 1, tempflag, from_tty);
 #else
       error ("Catch of load not implemented");
 #endif
@@ -5333,15 +6583,15 @@ catch_command_1 (arg, tempflag, from_tty)
     {
       error ("Catch of stop not yet implemented");
     }
+
   /* This doesn't appear to be an event name */
 
   else
     {
       /* Pre-v.4.16 behaviour was to treat the argument
-         as the name of an exception */ 
+         as the name of an exception */
       /* catch_throw_command_1 (arg1_start, tempflag, from_tty); */
-      /* Now this is not allowed */ 
+      /* Now this is not allowed */
       error ("Unknown event kind specified for catch");
 
     }
@@ -5427,9 +6677,9 @@ clear_command (arg, from_tty)
     }
   else
     {
-      sals.sals = (struct symtab_and_line *) 
+      sals.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
-      INIT_SAL (&sal); /* initialize to zeroes */
+      INIT_SAL (&sal);         /* initialize to zeroes */
       sal.line = default_breakpoint_line;
       sal.symtab = default_breakpoint_symtab;
       sal.pc = default_breakpoint_address;
@@ -5453,37 +6703,37 @@ clear_command (arg, from_tty)
   for (i = 0; i < sals.nelts; i++)
     {
       /* If exact pc given, clear bpts at that pc.
-        If line given (pc == 0), clear all bpts on specified line.
-        If defaulting, clear all bpts on default line
+         If line given (pc == 0), clear all bpts on specified line.
+         If defaulting, clear all bpts on default line
          or at default pc.
-       
-               defaulting    sal.pc != 0    tests to do
-       
-                0              1             pc
-                1              1             pc _and_ line
-                0              0             line
-                1              0             <can't happen> */
+
+         defaulting    sal.pc != 0    tests to do
+
+         0              1             pc
+         1              1             pc _and_ line
+         0              0             line
+         1              0             <can't happen> */
 
       sal = sals.sals[i];
       found = (struct breakpoint *) 0;
 
 
       while (breakpoint_chain
-             /* Why don't we check here that this is not
-               a watchpoint, etc., as we do below?
-               I can't make it fail, but don't know
-               what's stopping the failure: a watchpoint
-               of the same address as "sal.pc" should
-               wind up being deleted. */
-             && (  ((sal.pc && (breakpoint_chain->address == sal.pc)) &&
-                   (overlay_debugging == 0 ||
-                    breakpoint_chain->section == sal.section))
-                || ((default_match || (0 == sal.pc))
-                   && breakpoint_chain->source_file != NULL
-                   && sal.symtab != NULL
-                   && STREQ (breakpoint_chain->source_file, sal.symtab->filename)
-                   && breakpoint_chain->line_number == sal.line)))
+      /* Why don't we check here that this is not
+         a watchpoint, etc., as we do below?
+         I can't make it fail, but don't know
+         what's stopping the failure: a watchpoint
+         of the same address as "sal.pc" should
+         wind up being deleted. */
+
+            && (((sal.pc && (breakpoint_chain->address == sal.pc)) &&
+                 (overlay_debugging == 0 ||
+                  breakpoint_chain->section == sal.section))
+                || ((default_match || (0 == sal.pc))
+                    && breakpoint_chain->source_file != NULL
+                    && sal.symtab != NULL
+             && STREQ (breakpoint_chain->source_file, sal.symtab->filename)
+                    && breakpoint_chain->line_number == sal.line)))
 
        {
          b1 = breakpoint_chain;
@@ -5494,28 +6744,28 @@ clear_command (arg, from_tty)
 
       ALL_BREAKPOINTS (b)
 
-      while (b->next
-             && b->next->type != bp_none
-             && b->next->type != bp_watchpoint
-             && b->next->type != bp_hardware_watchpoint
-             && b->next->type != bp_read_watchpoint
-             && b->next->type != bp_access_watchpoint
-             && (  ((sal.pc && (b->next->address == sal.pc)) &&
-                   (overlay_debugging == 0 ||
-                    b->next->section == sal.section))
-                || ((default_match || (0 == sal.pc))
-                   && b->next->source_file != NULL
-                   && sal.symtab != NULL
-                   && STREQ (b->next->source_file, sal.symtab->filename)
-                   && b->next->line_number == sal.line)))
+       while (b->next
+              && b->next->type != bp_none
+              && b->next->type != bp_watchpoint
+              && b->next->type != bp_hardware_watchpoint
+              && b->next->type != bp_read_watchpoint
+              && b->next->type != bp_access_watchpoint
+              && (((sal.pc && (b->next->address == sal.pc)) &&
+                   (overlay_debugging == 0 ||
+                    b->next->section == sal.section))
+                  || ((default_match || (0 == sal.pc))
+                      && b->next->source_file != NULL
+                      && sal.symtab != NULL
+                      && STREQ (b->next->source_file, sal.symtab->filename)
+                      && b->next->line_number == sal.line)))
 
 
-         {
-           b1 = b->next;
-           b->next = b1->next;
-           b1->next = found;
-           found = b1;
-         }
+       {
+         b1 = b->next;
+         b->next = b1->next;
+         b1->next = found;
+         found = b1;
+       }
 
       if (found == 0)
        {
@@ -5525,19 +6775,23 @@ clear_command (arg, from_tty)
            error ("No breakpoint at this line.");
        }
 
-      if (found->next) from_tty = 1; /* Always report if deleted more than one */
-      if (from_tty) printf_unfiltered ("Deleted breakpoint%s ", found->next ? "s" : "");
+      if (found->next)
+       from_tty = 1;           /* Always report if deleted more than one */
+      if (from_tty)
+       printf_unfiltered ("Deleted breakpoint%s ", found->next ? "s" : "");
       breakpoints_changed ();
       while (found)
        {
-         if (from_tty) printf_unfiltered ("%d ", found->number);
+         if (from_tty)
+           printf_unfiltered ("%d ", found->number);
          b1 = found->next;
          delete_breakpoint (found);
          found = b1;
        }
-      if (from_tty) putchar_unfiltered ('\n');
+      if (from_tty)
+       putchar_unfiltered ('\n');
     }
-  free ((PTR)sals.sals);
+  free ((PTR) sals.sals);
 }
 \f
 /* Delete breakpoint in BS if they are `delete' breakpoints and
@@ -5551,18 +6805,19 @@ breakpoint_auto_delete (bs)
   struct breakpoint *b, *temp;
 
   for (; bs; bs = bs->next)
-    if (bs->breakpoint_at && bs->breakpoint_at->disposition == del 
+    if (bs->breakpoint_at && bs->breakpoint_at->disposition == del
        && bs->stop)
       delete_breakpoint (bs->breakpoint_at);
 
   ALL_BREAKPOINTS_SAFE (b, temp)
-    {
-      if (b->disposition == del_at_next_stop)
-       delete_breakpoint (b);
-    }
+  {
+    if (b->disposition == del_at_next_stop)
+      delete_breakpoint (b);
+  }
 }
 
-/* Delete a breakpoint and clean up all traces of it in the data structures. */
+/* Delete a breakpoint and clean up all traces of it in the data
+   structures. */
 
 void
 delete_breakpoint (bpt)
@@ -5593,10 +6848,11 @@ delete_breakpoint (bpt)
 
   if (delete_breakpoint_hook)
     delete_breakpoint_hook (bpt);
+  breakpoint_delete_event (bpt->number);
 
   if (bpt->inserted)
     remove_breakpoint (bpt, mark_uninserted);
-      
+
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
 
@@ -5605,15 +6861,17 @@ delete_breakpoint (bpt)
      isn't actually running.  target_enable_exception_callback for a
      null target ops vector gives an undesirable error message, so we
      check here and avoid it. Since currently (1997-09-17) only HP-UX aCC's
-     exceptions are supported in this way, it's OK for now. FIXME */ 
+     exceptions are supported in this way, it's OK for now. FIXME */
   if (ep_is_exception_catchpoint (bpt) && target_has_execution)
     {
       static char message1[] = "Error in deleting catchpoint %d:\n";
       static char message[sizeof (message1) + 30];
       args_for_catchpoint_enable args;
 
-      sprintf (message, message1, bpt->number);        /* Format possible error msg */
-      args.kind = bpt->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW;
+      /* Format possible error msg */
+      sprintf (message, message1, bpt->number);
+      args.kind = bpt->type == bp_catch_catch ? 
+       EX_EVENT_CATCH : EX_EVENT_THROW;
       args.enable = 0;
       catch_errors (cover_target_enable_exception_callback, &args,
                    message, RETURN_MASK_ALL);
@@ -5622,10 +6880,10 @@ delete_breakpoint (bpt)
 
   ALL_BREAKPOINTS (b)
     if (b->next == bpt)
-      {
-       b->next = bpt->next;
-       break;
-      }
+    {
+      b->next = bpt->next;
+      break;
+    }
 
   /* Before turning off the visuals for the bp, check to see that
      there are no other bps at the same address. */
@@ -5634,17 +6892,17 @@ delete_breakpoint (bpt)
       int clearIt;
 
       ALL_BREAKPOINTS (b)
-        {
-          clearIt = (b->address != bpt->address);
-          if (!clearIt)
-            break;
-        }
+      {
+       clearIt = (b->address != bpt->address);
+       if (!clearIt)
+         break;
+      }
 
       if (clearIt)
-        {
-          TUIDO(((TuiOpaqueFuncPtr)tui_vAllSetHasBreakAt, bpt, 0));
-          TUIDO(((TuiOpaqueFuncPtr)tuiUpdateAllExecInfos));
-        }
+       {
+         TUIDO (((TuiOpaqueFuncPtr) tui_vAllSetHasBreakAt, bpt, 0));
+         TUIDO (((TuiOpaqueFuncPtr) tuiUpdateAllExecInfos));
+       }
     }
 
   check_duplicates (bpt->address, bpt->section);
@@ -5665,18 +6923,31 @@ delete_breakpoint (bpt)
            && b->enable != disabled
            && b->enable != shlib_disabled
            && b->enable != call_disabled)
-         {
-           int val;
+       {
+         int val;
+
+         /* We should never reach this point if there is a permanent
+            breakpoint at the same address as the one being deleted.
+            If there is a permanent breakpoint somewhere, it should
+            always be the only one inserted.  */
+         if (b->enable == permanent)
+           internal_error ("another breakpoint was inserted on top of "
+                           "a permanent breakpoint");
+
+         if (b->type == bp_hardware_breakpoint)
+           val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
+         else
            val = target_insert_breakpoint (b->address, b->shadow_contents);
-           if (val != 0)
-             {
-               target_terminal_ours_for_output ();
-               fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number);
-               memory_error (val, b->address); /* which bombs us out */
-             }
-           else
-             b->inserted = 1;
-         }
+
+         if (val != 0)
+           {
+             target_terminal_ours_for_output ();
+             warning ("Cannot insert breakpoint %d:", b->number);
+             memory_error (val, b->address);   /* which bombs us out */
+           }
+         else
+           b->inserted = 1;
+       }
     }
 
   free_command_lines (&bpt->commands);
@@ -5721,7 +6992,7 @@ delete_breakpoint (bpt)
      bp, we mark it as deleted before freeing its storage. */
   bpt->type = bp_none;
 
-  free ((PTR)bpt);
+  free ((PTR) bpt);
 }
 
 void
@@ -5736,27 +7007,29 @@ delete_command (arg, from_tty)
       int breaks_to_delete = 0;
 
       /* Delete all breakpoints if no argument.
-        Do not delete internal or call-dummy breakpoints, these
-        have to be deleted with an explicit breakpoint number argument.  */
-      ALL_BREAKPOINTS (b) 
-       {
-         if (b->type != bp_call_dummy && 
-              b->type != bp_shlib_event && 
-              b->number >= 0)
-           breaks_to_delete = 1;
-       }
+         Do not delete internal or call-dummy breakpoints, these
+         have to be deleted with an explicit breakpoint number argument.  */
+      ALL_BREAKPOINTS (b)
+      {
+       if (b->type != bp_call_dummy &&
+           b->type != bp_shlib_event &&
+           b->type != bp_thread_event &&
+           b->number >= 0)
+         breaks_to_delete = 1;
+      }
 
       /* Ask user only if there are some breakpoints to delete.  */
       if (!from_tty
          || (breaks_to_delete && query ("Delete all breakpoints? ")))
        {
-         ALL_BREAKPOINTS_SAFE (b, temp) 
-           {
-             if (b->type != bp_call_dummy &&
-                  b->type != bp_shlib_event &&
-                  b->number >= 0)
-               delete_breakpoint (b);
-           }
+         ALL_BREAKPOINTS_SAFE (b, temp)
+         {
+           if (b->type != bp_call_dummy &&
+               b->type != bp_shlib_event &&
+               b->type != bp_thread_event &&
+               b->number >= 0)
+             delete_breakpoint (b);
+         }
        }
     }
   else
@@ -5771,7 +7044,8 @@ static int
 breakpoint_re_set_one (bint)
      PTR bint;
 {
-  struct breakpoint *b = (struct breakpoint *)bint;  /* get past catch_errs */
+  /* get past catch_errs */
+  struct breakpoint *b = (struct breakpoint *) bint;
   struct value *mark;
   int i;
   struct symtabs_and_lines sals;
@@ -5781,7 +7055,8 @@ breakpoint_re_set_one (bint)
   switch (b->type)
     {
     case bp_none:
-      warning ("attempted to reset apparently deleted breakpoint #%d?\n", b->number);
+      warning ("attempted to reset apparently deleted breakpoint #%d?",
+              b->number);
       return 0;
     case bp_breakpoint:
     case bp_hardware_breakpoint:
@@ -5794,14 +7069,14 @@ breakpoint_re_set_one (bint)
          return 0;
        }
       /* In case we have a problem, disable this breakpoint.  We'll restore
-        its status if we succeed.  */
+         its status if we succeed.  */
       save_enable = b->enable;
       b->enable = disabled;
 
       set_language (b->language);
       input_radix = b->input_radix;
       s = b->addr_string;
-      sals = decode_line_1 (&s, 1, (struct symtab *)NULL, 0, (char ***)NULL);
+      sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL);
       for (i = 0; i < sals.nelts; i++)
        {
          resolve_sal_pc (&sals.sals[i]);
@@ -5812,23 +7087,23 @@ breakpoint_re_set_one (bint)
            {
              s = b->cond_string;
              if (b->cond)
-               free ((PTR)b->cond);
+               free ((PTR) b->cond);
              b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0);
            }
 
-         /* We need to re-set the breakpoint if the address changes...*/
+         /* We need to re-set the breakpoint if the address changes... */
          if (b->address != sals.sals[i].pc
-             /* ...or new and old breakpoints both have source files, and
-                the source file name or the line number changes...  */
+         /* ...or new and old breakpoints both have source files, and
+            the source file name or the line number changes...  */
              || (b->source_file != NULL
                  && sals.sals[i].symtab != NULL
                  && (!STREQ (b->source_file, sals.sals[i].symtab->filename)
                      || b->line_number != sals.sals[i].line)
-                 )
-             /* ...or we switch between having a source file and not having
-                one.  */
-             || ((b->source_file == NULL) != (sals.sals[i].symtab == NULL))
              )
+         /* ...or we switch between having a source file and not having
+            one.  */
+             || ((b->source_file == NULL) != (sals.sals[i].symtab == NULL))
+           )
            {
              if (b->source_file != NULL)
                free (b->source_file);
@@ -5841,26 +7116,26 @@ breakpoint_re_set_one (bint)
              b->line_number = sals.sals[i].line;
              b->address = sals.sals[i].pc;
 
-             /* Used to check for duplicates here, but that can
-               cause trouble, as it doesn't check for disable
-                breakpoints. */
+             /* Used to check for duplicates here, but that can
+                cause trouble, as it doesn't check for disable
+                breakpoints. */
 
              mention (b);
 
              /* Might be better to do this just once per breakpoint_re_set,
-                rather than once for every breakpoint.  */
+                rather than once for every breakpoint.  */
              breakpoints_changed ();
            }
          b->section = sals.sals[i].section;
          b->enable = save_enable;      /* Restore it, this worked. */
 
 
-          /* Now that this is re-enabled, check_duplicates
+         /* Now that this is re-enabled, check_duplicates
             can be used. */
-          check_duplicates (b->address, b->section);
+         check_duplicates (b->address, b->section);
 
        }
-      free ((PTR)sals.sals);
+      free ((PTR) sals.sals);
       break;
 
     case bp_watchpoint:
@@ -5868,16 +7143,17 @@ breakpoint_re_set_one (bint)
     case bp_read_watchpoint:
     case bp_access_watchpoint:
       innermost_block = NULL;
-      /* The issue arises of what context to evaluate this in.  The same
-        one as when it was set, but what does that mean when symbols have
-        been re-read?  We could save the filename and functionname, but
-        if the context is more local than that, the best we could do would
-        be something like how many levels deep and which index at that
-        particular level, but that's going to be less stable than filenames
-        or functionnames.  */
+      /* The issue arises of what context to evaluate this in.  The
+         same one as when it was set, but what does that mean when
+         symbols have been re-read?  We could save the filename and
+         functionname, but if the context is more local than that, the
+         best we could do would be something like how many levels deep
+         and which index at that particular level, but that's going to
+         be less stable than filenames or function names.  */
+
       /* So for now, just use a global context.  */
       if (b->exp)
-       free ((PTR)b->exp);
+       free ((PTR) b->exp);
       b->exp = parse_expression (b->exp_string);
       b->exp_valid_block = innermost_block;
       mark = value_mark ();
@@ -5892,42 +7168,46 @@ breakpoint_re_set_one (bint)
        {
          s = b->cond_string;
          if (b->cond)
-           free ((PTR)b->cond);
-         b->cond = parse_exp_1 (&s, (struct block *)0, 0);
+           free ((PTR) b->cond);
+         b->cond = parse_exp_1 (&s, (struct block *) 0, 0);
        }
       if (b->enable == enabled)
        mention (b);
       value_free_to_mark (mark);
       break;
-    case bp_catch_catch:  
-    case bp_catch_throw:  
+    case bp_catch_catch:
+    case bp_catch_throw:
       break;
-    /* We needn't really do anything to reset these, since the mask
-       that requests them is unaffected by e.g., new libraries being
-       loaded. */
+      /* We needn't really do anything to reset these, since the mask
+         that requests them is unaffected by e.g., new libraries being
+         loaded. */
     case bp_catch_fork:
     case bp_catch_vfork:
     case bp_catch_exec:
       break;
+
     default:
       printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
       /* fall through */
-    /* Delete longjmp breakpoints, they will be reset later by
-       breakpoint_re_set.  */
+      /* Delete longjmp breakpoints, they will be reset later by
+         breakpoint_re_set.  */
     case bp_longjmp:
     case bp_longjmp_resume:
       delete_breakpoint (b);
       break;
 
-    /* This breakpoint is special, it's set up when the inferior
-       starts and we really don't want to touch it.  */
+      /* This breakpoint is special, it's set up when the inferior
+         starts and we really don't want to touch it.  */
     case bp_shlib_event:
 
-    /* Keep temporary breakpoints, which can be encountered when we step
-       over a dlopen call and SOLIB_ADD is resetting the breakpoints.
-       Otherwise these should have been blown away via the cleanup chain
-       or by breakpoint_init_inferior when we rerun the executable.  */
+      /* Like bp_shlib_event, this breakpoint type is special.
+        Once it is set up, we do not want to touch it.  */
+    case bp_thread_event:
+
+      /* Keep temporary breakpoints, which can be encountered when we step
+         over a dlopen call and SOLIB_ADD is resetting the breakpoints.
+         Otherwise these should have been blown away via the cleanup chain
+         or by breakpoint_init_inferior when we rerun the executable.  */
     case bp_until:
     case bp_finish:
     case bp_watchpoint_scope:
@@ -5947,15 +7227,16 @@ breakpoint_re_set ()
   enum language save_language;
   int save_input_radix;
   static char message1[] = "Error in re-setting breakpoint %d:\n";
-  char message[sizeof (message1) + 30 /* slop */];
-  
+  char message[sizeof (message1) + 30 /* slop */ ];
+
   save_language = current_language->la_language;
   save_input_radix = input_radix;
   ALL_BREAKPOINTS_SAFE (b, temp)
-    {
-      sprintf (message, message1, b->number);  /* Format possible error msg */
-      catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
-    }
+  {
+    /* Format possible error msg */
+    sprintf (message, message1, b->number);
+    catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
+  }
   set_language (save_language);
   input_radix = save_input_radix;
 
@@ -5985,12 +7266,12 @@ breakpoint_re_set ()
    - Else, reset it to the current thread for inferior_pid. */
 void
 breakpoint_re_set_thread (b)
-  struct breakpoint *  b;
+     struct breakpoint *b;
 {
   if (b->thread != -1)
     {
       if (in_thread_list (inferior_pid))
-        b->thread = pid_to_thread_id (inferior_pid);
+       b->thread = pid_to_thread_id (inferior_pid);
     }
 }
 
@@ -6005,22 +7286,22 @@ set_ignore_count (bptnum, count, from_tty)
 
   ALL_BREAKPOINTS (b)
     if (b->number == bptnum)
-      {
-       b->ignore_count = count;
-       if (!from_tty)
-         return;
-       else if (count == 0)
-         printf_filtered ("Will stop next time breakpoint %d is reached.",
-                          bptnum);
-       else if (count == 1)
-         printf_filtered ("Will ignore next crossing of breakpoint %d.",
-                          bptnum);
-       else
-         printf_filtered ("Will ignore next %d crossings of breakpoint %d.",
-                 count, bptnum);
-       breakpoints_changed ();
+    {
+      b->ignore_count = count;
+      if (!from_tty)
        return;
-      }
+      else if (count == 0)
+       printf_filtered ("Will stop next time breakpoint %d is reached.",
+                        bptnum);
+      else if (count == 1)
+       printf_filtered ("Will ignore next crossing of breakpoint %d.",
+                        bptnum);
+      else
+       printf_filtered ("Will ignore next %d crossings of breakpoint %d.",
+                        count, bptnum);
+      breakpoints_changed ();
+      return;
+    }
 
   error ("No breakpoint number %d.", bptnum);
 }
@@ -6047,9 +7328,10 @@ ignore_command (args, from_tty)
 
   if (p == 0)
     error_no_arg ("a breakpoint number");
-  
-  num = get_number (&p);
 
+  num = get_number (&p);
+  if (num == 0)
+    error ("bad breakpoint number: '%s'", args);
   if (*p == 0)
     error ("Second argument (specified ignore-count) is missing.");
 
@@ -6071,28 +7353,37 @@ map_breakpoint_numbers (args, function)
   register char *p = args;
   char *p1;
   register int num;
-  register struct breakpoint *b;
+  register struct breakpoint *b, *tmp;
+  int match;
 
   if (p == 0)
     error_no_arg ("one or more breakpoint numbers");
 
   while (*p)
     {
+      match = 0;
       p1 = p;
-      
-      num = get_number (&p1);
 
-      ALL_BREAKPOINTS (b)
-       if (b->number == num)
-         {
-           struct breakpoint *related_breakpoint = b->related_breakpoint;
-           function (b);
-           if (related_breakpoint)
-             function (related_breakpoint);
-           goto win;
-         }
-      printf_unfiltered ("No breakpoint number %d.\n", num);
-    win:
+      num = get_number_or_range (&p1);
+      if (num == 0)
+       {
+         warning ("bad breakpoint number at or near '%s'", p);
+       }
+      else
+       {
+         ALL_BREAKPOINTS_SAFE (b, tmp)
+           if (b->number == num)
+             {
+               struct breakpoint *related_breakpoint = b->related_breakpoint;
+               match = 1;
+               function (b);
+               if (related_breakpoint)
+                 function (related_breakpoint);
+               break;
+             }
+         if (match == 0)
+           printf_unfiltered ("No breakpoint number %d.\n", num);
+       }
       p = p1;
     }
 }
@@ -6107,12 +7398,17 @@ disable_breakpoint (bpt)
   if (bpt->type == bp_watchpoint_scope)
     return;
 
+  /* You can't disable permanent breakpoints.  */
+  if (bpt->enable == permanent)
+    return;
+
   bpt->enable = disabled;
 
   check_duplicates (bpt->address, bpt->section);
 
   if (modify_breakpoint_hook)
     modify_breakpoint_hook (bpt);
+  breakpoint_modify_event (bpt->number);
 }
 
 /* ARGSUSED */
@@ -6125,27 +7421,28 @@ disable_command (args, from_tty)
   if (args == 0)
     ALL_BREAKPOINTS (bpt)
       switch (bpt->type)
-       {
-        case bp_none:
-          warning ("attempted to disable apparently deleted breakpoint #%d?\n", bpt->number);
-          continue;
-       case bp_breakpoint:
-        case bp_catch_load:
-        case bp_catch_unload:
-        case bp_catch_fork:
-        case bp_catch_vfork:
-        case bp_catch_exec:
-       case bp_catch_catch:
-       case bp_catch_throw:
-        case bp_hardware_breakpoint:
-        case bp_watchpoint:
-        case bp_hardware_watchpoint:
-        case bp_read_watchpoint:
-        case bp_access_watchpoint:
-         disable_breakpoint (bpt);
-       default:
-         continue;
-       }
+      {
+      case bp_none:
+       warning ("attempted to disable apparently deleted breakpoint #%d?",
+                bpt->number);
+       continue;
+      case bp_breakpoint:
+      case bp_catch_load:
+      case bp_catch_unload:
+      case bp_catch_fork:
+      case bp_catch_vfork:
+      case bp_catch_exec:
+      case bp_catch_catch:
+      case bp_catch_throw:
+      case bp_hardware_breakpoint:
+      case bp_watchpoint:
+      case bp_hardware_watchpoint:
+      case bp_read_watchpoint:
+      case bp_access_watchpoint:
+       disable_breakpoint (bpt);
+      default:
+       continue;
+      }
   else
     map_breakpoint_numbers (args, disable_breakpoint);
 }
@@ -6163,32 +7460,36 @@ do_enable_breakpoint (bpt, disposition)
   if (bpt->type == bp_hardware_breakpoint)
     {
       int i;
-      i = hw_breakpoint_used_count();
-      target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT(
-               bp_hardware_breakpoint, i+1, 0);
+      i = hw_breakpoint_used_count ();
+      target_resources_ok = 
+       TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint, 
+                                           i + 1, 0);
       if (target_resources_ok == 0)
-        error ("No hardware breakpoint support in the target.");
+       error ("No hardware breakpoint support in the target.");
       else if (target_resources_ok < 0)
-        error ("Hardware breakpoints used exceeds limit.");
+       error ("Hardware breakpoints used exceeds limit.");
     }
 
-  bpt->enable = enabled;
+  if (bpt->enable != permanent)
+    bpt->enable = enabled;
   bpt->disposition = disposition;
   check_duplicates (bpt->address, bpt->section);
   breakpoints_changed ();
 
-  if (bpt->type == bp_watchpoint || bpt->type == bp_hardware_watchpoint ||
-      bpt->type == bp_read_watchpoint || bpt->type == bp_access_watchpoint)
+  if (bpt->type == bp_watchpoint || 
+      bpt->type == bp_hardware_watchpoint ||
+      bpt->type == bp_read_watchpoint || 
+      bpt->type == bp_access_watchpoint)
     {
       if (bpt->exp_valid_block != NULL)
        {
          struct frame_info *fr =
 
-          /* Ensure that we have the current frame.  Else, this
-             next query may pessimistically be answered as, "No,
-             not within current scope". */
-          get_current_frame ();
-          fr = find_frame_addr_in_frame_chain (bpt->watchpoint_frame);
+         /* Ensure that we have the current frame.  Else, this
+            next query may pessimistically be answered as, "No,
+            not within current scope". */
+         get_current_frame ();
+         fr = find_frame_addr_in_frame_chain (bpt->watchpoint_frame);
          if (fr == NULL)
            {
              printf_filtered ("\
@@ -6211,35 +7512,37 @@ is valid is not currently in scope.\n", bpt->number);
        value_fetch_lazy (bpt->val);
 
       if (bpt->type == bp_hardware_watchpoint ||
-           bpt->type == bp_read_watchpoint ||
-           bpt->type == bp_access_watchpoint)
-      {
-        int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
-        int mem_cnt = can_use_hardware_watchpoint (bpt->val);
-
-        /* Hack around 'unused var' error for some targets here */
-        (void) mem_cnt, i;
-        target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT(
-                bpt->type, i + mem_cnt, other_type_used);
-        /* we can consider of type is bp_hardware_watchpoint, convert to 
-          bp_watchpoint in the following condition */
-        if (target_resources_ok < 0)
-         {
-             printf_filtered("\
+         bpt->type == bp_read_watchpoint ||
+         bpt->type == bp_access_watchpoint)
+       {
+         int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
+         int mem_cnt = can_use_hardware_watchpoint (bpt->val);
+
+         /* Hack around 'unused var' error for some targets here */
+         (void) mem_cnt, i;
+         target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
+                                  bpt->type, i + mem_cnt, other_type_used);
+         /* we can consider of type is bp_hardware_watchpoint, convert to 
+            bp_watchpoint in the following condition */
+         if (target_resources_ok < 0)
+           {
+             printf_filtered ("\
 Cannot enable watchpoint %d because target watch resources\n\
 have been allocated for other watchpoints.\n", bpt->number);
-            bpt->enable = disabled;
-            value_free_to_mark (mark);
-            return;
-          }
-      }
+             bpt->enable = disabled;
+             value_free_to_mark (mark);
+             return;
+           }
+       }
 
       if (save_selected_frame_level >= 0)
-       select_and_print_frame (save_selected_frame, save_selected_frame_level);
+       select_and_print_frame (save_selected_frame,
+                               save_selected_frame_level);
       value_free_to_mark (mark);
     }
   if (modify_breakpoint_hook)
     modify_breakpoint_hook (bpt);
+  breakpoint_modify_event (bpt->number);
 }
 
 void
@@ -6263,27 +7566,28 @@ enable_command (args, from_tty)
   if (args == 0)
     ALL_BREAKPOINTS (bpt)
       switch (bpt->type)
-       {
-        case bp_none:
-          warning ("attempted to enable apparently deleted breakpoint #%d?\n", bpt->number);
-          continue;
-       case bp_breakpoint:
-        case bp_catch_load:
-        case bp_catch_unload:
-        case bp_catch_fork:
-        case bp_catch_vfork:
-        case bp_catch_exec:
-       case bp_catch_catch:
-       case bp_catch_throw:
-       case bp_hardware_breakpoint:
-       case bp_watchpoint:
-       case bp_hardware_watchpoint:
-       case bp_read_watchpoint:
-       case bp_access_watchpoint:
-         enable_breakpoint (bpt);
-       default:
-         continue;
-       }
+      {
+      case bp_none:
+       warning ("attempted to enable apparently deleted breakpoint #%d?",
+                bpt->number);
+       continue;
+      case bp_breakpoint:
+      case bp_catch_load:
+      case bp_catch_unload:
+      case bp_catch_fork:
+      case bp_catch_vfork:
+      case bp_catch_exec:
+      case bp_catch_catch:
+      case bp_catch_throw:
+      case bp_hardware_breakpoint:
+      case bp_watchpoint:
+      case bp_hardware_watchpoint:
+      case bp_read_watchpoint:
+      case bp_access_watchpoint:
+       enable_breakpoint (bpt);
+      default:
+       continue;
+      }
   else
     map_breakpoint_numbers (args, enable_breakpoint);
 }
@@ -6332,11 +7636,12 @@ decode_line_spec_1 (string, funfirstline)
     error ("Empty line specification.");
   if (default_breakpoint_valid)
     sals = decode_line_1 (&string, funfirstline,
-                         default_breakpoint_symtab, default_breakpoint_line,
-                         (char ***)NULL);
+                         default_breakpoint_symtab,
+                         default_breakpoint_line,
+                         (char ***) NULL);
   else
     sals = decode_line_1 (&string, funfirstline,
-                         (struct symtab *)NULL, 0, (char ***)NULL);
+                         (struct symtab *) NULL, 0, (char ***) NULL);
   if (*string)
     error ("Junk at end of line specification: %s", string);
   return sals;
@@ -6356,7 +7661,7 @@ _initialize_breakpoint ()
           "Set ignore-count of breakpoint number N to COUNT.\n\
 Usage is `ignore N COUNT'.");
   if (xdb_commands)
-    add_com_alias("bc", "ignore", class_breakpoint, 1);
+    add_com_alias ("bc", "ignore", class_breakpoint, 1);
 
   add_com ("commands", class_breakpoint, commands_command,
           "Set commands to be executed when a breakpoint is hit.\n\
@@ -6377,8 +7682,8 @@ expression to be evaluated whenever breakpoint N is reached.  ");
 Like \"break\" except the breakpoint is only temporary,\n\
 so it will be deleted when hit.  Equivalent to \"break\" followed\n\
 by using \"enable delete\" on the breakpoint number.");
-  add_com("txbreak", class_breakpoint, tbreak_at_finish_command,
-          "Set temporary breakpoint at procedure exit.  Either there should\n\
+  add_com ("txbreak", class_breakpoint, tbreak_at_finish_command,
+          "Set temporary breakpoint at procedure exit.  Either there should\n\
 be no argument or the argument must be a depth.\n");
 
   add_com ("hbreak", class_breakpoint, hbreak_command,
@@ -6399,8 +7704,8 @@ This is used to cancel the effect of the \"disable\" command.\n\
 With a subcommand you can enable temporarily.",
                  &enablelist, "enable ", 1, &cmdlist);
   if (xdb_commands)
-      add_com("ab", class_breakpoint, enable_command,
-                     "Enable some breakpoints.\n\
+    add_com ("ab", class_breakpoint, enable_command,
+            "Enable some breakpoints.\n\
 Give breakpoint numbers (separated by spaces) as arguments.\n\
 With no subcommand, breakpoints are enabled until you command otherwise.\n\
 This is used to cancel the effect of the \"disable\" command.\n\
@@ -6409,11 +7714,11 @@ With a subcommand you can enable temporarily.");
   add_com_alias ("en", "enable", class_breakpoint, 1);
 
   add_abbrev_prefix_cmd ("breakpoints", class_breakpoint, enable_command,
-                 "Enable some breakpoints.\n\
+                        "Enable some breakpoints.\n\
 Give breakpoint numbers (separated by spaces) as arguments.\n\
 This is used to cancel the effect of the \"disable\" command.\n\
 May be abbreviated to simply \"enable\".\n",
-                 &enablebreaklist, "enable breakpoints ", 1, &enablelist);
+                  &enablebreaklist, "enable breakpoints ", 1, &enablelist);
 
   add_cmd ("once", no_class, enable_once_command,
           "Enable breakpoints for one hit.  Give breakpoint numbers.\n\
@@ -6436,7 +7741,7 @@ If a breakpoint is hit while enabled in this fashion, it becomes disabled.",
           &enablelist);
 
   add_prefix_cmd ("disable", class_breakpoint, disable_command,
-          "Disable some breakpoints.\n\
+                 "Disable some breakpoints.\n\
 Arguments are breakpoint numbers with spaces in between.\n\
 To disable all breakpoints, give no argument.\n\
 A disabled breakpoint is not forgotten, but has no effect until reenabled.",
@@ -6444,8 +7749,8 @@ A disabled breakpoint is not forgotten, but has no effect until reenabled.",
   add_com_alias ("dis", "disable", class_breakpoint, 1);
   add_com_alias ("disa", "disable", class_breakpoint, 1);
   if (xdb_commands)
-    add_com("sb", class_breakpoint, disable_command,
-               "Disable some breakpoints.\n\
+    add_com ("sb", class_breakpoint, disable_command,
+            "Disable some breakpoints.\n\
 Arguments are breakpoint numbers with spaces in between.\n\
 To disable all breakpoints, give no argument.\n\
 A disabled breakpoint is not forgotten, but has no effect until reenabled.");
@@ -6459,7 +7764,7 @@ This command may be abbreviated \"disable\".",
           &disablelist);
 
   add_prefix_cmd ("delete", class_breakpoint, delete_command,
-          "Delete some breakpoints or auto-display expressions.\n\
+                 "Delete some breakpoints or auto-display expressions.\n\
 Arguments are breakpoint numbers with spaces in between.\n\
 To delete all breakpoints, give no argument.\n\
 \n\
@@ -6469,7 +7774,7 @@ The \"unset\" command is also an alias for \"delete\".",
   add_com_alias ("d", "delete", class_breakpoint, 1);
   if (xdb_commands)
     add_com ("db", class_breakpoint, delete_command,
-          "Delete some breakpoints.\n\
+            "Delete some breakpoints.\n\
 Arguments are breakpoint numbers with spaces in between.\n\
 To delete all breakpoints, give no argument.\n");
 
@@ -6486,7 +7791,7 @@ Argument may be line number, function name, or \"*\" and an address.\n\
 If line number is specified, all breakpoints in that line are cleared.\n\
 If function is specified, breakpoints at beginning of function are cleared.\n\
 If an address is specified, breakpoints at that address are cleared.\n\n",
-"With no argument, clears all breakpoints in the line that the selected frame\n\
+                  "With no argument, clears all breakpoints in the line that the selected frame\n\
 is executing in.\n\
 \n\
 See also the \"delete\" command which clears breakpoints by number.", NULL));
@@ -6497,7 +7802,7 @@ Argument may be line number, function name, or \"*\" and an address.\n\
 If line number is specified, break at start of code for that line.\n\
 If function is specified, break at start of code for that function.\n\
 If an address is specified, break at that exact address.\n",
-"With no arg, uses current execution address of selected stack frame.\n\
+                  "With no arg, uses current execution address of selected stack frame.\n\
 This is useful for breaking on return to a stack frame.\n\
 \n\
 Multiple breakpoints at one place are permitted, and useful if conditional.\n\
@@ -6508,13 +7813,13 @@ Do \"help breakpoints\" for info on other commands dealing with breakpoints.", N
   add_com_alias ("bre", "break", class_run, 1);
   add_com_alias ("brea", "break", class_run, 1);
 
-  add_com("xbreak", class_breakpoint, break_at_finish_command,
-          concat("Set breakpoint at procedure exit. \n\
+  add_com ("xbreak", class_breakpoint, break_at_finish_command,
+          concat ("Set breakpoint at procedure exit. \n\
 Argument may be function name, or \"*\" and an address.\n\
 If function is specified, break at end of code for that function.\n\
 If an address is specified, break at the end of the function that contains \n\
 that exact address.\n",
-"With no arg, uses current execution address of selected stack frame.\n\
+                  "With no arg, uses current execution address of selected stack frame.\n\
 This is useful for breaking on return to a stack frame.\n\
 \n\
 Multiple breakpoints at one place are permitted, and useful if conditional.\n\
@@ -6530,21 +7835,21 @@ Do \"help breakpoints\" for info on other commands dealing with breakpoints.", N
       add_com_alias ("ba", "break", class_breakpoint, 1);
       add_com_alias ("bu", "ubreak", class_breakpoint, 1);
       add_com ("bx", class_breakpoint, break_at_finish_at_depth_command,
-          "Set breakpoint at procedure exit.  Either there should\n\
+              "Set breakpoint at procedure exit.  Either there should\n\
 be no argument or the argument must be a depth.\n");
     }
 
   if (dbx_commands)
     {
-      add_abbrev_prefix_cmd("stop", class_breakpoint, stop_command, 
-           "Break in function/address or break at a line in the current file.",
-           &stoplist, "stop ", 1, &cmdlist);
-      add_cmd("in", class_breakpoint, stopin_command,
-              "Break in function or address.\n", &stoplist);
-      add_cmd("at", class_breakpoint, stopat_command,
-              "Break at a line in the current file.\n", &stoplist);
-      add_com("status", class_info, breakpoints_info, 
-           concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+      add_abbrev_prefix_cmd ("stop", class_breakpoint, stop_command,
+       "Break in function/address or break at a line in the current file.",
+                            &stoplist, "stop ", 1, &cmdlist);
+      add_cmd ("in", class_breakpoint, stopin_command,
+              "Break in function or address.\n", &stoplist);
+      add_cmd ("at", class_breakpoint, stopat_command,
+              "Break at a line in the current file.\n", &stoplist);
+      add_com ("status", class_info, breakpoints_info,
+              concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
 The \"Type\" column indicates one of:\n\
 \tbreakpoint     - normal breakpoint\n\
 \twatchpoint     - watchpoint\n\
@@ -6552,7 +7857,7 @@ The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
 the disposition of the breakpoint after it gets hit.  \"dis\" means that the\n\
 breakpoint will be disabled.  The \"Address\" and \"What\" columns indicate the\n\
 address and file/line number respectively.\n\n",
-"Convenience variable \"$_\" and default examine address for \"x\"\n\
+                      "Convenience variable \"$_\" and default examine address for \"x\"\n\
 are set to the address of the last breakpoint listed.\n\n\
 Convenience variable \"$bpnum\" contains the number of the last\n\
 breakpoint set.", NULL));
@@ -6567,14 +7872,14 @@ The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
 the disposition of the breakpoint after it gets hit.  \"dis\" means that the\n\
 breakpoint will be disabled.  The \"Address\" and \"What\" columns indicate the\n\
 address and file/line number respectively.\n\n",
-"Convenience variable \"$_\" and default examine address for \"x\"\n\
+                   "Convenience variable \"$_\" and default examine address for \"x\"\n\
 are set to the address of the last breakpoint listed.\n\n\
 Convenience variable \"$bpnum\" contains the number of the last\n\
 breakpoint set.", NULL));
 
   if (xdb_commands)
-    add_com("lb", class_breakpoint, breakpoints_info,
-           concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+    add_com ("lb", class_breakpoint, breakpoints_info,
+            concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
 The \"Type\" column indicates one of:\n\
 \tbreakpoint     - normal breakpoint\n\
 \twatchpoint     - watchpoint\n\
@@ -6582,15 +7887,13 @@ The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
 the disposition of the breakpoint after it gets hit.  \"dis\" means that the\n\
 breakpoint will be disabled.  The \"Address\" and \"What\" columns indicate the\n\
 address and file/line number respectively.\n\n",
-"Convenience variable \"$_\" and default examine address for \"x\"\n\
+                    "Convenience variable \"$_\" and default examine address for \"x\"\n\
 are set to the address of the last breakpoint listed.\n\n\
 Convenience variable \"$bpnum\" contains the number of the last\n\
 breakpoint set.", NULL));
 
-#if MAINTENANCE_CMDS
-
   add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints,
-           concat ("Status of all breakpoints, or breakpoint number NUMBER.\n\
+          concat ("Status of all breakpoints, or breakpoint number NUMBER.\n\
 The \"Type\" column indicates one of:\n\
 \tbreakpoint     - normal breakpoint\n\
 \twatchpoint     - watchpoint\n\
@@ -6598,20 +7901,18 @@ The \"Type\" column indicates one of:\n\
 \tlongjmp resume - internal breakpoint at the target of longjmp()\n\
 \tuntil          - internal breakpoint used by the \"until\" command\n\
 \tfinish         - internal breakpoint used by the \"finish\" command\n",
-"The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+                  "The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
 the disposition of the breakpoint after it gets hit.  \"dis\" means that the\n\
 breakpoint will be disabled.  The \"Address\" and \"What\" columns indicate the\n\
 address and file/line number respectively.\n\n",
-"Convenience variable \"$_\" and default examine address for \"x\"\n\
+                  "Convenience variable \"$_\" and default examine address for \"x\"\n\
 are set to the address of the last breakpoint listed.\n\n\
 Convenience variable \"$bpnum\" contains the number of the last\n\
 breakpoint set.", NULL),
           &maintenanceinfolist);
 
-#endif /* MAINTENANCE_CMDS */
-
   add_com ("catch", class_breakpoint, catch_command,
-         "Set catchpoints to catch events.\n\
+          "Set catchpoints to catch events.\n\
 Raised signals may be caught:\n\
 \tcatch signal              - all signals\n\
 \tcatch signal <signame>    - a particular signal\n\
@@ -6644,16 +7945,15 @@ C++ exceptions may be caught:\n\
 Do \"help set follow-fork-mode\" for info on debugging your program\n\
 after a fork or vfork is caught.\n\n\
 Do \"help breakpoints\" for info on other commands dealing with breakpoints.");
+
   add_com ("tcatch", class_breakpoint, tcatch_command,
-         "Set temporary catchpoints to catch events.\n\
+          "Set temporary catchpoints to catch events.\n\
 Args like \"catch\" command.\n\
 Like \"catch\" except the catchpoint is only temporary,\n\
 so it will be deleted when hit.  Equivalent to \"catch\" followed\n\
 by using \"enable delete\" on the catchpoint number.");
-add_com ("watch", class_breakpoint, watch_command,
 
+  add_com ("watch", class_breakpoint, watch_command,
           "Set a watchpoint for an expression.\n\
 A watchpoint stops execution of your program whenever the value of\n\
 an expression changes.");
@@ -6673,13 +7973,13 @@ an expression is either read or written.");
 
 
   c = add_set_cmd ("can-use-hw-watchpoints", class_support, var_zinteger,
-                   (char *) &can_use_hw_watchpoints,
-                   "Set debugger's willingness to use watchpoint hardware.\n\
+                  (char *) &can_use_hw_watchpoints,
+                  "Set debugger's willingness to use watchpoint hardware.\n\
 If zero, gdb will not use hardware for new watchpoints, even if\n\
 such is available.  (However, any hardware watchpoints that were\n\
 created before setting this to nonzero, will continue to use watchpoint\n\
 hardware.)",
-               &setlist);
+                  &setlist);
   add_show_from_set (c, &showlist);
 
   can_use_hw_watchpoints = 1;
index 2835fdf..1b3604c 100755 (executable)
@@ -18,6 +18,8 @@ ac_help="$ac_help
 ac_help="$ac_help
   --enable-multi-ice            Build the multi-ice-gdb-server"
 ac_help="$ac_help
+  --enable-gdbmi            Enable GDB-MI interface"
+ac_help="$ac_help
   --enable-tui            Enable full-screen terminal user interface"
 ac_help="$ac_help
   --enable-netrom         Enable NetROM support"
@@ -66,6 +68,7 @@ program_suffix=NONE
 program_transform_name=s,x,x,
 silent=
 site=
+sitefile=
 srcdir=
 target=NONE
 verbose=
@@ -180,6 +183,7 @@ Configuration:
   --help                  print this message
   --no-create             do not create output files
   --quiet, --silent       do not print \`checking...' messages
+  --site-file=FILE        use FILE as the site file
   --version               print the version of autoconf that created configure
 Directory and file names:
   --prefix=PREFIX         install architecture-independent files in PREFIX
@@ -350,6 +354,11 @@ EOF
   -site=* | --site=* | --sit=*)
     site="$ac_optarg" ;;
 
+  -site-file | --site-file | --site-fil | --site-fi | --site-f)
+    ac_prev=sitefile ;;
+  -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+    sitefile="$ac_optarg" ;;
+
   -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
     ac_prev=srcdir ;;
   -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
@@ -515,12 +524,16 @@ fi
 srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
 
 # Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
-  if test "x$prefix" != xNONE; then
-    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-  else
-    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+if test -z "$sitefile"; then
+  if test -z "$CONFIG_SITE"; then
+    if test "x$prefix" != xNONE; then
+      CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+    else
+      CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+    fi
   fi
+else
+  CONFIG_SITE="$sitefile"
 fi
 for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
@@ -564,7 +577,7 @@ fi
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:568: checking for $ac_word" >&5
+echo "configure:581: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -594,7 +607,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:598: checking for $ac_word" >&5
+echo "configure:611: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -645,7 +658,7 @@ fi
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:649: checking for $ac_word" >&5
+echo "configure:662: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -677,7 +690,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:681: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:694: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -688,12 +701,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 692 "configure"
+#line 705 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:710: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -719,12 +732,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:723: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:736: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:728: checking whether we are using GNU C" >&5
+echo "configure:741: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -733,7 +746,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:737: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:750: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -752,7 +765,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:756: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:769: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -784,7 +797,7 @@ else
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:788: checking how to run the C preprocessor" >&5
+echo "configure:801: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -799,13 +812,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 803 "configure"
+#line 816 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:809: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:822: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -816,13 +829,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 820 "configure"
+#line 833 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:826: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:839: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -833,13 +846,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 837 "configure"
+#line 850 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:843: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:856: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -864,9 +877,9 @@ fi
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for AIX""... $ac_c" 1>&6
-echo "configure:868: checking for AIX" >&5
+echo "configure:881: checking for AIX" >&5
 cat > conftest.$ac_ext <<EOF
-#line 870 "configure"
+#line 883 "configure"
 #include "confdefs.h"
 #ifdef _AIX
   yes
@@ -888,7 +901,7 @@ rm -f conftest*
 
 
 echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
-echo "configure:892: checking for POSIXized ISC" >&5
+echo "configure:905: checking for POSIXized ISC" >&5
 if test -d /etc/conf/kconfig.d &&
   grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
 then
@@ -912,7 +925,7 @@ fi
 
 
 echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
-echo "configure:916: checking for ${CC-cc} option to accept ANSI C" >&5
+echo "configure:929: checking for ${CC-cc} option to accept ANSI C" >&5
 if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -928,7 +941,7 @@ for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__
 do
   CC="$ac_save_CC $ac_arg"
   cat > conftest.$ac_ext <<EOF
-#line 932 "configure"
+#line 945 "configure"
 #include "confdefs.h"
 #include <stdarg.h>
 #include <stdio.h>
@@ -965,7 +978,7 @@ return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
 
 ; return 0; }
 EOF
-if { (eval echo configure:969: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:982: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   am_cv_prog_cc_stdc="$ac_arg"; break
 else
@@ -1036,7 +1049,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:1040: checking host system type" >&5
+echo "configure:1053: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -1057,7 +1070,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$host" 1>&6
 
 echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:1061: checking target system type" >&5
+echo "configure:1074: checking target system type" >&5
 
 target_alias=$target
 case "$target_alias" in
@@ -1075,7 +1088,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$target" 1>&6
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1079: checking build system type" >&5
+echo "configure:1092: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -1100,7 +1113,7 @@ test "$host_alias" != "$target_alias" &&
 
 ALL_LINGUAS=
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1104: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:1117: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1129,7 +1142,7 @@ fi
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1133: checking for $ac_word" >&5
+echo "configure:1146: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1157,12 +1170,12 @@ else
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1161: checking for ANSI C header files" >&5
+echo "configure:1174: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1166 "configure"
+#line 1179 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1170,7 +1183,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1174: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1187: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1187,7 +1200,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1191 "configure"
+#line 1204 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1205,7 +1218,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1209 "configure"
+#line 1222 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1226,7 +1239,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1230 "configure"
+#line 1243 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1237,7 +1250,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1261,12 +1274,12 @@ EOF
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1265: checking for working const" >&5
+echo "configure:1278: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1270 "configure"
+#line 1283 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1315,7 +1328,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:1319: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1332: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1336,21 +1349,21 @@ EOF
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:1340: checking for inline" >&5
+echo "configure:1353: checking for inline" >&5
 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
-#line 1347 "configure"
+#line 1360 "configure"
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:1354: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1367: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -1376,12 +1389,12 @@ EOF
 esac
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:1380: checking for off_t" >&5
+echo "configure:1393: checking for off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1385 "configure"
+#line 1398 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1409,12 +1422,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1413: checking for size_t" >&5
+echo "configure:1426: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1418 "configure"
+#line 1431 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1444,19 +1457,19 @@ fi
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:1448: checking for working alloca.h" >&5
+echo "configure:1461: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1453 "configure"
+#line 1466 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:1460: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1473: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -1477,12 +1490,12 @@ EOF
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:1481: checking for alloca" >&5
+echo "configure:1494: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1486 "configure"
+#line 1499 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -1510,7 +1523,7 @@ int main() {
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:1514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1527: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -1542,12 +1555,12 @@ EOF
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:1546: checking whether alloca needs Cray hooks" >&5
+echo "configure:1559: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1551 "configure"
+#line 1564 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -1572,12 +1585,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1576: checking for $ac_func" >&5
+echo "configure:1589: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1581 "configure"
+#line 1594 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1600,7 +1613,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1604: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1627,7 +1640,7 @@ done
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:1631: checking stack direction for C alloca" >&5
+echo "configure:1644: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1635,7 +1648,7 @@ else
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 1639 "configure"
+#line 1652 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -1654,7 +1667,7 @@ main ()
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:1658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
@@ -1679,17 +1692,17 @@ for ac_hdr in unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1683: checking for $ac_hdr" >&5
+echo "configure:1696: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1688 "configure"
+#line 1701 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1693: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1706: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1718,12 +1731,12 @@ done
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1722: checking for $ac_func" >&5
+echo "configure:1735: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1727 "configure"
+#line 1740 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1746,7 +1759,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1771,7 +1784,7 @@ fi
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:1775: checking for working mmap" >&5
+echo "configure:1788: checking for working mmap" >&5
 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1779,7 +1792,7 @@ else
   ac_cv_func_mmap_fixed_mapped=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 1783 "configure"
+#line 1796 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -1919,7 +1932,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:1923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -1947,17 +1960,17 @@ unistd.h values.h sys/param.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1951: checking for $ac_hdr" >&5
+echo "configure:1964: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1956 "configure"
+#line 1969 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1961: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1974: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1987,12 +2000,12 @@ done
 __argz_count __argz_stringify __argz_next
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1991: checking for $ac_func" >&5
+echo "configure:2004: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1996 "configure"
+#line 2009 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2015,7 +2028,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2044,12 +2057,12 @@ done
      for ac_func in stpcpy
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2048: checking for $ac_func" >&5
+echo "configure:2061: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2053 "configure"
+#line 2066 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2072,7 +2085,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2089: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2106,19 +2119,19 @@ EOF
 
    if test $ac_cv_header_locale_h = yes; then
     echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:2110: checking for LC_MESSAGES" >&5
+echo "configure:2123: checking for LC_MESSAGES" >&5
 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2115 "configure"
+#line 2128 "configure"
 #include "confdefs.h"
 #include <locale.h>
 int main() {
 return LC_MESSAGES
 ; return 0; }
 EOF
-if { (eval echo configure:2122: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   am_cv_val_LC_MESSAGES=yes
 else
@@ -2139,7 +2152,7 @@ EOF
     fi
   fi
    echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
-echo "configure:2143: checking whether NLS is requested" >&5
+echo "configure:2156: checking whether NLS is requested" >&5
         # Check whether --enable-nls or --disable-nls was given.
 if test "${enable_nls+set}" = set; then
   enableval="$enable_nls"
@@ -2159,7 +2172,7 @@ fi
 EOF
 
       echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
-echo "configure:2163: checking whether included gettext is requested" >&5
+echo "configure:2176: checking whether included gettext is requested" >&5
       # Check whether --with-included-gettext or --without-included-gettext was given.
 if test "${with_included_gettext+set}" = set; then
   withval="$with_included_gettext"
@@ -2178,17 +2191,17 @@ fi
 
        ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
-echo "configure:2182: checking for libintl.h" >&5
+echo "configure:2195: checking for libintl.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2187 "configure"
+#line 2200 "configure"
 #include "confdefs.h"
 #include <libintl.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2192: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2205: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2205,19 +2218,19 @@ fi
 if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
-echo "configure:2209: checking for gettext in libc" >&5
+echo "configure:2222: checking for gettext in libc" >&5
 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2214 "configure"
+#line 2227 "configure"
 #include "confdefs.h"
 #include <libintl.h>
 int main() {
 return (int) gettext ("")
 ; return 0; }
 EOF
-if { (eval echo configure:2221: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   gt_cv_func_gettext_libc=yes
 else
@@ -2233,7 +2246,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
 
           if test "$gt_cv_func_gettext_libc" != "yes"; then
             echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
-echo "configure:2237: checking for bindtextdomain in -lintl" >&5
+echo "configure:2250: checking for bindtextdomain in -lintl" >&5
 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2241,7 +2254,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2245 "configure"
+#line 2258 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2252,7 +2265,7 @@ int main() {
 bindtextdomain()
 ; return 0; }
 EOF
-if { (eval echo configure:2256: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2268,19 +2281,19 @@ fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
-echo "configure:2272: checking for gettext in libintl" >&5
+echo "configure:2285: checking for gettext in libintl" >&5
 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2277 "configure"
+#line 2290 "configure"
 #include "confdefs.h"
 
 int main() {
 return (int) gettext ("")
 ; return 0; }
 EOF
-if { (eval echo configure:2284: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2297: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   gt_cv_func_gettext_libintl=yes
 else
@@ -2308,7 +2321,7 @@ EOF
              # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2312: checking for $ac_word" >&5
+echo "configure:2325: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2342,12 +2355,12 @@ fi
                for ac_func in dcgettext
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2346: checking for $ac_func" >&5
+echo "configure:2359: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2351 "configure"
+#line 2364 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2370,7 +2383,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2397,7 +2410,7 @@ done
                # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2401: checking for $ac_word" >&5
+echo "configure:2414: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2433,7 +2446,7 @@ fi
                # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2437: checking for $ac_word" >&5
+echo "configure:2450: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2465,7 +2478,7 @@ else
 fi
 
                cat > conftest.$ac_ext <<EOF
-#line 2469 "configure"
+#line 2482 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2473,7 +2486,7 @@ extern int _nl_msg_cat_cntr;
                               return _nl_msg_cat_cntr
 ; return 0; }
 EOF
-if { (eval echo configure:2477: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   CATOBJEXT=.gmo
                   DATADIRNAME=share
@@ -2505,7 +2518,7 @@ fi
         # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2509: checking for $ac_word" >&5
+echo "configure:2522: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2539,7 +2552,7 @@ fi
         # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2543: checking for $ac_word" >&5
+echo "configure:2556: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2575,7 +2588,7 @@ fi
         # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2579: checking for $ac_word" >&5
+echo "configure:2592: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2665,7 +2678,7 @@ fi
        LINGUAS=
      else
        echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
-echo "configure:2669: checking for catalogs to be installed" >&5
+echo "configure:2682: checking for catalogs to be installed" >&5
        NEW_LINGUAS=
        for lang in ${LINGUAS=$ALL_LINGUAS}; do
          case "$ALL_LINGUAS" in
@@ -2693,17 +2706,17 @@ echo "configure:2669: checking for catalogs to be installed" >&5
       if test "$CATOBJEXT" = ".cat"; then
         ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
-echo "configure:2697: checking for linux/version.h" >&5
+echo "configure:2710: checking for linux/version.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2702 "configure"
+#line 2715 "configure"
 #include "confdefs.h"
 #include <linux/version.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2707: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2720: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2769,7 +2782,8 @@ fi
 CONFIG_OBS=
 CONFIG_DEPS=
 CONFIG_SRCS=
-CONFIG_INIT=
+CONFIG_INITS=
+ENABLE_CFLAGS=
 
 configdirs="doc testsuite"
 
@@ -2800,7 +2814,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2804: checking for $ac_word" >&5
+echo "configure:2818: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2841,7 +2855,7 @@ done
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:2845: checking for a BSD compatible install" >&5
+echo "configure:2859: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2902,7 +2916,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2906: checking for $ac_word" >&5
+echo "configure:2920: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2934,7 +2948,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2938: checking for $ac_word" >&5
+echo "configure:2952: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2966,7 +2980,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2970: checking for $ac_word" >&5
+echo "configure:2984: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3003,7 +3017,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3007: checking for $ac_word" >&5
+echo "configure:3021: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3055,12 +3069,12 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:3059: checking return type of signal handlers" >&5
+echo "configure:3073: checking return type of signal handlers" >&5
 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3064 "configure"
+#line 3078 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -3077,7 +3091,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:3081: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3095: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -3097,12 +3111,12 @@ EOF
 
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:3101: checking for ANSI C header files" >&5
+echo "configure:3115: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3106 "configure"
+#line 3120 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -3110,7 +3124,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3114: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3128: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3127,7 +3141,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 3131 "configure"
+#line 3145 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -3145,7 +3159,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 3149 "configure"
+#line 3163 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -3166,7 +3180,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 3170 "configure"
+#line 3184 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -3177,7 +3191,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:3181: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3195: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -3210,17 +3224,17 @@ for ac_hdr in ctype.h curses.h endian.h link.h thread_db.h proc_service.h \
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3214: checking for $ac_hdr" >&5
+echo "configure:3228: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3219 "configure"
+#line 3233 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3224: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3247,12 +3261,12 @@ fi
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:3251: checking whether stat file-mode macros are broken" >&5
+echo "configure:3265: checking whether stat file-mode macros are broken" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3256 "configure"
+#line 3270 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -3304,12 +3318,12 @@ fi
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:3308: checking for working const" >&5
+echo "configure:3322: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3313 "configure"
+#line 3327 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -3358,7 +3372,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:3362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3376: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -3382,12 +3396,12 @@ fi
 for ac_func in setpgid sbrk sigaction isascii bzero bcopy btowc poll sigprocmask
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3386: checking for $ac_func" >&5
+echo "configure:3400: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3391 "configure"
+#line 3405 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3410,7 +3424,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3414: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3437,19 +3451,19 @@ done
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:3441: checking for working alloca.h" >&5
+echo "configure:3455: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3446 "configure"
+#line 3460 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:3453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -3470,12 +3484,12 @@ EOF
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:3474: checking for alloca" >&5
+echo "configure:3488: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3479 "configure"
+#line 3493 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -3503,7 +3517,7 @@ int main() {
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:3507: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3521: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -3535,12 +3549,12 @@ EOF
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:3539: checking whether alloca needs Cray hooks" >&5
+echo "configure:3553: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3544 "configure"
+#line 3558 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -3565,12 +3579,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3569: checking for $ac_func" >&5
+echo "configure:3583: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3574 "configure"
+#line 3588 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3593,7 +3607,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3620,7 +3634,7 @@ done
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:3624: checking stack direction for C alloca" >&5
+echo "configure:3638: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3628,7 +3642,7 @@ else
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 3632 "configure"
+#line 3646 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -3647,7 +3661,7 @@ main ()
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:3651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
@@ -3670,19 +3684,19 @@ fi
 
 
 echo $ac_n "checking for PTRACE_GETXFPREGS""... $ac_c" 1>&6
-echo "configure:3674: checking for PTRACE_GETXFPREGS" >&5
+echo "configure:3688: checking for PTRACE_GETXFPREGS" >&5
 if eval "test \"`echo '$''{'gdb_cv_have_ptrace_getxfpregs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3679 "configure"
+#line 3693 "configure"
 #include "confdefs.h"
 #include <sys/ptrace.h>
 int main() {
 PTRACE_GETXFPREGS;
 ; return 0; }
 EOF
-if { (eval echo configure:3686: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3700: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   gdb_cv_have_ptrace_getxfpregs=yes
 else
@@ -3703,7 +3717,7 @@ EOF
 fi
 
 echo $ac_n "checking for socketpair in -lsocket""... $ac_c" 1>&6
-echo "configure:3707: checking for socketpair in -lsocket" >&5
+echo "configure:3721: checking for socketpair in -lsocket" >&5
 ac_lib_var=`echo socket'_'socketpair | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3711,7 +3725,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3715 "configure"
+#line 3729 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3722,7 +3736,7 @@ int main() {
 socketpair()
 ; return 0; }
 EOF
-if { (eval echo configure:3726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3752,12 +3766,12 @@ fi
 for ac_func in socketpair
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3756: checking for $ac_func" >&5
+echo "configure:3770: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3761 "configure"
+#line 3775 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3780,7 +3794,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3784: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3807,12 +3821,12 @@ done
 
 
 echo $ac_n "checking whether malloc must be declared""... $ac_c" 1>&6
-echo "configure:3811: checking whether malloc must be declared" >&5
+echo "configure:3825: checking whether malloc must be declared" >&5
 if eval "test \"`echo '$''{'bfd_cv_decl_needed_malloc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3816 "configure"
+#line 3830 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -3833,7 +3847,7 @@ int main() {
 char *(*pfn) = (char *(*)) malloc
 ; return 0; }
 EOF
-if { (eval echo configure:3837: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3851: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_decl_needed_malloc=no
 else
@@ -3854,12 +3868,12 @@ EOF
 fi
 
 echo $ac_n "checking whether realloc must be declared""... $ac_c" 1>&6
-echo "configure:3858: checking whether realloc must be declared" >&5
+echo "configure:3872: checking whether realloc must be declared" >&5
 if eval "test \"`echo '$''{'bfd_cv_decl_needed_realloc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3863 "configure"
+#line 3877 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -3880,7 +3894,7 @@ int main() {
 char *(*pfn) = (char *(*)) realloc
 ; return 0; }
 EOF
-if { (eval echo configure:3884: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3898: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_decl_needed_realloc=no
 else
@@ -3901,12 +3915,12 @@ EOF
 fi
 
 echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6
-echo "configure:3905: checking whether free must be declared" >&5
+echo "configure:3919: checking whether free must be declared" >&5
 if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3910 "configure"
+#line 3924 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -3927,7 +3941,7 @@ int main() {
 char *(*pfn) = (char *(*)) free
 ; return 0; }
 EOF
-if { (eval echo configure:3931: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3945: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_decl_needed_free=no
 else
@@ -3948,12 +3962,12 @@ EOF
 fi
 
 echo $ac_n "checking whether strerror must be declared""... $ac_c" 1>&6
-echo "configure:3952: checking whether strerror must be declared" >&5
+echo "configure:3966: checking whether strerror must be declared" >&5
 if eval "test \"`echo '$''{'bfd_cv_decl_needed_strerror'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3957 "configure"
+#line 3971 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -3974,7 +3988,7 @@ int main() {
 char *(*pfn) = (char *(*)) strerror
 ; return 0; }
 EOF
-if { (eval echo configure:3978: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3992: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_decl_needed_strerror=no
 else
@@ -3995,12 +4009,12 @@ EOF
 fi
 
 echo $ac_n "checking whether strdup must be declared""... $ac_c" 1>&6
-echo "configure:3999: checking whether strdup must be declared" >&5
+echo "configure:4013: checking whether strdup must be declared" >&5
 if eval "test \"`echo '$''{'bfd_cv_decl_needed_strdup'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4004 "configure"
+#line 4018 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4021,7 +4035,7 @@ int main() {
 char *(*pfn) = (char *(*)) strdup
 ; return 0; }
 EOF
-if { (eval echo configure:4025: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4039: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_decl_needed_strdup=no
 else
@@ -4042,12 +4056,12 @@ EOF
 fi
 
 echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6
-echo "configure:4046: checking whether strstr must be declared" >&5
+echo "configure:4060: checking whether strstr must be declared" >&5
 if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4051 "configure"
+#line 4065 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4068,7 +4082,7 @@ int main() {
 char *(*pfn) = (char *(*)) strstr
 ; return 0; }
 EOF
-if { (eval echo configure:4072: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4086: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_decl_needed_strstr=no
 else
@@ -4095,9 +4109,9 @@ fi
 # could be expunged. --jsm 1999-03-22
 
 echo $ac_n "checking for HPUX save_state structure""... $ac_c" 1>&6
-echo "configure:4099: checking for HPUX save_state structure" >&5
+echo "configure:4113: checking for HPUX save_state structure" >&5
 cat > conftest.$ac_ext <<EOF
-#line 4101 "configure"
+#line 4115 "configure"
 #include "confdefs.h"
 #include <machine/save_state.h>
 EOF
@@ -4112,7 +4126,7 @@ fi
 rm -f conftest*
 
 cat > conftest.$ac_ext <<EOF
-#line 4116 "configure"
+#line 4130 "configure"
 #include "confdefs.h"
 #include <machine/save_state.h>
 EOF
@@ -4179,19 +4193,19 @@ fi
 
 if test "$ac_cv_header_sys_procfs_h" = yes; then
   echo $ac_n "checking for pstatus_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4183: checking for pstatus_t in sys/procfs.h" >&5
+echo "configure:4197: checking for pstatus_t in sys/procfs.h" >&5
  if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4188 "configure"
+#line 4202 "configure"
 #include "confdefs.h"
 #include <sys/procfs.h>
 int main() {
 pstatus_t avar
 ; return 0; }
 EOF
-if { (eval echo configure:4195: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4209: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_have_sys_procfs_type_pstatus_t=yes
 else
@@ -4213,19 +4227,19 @@ EOF
  echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus_t" 1>&6
 
   echo $ac_n "checking for prrun_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4217: checking for prrun_t in sys/procfs.h" >&5
+echo "configure:4231: checking for prrun_t in sys/procfs.h" >&5
  if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prrun_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4222 "configure"
+#line 4236 "configure"
 #include "confdefs.h"
 #include <sys/procfs.h>
 int main() {
 prrun_t avar
 ; return 0; }
 EOF
-if { (eval echo configure:4229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4243: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_have_sys_procfs_type_prrun_t=yes
 else
@@ -4247,19 +4261,19 @@ EOF
  echo "$ac_t""$bfd_cv_have_sys_procfs_type_prrun_t" 1>&6
 
   echo $ac_n "checking for gregset_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4251: checking for gregset_t in sys/procfs.h" >&5
+echo "configure:4265: checking for gregset_t in sys/procfs.h" >&5
  if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_gregset_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4256 "configure"
+#line 4270 "configure"
 #include "confdefs.h"
 #include <sys/procfs.h>
 int main() {
 gregset_t avar
 ; return 0; }
 EOF
-if { (eval echo configure:4263: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4277: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_have_sys_procfs_type_gregset_t=yes
 else
@@ -4281,19 +4295,19 @@ EOF
  echo "$ac_t""$bfd_cv_have_sys_procfs_type_gregset_t" 1>&6
 
   echo $ac_n "checking for fpregset_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4285: checking for fpregset_t in sys/procfs.h" >&5
+echo "configure:4299: checking for fpregset_t in sys/procfs.h" >&5
  if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_fpregset_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4290 "configure"
+#line 4304 "configure"
 #include "confdefs.h"
 #include <sys/procfs.h>
 int main() {
 fpregset_t avar
 ; return 0; }
 EOF
-if { (eval echo configure:4297: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4311: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_have_sys_procfs_type_fpregset_t=yes
 else
@@ -4315,19 +4329,19 @@ EOF
  echo "$ac_t""$bfd_cv_have_sys_procfs_type_fpregset_t" 1>&6
 
   echo $ac_n "checking for prgregset_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4319: checking for prgregset_t in sys/procfs.h" >&5
+echo "configure:4333: checking for prgregset_t in sys/procfs.h" >&5
  if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prgregset_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4324 "configure"
+#line 4338 "configure"
 #include "confdefs.h"
 #include <sys/procfs.h>
 int main() {
 prgregset_t avar
 ; return 0; }
 EOF
-if { (eval echo configure:4331: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4345: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_have_sys_procfs_type_prgregset_t=yes
 else
@@ -4349,19 +4363,19 @@ EOF
  echo "$ac_t""$bfd_cv_have_sys_procfs_type_prgregset_t" 1>&6
 
   echo $ac_n "checking for prfpregset_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4353: checking for prfpregset_t in sys/procfs.h" >&5
+echo "configure:4367: checking for prfpregset_t in sys/procfs.h" >&5
  if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prfpregset_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4358 "configure"
+#line 4372 "configure"
 #include "confdefs.h"
 #include <sys/procfs.h>
 int main() {
 prfpregset_t avar
 ; return 0; }
 EOF
-if { (eval echo configure:4365: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4379: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_have_sys_procfs_type_prfpregset_t=yes
 else
@@ -4383,19 +4397,19 @@ EOF
  echo "$ac_t""$bfd_cv_have_sys_procfs_type_prfpregset_t" 1>&6
 
   echo $ac_n "checking for lwpid_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4387: checking for lwpid_t in sys/procfs.h" >&5
+echo "configure:4401: checking for lwpid_t in sys/procfs.h" >&5
  if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_lwpid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4392 "configure"
+#line 4406 "configure"
 #include "confdefs.h"
 #include <sys/procfs.h>
 int main() {
 lwpid_t avar
 ; return 0; }
 EOF
-if { (eval echo configure:4399: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4413: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_have_sys_procfs_type_lwpid_t=yes
 else
@@ -4417,19 +4431,19 @@ EOF
  echo "$ac_t""$bfd_cv_have_sys_procfs_type_lwpid_t" 1>&6
 
   echo $ac_n "checking for psaddr_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4421: checking for psaddr_t in sys/procfs.h" >&5
+echo "configure:4435: checking for psaddr_t in sys/procfs.h" >&5
  if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_psaddr_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4426 "configure"
+#line 4440 "configure"
 #include "confdefs.h"
 #include <sys/procfs.h>
 int main() {
 psaddr_t avar
 ; return 0; }
 EOF
-if { (eval echo configure:4433: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4447: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   bfd_cv_have_sys_procfs_type_psaddr_t=yes
 else
@@ -4453,12 +4467,12 @@ EOF
 
   
   echo $ac_n "checking for PIOCSET ioctl entry in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:4457: checking for PIOCSET ioctl entry in sys/procfs.h" >&5
+echo "configure:4471: checking for PIOCSET ioctl entry in sys/procfs.h" >&5
   if eval "test \"`echo '$''{'gdb_cv_have_procfs_piocset'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4462 "configure"
+#line 4476 "configure"
 #include "confdefs.h"
 #include <unistd.h>
 #include <sys/types.h>
@@ -4471,7 +4485,7 @@ int main() {
   
 ; return 0; }
 EOF
-if { (eval echo configure:4475: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4489: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   gdb_cv_have_procfs_piocset=yes
 else
@@ -4493,7 +4507,7 @@ EOF
 fi
 
 echo $ac_n "checking for main in -lm""... $ac_c" 1>&6
-echo "configure:4497: checking for main in -lm" >&5
+echo "configure:4511: checking for main in -lm" >&5
 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4501,14 +4515,14 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4505 "configure"
+#line 4519 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:4512: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4537,7 +4551,7 @@ fi
 
 
 echo $ac_n "checking for wctype in -lc""... $ac_c" 1>&6
-echo "configure:4541: checking for wctype in -lc" >&5
+echo "configure:4555: checking for wctype in -lc" >&5
 ac_lib_var=`echo c'_'wctype | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4545,7 +4559,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4549 "configure"
+#line 4563 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4556,7 +4570,7 @@ int main() {
 wctype()
 ; return 0; }
 EOF
-if { (eval echo configure:4560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4575,7 +4589,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for wctype in -lw""... $ac_c" 1>&6
-echo "configure:4579: checking for wctype in -lw" >&5
+echo "configure:4593: checking for wctype in -lw" >&5
 ac_lib_var=`echo w'_'wctype | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4583,7 +4597,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lw  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4587 "configure"
+#line 4601 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4594,7 +4608,7 @@ int main() {
 wctype()
 ; return 0; }
 EOF
-if { (eval echo configure:4598: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4626,12 +4640,12 @@ fi
 
 
 echo $ac_n "checking for long long support in compiler""... $ac_c" 1>&6
-echo "configure:4630: checking for long long support in compiler" >&5
+echo "configure:4644: checking for long long support in compiler" >&5
 if eval "test \"`echo '$''{'gdb_cv_c_long_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4635 "configure"
+#line 4649 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -4641,7 +4655,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:4645: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4659: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   gdb_cv_c_long_long=yes
 else
@@ -4663,7 +4677,7 @@ fi
 
 
 echo $ac_n "checking for long long support in printf""... $ac_c" 1>&6
-echo "configure:4667: checking for long long support in printf" >&5
+echo "configure:4681: checking for long long support in printf" >&5
 if eval "test \"`echo '$''{'gdb_cv_printf_has_long_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4671,7 +4685,7 @@ else
   gdb_cv_printf_has_long_long=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 4675 "configure"
+#line 4689 "configure"
 #include "confdefs.h"
 
 int main () {
@@ -4685,7 +4699,7 @@ int main () {
   return (strcmp ("0x0123456789abcdef", buf));
 }
 EOF
-if { (eval echo configure:4689: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4703: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   gdb_cv_printf_has_long_long=yes
 else
@@ -4709,19 +4723,19 @@ echo "$ac_t""$gdb_cv_printf_has_long_long" 1>&6
 
 
 echo $ac_n "checking for long double support in compiler""... $ac_c" 1>&6
-echo "configure:4713: checking for long double support in compiler" >&5
+echo "configure:4727: checking for long double support in compiler" >&5
 if eval "test \"`echo '$''{'ac_cv_c_long_double'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4718 "configure"
+#line 4732 "configure"
 #include "confdefs.h"
 
 int main() {
 long double foo;
 ; return 0; }
 EOF
-if { (eval echo configure:4725: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4739: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_long_double=yes
 else
@@ -4743,7 +4757,7 @@ fi
 
 
 echo $ac_n "checking for long double support in printf""... $ac_c" 1>&6
-echo "configure:4747: checking for long double support in printf" >&5
+echo "configure:4761: checking for long double support in printf" >&5
 if eval "test \"`echo '$''{'gdb_cv_printf_has_long_double'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4751,7 +4765,7 @@ else
   gdb_cv_printf_has_long_double=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 4755 "configure"
+#line 4769 "configure"
 #include "confdefs.h"
 
 int main () {
@@ -4761,7 +4775,7 @@ int main () {
   return (strncmp ("3.14159", buf, 7));
 }
 EOF
-if { (eval echo configure:4765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   gdb_cv_printf_has_long_double=yes
 else
@@ -4785,7 +4799,7 @@ echo "$ac_t""$gdb_cv_printf_has_long_double" 1>&6
 
 
 echo $ac_n "checking for long double support in scanf""... $ac_c" 1>&6
-echo "configure:4789: checking for long double support in scanf" >&5
+echo "configure:4803: checking for long double support in scanf" >&5
 if eval "test \"`echo '$''{'gdb_cv_scanf_has_long_double'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4793,7 +4807,7 @@ else
   gdb_cv_scanf_has_long_double=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 4797 "configure"
+#line 4811 "configure"
 #include "confdefs.h"
 
 int main () {
@@ -4803,7 +4817,7 @@ int main () {
   return !(f > 3.14159 && f < 3.14160);
 }
 EOF
-if { (eval echo configure:4807: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4821: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   gdb_cv_scanf_has_long_double=yes
 else
@@ -4829,17 +4843,17 @@ for ac_hdr in unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4833: checking for $ac_hdr" >&5
+echo "configure:4847: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4838 "configure"
+#line 4852 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4843: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4857: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -4868,12 +4882,12 @@ done
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4872: checking for $ac_func" >&5
+echo "configure:4886: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4877 "configure"
+#line 4891 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4896,7 +4910,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4921,7 +4935,7 @@ fi
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:4925: checking for working mmap" >&5
+echo "configure:4939: checking for working mmap" >&5
 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4929,7 +4943,7 @@ else
   ac_cv_func_mmap_fixed_mapped=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 4933 "configure"
+#line 4947 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -5069,7 +5083,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:5073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -5098,7 +5112,7 @@ if test ${build} = ${host} -a ${host} = ${target} ; then
    case ${host_os} in
    hpux*)
       echo $ac_n "checking for HPUX/OSF thread support""... $ac_c" 1>&6
-echo "configure:5102: checking for HPUX/OSF thread support" >&5
+echo "configure:5116: checking for HPUX/OSF thread support" >&5
       if test -f /usr/include/dce/cma_config.h ; then
          if test "$GCC" = "yes" ; then
             echo "$ac_t""yes" 1>&6
@@ -5118,7 +5132,7 @@ EOF
       ;;
    solaris*)
       echo $ac_n "checking for Solaris thread debugging library""... $ac_c" 1>&6
-echo "configure:5122: checking for Solaris thread debugging library" >&5
+echo "configure:5136: checking for Solaris thread debugging library" >&5
       if test -f /usr/lib/libthread_db.so.1 ; then
          echo "$ac_t""yes" 1>&6
          cat >> confdefs.h <<\EOF
@@ -5128,7 +5142,7 @@ EOF
          CONFIG_OBS="${CONFIG_OBS} sol-thread.o"
          CONFIG_SRCS="${CONFIG_SRCS} sol-thread.c"
          echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:5132: checking for dlopen in -ldl" >&5
+echo "configure:5146: checking for dlopen in -ldl" >&5
 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5136,7 +5150,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5140 "configure"
+#line 5154 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5147,7 +5161,7 @@ int main() {
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:5151: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5179,17 +5193,17 @@ fi
             # all symbols visible in the dynamic symbol table.
             hold_ldflags=$LDFLAGS
             echo $ac_n "checking for the ld -export-dynamic flag""... $ac_c" 1>&6
-echo "configure:5183: checking for the ld -export-dynamic flag" >&5
+echo "configure:5197: checking for the ld -export-dynamic flag" >&5
             LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
             cat > conftest.$ac_ext <<EOF
-#line 5186 "configure"
+#line 5200 "configure"
 #include "confdefs.h"
 
 int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:5193: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5207: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   found=yes
 else
@@ -5208,13 +5222,13 @@ rm -f conftest*
         # Sun randomly tweaked the prototypes in <proc_service.h>
         # at one point.
         echo $ac_n "checking if <proc_service.h> is old""... $ac_c" 1>&6
-echo "configure:5212: checking if <proc_service.h> is old" >&5
+echo "configure:5226: checking if <proc_service.h> is old" >&5
         if eval "test \"`echo '$''{'gdb_cv_proc_service_is_old'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
            cat > conftest.$ac_ext <<EOF
-#line 5218 "configure"
+#line 5232 "configure"
 #include "confdefs.h"
 
                #include <proc_service.h>
@@ -5225,7 +5239,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:5229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5243: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   gdb_cv_proc_service_is_old=no
 else
@@ -5253,7 +5267,32 @@ EOF
    
 fi
 
-ENABLE_CFLAGS=
+
+# Check whether --enable-gdbmi or --disable-gdbmi was given.
+if test "${enable_gdbmi+set}" = set; then
+  enableval="$enable_gdbmi"
+  
+  case "${enable_gdbmi}" in
+    yes | no) ;;
+    "")  enable_gdbmi=yes ;;
+    *)
+      { echo "configure: error: Bad value for --enable-gdbmi: ${enableval}" 1>&2; exit 1; }
+    ;;
+  esac
+
+fi
+
+case ${enable_gdbmi} in
+  "yes" )
+    if test -d "${srcdir}/mi" ; then
+      CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_MI_OBS)"
+      CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_MI_DEPS)"
+      CONFIG_SRCS="${CONFIG_SRS} \$(SUBDIR_MI_SRCS)"
+      CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_MI_INITS)"
+      ENABLE_CFLAGS="${ENABLE_CFLAGS} -DUI_OUT=1"
+    fi
+    ;;
+esac
 
 # Check whether --enable-tui or --disable-tui was given.
 if test "${enable_tui+set}" = set; then
@@ -5372,12 +5411,12 @@ fi
 
 # In the Cygwin environment, we need some additional flags.
 echo $ac_n "checking for cygwin""... $ac_c" 1>&6
-echo "configure:5376: checking for cygwin" >&5
+echo "configure:5415: checking for cygwin" >&5
 if eval "test \"`echo '$''{'gdb_cv_os_cygwin'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5381 "configure"
+#line 5420 "configure"
 #include "confdefs.h"
 
 #if defined (__CYGWIN__) || defined (__CYGWIN32__)
@@ -5411,7 +5450,7 @@ if test x$gdb_cv_os_cygwin = xyes; then
 else
   TERM_LIB=
   echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6
-echo "configure:5415: checking for tgetent in -lncurses" >&5
+echo "configure:5454: checking for tgetent in -lncurses" >&5
 ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5419,7 +5458,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lncurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5423 "configure"
+#line 5462 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5430,7 +5469,7 @@ int main() {
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:5434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5473: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5449,7 +5488,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for tgetent in -lHcurses""... $ac_c" 1>&6
-echo "configure:5453: checking for tgetent in -lHcurses" >&5
+echo "configure:5492: checking for tgetent in -lHcurses" >&5
 ac_lib_var=`echo Hcurses'_'tgetent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5457,7 +5496,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lHcurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5461 "configure"
+#line 5500 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5468,7 +5507,7 @@ int main() {
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:5472: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5511: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5487,7 +5526,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for tgetent in -ltermlib""... $ac_c" 1>&6
-echo "configure:5491: checking for tgetent in -ltermlib" >&5
+echo "configure:5530: checking for tgetent in -ltermlib" >&5
 ac_lib_var=`echo termlib'_'tgetent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5495,7 +5534,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ltermlib  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5499 "configure"
+#line 5538 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5506,7 +5545,7 @@ int main() {
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:5510: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5525,7 +5564,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6
-echo "configure:5529: checking for tgetent in -ltermcap" >&5
+echo "configure:5568: checking for tgetent in -ltermcap" >&5
 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5533,7 +5572,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ltermcap  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5537 "configure"
+#line 5576 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5544,7 +5583,7 @@ int main() {
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:5548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5563,7 +5602,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6
-echo "configure:5567: checking for tgetent in -lcurses" >&5
+echo "configure:5606: checking for tgetent in -lcurses" >&5
 ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5571,7 +5610,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lcurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5575 "configure"
+#line 5614 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5582,7 +5621,7 @@ int main() {
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:5586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5625: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5601,7 +5640,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for tgetent in -lterminfo""... $ac_c" 1>&6
-echo "configure:5605: checking for tgetent in -lterminfo" >&5
+echo "configure:5644: checking for tgetent in -lterminfo" >&5
 ac_lib_var=`echo terminfo'_'tgetent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5609,7 +5648,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lterminfo  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5613 "configure"
+#line 5652 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5620,7 +5659,7 @@ int main() {
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:5624: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5777,7 +5816,7 @@ if test "${with_tclconfig+set}" = set; then
 fi
 
   echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6
-echo "configure:5781: checking for Tcl configuration" >&5
+echo "configure:5820: checking for Tcl configuration" >&5
   if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5885,7 +5924,7 @@ if test "${with_tkconfig+set}" = set; then
 fi
 
   echo $ac_n "checking for Tk configuration""... $ac_c" 1>&6
-echo "configure:5889: checking for Tk configuration" >&5
+echo "configure:5928: checking for Tk configuration" >&5
   if eval "test \"`echo '$''{'ac_cv_c_tkconfig'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5981,7 +6020,7 @@ fi
 
 no_tcl=true
 echo $ac_n "checking for Tcl private headers. dir=${configdir}""... $ac_c" 1>&6
-echo "configure:5985: checking for Tcl private headers. dir=${configdir}" >&5
+echo "configure:6024: checking for Tcl private headers. dir=${configdir}" >&5
 # Check whether --with-tclinclude or --without-tclinclude was given.
 if test "${with_tclinclude+set}" = set; then
   withval="$with_tclinclude"
@@ -6047,17 +6086,17 @@ fi
 if test x"${ac_cv_c_tclh}" = x ; then
    ac_safe=`echo "tclInt.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for tclInt.h""... $ac_c" 1>&6
-echo "configure:6051: checking for tclInt.h" >&5
+echo "configure:6090: checking for tclInt.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6056 "configure"
+#line 6095 "configure"
 #include "confdefs.h"
 #include <tclInt.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6061: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6100: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6117,7 +6156,7 @@ fi
 #
 no_tk=true
 echo $ac_n "checking for Tk private headers""... $ac_c" 1>&6
-echo "configure:6121: checking for Tk private headers" >&5
+echo "configure:6160: checking for Tk private headers" >&5
 # Check whether --with-tkinclude or --without-tkinclude was given.
 if test "${with_tkinclude+set}" = set; then
   withval="$with_tkinclude"
@@ -6183,17 +6222,17 @@ fi
 if test x"${ac_cv_c_tkh}" = x ; then
    ac_safe=`echo "tk.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for tk.h""... $ac_c" 1>&6
-echo "configure:6187: checking for tk.h" >&5
+echo "configure:6226: checking for tk.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6192 "configure"
+#line 6231 "configure"
 #include "confdefs.h"
 #include <tk.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6197: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6236: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6239,7 +6278,7 @@ fi
 
           
 echo $ac_n "checking for Itcl private headers. srcdir=${srcdir}""... $ac_c" 1>&6
-echo "configure:6243: checking for Itcl private headers. srcdir=${srcdir}" >&5
+echo "configure:6282: checking for Itcl private headers. srcdir=${srcdir}" >&5
 if test x"${ac_cv_c_itclh}" = x ; then
   for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itcl; do
     if test -f $i/generic/itcl.h ; then
@@ -6262,7 +6301,7 @@ fi
 
           
 echo $ac_n "checking for Itk private headers. srcdir=${srcdir}""... $ac_c" 1>&6
-echo "configure:6266: checking for Itk private headers. srcdir=${srcdir}" >&5
+echo "configure:6305: checking for Itk private headers. srcdir=${srcdir}" >&5
 if test x"${ac_cv_c_itkh}" = x ; then
   for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itk; do
     if test -f $i/generic/itk.h ; then
@@ -6285,7 +6324,7 @@ fi
 
           
 echo $ac_n "checking for Tix private headers. srcdir=${srcdir}""... $ac_c" 1>&6
-echo "configure:6289: checking for Tix private headers. srcdir=${srcdir}" >&5
+echo "configure:6328: checking for Tix private headers. srcdir=${srcdir}" >&5
 if test x"${ac_cv_c_tixh}" = x ; then
   for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do
     if test -f $i/generic/tix.h ; then
@@ -6323,7 +6362,7 @@ if test "${with_itclconfig+set}" = set; then
 fi
 
   echo $ac_n "checking for Itcl configuration""... $ac_c" 1>&6
-echo "configure:6327: checking for Itcl configuration" >&5
+echo "configure:6366: checking for Itcl configuration" >&5
   if eval "test \"`echo '$''{'ac_cv_c_itclconfig'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6435,7 +6474,7 @@ if test "${with_itkconfig+set}" = set; then
 fi
 
   echo $ac_n "checking for Itk configuration""... $ac_c" 1>&6
-echo "configure:6439: checking for Itk configuration" >&5
+echo "configure:6478: checking for Itk configuration" >&5
   if eval "test \"`echo '$''{'ac_cv_c_itkconfig'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6547,7 +6586,7 @@ if test "${with_tixconfig+set}" = set; then
 fi
 
   echo $ac_n "checking for Tix configuration""... $ac_c" 1>&6
-echo "configure:6551: checking for Tix configuration" >&5
+echo "configure:6590: checking for Tix configuration" >&5
   if eval "test \"`echo '$''{'ac_cv_c_tixconfig'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6684,7 +6723,7 @@ fi
 # Uses ac_ vars as temps to allow command line to override cache and checks.
 # --without-x overrides everything else, but does not touch the cache.
 echo $ac_n "checking for X""... $ac_c" 1>&6
-echo "configure:6688: checking for X" >&5
+echo "configure:6727: checking for X" >&5
 
 # Check whether --with-x or --without-x was given.
 if test "${with_x+set}" = set; then
@@ -6746,12 +6785,12 @@ if test "$ac_x_includes" = NO; then
 
   # First, try using that file with no special directory specified.
 cat > conftest.$ac_ext <<EOF
-#line 6750 "configure"
+#line 6789 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6755: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6794: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6820,14 +6859,14 @@ if test "$ac_x_libraries" = NO; then
   ac_save_LIBS="$LIBS"
   LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6824 "configure"
+#line 6863 "configure"
 #include "confdefs.h"
 
 int main() {
 ${x_direct_test_function}()
 ; return 0; }
 EOF
-if { (eval echo configure:6831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6870: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   LIBS="$ac_save_LIBS"
 # We can link X programs with no special library path.
@@ -7105,7 +7144,7 @@ files="${files} config/nm-empty.h"
 links="${links} nm.h"
 fi
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:7109: checking whether ln -s works" >&5
+echo "configure:7148: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7139,12 +7178,12 @@ fi
 
 
 echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:7143: checking for Cygwin environment" >&5
+echo "configure:7182: checking for Cygwin environment" >&5
 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7148 "configure"
+#line 7187 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -7155,7 +7194,7 @@ int main() {
 return __CYGWIN__;
 ; return 0; }
 EOF
-if { (eval echo configure:7159: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7198: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_cygwin=yes
 else
@@ -7172,19 +7211,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6
 CYGWIN=
 test "$ac_cv_cygwin" = yes && CYGWIN=yes
 echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:7176: checking for mingw32 environment" >&5
+echo "configure:7215: checking for mingw32 environment" >&5
 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7181 "configure"
+#line 7220 "configure"
 #include "confdefs.h"
 
 int main() {
 return __MINGW32__;
 ; return 0; }
 EOF
-if { (eval echo configure:7188: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7227: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_mingw32=yes
 else
@@ -7203,7 +7242,7 @@ test "$ac_cv_mingw32" = yes && MINGW32=yes
 
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:7207: checking for executable suffix" >&5
+echo "configure:7246: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7213,10 +7252,10 @@ else
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:7217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  if { (eval echo configure:7256: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
-      *.c | *.o | *.obj) ;;
+      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
index 84d9fe2..cfb8308 100644 (file)
@@ -41,7 +41,8 @@ dnl List of object files added by configure.
 CONFIG_OBS=
 CONFIG_DEPS=
 CONFIG_SRCS=
-CONFIG_INIT=
+CONFIG_INITS=
+ENABLE_CFLAGS=
 
 configdirs="doc testsuite"
 
@@ -363,7 +364,30 @@ if test ${build} = ${host} -a ${host} = ${target} ; then
 fi
 
 dnl Handle optional features that can be enabled.
-ENABLE_CFLAGS=
+
+dnl Handle MI sub-directory configury.
+AC_ARG_ENABLE(gdbmi,
+[  --enable-gdbmi            Enable GDB-MI interface],
+[
+  case "${enable_gdbmi}" in
+    yes | no) ;;
+    "")  enable_gdbmi=yes ;;
+    *)
+      AC_MSG_ERROR(Bad value for --enable-gdbmi: ${enableval})
+    ;;
+  esac
+])
+case ${enable_gdbmi} in
+  "yes" )
+    if test -d "${srcdir}/mi" ; then
+      CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_MI_OBS)"
+      CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_MI_DEPS)"
+      CONFIG_SRCS="${CONFIG_SRS} \$(SUBDIR_MI_SRCS)"
+      CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_MI_INITS)"
+      ENABLE_CFLAGS="${ENABLE_CFLAGS} \${SUBDIR_MI_CFLAGS)"
+    fi
+    ;;
+esac
 
 AC_ARG_ENABLE(tui,
 [  --enable-tui            Enable full-screen terminal user interface],
@@ -406,7 +430,9 @@ fi
 
 AC_ARG_ENABLE(build-warnings,
 [  --enable-build-warnings Enable build-time compiler warnings if gcc is used],
-[build_warnings="-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations"
+[
+# not yet: -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
+build_warnings="-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith"
 case "${enableval}" in
   yes) ;;
   no)  build_warnings="-w";;
index ba958c7..fa9f540 100644 (file)
@@ -1122,6 +1122,16 @@ extern int watchdog;
 
 /* Hooks for alternate command interfaces.  */
 
+#ifdef UI_OUT
+/* The name of the interpreter if specified on the command line. */
+extern char *interpreter_p;
+#endif
+
+/* If a given interpreter matches INTERPRETER_P then it should update
+   command_loop_hook and init_ui_hook with the per-interpreter
+   implementation. */
+/* FIXME: command_loop_hook and init_ui_hook should be moved here. */
+
 struct target_waitstatus;
 struct cmd_list_element;
 
index 5851fd2..9e19d45 100644 (file)
 
    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. */
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
 
 #include "defs.h"
-#include "event-loop.h"
-#ifdef HAVE_POLL
-#include <sys/poll.h>
-#endif
+#include "top.h"
 #include "inferior.h"
+#include "target.h"
+#include "terminal.h"          /* for job_control */
+#include "signals.h"
+#include "event-loop.h"
+#include "event-top.h"
+
+/* For dont_repeat() */
+#include "gdbcmd.h"
 
 /* readline include files */
 #include <readline/readline.h>
 #include <readline/history.h>
 
+#include <signal.h>
+
 /* readline defines this.  */
 #undef savestring
 
-extern FILE *instream;
+extern void _initialize_event_loop (void);
 
-static void command_line_handler PARAMS ((char *));
-static void gdb_readline2 PARAMS ((void));
-static void pop_prompt PARAMS ((void));
-static void push_prompt PARAMS ((char *, char *, char *));
+static void rl_callback_read_char_wrapper (gdb_client_data client_data);
+static void command_line_handler (char *rl);
+static void command_line_handler_continuation (struct continuation_arg *arg);
+static void change_line_handler (void);
+static void change_annotation_level (void);
+static void command_handler (char *command);
+void cli_command_loop (void);
+static void async_do_nothing (gdb_client_data arg);
+static void async_disconnect (gdb_client_data arg);
+static void async_stop_sig (gdb_client_data arg);
+static void async_float_handler (gdb_client_data arg);
 
 /* Signal handlers. */
-void handle_sigint PARAMS ((int));
-void handle_sigquit PARAMS ((int));
-void handle_sighup PARAMS ((int));
-void handle_sigfpe PARAMS ((int));
-void handle_sigwinch PARAMS ((int));
+static void handle_sigquit (int sig);
+static void handle_sighup (int sig);
+static void handle_sigfpe (int sig);
+#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
+static void handle_sigwinch (int sig);
+#endif
 
 /* Functions to be invoked by the event loop in response to
    signals. */
-void async_request_quit PARAMS ((void));
-void async_do_nothing PARAMS ((void));
-void async_disconnect PARAMS ((void));
-void async_float_handler PARAMS ((void));
-
-/* Functions from top.c. */
-extern void command_loop_marker PARAMS ((int));
-extern int quit_cover PARAMS ((PTR));
-extern void quit_command PARAMS ((char *, int));
-extern void execute_command PARAMS ((char *, int));
-
-/* Variables from top.c. */
-extern int source_line_number;
-extern char *source_file_name;
-extern char *source_error;
-extern char *source_pre_error;
-extern int history_expansion_p;
-extern int server_command;
-
-/* If this definition isn't overridden by the header files, assume
-   that isatty and fileno exist on this system.  */
-#ifndef ISATTY
-#define ISATTY(FP)     (isatty (fileno (FP)))
-#endif
-
-/* Hook for alternate command interface.  */
-void (*async_hook) PARAMS ((void));
+static void async_do_nothing (gdb_client_data);
+static void async_disconnect (gdb_client_data);
+static void async_float_handler (gdb_client_data);
+static void async_stop_sig (gdb_client_data);
 
 /* Readline offers an alternate interface, via callback
    functions. These are all included in the file callback.c in the
@@ -96,15 +89,15 @@ void (*async_hook) PARAMS ((void));
    line of input is ready.  CALL_READLINE is to be set to the function
    that readline offers as callback to the event_loop. */
 
-void (*input_handler) PARAMS ((char *));
-void (*call_readline) PARAMS ((void));
+void (*input_handler) (char *);
+void (*call_readline) (gdb_client_data);
 
 /* Important variables for the event loop. */
 
 /* This is used to determine if GDB is using the readline library or
    its own simplified form of readline. It is used by the asynchronous
-   form of the set editing command. 
-   ezannoni: as of 4/29/99 I expect that this
+   form of the set editing command.
+   ezannoni: as of 1999-04-29 I expect that this
    variable will not be used after gdb is changed to use the event
    loop as default engine, and event-top.c is merged into top.c. */
 int async_command_editing_p;
@@ -117,6 +110,10 @@ char *new_async_prompt;
    annotation_level is 2. */
 char *async_annotation_suffix;
 
+/* This is used to display the notification of the completion of an
+   asynchronous execution command. */
+int exec_done_display_p = 0;
+
 /* This is the file descriptor for the input stream that GDB uses to
    read commands from. */
 int input_fd;
@@ -132,14 +129,17 @@ struct prompts the_prompts;
    handlers mark these functions as ready to be executed and the event
    loop, in a later iteration, calls them. See the function
    invoke_async_signal_handler. */
-async_signal_handler *sigint_token;
+PTR sigint_token;
 #ifdef SIGHUP
-async_signal_handler *sighup_token;
+PTR sighup_token;
 #endif
-async_signal_handler *sigquit_token;
-async_signal_handler *sigfpe_token;
+PTR sigquit_token;
+PTR sigfpe_token;
 #if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-async_signal_handler *sigwinch_token;
+PTR sigwinch_token;
+#endif
+#ifdef STOP_SIGNAL
+PTR sigtstp_token;
 #endif
 
 /* Structure to save a partially entered command.  This is used when
@@ -157,60 +157,43 @@ struct readline_input_state
 readline_input_state;
 \f
 
+/* Wrapper function foe calling into the readline library. The event
+   loop expects the callback function to have a paramter, while readline 
+   expects none. */
+static void
+rl_callback_read_char_wrapper (gdb_client_data client_data)
+{
+  rl_callback_read_char ();
+}
+
 /* Initialize all the necessary variables, start the event loop,
-   register readline, and stdin. */
+   register readline, and stdin, start the loop. */
 void
-setup_event_loop ()
+cli_command_loop (void)
 {
-  int length = strlen (PREFIX (0)) + strlen (PROMPT (0)) + strlen (SUFFIX (0)) + 1;
-  char *a_prompt = (char *) xmalloc (length);
-
-  /* Set things up for readline to be invoked via the alternate
-     interface, i.e. via a callback function (rl_callback_read_char). */
-  call_readline = rl_callback_read_char;
-
-  /* When readline has read an end-of-line character, it passes the
-     complete line to gdb for processing. command_line_handler is the
-     function that does this. */
-  input_handler = command_line_handler;
-
-  /* Tell readline what the prompt to display is and what function it
-     will need to call after a whole line is read. */
-  strcpy (a_prompt, PREFIX (0));
-  strcat (a_prompt, PROMPT (0));
-  strcat (a_prompt, SUFFIX (0));
-  rl_callback_handler_install (a_prompt, input_handler);
-
-  /* Tell readline to use the same input stream that gdb uses. */
-  rl_instream = instream;
-  /* Get a file descriptor for the input stream, so that we can
-     register it with the event loop. */
-  input_fd = fileno (instream);
-
-  /* Now we need to create the event sources for the input file descriptor. */
-  /* At this point in time, this is the only event source that we
-     register with the even loop. Another source is going to be the
-     target program (inferior), but that must be registered only when
-     it actually exists (I.e. after we say 'run' or after we connect
-     to a remote target. */
-#ifdef HAVE_POLL
-  create_file_handler (input_fd, POLLIN,
-                      (file_handler_func *) call_readline, 0);
-#else
-  create_file_handler (input_fd, GDB_READABLE,
-                      (file_handler_func *) call_readline, 0);
-#endif
+  int length;
+  char *a_prompt;
+  char *gdb_prompt = get_prompt ();
 
-  /* Loop until there is something to do. This is the entry point to
-     the event loop engine. gdb_do_one_event will process one event
-     for each invocation.  It always returns 1, unless there are no
-     more event sources registered. In this case it returns 0.  */
-  while (gdb_do_one_event () != 0)
-    ;
+  /* If we are using readline, set things up and display the first
+     prompt, otherwise just print the prompt. */
+  if (async_command_editing_p)
+    {
+      /* Tell readline what the prompt to display is and what function it
+         will need to call after a whole line is read. This also displays
+         the first prompt. */
+      length = strlen (PREFIX (0)) + strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1;
+      a_prompt = (char *) xmalloc (length);
+      strcpy (a_prompt, PREFIX (0));
+      strcat (a_prompt, gdb_prompt);
+      strcat (a_prompt, SUFFIX (0));
+      rl_callback_handler_install (a_prompt, input_handler);
+    }
+  else
+    display_gdb_prompt (0);
 
-  /* We are done with the event loop. There are no more event sources
-     to listen to.  So we exit GDB. */
-  return;
+  /* Now it's time to start the event loop. */
+  start_event_loop ();
 }
 
 /* Change the function to be invoked every time there is a character
@@ -219,64 +202,90 @@ setup_event_loop ()
    itself, via gdb_readline2. Also it is used in the opposite case in
    which the user sets editing on again, by restoring readline
    handling of the input. */
-void
-change_line_handler ()
+static void
+change_line_handler (void)
 {
+  /* NOTE: this operates on input_fd, not instream. If we are reading
+     commands from a file, instream will point to the file. However in
+     async mode, we always read commands from a file with editing
+     off. This means that the 'set editing on/off' will have effect
+     only on the interactive session. */
+
   if (async_command_editing_p)
     {
       /* Turn on editing by using readline. */
-      call_readline = rl_callback_read_char;
+      call_readline = rl_callback_read_char_wrapper;
+      input_handler = command_line_handler;
     }
   else
     {
       /* Turn off editing by using gdb_readline2. */
       rl_callback_handler_remove ();
       call_readline = gdb_readline2;
-    }
 
-  /* To tell the event loop to change the handler associated with the
-     input file descriptor, we need to create a new event source,
-     corresponding to the same fd, but with a new event handler
-     function. */
-  delete_file_handler (input_fd);
-#ifdef HAVE_POLL
-  create_file_handler (input_fd, POLLIN,
-                      (file_handler_func *) call_readline, 0);
-#else
-  create_file_handler (input_fd, GDB_READABLE,
-                      (file_handler_func *) call_readline, 0);
-#endif
+      /* Set up the command handler as well, in case we are called as
+         first thing from .gdbinit. */
+      input_handler = command_line_handler;
+    }
 }
 
 /* Displays the prompt. The prompt that is displayed is the current
    top of the prompt stack, if the argument NEW_PROMPT is
    0. Otherwise, it displays whatever NEW_PROMPT is. This is used
    after each gdb command has completed, and in the following cases:
-   1. when the user enters a command line which is ended by '\' 
-   indicating that the command will continue on the next line. 
+   1. when the user enters a command line which is ended by '\'
+   indicating that the command will continue on the next line.
    In that case the prompt that is displayed is the empty string.
-   2. When the user is entering 'commands' for a breakpoint, or 
-   actions for a tracepoint. In this case the prompt will be '>' 
-   3. Other???? 
+   2. When the user is entering 'commands' for a breakpoint, or
+   actions for a tracepoint. In this case the prompt will be '>'
+   3. Other????
    FIXME: 2. & 3. not implemented yet for async. */
 void
-display_gdb_prompt (new_prompt)
-     char *new_prompt;
+display_gdb_prompt (char *new_prompt)
 {
   int prompt_length = 0;
+  char *gdb_prompt = get_prompt ();
+
+#ifdef UI_OUT
+  /* When an alternative interpreter has been installed, do not
+     display the comand prompt. */
+  if (interpreter_p)
+    return;
+#endif
+
+  if (target_executing && sync_execution)
+    {
+      /* This is to trick readline into not trying to display the
+         prompt.  Even though we display the prompt using this
+         function, readline still tries to do its own display if we
+         don't call rl_callback_handler_install and
+         rl_callback_handler_remove (which readline detects because a
+         global variable is not set). If readline did that, it could
+         mess up gdb signal handlers for SIGINT.  Readline assumes
+         that between calls to rl_set_signals and rl_clear_signals gdb
+         doesn't do anything with the signal handlers. Well, that's
+         not the case, because when the target executes we change the
+         SIGINT signal handler. If we allowed readline to display the
+         prompt, the signal handler change would happen exactly
+         between the calls to the above two functions.
+         Calling rl_callback_handler_remove(), does the job. */
+
+      rl_callback_handler_remove ();
+      return;
+    }
 
   if (!new_prompt)
     {
       /* Just use the top of the prompt stack. */
       prompt_length = strlen (PREFIX (0)) +
        strlen (SUFFIX (0)) +
-       strlen (PROMPT (0)) + 1;
+       strlen (gdb_prompt) + 1;
 
       new_prompt = (char *) alloca (prompt_length);
 
       /* Prefix needs to have new line at end. */
       strcpy (new_prompt, PREFIX (0));
-      strcat (new_prompt, PROMPT (0));
+      strcat (new_prompt, gdb_prompt);
       /* Suffix needs to have a new line at end and \032 \032 at
          beginning. */
       strcat (new_prompt, SUFFIX (0));
@@ -287,6 +296,7 @@ display_gdb_prompt (new_prompt)
       rl_callback_handler_remove ();
       rl_callback_handler_install (new_prompt, input_handler);
     }
+  /* new_prompt at this point can be the top of the stack or the one passed in */
   else if (new_prompt)
     {
       /* Don't use a _filtered function here.  It causes the assumed
@@ -307,9 +317,9 @@ display_gdb_prompt (new_prompt)
    'set annotate'. It pushes a new prompt (with prefix and suffix) on top
    of the prompt stack, if the annotation level desired is 2, otherwise
    it pops the top of the prompt stack when we want the annotation level
-   to be the normal ones (1 or 2). */
-void
-change_annotation_level ()
+   to be the normal ones (1 or 0). */
+static void
+change_annotation_level (void)
 {
   char *prefix, *suffix;
 
@@ -353,15 +363,15 @@ change_annotation_level ()
    parts: prefix, prompt, suffix. Usually prefix and suffix are empty
    strings, except when the annotation level is 2. Memory is allocated
    within savestring for the new prompt. */
-static void
-push_prompt (prefix, prompt, suffix)
-     char *prefix;
-     char *prompt;
-     char *suffix;
+void
+push_prompt (char *prefix, char *prompt, char *suffix)
 {
   the_prompts.top++;
   PREFIX (0) = savestring (prefix, strlen (prefix));
 
+  /* Note that this function is used by the set annotate 2
+     command. This is why we take care of saving the old prompt
+     in case a new one is not specified. */
   if (prompt)
     PROMPT (0) = savestring (prompt, strlen (prompt));
   else
@@ -371,33 +381,98 @@ push_prompt (prefix, prompt, suffix)
 }
 
 /* Pops the top of the prompt stack, and frees the memory allocated for it. */
-static void
-pop_prompt ()
+void
+pop_prompt (void)
 {
-  if (strcmp (PROMPT (0), PROMPT (-1)))
-    {
-      free (PROMPT (-1));
-      PROMPT (-1) = savestring (PROMPT (0), strlen (PROMPT (0)));
-    }
+  /* If we are not during a 'synchronous' execution command, in which
+     case, the top prompt would be empty. */
+  if (strcmp (PROMPT (0), ""))
+    /* This is for the case in which the prompt is set while the
+       annotation level is 2. The top prompt will be changed, but when
+       we return to annotation level < 2, we want that new prompt to be
+       in effect, until the user does another 'set prompt'. */
+    if (strcmp (PROMPT (0), PROMPT (-1)))
+      {
+       free (PROMPT (-1));
+       PROMPT (-1) = savestring (PROMPT (0), strlen (PROMPT (0)));
+      }
 
   free (PREFIX (0));
   free (PROMPT (0));
   free (SUFFIX (0));
   the_prompts.top--;
 }
+
+/* When there is an event ready on the stdin file desriptor, instead
+   of calling readline directly throught the callback function, or
+   instead of calling gdb_readline2, give gdb a chance to detect
+   errors and do something. */
+void
+stdin_event_handler (int error, gdb_client_data client_data)
+{
+  if (error)
+    {
+      printf_unfiltered ("error detected on stdin\n");
+      delete_file_handler (input_fd);
+      discard_all_continuations ();
+      /* If stdin died, we may as well kill gdb. */
+      quit_command ((char *) 0, stdin == instream);
+    }
+  else
+    (*call_readline) (client_data);
+}
+
+/* Re-enable stdin after the end of an execution command in
+   synchronous mode, or after an error from the target, and we aborted
+   the exec operation. */
+
+void
+async_enable_stdin (void *dummy)
+{
+  /* See NOTE in async_disable_stdin() */
+  /* FIXME: cagney/1999-09-27: Call this before clearing
+     sync_execution.  Current target_terminal_ours() implementations
+     check for sync_execution before switching the terminal. */
+  target_terminal_ours ();
+  pop_prompt ();
+  sync_execution = 0;
+}
+
+/* Disable reads from stdin (the console) marking the command as
+   synchronous. */
+
+void
+async_disable_stdin (void)
+{
+  sync_execution = 1;
+  push_prompt ("", "", "");
+  /* FIXME: cagney/1999-09-27: At present this call is technically
+     redundant since infcmd.c and infrun.c both already call
+     target_terminal_inferior().  As the terminal handling (in
+     sync/async mode) is refined, the duplicate calls can be
+     eliminated (Here or in infcmd.c/infrun.c). */
+  target_terminal_inferior ();
+  /* Add the reinstate of stdin to the list of cleanups to be done
+     in case the target errors out and dies. These cleanups are also
+     done in case of normal successful termination of the execution
+     command, by complete_execution(). */
+  make_exec_error_cleanup (async_enable_stdin, NULL);
+}
 \f
+
 /* Handles a gdb command. This function is called by
    command_line_handler, which has processed one or more input lines
    into COMMAND. */
-/* NOTE: 4/30/99 This is the asynchronous version of the command_loop
+/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop
    function.  The command_loop function will be obsolete when we
    switch to use the event loop at every execution of gdb. */
-void
-command_handler (command)
-     char *command;
+static void
+command_handler (char *command)
 {
   struct cleanup *old_chain;
   int stdin_is_tty = ISATTY (stdin);
+  struct continuation_arg *arg1;
+  struct continuation_arg *arg2;
   long time_at_cmd_start;
 #ifdef HAVE_SBRK
   long space_at_cmd_start = 0;
@@ -439,9 +514,69 @@ command_handler (command)
 
   execute_command (command, instream == stdin);
 
-  /* Do any commands attached to breakpoint we stopped at.  */
+  /* Set things up for this function to be compete later, once the
+     executin has completed, if we are doing an execution command,
+     otherwise, just go ahead and finish. */
+  if (target_can_async_p () && target_executing)
+    {
+      arg1 =
+       (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+      arg2 =
+       (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+      arg1->next = arg2;
+      arg2->next = NULL;
+      arg1->data = (PTR) time_at_cmd_start;
+      arg2->data = (PTR) space_at_cmd_start;
+      add_continuation (command_line_handler_continuation, arg1);
+    }
+
+  /* Do any commands attached to breakpoint we stopped at. Only if we
+     are always running synchronously. Or if we have just executed a
+     command that doesn't start the target. */
+  if (!target_can_async_p () || !target_executing)
+    {
+      bpstat_do_actions (&stop_bpstat);
+      do_cleanups (old_chain);
+
+      if (display_time)
+       {
+         long cmd_time = get_run_time () - time_at_cmd_start;
+
+         printf_unfiltered ("Command execution time: %ld.%06ld\n",
+                            cmd_time / 1000000, cmd_time % 1000000);
+       }
+
+      if (display_space)
+       {
+#ifdef HAVE_SBRK
+         extern char **environ;
+         char *lim = (char *) sbrk (0);
+         long space_now = lim - (char *) &environ;
+         long space_diff = space_now - space_at_cmd_start;
+
+         printf_unfiltered ("Space used: %ld (%c%ld for this command)\n",
+                            space_now,
+                            (space_diff >= 0 ? '+' : '-'),
+                            space_diff);
+#endif
+       }
+    }
+}
+
+/* Do any commands attached to breakpoint we stopped at. Only if we
+   are always running synchronously. Or if we have just executed a
+   command that doesn't start the target. */
+void
+command_line_handler_continuation (struct continuation_arg *arg)
+{
+  extern int display_time;
+  extern int display_space;
+
+  long time_at_cmd_start = (long) arg->data;
+  long space_at_cmd_start = (long) arg->next->data;
+
   bpstat_do_actions (&stop_bpstat);
-  do_cleanups (old_chain);
+  /*do_cleanups (old_chain); *//*?????FIXME????? */
 
   if (display_time)
     {
@@ -450,7 +585,6 @@ command_handler (command)
       printf_unfiltered ("Command execution time: %ld.%06ld\n",
                         cmd_time / 1000000, cmd_time % 1000000);
     }
-
   if (display_space)
     {
 #ifdef HAVE_SBRK
@@ -471,19 +605,17 @@ command_handler (command)
    mechanism within the readline library.  Deal with incomplete commands
    as well, by saving the partial input in a global buffer.  */
 
-/* NOTE: 4/30/99 This is the asynchronous version of the
+/* NOTE: 1999-04-30 This is the asynchronous version of the
    command_line_input function. command_line_input will become
    obsolete once we use the event loop as the default mechanism in
    GDB. */
 static void
-command_line_handler (rl)
-     char *rl;
+command_line_handler (char *rl)
 {
   static char *linebuffer = 0;
   static unsigned linelength = 0;
   register char *p;
   char *p1;
-  int change_prompt = 0;
   extern char *line;
   extern int linesize;
   char *nline;
@@ -513,12 +645,12 @@ command_line_handler (rl)
       p = readline_input_state.linebuffer_ptr;
       free (readline_input_state.linebuffer);
       more_to_come = 0;
-      change_prompt = 1;
+      pop_prompt ();
     }
 
 #ifdef STOP_SIGNAL
   if (job_control)
-    signal (STOP_SIGNAL, stop_sig);
+    signal (STOP_SIGNAL, handle_stop_sig);
 #endif
 
   /* Make sure that all output has been output.  Some machines may let
@@ -560,9 +692,8 @@ command_line_handler (rl)
 
   free (rl);                   /* Allocated in readline.  */
 
-  if (p == linebuffer || *(p - 1) == '\\')
+  if (*(p - 1) == '\\')
     {
-      /* We come here also if the line entered is empty (just a 'return') */
       p--;                     /* Put on top of '\'.  */
 
       if (*p == '\\')
@@ -574,8 +705,10 @@ command_line_handler (rl)
          /* We will not invoke a execute_command if there is more
             input expected to complete the command. So, we need to
             print an empty prompt here. */
-         display_gdb_prompt ("");
          more_to_come = 1;
+         push_prompt ("", "", "");
+         display_gdb_prompt (0);
+         return;
        }
     }
 
@@ -689,16 +822,29 @@ command_line_handler (rl)
 /* Does reading of input from terminal w/o the editing features
    provided by the readline library. */
 
-/* NOTE: 4/30/99 Asynchronous version of gdb_readline. gdb_readline
+/* NOTE: 1999-04-30 Asynchronous version of gdb_readline. gdb_readline
    will become obsolete when the event loop is made the default
    execution for gdb. */
-static void
-gdb_readline2 ()
+void
+gdb_readline2 (gdb_client_data client_data)
 {
   int c;
   char *result;
   int input_index = 0;
   int result_size = 80;
+  static int done_once = 0;
+
+  /* Unbuffer the input stream, so that, later on, the calls to fgetc
+     fetch only one char at the time from the stream. The fgetc's will
+     get up to the first newline, but there may be more chars in the
+     stream after '\n'. If we buffer the input and fgetc drains the
+     stream, getting stuff beyond the newline as well, a select, done
+     afterwards will not trigger. */
+  if (!done_once && !ISATTY (instream))
+    {
+      setbuf (instream, NULL);
+      done_once = 1;
+    }
 
   result = (char *) xmalloc (result_size);
 
@@ -723,7 +869,7 @@ gdb_readline2 ()
               we'll return NULL then.  */
            break;
          free (result);
-         command_line_handler (0);
+         (*input_handler) (0);
        }
 
       if (c == '\n')
@@ -746,7 +892,7 @@ gdb_readline2 ()
     }
 
   result[input_index++] = '\0';
-  command_line_handler (result);
+  (*input_handler) (result);
 }
 \f
 
@@ -759,15 +905,15 @@ gdb_readline2 ()
    procedures are the old signal handlers. The event loop will take
    care of invoking the queued procedures to perform the usual tasks
    associated with the reception of the signal. */
-/* NOTE: 4/30/99 This is the asynchronous version of init_signals.
+/* NOTE: 1999-04-30 This is the asynchronous version of init_signals.
    init_signals will become obsolete as we move to have to event loop
    as the default for gdb. */
 void
-async_init_signals ()
+async_init_signals (void)
 {
   signal (SIGINT, handle_sigint);
   sigint_token =
-    create_async_signal_handler ((async_handler_func *) async_request_quit, NULL);
+    create_async_signal_handler (async_request_quit, NULL);
 
   /* If SIGTRAP was set to SIG_IGN, then the SIG_IGN will get passed
      to the inferior and breakpoints will be ignored.  */
@@ -785,31 +931,41 @@ async_init_signals ()
      to SIG_DFL for us.  */
   signal (SIGQUIT, handle_sigquit);
   sigquit_token =
-    create_async_signal_handler ((async_handler_func *) async_do_nothing, NULL);
+    create_async_signal_handler (async_do_nothing, NULL);
 #ifdef SIGHUP
   if (signal (SIGHUP, handle_sighup) != SIG_IGN)
     sighup_token =
-      create_async_signal_handler ((async_handler_func *) async_disconnect, NULL);
+      create_async_signal_handler (async_disconnect, NULL);
   else
     sighup_token =
-      create_async_signal_handler ((async_handler_func *) async_do_nothing, NULL);
+      create_async_signal_handler (async_do_nothing, NULL);
 #endif
   signal (SIGFPE, handle_sigfpe);
   sigfpe_token =
-    create_async_signal_handler ((async_handler_func *) async_float_handler, NULL);
+    create_async_signal_handler (async_float_handler, NULL);
 
 #if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
   signal (SIGWINCH, handle_sigwinch);
   sigwinch_token =
-    create_async_signal_handler ((async_handler_func *) SIGWINCH_HANDLER, NULL);
+    create_async_signal_handler (SIGWINCH_HANDLER, NULL);
+#endif
+#ifdef STOP_SIGNAL
+  sigtstp_token =
+    create_async_signal_handler (async_stop_sig, NULL);
 #endif
+
+}
+
+void
+mark_async_signal_handler_wrapper (PTR token)
+{
+  mark_async_signal_handler ((struct async_signal_handler *) token);
 }
 
 /* Tell the event loop what to do if SIGINT is received. 
    See event-signal.c. */
-void 
-handle_sigint (sig)
-     int sig;
+void
+handle_sigint (int sig)
 {
   signal (sig, handle_sigint);
 
@@ -821,16 +977,16 @@ handle_sigint (sig)
      that point, though, the command that we want to interrupt needs to
      finish first, which is unacceptable. */
   if (immediate_quit)
-    async_request_quit ();
+    async_request_quit (0);
   else
     /* If immediate quit is not set, we process SIGINT the next time
        through the loop, which is fine. */
-    mark_async_signal_handler (sigint_token);
+    mark_async_signal_handler_wrapper (sigint_token);
 }
 
 /* Do the quit. All the checks have been done by the caller. */
-void 
-async_request_quit ()
+void
+async_request_quit (gdb_client_data arg)
 {
   quit_flag = 1;
 #ifdef REQUEST_QUIT
@@ -842,17 +998,16 @@ async_request_quit ()
 
 /* Tell the event loop what to do if SIGQUIT is received. 
    See event-signal.c. */
-void 
-handle_sigquit (sig)
-     int sig;
+static void
+handle_sigquit (int sig)
 {
-  mark_async_signal_handler (sigquit_token);
+  mark_async_signal_handler_wrapper (sigquit_token);
   signal (sig, handle_sigquit);
 }
 
 /* Called by the event loop in response to a SIGQUIT. */
-void 
-async_do_nothing ()
+static void
+async_do_nothing (gdb_client_data arg)
 {
   /* Empty function body. */
 }
@@ -860,17 +1015,17 @@ async_do_nothing ()
 #ifdef SIGHUP
 /* Tell the event loop what to do if SIGHUP is received. 
    See event-signal.c. */
-void 
+static void
 handle_sighup (sig)
      int sig;
 {
-  mark_async_signal_handler (sighup_token);
+  mark_async_signal_handler_wrapper (sighup_token);
   signal (sig, handle_sighup);
 }
 
-/* Called by the event loop to process a SIGHUP. */
-void 
-async_disconnect ()
+/* Called by the event loop to process a SIGHUP */
+static void
+async_disconnect (gdb_client_data arg)
 {
   catch_errors (quit_cover, NULL,
                "Could not kill the program being debugged",
@@ -880,19 +1035,54 @@ async_disconnect ()
 }
 #endif
 
+#ifdef STOP_SIGNAL
+void
+handle_stop_sig (int sig)
+{
+  mark_async_signal_handler_wrapper (sigtstp_token);
+  signal (sig, handle_stop_sig);
+}
+
+static void
+async_stop_sig (gdb_client_data arg)
+{
+  char *prompt = get_prompt ();
+#if STOP_SIGNAL == SIGTSTP
+  signal (SIGTSTP, SIG_DFL);
+#if HAVE_SIGPROCMASK
+  {
+    sigset_t zero;
+    sigemptyset (&zero);
+    sigprocmask (SIG_SETMASK, &zero, 0);
+  }
+#else
+  sigsetmask (0);
+#endif
+  kill (getpid (), SIGTSTP);
+  signal (SIGTSTP, handle_stop_sig);
+#else
+  signal (STOP_SIGNAL, handle_stop_sig);
+#endif
+  printf_unfiltered ("%s", prompt);
+  gdb_flush (gdb_stdout);
+
+  /* Forget about any previous command -- null line now will do nothing.  */
+  dont_repeat ();
+}
+#endif /* STOP_SIGNAL */
+
 /* Tell the event loop what to do if SIGFPE is received. 
    See event-signal.c. */
-void 
-handle_sigfpe (sig)
-     int sig;
+static void
+handle_sigfpe (int sig)
 {
-  mark_async_signal_handler (sigfpe_token);
+  mark_async_signal_handler_wrapper (sigfpe_token);
   signal (sig, handle_sigfpe);
 }
 
 /* Event loop will call this functin to process a SIGFPE. */
-void 
-async_float_handler ()
+static void
+async_float_handler (gdb_client_data arg)
 {
   /* This message is based on ANSI C, section 4.7. Note that integer
      divide by zero causes this, so "float" is a misnomer. */
@@ -902,11 +1092,10 @@ async_float_handler ()
 /* Tell the event loop what to do if SIGWINCH is received. 
    See event-signal.c. */
 #if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-void 
-handle_sigwinch (sig)
-     int sig;
+static void
+handle_sigwinch (int sig)
 {
-  mark_async_signal_handler (sigwinch_token);
+  mark_async_signal_handler_wrapper (sigwinch_token);
   signal (sig, handle_sigwinch);
 }
 #endif
@@ -915,10 +1104,7 @@ handle_sigwinch (sig)
 /* Called by do_setshow_command.  */
 /* ARGSUSED */
 void
-set_async_editing_command (args, from_tty, c)
-     char *args;
-     int from_tty;
-     struct cmd_list_element *c;
+set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c)
 {
   change_line_handler ();
 }
@@ -926,10 +1112,7 @@ set_async_editing_command (args, from_tty, c)
 /* Called by do_setshow_command.  */
 /* ARGSUSED */
 void
-set_async_annotation_level (args, from_tty, c)
-     char *args;
-     int from_tty;
-     struct cmd_list_element *c;
+set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c)
 {
   change_annotation_level ();
 }
@@ -937,14 +1120,50 @@ set_async_annotation_level (args, from_tty, c)
 /* Called by do_setshow_command.  */
 /* ARGSUSED */
 void
-set_async_prompt (args, from_tty, c)
-     char *args;
-     int from_tty;
-     struct cmd_list_element *c;
+set_async_prompt (char *args, int from_tty, struct cmd_list_element *c)
 {
   PROMPT (0) = savestring (new_async_prompt, strlen (new_async_prompt));
 }
 
-
-
-
+/* Set things up for readline to be invoked via the alternate
+   interface, i.e. via a callback function (rl_callback_read_char),
+   and hook up instream to the event loop. */
+void
+_initialize_event_loop (void)
+{
+  if (event_loop_p)
+    {
+      /* When a character is detected on instream by select or poll,
+         readline will be invoked via this callback function. */
+      call_readline = rl_callback_read_char_wrapper;
+
+      /* When readline has read an end-of-line character, it passes
+         the complete line to gdb for processing. command_line_handler
+         is the function that does this. */
+      input_handler = command_line_handler;
+
+      /* Tell readline to use the same input stream that gdb uses. */
+      rl_instream = instream;
+
+      /* Get a file descriptor for the input stream, so that we can
+         register it with the event loop. */
+      input_fd = fileno (instream);
+
+      /* Tell gdb to use the cli_command_loop as the main loop. */
+      command_loop_hook = cli_command_loop;
+
+      /* Now we need to create the event sources for the input file
+         descriptor. */
+      /* At this point in time, this is the only event source that we
+         register with the even loop. Another source is going to be
+         the target program (inferior), but that must be registered
+         only when it actually exists (I.e. after we say 'run' or
+         after we connect to a remote target. */
+      add_file_handler (input_fd, stdin_event_handler, 0);
+
+      /* Tell gdb that we will be using the readline library. This
+         could be overwritten by a command in .gdbinit like 'set
+         editing on' or 'off'. */
+      async_command_editing_p = 1;
+    }
+}
index 078e957..2a3a1c8 100644 (file)
@@ -3223,6 +3223,13 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
     case END_STEPPING_RANGE:
       /* We are done with a step/next/si/ni command. */
       /* For now print nothing. */
+#ifdef UI_OUT
+      /* Print a message only if not in the middle of doing a "step n"
+        operation for n > 1 */
+      if (!step_multi || !stop_step)
+       if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+         ui_out_field_string (uiout, "reason", "end-stepping-range");
+#endif
       break;
     case BREAKPOINT_HIT:
       /* We found a breakpoint. */
@@ -3232,6 +3239,8 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
       /* The inferior was terminated by a signal. */
 #ifdef UI_OUT
       annotate_signalled ();
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "exited-signalled");
       ui_out_text (uiout, "\nProgram terminated with signal ");
       annotate_signal_name ();
       ui_out_field_string (uiout, "signal-name", target_signal_to_name (stop_info));
@@ -3264,12 +3273,16 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
       annotate_exited (stop_info);
       if (stop_info)
        {
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_field_string (uiout, "reason", "exited");
          ui_out_text (uiout, "\nProgram exited with code ");
          ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) stop_info);
          ui_out_text (uiout, ".\n");
        }
       else
        {
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_field_string (uiout, "reason", "exited-normally");
          ui_out_text (uiout, "\nProgram exited normally.\n");
        }
 #else
@@ -3445,7 +3458,17 @@ The same program may be running in another process.\n");
            default:
              internal_error ("Unknown value.");
            }
+#ifdef UI_OUT
+         /* For mi, have the same behavior every time we stop:
+             print everything but the source line. */
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           source_flag = LOC_AND_ADDRESS;
+#endif
 
+#ifdef UI_OUT
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_field_int (uiout, "thread-id", pid_to_thread_id (inferior_pid));
+#endif
          /* The behavior of this routine with respect to the source
             flag is:
             SRC_LINE: Print only source line
index 18c2445..9f845a8 100644 (file)
@@ -1,25 +1,24 @@
 /* Top level stuff for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
-   Free Software Foundation, Inc.
+   Copyright 1986-1995, 1999-2000 Free Software Foundation, Inc.
 
-This file is part of GDB.
+   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 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.
+   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.  */
+   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 <setjmp.h>
 #include "top.h"
 #include "target.h"
 #include "inferior.h"
@@ -32,19 +31,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <ctype.h>
 
 #include "gdb_string.h"
-
-/* Temporary variable for SET_TOP_LEVEL.  */
-
-static int top_level_val;
-
-/* Do a setjmp on error_return and quit_return.  catch_errors is
-   generally a cleaner way to do this, but main() would look pretty
-   ugly if it had to use catch_errors each time.  */
-
-#define SET_TOP_LEVEL() \
-  (((top_level_val = SIGSETJMP (error_return)) \
-    ? (PTR) 0 : (PTR) memcpy (quit_return, error_return, sizeof (SIGJMP_BUF))) \
-   , top_level_val)
+#include "event-loop.h"
+#include "ui-out.h"
+#if defined (TUI) || defined (GDBTK)
+/* FIXME: cagney/2000-01-31: This #include is to allow older code such
+   as that found in the TUI to continue to build. */
+#include "tui/tui-file.h"
+#endif
 
 /* If nonzero, display time usage both at startup and for each command.  */
 
@@ -54,6 +47,17 @@ int display_time;
 
 int display_space;
 
+/* Whether this is the async version or not.  The async version is
+   invoked on the command line with the -nw --async options.  In this
+   version, the usual command_loop is substituted by and event loop which
+   processes UI events asynchronously. */
+int event_loop_p = 1;
+
+#ifdef UI_OUT
+/* Has an interpreter been specified and if so, which. */
+char *interpreter_p;
+#endif
+
 /* Whether this is the command line version or not */
 int tui_version = 0;
 
@@ -63,31 +67,69 @@ int xdb_commands = 0;
 /* Whether dbx commands will be handled */
 int dbx_commands = 0;
 
-GDB_FILE *gdb_stdout;
-GDB_FILE *gdb_stderr;
+struct ui_file *gdb_stdout;
+struct ui_file *gdb_stderr;
+struct ui_file *gdb_stdlog;
+struct ui_file *gdb_stdtarg;
+
+/* Used to initialize error() - defined in utils.c */
+
+extern void error_init (void);
 
 /* Whether to enable writing into executable and core files */
 extern int write_files;
 
-static void print_gdb_help PARAMS ((GDB_FILE *));
-extern void gdb_init PARAMS ((char *));
+static void print_gdb_help (struct ui_file *);
 
 /* These two are used to set the external editor commands when gdb is farming
    out files to be edited by another program. */
 
 extern int enable_external_editor;
-extern char * external_editor_command;
+extern char *external_editor_command;
 
 #ifdef __CYGWIN__
-#include <windows.h> /* for MAX_PATH */
-#include <sys/cygwin.h> /* for cygwin32_conv_to_posix_path */
+#include <windows.h>           /* for MAX_PATH */
+#include <sys/cygwin.h>                /* for cygwin32_conv_to_posix_path */
 #endif
 
-int
-main (argc, argv)
-     int argc;
-     char **argv;
+/* Call command_loop.  If it happens to return, pass that through as a
+   non-zero return status. */
+
+static int
+captured_command_loop (void *data)
 {
+  if (command_loop_hook == NULL)
+    command_loop ();
+  else
+    command_loop_hook ();
+  /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton
+     would clean things up (restoring the cleanup chain) to the state
+     they were just prior to the call.  Technically, this means that
+     the do_cleanups() below is redundant.  Unfortunatly, many FUNC's
+     are not that well behaved.  do_cleanups should either be replaced
+     with a do_cleanups call (to cover the problem) or an assertion
+     check to detect bad FUNCs code. */
+  do_cleanups (ALL_CLEANUPS);
+  /* If the command_loop returned, normally (rather than threw an
+     error) we try to quit. If the quit is aborted, catch_errors()
+     which called this catch the signal and restart the command
+     loop. */
+  quit_command (NULL, instream == stdin);
+  return 1;
+}
+
+struct captured_main_args
+  {
+    int argc;
+    char **argv;
+  };
+
+static int
+captured_main (void *data)
+{
+  struct captured_main_args *context = data;
+  int argc = context->argc;
+  char **argv = context->argv;
   int count;
   static int quiet = 0;
   static int batch = 0;
@@ -116,7 +158,7 @@ main (argc, argv)
   int dirsize;
   /* Number of elements used.  */
   int ndir;
-  
+
   struct stat homebuf, cwdbuf;
   char *homedir, *homeinit;
 
@@ -124,8 +166,6 @@ main (argc, argv)
 
   long time_at_startup = get_run_time ();
 
-  int gdb_file_size;
-
   START_PROGRESS (argv[0], 0);
 
 #ifdef MPW
@@ -142,11 +182,6 @@ main (argc, argv)
     alloca (4 - i);
 #endif
 
-  /* If error() is called from initialization code, just exit */
-  if (SET_TOP_LEVEL ()) {
-    exit(1);
-  }
-
   cmdsize = 1;
   cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg));
   ncmd = 0;
@@ -162,19 +197,23 @@ main (argc, argv)
   getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
   current_directory = gdb_dirbuf;
 
-  gdb_file_size = sizeof(GDB_FILE);
-
-  gdb_stdout = (GDB_FILE *)xmalloc (gdb_file_size);
-  gdb_stdout->ts_streamtype = afile;
-  gdb_stdout->ts_filestream = stdout;
-  gdb_stdout->ts_strbuf = NULL;
-  gdb_stdout->ts_buflen = 0;
+#if defined (TUI) || defined (GDBTK)
+  /* Older code uses the tui_file and fputs_unfiltered_hook().  It
+     should be using a customized UI_FILE object and re-initializing
+     within its own _initialize function.  */
+  gdb_stdout = tui_fileopen (stdout);
+  gdb_stderr = tui_fileopen (stderr);
+  gdb_stdlog = gdb_stdout;     /* for moment */
+  gdb_stdtarg = gdb_stderr;    /* for moment */
+#else
+  gdb_stdout = stdio_fileopen (stdout);
+  gdb_stderr = stdio_fileopen (stderr);
+  gdb_stdlog = gdb_stderr;     /* for moment */
+  gdb_stdtarg = gdb_stderr;    /* for moment */
+#endif
 
-  gdb_stderr = (GDB_FILE *)xmalloc (gdb_file_size);
-  gdb_stderr->ts_streamtype = afile;
-  gdb_stderr->ts_filestream = stderr;
-  gdb_stderr->ts_strbuf = NULL;
-  gdb_stderr->ts_buflen = 0;
+  /* initialize error() */
+  error_init ();
 
   /* Parse arguments and options.  */
   {
@@ -183,59 +222,72 @@ main (argc, argv)
        short option (or arbitrary numbers starting at 10 for those
        with no equivalent).  */
     static struct option long_options[] =
-      {
+    {
+      {"async", no_argument, &event_loop_p, 1},
+      {"noasync", no_argument, &event_loop_p, 0},
 #if defined(TUI)
-       {"tui", no_argument, &tui_version, 1},
+      {"tui", no_argument, &tui_version, 1},
+#endif
+      {"xdb", no_argument, &xdb_commands, 1},
+      {"dbx", no_argument, &dbx_commands, 1},
+      {"readnow", no_argument, &readnow_symbol_files, 1},
+      {"r", no_argument, &readnow_symbol_files, 1},
+      {"mapped", no_argument, &mapped_symbol_files, 1},
+      {"m", no_argument, &mapped_symbol_files, 1},
+      {"quiet", no_argument, &quiet, 1},
+      {"q", no_argument, &quiet, 1},
+      {"silent", no_argument, &quiet, 1},
+      {"nx", no_argument, &inhibit_gdbinit, 1},
+      {"n", no_argument, &inhibit_gdbinit, 1},
+      {"batch", no_argument, &batch, 1},
+      {"epoch", no_argument, &epoch_interface, 1},
+
+    /* This is a synonym for "--annotate=1".  --annotate is now preferred,
+       but keep this here for a long time because people will be running
+       emacses which use --fullname.  */
+      {"fullname", no_argument, 0, 'f'},
+      {"f", no_argument, 0, 'f'},
+
+      {"annotate", required_argument, 0, 12},
+      {"help", no_argument, &print_help, 1},
+      {"se", required_argument, 0, 10},
+      {"symbols", required_argument, 0, 's'},
+      {"s", required_argument, 0, 's'},
+      {"exec", required_argument, 0, 'e'},
+      {"e", required_argument, 0, 'e'},
+      {"core", required_argument, 0, 'c'},
+      {"c", required_argument, 0, 'c'},
+      {"command", required_argument, 0, 'x'},
+      {"version", no_argument, &print_version, 1},
+      {"x", required_argument, 0, 'x'},
+#ifdef GDBTK
+      {"tclcommand", required_argument, 0, 'z'},
+      {"enable-external-editor", no_argument, 0, 'y'},
+      {"editor-command", required_argument, 0, 'w'},
+#endif
+#ifdef UI_OUT
+      {"ui", required_argument, 0, 'i'},
+      {"interpreter", required_argument, 0, 'i'},
+      {"i", required_argument, 0, 'i'},
 #endif
-       {"xdb", no_argument, &xdb_commands, 1},
-       {"dbx", no_argument, &dbx_commands, 1},
-       {"readnow", no_argument, &readnow_symbol_files, 1},
-       {"r", no_argument, &readnow_symbol_files, 1},
-       {"mapped", no_argument, &mapped_symbol_files, 1},
-       {"m", no_argument, &mapped_symbol_files, 1},
-       {"quiet", no_argument, &quiet, 1},
-       {"q", no_argument, &quiet, 1},
-       {"silent", no_argument, &quiet, 1},
-       {"nx", no_argument, &inhibit_gdbinit, 1},
-       {"n", no_argument, &inhibit_gdbinit, 1},
-       {"batch", no_argument, &batch, 1},
-       {"epoch", no_argument, &epoch_interface, 1},
-
-       /* This is a synonym for "--annotate=1".  --annotate is now preferred,
-          but keep this here for a long time because people will be running
-          emacses which use --fullname.  */
-       {"fullname", no_argument, 0, 'f'},
-       {"f", no_argument, 0, 'f'},
-
-       {"annotate", required_argument, 0, 12},
-       {"help", no_argument, &print_help, 1},
-       {"se", required_argument, 0, 10},
-       {"symbols", required_argument, 0, 's'},
-       {"s", required_argument, 0, 's'},
-       {"exec", required_argument, 0, 'e'},
-       {"e", required_argument, 0, 'e'},
-       {"core", required_argument, 0, 'c'},
-       {"c", required_argument, 0, 'c'},
-       {"command", required_argument, 0, 'x'},
-       {"version", no_argument, &print_version, 1},
-       {"x", required_argument, 0, 'x'},
-       {"directory", required_argument, 0, 'd'},
-       {"cd", required_argument, 0, 11},
-       {"tty", required_argument, 0, 't'},
-       {"baud", required_argument, 0, 'b'},
-       {"b", required_argument, 0, 'b'},
-       {"nw", no_argument, &use_windows, 0},
-       {"nowindows", no_argument, &use_windows, 0},
-       {"w", no_argument, &use_windows, 1},
-       {"windows", no_argument, &use_windows, 1},
-       {"statistics", no_argument, 0, 13},
-       {"write", no_argument, &write_files, 1},
+      {"directory", required_argument, 0, 'd'},
+      {"d", required_argument, 0, 'd'},
+      {"cd", required_argument, 0, 11},
+      {"tty", required_argument, 0, 't'},
+      {"baud", required_argument, 0, 'b'},
+      {"b", required_argument, 0, 'b'},
+      {"nw", no_argument, &use_windows, 0},
+      {"nowindows", no_argument, &use_windows, 0},
+      {"w", no_argument, &use_windows, 1},
+      {"windows", no_argument, &use_windows, 1},
+      {"statistics", no_argument, 0, 13},
+      {"write", no_argument, &write_files, 1},
 /* Allow machine descriptions to add more options... */
 #ifdef ADDITIONAL_OPTIONS
-       ADDITIONAL_OPTIONS
+      ADDITIONAL_OPTIONS
 #endif
-       {0, no_argument, 0, 0}
-      };
+      {0, no_argument, 0, 0}
+    };
 
     while (1)
       {
@@ -290,16 +342,55 @@ main (argc, argv)
            if (ncmd >= cmdsize)
              {
                cmdsize *= 2;
-               cmdarg = (char **) xrealloc ((char *)cmdarg,
+               cmdarg = (char **) xrealloc ((char *) cmdarg,
                                             cmdsize * sizeof (*cmdarg));
              }
            break;
+#ifdef GDBTK
+         case 'z':
+           {
+             extern int gdbtk_test PARAMS ((char *));
+             if (!gdbtk_test (optarg))
+               {
+                 fprintf_unfiltered (gdb_stderr, "%s: unable to load tclcommand file \"%s\"",
+                                     argv[0], optarg);
+                 exit (1);
+               }
+             break;
+           }
+         case 'y':
+           {
+             /*
+              * This enables the edit/button in the main window, even
+              * when IDE_ENABLED is set to false. In this case you must
+              * use --tclcommand to specify a tcl/script to be called,
+              * Tcl/Variable to store the edit/command is:
+              * external_editor
+              */
+             enable_external_editor = 1;
+             break;
+           }
+         case 'w':
+           {
+             /*
+              * if editor command is enabled, both flags are set
+              */
+             enable_external_editor = 1;
+             external_editor_command = xstrdup (optarg);
+             break;
+           }
+#endif /* GDBTK */
+#ifdef UI_OUT
+         case 'i':
+           interpreter_p = optarg;
+           break;
+#endif
          case 'd':
            dirarg[ndir++] = optarg;
            if (ndir >= dirsize)
              {
                dirsize *= 2;
-               dirarg = (char **) xrealloc ((char *)dirarg,
+               dirarg = (char **) xrealloc ((char *) dirarg,
                                             dirsize * sizeof (*dirarg));
              }
            break;
@@ -318,7 +409,7 @@ main (argc, argv)
              if (i == 0 && p == optarg)
 
                /* Don't use *_filtered or warning() (which relies on
-                   current_target) until after initialize_all_files(). */
+                  current_target) until after initialize_all_files(). */
 
                fprintf_unfiltered
                  (gdb_stderr,
@@ -335,23 +426,23 @@ main (argc, argv)
              if (i == 0 && p == optarg)
 
                /* Don't use *_filtered or warning() (which relies on
-                   current_target) until after initialize_all_files(). */
+                  current_target) until after initialize_all_files(). */
 
                fprintf_unfiltered
                  (gdb_stderr,
-                  "warning: could not set timeout limit to `%s'.\n", optarg);
+                "warning: could not set timeout limit to `%s'.\n", optarg);
              else
                remote_timeout = i;
            }
            break;
 
 #ifdef ADDITIONAL_OPTION_CASES
-         ADDITIONAL_OPTION_CASES
+           ADDITIONAL_OPTION_CASES
 #endif
          case '?':
            fprintf_unfiltered (gdb_stderr,
-                    "Use `%s --help' for a complete list of options.\n",
-                    argv[0]);
+                       "Use `%s --help' for a complete list of options.\n",
+                               argv[0]);
            exit (1);
          }
       }
@@ -371,7 +462,7 @@ main (argc, argv)
        window system.  */
     if (tui_version)
       use_windows = 0;
-#endif      
+#endif
 
     /* OK, that's all the options.  The other arguments are filenames.  */
     count = 0;
@@ -387,8 +478,8 @@ main (argc, argv)
          break;
        case 3:
          fprintf_unfiltered (gdb_stderr,
-                  "Excess command line arguments ignored. (%s%s)\n",
-                  argv[optind], (optind == argc - 1) ? "" : " ...");
+                         "Excess command line arguments ignored. (%s%s)\n",
+                         argv[optind], (optind == argc - 1) ? "" : " ...");
          break;
        }
     if (batch)
@@ -396,9 +487,13 @@ main (argc, argv)
   }
 
 #if defined(TUI)
+  /* Should this be moved to tui-top.c:_initialize_tui()? */
   if (tui_version)
     init_ui_hook = tuiInit;
 #endif
+
+  /* Initialize all files.  Give the interpreter a chance to take
+     control of the console via the init_ui_hook()) */
   gdb_init (argv[0]);
 
   /* Do these (and anything which might call wrap_here or *_filtered)
@@ -421,12 +516,12 @@ main (argc, argv)
   if (!quiet)
     {
       /* Print all the junk at the top, with trailing "..." if we are about
-        to read a symbol file (possibly slowly).  */
+         to read a symbol file (possibly slowly).  */
       print_gdb_version (gdb_stdout);
       if (symarg)
        printf_filtered ("..");
-      wrap_here("");
-      gdb_flush (gdb_stdout);          /* Force to screen during slow operations */
+      wrap_here ("");
+      gdb_flush (gdb_stdout);  /* Force to screen during slow operations */
     }
 
   error_pre_print = "\n\n";
@@ -441,18 +536,18 @@ main (argc, argv)
      debugging or what directory you are in.  */
 #ifdef __CYGWIN32__
   {
-    char * tmp = getenv ("HOME");
-    
+    char *tmp = getenv ("HOME");
+
     if (tmp != NULL)
       {
-        homedir = (char *) alloca (MAX_PATH+1);
-        cygwin32_conv_to_posix_path (tmp, homedir);
+       homedir = (char *) alloca (MAX_PATH + 1);
+       cygwin32_conv_to_posix_path (tmp, homedir);
       }
     else
       homedir = NULL;
   }
 #else
-  homedir = getenv ("HOME");  
+  homedir = getenv ("HOME");
 #endif
   if (homedir)
     {
@@ -464,62 +559,49 @@ main (argc, argv)
 
       if (!inhibit_gdbinit)
        {
-         if (!SET_TOP_LEVEL ())
-           source_command (homeinit, 0);
+         catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
        }
-      do_cleanups (ALL_CLEANUPS);
 
       /* Do stats; no need to do them elsewhere since we'll only
-        need them if homedir is set.  Make sure that they are
-        zero in case one of them fails (this guarantees that they
-        won't match if either exists).  */
-      
+         need them if homedir is set.  Make sure that they are
+         zero in case one of them fails (this guarantees that they
+         won't match if either exists).  */
+
       memset (&homebuf, 0, sizeof (struct stat));
       memset (&cwdbuf, 0, sizeof (struct stat));
-      
+
       stat (homeinit, &homebuf);
-      stat (gdbinit, &cwdbuf); /* We'll only need this if
-                                      homedir was set.  */
+      stat (gdbinit, &cwdbuf); /* We'll only need this if
+                                  homedir was set.  */
     }
 
   /* Now perform all the actions indicated by the arguments.  */
   if (cdarg != NULL)
     {
-      if (!SET_TOP_LEVEL ())
-       {
-         cd_command (cdarg, 0);
-       }
+      catch_command_errors (cd_command, cdarg, 0, RETURN_MASK_ALL);
     }
-  do_cleanups (ALL_CLEANUPS);
 
   for (i = 0; i < ndir; i++)
-    if (!SET_TOP_LEVEL ())
-      directory_command (dirarg[i], 0);
-  free ((PTR)dirarg);
-  do_cleanups (ALL_CLEANUPS);
+    catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL);
+  free ((PTR) dirarg);
 
   if (execarg != NULL
       && symarg != NULL
       && STREQ (execarg, symarg))
     {
-      /* The exec file and the symbol-file are the same.  If we can't open
-        it, better only print one error message.  */
-      if (!SET_TOP_LEVEL ())
-       {
-         exec_file_command (execarg, !batch);
-         symbol_file_command (symarg, 0);
-       }
+      /* The exec file and the symbol-file are the same.  If we can't
+         open it, better only print one error message.
+         catch_command_errors returns non-zero on success! */
+      if (catch_command_errors (exec_file_command, execarg, !batch, RETURN_MASK_ALL))
+       catch_command_errors (symbol_file_command, symarg, 0, RETURN_MASK_ALL);
     }
   else
     {
       if (execarg != NULL)
-       if (!SET_TOP_LEVEL ())
-         exec_file_command (execarg, !batch);
+       catch_command_errors (exec_file_command, execarg, !batch, RETURN_MASK_ALL);
       if (symarg != NULL)
-       if (!SET_TOP_LEVEL ())
-         symbol_file_command (symarg, 0);
+       catch_command_errors (symbol_file_command, symarg, 0, RETURN_MASK_ALL);
     }
-  do_cleanups (ALL_CLEANUPS);
 
   /* After the symbol file has been read, print a newline to get us
      beyond the copyright line...  But errors should still set off
@@ -532,17 +614,16 @@ main (argc, argv)
 
   if (corearg != NULL)
     {
-      if (!SET_TOP_LEVEL ())
-       core_file_command (corearg, !batch);
-      else if (isdigit (corearg[0]) && !SET_TOP_LEVEL ())
-       attach_command (corearg, !batch);
+      if (catch_command_errors (core_file_command, corearg, !batch, RETURN_MASK_ALL) == 0)
+       {
+         /* See if the core file is really a PID. */
+         if (isdigit (corearg[0]))
+           catch_command_errors (attach_command, corearg, !batch, RETURN_MASK_ALL);
+       }
     }
-  do_cleanups (ALL_CLEANUPS);
 
   if (ttyarg != NULL)
-    if (!SET_TOP_LEVEL ())
-      tty_command (ttyarg, !batch);
-  do_cleanups (ALL_CLEANUPS);
+    catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL);
 
 #ifdef ADDITIONAL_OPTION_HANDLER
   ADDITIONAL_OPTION_HANDLER;
@@ -555,31 +636,39 @@ main (argc, argv)
 
   /* Read the .gdbinit file in the current directory, *if* it isn't
      the same as the $HOME/.gdbinit file (it should exist, also).  */
-  
+
   if (!homedir
       || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
     if (!inhibit_gdbinit)
       {
-       if (!SET_TOP_LEVEL ())
-         source_command (gdbinit, 0);
+       catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL);
       }
-  do_cleanups (ALL_CLEANUPS);
 
   for (i = 0; i < ncmd; i++)
     {
-      if (!SET_TOP_LEVEL ())
+#if 0
+      /* NOTE: cagney/1999-11-03: SET_TOP_LEVEL() was a macro that
+         expanded into a call to setjmp().  */
+      if (!SET_TOP_LEVEL ()) /* NB: This is #if 0'd out */
        {
+         /* NOTE: I am commenting this out, because it is not clear
+            where this feature is used. It is very old and
+            undocumented. ezannoni: 1999-05-04 */
+#if 0
          if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0')
            read_command_file (stdin);
          else
+#endif
            source_command (cmdarg[i], !batch);
          do_cleanups (ALL_CLEANUPS);
        }
+#endif
+      catch_command_errors (source_command, cmdarg[i], !batch, RETURN_MASK_ALL);
     }
-  free ((PTR)cmdarg);
+  free ((PTR) cmdarg);
 
   /* Read in the old history after all the command files have been read. */
-  init_history();
+  init_history ();
 
   if (batch)
     {
@@ -621,11 +710,16 @@ main (argc, argv)
      The WIN32 Gui calls this main to set up gdb's state, and 
      has its own command loop. */
 #if !defined _WIN32 || defined __GNUC__
+  /* GUIs generally have their own command loop, mainloop, or
+     whatever.  This is a good place to gain control because many
+     error conditions will end up here via longjmp(). */
+#if 0
+  /* FIXME: cagney/1999-11-06: The original main loop was like: */
   while (1)
     {
       if (!SET_TOP_LEVEL ())
        {
-         do_cleanups (ALL_CLEANUPS);           /* Do complete cleanup */
+         do_cleanups (ALL_CLEANUPS);   /* Do complete cleanup */
          /* GUIs generally have their own command loop, mainloop, or whatever.
             This is a good place to gain control because many error
             conditions will end up here via longjmp(). */
@@ -633,36 +727,65 @@ main (argc, argv)
            command_loop_hook ();
          else
            command_loop ();
-          quit_command ((char *)0, instream == stdin);
+         quit_command ((char *) 0, instream == stdin);
        }
     }
-
-  /* No exit -- exit is through quit_command.  */
+  /* NOTE: If the command_loop() returned normally, the loop would
+     attempt to exit by calling the function quit_command().  That
+     function would either call exit() or throw an error returning
+     control to SET_TOP_LEVEL. */
+  /* NOTE: The function do_cleanups() was called once each time round
+     the loop.  The usefulness of the call isn't clear.  If an error
+     was thrown, everything would have already been cleaned up.  If
+     command_loop() returned normally and quit_command() was called,
+     either exit() or error() (again cleaning up) would be called. */
+#endif
+  /* NOTE: cagney/1999-11-07: There is probably no reason for not
+     moving this loop and the code found in captured_command_loop()
+     into the command_loop() proper.  The main thing holding back that
+     change - SET_TOP_LEVEL() - has been eliminated. */
+  while (1)
+    {
+      catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
+    }
 #endif
+  /* No exit -- exit is through quit_command.  */
+}
 
+int
+main (int argc, char **argv)
+{
+  struct captured_main_args args;
+  args.argc = argc;
+  args.argv = argv;
+  catch_errors (captured_main, &args, "", RETURN_MASK_ALL);
+  return 0;
 }
 
+
 /* Don't use *_filtered for printing help.  We don't want to prompt
    for continue no matter how small the screen or how much we're going
    to print.  */
 
 static void
-print_gdb_help (stream)
-  GDB_FILE *stream;
+print_gdb_help (struct ui_file *stream)
 {
-      fputs_unfiltered ("\
+  fputs_unfiltered ("\
 This is the GNU debugger.  Usage:\n\n\
     gdb [options] [executable-file [core-file or process-id]]\n\n\
 Options:\n\n\
 ", stream);
-      fputs_unfiltered ("\
+  fputs_unfiltered ("\
+  --[no]async        Enable (disable) asynchronous version of CLI\n\
+", stream);
+  fputs_unfiltered ("\
   -b BAUDRATE        Set serial port baud rate used for remote debugging.\n\
   --batch            Exit after processing options.\n\
   --cd=DIR           Change current directory to DIR.\n\
   --command=FILE     Execute GDB commands from FILE.\n\
   --core=COREFILE    Analyze the core dump COREFILE.\n\
 ", stream);
-      fputs_unfiltered ("\
+  fputs_unfiltered ("\
   --dbx              DBX compatibility mode.\n\
   --directory=DIR    Search for source files in DIR.\n\
   --epoch            Output information used by epoch emacs-GDB interface.\n\
@@ -670,111 +793,41 @@ Options:\n\n\
   --fullname         Output information used by emacs-GDB interface.\n\
   --help             Print this message.\n\
 ", stream);
-      fputs_unfiltered ("\
+  fputs_unfiltered ("\
+  --interpreter=INTERP\n\
+                     Select a specific interpreter / user interface\n\
+", stream);
+  fputs_unfiltered ("\
   --mapped           Use mapped symbol files if supported on this system.\n\
   --nw              Do not use a window interface.\n\
-  --nx               Do not read .gdbinit file.\n\
+  --nx               Do not read ", stream);
+  fputs_unfiltered (gdbinit, stream);
+  fputs_unfiltered (" file.\n\
   --quiet            Do not print version number on startup.\n\
   --readnow          Fully read symbol files on first access.\n\
 ", stream);
-      fputs_unfiltered ("\
+  fputs_unfiltered ("\
   --se=FILE          Use FILE as symbol file and executable file.\n\
   --symbols=SYMFILE  Read symbols from SYMFILE.\n\
   --tty=TTY          Use TTY for input/output by the program being debugged.\n\
 ", stream);
 #if defined(TUI)
-      fputs_unfiltered ("\
+  fputs_unfiltered ("\
   --tui              Use a terminal user interface.\n\
 ", stream);
 #endif
-      fputs_unfiltered ("\
+  fputs_unfiltered ("\
   --version          Print version information and then exit.\n\
   -w                 Use a window interface.\n\
   --write            Set writing into executable and core files.\n\
   --xdb              XDB compatibility mode.\n\
 ", stream);
 #ifdef ADDITIONAL_OPTION_HELP
-      fputs_unfiltered (ADDITIONAL_OPTION_HELP, stream);
+  fputs_unfiltered (ADDITIONAL_OPTION_HELP, stream);
 #endif
-      fputs_unfiltered ("\n\
+  fputs_unfiltered ("\n\
 For more information, type \"help\" from within GDB, or consult the\n\
 GDB manual (available as on-line info or a printed manual).\n\
-Report bugs to \"bug-gdb@prep.ai.mit.edu\".\
+Report bugs to \"bug-gdb@gnu.org\".\
 ", stream);
 }
-
-\f
-void
-init_proc ()
-{
-}
-
-void
-proc_remove_foreign (pid)
-     int pid;
-{
-}
-
-/* All I/O sent to the *_filtered and *_unfiltered functions eventually ends up
-   here.  The fputs_unfiltered_hook is primarily used by GUIs to collect all
-   output and send it to the GUI, instead of the controlling terminal.  Only
-   output to gdb_stdout and gdb_stderr are sent to the hook.  Everything else
-   is sent on to fputs to allow file I/O to be handled appropriately.  */
-
-void
-fputs_unfiltered (linebuffer, stream)
-     const char *linebuffer;
-     GDB_FILE *stream;
-{
-#if defined(TUI)
-  extern int tui_owns_terminal;
-#endif
-  /* If anything (GUI, TUI) wants to capture GDB output, this is
-   * the place... the way to do it is to set up 
-   * fputs_unfiltered_hook.
-   * Our TUI ("gdb -tui") used to hook output, but in the
-   * new (XDB style) scheme, we do not do that anymore... - RT
-   */
-  if (fputs_unfiltered_hook
-      && (stream == gdb_stdout
-         || stream == gdb_stderr))
-    fputs_unfiltered_hook (linebuffer, stream);
-  else
-    {
-#if defined(TUI)
-      if (tui_version && tui_owns_terminal) {
-       /* If we get here somehow while updating the TUI (from
-        * within a tuiDo(), then we need to temporarily 
-        * set up the terminal for GDB output. This probably just
-        * happens on error output.
-        */
-
-        if (stream->ts_streamtype == astring) {
-           gdb_file_adjust_strbuf(strlen(linebuffer), stream);
-           strcat(stream->ts_strbuf, linebuffer);
-        } else {
-           tuiTermUnsetup(0, (tui_version) ? cmdWin->detail.commandInfo.curch : 0);
-           fputs (linebuffer, stream->ts_filestream);
-           tuiTermSetup(0);
-           if (linebuffer[strlen(linebuffer) - 1] == '\n')
-              tuiClearCommandCharCount();
-           else
-              tuiIncrCommandCharCountBy(strlen(linebuffer));
-        }
-      } else {
-        /* The normal case - just do a fputs() */
-        if (stream->ts_streamtype == astring) {
-           gdb_file_adjust_strbuf(strlen(linebuffer), stream);
-           strcat(stream->ts_strbuf, linebuffer);
-        } else fputs (linebuffer, stream->ts_filestream);
-      }
-
-#else
-      if (stream->ts_streamtype == astring) {
-           gdb_file_adjust_strbuf(strlen(linebuffer), stream);
-           strcat(stream->ts_strbuf, linebuffer);
-        } else fputs (linebuffer, stream->ts_filestream);
-#endif
-    }
-}
diff --git a/gdb/mi/ChangeLog-mi b/gdb/mi/ChangeLog-mi
new file mode 100644 (file)
index 0000000..6e22c26
--- /dev/null
@@ -0,0 +1,1346 @@
+Wed Feb 23 10:30:55 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gdbmi.texinfo: Update copyright - FSF.  Update version
+       information.
+
+       mi-cmd-break.c, mi-cmd-disas.c, mi-cmd-stack.c, mi-cmd-var.c,
+       mi-cmds.h, mi-main.c, mi-parse.c, mi-parse.h: Re-format using GNU
+       indent.
+
+2000-02-21  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c: Add include of gdbcore.h for write_memory()
+       prototype.
+
+2000-02-18  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmd-disas.c (mi_cmd_disassemble): Change syntax of
+       command. Now use options.  
+       Instead of printing the symbolic address of instructions via
+       print_address_symbolic(), use build_address_symbolic() and format
+       properly for output.
+       (gdb_do_disassmble): Delete.
+
+2000-02-18  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmd-disas.c (mi_cmd_disassemble): 
+
+2000-02-17  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_data_write_memory): New function. Write a
+       value into target memory.
+
+       * mi-cmds.h (mi_cmd_data_write_memory): Export. 
+
+       * mi-cmds.c (mi_cmds): Hook up data-write-memory to
+       mi_cmd_data_write_memory().
+
+2000-02-17  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_target_download): Correct error message to
+       report right function name.
+       (mi_cmd_target_select): Add doing exec cleanups at end.
+       (mi_cmd_data_read_memory): Correct typo.
+       (mi_cmd_execute): Do not simply free last_async_command, but reset
+       it to NULL as well.
+       (free_and_reset): New function, free the argument and set it to
+       NULL.
+       (mi_cmd_target_select_continuation): Delete prototype.
+       
+Tue Feb  1 00:17:12 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmd-disas.c, mi-cmds.h, mi-console.c, mi-console.h,
+       mi-main.c, mi-out.c, mi-out.h: Update to reflect rename of
+       gdb-file / GDB_FILE to ui-file / ``struct ui_file''.
+       
+Mon Jan 31 18:33:28 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_command_loop): Delete reference to
+       fputs_unfiltered_hook.
+
+2000-01-27  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.c (mi_cmds): Update entries for
+       mi_cmd_data_list_register_names,
+       mi_cmd_data_list_changed_registers,
+       mi_cmd_data_list_register_values.
+
+       * mi-cmds.h (mi_cmd_data_list_register_names,
+       mi_cmd_data_list_changed_registers,
+       mi_cmd_data_list_register_values): Update to mi_cmd_argv_ftype.
+
+       * mi-main.c (mi_cmd_data_list_register_names,
+       mi_cmd_data_list_changed_registers,
+       mi_cmd_data_list_register_values): Update to use argc, argv
+       parameters.
+       
+2000-01-27  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_data_read_memory): Correct the computation of
+       next-row.
+
+2000-01-27  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-cmd-var.c (mi_cmd_var_create): Test for NULL type.
+       (mi_cmd_var_set_format, mi_cmd_var_show_format,
+       mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+       mi_cmd_var_info_type, mi_cmd_var_info_expression,
+       mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+       mi_cmd_var_assign, mi_cmd_var_update): Prevent possibility of memory
+       leak on error.
+
+2000-01-27  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-out.c (mi_field_string): Test for NULL string pointer.
+
+2000-01-17  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmd-stack.c (mi_cmd_stack_list_frames): Call
+       print_frmae_info() with the correct arguments.
+
+       * mi-main.c (mi_cmd_exec_return): Call
+       show_and_print_stack_frame() with LOC_AND_ADDRESS, so it does the
+       right thing.  Update Copyright.
+
+2000-01-13  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c: Move disassemble commands from here.
+
+       * mi-cmd-disas.c: To here. New file.
+
+2000-01-13  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmd-stack.c: Remove include of mi-out.h.
+
+       * mi-main.c (mi_cmd_disassemble): Update function to use argc/argv
+       interface.
+
+       * mi-cmds.h: Ditto.
+
+       * mi-cmds.c: Ditto.
+
+2000-01-12  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Update stack commands descriptions.
+       Add thread commands descriptions and examples.
+
+       * mi-main.c (mi_cmd_thread_list_ids): Fix typo.
+
+2000-01-12  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_thread_list_ids): New function, print a list
+       of currently known threads ids, and the total number of threads.
+       (mi_cmd_thread_select): New function. Switch current thread.
+
+       * mi-cmds.c (mi_cmds): Implement thread-list-ids by
+       mi_cmd_thread_list_ids, and thread-select by mi_cmd_thread_select.
+
+       * mi-cmds.h (mi_cmd_thread_select, mi_cmd_thread_list_ids): Export.
+
+2000-01-11  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c: Move stack commands from here.
+
+       * mi-cmd-stack.c: To here. New file.
+
+2000-01-07  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (list_args_or_locals): Add a new paramter, the frame
+       for which to display args or locals. Don't use selected_frame
+       anymore, use the new parameter instead. Return void instead of
+       mi_cmd_result, let callers do so.
+       (mi_cmd_stack_list_args): Change interface. Now accept low and
+       high frame numbers to display args for a range of frames. Without
+       these two, display args for the whole stack.
+       (mi_cmd_stack_list_locals): Adapt to new interface for
+       list_args_or_locals.
+
+2000-01-06  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_stack_info_depth, mi_cmd_stack_list_args,
+       mi_cmd_stack_list_frames, mi_cmd_stack_list_locals,
+       mi_cmd_stack_select_frame): Change to use argv type of parameters.
+
+       * mi-cmds.c (mi_cmds): Change stack-info-depth,
+       stack-list-arguments, stack-list-frames, stack-list-locals,
+       stack-select-frame to use argv parameters.
+
+       * mi-cmds.h (mi_cmd_stack_info_depth, mi_cmd_stack_list_args,
+       mi_cmd_stack_list_frames, mi_cmd_stack_list_locals,
+       mi_cmd_stack_select_frame): Update definitions.
+
+Tue Jan  4 12:38:54 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_command_loop): Force the MI interface to use seven
+       bit strings.
+       * gdbmi.texinfo: Make it clear that a quoted C string is seven
+       bit.
+
+Thu Dec 30 14:15:22 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-getopt.c (mi_getopt): Rewrite.  Allow long options.
+       * mi-getopt.h (struct mi_opt): Declare.
+       (mi_getopt): Update.
+
+       * mi-main.c (mi_cmd_data_read_memory), mi-cmd-break.c
+       (mi_cmd_break_insert, mi_cmd_break_watch): Update.
+
+Wed Dec 29 23:38:35 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmd-break.c (mi_cmd_break_insert): Add support for -c
+       <condition>, -i <ignore-count> and -p <thread>.
+       (breakpoint_notify): New function.
+       (mi_cmd_break_insert): Wrap GDB call with callback hooks so that
+       MI is notified when ever a breakpoint is created.
+
+       * gdbmi.texinfo: Update.
+
+Fri Dec 24 11:23:22 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (gdb_do_disassemble): Strip out more useless #ifdef
+       UI_OUTs.
+
+1999-12-23  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (gdb_do_disassemble): Fix output. Lines that have no
+       assembly instructions must still be outputted, to keep the source
+       line numbering correct.
+       Remove #ifdef UI_OUT's, they are useless.
+
+1999-12-17  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (gdb_do_disassemble): Don't print a new list in mixed
+       mode, every time. Just do it when we actually encounter a new
+       source line.
+
+1999-12-17  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-cmd-var.c (mi_cmd_var_list_children): Add test for C++ pseudo
+       variable objects (private, public, protected) as these do not have
+        a type and the -var-list-children operation was dumping core.
+       
+Fri Dec 17 20:23:33 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gdbmi.texinfo: Document recommended syntax for options.
+
+       * mi-main.c (mi_cmd_data_read_memory): Add support for ``-o
+       <offset>''.
+       * gdbmi.texinfo: Document.
+       
+Wed Dec 15 17:43:08 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-getopt.h (mi_getopt): Change optarg to a char pointer. Check
+       optind.
+       * mi-cmd-break.c (mi_cmd_break_insert): Update.
+
+       * mi-main.c (mi_cmd_data_read_memory): Add fields "next-row-addr",
+       "prev-row-addr", "next-page-addr", "prev-page-addr" and a per row
+       "addr".
+       * gdbmi.texinfo: Update.
+
+Wed Dec 15 01:05:40 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.h (mi_cmd_result): Add MI_CMD_CAUGHT_ERROR for when the
+       error is caught.
+
+       * mi-main.c (captured_mi_execute_command): When
+       MI_CMD_CAUGHT_ERROR return 0 rethrowing the eror.
+
+1999-12-13  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmd-break.c (mi_cmd_break_insert): Remove unused var.
+
+       * mi-cmd-var.c (mi_cmd_var_update): Remove unused variables.
+
+Mon Dec 13 18:43:36 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-parse.c (mi_parse): Quote the command when printing it.
+       (mi_parse_argv): Fix handling of quoted strings. Was not
+       de-quoting them.
+       (mi_parse_argv): Make static.
+
+Mon Dec 13 18:30:03 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.h (mi_cmd_break_insert, mi_cmd_break_watch): Change type
+       to mi_cmd_argv_ftype.
+       * mi-cmds.c (mi_cmds): Update.
+       * mi-cmd-break.c (mi_cmd_break_insert, mi_cmd_break_watch): Change
+       to new style of arguments with argc and argv.  Parse arguments
+       using mi_getopt.
+
+       * mi-cmd-break.c (mi_cmd_break_insert): Wrap body in #ifdef UI_OUT
+       to avoid non-ui compile problems.
+
+Mon Dec 13 15:08:36 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-getopt.h, mi-getopt.c: New files. Similar to getopt but with
+       well defined semantics.
+       
+Mon Dec 13 14:22:21 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_cmd_break_insert, mi_cmd_break_watch, enum
+       wp_type, enum bp_type): Move from here.
+       * mi-cmd-break.c: To here.  New file.
+       (mi_cmd_break_insert, mi_cmd_break_insert, mi_cmd_break_watch):
+       Use error to report problems.
+
+1999-12-09  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Update description of exec-interrupt.
+
+       * mi-main.c (mi_cmd_exec_interrupt): If the program is not
+       executing, don't try to interrupt it, but error out instead.  Make
+       sure previous_async_command is not null before duplicating it into
+       last_async_command.
+
+       * gdbmi.texinfo: Add examples for data-evaluate-expression.
+
+1999-12-08  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmd-var.c (mi_cmd_var_assign, mi_cmd_var_create,
+       mi_cmd_var_delete, mi_cmd_var_evaluate_expression,
+       mi_cmd_var_info_expression, mi_cmd_var_info_num_children,
+       mi_cmd_var_info_type, mi_cmd_var_list_children,
+       mi_cmd_var_set_format, mi_cmd_var_show_attributes,
+       mi_cmd_var_show_format, mi_cmd_var_update): Change to use new
+       style of arguments with argc and argv.
+       (next_arg): Delete.
+       (which_var): Delete.
+
+       * mi-cmds.c (mi_cmds): Update entries for mi_cmd_var_assign,
+       mi_cmd_var_create, mi_cmd_var_delete,
+       mi_cmd_var_evaluate_expression, mi_cmd_var_info_expression,
+       mi_cmd_var_info_num_children, mi_cmd_var_info_type,
+       mi_cmd_var_list_children, mi_cmd_var_set_format,
+       mi_cmd_var_show_attributes, mi_cmd_var_show_format,
+       mi_cmd_var_update.
+
+       * mi-cmds.h (mi_cmd_var_assign, mi_cmd_var_create,
+       mi_cmd_var_delete, mi_cmd_var_evaluate_expression,
+       mi_cmd_var_info_expression, mi_cmd_var_info_num_children,
+       mi_cmd_var_info_type, mi_cmd_var_list_children,
+       mi_cmd_var_set_format, mi_cmd_var_show_attributes,
+       mi_cmd_var_show_format, mi_cmd_var_update): Update declarations.
+
+1999-12-08  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Comment out -data-assign command.  * mi-main.c
+       (mi_cmd_data_assign): Do not use, comment out.  * mi-cmds.h
+       (mi_cmd_data_assign): Remove.  * mi-cmds.c: Remove -data-assign
+       command from MI interface.
+
+1999-12-07  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-parse.c (mi_parse): Add '\n' at end of error messages, so
+       that prompt comes out on new line.
+
+       * gdbmi.texinfo: Update disassembly command output.
+
+1999-12-06  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (gdb_do_disassemble): Update output for UI_OUT case.
+
+1999-12-02  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Update exec-until output, including the reason
+       for stopping.
+
+Thu Dec  2 17:17:22 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.c: Include <string.h> for memset.
+
+1999-12-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_exec_return): ifdef the references to
+       return_command_wrapper().
+       
+1999-12-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_gdb_exit, mi_cmd_exec_interrupt,
+       mi_cmd_target_select, mi_execute_async_cli_command,
+       mi_exec_async_cli_cmd_continuation, mi_load_progress): Don't print
+       last_async_command if it is NULL.
+       (mi_cmd_exec_return): 
+
+1999-12-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_exec_return): Reimplement using
+       return_command() instead of mi_execute_async_cli_command().
+
+1999-12-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.h: Export mi_cmd_data_assign and
+       mi_cmd_data_evaluate_expression.
+
+       * mi-cmds.c (mi_cmds): Hook data-assign to mi_cmd_data_assign and
+       data-evaluate-expression to mi_cmd_data_evaluate_expression.
+
+       * mi-main.c (mi_cmd_data_assign): New function. Implement
+       data-assign command.
+       (mi_cmd_data_evaluate_expression): New function. Implement
+       data-evaluate-expression command.
+
+1999-12-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Fix some texinfo formatting errors.
+
+1999-12-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Update data-list-register-values description.
+
+       * mi-cmds.h: Export mi_cmd_data_list_register_values.
+
+       * mi-cmds.c (mi_cmds): Hook data-list-register-values to
+       mi_cmd_data_list_register_values.
+
+       * mi-main.c (mi_cmd_data_list_register_values): New
+       function. Implements the -data-list-register-values command.
+       (get_register): New function. Output the contents of a given
+       register.
+
+Wed Dec  1 20:27:22 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_execute_async_cli_command): Append missing "\n"
+       for synchronous stopped message.
+
+1999-11-30  James Ingham  <jingham@leda.cygnus.com>
+
+       * gdbmi.texinfo: Fix obvious typo in @end statement.
+
+Wed Dec  1 12:36:27 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmd-var.c: Include "value.h".
+       * mi-console.c: Include <string.h>.
+
+Wed Dec  1 00:21:03 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (captured_mi_execute_command): For a CLI command, pass
+       "%s" to mi_execute_cli_command to stop core dumps.
+       (captured_mi_execute_command): Echo CLI commands on gdb_stdlog.
+
+Wed Dec  1 00:10:07 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gdbmi.texinfo: Explain NR-BYTES and ADDR.
+
+Tue Nov 30 23:31:57 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmd-var.c (mi_cmd_var_create, mi_cmd_var_delete,
+       mi_cmd_var_set_format, mi_cmd_var_show_format,
+       mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+       mi_cmd_var_info_type, mi_cmd_var_info_expression,
+       mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+       mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one, next_arg,
+       which_var): New file.  Move varobj commands to here from
+       mi-main.c.
+
+       * mi-console.h, mi-console.c (mi_console_file_new,
+       mi_console_file_delete, mi_console_file_fputs,
+       mi_console_raw_packet, mi_console_file_flush): New files. Move
+       mi_console_file to here from mi-main.c.
+
+Tue Nov 30 19:37:25 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (captured_mi_execute_command): Use fputstr_unfiltered
+       when printing error messages.
+       (mi_cmd_execute): Ditto.
+
+1999-11-29  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Describe -data-list-changed-registers,
+       -data-list-register-names. Add examples for
+       -exec-next-instruction, exec-step-instruction, -exec-run,
+       -exec-until.  Format examples for -data-read-memory.
+       update example for -target-download.
+       
+1999-11-29  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Remove mentioning of inaccurate watchpoint hit
+       count.
+       
+Mon Nov 29 19:28:55 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_execute_async_cli_command): Return ``enum
+       mi_cmd_cmd_result''.  mi_cmd_exec_run, mi_cmd_exec_next,
+       mi_cmd_exec_step, mi_cmd_exec_step_instruction,
+       mi_cmd_exec_finish, mi_cmd_exec_until, mi_cmd_exec_return,
+       mi_cmd_exec_continue): Update call.
+       (mi_execute_async_cli_command): When target is synchronous, fake
+       asynchronous behavour (ulgh).  Allows tests to be run on built-in
+       simulator and native targets.
+
+Mon Nov 29 15:15:16 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.h (mi_cmd_gdb_exit), mi-cmds.c (mi_cmds), mi-main.c
+       (mi_cmd_gdb_exit): Change function signature to mi_cmd_argv_ftype.
+
+1999-11-28  Andew Cagney  <cagney@rat-in-a-hat.cygnus.com>
+
+       * mi-parse.c: Include <ctype.h> and <string.h>
+
+1999-11-26  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdbmi.texinfo: Added watchpoint command descriptions and
+       examples.
+
+       * mi-main.c (mi_load_progress): Add parameter for total sent so far.
+       Print it as well.
+       
+Fri Nov 26 10:17:49 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gdbmi.texinfo (section Output Syntax): For lists, the <string>
+       part of a <result> is optional.  Clarify syntax.
+       (appendix Proposed v2.0 Output Syntax): New section. Provide
+       record of discussion of possible changes to syntax.
+
+Wed Nov 24 19:41:35 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_cmd_data_read_memory): Simplify.  Fix coredump
+       when arguments were bad.
+       (mi_cmd_execute): Change parameter to ``struct mi_parse''.  Handle
+       case of argv_func as well as args_func.
+       (captured_mi_execute_command): Update.
+
+       * mi-cmds.c (struct mi_cmd): Add field for mi_cmd_argv_ftype.
+       (mi_cmds): Update mi_cmd_data_read_memory.
+       (mi_lookup): Return 
+
+       * mi-cmds.h (mi_cmd_args_ftype): Rename mi_cmd_ftype. Make all
+       functions of type this type.
+       (mi_cmd_argv_ftype): Declare.
+       (mi_cmd_data_read_memory): Change type to mi_cmd_argv_fytpe.
+       (struct mi_cmd): Move declaration to here from mi-cmds.c.
+       (mi_lookup): Return a pointer to ``struct mi_cmd''.
+       
+Wed Nov 24 15:03:34 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-parse.c (mi_parse): Initialize TOKEN when a CLI command.
+
+       * gdbmi.texinfo: Allow a <token> before a CLI command.
+
+       * mi-parse.h (struct mi_parse): Declare.
+       (mi_parse): Change to return a ``struct mi_parse''.
+       (enum mi_command_type): Delete PARSE_ERROR.
+
+       * mi-main.c (struct mi_execute_command_context): Delete.
+       (captured_mi_execute_command): Update
+       (mi_execute_command): Update.  Check for mi_parse returning NULL.
+
+Wed Nov 24 12:57:14 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-parse.h: Remove const, from cmd parameter.  Causes cascading
+       warnings.
+
+Wed Nov 24 15:03:34 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-parse.c (mi_parse): New function.  Move parse code to here.
+       * mi-main.c (parse): From here. Delete.
+
+Wed Nov 24 12:57:14 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-parse.c, mi-parse.h: New files. Implement mi_parse_env.
+
+Wed Nov 24 11:24:05 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-out.c (mi_field_string): Make string parameter constant.
+
+1999-11-23  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.h (mi_cmd_target_download): Export. 
+
+       * mi-cmds.c (mi_cmds): Add mi_cmd_target_download.
+
+       * mi-main.c: Include <sys/time.h>.
+       (mi_cmd_target_download): New function, implement the
+       target-download command.
+       (mi_load_progress): New function. Called via the
+       show_load_progress hook. Prints updates every 0.5 secs.
+       (mi_command_loop): Initialize the show_load_progress hook.
+
+1999-11-22  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_exec_until): New function. Implement until
+       command.
+       (mi_cmd_exec_step_instruction): New function. Implement stepi
+       command.
+       (mi_cmd_exec_next_instruction): New function. Implement nexti
+       command.
+       
+       * mi-cmds.c (mi_cmds): Add mi_cmd_exec_step_instruction,
+       mi_cmd_exec_next_instruction, mi_cmd_exec_until.
+
+       * mi-cmds.h (mi_cmd_exec_step_instruction,
+       mi_cmd_exec_next_instruction, mi_cmd_exec_until): Export.
+       
+Tue Nov 23 00:30:37 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi/gdbmi.texinfo: Document -data-read-memory.
+       
+       * mi-main.c (mi_cmd_data_read_memory): Fix off-by-one check of
+       argc.
+       (mi_cmd_data_read_memory): Label the output table with "memory".
+
+Thu Nov 18 18:15:53 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_cmd_exec_interrupt, mi_cmd_break_insert,
+       mi_cmd_break_watch, mi_cmd_disassemble, mi_cmd_execute): Replace
+       strdup with xstrdup.
+
+Thu Nov 18 20:50:09 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_cmd_data_read_memory): New function.  Implement
+       data-read-memory.
+
+       * mi-cmds.h, mi-cmds.c: Add mi_cmd_data_read_memory.
+       * mi-cmds.c (mi_cmds): Ditto.
+
+1999-11-11  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.h (mi_cmd_break_watch): Export.
+
+       * mi-cmds.c (mi_cmds): Hook up break-watch to function
+       mi_cmd_break_watch.
+
+       * mi-main.c (wp_type): New enumeration for the possible types of
+       watchpoints.
+       (mi_cmd_break_watch): New function, implements the break-watch
+       command.
+
+1999-11-11  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_break_insert): Handle case in which the command is
+       just a -break-insert w/o args.
+
+Fri Nov 12 00:01:52 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-out.c (mi_field_string): Always quote the string.
+
+1999-11-10  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.h(mi_cmd_data_list_changed_registers,
+       mi_cmd_data_list_register_names): Export.
+
+       * mi-cmds.c (mi_cmds): Hook up data-list-changed-registers to
+       mi_cmd_data_list_changed_registers and data-list-register-names to
+       mi_cmd_data_list_register_names.
+
+       * mi-main.c (mi_cmd_data_list_changed_registers): New function,
+       implements the data-list-changed-registers command.
+       (mi_cmd_data_list_register_names): New function, implements the
+       data-list-register-names command.
+       (register_changed_p): New function. Decide whether the register
+       contents have changed.
+       (setup_architecture_data): New function. Initialize registers
+       memory.
+       (_initialize_mi_main): Call setup_architecture_data(), and
+       register_gdbarch_swap().
+
+Wed Nov 10 18:35:08 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_execute_command): Correctly quote error messages.
+
+Wed Nov 10 11:05:14 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi/gdbmi.texinfo: Delete <stream-output>.  Replaced by
+       <c-string>.
+
+       * mi-main.c (mi_console_raw_packet): Always quote console output.
+
+Tue Nov  9 17:53:05 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_console_file_new), mi-out.c (mi_out_new): Replace
+       the tui_file with a mem_file. Ya!
+       
+       * mi-out.c (do_write): New function, wrapper to gdb_file_write.
+       (mi_out_put): Pass do_write to gdb_file_put.
+
+       * mi-main.c (mi_console_file_flush): Rewrite.  Use
+       mi_console_raw_packet to send data to the console.
+       (mi_console_raw_packet): New function. Correctly
+       create quoted C string packets.
+
+1999-11-08  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.c (mi_cmds): Break-insert is now implemented by
+       mi_cmd_break_insert.
+       * mi-cmds.h (mi_cmd_break_insert): Export. 
+       * mi-main.c (bp_type): New enumeration.
+       (mi_cmd_break_insert): New function. Implements all flavors of
+       breakpoint insertion.
+
+Mon Nov  8 17:49:17 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_console_file_flush): Replace gdb_file_get_strbuf
+       with tui_file_get_strbuf.
+
+Fri Nov  5 17:06:07 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_console_file_delete, mi_console_file_fputs,
+       mi_console_file_flush): Call internal_error instead of error.
+
+Thu Nov  4 19:53:32 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (captured_mi_execute_command): New function.
+       (mi_execute_command): Rewrite.  Replace SET_TOP_LEVEL() with call
+       to captured_mi_execute_command via catch_errors.
+
+Thu Nov  4 20:33:58 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (clean): Delete.
+       (mi_command_loop): Delete extern declaration of
+       mi_execute_command.
+
+1999-10-28  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_stack_select_frame): Conditionalize the body
+       on UI_OUT, because select_frame_command_wrapper is only defined if
+       UI_OUT is.
+       (mi_cmd_exec_interrupt): Conditionalize the body on UI_OUT,
+       because interrupt_target_command_wrapper is only defined if UI_OUT is.
+
+       * mi-cmds.c (mi_cmds): Implement command exec-interrupt by
+       mi_cmd_exec_interrupt.  
+
+       * mi-main.c (mi_cmd_exec_interrupt): New function. Implements
+       exec-interrupt command.
+       (mi_cmd_execute): If the target is running save execution command
+       token in previous_async_command. If the command is not 'interrupt' 
+       and the target is running, reject it.
+       (clean): New function. Free the arg and reset it to NULL.
+
+       * mi-cmds.h (mi_cmd_exec_interrupt):Export.
+
+1999-10-28  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.c (mi_cmds): Implement command stack-select-frame by
+       mi_cmd_stack_select_frame.  
+
+       * mi-main.c (mi_cmd_stack_select_frame): New function. Implements
+       stack-select-frame command.
+
+       * mi-cmds.h (mi_cmd_select_frame):Export.
+
+1999-10-26  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.c (mi_cmds): Implement commands stack-list-locals and
+       stack-list-arguments by mi_cmd_stack_list_locals and
+       mi_cmd_stack_list_args.
+
+       * mi-main.c (mi_cmd_stack_list_locals): New function. Implements
+       stack-list-locals command.
+       (mi_cmd_stack_list_args): New function. Implements
+       stack-list-arguments command.
+       (list_args_or_locals): New function. Do all the work for the
+       listing of locals or arguments.
+
+       * mi-cmds.h (mi_cmd_stack_list_args,mi_cmd_stack_list_locals) :
+       Export.
+
+1999-10-25  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-cmds.c (mi_cmds): Add new command stack-info-depth.
+
+       * mi-main.c (mi_cmd_stack_info_depth): New function. Implements
+       the stack-info-depth command.
+       * mi-cmds.h (mi_cmd_stack_info_depth): Export.
+
+
+1999-10-22  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_execute_command): Handle MI_CMD_ERROR case
+       properly, for command that return error code and don't set
+       mi_error_message.
+
+       * mi-cmds.c (mi_cmds): Hook stack-list-frames command to
+       mi_cmd_stack_list_frames function.
+       * mi-cmds.h (mi_cmd_stack_list_frames): Export.
+       
+       * mi-main.c (mi_execute_command): Deal with a return code of
+       MI_CMD_ERROR from the execution of mi commands.
+       (mi_error_message): Static string variable, to contain the error
+       message from mi commands.
+       (mi_cmd_stack_list_frames): New function. Prints a backtrace.
+
+1999-10-18  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_disassemble): Handle the new command line
+       parameter that specifies the number of disassembly lines to be
+       displayed.
+       (gdb_do_disassemble): Add new parameter. Count the number of lines
+       that have been displayed, and stop when limit is reached.
+
+Wed Oct 13 18:04:13 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_command_loop): Don't initialize ``flush_hook''.
+
+1999-10-13  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi/gdbmi.texinfo: More reformatting of the grammars.
+
+1999-10-12  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi/gdbmi.texinfo: More TeX formatting.
+
+1999-10-11  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi/gdbmi.texinfo: First pass completed. All commands should have
+       some comments/info.
+       Escape '@' output special char.
+       Reformat for TeX.
+
+1999-10-08  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi/gdbmi.texinfo: Filled in part of file command section, and
+       stack section.
+
+1999-10-07  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi/gdbmi.texinfo: Filled in some sections about execution
+       commands.
+
+Tue Oct  5 15:27:28 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.h: Sort table
+       * mi-cmds.c: Ditto.
+       (MI_TABLE_SIZE): Increase to 251.
+
+1999-10-04  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_cmd_var_create, mi_cmd_var_delete): Add missing
+       cleanups.
+       
+1999-10-04  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (next_arg): Returns lenght as well.
+       (which_var, mi_cmd_var_create, mi_cmd_var_delete,
+       mi_cmd_var_set_format, mi_cmd_var_update): Do not modify the input
+       string, use allocated storage instead.
+       (mi_cmd_var_assign): Adjust call to next_arg() to include new
+       argument.
+
+1999-10-04  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_execute_command): Fix handling of errors.
+
+1999-10-04  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-out.c (mi_out_new): Call tui_sfileopen() instead of
+        deprecated gdb_file_init_astream().
+       * mi-main.c (mi_console_file_new): Ditto.
+
+Mon Oct  4 15:17:29 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.h: Sort function declarations.
+       (mi_lookup): Add extern.
+
+       * mi-cmds.c (mi_lookup): Delete dead code.
+       (build_table): Call  internal_error instead of error.
+       (build_table): Send trace output to gdb_stdlog.
+
+1999-10-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_execute_async_cli_command): Don't do the cleanups
+       if target_executing is null.
+
+1999-09-28  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (async_p): Change var name to event_loop_p.
+
+Mon Sep 27 15:11:00 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_execute_async_cli_command, mi_execute_command):
+       Replace target_has_async with function target_can_async_p.
+
+Sun Sep 26 00:12:52 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_cmd_target_select_continuation): Delete function.
+       (mi_cmd_target_select): Simplify.  target-connect is guarenteed to
+       be synchronous.
+
+Sun Sep 26 00:12:52 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.h (mi_cmd_ftype): Replace mi_impl_ftype.
+       (enum mi_cmd_result): Define.
+       * mi-cmds.c (struct mi_cmd): Update.
+       (mi_lookup): Update.
+       * mi-main.c (mi_cmd_execute): Update.
+
+       * mi-main.c (mi_cmd_gdb_exit, mi_cmd_exec_run, mi_cmd_exec_next,
+       mi_cmd_exec_step, mi_cmd_target_select, mi_cmd_exec_continue,
+       mi_cmd_exec_return, mi_cmd_exec_finish, mi_cmd_disassemble,
+       mi_cmd_var_create, mi_cmd_var_delete, mi_cmd_var_set_format,
+       mi_cmd_var_show_format, mi_cmd_var_info_num_children,
+       mi_cmd_var_list_children, mi_cmd_var_info_type,
+       mi_cmd_var_info_expression, mi_cmd_var_show_attributes,
+       mi_cmd_var_evaluate_expression, mi_cmd_var_update): Update.
+       Return MI_CMD_DONE.
+
+1999-09-22  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_cmd_var_create): Use paddr() to format address
+       on trace output.
+
+1999-09-21  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_cmd_var_create): Test for varobjdebug before
+       printing trace and send it to gdb_stdlog.
+
+Mon Sep 20 13:41:04 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * Makefile.in (mi-out.o): Add dependency list.
+       * mi-out.c: Include "mi-out.h".
+
+1999-09-18  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (_initialize_mi_main): Events on stadin are now
+       handled by stdin_event_handler.
+
+1999-09-17  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-cmds.c (mi_cmds): Add var-* commands.
+
+1999-09-17  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_cmd_var_create, mi_cmd_var_delete,
+       mi_cmd_var_set_format, mi_cmd_var_show_format,
+       mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+       mi_cmd_var_info_type, mi_cmd_var_info_expression,
+       mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+       mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one,
+       which_var, next_arg): New functions.  Implement the -var-*
+       commands.
+       * mi-cmds.h: Add prototypes for the above.
+
+1999-09-14  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-cmds.c (mi_cmds): Add detach command.
+
+1999-09-09  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-cmds.c (lookup_table): Fix typo.
+
+1999-09-09  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-cmds.c (mi_cmds): Fix typo and missing command.
+
+1999-09-09  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c: Properly align function prototypes.
+       (mi_cmd_target_select): Proper check for NULL value.
+
+1999-09-09  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_execute_async_cli_command): Fix for native targets
+       that do not have async yet.
+
+1999-09-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_disassemble): Remove unused var.
+       (gdb_do_disassemble): Ditto.
+
+1999-08-30  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c: Replace all the occurrences of 'asynch' in variable
+       or function names with 'async' to make it consistent with the rest
+       of gdb.
+
+Mon Aug 30 18:16:39 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c: #include <ctype.h> for isspace().
+
+1999-08-27  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (gdb_do_disassemble): This function returns void, not
+       int.
+
+1999-08-26  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_disassemble): Don't use atoi() on the high
+       address string, just treat it same as address low.
+       (gdb_do_disassemble): Parse high_address string before seeing if
+       it is zero.
+
+1999-08-25  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_disassemble): New function to produce
+       disassembly output for mi.
+       (gdb_dis_asm_read_memory): New function. Read the disassembly from
+       the executable file, instead of target memory.
+       (compare_lines): New function. Compare order of disassembly lines.
+       (gdb_do_disassemble): New function. Do the real job of getting the
+       assembly code out.
+
+       * mi-cmds.c (mi_cmds): Do data-disassemble mi command via the
+       mi_cmd_disassemble function.
+
+       * mi-cmds.h: Export new function mi_cmd_disassemble.
+
+Wed Aug 25 15:58:31 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_command_loop): Remove references to ui-hooks.
+
+1999-08-21  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_execute_asynch_cli_command): Fix the incorrect
+       usage of strcat(): allocate enough space for the string.
+
+1999-08-13  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       From Christopher Faylor <cgf@cygnus.com>
+       * mi-main.c (mi_execute_command): Make sure we flush all the
+       output after each command.
+
+1999-08-10  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (_initialize_mi_main): Remove casting in call to
+       add_file_handler.
+
+Sun Aug  8 17:20:57 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_cmd_target_select, mi_execute_asynch_cli_command):
+       Replace call to fatal with call to internal_error.
+
+1999-07-26  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_cmd_execute): Add return code.
+       (mi_execute_command): Make appropriate changes when calling the
+       function mentioned above.
+       (mi_cmd_gdb_exit, mi_cmd_target_select,
+       mi_cmd_target_select_continuation, mi_execute_command,
+       mi_exec_asynch_cli_cmd, mi_exec_asynch_cli_cmd_continuation):
+       Print token, prefix, class and output (if any) in one single group
+       of statements.
+       (mi_execute_command, mi_cmd_execute): Fix error prefix.
+       (mi_cmd_execute): Use exec cleanup for token.
+       * mi-out.c (mi_out_rewind): New function.
+       * mi-out.h: Prototype for the above.
+
+1999-07-16  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_cmd_gdb_exit): Use buffer for exit message.
+       (mi_cmd_execute): Route error messages to correct file.
+       (mi_execute_asynch_cli_command): Insert line feed after running
+       message.
+
+1999-07-16  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-out.h (mi_out_buffered): Add extern declaration.
+       * mi-out.c (mi_out_buffered): New function. Insert a string at the
+       current buffer position.
+       * mi-main.c (mi_cmd_target_select, mi_execute_command,
+       mi_cmd_execute, mi_execute_asynch_cli_command): Use the above
+       function instead of printing to raw_stdout.
+       (mi_cmd_target_select, mi_cmd_target_select_continuation,
+       mi_execute_command, mi_cmd_execute, mi_execute_cli_command,
+       mi_exec_asynch_cli_cmd_continuation): Fix handling of token and
+       prefix.
+       (mi_execute_cli_command): Remove parameter no longer needed.
+
+1999-07-15  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c (mi_cmd_target_select_continuation): Print the numeric
+       token when we are connected.
+       (mi_execute_command): Don't print the token now, do it later.
+       (mi_execute_cli_command): Add a new parameter for the numeric
+       token.  Print the token, the prefix and the class after the
+       command has executed, not before.
+       (mi_execute_asynch_cli_command): Don't print an extra blank line.
+
+1999-07-15  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_gdb_exit): Add \n at the end.
+
+1999-07-15  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_cmd_execute): New function. Dispatch a mi operation.
+       (mi_execute_command): Use the above.
+
+1999-07-15  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c: Fix identation.
+
+1999-07-15  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-main.c: Include target.h and inferior.h.
+       (mi_cmd_target_select): New function to execute the target-select
+       mi operation.
+       (mi_cmd_target_select_continuation): New function. Continuation
+       for the target-select operation.
+       (mi_execute_command): In case of an MI command which requires
+       asynchronous execution, do not try to display the result now. If
+       the execution has to look synchronous don't display the "(gdb)"
+       prompt.
+       (mi_execute_asynch_cli_command): Invoke real asynchronous
+       commands, set up exec_cleanups, and continuations.
+       (mi_exec_asynch_cli_cmd_continuation): New function. Continuation
+       for all the MI execution commands except 'target-select'.
+       (mi_execute_command): Handle null commands by exiting gdb, instead
+       of core dumping.
+
+       * mi-cmds.c (mi_cmds): Hook up -target-select operation to new mi
+       function.
+
+       * mi-cmds.h (mi_cmd_target_select): Add extern declaration.
+
+Thu Jul 15 10:31:39 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (struct mi_console_file): Add field ``prefix''.
+       (mi_console_file_new): Add argument prefix.  Initialize prefix
+       field.
+       (mi_console_file_flush): Use ``prefix'' instead of "~" as the
+       prefix string.
+       (mi_command_loop): Update stream output prefixes. gdb_stdout ==
+       "~", gdb_stderr / gdb_stdlog == "&", gdb_stdtarg == "@".
+
+1999-07-13  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (ui_out_data): New field first_header. Fix output when
+       no breakpoints are found.
+       (mi_table_begin, mi_table_body, mi_table_header): Test for
+       first_header.
+       (mi_table_end): Test for supress_field_separator.
+       (mi_message): Remove messages from MI output.
+
+1999-06-30  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-cmds.c (mi_cmds[]): Delete gdb-cli operation.
+       * mi-main.c (parse): Remove ifdefs for cli commands parsing.
+       (mi-execute-command): Ditto.
+
+Mon Jun 28 13:06:52 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-out.h: New file.
+       (mi_out_new, mi_out_put): Move mi specific delcarations to here.
+       * ui-out.h: From here.
+
+       * mi-main.c: Include "mi-out.h".
+
+1999-06-25  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * top.c (print_gdb_version): Add the word HEADLESS when output
+       follows headless format.
+       (print_command_lines): Fix typo.
+
+1999-06-25  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * event-loop.h: Export input_fd.  
+       * mi-main.c (mi_command_loop): Use the event loop if running
+       asynchronously.
+       (mi_execute_command_wrapper): New function.
+       (_initialize_mi-main): Set things up for running asynchronously.
+
+1999-06-18  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+        * mi-cmds.c (mi_lookup): Deleted.
+        (lookup_table): New function. Replaces old mi_lookup() for local
+        use.
+        (mi_lookup): New function. External interface for command table
+        searchs.
+        (build_table): New definition.
+        (mi_cmds[]): Add several command implementations and the gdb-cli
+        special operation.
+        (mi_cmd_execute): Deleted.
+        * mi-cmds.h: Add type definition for command implementation
+        function pointers, add declaration for new implementation
+        functions and a declaration for mi_lookup().
+        * mi-main.c (mi_execute_asynch_cli_command): New
+        function. Captures code that was repeated for all asynch
+        operations.
+        (mi_cmd_exec_*): Use the above new function.
+        (mi_gdb_cmd_exit): Fix the output, printing something appropriate.
+        (mi_cmd_exec_finish): New operation implementation function.
+        (mi_cmd_exec_return): Ditto.
+        (parse): Prepare to remove cli commands.
+        (mi_execute_command): Fix the output and change the way mi-cmds is
+        used.
+
+1999-06-18  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+        * mi-out.c (mi_table_begin): Add missing field separator call.
+
+Thu Jun 17 21:05:40 1999  Fernando Nasser  <fnasser@tofu.to.cygnus.com>
+
+       * breakpoint.c (breakpoint_1): Remove space in breakpoint table
+       id.
+       (mention): Use ui_out for last new line (forgotten).
+
+1999-06-16  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c (mi_console_file_flush): Prevent prefix printing when
+       buffer empty; change prefix to '~'.
+       (mi_cmd_exec_*): Prefix normal output with '^' instead of
+       ','; remove unwanted new lines before "stopped".
+
+1999-06-16  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-cmds.c (struct mi_cmds): Updated entries for -exec-continue
+       and exec-next operations.
+       (mi_cmd_execute): New text for error messages.
+       * mi-cmds.h: Add declaration for mi_cmd_exec_next and
+       mi_cmd_exec_continue.
+       * mi-main.c (mi_cmd_exec_next): New function. Implements exec-next
+       operation.
+       (mi_cmd_exec_continue): New function. Implements exec-continue
+       operation.
+       (mi_execute_comand): Add missing space to prompt.
+       (mi_cmd_exec_run): Ditto.
+       (mi_cmd_exec_step): Ditto.
+       * mi-out.c (mi_out_new): Add flags argument to ui_out_new call.
+       (ui_list_end): Reset supress_field_separator flag.
+
+Sat Jun 12 11:49:10 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.h. mi-cmds.c (exec step): Command implemented by
+       mi_cmd_exec_step instead of cli call.
+       * mi-main.c (mi_cmd_exec_step): New function.
+
+       * mi-cmds.h. mi-cmds.c (exec run): Command implemented by
+       mi_cmd_exec_run instead of cli call.
+       * mi-main.c (mi_cmd_exec_run): New function.
+
+       * mi-cmds.h. mi-cmds.c (gdb exit): Command implemented by
+       mi_cmd_gdb_exit instead of quit_force.
+       * mi-main.c (mi_cmd_gdb_exit): New function.
+
+Sat Jun 12 11:33:23 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_command_loop): Pass mi_input to
+       simplified_command_loop.
+       (mi_input): New function.  Calls gdb_readline with no prompt.
+
+Sat Jun 12 11:19:02 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_console_file_fputs): Re-implement.  Use a buffer
+       to accumulate output.
+
+       * mi-main.c (struct mi_console_file): Add a buffer.
+       (mi_console_file_new): Create a buffer.
+       (mi_console_file_flush): New function.
+
+Sat Jun 12 10:59:39 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-cmds.h (raw_stdout): Declare.  Will be moved later.
+       * mi-cmds.c (mi_cmd_execute): Send error messages to RAW stdout.
+       (mi_cmds): Sort by class.
+
+       * mi-main.c (raw_stdout): Make global.
+       * mi-main.c: Remove #ifdef UI_OUT.  File assumes UI_OUT is
+       present.
+       * mi-main.c: Include "gdb_string.h".
+       (mi_out_put): Delete declaration.
+
+1999-06-11  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-main.c: Add pre-processor test for UI_OUT.
+       (mi_execute_command): Add pre-processor test for UI_OUT.
+
+Fri Jun 11 23:11:41 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (raw_stdout): New variable.
+       (mi_execute_command): Write mi-out direct to raw_stdout.
+       (mi_command_loop): Create raw_stdout. Attach gdb_stdout to the
+       console.
+       (mi_console_file_fputs, mi_console_file_delete,
+       mi_console_file_new): New functions.
+       (struct mi_console_file): Declare.
+
+Fri Jun 11 18:34:33 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c (mi_execute_command): Call mi_out_put to display the
+       result.
+       * mi-out.c (mi_out_put): New function.
+       * ui-out.h (mi_out_put): Add declare.  Will move later.
+       * Makefile.in (mi-cmds.o, mi-main.o): Add dependency on ui-out.h.
+
+       * mi-out.c (mi_field_string, mi_field_fmt, mi_message, mi_flush,
+       out_field_fmt, list_open, list_close): Replace gdb_stdout with
+       data->buffer.
+       (field_separator, list_open, list_close): Add uiout parameter.
+       (mi_table_begin, mi_table_body, mi_table_end, mi_list_begin,
+       mi_list_end, mi_field_string, mi_field_fmt, out_field_fmt,
+       out_field_fmt): Update.
+
+       * mi-out.c (mi_out_new): Initialize supress_field_separator.
+       (supress_field_separator): Move into mi-out local data object.
+       (mi_table_begin, mi_list_begin, field_separator): Update.
+
+Fri Jun 11 16:08:37 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-out.c (mi_out_new): New function, replace init_mi_out.
+       * mi-main.c (mi_command_loop): Call mi_out_new().
+
+       * ui-out.h (mi_out_new): Add declaration.  Will move later.
+       (mi_ui_out_impl): Delete.
+
+Wed Jun  9 16:42:16 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-main.c: Include "ui-hooks.h".
+       (mi_init_ui, mi_command_loop): New functions.
+       (_initialize_mi_main): Install ``mi'' as the interpreter when
+       selected.
+
+Mon Jun  7 18:43:43 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       From Fernando Nasser  <fnasser@totem.to.cygnus.com>
+       * mi-cmds.c (build_table): Clean up error message.
+       * mi-cmds.c (mi_cmd_execute), mi-main.c (mi_execute_command): Only
+       print debug information when mi_debug_p.
+       * mi-cmds.h (mi_debug_p), mi-main.c: Global, control debug messages.
+       
+Thu Jun  3 00:44:52 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       From Fernando Nasser  <fnasser@totem.to.cygnus.com>:
+       * mi-cmds.c: Add CLI definitions for "exec-arguments",
+       "exec-next", "gdb-exit", "break-list", "break-info", "exec-step"
+       and "stack-list-frames" to mi_cmds.
+       (struct mi_command): Add ``from_tty'' argument to func.
+       * mi-cmds.h (quit_force): Declare.
+
+1999-05-31  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-out.c (mi_table_end): Remove unwanted "\n".
+
+Thu May 27 14:59:06 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * top.c: Include "ui-hooks.h".
+       (call_interp_loop): Tempoary.  Pass mi_execute_command to
+       simplified_command_loop.  Initialize gdb_stdout & gdb_stderr to
+       stdio gdb_file streams.  Force all hooks to null.
+
+       * mi-cmds.h, mi-main.c, mi-cmds.c: New files.
+       * Makefile.in (SFILES): Add mi-main.c, mi-cmds.c
+       (COMMON_OBS): Add mi-main.o, mi-cmds.o.
+       (mi_cmds_h): Define.
+
+Wed May 26 12:39:49 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * top.c (call_interp_loop): Hack.  Add extern declaration for
+       mi_ui_out_impl.
+
+1999-05-25  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-out.c: New table syntax.
+
+Mon May 24 16:16:29 1999  Andrew Cagney  <cagney@amy.cygnus.com>
+
+       mi-out.c (_initialize_mi_out): Add external declaration.
+
+1999-05-21  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-out.c (mi_table_begin): Added missing parameter.
+
+1999-05-21  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-out.c: Changed table markers and added table id.
+
+1999-05-21  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * mi-out.c: New file. Implements low-level ui-out primitives for
+       CLI-based interaction.
+
+\f
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/mi/gdbmi.texinfo b/gdb/mi/gdbmi.texinfo
new file mode 100644 (file)
index 0000000..ec2590e
--- /dev/null
@@ -0,0 +1,2513 @@
+\input texinfo   @c -*-texinfo-*-
+@c %**start of header
+@setfilename gdbmi.info
+@settitle GDB/MI Machine Interface
+@setchapternewpage off
+@c %**end of header
+
+@ifinfo
+This file documents GDB/MI, a Machine Interface to GDB.
+
+Copyright (C) 2000, Free Software Foundation, Inc.
+Contributed by Cygnus Solutions.
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@c  This title page illustrates only one of the
+@c  two methods of forming a title page.
+
+@titlepage
+@title GDB/MI
+@subtitle Version 0.2
+@subtitle Feb 2000
+@author Andrew Cagney, Fernando Nasser and Elena Zannoni
+
+@c  The following two commands
+@c  start the copyright page.
+@page
+@vskip 0pt plus 1filll
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+Copyright @copyright{} 2000, Free Software Foundation, Inc.
+@end titlepage
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Overview
+
+@heading Function and Purpose
+
+GDB/MI is a line based machine oriented text interface to GDB.  It is
+specifically intended to support the development of systems which use
+the debugger as just one small component of a larger system.
+
+@heading This Document
+
+This document is a specification of the GDB/MI interface.  It is written
+in the form of a reference manual.
+
+@heading Terminology
+
+@heading Dependencies
+
+@heading Acknowledgments
+
+In alphabetic order: Fernando Nasser, Stan Shebs and Elena Zannoni.
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Command Syntax
+
+@section Input Syntax
+
+@table @code
+
+@item <command> @expansion{} 
+<cli-command> | <mi-command>
+
+@item <cli-command> @expansion{}
+[ <token> ] "any existing GDB CLI command" <nl>
+
+@item <mi-command> @expansion{}
+[ <token> ] ``-'' <operation> ( `` '' <option> )* [ `` --'' ] ( `` '' <parameter> )* <nl> 
+
+@item <token> @expansion{}
+``any sequence of digits''
+
+@item <option> @expansion{}
+``-'' <parameter> [ `` '' <parameter> ]
+
+@item <parameter> @expansion{}
+<non-blank-sequence> | <c-string>
+
+@item <operation> @expansion{}
+any of the operations described in this document.
+
+@item <non-blank-sequence> @expansion{}
+anything provided it doesn't contain special characters such as ``-''
+ <nl>, ``"'' and of course `` ''.
+
+@item <c-string> @expansion{}
+``"'' <seven-bit-iso-c-string-content> ``"''
+
+@item <nl> @expansion{}
+CR | CR-LF
+
+@end table
+
+Notes:
+
+@itemize @bullet
+
+@item
+The CLI commands are still handled by the MI interpreter; their output
+is described below
+
+@item
+The @code{<token>}, when present, is passed back when the command
+finishes.
+
+@item
+Some mi commands accept optional arguments as part of the parameter
+list. Each option is identified by a leading @code{-} (dash) and may be
+followed by an option argument parameter.  Options occure first in the
+parameter list and can be delimiated from normal parameters using
+@code{--}.
+
+@end itemize
+
+Pragmatics:
+
+@itemize @bullet
+
+@item
+We want easy access to the existing CLI syntax (for debugging).
+
+@item
+We want it easy to spot a MI operation
+
+@end itemize
+
+@section Output Syntax
+
+The output from GDB/MI consists of zero or more out-of-band records
+followed, optionally, by a single result record.  The result record
+being for the most recent command.  The sequence of output records is
+terminated by ``(gdb)''.
+
+If an input command was prefixed with a @code{<token>} then the
+corresponding output for that command will also be prefixed by that same
+token.
+
+@table @code
+@item <output> @expansion{}
+( <out-of-band-record> )* [ <result-record> ] ``(gdb)'' <nl> 
+
+@item <result-record> @expansion{}
+[ <token> ] ``^'' <result-class> ( ``,'' <result> )* <nl>
+
+@item <out-of-band-record> @expansion{}
+<async-record> | <stream-record>
+
+@item <async-record> @expansion{}
+<exec-async-output> | <status-async-output> | <notify-async-output>
+
+@item <exec-async-output> @expansion{}
+[ <token> ] ``*'' <async-output>
+
+@item <status-async-output> @expansion{}
+[ <token> ] ``+'' <async-output>
+
+@item <notify-async-output> @expansion{}
+[ <token> ] ``='' <async-output>
+
+@item <async-output> @expansion{}
+<async-class> ( ``,'' <result> )* <nl> 
+
+@item <result-class> @expansion{} 
+``done'' | ``running'' | ``connected'' | ``error'' | ``exit''
+
+@item <async-class> @expansion{} 
+``stopped'' | others (depending on needs, still in development)
+
+@item <result> @expansion{}
+[ <string> ``='' ] <value>
+
+@item <value> @expansion{}
+<const> | ``@{'' <result> ( ``,'' <result> )* ``@}''
+
+@item <const> @expansion{}
+<c-string>
+
+@item <stream-record> @expansion{}
+<console-stream-output> | <target-stream-output> | <log-stream-output>
+
+@item <console-stream-output> @expansion{}
+``~'' <c-string>
+
+@item <target-stream-output> @expansion{}
+``@@'' <c-string>
+
+@item <log-stream-output> @expansion{}
+``&'' <c-string>
+
+@item <nl> @expansion{}
+CR | CR-LF
+
+@item <token> @expansion{}
+``any sequence of digits''
+
+@end table
+
+In addition, the following are still being developed.
+
+@table @code
+
+@item <query>
+This action is currently undefined.
+
+@end table
+
+Notes:
+
+@itemize @bullet
+
+@item
+All output sequences end in a single line containing a period.
+
+@item
+The @code{<token>} is from the corresponding request.  If an execution
+command is interrupted by the -exec-interrupt command, the token
+associated with the `*stopped' message is the one of the original
+execution command, not the one of the interrupt-command.
+
+@item
+<status-async-output> contains on-going status information about the progress
+of a slow operation.  It can be discarded. All status output is prefixed by
+the prefix `+'.
+
+@item
+<exec-async-output> contains asynchronous state change on the target
+(stopped, started, disappeared). All async output is prefixed by
+the prefix `*'.
+
+@item
+<notify-async-output> contains supplementary information that the client should
+handle (new breakpoint information). All notify output is prefixed by
+the prefix `='.
+
+@item
+<console-stream-output> is output that should be displayed as is in the
+console.  It is the textual response to a CLI command. All the console
+output is prefixed by the prefix ``~''.
+
+@item
+<target-stream-output> is the output produced by the target program.
+All the target output is prefixed by the prefix ``@@''.
+
+@item
+<log-stream-output> is output text coming from GDB's internals, for
+instance messages that should be displayed as part of an error log.  All
+the log output is prefixed by the prefix ``&''.
+
+@end itemize
+
+@section Simple Examples
+
+@subheading Target stop:
+
+@example
+-> -stop
+<- (gdb)
+@end example
+
+(later)
+
+@example
+<- *stop,reason="stop",address="0x123",source="a.c:123"
+<- (gdb)
+@end example
+
+
+@subheading Simple CLI command being passed through the MI and on to the CLI.
+
+@example
+-> print 1+2
+<- ~3\n
+<- (gdb)
+@end example
+
+
+@subheading Command with side effects:
+
+@example
+-> -symbol-file xyz.exe
+<- *breakpoint,nr="3",address="0x123",source="a.c:123"
+<- (gdb)
+@end example
+
+
+@subheading A bad command:
+
+@example
+-> -rubbish
+<- error,"Rubbish not found"
+<- (gdb)
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter CLI compatibility
+
+To help users familiar with the GDB's existing CLI interface, the GDB/MI
+will accept existing CLI commands.  As specified by the syntax, such
+commands can be directly entered into the MI interface and GDB will
+respond.
+
+The mechanism is provided as an aid to developers of MI clients and not
+as a reliable interface into the CLI.  Since the command is being
+interpreteted in an environment that assumes MI behaviour the exact
+output of such commands is likely to end up being an un-supported hybrid
+of MI and CLI output.
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Output Records
+
+@section Result Records
+
+In addition to a number of out-of-band notifications the response to an
+MI command includes one of the following result indications.
+
+@table @code
+
+@item ``^done'' [ ``,'' <results> ]
+The synchronous operation was successful, @code{<results>} is the return
+value.
+
+@item ``^running''
+The asynchronous operation was successfully started.  The target is
+running.  @emph{Is this one correct should it be an out-of-band
+notification?}
+
+@item ``^error'' ``,'' <c-string>
+The operation failed.  The @code{<c-string>} contains the corresponding
+error message.
+
+@end table
+
+@section Stream Records
+
+GDB internally maintains a number of output streams: the console, the
+target, and the log.  The output intended for each of these streams is
+tunneled through the MI interface using stream records.
+
+In addition to the prefix each stream record contains a
+@code{<string-output>}.  This is either raw text (with an implicit new
+line) or a quoted C string (which does not contain an implicit newline).
+
+@table @code
+
+@item ``~'' <string-output>
+The console output stream contains text that should be displayed in the
+CLI console window.  It contains the textual responses to CLI commands.
+
+@item ``@@'' <string-output>
+The target output stream contains any textual output from the running
+target.
+
+@item ``&'' <string-output>
+The LOG stream contains debugging messages being produced by GDB's
+internals.
+
+@end table
+
+@section Out-of-band Records.
+
+Out-of-band records are used to notify the MI client of additional
+changes that have occurred.  Those changes can either be a consequence of
+an MI (breakpoint modified) or as a result of target activity (target
+stopped).
+
+The following is a preliminary list of possible out-of-band records.
+
+@table @code
+
+@item ``*'' ``stop''
+
+@end table
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Command Description Format
+
+The remaining chapters describe blocks of commands.  Each block of
+commands is laid out in a fashion similar to this chapter.
+
+Note the the line breaks shown in the examples are here only for
+readability. They don't appear in the real output.
+Note that the commands with a non available example (N.A.) are not yet
+implemented.
+
+@section Motivation
+
+What motivates the collection of commands
+
+@section Introduction
+
+Brief introduction to the commands as a whole.
+
+@section Operations
+
+@subsection -command <args>...
+
+@subsubsection Result
+
+@subsubsection Out-of-band
+
+@subsubsection Notes
+
+@subsubsection Example
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Breakpoint table commands
+
+@section -break-after <number> <count>
+The breakpoint number <number> is not in effect until it has been hit <count> times.
+Note how this is reflected in the output of the -break-list command.
+
+@subsection GDB command
+ignore
+
+@subsection Example
+@example
+(gdb) 
+-break-insert main
+^done,bkpt=@{number="1",addr="0x000100d0",file="hello.c",line="5"@}
+(gdb) 
+-break-after 1 3
+~
+^done
+(gdb) 
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0",ignore="3"@}@}
+(gdb) 
+@end example
+
+@c @section -break-catch
+
+@c @section -break-commands
+
+@section -break-condition <number> <expr>
+Breakpoint <number> will stop the program only if the condition in <expr> is true.
+The condition becomes part of the -break-list output.
+@subsection GDB command
+condition
+@subsection Example
+@example
+(gdb) 
+-break-condition 1 1
+^done
+(gdb) 
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",cond="1",times="0",ignore="3"@}@}
+(gdb) 
+@end example
+
+@section -break-delete @{ <breakpoint> @}+
+Delete the breakpoint(s) specified in the argument list. This is
+obviously reflected in the breakpoint list.
+@subsection GDB command
+delete
+@subsection Example
+@example
+(gdb) 
+-break-delete 1  
+^done
+(gdb) 
+-break-list
+^done,BreakpointTable=@{@}
+(gdb) 
+@end example
+
+@section -break-disable @{ <breakpoint> @}+
+Disable the breakpoint(s). Note how the field 'enabled' in the break
+list is now set to 'n'.
+@subsection GDB command
+disable
+@subsection Example
+@example
+(gdb) 
+-break-disable 2
+^done
+(gdb) 
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="2",type="breakpoint",disp="keep",enabled="n",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}@}
+(gdb) 
+@end example
+
+@section -break-enable @{ <breakpoint> @}+
+Enable a previously disabled breakpoint(s). 
+@subsection GDB command
+enable
+@subsection Example
+@example
+(gdb) 
+enable 2
+^done
+(gdb) 
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}@}
+(gdb) 
+@end example
+
+@section -break-info <breakpoint>
+REDUNDANT??? Get information about a single breakpoint.
+@subsection GDB command
+@subsection Example
+N.A.
+
+@section -break-insert [ "-t" ] [ "-h" ] [ "-r" ] [ "-c" <condition> ] [ "-i" <ignore-count> ] [ "-p" <thread> ] [ <line> | <addr> ]
+
+<line>, if specified, accordingly to the gdb manual can be one of:
+@itemize @bullet
+@item function
+@c @item +offset
+@c @item -offset
+@c @item linenum
+@item filename:linenum
+@item filename:function
+@item *address
+@end itemize
+
+The possible forms of this command are: 
+
+@table @samp
+@item -t
+Insert a tempoary breakpoint.
+@item -h
+Insert a hardware breakpoint.
+@item -c <condition>
+Make the breakpoint conditional on <condition>
+@item -i <ignore-count>
+Initialize the <ignore-count>
+@item -r
+Insert a regular breakpoint in all the functions whose names match the
+given regular expression.  Other flags are not applicable to regular
+expresson.
+@end table
+
+
+The result is in the form:
+
+^done,bkptno="<gdb number for this breakpoint>",func="<name of the
+function where the breakpoint was inserted>",file="<source file which
+contains this function>",line="<source line number within the file>"
+
+Note: this is open to change.  An out-of-band breakpoint instead of part
+of the result?
+@subsection GDB command
+break, tbreak, hbreak, thbreak, rbreak.
+@subsection Example
+@example
+(gdb) 
+-break-insert main
+^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@}
+(gdb) 
+-break-insert -t foo
+^done,bkpt=@{number="2",addr="0x00010774",file="recursive2.c",line="11"@}
+(gdb) 
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0001072c",
+func="main",file="recursive2.c",line="4",times="0"@},
+bkpt=@{number="2",type="breakpoint",disp="del",enabled="y",addr="0x00010774",
+func="foo",file="recursive2.c",line="11",times="0"@}@}
+(gdb) 
+-break-insert -r foo.*
+~int foo(int, int);
+^done,bkpt=@{number="3",addr="0x00010774",file="recursive2.c",line="11"@}
+(gdb) 
+@end example
+
+@section -break-list
+Displays the list of inserted breakpoints, showing the following fields:
+@table @samp
+@item Number
+Number of the breakpoint
+@item Type
+Type of the breakpoint: breakpoint or watchpoint
+@item Disposition
+Should the breakpoint be deleted or disabled when it is hit: keep or nokeep
+@item Enabled
+Is the breakpoint enabled or no: y or n
+@item Address
+Memory location at which the breakpoint is set.
+@item What
+Logical location of the breakpoint, expressed by function name, file name, line number.
+@item times
+Number of times the breakpoint has been hit.
+@end table
+
+If there are no breakpoints or watchpoints, the BreakpointTable field is
+an empty list.
+@subsection GDB command
+info break
+
+@subsection Example 1
+@example
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@},
+bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010114",func="foo",file="hello.c",line="13",times="0"@}@}
+(gdb)
+@end example
+@subsection Example 2
+@example
+(gdb)
+-break-list
+^done,BreakpointTable=@{@}
+(gdb) 
+@end example
+
+@section -break-watch [ "-a" | "-r" ]
+Create a watchpoint.  With the ``-a'' option it will create an access
+watchpoint, i.e. a watchpoints that triggers either on a read or on a
+write on the memory location.  With the ``-r'' option, the watchoint
+created is a read watchpoint, i.e. it will trigger only when the memory
+location os accessed for reading.  Without either of the options, the
+watchpoint created is a regular watchpoint, i.e. it will trigger whe the
+memory location is accessed for writing.
+
+Note that ``-break-list'' will report a single list of watchpoints and
+breakpoints inserted.
+
+@subsection GDB command
+watch, awatch, rwatch
+
+@subsection Example 1
+Watchpoint on a variable in main().
+@example
+(gdb) 
+-break-watch x
+^done,wpt=@{number="2",exp="x"@}
+(gdb) 
+-exec-continue 
+^running
+^done,reason="watchpoint-trigger",wpt=@{number="2",exp="x"@},
+value=@{old="-268439212",new="55"@},
+frame=@{func="main",args=@{@},file="recursive2.c",line="5"@}
+(gdb) 
+@end example
+@subsection Example 2
+Watchpoint on a variable local to a function. Gdb will stop the program execution 
+twice: first for the variable changing value, then for the watchpoint going out of scope.
+@example
+(gdb) 
+-break-watch C
+^done,wpt=@{number="5",exp="C"@}
+(gdb) 
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",
+wpt=@{number="5",exp="C"@},value=@{old="-276895068",new="3"@},
+frame=@{func="callee4",args=@{@},file="../../../devo/gdb/testsuite/gdb.mi/basics.c",
+line="13"@}
+(gdb) 
+-exec-continue
+^running
+^done,reason="watchpoint-scope",wpnum="5",
+frame=@{func="callee3",args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(gdb) 
+@end example
+
+@subsection Example 3
+Listing breakpoints and watchpoints, at different points in the program execution.
+Note that once the watchpoint goes out of scope, it is deleted.
+@example
+(gdb) 
+-break-watch C
+^done,wpt=@{number="2",exp="C"@}
+(gdb) 
+-break-list   
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00010734",
+func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@},
+bkpt=@{number="2",type="watchpoint",disp="keep",
+enabled="y",addr="",what="C",times="0"@}@}
+(gdb) 
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",wpt=@{number="2",exp="C"@},
+value=@{old="-276895068",new="3"@},
+frame=@{func="callee4",args=@{@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@}
+(gdb) 
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00010734",
+func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@},
+bkpt=@{number="2",type="watchpoint",disp="keep",
+enabled="y",addr="",what="C",times="-5"@}@}
+(gdb) 
+-exec-continue
+^running
+^done,reason="watchpoint-scope",wpnum="2",
+frame=@{func="callee3",args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(gdb) 
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00010734",
+func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}@}
+(gdb) 
+@end example
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Data manipulation
+
+@c REMOVED FROM THE ITNERFACE.
+@c @section -data-assign
+@c Change the value of a program variable. Plenty of side effects.
+@c @subsection GDB command
+@c set variable
+@c @subsection Example 
+@c N.A.
+
+@section -data-disassemble <begin> <end> <mode> <number-of-lines>
+Where
+@table @samp
+@item <begin>
+Is a function name or an address (or $pc)
+@item <end>
+can be 0 (in which case the enclosing function will be disassembled), or
+an address.
+@item <mode>
+can be 0 (only disassembly) or 1 (mixed source and disassembly).
+@item <number-of-lines>
+specifies the number of disassembly lines to be produced. If it is -1
+the whole function will be disassembled, in case no <end> address is
+specified.  If <end> is specified as a non-zero value, and
+<number-of-lines> is lower that the number of disassembly lines between
+<begin> and <end>, we'll display only <number-of-lines> lines, vice
+versa if <number-of-lines> is higher than the number of lines between
+<begin> and <end>, we'll display only the lines up to <end>.
+@end table
+
+The output for each instruction is composed of two fields:
+@itemize @bullet
+@item Address
+@item Instruction
+@end itemize
+Note that whatever included in those fields, is not manipulated
+directely by Flathead, i.e. it is not possible to adjust their format.
+@subsection GDB command
+N.A. No direct mapping.
+
+@subsection Example 1
+@example
+(gdb)
+-data-disassemble main 0 0 -1
+^done,asm_insns=@{
+@{address="0x100b8 <main>",inst=" stwu r1,-16(r1)"@},
+@{address="0x100bc <main+4>",inst="mflr r0"@},
+@{address="0x100c0 <main+8>",inst=" stw r31,12(r1)"@},
+@{address="0x100c4 <main+12>",inst=" stw r0,20(r1)"@},
+@{address="0x100c8 <main+16>",inst=" mr r31,r1"@},
+@{address="0x100cc <main+20>",inst=" bl0x1013c <__eabi>"@},
+@{address="0x100d0 <main+24>",inst=" lis r9,2"@},
+@{address="0x100d4 <main+28>",inst=" addi r3,r9,-25680"@},
+@{address="0x100d8 <main+32>",inst=" bl 0x10fc8 <printf>"@},
+@{address="0x100dc <main+36>",inst=" bl 0x10100 <foo>"@},
+@{address="0x100e0 <main+40>",inst=" li r3,0"@},
+@{address="0x100e4 <main+44>",inst=" b 0x100e8 <main+48>"@},
+@{address="0x100e8 <main+48>",inst=" lwz r11,0(r1)"@},
+@{address="0x100ec <main+52>",inst=" lwz r0,4(r11)"@},
+@{address="0x100f0 <main+56>",inst=" mtlr r0"@},
+@{address="0x100f4 <main+60>",inst=" lwz r31,-4(r11)"@},
+@{address="0x100f8 <main+64>",inst=" mr r1,r11"@},
+@{address="0x100fc <main+68>",inst=" blr"@}
+(gdb) 
+@end example
+
+@subsection Example 2
+@example
+(gdb)
+-data-disassemble main 0 0 3
+^done,asm_insns=@{
+@{address=" 0x100b8 <main>",inst=" stwu r1,-16(r1)"@},
+@{address=" 0x100bc <main+4>",inst="mflr r0"@},
+@{address=" 0x100c0 <main+8>",inst=" stw r31,12(r1)"@}
+(gdb) 
+@end example
+
+@subsection Example 3
+@example
+(gdb) 
+-data-disassemble foo 0 1 -1
+^done,asm_insns=@{src_and_asm_line=@{line="11",file="hello.c",
+line_asm_insn=@{
+@{address="    0x10100 <foo>",inst="      stwu        r1,-16(r1)"@},
+@{address="    0x10104 <foo+4>",inst="           mflrr0"@},
+@{address="    0x10108 <foo+8>",inst="           stw r31,12(r1)"@},
+@{address="    0x1010c <foo+12>",inst="         stw  r0,20(r1)"@},
+@{address="    0x10110 <foo+16>",inst="           mr  r31,r1"@}@}@},
+src_and_asm_line=@{line="12",file="hello.c",
+line_asm_insn=@{
+@{address="    0x10114 <foo+20>",inst="          lisr9,2"@},
+@{address="    0x10118 <foo+24>",inst="         addi        r3,r9,-25664"@},
+@{address="    0x1011c <foo+28>",inst="        bl  0x10fc8 <printf>"@}@}@},
+src_and_asm_line=@{line="14",file="hello.c",
+line_asm_insn=@{
+@{address="    0x10120 <foo+32>",inst="        lwz r11,0(r1)"@},
+@{address="    0x10124 <foo+36>",inst="           lwz r0,4(r11)"@},
+@{address="    0x10128 <foo+40>",inst="           mtlr        r0"@},
+@{address="    0x1012c <foo+44>",inst="          lwz r31,-4(r11)"@},
+@{address="    0x10130 <foo+48>",inst="         mr r1,r11"@},
+@{address="    0x10134 <foo+52>",inst="       blr"@}@}@}@}
+(gdb) 
+@end example
+
+@section -data-evaluate-expression
+Evaluate an expression. The expression could contain an inferior
+function call. The function call will execute synchronously.
+If the expression contains spaces, it must be enclosed in double quotes.
+@subsection GDB command
+print, output, gdb_eval
+@subsection Example
+@example
+211-data-evaluate-expression A
+211^done,value="1"
+(gdb) 
+311-data-evaluate-expression &A
+311^done,value="0xefffeb7c"
+(gdb)
+411-data-evaluate-expression A+3
+411^done,value="4"
+(gdb) 
+511-data-evaluate-expression "A + 3"
+511^done,value="4"
+(gdb) 
+@end example
+
+@section -data-list-changed-registers
+Display a list of the registers that have changed.
+@subsection GDB command
+gdb_changed_register_list. This is in gdbtk only.
+@subsection Example
+On a PPC MBX board.
+@example
+(gdb) 
+-exec-continue
+^running
+
+(gdb) 
+*stopped,reason="breakpoint-hit",bkptno="1",frame=@{func="main",
+args=@{@},file="try.c",line="5"@}
+(gdb) 
+-data-list-changed-registers
+^done,changed-registers=@{"0","1","2","4","5","6","7","8","9",
+"10","11","13","14","15","16","17","18","19","20","21","22","23",
+"24","25","26","27","28","30","31","64","65","66","67","69"@}
+(gdb) 
+@end example
+
+@section -data-list-register-names
+Show a list of register names for the current target.  If no arguments
+are given, it shows a list of the names of all the registers.  If
+integer numbers are given as arguments, it will print a list of the
+names corresponding to the arguments.
+@subsection GDB command
+gdb_regnames
+@subsection Example
+For the PPC MBX board:
+@example
+(gdb)
+-data-list-register-names
+^done,register-names=@{"r0","r1","r2","r3","r4","r5","r6","r7",
+"r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18",
+"r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29",
+"r30","r31","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9",
+"f10","f11","f12","f13","f14","f15","f16","f17","f18","f19","f20",
+"f21","f22","f23","f24","f25","f26","f27","f28","f29","f30","f31",
+"pc","ps","cr","lr","ctr","xer"@}
+(gdb)
+-data-list-register-names 1 2 3
+^done,register-names=@{"r1","r2","r3"@}
+(gdb) 
+@end example
+
+@section -data-list-register-values
+Display the registers contents.  Arguments are the format according to
+which the registers contents are to be returned, and a list of numbers
+specifying the registers to display. A missing list of number indicates
+that the contents of all the registers must be returned.
+Allowed formats are:
+@itemize @bullet
+@item 'x': Hexadecimal
+@item 'o': Octal
+@item 't': Binary
+@item 'd': Decimal
+@item 'r': Raw
+@item 'N': Natural
+@end itemize
+
+@subsection GDB command
+info reg, info all-reg  AND/OR gdb_fetch_registers
+@subsection Example
+For a PPC MBX board. Note, line breaks are for readability only, they
+don't appear in the actual output.
+@example
+(gdb) 
+-data-list-register-values r 64 65
+^done,register-values=@{@{number="64",value="0xfe00a300"@},
+@{number="65",value="0x00029002"@}@}
+(gdb) 
+-data-list-register-values x
+^done,register-values=@{@{number="0",value="0xfe0043c8"@},
+@{number="1",value="0x3fff88"@},@{number="2",value="0xfffffffe"@},
+@{number="3",value="0x0"@},@{number="4",value="0xa"@},
+@{number="5",value="0x3fff68"@},@{number="6",value="0x3fff58"@},
+@{number="7",value="0xfe011e98"@},@{number="8",value="0x2"@},
+@{number="9",value="0xfa202820"@},@{number="10",value="0xfa202808"@},
+@{number="11",value="0x1"@},@{number="12",value="0x0"@},
+@{number="13",value="0x4544"@},@{number="14",value="0xffdfffff"@},
+@{number="15",value="0xffffffff"@},@{number="16",value="0xfffffeff"@},
+@{number="17",value="0xefffffed"@},@{number="18",value="0xfffffffe"@},
+@{number="19",value="0xffffffff"@},@{number="20",value="0xffffffff"@},
+@{number="21",value="0xffffffff"@},@{number="22",value="0xfffffff7"@},
+@{number="23",value="0xffffffff"@},@{number="24",value="0xffffffff"@},
+@{number="25",value="0xffffffff"@},@{number="26",value="0xfffffffb"@},
+@{number="27",value="0xffffffff"@},@{number="28",value="0xf7bfffff"@},
+@{number="29",value="0x0"@},@{number="30",value="0xfe010000"@},
+@{number="31",value="0x0"@},@{number="32",value="0x0"@},
+@{number="33",value="0x0"@},@{number="34",value="0x0"@},
+@{number="35",value="0x0"@},@{number="36",value="0x0"@},
+@{number="37",value="0x0"@},@{number="38",value="0x0"@},
+@{number="39",value="0x0"@},@{number="40",value="0x0"@},
+@{number="41",value="0x0"@},@{number="42",value="0x0"@},
+@{number="43",value="0x0"@},@{number="44",value="0x0"@},
+@{number="45",value="0x0"@},@{number="46",value="0x0"@},
+@{number="47",value="0x0"@},@{number="48",value="0x0"@},
+@{number="49",value="0x0"@},@{number="50",value="0x0"@},
+@{number="51",value="0x0"@},@{number="52",value="0x0"@},
+@{number="53",value="0x0"@},@{number="54",value="0x0"@},
+@{number="55",value="0x0"@},@{number="56",value="0x0"@},
+@{number="57",value="0x0"@},@{number="58",value="0x0"@},
+@{number="59",value="0x0"@},@{number="60",value="0x0"@},
+@{number="61",value="0x0"@},@{number="62",value="0x0"@},
+@{number="63",value="0x0"@},@{number="64",value="0xfe00a300"@},
+@{number="65",value="0x29002"@},@{number="66",value="0x202f04b5"@},
+@{number="67",value="0xfe0043b0"@},@{number="68",value="0xfe00b3e4"@},
+@{number="69",value="0x20002b03"@}@}
+(gdb) 
+@end example
+
+@section -data-read-memory [ -o <byte-offset> ] [ -- ] <address> <word-format> <word-size> <nr-rows> <nr-cols> [ <aschar> ]
+Where
+@table @samp
+@item <address>
+An expression specifying the address of the first memory word to be
+read.  Complex expressions containing embedded white space should be
+quoted using the C convention.
+@item <word-format>
+The format to be used to print the memory words.  The notation is the
+same as for GDB's @code{print} command.
+@item <word-size>
+The size of each memory word in bytes.
+@item <nr-rows>
+The number of rows in the output table.
+@item <nr-cols>
+The number of columns in the output table.
+@item <aschar>
+If present, indicates that each row should include an ascii dump.  The
+value of <aschar> is used as a padding character when a byte is not a
+member of the printable ascii character set (@code{<32} or @code{>126}).
+@item <byte-offset>
+An offset to add to the <address> before fetching memory.
+@end table
+Display memory contents as a table of <nr-rows> by <nr-cols> words.
+Each word being <word-size> bytes.  In total @code{<nr-rows> * <nr-cols>
+* <word-size>} bytes are read (returned as @code{total-bytes}.  Should
+less then the requested number of bytes be returned by the target, the
+missing words are identified using @code{N/A}.  The number of bytes read
+from the target is returned in @code{nr-bytes} and the starting address
+used to read memory by @code{addr}.
+
+The address of the next/previous page or row is available in
+@code{next-row} and @code{prev-row}, @code{next-page} and
+@code{prev-page}.
+@subsection GDB command
+x AND/OR gdb_get_mem AND/OR GDBtk's memory read.
+@subsection Example 1
+Read six bytes of memory starting at @code{bytes+6} but then offset by
+@code{-6} bytes.  Format as three rows of two columns. One byte per
+word.  Display each word in hex.
+@example
+(gdb) 
+9-data-read-memory -o -6 -- bytes+6 x 1 3 2
+9^done,addr="0x00001390",nr-bytes="6",total-bytes="6",
+next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396",
+prev-page="0x0000138a",memory=@{
+@{addr="0x00001390",data=@{"0x00","0x01"@}@},
+@{addr="0x00001392",data=@{"0x02","0x03"@}@},
+@{addr="0x00001394",data=@{"0x04","0x05"@}@}@}
+(gdb) 
+@end example
+@subsection Example 2
+Read two bytes of memory starting at address @code{shorts + 64} and
+display as a single word formatted in decimal.
+@example
+(gdb) 
+5-data-read-memory shorts+64 d 2 1 1
+5^done,addr="0x00001510",nr-bytes="2",total-bytes="2",
+next-row="0x00001512",prev-row="0x0000150e",
+next-page="0x00001512",prev-page="0x0000150e",memory=@{
+@{addr="0x00001510",data=@{"128"@}@}@}
+(gdb) 
+@end example
+@subsection Example 3
+Read thirty two bytes of memory starting at @code{bytes+16} and format
+as eight rows of four columns.  Include a string encoding with @code{x}
+used as the non-printable character.
+@example
+(gdb) 
+4-data-read-memory bytes+16 x 1 8 4 x
+4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32",
+next-row="0x000013c0",prev-row="0x0000139c",
+next-page="0x000013c0",prev-page="0x00001380",memory=@{
+@{addr="0x000013a0",data=@{"0x10","0x11","0x12","0x13"@},ascii="xxxx"@},
+@{addr="0x000013a4",data=@{"0x14","0x15","0x16","0x17"@},ascii="xxxx"@},
+@{addr="0x000013a8",data=@{"0x18","0x19","0x1a","0x1b"@},ascii="xxxx"@},
+@{addr="0x000013ac",data=@{"0x1c","0x1d","0x1e","0x1f"@},ascii="xxxx"@},
+@{addr="0x000013b0",data=@{"0x20","0x21","0x22","0x23"@},ascii=" !\"#"@},
+@{addr="0x000013b4",data=@{"0x24","0x25","0x26","0x27"@},ascii="$%&'"@},
+@{addr="0x000013b8",data=@{"0x28","0x29","0x2a","0x2b"@},ascii="()*+"@},
+@{addr="0x000013bc",data=@{"0x2c","0x2d","0x2e","0x2f"@},ascii=",-./"@}@}
+(gdb) 
+@end example
+
+@section -display-delete <number>
+Delete the display <number>.
+@subsection GDB command
+delete display 
+@subsection Example
+N.A.
+
+@section -display-disable <number>
+Disable display <number>
+@subsection GDB command
+disable display
+@subsection Example
+N.A.
+
+@section -display-enable <number>
+Enable display <number>
+@subsection GDB command
+enable display
+@subsection Example
+N.A.
+
+@section -display-insert <expression>
+Display <expression> every time the program stops.
+@subsection GDB command
+display
+@subsection Example
+N.A.
+
+@section -display-list
+List the displays. Do not show the current values.
+@subsection GDB command
+info display
+@subsection Example
+N.A.
+
+@section -environment-cd <pathdir>
+Set GDB's working directory.
+@subsection GDB command
+cd
+@subsection Example
+@example
+(gdb) 
+-environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb
+^done
+(gdb) 
+@end example
+
+@section -environment-directory <pathdir>
+Add directory <pathdir> to beginning of search path for source files.
+@subsection GDB command
+dir
+@subsection Example
+@example
+(gdb) 
+-environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb
+^done
+(gdb)
+@end example 
+
+@section -environment-path @{ <pathdir> @}+
+Add directories to beginning of search path for object files.
+@subsection GDB command
+path
+@subsection Example
+@example
+(gdb) 
+-environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb
+^done
+(gdb)
+@end example 
+
+@section -environment-pwd
+Show the current working directory
+@subsection GDB command
+pwd
+@subsection Example
+@example
+(gdb) 
+-environment-pwd
+~Working directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb.
+^done
+(gdb) 
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Program control
+
+@section Program termination
+As a result of execution, the inferior program can run to completion, if
+it doesn't encouter any breakpoints.  In this case the ouput will
+include an exit code, if the program has exited exceptionally.
+@subsection Example 1
+Program exited normally:
+@example
+(gdb) 
+-exec-run
+^running
+(gdb)
+x = 55
+*stopped,reason="exited-normally"
+(gdb) 
+@end example
+
+@subsection Example 2
+Program exited exceptionally:
+@example
+(gdb) 
+-exec-run
+^running
+(gdb)
+x = 55
+*stopped,reason="exited",exit-code="01"
+(gdb) 
+@end example
+
+Another way the program can terminate is if it receives a signal like SIGINT.
+@subsection Example 
+Program exited with signal (for a more complete example, see the exec-interrupt command).
+@example
+(gdb) 
+*stopped,reason="exited-signalled",signal-name="SIGINT",signal-meaning="Interrupt"
+@end example
+
+
+@section -exec-abort
+Kill the inferior running program.
+
+@subsection GDB command
+kill
+
+@subsection Example
+N.A.
+
+@section -exec-arguments
+Set the inferior program arguments, to be used in the next -exec-run.
+
+@subsection GDB command
+set args
+
+@subsection Example
+Don't have it around.
+
+@section -exec-continue
+Asynchronous command. Resumes the execution of the inferior program until
+a breakpoint is encountered, or the inferior exits.
+
+@subsection GDB command
+continue
+
+@subsection Example
+@example
+-exec-continue
+^running
+(gdb) 
+@@Hello world
+*stopped,reason="breakpoint-hit",bkptno="2",frame=@{func="foo",args=@{@},
+file="hello.c",line="13"@}
+(gdb)
+@end example
+
+@section -exec-finish
+Asynchronous command. Resumes the execution of the inferior program until the
+current function is exited. Displays the results returned by the function (???).
+
+@subsection GDB command
+finish
+
+@subsection Example 1
+Function returning 'void'.
+@example
+-exec-finish
+^running
+(gdb) 
+@@hello from foo
+*stopped,reason="function-finished",frame=@{func="main",args=@{@},
+file="hello.c",line="7"@}
+(gdb) 
+@end example
+@subsection Example 2
+Function returning other than 'void'. The name of the internal gdb variable storing the
+result is printed, and the value itself.
+@example
+-exec-finish
+^running
+(gdb) 
+*stopped,reason="function-finished",frame=@{addr="0x000107b0",func="foo",
+args=@{@{name="a",value="1"@},@{name="b",value="9"@}@},file="recursive2.c",line="14"@},
+gdb-result-var="$1",return-value="0"
+(gdb) 
+
+@end example
+@section -exec-interrupt
+Asynchronous command. Interrupts the background execution of the target.
+Note how the token associated with the stop message is the one for the
+execution command that has been interrupted. The token for the interrupt
+itself only appears in the '^done' output.  If the user is trying to
+interrupt a non running program, an error message will be printed.
+@subsection GDB command
+interrupt
+
+@subsection Example
+@example
+(gdb) 
+111-exec-continue
+111^running
+
+(gdb) 
+222-exec-interrupt
+222^done
+(gdb) 
+111*stopped,signal-name="SIGINT",signal-meaning="Interrupt",
+frame=@{addr="0x00010140",func="foo",args=@{@},file="try.c",line="13"@}
+(gdb) 
+
+(gdb) 
+-exec-interrupt
+^error,msg="mi_cmd_exec_interrupt: Inferior not executing."
+(gdb) 
+
+@end example
+
+@section -exec-next
+Asynchronous command. Resumes execution of the inferior program, stopping
+when the beginning of the next source line is reached.
+
+@subsection GDB command
+next
+
+@subsection Example
+@example
+-exec-next
+^running
+(gdb) 
+*stopped,reason="end-stepping-range",line="8",file="hello.c"
+(gdb) 
+@end example
+
+@section -exec-next-instruction
+Asynchronous command. Executes one machine instruction. If the
+instruction is a function call continues until the function returns.  If
+the program stops at an instruction in the middle of a source line, the
+address will be printed as well.
+@subsection GDB command
+nexti
+
+@subsection Example
+@example
+(gdb) 
+-exec-next-instruction
+^running
+
+(gdb) 
+*stopped,reason="end-stepping-range",
+addr="0x000100d4",line="5",file="hello.c"
+(gdb) 
+@end example
+
+@section -exec-return
+Makes current function return immediately. Doesn't execute the inferior.
+It displays the new current frame.
+
+@subsection GDB command
+return
+
+@subsection Example
+@example
+(gdb)
+200-break-insert callee4
+200^done,bkpt=@{number="1",addr="0x00010734",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}
+(gdb)
+000-exec-run 
+000^running
+(gdb)
+000*stopped,reason="breakpoint-hit",bkptno="1",
+frame=@{func="callee4",args=@{@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}
+(gdb) 
+205-break-delete
+205^done
+(gdb)
+111-exec-return
+111^done,frame=@{level="0 ",func="callee3",
+args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(gdb)
+@end example
+
+@section -exec-run
+Asynchronous command. Starts execution of the inferior from the
+beginning. The inferior executes until either a breakpoint is
+encountered or the program exits.
+
+@subsection GDB command
+run
+
+@subsection Example
+@example
+(gdb) 
+-break-insert main
+^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@}
+(gdb) 
+-exec-run
+^running
+(gdb) 
+*stopped,reason="breakpoint-hit",bkptno="1",
+frame=@{func="main",args=@{@},file="recursive2.c",line="4"@}
+(gdb) 
+@end example
+
+
+@section -exec-show-arguments
+Print the arguments of the program.
+@subsection GDB command
+show args
+@subsection Example
+N.A.
+
+@c @section -exec-signal
+
+@section -exec-step
+Asynchronous command. Resumes execution of the inferior program, stopping
+when the beginning of the next source line is reached, if the next
+source line is not a function call. If it is, stop at the first
+instruction of the called function.
+
+@subsection GDB command
+step
+
+@subsection Example 1
+Stepping into a function:
+@example
+-exec-step
+^running
+(gdb) 
+*stopped,reason="end-stepping-range",frame=@{func="foo",args=@{@{name="a",value="10"@},
+@{name="b",value="0"@}@},file="recursive2.c",line="11"@}
+(gdb) 
+@end example
+@subsection Example 2
+Regular stepping 
+@example
+-exec-step
+^running
+(gdb) 
+*stopped,reason="end-stepping-range",line="14",file="recursive2.c"
+(gdb) 
+@end example
+
+@section -exec-step-instruction
+Asynchronous command. Resumes the inferior which executes one machine
+instruction. The output, once stop, will vary depend on whether we have
+stopped in the middle of a source line or not.  In the former case, the
+address at which the program stopped will be printed as well.
+
+@subsection GDB command
+stepi
+
+@subsection Example
+@example
+(gdb) 
+-exec-step-instruction
+^running
+
+(gdb) 
+*stopped,reason="end-stepping-range",
+frame=@{func="foo",args=@{@},file="try.c",line="10"@}
+(gdb) 
+-exec-step-instruction
+^running
+
+(gdb) 
+*stopped,reason="end-stepping-range",
+frame=@{addr="0x000100f4",func="foo",args=@{@},file="try.c",line="10"@}
+(gdb) 
+@end example
+
+@section -exec-until
+Asynchronous command. Executes the inferior until the location specified
+in the argument is reached. If there is no argument, the inferior
+executes until a source line greater than the current one is reached.
+The reason for stopping in this case will be ``location-reached''.
+@subsection GDB command
+until
+
+@subsection Example
+@example
+(gdb) 
+-exec-until recursive2.c:6
+^running
+(gdb) 
+x = 55
+*stopped,reason="location-reached",frame=@{func="main",args=@{@},
+file="recursive2.c",line="6"@}
+(gdb) 
+@end example
+
+@section -file-clear
+Is this going away????
+
+@section -file-exec-and-symbols <file>
+Specify the executable file to be debugged. This file is the one from
+which the symbol table is also read.  If no file is specified, it clears
+the executable and symbol information.  If breakpoints are set when
+using this command with no arguments, gdb will produce errors. No output
+is produced, except a completion notification.
+@subsection GDB command
+file <file>
+
+@subsection Example
+@example
+(gdb)
+-file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(gdb)
+@end example
+
+@section -file-exec-file <file>
+Specify the executable file to be debugged. The symbol table is not read
+from this file. If used without argument gdb clears the information
+about the executable file.  No output is produced, except a completion
+notification.
+@subsection GDB command
+exec-file <file>
+
+@subsection Example
+@example
+(gdb) 
+-file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(gdb) 
+@end example
+
+@section -file-list-exec-sections
+List the sections of the current executable file.
+@subsection GDB command
+info file (only part of it), gdb_load_info
+@subsection Example
+N.A.
+
+@section -file-list-exec-source-files
+List the source files for the current executable.
+@subsection GDB command
+gdb_listfiles (gdbtk).
+@subsection Example
+N.A.
+
+@section -file-list-shared-libraries
+List the shared libraries in the program.
+@subsection GDB command
+info shared
+@subsection Example
+N.A.
+
+@section -file-list-symbol-files
+List symbol files.
+@subsection GDB command
+info file (part of it).
+@subsection Example
+N.A.
+
+@section -file-symbol-file <file>
+Read symbol table info from the file specified as argument.  Used
+without arguments clears gdb's symbol table info.  No output is
+produced, except a completion notification.
+@subsection GDB command
+symbol-file <file>
+
+@subsection Example
+@example
+(gdb) 
+-file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(gdb) 
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Misc GDB commands
+
+@c @section -gdb-complete
+
+@section -gdb-exit
+
+Exit GDB immediately.
+@subsection GDB command
+Approximately corresponds to 'quit'.
+
+@subsection Example
+@example
+(gdb) 
+-gdb-exit
+@end example
+
+@section -gdb-set
+Set an internal GDB variable.
+IS THIS A DOLLAR VARIABLE? OR SOMETHING LIKE ANNOTATE ?????
+
+@subsection GDB command
+set
+
+@subsection Example
+@example
+(gdb)
+-gdb-set $foo=3
+^done
+(gdb) 
+@end example
+
+@section -gdb-show
+Show the current value of a GDB variable.
+
+@subsection GDB command
+show
+
+@subsection Example
+@example
+(gdb) 
+-gdb-show annotate
+^done,value="0"
+(gdb) 
+@end example
+
+@c @section -gdb-source
+
+@section -gdb-version
+Show version information for gdb. Used in testing mostly.
+
+@subsection GDB command
+No equivalent.
+
+@subsection Example
+@example
+(gdb)
+-gdb-version
+~GNU gdb 4.18.1 HEADLESS
+~Copyright 1998 Free Software Foundation, Inc.
+~GDB is free software, covered by the GNU General Public License, and you are
+~welcome to change it and/or distribute copies of it under certain conditions.
+~Type "show copying" to see the conditions.
+~There is absolutely no warranty for GDB.  Type "show warranty" for details.
+~This GDB was configured as "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi".
+^done
+(gdb) 
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Kod Commands
+
+The Kod commands are not implemented.
+
+@c @section -kod-info
+
+@c @section -kod-list
+
+@c @section -kod-list-object-types
+
+@c @section -kod-show
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Memory Overlay Commands
+
+the memory overlay commands not implemented.
+
+@c @section -overlay-auto
+
+@c @section -overlay-list-mapping-state
+
+@c @section -overlay-list-overlays
+
+@c @section -overlay-map
+
+@c @section -overlay-off
+
+@c @section -overlay-on
+
+@c @section -overlay-unmap
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Signal Handling Commands
+
+Signal handling commands are not implemented.
+
+@c @section -signal-handle
+
+@c @section -signal-list-handle-actions
+
+@c @section -signal-list-signal-types
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Stack manipulation commands
+
+@section -stack-info-frame
+Get info on the current frame.
+@subsection GDB command
+info frame or frame (w/o args).
+@subsection Example
+N.A.
+
+@section -stack-info-depth [max-depth]
+Return the depth of the stack. If the integer argument <max-depth> is specified, do not
+count beyond max-depth frames. 
+@subsection GDB command
+No equivalent.
+@subsection Example
+For a stack with frame levels 0 through 11:
+@example
+(gdb) 
+-stack-info-depth
+^done,depth="12"
+(gdb) 
+-stack-info-depth 4
+^done,depth="4"
+(gdb) 
+-stack-info-depth 12
+^done,depth="12"
+(gdb) 
+-stack-info-depth 11
+^done,depth="11"
+(gdb) 
+-stack-info-depth 13
+^done,depth="12"
+(gdb) 
+@end example
+
+@section -stack-list-arguments <show-values> [ <low-frame> <high-frame> ]
+Display a list of the arguments for the frames between low-frame and
+high-frame (inclusive). If low-frame and high-frame are not provided, it
+will list the arguments for the whole stack. The show-values argument
+must have a value of 0 or 1. A value of 0 means that only the names of
+the arguments are listed, a value of 1 means that both names and values
+of the argumetns are printed.
+@subsection GDB command
+gdb_get_args (partially).
+@subsection Example
+@example
+(gdb) 
+-stack-list-frames
+^done,
+stack=@{
+frame=@{level="0 ",addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@},
+frame=@{level="1 ",addr="0x0001076c",func="callee3",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="17"@},
+frame=@{level="2 ",addr="0x0001078c",func="callee2",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="22"@},
+frame=@{level="3 ",addr="0x000107b4",func="callee1",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="27"@},
+frame=@{level="4 ",addr="0x000107e0",func="main",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="32"@}@}
+(gdb) 
+-stack-list-arguments 0
+^done,
+stack-args=@{
+frame=@{level="0",args=@{@}@},
+frame=@{level="1",args=@{name="strarg"@}@},
+frame=@{level="2",args=@{name="intarg",name="strarg"@}@},
+frame=@{level="3",args=@{name="intarg",name="strarg",name="fltarg"@}@},
+frame=@{level="4",args=@{@}@}@}
+(gdb) 
+-stack-list-arguments 1
+^done,
+stack-args=@{
+frame=@{level="0",args=@{@}@},
+frame=@{level="1",args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@}@},
+frame=@{level="2",args=@{
+@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@}@}@},
+@{frame=@{level="3",args=@{
+@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@},
+@{name="fltarg",value="3.5"@}@}@},
+frame=@{level="4",args=@{@}@}@}
+(gdb) 
+-stack-list-arguments 0 2 2
+^done,stack-args=@{frame=@{level="2",args=@{name="intarg",name="strarg"@}@}@}
+(gdb) 
+-stack-list-arguments 1 2 2
+^done,stack-args=@{frame=@{level="2",
+args=@{@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@}@}@}@}
+(gdb) 
+@end example
+
+@c @section -stack-list-exception-handlers
+
+@section -stack-list-frames [ <low-frame> <high-frame> ]
+List the frames currently on the stack. For each frame it displays the following info:
+@table @samp
+@item <level>
+The frame number, 0 being the topmost frame, i.e. the innermost function.
+@item <addr>
+Pc value for that frame.
+@item <func>
+Function name 
+@item <file>
+File name of the source fle where the function lives.
+@item <line>
+Line number corresponding to the pc.
+@end table
+
+If invoked without arguments, it prints a backtrace for the whole stack.
+If given two integer arguments it shows the frames whose levels are
+between the two arguments (inclusive). If the two arguments are equal,
+it shows the single frame at the corresponding level.
+
+@subsection GDB command
+backtrace or where
+
+@subsection Example 1
+Whole stack backtrace.
+
+@example
+(gdb)
+-stack-list-frames
+^done,stack=
+@{frame=@{level="0 ",addr="0x0001076c",func="foo",file="recursive2.c",line="11"@},
+frame=@{level="1 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="2 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="3 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="4 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="5 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="6 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="7 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="8 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="9 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="10",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="11",addr="0x00010738",func="main",file="recursive2.c",line="4"@}@}
+
+(gdb) 
+@end example
+
+@subsection Example 2
+Show frames between low_frame and high_frame.
+@example
+(gdb) 
+-stack-list-frames 3 5
+^done,stack=
+@{frame=@{level="3 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="4 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="5 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@}@}
+(gdb) 
+@end example
+@subsection Example 3
+Show one single frame.
+@example
+(gdb) 
+-stack-list-frames 3 3
+^done,stack=
+@{frame=@{level="3 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@}@}
+(gdb) 
+@end example
+
+@section -stack-list-locals <print-values>
+Display the local variables names for the current frame.  With an
+argument of 0 prints only the names of the variables, with argument of 1
+prints also the values.
+@subsection GDB command
+gdb_get_locals
+
+@subsection Example
+@example
+(gdb) 
+-stack-list-locals 0
+^done,locals=@{name="A",name="B",name="C"@}
+(gdb) 
+-stack-list-locals 1
+^done,locals=@{@{name="A",value="1"@},@{name="B",value="2"@},@{name="C",value="3"@}@}
+(gdb) 
+@end example
+
+@section -stack-select-frame <framenum>
+Change the current frame. Select a different frame on the stack.
+@subsection GDB command
+frame (part), up, down
+AND/OR select-frame,
+up-silent, down-silent
+@subsection Example
+@example
+(gdb) 
+-stack-select-frame 2
+^done
+(gdb) 
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Symbol query commands
+
+@section -symbol-info-address <symbol>
+Describe where <symbol> is stored.
+@subsection GDB command
+Info address
+@subsection Example
+N.A.
+
+@section -symbol-info-file
+Show the file for the symbol [NOT SURE]
+@subsection GDB command
+gdb_filnd_file (gdbtk).
+@subsection Example
+N.A.
+
+@section -symbol-info-function
+Show which function the symbol lives in. [NOT SURE]
+@subsection GDB command
+gdb_get_function (gdbtk)
+@subsection Example
+N.A.
+
+@section -symbol-info-line
+Core addresses of the code for a source line.
+@subsection GDB command
+info line , gdb_get_line, gdb_get_file
+@subsection Example
+N.A.
+
+@section -symbol-info-symbol
+Describe what symbol is at location ADDR [NOT SURE]
+@subsection GDB command
+info symbol
+@subsection Example
+N.A.
+
+@section -symbol-list-functions
+List the functions in the executable.
+@subsection GDB command
+info functions, gdb_listfunc, gdb_search
+@subsection Example
+N.A.
+
+@section -symbol-list-types
+List all the type names.
+@subsection GDB command
+info types, gdb_search
+@subsection Example
+N.A.
+
+@section -symbol-list-variables
+List all global and static variable names.
+@subsection GDB command
+Info variables, gdb_search
+@subsection Example
+N.A.
+
+@section -symbol-locate
+@subsection GDB command
+gdb_loc (gdbtk)
+@subsection Example
+N.A.
+
+@section -symbol-type
+Show type of a variable.
+@subsection GDB command
+ptype, gdb_obj_variable
+@subsection Example
+N.A.
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Target manipulation commands
+
+@section -target-attach
+Attach to a process or file outside of GDB.
+@subsection GDB command
+attach
+@subsection Example
+N.A.
+
+@section -target-compare-sections
+Compare section data on target to the exec file.
+@subsection GDB command
+compare-sections
+@subsection Example
+N.A.
+
+@section -target-detach
+Disconnect from the remote target.
+No output.
+
+@subsection GDB command
+detach
+
+@subsection Example
+@example
+(gdb) 
+-target-detach
+^done
+(gdb) 
+@end example
+
+@section -target-download
+Loads the executable onto the remote target.
+It prints out an update message every half second, which includes the fields:
+@itemize @bullet
+@item section: The name of the section.
+@item section-sent: The size of what has been sent so far for that section.
+@item section-size: The size of the section.
+@item total-sent: The total size of what was sent so far (the current and the previous sections).
+@item total-size: The size of the overall executable to download.
+@end itemize
+Each message is sent as status record.
+
+In addition it prints the name and size of the sections, as they are
+downloaded. These messages include the fields:
+@itemize @bullet
+@item section: The name of the section.
+@item section-size: The size of the section.
+@item total-size: The size of the overall executable to download.
+@end itemize
+At the end a summary is printed.
+@subsection GDB command
+load
+
+@subsection Example
+Note: Each status message appears on a single line. Here the messages
+have been broken down, so they can fit into a page.
+@example
+(gdb)
+-target-download
++download,@{section=".text",section-size="6668",total-size="9880"@}
++download,@{section=".text",section-sent="512",section-size="6668",
+total-sent="512",total-size="9880"@}
++download,@{section=".text",section-sent="1024",section-size="6668",
+total-sent="1024",total-size="9880"@}
++download,@{section=".text",section-sent="1536",section-size="6668",
+total-sent="1536",total-size="9880"@}
++download,@{section=".text",section-sent="2048",section-size="6668",
+total-sent="2048",total-size="9880"@}
++download,@{section=".text",section-sent="2560",section-size="6668",
+total-sent="2560",total-size="9880"@}
++download,@{section=".text",section-sent="3072",section-size="6668",
+total-sent="3072",total-size="9880"@}
++download,@{section=".text",section-sent="3584",section-size="6668",
+total-sent="3584",total-size="9880"@}
++download,@{section=".text",section-sent="4096",section-size="6668",
+total-sent="4096",total-size="9880"@}
++download,@{section=".text",section-sent="4608",section-size="6668",
+total-sent="4608",total-size="9880"@}
++download,@{section=".text",section-sent="5120",section-size="6668",
+total-sent="5120",total-size="9880"@}
++download,@{section=".text",section-sent="5632",section-size="6668",
+total-sent="5632",total-size="9880"@}
++download,@{section=".text",section-sent="6144",section-size="6668",
+total-sent="6144",total-size="9880"@}
++download,@{section=".text",section-sent="6656",section-size="6668",
+total-sent="6656",total-size="9880"@}
++download,@{section=".init",section-size="28",total-size="9880"@}
++download,@{section=".fini",section-size="28",total-size="9880"@}
++download,@{section=".data",section-size="3156",total-size="9880"@}
++download,@{section=".data",section-sent="512",section-size="3156",
+total-sent="7236",total-size="9880"@}
++download,@{section=".data",section-sent="1024",section-size="3156",
+total-sent="7748",total-size="9880"@}
++download,@{section=".data",section-sent="1536",section-size="3156",
+total-sent="8260",total-size="9880"@}
++download,@{section=".data",section-sent="2048",section-size="3156",
+total-sent="8772",total-size="9880"@}
++download,@{section=".data",section-sent="2560",section-size="3156",
+total-sent="9284",total-size="9880"@}
++download,@{section=".data",section-sent="3072",section-size="3156",
+total-sent="9796",total-size="9880"@}
+^done,address="0x10004",load-size="9880",transfer-rate="6586",write-rate="429"
+(gdb) 
+@end example
+
+@section -target-exec-status
+Provide information on the state of the target. Whether it is running or not, for instance.
+@subsection GDB command
+No equivalent
+@subsection Example
+N.A.
+
+@section -target-list-available-targets
+List the possible targets to connect to.
+@subsection GDB command
+help target
+@subsection Example
+N.A.
+
+@section -target-list-current-targets
+What the current target is.
+@subsection GDB command
+info file (part of it).
+@subsection Example
+N.A.
+
+@section -target-list-parameters
+????
+@subsection GDB command
+No equivalent
+@subsection Example
+N.A.
+
+@section -target-select
+Connect GDB to the remote target.
+It takes two args:
+
+-target-select <type> <parameters>.
+
+Where:
+
+@table @samp
+@item <type>
+The type of target, for instance async, remote, etc.
+@item <parameters>
+Device names, host names and the like.
+@end table
+The output is a connection notification, followed by the address at
+which the target program is, in the following form: 
+^connected,addr="<address>",func="<function name>",args=@{<arg list>@}
+
+@subsection GDB command
+target
+
+@subsection Example
+@example
+(gdb) 
+-target-select async /dev/ttya
+^connected,addr="0xfe00a300",func="??",args=@{@}
+(gdb) 
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Thread commands
+
+@section -thread-info
+@subsection GDB command
+@subsection Example
+
+@section -thread-list-all-threads
+@subsection GDB command
+@subsection Example
+
+@section -thread-list-ids
+Produces a list of the currently known gdb thread ids. At the end of the
+list it also prints the toal number of such threads.
+@subsection GDB command
+None equivalent. (Maybe part of info threads).
+@subsection Example 1
+No threads present, besides the main process.
+@example
+(gdb) 
+-thread-list-ids
+^done,thread-ids=@{@},number-of-threads="0"
+(gdb) 
+@end example
+@subsection Example 2
+Several threads.
+@example
+(gdb) 
+-thread-list-ids
+^done,thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@},
+number-of-threads="3"
+(gdb) 
+@end example
+
+@section -thread-select <threadnum>
+Make <threadnum> the current thread. It prints the number of the new
+current thread, and the topmost frame for that thread.
+@subsection GDB command
+thread
+@subsection Example
+@example
+(gdb) 
+-exec-next
+^running
+(gdb) 
+*stopped,reason="end-stepping-range",thread-id="2",line="187",
+file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c"
+(gdb) 
+-thread-list-ids
+^done,
+thread-ids={thread-id="3",thread-id="2",thread-id="1"},
+number-of-threads="3"
+(gdb) 
+-thread-select 3
+^done,new-thread-id="3",
+frame=@{level="0 ",func="vprintf",
+args=@{@{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""@},
+@{name="arg",value="0x2"@}@},file="vprintf.c",line="31"@}
+(gdb) 
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Tracepoint Commands
+
+The tracepoint commands are not implemented.
+
+@c @section -trace-actions
+
+@c @section -trace-delete
+
+@c @section -trace-disable
+
+@c @section -trace-dump
+
+@c @section -trace-enable
+
+@c @section -trace-exists
+
+@c @section -trace-find
+
+@c @section -trace-frame-number
+
+@c @section -trace-info
+
+@c @section -trace-insert
+
+@c @section -trace-list
+
+@c @section -trace-pass-count
+
+@c @section -trace-save
+
+@c @section -trace-start
+
+@c @section -trace-stop
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Variable Objects
+
+@section Motivation
+
+For the implementation of a variable debugger window (locals, watched
+expressions, etc.), we are proposing the adaptation of the existent code
+used by Insight.
+
+The two main reason for that are:
+
+@enumerate 1
+@item
+It has been proven in practice (it is already on it's second generation)
+@item
+It will shorten development time (needless to say how important it is
+now)
+@end enumerate
+
+The original interface was designed to be used by Tcl code, so it was
+slightly changed so it can be used through flathead.  This document
+describes the flathead operations that will be available and gives some
+hints about its use.
+
+@emph{Note}: In addition to the set of operations described here, we
+expect the GUI implementation of a variable window to require, at least,
+the following operations:
+@itemize bullet
+@item -gdb-show output-radix
+@item -stack-list-arguments
+@item -stack-list-locals
+@item -stack-select-frame
+@end itemize
+
+@section Introduction
+
+The basic idea behind variable objects is the creation of a named object
+to represent a variable, an expression, a memory location or even a CPU
+register.  For each object created, a set of operations is available for
+examining or changing its properties.
+
+Furthermore, complex data types, such as C structures, are represented
+in a tree format.  For instance, the struct type variable is the root
+and the children will represent the struct members.  If a children is
+itself of a complex type, it will also have children of its own.
+Appropriate language differences are handled for C, C++ and Java.
+
+When returning the actual values of the objects, this facility allows
+for the individual selection of the display format used in the result
+creation.  It can be chosen among: binary, decimal, hexadecimal, octal
+and natural. Natural refers to the a default format automatically chosen
+based on the variable type (like decimal for int, hex for pointers,
+etc.).
+
+The following is the complete set of flathead operations defined to
+access this functionality:
+
+@multitable @columnfractions .3 .6
+@item @strong{Operation}
+@tab @strong{Description}
+
+@item -var-create
+@tab create a variable object
+@item -var-delete
+@tab delete the variable object and its children
+@item -var-set-format
+@tab set the display format of this variable
+@item -var-show-format
+@tab show the display format of this variable
+@item -var-info-num-children
+@tab tells how many children this object has
+@item -var-list-children
+@tab return a list of the object's children
+@item -var-info-type
+@tab show the type of this variable object
+@item -var-info-expression
+@tab print what this variable object represents
+@item -var-show-attributes
+@tab is this variable editable? does it exist here?
+@item -var-evaluate-expression
+@tab get the value of this variable
+@item -var-assign
+@tab set the value of this variable
+@item -var-update
+@tab update the variable and its children
+@end multitable
+
+In the next section we describe each operation in detail and suggest how
+it can be used.
+
+
+@section Operations Description And Use
+
+@subsection -var-create @{<name> | '-'@} @{<frame-addr> | '*'@} <expression>
+
+This operation creates a variable object, which allows the monitoring of
+a variable, the result of an expression, a memory cell or a CPU
+register.
+
+The <name> parameter is the string by which the object can be
+referenced.  It must be unique.  If '-' is specified, the varobj system
+will generate a string "varNNNNNN" automatically.  It will be unique
+provided that one does not specify <name> on that format.  The command
+fails if a duplicate name is found.
+
+The frame under which the expression should be evaluated can be
+specified.  A '*' indicates that the current frame should be used.
+
+Expression is any expression valid on the current language set (must not
+begin with '*') or: *<addr> - The address of a memory cell
+*<addr>-<addr> - An memory address range (TBD) $<regname> - A CPU
+register
+  
+This operation returns the name, number of children and the type of the
+object created.  Type is returned as a string as the ones generated by
+gdb CLI.
+
+name="<name>",numchild="N",type="<type>"
+
+@subsection -var-delete <name>
+
+Deletes a previously created variable object and all of it's children.
+
+Returns an error if the object <name> is not found.
+
+@subsection -var-set-format <name> <format-spec>
+
+Sets the output format for the value of the object.
+
+<format-spec> = @{binary | decimal | hexadecimal | octal | natural@}
+
+@subsection -var-show-format <name>
+
+Returns the format used to display the value of the object.
+
+format="<format-spec>"
+
+@subsection -var-info-num-children <name>
+
+Returns the number of children of a variable object.
+
+numchild="N"
+
+@subsection -var-list-children <name>
+
+Returns a list of the children of the specified variable object.
+
+numchild="N",children=@{@{name="<name>",numchild="N",type="<type>"@},(repeats N times)@}
+
+@subsection -var-info-type <name>
+
+Returns the type of the specified variable.  The type is returned as a
+string in the same format as it is output by gdb's CLI.
+
+type="<type>"
+
+@subsection -var-info-expression <name>
+
+Returns what is represented by the specified variable object.
+
+lang="<lang-spec>",exp="<expression>"
+
+where <lang-spec> = @{"C" | "C++" | "Java"@}
+
+@subsection -var-show-attributes <name>
+
+List attributes of the specified variable object.
+
+status="<attr>[,<attr>]*"
+
+where <attr> = @{ @{ editable | noneditable @} | TBD @}
+
+@subsection -var-evaluate-expression <name>
+
+Evaluates the expression that is represented by the specified variable
+object and returns its value as a string in the current format specified
+for the object.
+
+value="<value>"
+
+@subsection -var-assign <name> <expression>
+
+Assigns a new value for the variable object specified.  The object must
+be "editable".
+
+@subsection -var-update @{<name> | '*'@}
+
+Update the value of the variable object by evaluating its expression
+after fetching all the new values from memory or registers.  A '*'
+causes all existing variable objects to be updated.
+
+
+@c%%%%%%%%%%%%%%%%%%%%%%%%%%%% APPENDIX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@appendix Proposed v2.0 Output Syntax
+
+This appendix is not part of the MI specification.  It is provided as a
+discussion point.
+
+The output from GDB/MI consists of zero or more out-of-band records
+optionally followed by a single result record.  The result record being
+for the most recent command input.  The sequence being terminated by
+``(gdb)''.
+
+Asynchronous GDB/MI output is similar.
+
+Each output record directly associated with an input command is prefixed
+by the input commands @code{<token>}.
+
+@table @code
+@item <output> @expansion{}
+@{ <out-of-band-record> @} [ <result-record> ] ``(gdb)'' <nl> 
+
+@item <result-record> @expansion{}
+[ <token> ] ``^'' <result-class> @{ ``,'' <result> @} <nl>
+
+@item <out-of-band-record> @expansion{}
+<async-record> | <stream-record>
+
+@item <async-record> @expansion{}
+<exec-async-output> | <status-async-output> | <notify-async-output>
+
+@item <exec-async-output> @expansion{}
+[ <token> ] ``*'' <async-output>
+
+@item <status-async-output> @expansion{}
+[ <token> ] ``+'' <async-output>
+
+@item <notify-async-output> @expansion{}
+[ <token> ] ``='' <async-output>
+
+@item <async-output> @expansion{}
+<async-class> @{ ``,'' <result> @} <nl> 
+
+@item <result-class> @expansion{} 
+``done'' | ``running'' | ``connected'' | ``error'' | ``exit''
+
+@item <async-class> @expansion{} 
+``stopped'' | @emph{others depending on need as still in development}
+
+@item <result> @expansion{}
+<string> ``='' <value>
+
+@item <value> @expansion{}
+<c-string> | <tupple> | <list>
+
+@item <tupple> @expansion{}
+``@{@}'' | ``@{'' <result> @{ ``,'' <result> @} ``@}''
+
+@item <list> @expansion{}
+``[]'' | ``['' <value> @{ ``,'' <value> @} ``]''
+
+@item <string> @expansion{}
+@emph{[-A-Za-z\.0-9_]*}
+
+@item <c-string> @expansion{}
+@emph{See the input specification}
+
+@item <stream-record> @expansion{}
+<console-stream-output> | <target-stream-output> | <log-stream-output>
+
+@item <console-stream-output> @expansion{}
+``~'' <c-string>
+
+@item <target-stream-output> @expansion{}
+``@@'' <c-string>
+
+@item <log-stream-output> @expansion{}
+``&'' <c-string>
+
+@item <nl> @expansion{}
+CR | CR-LF
+
+@item <token> @expansion{}
+``any sequence of digits''
+
+@end table
+
+In addition, the following are still being developed.
+
+@table @code
+
+@item <query>
+This action is currently undefined.
+
+@end table
+
+Notes:
+
+@itemize @bullet
+
+@item
+All output sequences end in a single line containing a period.
+
+@item
+The @code{<token>} is from the corresponding request.  If an execution
+command is interrupted by the -exec-interrupt command, the token
+associated with the `*stopped' message is the one of the original
+execution command, not the one of the interrupt-command.
+
+@item
+<status-async-output> contains on-going status information about the progress
+of a slow operation.  It can be discarded. All status output is prefixed by
+the prefix `+'.
+
+@item
+<exec-async-output> contains asynchronous state change on the target
+(stopped, started, disappeared). All async output is prefixed by
+the prefix `*'.
+
+@item
+<notify-async-output> contains supplementary information that the client should
+handle (new breakpoint information). All notify output is prefixed by
+the prefix `='.
+
+@item
+<console-stream-output> is output that should be displayed as is in the
+console.  It is the textual response to a CLI command. All the console
+output is prefixed by the prefix ``~''.
+
+@item
+<target-stream-output> is the output produced by the target program.
+All the target output is prefixed by the prefix ``@@''.
+
+@item
+<log-stream-output> is output text coming from GDB's internals, for
+instance messages that should be displayed as part of an error log.  All
+the log output is prefixed by the prefix ``&''.
+
+@end itemize
+
+
+@c Local variables:
+@c change-log-default-name: "ChangeLog-mi"
+@c End:
+@bye
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
new file mode 100644 (file)
index 0000000..d366531
--- /dev/null
@@ -0,0 +1,253 @@
+/* MI Command Set - breakpoint and watchpoint commands.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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 "ui-out.h"
+#include "mi-out.h"
+#include "breakpoint.h"
+#include "gdb_string.h"
+#include "mi-getopt.h"
+#include "gdb-events.h"
+
+/* Convenience macro for allocting typesafe memory. */
+
+#undef XMALLOC
+#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
+
+enum
+  {
+    FROM_TTY = 0
+  };
+
+/* Output a single breakpoint. */
+
+static void
+breakpoint_notify (int b)
+{
+  gdb_breakpoint_query (b);
+}
+
+
+struct gdb_events breakpoint_hooks =
+{
+  breakpoint_notify,
+  breakpoint_notify,
+  breakpoint_notify,
+};
+
+
+enum bp_type
+  {
+    REG_BP,
+    HW_BP,
+    REGEXP_BP
+  };
+
+/* Insert a breakpoint. The type of breakpoint is specified by the
+   first argument: -break-insert <location> --> insert a regular
+   breakpoint.  -break-insert -t <location> --> insert a temporary
+   breakpoint.  -break-insert -h <location> --> insert an hardware
+   breakpoint.  -break-insert -t -h <location> --> insert a temporary
+   hw bp.  
+   -break-insert -r <regexp> --> insert a bp at functions matching
+   <regexp> */
+
+enum mi_cmd_result
+mi_cmd_break_insert (char *command, char **argv, int argc)
+{
+  char *address = NULL;
+  enum bp_type type = REG_BP;
+  int temp_p = 0;
+  int thread = -1;
+  int ignore_count = 0;
+  char *condition = NULL;
+  enum gdb_rc rc;
+  struct gdb_events *old_hooks;
+  enum opt
+    {
+      HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
+      IGNORE_COUNT_OPT, THREAD_OPT
+    };
+  static struct mi_opt opts[] =
+  {
+    {"h", HARDWARE_OPT, 0},
+    {"t", TEMP_OPT, 0},
+    {"c", CONDITION_OPT, 1},
+    {"i", IGNORE_COUNT_OPT, 1},
+    {"p", THREAD_OPT, 1},
+    0
+  };
+
+  /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
+     to denote the end of the option list. */
+  int optind = 0;
+  char *optarg;
+  while (1)
+    {
+      int opt = mi_getopt ("mi_cmd_break_insert", argc, argv, opts, &optind, &optarg);
+      if (opt < 0)
+       break;
+      switch ((enum opt) opt)
+       {
+       case TEMP_OPT:
+         temp_p = 1;
+         break;
+       case HARDWARE_OPT:
+         type = HW_BP;
+         break;
+#if 0
+       case REGEXP_OPT:
+         type = REGEXP_BP;
+         break;
+#endif
+       case CONDITION_OPT:
+         condition = optarg;
+         break;
+       case IGNORE_COUNT_OPT:
+         ignore_count = atol (optarg);
+         break;
+       case THREAD_OPT:
+         thread = atol (optarg);
+         break;
+       }
+    }
+
+  if (optind >= argc)
+    error ("mi_cmd_break_insert: Missing <location>");
+  if (optind < argc - 1)
+    error ("mi_cmd_break_insert: Garbage following <location>");
+  address = argv[optind];
+
+  /* Now we have what we need, let's insert the breakpoint! */
+  old_hooks = set_gdb_event_hooks (&breakpoint_hooks);
+  switch (type)
+    {
+    case REG_BP:
+      rc = gdb_breakpoint (address, condition,
+                          0 /*hardwareflag */ , temp_p,
+                          thread, ignore_count);
+      break;
+    case HW_BP:
+      rc = gdb_breakpoint (address, condition,
+                          1 /*hardwareflag */ , temp_p,
+                          thread, ignore_count);
+      break;
+#if 0
+    case REGEXP_BP:
+      if (temp_p)
+       error ("mi_cmd_break_insert: Unsupported tempoary regexp breakpoint");
+      else
+       rbreak_command_wrapper (address, FROM_TTY);
+      return MI_CMD_DONE;
+      break;
+#endif
+    default:
+      internal_error ("mi_cmd_break_insert: Bad switch.");
+    }
+  set_gdb_event_hooks (old_hooks);
+
+  if (rc == GDB_RC_FAIL)
+    return MI_CMD_CAUGHT_ERROR;
+  else
+    return MI_CMD_DONE;
+}
+
+enum wp_type
+{
+  REG_WP,
+  READ_WP,
+  ACCESS_WP
+};
+
+/* Insert a watchpoint. The type of watchpoint is specified by the
+   first argument: 
+   -break-watch <expr> --> insert a regular wp.  
+   -break-watch -r <expr> --> insert a read watchpoint.
+   -break-watch -a <expr> --> insert an access wp. */
+
+enum mi_cmd_result
+mi_cmd_break_watch (char *command, char **argv, int argc)
+{
+  char *expr = NULL;
+  enum wp_type type = REG_WP;
+  enum opt
+    {
+      READ_OPT, ACCESS_OPT
+    };
+  static struct mi_opt opts[] =
+  {
+    {"r", READ_OPT, 0},
+    {"a", ACCESS_OPT, 0},
+    0
+  };
+
+  /* Parse arguments. */
+  int optind = 0;
+  char *optarg;
+  while (1)
+    {
+      int opt = mi_getopt ("mi_cmd_break_watch", argc, argv, opts, &optind, &optarg);
+      if (opt < 0)
+       break;
+      switch ((enum opt) opt)
+       {
+       case READ_OPT:
+         type = READ_WP;
+         break;
+       case ACCESS_OPT:
+         type = ACCESS_WP;
+         break;
+       }
+    }
+  if (optind >= argc)
+    error ("mi_cmd_break_watch: Missing <expression>");
+  if (optind < argc - 1)
+    error ("mi_cmd_break_watch: Garbage following <expression>");
+  expr = argv[optind];
+
+  /* Now we have what we need, let's insert the watchpoint! */
+  switch (type)
+    {
+    case REG_WP:
+#ifdef UI_OUT
+      watch_command_wrapper (expr, FROM_TTY);
+#endif
+      break;
+    case READ_WP:
+#ifdef UI_OUT
+      rwatch_command_wrapper (expr, FROM_TTY);
+#endif
+      break;
+    case ACCESS_WP:
+#ifdef UI_OUT
+      awatch_command_wrapper (expr, FROM_TTY);
+#endif
+      break;
+    default:
+      error ("mi_cmd_break_watch: Unknown watchpoint type.");
+    }
+  return MI_CMD_DONE;
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmd-disas.c b/gdb/mi/mi-cmd-disas.c
new file mode 100644 (file)
index 0000000..9bbc9ef
--- /dev/null
@@ -0,0 +1,499 @@
+/* MI Command Set - disassemble commands.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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 "target.h"
+#include "value.h"
+#include "mi-cmds.h"
+#include "mi-getopt.h"
+#include "ui-out.h"
+
+static int gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, 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, int len, disassemble_info * info)
+{
+  extern struct target_ops exec_ops;
+  int res;
+
+  errno = 0;
+  res = xfer_memory (memaddr, myaddr, len, 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;
+}
+
+/* The arguments to be passed on the command line and parsed here are:
+
+   either:
+
+   START-ADDRESS: address to start the disassembly at.
+   END-ADDRESS: address to end the disassembly at.
+
+   or:
+
+   FILENAME: The name of the file where we want disassemble from.
+   LINE: The line around which we want to disassemble. It will
+   disassemble the function that contins that line.
+   HOW_MANY: Number of disassembly lines to display. In mixed mode, it
+   is the number of disassembly lines only, not counting the source
+   lines.  
+
+   always required:
+
+   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;
+  CORE_ADDR start;
+  CORE_ADDR low = 0;
+  CORE_ADDR high = 0;
+
+  int how_many = -1;
+  int mixed_source_and_assembly;
+  int num_displayed;
+  int line_num;
+
+  char *file_string;
+  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;
+  int num_seen = 0;
+  int start_seen = 0;
+  int end_seen = 0;
+
+  /* Options processing stuff. */
+  int optind = 0;
+  char *optarg;
+  enum opt
+    {
+      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},
+    {"s", START_OPT, 1},
+    {"e", END_OPT, 1},
+    0
+  };
+
+  /* Get the options with their arguments. Keep track of what we
+     encountered. */
+  while (1)
+    {
+      int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts,
+                          &optind, &optarg);
+      if (opt < 0)
+       break;
+      switch ((enum opt) opt)
+       {
+       case FILE_OPT:
+         file_string = xstrdup (optarg);
+         file_seen = 1;
+         break;
+       case LINE_OPT:
+         line_num = atoi (optarg);
+         line_seen = 1;
+         break;
+       case NUM_OPT:
+         how_many = atoi (optarg);
+         num_seen = 1;
+         break;
+       case START_OPT:
+         low = parse_and_eval_address (optarg);
+         start_seen = 1;
+         break;
+       case END_OPT:
+         high = parse_and_eval_address (optarg);
+         end_seen = 1;
+         break;
+       }
+    }
+  argv += optind;
+  argc -= optind;
+
+  /* Allow only filename + linenum (with how_many which is not
+     required) OR start_addr + and_addr */
+
+  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.");
+
+  if (argc != 1)
+    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. */
+
+  if (line_seen && file_seen)
+    {
+      s = lookup_symtab (file_string);
+      if (s == NULL)
+       error ("mi_cmd_disassemble: Invalid filename.");
+      if (!find_line_pc (s, line_num, &start))
+       error ("mi_cmd_disassemble: Invalid line number");
+      if (find_pc_partial_function (start, NULL, &low, &high) == 0)
+       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 == BIG_ENDIAN)
+    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 */
+
+         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_list_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_list_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_list_end (uiout);
+                       }
+                     /* Print the last line and leave list open for
+                        asm instructions to be added. */
+                     ui_out_list_begin (uiout, "src_and_asm_line");
+                     print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+                   }
+               }
+             else
+               {
+                 ui_out_list_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_list_begin (uiout, NULL);
+             print_address_numeric (pc, 1, stb->stream);
+             ui_out_field_stream (uiout, "address", stb);
+
+             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)
+               free (filename);
+             if (name != NULL)
+               free (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_list_end (uiout);
+           }
+         if (close_list)
+           {
+             ui_out_list_end (uiout);
+             ui_out_list_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_list_begin (uiout, NULL);
+         print_address_numeric (pc, 1, stb->stream);
+         ui_out_field_stream (uiout, "address", stb);
+
+         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)
+           free (filename);
+         if (name != NULL)
+           free (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_list_end (uiout);
+       }
+      ui_out_list_end (uiout);
+    }
+  gdb_flush (gdb_stdout);
+
+  return MI_CMD_DONE;
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
new file mode 100644 (file)
index 0000000..143054c
--- /dev/null
@@ -0,0 +1,317 @@
+/* MI Command Set - stack commands.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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 "target.h"
+#include "frame.h"
+#include "value.h"
+#include "mi-cmds.h"
+#include "ui-out.h"
+
+#ifdef UI_OUT
+/* 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);
+#endif
+
+static void list_args_or_locals (int locals, int values, struct frame_info *fi);
+
+/* Print a list of the stack frames. Args can be none, in which case
+   we want to print the whole backtrace, or a pair of numbers
+   specifying the frame numbers at which to start and stop the
+   display. If the two numbers are equal, a single frame will be
+   displayed. */
+enum mi_cmd_result
+mi_cmd_stack_list_frames (char *command, char **argv, int argc)
+{
+  int frame_low;
+  int frame_high;
+  int i;
+  struct frame_info *fi;
+
+  if (!target_has_stack)
+    error ("mi_cmd_stack_list_frames: No stack.");
+
+  if (argc > 2 || argc == 1)
+    error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]");
+
+  if (argc == 2)
+    {
+      frame_low = atoi (argv[0]);
+      frame_high = atoi (argv[1]);
+    }
+  else
+    {
+      /* Called with no arguments, it means we want the whole
+         backtrace. */
+      frame_low = -1;
+      frame_high = -1;
+    }
+
+  /* Let's position fi on the frame at which to start the
+     display. Could be the innermost frame if the whole stack needs
+     displaying, or if frame_low is 0. */
+  for (i = 0, fi = get_current_frame ();
+       fi && i < frame_low;
+       i++, fi = get_prev_frame (fi));
+
+  if (fi == NULL)
+    error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
+
+  ui_out_list_begin (uiout, "stack");
+
+  /* Now let;s print the frames up to frame_high, or until there are
+     frames in the stack. */
+  for (;
+       fi && (i <= frame_high || frame_high == -1);
+       i++, fi = get_prev_frame (fi))
+    {
+      QUIT;
+      /* level == i: always print the level 'i'
+         source == LOC_AND_ADDRESS: print the location and the address 
+         always, even for level 0.
+         args == 0: don't print the arguments. */
+      print_frame_info (fi /* frame info */ ,
+                       i /* level */ ,
+                       LOC_AND_ADDRESS /* source */ ,
+                       0 /* args */ );
+    }
+
+  ui_out_list_end (uiout);
+  if (i < frame_high)
+    error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
+
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_stack_info_depth (char *command, char **argv, int argc)
+{
+  int frame_high;
+  int i;
+  struct frame_info *fi;
+
+  if (!target_has_stack)
+    error ("mi_cmd_stack_info_depth: No stack.");
+
+  if (argc > 1)
+    error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]");
+
+  if (argc == 1)
+    frame_high = atoi (argv[0]);
+  else
+    /* Called with no arguments, it means we want the real depth of
+       the stack. */
+    frame_high = -1;
+
+  for (i = 0, fi = get_current_frame ();
+       fi && (i < frame_high || frame_high == -1);
+       i++, fi = get_prev_frame (fi))
+    QUIT;
+
+  ui_out_field_int (uiout, "depth", i);
+
+  return MI_CMD_DONE;
+}
+
+/* Print a list of the locals for the current frame. With argument of
+   0, print only the names, with argument of 1 print also the
+   values. */
+enum mi_cmd_result
+mi_cmd_stack_list_locals (char *command, char **argv, int argc)
+{
+  if (argc != 1)
+    error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES");
+
+  list_args_or_locals (1, atoi (argv[0]), selected_frame);
+  return MI_CMD_DONE;
+}
+
+/* Print a list of the arguments for the current frame. With argument
+   of 0, print only the names, with argument of 1 print also the
+   values. */
+enum mi_cmd_result
+mi_cmd_stack_list_args (char *command, char **argv, int argc)
+{
+  int frame_low;
+  int frame_high;
+  int i;
+  struct frame_info *fi;
+
+  if (argc < 1 || argc > 3 || argc == 2)
+    error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]");
+
+  if (argc == 3)
+    {
+      frame_low = atoi (argv[1]);
+      frame_high = atoi (argv[2]);
+    }
+  else
+    {
+      /* Called with no arguments, it means we want args for the whole
+         backtrace. */
+      frame_low = -1;
+      frame_high = -1;
+    }
+
+  /* Let's position fi on the frame at which to start the
+     display. Could be the innermost frame if the whole stack needs
+     displaying, or if frame_low is 0. */
+  for (i = 0, fi = get_current_frame ();
+       fi && i < frame_low;
+       i++, fi = get_prev_frame (fi));
+
+  if (fi == NULL)
+    error ("mi_cmd_stack_list_args: Not enough frames in stack.");
+
+  ui_out_list_begin (uiout, "stack-args");
+
+  /* Now let's print the frames up to frame_high, or until there are
+     frames in the stack. */
+  for (;
+       fi && (i <= frame_high || frame_high == -1);
+       i++, fi = get_prev_frame (fi))
+    {
+      QUIT;
+      ui_out_list_begin (uiout, "frame");
+      ui_out_field_int (uiout, "level", i);
+      list_args_or_locals (0, atoi (argv[0]), fi);
+      ui_out_list_end (uiout);
+    }
+
+  ui_out_list_end (uiout);
+  if (i < frame_high)
+    error ("mi_cmd_stack_list_args: Not enough frames in stack.");
+
+  return MI_CMD_DONE;
+}
+
+/* Print a list of the locals or the arguments for the currently
+   selected frame.  If the argument passed is 0, printonly the names
+   of the variables, if an argument of 1 is passed, print the values
+   as well. */
+static void
+list_args_or_locals (int locals, int values, struct frame_info *fi)
+{
+  struct block *block;
+  struct symbol *sym;
+  int i, nsyms;
+  int print_me = 0;
+  static struct ui_stream *stb = NULL;
+
+  stb = ui_out_stream_new (uiout);
+
+  block = get_frame_block (fi);
+
+  ui_out_list_begin (uiout, locals ? "locals" : "args");
+
+  while (block != 0)
+    {
+      nsyms = BLOCK_NSYMS (block);
+      for (i = 0; i < nsyms; i++)
+       {
+         sym = BLOCK_SYM (block, i);
+         switch (SYMBOL_CLASS (sym))
+           {
+           default:
+           case LOC_UNDEF:     /* catches errors        */
+           case LOC_CONST:     /* constant              */
+           case LOC_TYPEDEF:   /* local typedef         */
+           case LOC_LABEL:     /* local label           */
+           case LOC_BLOCK:     /* local function        */
+           case LOC_CONST_BYTES:       /* loc. byte seq.        */
+           case LOC_UNRESOLVED:        /* unresolved static     */
+           case LOC_OPTIMIZED_OUT:     /* optimized out         */
+             print_me = 0;
+             break;
+
+           case LOC_ARG:       /* argument              */
+           case LOC_REF_ARG:   /* reference arg         */
+           case LOC_REGPARM:   /* register arg          */
+           case LOC_REGPARM_ADDR:      /* indirect register arg */
+           case LOC_LOCAL_ARG: /* stack arg             */
+           case LOC_BASEREG_ARG:       /* basereg arg           */
+             if (!locals)
+               print_me = 1;
+             break;
+
+           case LOC_LOCAL:     /* stack local           */
+           case LOC_BASEREG:   /* basereg local         */
+           case LOC_STATIC:    /* static                */
+           case LOC_REGISTER:  /* register              */
+             if (locals)
+               print_me = 1;
+             break;
+           }
+         if (print_me)
+           {
+             if (values)
+               ui_out_list_begin (uiout, NULL);
+             ui_out_field_string (uiout, "name", SYMBOL_NAME (sym));
+
+             if (values)
+               {
+                 struct symbol *sym2;
+                 if (!locals)
+                   sym2 = lookup_symbol (SYMBOL_NAME (sym),
+                                         block, VAR_NAMESPACE,
+                                         (int *) NULL,
+                                         (struct symtab **) NULL);
+                 else
+                   sym2 = sym;
+                 print_variable_value (sym2, fi, stb->stream);
+                 ui_out_field_stream (uiout, "value", stb);
+                 ui_out_list_end (uiout);
+               }
+           }
+       }
+      if (BLOCK_FUNCTION (block))
+       break;
+      else
+       block = BLOCK_SUPERBLOCK (block);
+    }
+  ui_out_list_end (uiout);
+  ui_out_stream_delete (stb);
+}
+
+enum mi_cmd_result
+mi_cmd_stack_select_frame (char *command, char **argv, int argc)
+{
+#ifdef UI_OUT
+  if (!target_has_stack)
+    error ("mi_cmd_stack_select_frame: No stack.");
+
+  if (argc > 1)
+    error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
+
+  /* with no args, don't change frame */
+  if (argc == 0)
+    select_frame_command_wrapper (0, 1 /* not used */ );
+  else
+    select_frame_command_wrapper (argv[0], 1 /* not used */ );
+#endif
+  return MI_CMD_DONE;
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
new file mode 100644 (file)
index 0000000..cf94496
--- /dev/null
@@ -0,0 +1,474 @@
+/* MI Command Set - varobj commands.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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 "ui-out.h"
+#include "mi-out.h"
+#include "varobj.h"
+#include "value.h"
+#include <ctype.h>
+
+/* Convenience macro for allocting typesafe memory. */
+
+#undef XMALLOC
+#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
+
+extern int varobjdebug;                /* defined in varobj.c */
+
+static void varobj_update_one (struct varobj *var);
+
+/* VAROBJ operations */
+
+enum mi_cmd_result
+mi_cmd_var_create (char *command, char **argv, int argc)
+{
+  CORE_ADDR frameaddr;
+  struct varobj *var;
+  char *name;
+  char *frame;
+  char *expr;
+  char *type;
+  struct cleanup *old_cleanups;
+
+  if (argc != 3)
+    {
+      /*      asprintf (&mi_error_message,
+         "mi_cmd_var_create: Usage: .");
+         return MI_CMD_ERROR; */
+      error ("mi_cmd_var_create: Usage: NAME FRAME EXPRESSION.");
+    }
+
+  name = xstrdup (argv[0]);
+  /* Add cleanup for name. Must be free_current_contents as
+     name can be reallocated */
+  old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents,
+                              &name);
+
+  frame = xstrdup (argv[1]);
+  old_cleanups = make_cleanup (free, frame);
+
+  expr = xstrdup (argv[2]);
+
+  if (strcmp (name, "-") == 0)
+    {
+      free (name);
+      name = varobj_gen_name ();
+    }
+  else if (!isalpha (*name))
+    error ("mi_cmd_var_create: name of object must begin with a letter");
+
+  if (strcmp (frame, "*") == 0)
+    frameaddr = -1;
+  else
+    frameaddr = parse_and_eval_address (frame);
+
+  if (varobjdebug)
+    fprintf_unfiltered (gdb_stdlog,
+                   "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n",
+                       name, frame, paddr (frameaddr), expr);
+
+  var = varobj_create (name, expr, frameaddr);
+
+  if (var == NULL)
+    error ("mi_cmd_var_create: unable to create variable object");
+
+  ui_out_field_string (uiout, "name", name);
+  ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
+  type = varobj_get_type (var);
+  if (type == NULL)
+    ui_out_field_string (uiout, "type", "");
+  else
+    {
+      ui_out_field_string (uiout, "type", type);
+      free (type);
+    }
+
+  do_cleanups (old_cleanups);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_delete (char *command, char **argv, int argc)
+{
+  char *name;
+  char *expr;
+  struct varobj *var;
+  int numdel;
+  int children_only_p = 0;
+  struct cleanup *old_cleanups;
+
+  if (argc < 1 || argc > 2)
+    error ("mi_cmd_var_delete: Usage: [-c] EXPRESSION.");
+
+  name = xstrdup (argv[0]);
+  /* Add cleanup for name. Must be free_current_contents as
+     name can be reallocated */
+  old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents,
+                              &name);
+
+  /* If we have one single argument it cannot be '-c' or any string
+     starting with '-'. */
+  if (argc == 1)
+    {
+      if (strcmp (name, "-c") == 0)
+       error ("mi_cmd_var_delete: Missing required argument after '-c': variable object name");
+      if (*name == '-')
+       error ("mi_cmd_var_delete: Illegal variable object name");
+    }
+
+  /* If we have 2 arguments they must be '-c' followed by a string
+     which would be the variable name. */
+  if (argc == 2)
+    {
+      expr = xstrdup (argv[1]);
+      if (strcmp (name, "-c") != 0)
+       error ("mi_cmd_var_delete: Invalid option.");
+      children_only_p = 1;
+      free (name);
+      name = xstrdup (expr);
+      free (expr);
+    }
+
+  /* If we didn't error out, now NAME contains the name of the
+     variable. */
+
+  var = varobj_get_handle (name);
+
+  if (var == NULL)
+    error ("mi_cmd_var_delete: Variable object not found.");
+
+  numdel = varobj_delete (var, NULL, children_only_p);
+
+  ui_out_field_int (uiout, "ndeleted", numdel);
+
+  do_cleanups (old_cleanups);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_set_format (char *command, char **argv, int argc)
+{
+  enum varobj_display_formats format;
+  int len;
+  struct varobj *var;
+  char *formspec;
+
+  if (argc != 2)
+    error ("mi_cmd_var_set_format: Usage: NAME FORMAT.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+
+  if (var == NULL)
+    error ("mi_cmd_var_set_format: Variable object not found");
+
+  formspec = xstrdup (argv[1]);
+  if (formspec == NULL)
+    error ("mi_cmd_var_set_format: Must specify the format as: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\"");
+
+  len = strlen (formspec);
+
+  if (STREQN (formspec, "natural", len))
+    format = FORMAT_NATURAL;
+  else if (STREQN (formspec, "binary", len))
+    format = FORMAT_BINARY;
+  else if (STREQN (formspec, "decimal", len))
+    format = FORMAT_DECIMAL;
+  else if (STREQN (formspec, "hexadecimal", len))
+    format = FORMAT_HEXADECIMAL;
+  else if (STREQN (formspec, "octal", len))
+    format = FORMAT_OCTAL;
+  else
+    error ("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\"");
+
+  /* Set the format of VAR to given format */
+  varobj_set_display_format (var, format);
+
+  /* Report the new current format */
+  ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_show_format (char *command, char **argv, int argc)
+{
+  enum varobj_display_formats format;
+  struct varobj *var;
+
+  if (argc != 1)
+    error ("mi_cmd_var_show_format: Usage: NAME.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+  if (var == NULL)
+    error ("mi_cmd_var_show_format: Variable object not found");
+
+  format = varobj_get_display_format (var);
+
+  /* Report the current format */
+  ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_num_children (char *command, char **argv, int argc)
+{
+  struct varobj *var;
+
+  if (argc != 1)
+    error ("mi_cmd_var_info_num_children: Usage: NAME.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+  if (var == NULL)
+    error ("mi_cmd_var_info_num_children: Variable object not found");
+
+  ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_list_children (char *command, char **argv, int argc)
+{
+  struct varobj *var;
+  struct varobj **childlist;
+  struct varobj **cc;
+  int numchild;
+  char *type;
+
+  if (argc != 1)
+    error ("mi_cmd_var_list_children: Usage: NAME.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+  if (var == NULL)
+    error ("mi_cmd_var_list_children: Variable object not found");
+
+  numchild = varobj_list_children (var, &childlist);
+  ui_out_field_int (uiout, "numchild", numchild);
+
+  if (numchild <= 0)
+    return MI_CMD_DONE;
+
+  ui_out_list_begin (uiout, "children");
+  cc = childlist;
+  while (*cc != NULL)
+    {
+      ui_out_list_begin (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));
+      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_list_end (uiout);
+      cc++;
+    }
+  ui_out_list_end (uiout);
+  free (childlist);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_type (char *command, char **argv, int argc)
+{
+  struct varobj *var;
+
+  if (argc != 1)
+    error ("mi_cmd_var_info_type: Usage: NAME.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+  if (var == NULL)
+    error ("mi_cmd_var_info_type: Variable object not found");
+
+  ui_out_field_string (uiout, "type", varobj_get_type (var));
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_expression (char *command, char **argv, int argc)
+{
+  enum varobj_languages lang;
+  struct varobj *var;
+
+  if (argc != 1)
+    error ("mi_cmd_var_info_expression: Usage: NAME.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+  if (var == NULL)
+    error ("mi_cmd_var_info_expression: Variable object not found");
+
+  lang = varobj_get_language (var);
+
+  ui_out_field_string (uiout, "lang", varobj_language_string[(int) lang]);
+  ui_out_field_string (uiout, "exp", varobj_get_expression (var));
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_show_attributes (char *command, char **argv, int argc)
+{
+  int attr;
+  char *attstr;
+  struct varobj *var;
+
+  if (argc != 1)
+    error ("mi_cmd_var_show_attributes: Usage: NAME.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+  if (var == NULL)
+    error ("mi_cmd_var_show_attributes: Variable object not found");
+
+  attr = varobj_get_attributes (var);
+  /* FIXME: define masks for attributes */
+  if (attr & 0x00000001)
+    attstr = "editable";
+  else
+    attstr = "noneditable";
+
+  ui_out_field_string (uiout, "attr", attstr);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
+{
+  struct varobj *var;
+
+  if (argc != 1)
+    error ("mi_cmd_var_evaluate_expression: Usage: NAME.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+  if (var == NULL)
+    error ("mi_cmd_var_evaluate_expression: Variable object not found");
+
+  ui_out_field_string (uiout, "value", varobj_get_value (var));
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_assign (char *command, char **argv, int argc)
+{
+  struct varobj *var;
+  char *expression;
+
+  if (argc != 2)
+    error ("mi_cmd_var_assign: Usage: NAME EXPRESSION.");
+
+  /* Get varobj handle, if a valid var obj name was specified */
+  var = varobj_get_handle (argv[0]);
+  if (var == NULL)
+    error ("mi_cmd_var_assign: Variable object not found");
+
+  /* FIXME: define masks for attributes */
+  if (!(varobj_get_attributes (var) & 0x00000001))
+    error ("mi_cmd_var_assign: Variable object is not editable");
+
+  expression = xstrdup (argv[1]);
+
+  if (!varobj_set_value (var, expression))
+    error ("mi_cmd_var_assign: Could not assign expression to varible object");
+
+  ui_out_field_string (uiout, "value", varobj_get_value (var));
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_update (char *command, char **argv, int argc)
+{
+  struct varobj *var;
+  struct varobj **rootlist;
+  struct varobj **cr;
+  char *name;
+  int nv;
+
+  if (argc != 1)
+    error ("mi_cmd_var_update: Usage: NAME.");
+
+  name = argv[0];
+
+  /* Check if the parameter is a "*" which means that we want
+     to update all variables */
+
+  if ((*name == '*') && (*(name + 1) == '\0'))
+    {
+      nv = varobj_list (&rootlist);
+      ui_out_list_begin (uiout, "changelist");
+      if (nv <= 0)
+       {
+         ui_out_list_end (uiout);
+         return MI_CMD_DONE;
+       }
+      cr = rootlist;
+      while (*cr != NULL)
+       {
+         varobj_update_one (*cr);
+         cr++;
+       }
+      free (rootlist);
+      ui_out_list_end (uiout);
+    }
+  else
+    {
+      /* Get varobj handle, if a valid var obj name was specified */
+      var = varobj_get_handle (name);
+      if (var == NULL)
+       error ("mi_cmd_var_update: Variable object not found");
+
+      ui_out_list_begin (uiout, "changelist");
+      varobj_update_one (var);
+      ui_out_list_end (uiout);
+    }
+  return MI_CMD_DONE;
+}
+
+/* Helper for mi_cmd_var_update() */
+
+static void
+varobj_update_one (struct varobj *var)
+{
+  struct varobj **changelist;
+  struct varobj **cc;
+  int nc;
+
+  nc = varobj_update (var, &changelist);
+
+  if (nc <= 0)
+    return;
+
+  cc = changelist;
+  while (*cc != NULL)
+    {
+      ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
+      cc++;
+    }
+  free (changelist);
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
new file mode 100644 (file)
index 0000000..f0d4fc8
--- /dev/null
@@ -0,0 +1,263 @@
+/* MI Command Set.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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 "top.h"
+#include "mi-cmds.h"
+#include <string.h>
+
+extern void _initialize_mi_cmds (void);
+struct mi_cmd;
+static struct mi_cmd **lookup_table (const char *command);
+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},
+  {"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,}
+};
+
+/* Pointer to the mi command table (built at run time) */
+
+static struct mi_cmd **mi_table;
+
+/* A prime large enough to accomodate the entire command table */
+enum
+  {
+    MI_TABLE_SIZE = 227
+  };
+
+/* Exported function used to obtain info from the table */
+struct mi_cmd *
+mi_lookup (const char *command)
+{
+  return *lookup_table (command);
+}
+
+/* stat collecting */
+struct mi_cmd_stats
+{
+  int hit;
+  int miss;
+  int rehash;
+};
+struct mi_cmd_stats stats;
+
+/* our lookup function */
+static struct mi_cmd **
+lookup_table (const char *command)
+{
+  const char *chp;
+  unsigned int index = 0;
+  /* compute our hash */
+  for (chp = command; *chp; chp++)
+    {
+      /* some what arbitrary */
+      index = ((index << 6) + (unsigned int) *chp) % MI_TABLE_SIZE;
+    }
+  /* look it up */
+  while (1)
+    {
+      struct mi_cmd **entry = &mi_table[index];
+      if ((*entry) == 0)
+       {
+         /* not found, return pointer to next free. */
+         stats.miss++;
+         return entry;
+       }
+      if (strcmp (command, (*entry)->name) == 0)
+       {
+         stats.hit++;
+         return entry;         /* found */
+       }
+      index = (index + 1) % MI_TABLE_SIZE;
+      stats.rehash++;
+    }
+}
+
+static void
+build_table (struct mi_cmd *commands)
+{
+  int nr_rehash = 0;
+  int nr_entries = 0;
+  struct mi_cmd *command;
+  int sizeof_table = sizeof (struct mi_cmd **) * MI_TABLE_SIZE;
+
+  mi_table = xmalloc (sizeof_table);
+  memset (mi_table, 0, sizeof_table);
+  for (command = commands; command->name != 0; command++)
+    {
+      struct mi_cmd **entry = lookup_table (command->name);
+      if (*entry)
+       internal_error ("command `%s' appears to be duplicated",
+                       command->name);
+      *entry = command;
+      if (0)
+       {
+         fprintf_unfiltered (gdb_stdlog, "%-30s %2d\n",
+                             command->name, stats.rehash - nr_rehash);
+       }
+      nr_entries++;
+      nr_rehash = stats.rehash;
+    }
+  if (0)
+    {
+      fprintf_filtered (gdb_stdlog, "Average %3.1f\n",
+                       (double) nr_rehash / (double) nr_entries);
+    }
+}
+
+void
+_initialize_mi_cmds ()
+{
+  build_table (mi_cmds);
+  memset (&stats, 0, sizeof (stats));
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
new file mode 100644 (file)
index 0000000..3b4f73e
--- /dev/null
@@ -0,0 +1,128 @@
+/* MI Command Set.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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_CMDS_H
+#define MI_CMDS_H
+
+/* An MI command can return any of the following. */
+
+enum mi_cmd_result
+  {
+    /* Report the command as ``done''.  Display both the ``NNN^done''
+       message and the completion prompt.  */
+    MI_CMD_DONE = 0,
+    /* The command is still running in the forground.  Main loop should
+       display the completion prompt. */
+    MI_CMD_FORGROUND,
+    /* An error condition was detected and an error message was
+       asprintf'd into the mi_error_message buffer.  The main loop will
+       display the error message and the completion prompt. */
+    MI_CMD_ERROR,
+    /* An error condition was detected and caught.  The error message is
+       in the global error message buffer. The main loop will display
+       the error message and the completion prompt. */
+    MI_CMD_CAUGHT_ERROR,
+    /* The MI command has already displayed its completion message.
+       Main loop will not display a completion message but will display
+       the completion prompt. */
+    MI_CMD_QUIET
+  };
+
+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
+   commands are flushed. */
+
+typedef enum mi_cmd_result (mi_cmd_args_ftype) ( /*ui */ char *args, int from_tty);
+
+/* Function implementing each command */
+extern mi_cmd_argv_ftype mi_cmd_break_insert;
+extern mi_cmd_argv_ftype mi_cmd_break_watch;
+extern mi_cmd_argv_ftype mi_cmd_disassemble;
+extern mi_cmd_argv_ftype mi_cmd_data_evaluate_expression;
+extern mi_cmd_argv_ftype mi_cmd_data_list_register_names;
+extern mi_cmd_argv_ftype mi_cmd_data_list_register_values;
+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_args_ftype mi_cmd_exec_continue;
+extern mi_cmd_args_ftype mi_cmd_exec_finish;
+extern mi_cmd_args_ftype mi_cmd_exec_next;
+extern mi_cmd_args_ftype mi_cmd_exec_next_instruction;
+extern mi_cmd_args_ftype mi_cmd_exec_return;
+extern mi_cmd_args_ftype mi_cmd_exec_run;
+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_gdb_exit;
+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_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;
+extern mi_cmd_argv_ftype mi_cmd_thread_select;
+extern mi_cmd_argv_ftype mi_cmd_var_assign;
+extern mi_cmd_argv_ftype mi_cmd_var_create;
+extern mi_cmd_argv_ftype mi_cmd_var_delete;
+extern mi_cmd_argv_ftype mi_cmd_var_evaluate_expression;
+extern mi_cmd_argv_ftype mi_cmd_var_info_expression;
+extern mi_cmd_argv_ftype mi_cmd_var_info_num_children;
+extern mi_cmd_argv_ftype mi_cmd_var_info_type;
+extern mi_cmd_argv_ftype mi_cmd_var_list_children;
+extern mi_cmd_argv_ftype mi_cmd_var_set_format;
+extern mi_cmd_argv_ftype mi_cmd_var_show_attributes;
+extern mi_cmd_argv_ftype mi_cmd_var_show_format;
+extern mi_cmd_argv_ftype mi_cmd_var_update;
+
+/* Description of a single command. */
+
+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;
+  };
+
+/* Lookup a command in the mi comand table */
+
+extern struct mi_cmd *mi_lookup (const char *command);
+
+/* Debug flag */
+extern int mi_debug_p;
+
+/* Raw console output - FIXME: should this be a parameter? */
+extern struct ui_file *raw_stdout;
+
+#endif
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-console.c b/gdb/mi/mi-console.c
new file mode 100644 (file)
index 0000000..3bf6a73
--- /dev/null
@@ -0,0 +1,118 @@
+/* MI Console code.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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-console.h"
+#include <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;
+static ui_file_flush_ftype mi_console_file_flush;
+static ui_file_delete_ftype mi_console_file_delete;
+
+struct mi_console_file
+  {
+    int *magic;
+    struct ui_file *raw;
+    struct ui_file *buffer;
+    const char *prefix;
+  };
+
+int mi_console_file_magic;
+
+struct ui_file *
+mi_console_file_new (struct ui_file *raw,
+                    const char *prefix)
+{
+  struct ui_file *ui_file = ui_file_new ();
+  struct mi_console_file *mi_console = XMALLOC (struct mi_console_file);
+  mi_console->magic = &mi_console_file_magic;
+  mi_console->raw = raw;
+  mi_console->buffer = mem_fileopen ();
+  mi_console->prefix = prefix;
+  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);
+  return ui_file;
+}
+
+static void
+mi_console_file_delete (struct ui_file *file)
+{
+  struct mi_console_file *mi_console = ui_file_data (file);
+  if (mi_console->magic != &mi_console_file_magic)
+    internal_error ("mi_console_file_delete: bad magic number");
+  free (mi_console);
+}
+
+static void
+mi_console_file_fputs (const char *buf,
+                      struct ui_file *file)
+{
+  struct mi_console_file *mi_console = ui_file_data (file);
+  if (mi_console->magic != &mi_console_file_magic)
+    internal_error ("mi_console_file_fputs: bad magic number");
+  /* Append the text to our internal buffer */
+  fputs_unfiltered (buf, mi_console->buffer);
+  /* Flush when an embedded \n */
+  if (strchr (buf, '\n') != NULL)
+    gdb_flush (file);
+}
+
+/* Transform a byte sequence into a console output packet. */
+static void
+mi_console_raw_packet (void *data,
+                      const char *buf,
+                      long length_buf)
+{
+  struct mi_console_file *mi_console = data;
+  if (mi_console->magic != &mi_console_file_magic)
+    internal_error ("mi_console_file_transform: bad magic number");
+
+  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);
+      gdb_flush (mi_console->raw);
+    }
+}
+
+static void
+mi_console_file_flush (struct ui_file *file)
+{
+  struct mi_console_file *mi_console = ui_file_data (file);
+  if (mi_console->magic != &mi_console_file_magic)
+    internal_error ("mi_console_file_flush: bad magic number");
+  ui_file_put (mi_console->buffer, mi_console_raw_packet, mi_console);
+  ui_file_rewind (mi_console->buffer);
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-console.h b/gdb/mi/mi-console.h
new file mode 100644 (file)
index 0000000..80cfec9
--- /dev/null
@@ -0,0 +1,31 @@
+/* MI Command Set - MI Console.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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_CONSOLE_H
+#define MI_CONSOLE_H
+
+extern struct ui_file *mi_console_file_new (struct ui_file *raw, const char *prefix);
+
+#endif
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-getopt.c b/gdb/mi/mi-getopt.c
new file mode 100644 (file)
index 0000000..4a3758a
--- /dev/null
@@ -0,0 +1,80 @@
+/* MI Command Set - MI Option Parser.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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-getopt.h"
+#include "string.h"
+
+int
+mi_getopt (const char *prefix,
+          int argc, char **argv,
+          struct mi_opt *opts,
+          int *optind, char **optarg)
+{
+  char *arg;
+  struct mi_opt *opt;
+  /* We assume that argv/argc are ok. */
+  if (*optind > argc || *optind < 0)
+    internal_error ("mi_getopt_long: optind out of bounds");
+  if (*optind == argc)
+    return -1;
+  arg = argv[*optind];
+  /* ``--''? */
+  if (strcmp (arg, "--") == 0)
+    {
+      *optind += 1;
+      *optarg = NULL;
+      return -1;
+    }
+  /* End of option list. */
+  if (arg[0] != '-')
+    {
+      *optarg = NULL;
+      return -1;
+    }
+  /* Look the option up. */
+  for (opt = opts; opt->name != NULL; opt++)
+    {
+      if (strcmp (opt->name, arg + 1) != 0)
+       continue;
+      if (opt->arg_p)
+       {
+         /* A non-simple optarg option. */
+         if (argc < *optind + 2)
+           error ("%s: Option %s requires an argument", prefix, arg);
+         *optarg = argv[(*optind) + 1];
+         *optind = (*optind) + 2;
+         return opt->index;
+       }
+      else
+       {
+         *optarg = NULL;
+         *optind = (*optind) + 1;
+         return opt->index;
+       }
+    }
+  error ("%s: Unknown option ``%s''", prefix, arg + 1);
+}
+
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-getopt.h b/gdb/mi/mi-getopt.h
new file mode 100644 (file)
index 0000000..d633d43
--- /dev/null
@@ -0,0 +1,64 @@
+/* MI Option Parser.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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_GETOPT_H
+#define MI_GETOPT_H
+
+/* Like getopt() but with simpler semantics.
+
+   An option has the form ``-<name>''. The special option ``--''
+   denotes the end of the option list. An option can be followed by a
+   separate argument (on a per option basis).
+
+   On entry OPTIND contains the index of the next element of ARGV that
+   needs parsing.  OPTIND is updated to indicate the index of the next
+   argument before mi_getopt() returns.
+
+   If ARGV[OPTIND] is an option, that options INDEX is returned.
+   OPTARG is set to the options argument or NULL.  OPTIND is updated.
+
+   If ARGV[OPTIND] is not an option, -1 is returned and OPTIND updated
+   to specify the non-option argument.  OPTARG is set to NULL.
+
+   mi_getopt() calls ``error("%s: Unknown option %c", prefix,
+   option)'' if an unknown option is encountered. */
+
+struct mi_opt;
+extern int mi_getopt (const char *prefix, int argc, char **argv,
+                     struct mi_opt *opt, int *optind, char **optarg);
+
+/* The option list.  Terminated by NAME==NULL.  ARG_P that the option
+   requires an argument.  INDEX is returned to identify th option. */
+
+struct mi_opt
+  {
+    const char *name;
+    int index;
+    int arg_p;
+  };
+
+struct mi_opt;
+
+#endif
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
new file mode 100644 (file)
index 0000000..ec7f05e
--- /dev/null
@@ -0,0 +1,1446 @@
+/* MI Command Set.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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.  */
+
+/* Work in progress */
+
+#include "defs.h"
+#include "target.h"
+#include "inferior.h"
+#include "gdb_string.h"
+#include "top.h"
+#include "gdbthread.h"
+#include "mi-cmds.h"
+#include "mi-parse.h"
+#include "mi-getopt.h"
+#include "mi-console.h"
+#include "ui-out.h"
+#include "mi-out.h"
+#include "event-loop.h"
+#include "event-top.h"
+#include "gdbcore.h"           /* for write_memory() */
+#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
+  };
+
+
+int mi_debug_p;
+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;
+static char *old_regs;
+
+extern void _initialize_mi_main (void);
+static char *mi_input (char *);
+static void mi_execute_command (char *cmd, int from_tty);
+static enum mi_cmd_result mi_cmd_execute (struct mi_parse *parse);
+
+static void mi_execute_cli_command (const char *cli, char *args);
+static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty);
+static void mi_execute_command_wrapper (char *cmd);
+
+void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg);
+static void free_and_reset (char **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);
+
+#ifdef UI_OUT
+/* 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);
+#endif
+
+/* Command implementations. FIXME: Is this libgdb? No.  This is the MI
+   layer that calls libgdb.  Any operation used in the below should be
+   formalized. */
+
+enum mi_cmd_result
+mi_cmd_gdb_exit (char *command, char **argv, int argc)
+{
+  /* We have to print everything right here because we never return */
+  if (last_async_command)
+    fputs_unfiltered (last_async_command, raw_stdout);
+  fputs_unfiltered ("^exit\n", raw_stdout);
+  mi_out_put (uiout, raw_stdout);
+  /* FIXME: The function called is not yet a formal libgdb function */
+  quit_force (NULL, FROM_TTY);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_exec_run (char *args, int from_tty)
+{
+  /* FIXME: Should call a libgdb function, not a cli wrapper */
+  return mi_execute_async_cli_command ("run", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_next (char *args, int from_tty)
+{
+  /* FIXME: Should call a libgdb function, not a cli wrapper */
+  return mi_execute_async_cli_command ("next", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_next_instruction (char *args, int from_tty)
+{
+  /* FIXME: Should call a libgdb function, not a cli wrapper */
+  return mi_execute_async_cli_command ("nexti", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_step (char *args, int from_tty)
+{
+  /* FIXME: Should call a libgdb function, not a cli wrapper */
+  return mi_execute_async_cli_command ("step", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_step_instruction (char *args, int from_tty)
+{
+  /* FIXME: Should call a libgdb function, not a cli wrapper */
+  return mi_execute_async_cli_command ("stepi", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_finish (char *args, int from_tty)
+{
+  /* FIXME: Should call a libgdb function, not a cli wrapper */
+  return mi_execute_async_cli_command ("finish", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_until (char *args, int from_tty)
+{
+  /* FIXME: Should call a libgdb function, not a cli wrapper */
+  return mi_execute_async_cli_command ("until", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_return (char *args, int from_tty)
+{
+#ifdef UI_OUT
+  /* This command doesn't really execute the target, it just pops the
+     specified number of frames. */
+  if (*args)
+    /* Call return_command with from_tty argument equal to 0 so as to
+       avoid being queried. */
+    return_command_wrapper (args, 0);
+  else
+    /* Call return_command with from_tty argument equal to 0 so as to
+       avoid being queried. */
+    return_command_wrapper (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);
+#endif
+
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_exec_continue (char *args, int from_tty)
+{
+  /* FIXME: Should call a libgdb function, not a cli wrapper */
+  return mi_execute_async_cli_command ("continue", args, from_tty);
+}
+
+/* Interrupt the execution of the target. Note how we must play around
+   with the token varialbes, in order to display the current token in
+   the result of the interrupt command, and the previous execution
+   token when the target finally stops. See comments in
+   mi_cmd_execute. */
+enum mi_cmd_result
+mi_cmd_exec_interrupt (char *args, int from_tty)
+{
+#ifdef UI_OUT
+  if (!target_executing)
+    {
+      asprintf (&mi_error_message, "mi_cmd_exec_interrupt: Inferior not executing.");
+      return MI_CMD_ERROR;
+    }
+  interrupt_target_command_wrapper (args, from_tty);
+  if (last_async_command)
+    fputs_unfiltered (last_async_command, raw_stdout);
+  fputs_unfiltered ("^done", raw_stdout);
+  free (last_async_command);
+  if (previous_async_command)
+    last_async_command = xstrdup (previous_async_command);
+  free (previous_async_command);
+  previous_async_command = NULL;
+  mi_out_put (uiout, raw_stdout);
+  mi_out_rewind (uiout);
+  fputs_unfiltered ("\n", raw_stdout);
+#endif
+  return MI_CMD_QUIET;
+}
+
+enum mi_cmd_result
+mi_cmd_thread_select (char *command, char **argv, int argc)
+{
+  enum gdb_rc rc;
+
+  if (argc != 1)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_thread_select: USAGE: threadnum.");
+      return MI_CMD_ERROR;
+    }
+  else
+    rc = gdb_thread_select (argv[0]);
+
+  if (rc == GDB_RC_FAIL)
+    return MI_CMD_CAUGHT_ERROR;
+  else
+    return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_thread_list_ids (char *command, char **argv, int argc)
+{
+  enum gdb_rc rc = MI_CMD_DONE;
+
+  if (argc != 0)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_thread_list_ids: No arguments required.");
+      return MI_CMD_ERROR;
+    }
+  else
+#ifdef UI_OUT
+    rc = gdb_list_thread_ids ();
+#endif
+
+  if (rc == GDB_RC_FAIL)
+    return MI_CMD_CAUGHT_ERROR;
+  else
+    return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_data_list_register_names (char *command, char **argv, int argc)
+{
+  int regnum, numregs;
+  int i;
+
+  /* Note that the test for a valid register must include checking the
+     REGISTER_NAME because NUM_REGS may be allocated for the union of
+     the register sets within a family of related processors.  In this
+     case, some entries of REGISTER_NAME will change depending upon
+     the particular processor being debugged.  */
+
+  numregs = ARCH_NUM_REGS;
+
+  ui_out_list_begin (uiout, "register-names");
+
+  if (argc == 0)               /* No args, just do all the regs */
+    {
+      for (regnum = 0;
+          regnum < numregs;
+          regnum++)
+       {
+         if (REGISTER_NAME (regnum) == NULL
+             || *(REGISTER_NAME (regnum)) == '\0')
+           continue;
+
+         ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum));
+       }
+    }
+
+  /* Else, list of register #s, just do listed regs */
+  for (i = 0; i < argc; i++)
+    {
+      regnum = atoi (argv[i]);
+
+      if (regnum >= 0
+         && regnum < numregs
+         && REGISTER_NAME (regnum) != NULL
+         && *REGISTER_NAME (regnum) != '\000')
+       ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum));
+      else
+       {
+         asprintf (&mi_error_message, "bad register number");
+         return MI_CMD_ERROR;
+       }
+    }
+  ui_out_list_end (uiout);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
+{
+  int regnum, numregs, changed;
+  int i;
+
+  /* Note that the test for a valid register must include checking the
+     REGISTER_NAME because NUM_REGS may be allocated for the union of
+     the register sets within a family of related processors.  In this
+     case, some entries of REGISTER_NAME will change depending upon
+     the particular processor being debugged.  */
+
+  numregs = ARCH_NUM_REGS;
+
+  ui_out_list_begin (uiout, "changed-registers");
+
+  if (argc == 0)               /* No args, just do all the regs */
+    {
+      for (regnum = 0;
+          regnum < numregs;
+          regnum++)
+       {
+         if (REGISTER_NAME (regnum) == NULL
+             || *(REGISTER_NAME (regnum)) == '\0')
+           continue;
+         changed = register_changed_p (regnum);
+         if (changed < 0)
+           {
+             asprintf (&mi_error_message,
+                       "mi_cmd_data_list_changed_registers: Unable to read register contents.");
+             return MI_CMD_ERROR;
+           }
+         else if (changed)
+           ui_out_field_int (uiout, NULL, regnum);
+       }
+    }
+
+  /* Else, list of register #s, just do listed regs */
+  for (i = 0; i < argc; i++)
+    {
+      regnum = atoi (argv[i]);
+
+      if (regnum >= 0
+         && regnum < numregs
+         && REGISTER_NAME (regnum) != NULL
+         && *REGISTER_NAME (regnum) != '\000')
+       {
+         changed = register_changed_p (regnum);
+         if (changed < 0)
+           {
+             asprintf (&mi_error_message,
+                       "mi_cmd_data_list_register_change: Unable to read register contents.");
+             return MI_CMD_ERROR;
+           }
+         else if (changed)
+           ui_out_field_int (uiout, NULL, regnum);
+       }
+      else
+       {
+         asprintf (&mi_error_message, "bad register number");
+         return MI_CMD_ERROR;
+       }
+    }
+  ui_out_list_end (uiout);
+  return MI_CMD_DONE;
+}
+
+static int
+register_changed_p (int regnum)
+{
+  char raw_buffer[MAX_REGISTER_RAW_SIZE];
+
+  if (read_relative_register_raw_bytes (regnum, raw_buffer))
+    return -1;
+
+  if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
+             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));
+
+  return 1;
+}
+
+/* Return a list of register number and value pairs. The valid
+   arguments expected are: a letter indicating the format in which to
+   display the registers contents. This can be one of: x (hexadecimal), d
+   (decimal), N (natural), t (binary), o (octal), r (raw).  After the
+   format argumetn there can be a sequence of numbers, indicating which
+   registers to fetch the content of. If the format is the only argument,
+   a list of all the registers with their values is returned. */
+enum mi_cmd_result
+mi_cmd_data_list_register_values (char *command, char **argv, int argc)
+{
+  int regnum, numregs, format, result;
+  int i;
+
+  /* Note that the test for a valid register must include checking the
+     REGISTER_NAME because NUM_REGS may be allocated for the union of
+     the register sets within a family of related processors.  In this
+     case, some entries of REGISTER_NAME will change depending upon
+     the particular processor being debugged.  */
+
+  numregs = ARCH_NUM_REGS;
+
+  if (argc == 0)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> [<regnum1>...<regnumN>]");
+      return MI_CMD_ERROR;
+    }
+
+  format = (int) argv[0][0];
+
+  if (!target_has_registers)
+    {
+      asprintf (&mi_error_message, "mi_cmd_data_list_register_values: No registers.");
+      return MI_CMD_ERROR;
+    }
+
+  ui_out_list_begin (uiout, "register-values");
+
+  if (argc == 1)               /* No args, beside the format: do all the regs */
+    {
+      for (regnum = 0;
+          regnum < numregs;
+          regnum++)
+       {
+         if (REGISTER_NAME (regnum) == NULL
+             || *(REGISTER_NAME (regnum)) == '\0')
+           continue;
+         ui_out_list_begin (uiout, NULL);
+         ui_out_field_int (uiout, "number", regnum);
+         result = get_register (regnum, format);
+         if (result == -1)
+           return MI_CMD_ERROR;
+         ui_out_list_end (uiout);
+       }
+    }
+
+  /* Else, list of register #s, just do listed regs */
+  for (i = 1; i < argc; i++)
+    {
+      regnum = atoi (argv[i]);
+
+      if (regnum >= 0
+         && regnum < numregs
+         && REGISTER_NAME (regnum) != NULL
+         && *REGISTER_NAME (regnum) != '\000')
+       {
+         ui_out_list_begin (uiout, NULL);
+         ui_out_field_int (uiout, "number", regnum);
+         result = get_register (regnum, format);
+         if (result == -1)
+           return MI_CMD_ERROR;
+         ui_out_list_end (uiout);
+       }
+      else
+       {
+         asprintf (&mi_error_message, "bad register number");
+         return MI_CMD_ERROR;
+       }
+    }
+  ui_out_list_end (uiout);
+  return MI_CMD_DONE;
+}
+
+/* Output one register's contents in the desired format. */
+static int
+get_register (int regnum, int format)
+{
+  char raw_buffer[MAX_REGISTER_RAW_SIZE];
+  char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
+  int optim;
+  static struct ui_stream *stb = NULL;
+
+  stb = ui_out_stream_new (uiout);
+
+  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);
+  if (optim)
+    {
+      asprintf (&mi_error_message, "Optimized out");
+      return -1;
+    }
+
+  /* Convert raw data to virtual format if necessary.  */
+
+  if (REGISTER_CONVERTIBLE (regnum))
+    {
+      REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
+                                  raw_buffer, virtual_buffer);
+    }
+  else
+    memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
+
+  if (format == 'r')
+    {
+      int j;
+      char *ptr, buf[1024];
+
+      strcpy (buf, "0x");
+      ptr = buf + 2;
+      for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
+       {
+         register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j
+         : REGISTER_RAW_SIZE (regnum) - 1 - j;
+         sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]);
+         ptr += 2;
+       }
+      ui_out_field_string (uiout, "value", buf);
+      /*fputs_filtered (buf, gdb_stdout); */
+    }
+  else
+    {
+      val_print (REGISTER_VIRTUAL_TYPE (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);
+    }
+  return 1;
+}
+
+#if 0
+/*This is commented out because we decided it was not useful. I leave
+   it, just in case. ezannoni:1999-12-08 */
+
+/* Assign a value to a variable. The expression argument must be in
+   the form A=2 or "A = 2" (I.e. if there are spaces it needs to be
+   quoted. */
+enum mi_cmd_result
+mi_cmd_data_assign (char *command, char **argv, int argc)
+{
+  struct expression *expr;
+  struct cleanup *old_chain;
+
+  if (argc != 1)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_data_assign: Usage: -data-assign expression");
+      return MI_CMD_ERROR;
+    }
+
+  /* NOTE what follows is a clone of set_command(). FIXME: ezannoni
+     01-12-1999: Need to decide what to do with this for libgdb purposes. */
+
+  expr = parse_expression (argv[0]);
+  old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+  evaluate_expression (expr);
+  do_cleanups (old_chain);
+  return MI_CMD_DONE;
+}
+#endif
+
+/* Evaluate the value of the argument. The argument is an
+   expression. If the expression contains spaces it needs to be
+   included in double quotes. */
+enum mi_cmd_result
+mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
+{
+  struct expression *expr;
+  struct cleanup *old_chain = NULL;
+  value_ptr val;
+  struct ui_stream *stb = NULL;
+
+  stb = ui_out_stream_new (uiout);
+
+  if (argc != 1)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_data_evaluate_expression: Usage: -data-evaluate-expression expression");
+      return MI_CMD_ERROR;
+    }
+
+  expr = parse_expression (argv[0]);
+
+  old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+
+  val = evaluate_expression (expr);
+
+  /* Print the result of the expression evaluation. */
+  val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
+            VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
+            stb->stream, 0, 0, 0, 0);
+
+  ui_out_field_stream (uiout, "value", stb);
+  ui_out_stream_delete (stb);
+
+  do_cleanups (old_chain);
+
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_target_download (char *args, int from_tty)
+{
+  char *run;
+  struct cleanup *old_cleanups = NULL;
+
+  asprintf (&run, "load %s", args);
+  if (run == 0)
+    internal_error ("mi_cmd_target_download: no memory");
+  old_cleanups = make_cleanup (free, run);
+  execute_command (run, from_tty);
+
+  do_cleanups (old_cleanups);
+  return MI_CMD_DONE;
+}
+
+/* Connect to the remote target. */
+enum mi_cmd_result
+mi_cmd_target_select (char *args, int from_tty)
+{
+  char *run;
+  struct cleanup *old_cleanups = NULL;
+
+  asprintf (&run, "target %s", args);
+  if (run == 0)
+    internal_error ("mi_cmd_target_select: no memory");
+  old_cleanups = make_cleanup (free, run);
+
+  /* target-select is always synchronous.  once the call has returned
+     we know that we are connected. */
+  /* NOTE: At present all targets that are connected are also
+     (implicitly) talking to a halted target.  In the future this may
+     change. */
+  execute_command (run, from_tty);
+
+  do_cleanups (old_cleanups);
+
+  /* Issue the completion message here. */
+  if (last_async_command)
+    fputs_unfiltered (last_async_command, raw_stdout);
+  fputs_unfiltered ("^connected", raw_stdout);
+  mi_out_put (uiout, raw_stdout);
+  mi_out_rewind (uiout);
+  fputs_unfiltered ("\n", raw_stdout);
+  do_exec_cleanups (ALL_CLEANUPS);
+  return MI_CMD_QUIET;
+}
+
+/* DATA-MEMORY-READ:
+
+   ADDR: start address of data to be dumped.
+   WORD-FORMAT: a char indicating format for the ``word''. See 
+   the ``x'' command.
+   WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes
+   NR_ROW: Number of rows.
+   NR_COL: The number of colums (words per row).
+   ASCHAR: (OPTIONAL) Append an ascii character dump to each row.  Use
+   ASCHAR for unprintable characters.
+
+   Reads SIZE*NR_ROW*NR_COL bytes starting at ADDR from memory and
+   displayes them.  Returns:
+
+   {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
+
+   Returns: 
+   The number of bytes read is SIZE*ROW*COL. */
+
+enum mi_cmd_result
+mi_cmd_data_read_memory (char *command, char **argv, int argc)
+{
+  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
+  CORE_ADDR addr;
+  long total_bytes;
+  long nr_cols;
+  long nr_rows;
+  char word_format;
+  struct type *word_type;
+  long word_size;
+  char word_asize;
+  char aschar;
+  char *mbuf;
+  int nr_bytes;
+  long offset = 0;
+  int optind = 0;
+  char *optarg;
+  enum opt
+    {
+      OFFSET_OPT
+    };
+  static struct mi_opt opts[] =
+  {
+    {"o", OFFSET_OPT, 1},
+    0
+  };
+
+  while (1)
+    {
+      int opt = mi_getopt ("mi_cmd_data_read_memory", argc, argv, opts,
+                          &optind, &optarg);
+      if (opt < 0)
+       break;
+      switch ((enum opt) opt)
+       {
+       case OFFSET_OPT:
+         offset = atol (optarg);
+         break;
+       }
+    }
+  argv += optind;
+  argc -= optind;
+
+  if (argc < 5 || argc > 6)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR].");
+      return MI_CMD_ERROR;
+    }
+
+  /* Extract all the arguments. */
+
+  /* Start address of the memory dump. */
+  addr = parse_and_eval_address (argv[0]) + offset;
+  /* The format character to use when displaying a memory word. See
+     the ``x'' command. */
+  word_format = argv[1][0];
+  /* The size of the memory word. */
+  word_size = atol (argv[2]);
+  switch (word_size)
+    {
+    case 1:
+      word_type = builtin_type_int8;
+      word_asize = 'b';
+      break;
+    case 2:
+      word_type = builtin_type_int16;
+      word_asize = 'h';
+      break;
+    case 4:
+      word_type = builtin_type_int32;
+      word_asize = 'w';
+      break;
+    case 8:
+      word_type = builtin_type_int64;
+      word_asize = 'g';
+      break;
+    default:
+      word_type = builtin_type_int8;
+      word_asize = 'b';
+    }
+  /* The number of rows */
+  nr_rows = atol (argv[3]);
+  if (nr_rows <= 0)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_data_read_memory: invalid number of rows.");
+      return MI_CMD_ERROR;
+    }
+  /* number of bytes per row. */
+  nr_cols = atol (argv[4]);
+  if (nr_cols <= 0)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_data_read_memory: invalid number of columns.");
+    }
+  /* The un-printable character when printing ascii. */
+  if (argc == 6)
+    aschar = *argv[5];
+  else
+    aschar = 0;
+
+  /* create a buffer and read it in. */
+  total_bytes = word_size * nr_rows * nr_cols;
+  mbuf = calloc (total_bytes, 1);
+  make_cleanup (free, mbuf);
+  if (mbuf == NULL)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_data_read_memory: out of memory.");
+      return MI_CMD_ERROR;
+    }
+  nr_bytes = 0;
+  while (nr_bytes < total_bytes)
+    {
+      int error;
+      long num = target_read_memory_partial (addr + nr_bytes, mbuf + nr_bytes,
+                                            total_bytes - nr_bytes,
+                                            &error);
+      if (num <= 0)
+       break;
+      nr_bytes += num;
+    }
+
+  /* output the header information. */
+  ui_out_field_core_addr (uiout, "addr", addr);
+  ui_out_field_int (uiout, "nr-bytes", nr_bytes);
+  ui_out_field_int (uiout, "total-bytes", total_bytes);
+  ui_out_field_core_addr (uiout, "next-row", addr + word_size * nr_cols);
+  ui_out_field_core_addr (uiout, "prev-row", addr - word_size * nr_cols);
+  ui_out_field_core_addr (uiout, "next-page", addr + total_bytes);
+  ui_out_field_core_addr (uiout, "prev-page", addr - total_bytes);
+
+  /* Build the result as a two dimentional table. */
+  {
+    struct ui_stream *stream = ui_out_stream_new (uiout);
+    int row;
+    int row_byte;
+    ui_out_list_begin (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_list_begin (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");
+       for (col = 0, col_byte = row_byte;
+            col < nr_cols;
+            col++, col_byte += word_size)
+         {
+           if (col_byte + word_size > nr_bytes)
+             {
+               ui_out_field_string (uiout, NULL, "N/A");
+             }
+           else
+             {
+               ui_file_rewind (stream->stream);
+               print_scalar_formatted (mbuf + col_byte, word_type, word_format,
+                                       word_asize, stream->stream);
+               ui_out_field_stream (uiout, NULL, stream);
+             }
+         }
+       ui_out_list_end (uiout);
+       if (aschar)
+         {
+           int byte;
+           ui_file_rewind (stream->stream);
+           for (byte = row_byte; byte < row_byte + word_size * nr_cols; byte++)
+             {
+               if (byte >= nr_bytes)
+                 {
+                   fputc_unfiltered ('X', stream->stream);
+                 }
+               else if (mbuf[byte] < 32 || mbuf[byte] > 126)
+                 {
+                   fputc_unfiltered (aschar, stream->stream);
+                 }
+               else
+                 fputc_unfiltered (mbuf[byte], stream->stream);
+             }
+           ui_out_field_stream (uiout, "ascii", stream);
+         }
+       ui_out_list_end (uiout);
+      }
+    ui_out_stream_delete (stream);
+    ui_out_list_end (uiout);
+  }
+  do_cleanups (cleanups);
+  return MI_CMD_DONE;
+}
+
+/* DATA-MEMORY-WRITE:
+
+   COLUMN_OFFSET: optional argument. Must be preceeded by '-o'. The
+   offset from the beginning of the memory grid row where the cell to
+   be written is.
+   ADDR: start address of the row in the memory grid where the memory
+   cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
+   the location to write to.
+   FORMAT: a char indicating format for the ``word''. See 
+   the ``x'' command.
+   WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
+   VALUE: value to be written into the memory address.
+
+   Writes VALUE into ADDR + (COLUMN_OFFSET * WORD_SIZE).
+
+   Prints nothing. */
+enum mi_cmd_result
+mi_cmd_data_write_memory (char *command, char **argv, int argc)
+{
+  CORE_ADDR addr;
+  char word_format;
+  long word_size;
+  /* FIXME: ezannoni 2000-02-17 LONGEST could possibly not be big
+     enough when using a compiler other than GCC. */
+  LONGEST value;
+  unsigned char *buffer;
+  long offset = 0;
+  int optind = 0;
+  char *optarg;
+  enum opt
+    {
+      OFFSET_OPT
+    };
+  static struct mi_opt opts[] =
+  {
+    {"o", OFFSET_OPT, 1},
+    0
+  };
+
+  while (1)
+    {
+      int opt = mi_getopt ("mi_cmd_data_write_memory", argc, argv, opts,
+                          &optind, &optarg);
+      if (opt < 0)
+       break;
+      switch ((enum opt) opt)
+       {
+       case OFFSET_OPT:
+         offset = atol (optarg);
+         break;
+       }
+    }
+  argv += optind;
+  argc -= optind;
+
+  if (argc != 4)
+    {
+      asprintf (&mi_error_message,
+               "mi_cmd_data_write_memory: Usage: [-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE.");
+      return MI_CMD_ERROR;
+    }
+
+  /* Extract all the arguments. */
+  /* Start address of the memory dump. */
+  addr = parse_and_eval_address (argv[0]);
+  /* The format character to use when displaying a memory word. See
+     the ``x'' command. */
+  word_format = argv[1][0];
+  /* The size of the memory word. */
+  word_size = atol (argv[2]);
+
+  /* Calculate the real address of the write destination. */
+  addr += (offset * word_size);
+
+  /* Get the value as a number */
+  value = parse_and_eval_address (argv[3]);
+  /* Get the value into an array */
+  buffer = (unsigned char *) xmalloc (word_size);
+  store_signed_integer (buffer, word_size, value);
+  /* Write it down to memory */
+  write_memory (addr, buffer, word_size);
+
+  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(). */
+
+static int
+captured_mi_execute_command (void *data)
+{
+  struct mi_parse *context = data;
+  enum mi_cmd_result rc;
+
+  switch (context->op)
+    {
+
+    case MI_COMMAND:
+      /* A MI command was read from the input stream */
+      if (mi_debug_p)
+       /* FIXME: gdb_???? */
+       fprintf_unfiltered (raw_stdout, " token=`%s' command=`%s' args=`%s'\n",
+                           context->token, context->command, context->args);
+      /* FIXME: cagney/1999-09-25: Rather than this convoluted
+         condition expression, each function should return an
+         indication of what action is required and then switch on
+         that. */
+      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)
+           {
+             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);
+           }
+         else if (rc == MI_CMD_ERROR)
+           {
+             if (mi_error_message)
+               {
+                 fputs_unfiltered (context->token, raw_stdout);
+                 fputs_unfiltered ("^error,msg=\"", raw_stdout);
+                 fputstr_unfiltered (mi_error_message, '"', raw_stdout);
+                 free (mi_error_message);
+                 fputs_unfiltered ("\"\n", raw_stdout);
+               }
+             mi_out_rewind (uiout);
+           }
+         else if (rc == MI_CMD_CAUGHT_ERROR)
+           {
+             mi_out_rewind (uiout);
+             return 0;
+           }
+         else
+           mi_out_rewind (uiout);
+       }
+      else if (sync_execution)
+       /* Don't print the prompt. We are executing the target in
+          synchronous mode. */
+       return -1;
+      break;
+
+    case CLI_COMMAND:
+      /* A CLI command was read from the input stream */
+      /* This will be removed as soon as we have a complete set of
+         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);
+      break;
+
+    }
+  return 1;
+}
+
+
+void
+mi_execute_command (char *cmd, int from_tty)
+{
+  struct mi_parse *command;
+
+  /* This is to handle EOF (^D). We just quit gdb. */
+  /* FIXME: we should call some API function here. */
+  if (cmd == 0)
+    quit_force (NULL, from_tty);
+
+  command = mi_parse (cmd);
+
+  if (command != NULL)
+    {
+      /* FIXME: cagney/1999-11-04: Can this use of catch_errors either
+         be pushed even further down or even eliminated? */
+      int rc = catch_errors (captured_mi_execute_command, command, "",
+                            RETURN_MASK_ALL);
+      if (rc < 0)
+       {
+         /* The command is executing synchronously.  Bail out early
+            suppressing the finished prompt. */
+         mi_parse_free (command);
+         return;
+       }
+      if (rc == 0)
+       {
+         char *msg = error_last_message ();
+         struct cleanup *cleanup = make_cleanup (free, msg);
+         /* The command execution failed and error() was called
+            somewhere */
+         fputs_unfiltered (command->token, raw_stdout);
+         fputs_unfiltered ("^error,msg=\"", raw_stdout);
+         fputstr_unfiltered (msg, '"', raw_stdout);
+         fputs_unfiltered ("\"\n", raw_stdout);
+       }
+      mi_parse_free (command);
+    }
+
+  gdb_flush (raw_stdout);
+  fputs_unfiltered ("(gdb) \n", raw_stdout);
+  /* print any buffered hook code */
+  /* ..... */
+}
+
+static enum mi_cmd_result
+mi_cmd_execute (struct mi_parse *parse)
+{
+  if (parse->cmd->argv_func != NULL
+      || parse->cmd->args_func != NULL)
+    {
+      /* FIXME: We need to save the token because the command executed
+         may be asynchronous and need to print the token again.
+         In the future we can pass the token down to the func
+         and get rid of the last_async_command */
+      /* The problem here is to keep the token around when we launch
+         the target, and we want to interrupt it later on.  The
+         interrupt command will have its own token, but when the
+         target stops, we must display the token corresponding to the
+         last execution command given. So we have another string where
+         we copy the token (previous_async_command), if this was
+         indeed the token of an execution command, and when we stop we
+         print that one. This is possible because the interrupt
+         command, when over, will copy that token back into the
+         default token string (last_async_command). */
+
+      if (target_executing)
+       {
+         if (!previous_async_command)
+           previous_async_command = xstrdup (last_async_command);
+         if (strcmp (parse->command, "exec-interrupt"))
+           {
+             fputs_unfiltered (parse->token, raw_stdout);
+             fputs_unfiltered ("^error,msg=\"", raw_stdout);
+             fputs_unfiltered ("Cannot execute command ", raw_stdout);
+             fputstr_unfiltered (parse->command, '"', raw_stdout);
+             fputs_unfiltered (" while target running", raw_stdout);
+             fputs_unfiltered ("\"\n", raw_stdout);
+             return MI_CMD_ERROR;
+           }
+       }
+      last_async_command = xstrdup (parse->token);
+      make_exec_cleanup ((make_cleanup_func) free_and_reset, &last_async_command);
+      /* FIXME: DELETE THIS! */
+      if (parse->cmd->args_func != NULL)
+       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)
+    {
+      /* 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);
+      return MI_CMD_DONE;
+    }
+  else
+    {
+      /* FIXME: DELETE THIS. */
+      fputs_unfiltered (parse->token, raw_stdout);
+      fputs_unfiltered ("^error,msg=\"", raw_stdout);
+      fputs_unfiltered ("Undefined mi command: ", raw_stdout);
+      fputstr_unfiltered (parse->command, '"', raw_stdout);
+      fputs_unfiltered (" (missing implementation)", raw_stdout);
+      fputs_unfiltered ("\"\n", raw_stdout);
+      return MI_CMD_ERROR;
+    }
+}
+
+void 
+free_and_reset (char **arg)
+{
+  free (*arg);
+  *arg = NULL;
+}
+
+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)
+{
+  if (cli != 0)
+    {
+      struct cleanup *old_cleanups;
+      char *run;
+      asprintf (&run, cli, args);
+      if (mi_debug_p)
+       /* FIXME: gdb_???? */
+       fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n",
+                           cli, run);
+      if (run == 0)
+       abort ();
+      old_cleanups = make_cleanup (free, run);
+      execute_command ( /*ui */ run, 0 /*from_tty */ );
+      do_cleanups (old_cleanups);
+      return;
+    }
+}
+
+enum mi_cmd_result
+mi_execute_async_cli_command (char *mi, char *args, int from_tty)
+{
+  struct cleanup *old_cleanups;
+  char *run;
+  char *async_args;
+
+  if (target_can_async_p ())
+    {
+      async_args = (char *) xmalloc (strlen (args) + 2);
+      make_exec_cleanup (free, async_args);
+      strcpy (async_args, args);
+      strcat (async_args, "&");
+      asprintf (&run, "%s %s", mi, async_args);
+      if (run == 0)
+       internal_error ("mi_execute_async_cli_command: no memory");
+      make_exec_cleanup (free, run);
+      add_continuation (mi_exec_async_cli_cmd_continuation, NULL);
+    }
+  else
+    {
+      asprintf (&run, "%s %s", mi, args);
+      if (run == 0)
+       internal_error ("mi_execute_async_cli_command: no memory");
+      old_cleanups = make_cleanup (free, run);
+    }
+
+  if (!target_can_async_p ())
+    {
+      /* NOTE: For synchronous targets asynchronous behavour is faked by
+         printing out the GDB prompt before we even try to execute the
+         command. */
+      if (last_async_command)
+       fputs_unfiltered (last_async_command, raw_stdout);
+      fputs_unfiltered ("^running\n", raw_stdout);
+      fputs_unfiltered ("(gdb) \n", raw_stdout);
+    }
+  else
+    {
+      /* FIXME: cagney/1999-11-29: Printing this message before
+         calling execute_command is wrong.  It should only be printed
+         once gdb has confirmed that it really has managed to send a
+         run command to the target. */
+      if (last_async_command)
+       fputs_unfiltered (last_async_command, raw_stdout);
+      fputs_unfiltered ("^running\n", raw_stdout);
+    }
+
+  execute_command ( /*ui */ run, 0 /*from_tty */ );
+
+  if (!target_can_async_p ())
+    {
+      /* Do this before doing any printing.  It would appear that some
+         print code leaves garbage around in the buffer. */
+      do_cleanups (old_cleanups);
+      /* If the target was doing the operation synchronously we fake
+         the stopped message. */
+      if (last_async_command)
+       fputs_unfiltered (last_async_command, raw_stdout);
+      fputs_unfiltered ("*stopped", raw_stdout);
+      mi_out_put (uiout, raw_stdout);
+      mi_out_rewind (uiout);
+      fputs_unfiltered ("\n", raw_stdout);
+      return MI_CMD_QUIET;
+    }
+  return MI_CMD_DONE;
+}
+
+void
+mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg)
+{
+  if (last_async_command)
+    fputs_unfiltered (last_async_command, raw_stdout);
+  fputs_unfiltered ("*stopped", raw_stdout);
+  mi_out_put (uiout, raw_stdout);
+  fputs_unfiltered ("\n", raw_stdout);
+  fputs_unfiltered ("(gdb) \n", raw_stdout);
+  do_exec_cleanups (ALL_CLEANUPS);
+}
+
+static char *
+mi_input (char *buf)
+{
+  return gdb_readline (NULL);
+}
+
+static void
+mi_load_progress (const char *section_name,
+                 unsigned long sent_so_far,
+                 unsigned long total_section,
+                 unsigned long total_sent,
+                 unsigned long grand_total)
+{
+  struct timeval time_now, delta, update_threshold;
+  static struct timeval last_update;
+  static char *previous_sect_name = NULL;
+  int new_section;
+
+  if (!interpreter_p || strcmp (interpreter_p, "mi") != 0)
+    return;
+
+  update_threshold.tv_sec = 0;
+  update_threshold.tv_usec = 500000;
+  gettimeofday (&time_now, NULL);
+
+  delta.tv_usec = time_now.tv_usec - last_update.tv_usec;
+  delta.tv_sec = time_now.tv_sec - last_update.tv_sec;
+
+  if (delta.tv_usec < 0)
+    {
+      delta.tv_sec -= 1;
+      delta.tv_usec += 1000000;
+    }
+
+  new_section = (previous_sect_name ?
+                strcmp (previous_sect_name, section_name) : 1);
+  if (new_section)
+    {
+      free (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_list_begin (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_list_end (uiout);
+      mi_out_put (uiout, raw_stdout);
+      fputs_unfiltered ("\n", raw_stdout);
+      gdb_flush (raw_stdout);
+    }
+
+  if (delta.tv_sec >= update_threshold.tv_sec &&
+      delta.tv_usec >= update_threshold.tv_usec)
+    {
+      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_list_begin (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_list_end (uiout);
+      mi_out_put (uiout, raw_stdout);
+      fputs_unfiltered ("\n", raw_stdout);
+      gdb_flush (raw_stdout);
+    }
+}
+
+static void
+mi_command_loop ()
+{
+  /* 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 ();
+
+  /* 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);
+
+  if (!event_loop_p)
+    simplified_command_loop (mi_input, mi_execute_command);
+  else
+    start_event_loop ();
+}
+
+static void
+setup_architecture_data ()
+{
+  /* 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 (arg0)
+     char *arg0;
+{
+  /* Eventually this will contain code that takes control of the
+     console. */
+}
+
+void
+_initialize_mi_main ()
+{
+  /* If we're _the_ interpreter, take control. */
+  if (interpreter_p
+      && strcmp (interpreter_p, "mi") == 0)
+    {
+      init_ui_hook = mi_init_ui;
+      command_loop_hook = mi_command_loop;
+      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? */
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
new file mode 100644 (file)
index 0000000..c389097
--- /dev/null
@@ -0,0 +1,401 @@
+/* MI Command Set - output generating routines.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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 "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 supress_field_separator;
+    int first_header;
+    struct ui_file *buffer;
+  };
+
+/* These are the MI output functions */
+
+static void mi_table_begin (struct ui_out *uiout, int nbrofcols, char *tblid);
+static void mi_table_body (struct ui_out *uiout);
+static void mi_table_end (struct ui_out *uiout);
+static void mi_table_header (struct ui_out *uiout, int width,
+                            enum ui_align alig, char *colhdr);
+static void mi_list_begin (struct ui_out *uiout, int list_flag, char *lstid);
+static void mi_list_end (struct ui_out *uiout, int list_flag);
+static void mi_field_int (struct ui_out *uiout, int fldno, int width,
+                         enum ui_align alig, char *fldname, int value);
+static void mi_field_skip (struct ui_out *uiout, int fldno, int width,
+                          enum ui_align alig, char *fldname);
+static void mi_field_string (struct ui_out *uiout, int fldno, int width,
+                            enum ui_align alig, char *fldname,
+                            const char *string);
+static void mi_field_fmt (struct ui_out *uiout, int fldno,
+                         int width, enum ui_align align,
+                         char *fldname, char *format, va_list args);
+static void mi_spaces (struct ui_out *uiout, int numspaces);
+static void mi_text (struct ui_out *uiout, char *string);
+static void mi_message (struct ui_out *uiout, int verbosity, char *format,
+                       va_list args);
+static void mi_wrap_hint (struct ui_out *uiout, char *identstring);
+static void mi_flush (struct ui_out *uiout);
+
+/* This is the MI ui-out implementation functions vector */
+
+/* FIXME: This can be initialized dynamically after default is set to
+   handle initial output in main.c */
+
+struct ui_out_impl mi_ui_out_impl =
+{
+  mi_table_begin,
+  mi_table_body,
+  mi_table_end,
+  mi_table_header,
+  mi_list_begin,
+  mi_list_end,
+  mi_field_int,
+  mi_field_skip,
+  mi_field_string,
+  mi_field_fmt,
+  mi_spaces,
+  mi_text,
+  mi_message,
+  mi_wrap_hint,
+  mi_flush
+};
+
+/* Prototypes for local functions */
+
+extern void _initialize_mi_out PARAMS ((void));
+static void field_separator (struct ui_out *uiout);
+static void list_open (struct ui_out *uiout);
+static void list_close (struct ui_out *uiout);
+
+static void out_field_fmt (struct ui_out *uiout, int fldno, char *fldname,
+                          char *format,...);
+
+/* Mark beginning of a table */
+
+void
+mi_table_begin (uiout, nbrofcols, tblid)
+     struct ui_out *uiout;
+     int nbrofcols;
+     char *tblid;
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  field_separator (uiout);
+  if (tblid)
+    fprintf_unfiltered (data->buffer, "%s=", tblid);
+  list_open (uiout);
+  data->first_header = 0;
+  data->supress_field_separator = 1;
+}
+
+/* Mark beginning of a table body */
+
+void
+mi_table_body (uiout)
+     struct ui_out *uiout;
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  /* close the table header line if there were any headers */
+  if (data->first_header)
+    list_close (uiout);
+}
+
+/* Mark end of a table */
+
+void
+mi_table_end (uiout)
+     struct ui_out *uiout;
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  list_close (uiout);
+  /* If table was empty this flag did not get reset yet */
+  data->supress_field_separator = 0;
+}
+
+/* Specify table header */
+
+void
+mi_table_header (uiout, width, alignment, colhdr)
+     struct ui_out *uiout;
+     int width;
+     int alignment;
+     char *colhdr;
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  if (!data->first_header++)
+    {
+      fputs_unfiltered ("hdr=", data->buffer);
+      list_open (uiout);
+    }
+  mi_field_string (uiout, 0, width, alignment, 0, colhdr);
+}
+
+/* Mark beginning of a list */
+
+void
+mi_list_begin (uiout, list_flag, lstid)
+     struct ui_out *uiout;
+     int list_flag;
+     char *lstid;
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  field_separator (uiout);
+  data->supress_field_separator = 1;
+  if (lstid)
+    fprintf_unfiltered (data->buffer, "%s=", lstid);
+  list_open (uiout);
+}
+
+/* Mark end of a list */
+
+void
+mi_list_end (uiout, list_flag)
+     struct ui_out *uiout;
+     int list_flag;
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  list_close (uiout);
+  /* If list was empty this flag did not get reset yet */
+  data->supress_field_separator = 0;
+}
+
+/* output an int field */
+
+void
+mi_field_int (uiout, fldno, width, alignment, fldname, value)
+     struct ui_out *uiout;
+     int fldno;
+     int width;
+     int alignment;
+     char *fldname;
+     int value;
+{
+  char buffer[20];             /* FIXME: how many chars long a %d can become? */
+
+  sprintf (buffer, "%d", value);
+  mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
+}
+
+/* used to ommit a field */
+
+void
+mi_field_skip (uiout, fldno, width, alignment, fldname)
+     struct ui_out *uiout;
+     int fldno;
+     int width;
+     int alignment;
+     char *fldname;
+{
+  mi_field_string (uiout, fldno, width, alignment, fldname, "");
+}
+
+/* other specific mi_field_* end up here so alignment and field
+   separators are both handled by mi_field_string */
+
+void
+mi_field_string (struct ui_out *uiout,
+                int fldno,
+                int width,
+                int align,
+                char *fldname,
+                const char *string)
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  field_separator (uiout);
+  if (fldname)
+    fprintf_unfiltered (data->buffer, "%s=", fldname);
+  fprintf_unfiltered (data->buffer, "\"");
+  if (string)
+    fputstr_unfiltered (string, '"', data->buffer);
+  fprintf_unfiltered (data->buffer, "\"");
+}
+
+/* This is the only field function that does not align */
+
+void
+mi_field_fmt (struct ui_out *uiout, int fldno,
+             int width, enum ui_align align,
+             char *fldname, char *format, va_list args)
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  field_separator (uiout);
+  if (fldname)
+    fprintf_unfiltered (data->buffer, "%s=\"", fldname);
+  else
+    fputs_unfiltered ("\"", data->buffer);
+  vfprintf_unfiltered (data->buffer, format, args);
+  fputs_unfiltered ("\"", data->buffer);
+}
+
+void
+mi_spaces (uiout, numspaces)
+     struct ui_out *uiout;
+     int numspaces;
+{
+}
+
+void
+mi_text (uiout, string)
+     struct ui_out *uiout;
+     char *string;
+{
+}
+
+void
+mi_message (struct ui_out *uiout, int verbosity, char *format, va_list args)
+{
+}
+
+void
+mi_wrap_hint (uiout, identstring)
+     struct ui_out *uiout;
+     char *identstring;
+{
+  wrap_here (identstring);
+}
+
+void
+mi_flush (uiout)
+     struct ui_out *uiout;
+{
+  struct ui_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);
+  if (data->supress_field_separator)
+    data->supress_field_separator = 0;
+  else
+    fputc_unfiltered (',', data->buffer);
+}
+
+static void
+list_open (struct ui_out *uiout)
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  fputc_unfiltered ('{', data->buffer);
+}
+
+static void
+list_close (struct ui_out *uiout)
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  fputc_unfiltered ('}', data->buffer);
+}
+
+/* add a string to the buffer */
+
+void
+mi_out_buffered (struct ui_out *uiout, char *string)
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  fprintf_unfiltered (data->buffer, "%s", string);
+}
+
+/* clear the buffer */
+
+void
+mi_out_rewind (struct ui_out *uiout)
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  ui_file_rewind (data->buffer);
+}
+
+/* dump the buffer onto the specified stream */
+
+static void
+do_write (void *data, const char *buffer, long length_buffer)
+{
+  ui_file_write (data, buffer, length_buffer);
+}
+
+void
+mi_out_put (struct ui_out *uiout,
+           struct ui_file *stream)
+{
+  struct ui_out_data *data = ui_out_data (uiout);
+  ui_file_put (data->buffer, do_write, stream);
+  ui_file_rewind (data->buffer);
+}
+
+/* initalize private members at startup */
+
+struct ui_out *
+mi_out_new (void)
+{
+  int flags = 0;
+  struct ui_out_data *data = XMALLOC (struct ui_out_data);
+  data->supress_field_separator = 0;
+  /* FIXME: This code should be using a ``string_file'' and not the
+     TUI buffer hack. */
+  data->buffer = mem_fileopen ();
+  return ui_out_new (&mi_ui_out_impl, data, flags);
+}
+
+/* standard gdb initialization hook */
+void
+_initialize_mi_out ()
+{
+  /* nothing happens here */
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-out.h b/gdb/mi/mi-out.h
new file mode 100644 (file)
index 0000000..ea2a2c6
--- /dev/null
@@ -0,0 +1,39 @@
+/* MI Command Set - MI output generating routines for GDB.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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_OUT_H
+#define MI_OUT_H 1
+
+#if __STDC__
+struct ui_out;
+struct ui_file;
+#endif
+
+extern struct ui_out *mi_out_new (void);
+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);
+
+#endif /* MI_OUT_H */
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-parse.c b/gdb/mi/mi-parse.c
new file mode 100644 (file)
index 0000000..d86f2ee
--- /dev/null
@@ -0,0 +1,243 @@
+/* MI Command Set - MI parser.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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-parse.h"
+
+#include <ctype.h>
+#include <string.h>
+
+#undef XMALLOC
+#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
+
+static void
+mi_parse_argv (char *args, struct mi_parse *parse)
+{
+  char *chp = args;
+  int argc = 0;
+  char **argv = xmalloc ((argc + 1) * sizeof (char *));
+  argv[argc] = NULL;
+  while (1)
+    {
+      char *arg;
+      /* skip leading white space */
+      while (isspace (*chp))
+       chp++;
+      /* Three possibilities: EOF, quoted string, or other text. */
+      switch (*chp)
+       {
+       case '\0':
+         parse->argv = argv;
+         parse->argc = argc;
+         return;
+       case '"':
+         {
+           /* A quoted string. */
+           int len;
+           char *start = chp + 1;
+           /* Determine the buffer size. */
+           chp = start;
+           len = 0;
+           while (*chp != '\0' && *chp != '"')
+             {
+               if (*chp == '\\')
+                 {
+                   chp++;
+                   if (parse_escape (&chp) <= 0)
+                     {
+                       /* Do not allow split lines or "\000" */
+                       freeargv (argv);
+                       return;
+                     }
+                 }
+               else
+                 chp++;
+               len++;
+             }
+           /* Insist on a closing quote. */
+           if (*chp != '"')
+             {
+               freeargv (argv);
+               return;
+             }
+           /* Insist on trailing white space. */
+           if (chp[1] != '\0' && !isspace (chp[1]))
+             {
+               freeargv (argv);
+               return;
+             }
+           /* create the buffer. */
+           arg = xmalloc ((len + 1) * sizeof (char));
+           /* And copy the characters in. */
+           chp = start;
+           len = 0;
+           while (*chp != '\0' && *chp != '"')
+             {
+               if (*chp == '\\')
+                 {
+                   chp++;
+                   arg[len] = parse_escape (&chp);
+                 }
+               else
+                 arg[len] = *chp++;
+               len++;
+             }
+           arg[len] = '\0';
+           chp++;              /* that closing quote. */
+           break;
+         }
+       default:
+         {
+           /* An unquoted string.  Accumulate all non blank
+              characters into a buffer. */
+           int len;
+           char *start = chp;
+           while (*chp != '\0' && !isspace (*chp))
+             {
+               chp++;
+             }
+           len = chp - start;
+           arg = xmalloc ((len + 1) * sizeof (char));
+           strncpy (arg, start, len);
+           arg[len] = '\0';
+           break;
+         }
+       }
+      /* Append arg to argv. */
+      argv = xrealloc (argv, (argc + 2) * sizeof (char *));
+      argv[argc++] = arg;
+      argv[argc] = NULL;
+    }
+}
+
+
+void
+mi_parse_free (struct mi_parse *parse)
+{
+  if (parse == NULL)
+    return;
+  if (parse->command != NULL)
+    free (parse->command);
+  if (parse->token != NULL)
+    free (parse->token);
+  if (parse->args != NULL)
+    free (parse->args);
+  if (parse->argv != NULL)
+    freeargv (parse->argv);
+  free (parse);
+}
+
+
+struct mi_parse *
+mi_parse (char *cmd)
+{
+  char *chp;
+  struct mi_parse *parse = XMALLOC (struct mi_parse);
+  memset (parse, 0, sizeof (*parse));
+
+  /* Before starting, skip leading white space. */
+  while (isspace (*cmd))
+    cmd++;
+
+  /* Find/skip any token and then extract it. */
+  for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++)
+    ;
+  parse->token = xmalloc ((chp - cmd + 1) * sizeof (char *));
+  memcpy (parse->token, cmd, (chp - cmd));
+  parse->token[chp - cmd] = '\0';
+
+  /* This wasn't a real MI command.  Return it as a CLI_COMMAND. */
+  if (*chp != '-')
+    {
+      while (isspace (*chp))
+       chp++;
+      parse->command = xstrdup (chp);
+      parse->op = CLI_COMMAND;
+      return parse;
+    }
+
+  /* Extract the command. */
+  {
+    char *tmp = chp + 1;       /* discard ``-'' */
+    for (; *chp && !isspace (*chp); chp++)
+      ;
+    parse->command = xmalloc ((chp - tmp + 1) * sizeof (char *));
+    memcpy (parse->command, tmp, chp - tmp);
+    parse->command[chp - tmp] = '\0';
+  }
+
+  /* Find the command in the MI table. */
+  parse->cmd = mi_lookup (parse->command);
+  if (parse->cmd == NULL)
+    {
+      /* FIXME: This should be a function call. */
+      fprintf_unfiltered
+       (raw_stdout,
+        "%s^error,msg=\"Undefined MI command: %s\"\n",
+        parse->token, parse->command);
+      mi_parse_free (parse);
+      return NULL;
+    }
+
+  /* Skip white space following the command. */
+  while (isspace (*chp))
+    chp++;
+
+  /* For new argv commands, attempt to return the parsed argument
+     list. */
+  if (parse->cmd->argv_func != NULL)
+    {
+      mi_parse_argv (chp, parse);
+      if (parse->argv == NULL)
+       {
+         /* FIXME: This should be a function call. */
+         fprintf_unfiltered
+           (raw_stdout,
+            "%s^error,msg=\"Problem parsing arguments: %s %s\"\n",
+            parse->token, parse->command, chp);
+         mi_parse_free (parse);
+         return NULL;
+       }
+    }
+
+  /* FIXME: DELETE THIS */
+  /* 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->args = xstrdup (chp);
+    }
+
+  /* Fully parsed. */
+  parse->op = MI_COMMAND;
+  return parse;
+}
+
+void
+_initialize_mi_parse ()
+{
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-parse.h b/gdb/mi/mi-parse.h
new file mode 100644 (file)
index 0000000..8206003
--- /dev/null
@@ -0,0 +1,59 @@
+/* MI Command Set - MI Command Parser.
+   Copyright (C) 2000, Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   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_PARSE_H
+#define MI_PARSE_H
+
+/* MI parser */
+
+enum mi_command_type
+  {
+    MI_COMMAND, CLI_COMMAND
+  };
+
+struct mi_parse
+  {
+    enum mi_command_type op;
+    char *command;
+    char *token;
+    const struct mi_cmd *cmd;
+    char *args;
+    char **argv;
+    int argc;
+  };
+
+/* Attempts to parse CMD returning a ``struct mi_command''.  If CMD is
+   invalid, an error mesage is reported (MI format) and NULL is
+   returned. For a CLI_COMMAND, COMMAND, TOKEN and OP are initialized.
+   For an MI_COMMAND COMMAND, TOKEN, ARGS and OP are
+   initialized. Un-initialized fields are zero. */
+
+extern struct mi_parse *mi_parse (char *cmd);
+
+/* Free a command returned by mi_parse_command. */
+
+extern void mi_parse_free (struct mi_parse *cmd);
+
+#endif
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
index 45a5f2e..ee3330d 100644 (file)
@@ -1,3 +1,10 @@
+Mon Feb 21 13:05:36 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * configure.in (configdirs): Add sub directory gdb.mi.
+       * configure: Re-generate.
+
+       * gdb.mi: New directory.
+       
 2000-02-16  Jim Blandy  <jimb@redhat.com>
 
        * gdb.base/break.exp ("breakpoint line number"): Make sure the
index bf663a2..1922f2f 100755 (executable)
@@ -13,6 +13,8 @@ ac_default_prefix=/usr/local
 # Any additions from configure.in:
 ac_help="$ac_help
   --enable-shared         use shared libraries"
+ac_help="$ac_help
+  --enable-gdbtk "
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -30,6 +32,7 @@ program_suffix=NONE
 program_transform_name=s,x,x,
 silent=
 site=
+sitefile=
 srcdir=
 target=NONE
 verbose=
@@ -144,6 +147,7 @@ Configuration:
   --help                  print this message
   --no-create             do not create output files
   --quiet, --silent       do not print \`checking...' messages
+  --site-file=FILE        use FILE as the site file
   --version               print the version of autoconf that created configure
 Directory and file names:
   --prefix=PREFIX         install architecture-independent files in PREFIX
@@ -314,6 +318,11 @@ EOF
   -site=* | --site=* | --sit=*)
     site="$ac_optarg" ;;
 
+  -site-file | --site-file | --site-fil | --site-fi | --site-f)
+    ac_prev=sitefile ;;
+  -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+    sitefile="$ac_optarg" ;;
+
   -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
     ac_prev=srcdir ;;
   -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
@@ -479,12 +488,16 @@ fi
 srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
 
 # Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
-  if test "x$prefix" != xNONE; then
-    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-  else
-    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+if test -z "$sitefile"; then
+  if test -z "$CONFIG_SITE"; then
+    if test "x$prefix" != xNONE; then
+      CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+    else
+      CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+    fi
   fi
+else
+  CONFIG_SITE="$sitefile"
 fi
 for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
@@ -573,7 +586,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:577: checking host system type" >&5
+echo "configure:590: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -594,7 +607,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$host" 1>&6
 
 echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:598: checking target system type" >&5
+echo "configure:611: checking target system type" >&5
 
 target_alias=$target
 case "$target_alias" in
@@ -612,7 +625,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$target" 1>&6
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:616: checking build system type" >&5
+echo "configure:629: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -636,7 +649,15 @@ test "$host_alias" != "$target_alias" &&
 
 
 # Directories to use in all configurations.
-configdirs="gdb.asm gdb.base gdb.c++ gdb.disasm gdb.chill gdb.threads gdb.trace"
+configdirs="gdb.asm \
+            gdb.base \
+            gdb.c++ \
+            gdb.disasm \
+            gdb.chill \
+            gdb.mi \
+            gdb.threads \
+            gdb.trace"
+
 
 # Directories to use for a configuration which uses stabs.
 stabsdirs="gdb.stabs"
@@ -689,6 +710,42 @@ if test "${shared}" = "true"; then
 fi
 
 # End stuff to support --enable-shared
+# Start stuff to support --enable-gdbtk
+# Check whether --enable-gdbtk or --disable-gdbtk was given.
+if test "${enable_gdbtk+set}" = set; then
+  enableval="$enable_gdbtk"
+  case "${enableval}" in
+    yes)
+        case "$host" in
+        *go32*)
+            enable_gdbtk=no ;;
+        *windows*)
+            enable_gdbtk=no ;;
+        *)
+            enable_gdbtk=yes ;;
+        esac ;;
+    no)
+        enable_gdbtk=no  ;;
+    *)
+        { echo "configure: error: bad value ${enableval} given for gdbtk option" 1>&2; exit 1; } ;;
+esac
+else
+  
+# Default is on for everything but go32 and windows
+case "$host" in
+    *go32* | *windows*)
+        ;;
+    *)
+        enable_gdbtk=yes ;;
+    esac
+
+fi
+
+
+if test "${enable_gdbtk}" = "yes"; then
+    configdirs="${configdirs} gdb.gdbtk"
+fi
+# End stuff to support --enable-shared
 
 # configure the subdirectories too
 subdirs="$configdirs"
index 83356a9..049a3b4 100644 (file)
@@ -13,7 +13,15 @@ AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..)
 AC_CANONICAL_SYSTEM
 
 # Directories to use in all configurations.
-configdirs="gdb.asm gdb.base gdb.c++ gdb.disasm gdb.chill gdb.threads gdb.trace"
+configdirs="gdb.asm \
+            gdb.base \
+            gdb.c++ \
+            gdb.disasm \
+            gdb.chill \
+            gdb.mi \
+            gdb.threads \
+            gdb.trace"
+
 
 # Directories to use for a configuration which uses stabs.
 stabsdirs="gdb.stabs"
@@ -64,6 +72,38 @@ if test "${shared}" = "true"; then
 fi
 AC_SUBST(RPATH_ENVVAR)
 # End stuff to support --enable-shared
+# Start stuff to support --enable-gdbtk
+AC_ARG_ENABLE(gdbtk,
+[  --enable-gdbtk ],
+[case "${enableval}" in
+    yes)
+        case "$host" in
+        *go32*)
+            enable_gdbtk=no ;;
+        *windows*)
+            enable_gdbtk=no ;;
+        *)
+            enable_gdbtk=yes ;;
+        esac ;;
+    no)
+        enable_gdbtk=no  ;;
+    *)
+        AC_MSG_ERROR(bad value ${enableval} given for gdbtk option) ;;
+esac],
+[
+# Default is on for everything but go32 and windows
+case "$host" in
+    *go32* | *windows*)
+        ;;
+    *)
+        enable_gdbtk=yes ;;
+    esac
+])
+
+if test "${enable_gdbtk}" = "yes"; then
+    configdirs="${configdirs} gdb.gdbtk"
+fi
+# End stuff to support --enable-shared
 
 # configure the subdirectories too
 AC_CONFIG_SUBDIRS($configdirs)
diff --git a/gdb/testsuite/gdb.mi/ChangeLog-mi b/gdb/testsuite/gdb.mi/ChangeLog-mi
new file mode 100644 (file)
index 0000000..9d4f1ce
--- /dev/null
@@ -0,0 +1,390 @@
+2000-02-01  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-support.exp (mi_gdb_start): Update to recognize start up
+       message with 'UI_OUT' instead of 'HEADLESS'.
+
+2000-01-27  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-regs.exp (test_running_the_program): Add global var 'hex'.
+
+       * mi-stack.exp, mi-stepi.exp, mi-until.exp, mi-watch.exp,
+       mi-var-display.exp, mi-var-cmd.exp, mi-var-child.exp,
+       mi-var-block.exp: Update all stopped messages.
+
+2000-01-17  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-console.exp, mi-disassemble.exp, mi-eval.exp,
+       mi-read-memory.exp, mi-regs.exp, mi-return.exp, mi-simplerun.exp:
+       Update stopped messages, update copyright.
+       
+       * mi-disassemble.exp: Update error messages output.
+       
+       * mi-support.exp (proc mi_step): Make gdb do a 'step' command, not
+       a 'next'. Update stopped message.
+       (proc mi_next): Update stop message.
+       (proc mi_run_to_main): Update stopped message.
+       Update copyright.
+
+2000-01-11  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-simplerun.exp: Remove stack frames tests from here, to:
+
+       * mi-stack.exp: New file, tests for stack commands.
+
+       * mi-support.exp (mi_run_to_main, mi_next, mi_step) : Update to
+       include thread-id in stopped message.
+
+       * mi-regs.exp: Update break-insert output.
+
+       * (mi-console.exp, mi-disassemble.exp, mi-eval.exp,
+       mi-read-memory.exp, mi-regs.exp, mi-return.exp, mi-simplerun.exp,
+       mi-stepi.exp, mi-until.exp, mi-var-block.exp, mi-var-child.exp,
+       mi-var-cmd.exp, mi-var-display.exp, mi-watch.exp): Update stopped
+       message to include thread-id.
+
+Wed Dec 29 22:06:05 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-watch.exp, mi-var-display.exp, mi-var-cmd.exp,
+       mi-var-child.exp, mi-var-block.exp, mi-until.exp, mi-stepi.exp,
+       mi-simplerun.exp, mi-return.exp, mi-support.exp, mi-eval.exp,
+       mi-console.exp, mi-disassemble.exp, mi-break.exp: Update to
+       reflect extended output from -break-insert command.
+       
+       * mi-break.exp (test_rbreak_creation_and_listing): XFAIL regexp
+       tests.  -r flag broken by above.
+       
+Sun Dec 19 19:28:13 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * cpp_variable.cc, cpp_variable.h, c_variable.c: Delete.
+
+Fri Dec 17 20:59:55 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-read-memory.exp: Test of ``-o <offset>'' now works.
+
+1999-12-16  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-var-cmd.exp: Fix 2 tests outputs.
+
+       * mi-var-child.exp: Add many more tests.
+
+       * mi-var-display.exp: Add many more tests.
+
+       * var-cmd.c: Change type of incr_a parameter to char.
+
+1999-12-15  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-var-block.exp: Set up xfails fro known problems.
+
+       * mi-var-display.exp: Set up printing of values of 'e' and 'anone'
+       as xfails.
+
+       * mi-var-child.exp: Fix typos.
+
+1999-12-15  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-var-child.exp: Space was missing before ``[10]''.
+
+Wed Dec 15 19:23:38 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-read-memory.exp: Add test for ``-o <offset>''.  Update checks
+       and match next-row et.al.
+
+1999-12-14  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-var-display.exp : New file. Tests for format and type, with
+       unions, structs and enums.
+       
+       * mi-var-cmd.exp: Add some var-assign tests.
+
+1999-12-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com> 
+
+       * mi-var-cmd.exp, mi-var-block.exp, mi-var-child.exp: New files
+       some tests for -var* commands.
+
+       * var-cmd.c: New source file for var-* commands tests.
+       * gdb.mi/Makefile.in (PROGS): Add var-cmd.
+       
+Mon Dec 13 18:06:09 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-break.exp: Fix quoting.  Changed "srcfile.c":6 to
+       "\"srcfile.c\":6".
+       * mi-simplerun.exp: Fix quoting.
+
+Sat Dec 11 21:33:37 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-simplerun.exp (exec-finish): Fix return value was zero,
+       should have been three.
+
+       * mi-disassemble.exp: Reduce number of wild card matches in
+       * patterns.  Remove all numeric constants.
+
+1999-12-09  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-eval.exp: New file. Some initial tests for
+       -data-evaluate-expression.
+
+1999-12-09  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * c_variable.c, cpp_variable.cc, cpp_variable.h: New files.  Used
+       for testing "var" operations.
+       * Makefile.in: Add reference to the above files.
+
+1999-12-08  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-regs.exp: Fix test for format 'N' for
+       data-list-register-values.
+
+1999-12-07  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-disassemble.exp: Update expected output. Break test of
+       disassembly in mixed mode into 2 functions.
+
+       * mi-regs.exp: Initial register tests. Works only on sparc right
+       now.
+
+1999-12-02  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-stepi.exp: New file. Tests exec-step-instruction and
+       exec-next-instruction.
+       * mi-until.exp: New file. Tests exec-until.
+       * until.c: New file.
+       * mi-return.exp: New file. Tests exec-return.
+
+Thu Dec  2 09:38:23 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-hack-cli.exp: New test.  Check the hacked up access to the
+       CLI.
+
+Wed Dec  1 16:47:40 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-basics.exp: Delete calls to mi_delete_breakpoints,
+       mi_gdb_reinitialize_dir and mi_gdb_load.  This test is checking
+       that these can work.
+
+       * mi-support.exp (mi_step, mi_next, mi_run_to_main): New
+       procedures.
+
+       * mi-read-memory.exp, mi-read-memory.c: New files.  Test
+       data-read-memory command.
+       
+Tue Nov 30 23:54:16 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-support.exp: Don't start SID until after GDB has been started
+       and verified.
+       
+Tue Nov 30 22:21:33 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-support.exp (mi_uncatched_gdb_exit): When SID, call sid_exit.
+       (mi_gdb_start): When SID, call sid_start.
+       (mi_gdb_start): Add MIFLAGS to spawn-GDB command.  Check for
+       HEADLESS gdb.  Return non-zero when GDB fails to start.
+       (mi_gdb_load): When SID or SIM, download program.
+       (mi_run_cmd): Don't do download here.  Assume target supports the
+       00-exec-run command.
+       (skip_mi_tests, setup_gdbmi, unset_gdbmi): Delete.  Merged into
+       mi_gdb_start.
+
+       * mi-basics.exp, mi-break.exp, mi-console.exp, mi-disassemble.exp,
+       mi-simplerun.exp, mi-watch.exp: Update.  Check status from
+       mi_gdb_start indicating that GDB started correctly.
+
+Tue Nov 30 15:22:08 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-support.exp (setup_gdbmi, unset_gdbmi): New
+       procedures.  Setup/unset dejagnu for mi tests.
+       * mi-basics.exp, mi-console.exp, mi-simplerun.exp, mi-break.exp,
+       mi-disassemble.exp, mi-watch.exp: Update.
+
+1999-11-29  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-simplerun.exp (test_running_the_program): Remove XFAIL. The
+       output is fixed now.
+       (test_program_termination): Update output pattern.
+
+Tue Nov 30 00:19:10 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-console.c, mi-console.exp: New files. Test console output.
+
+Mon Nov 29 17:59:13 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-support.exp (mi_run_command): Check for exec-run command
+       failure due to MI not having an active target.
+       (mi_run_command): Check for and handle a builtin simulator target.
+       (mi_run_command): Don't check/handle for ``The program has been
+       started already'', not a valid MI response.
+       
+       * mi-simplerun.exp (test_running_the_program): Update all patterns
+       to match async output.
+       (test_running_the_program): Mark ``step to callee4'' as XFAIL.  MI
+       output contains {,reason="end-stepping-range"}+.
+
+       * mi-simplerun.exp: Limit the timeout for ``step to callee4'' to
+       30 seconds.
+
+Mon Nov 29 17:30:00 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * mi-support.exp (skip_mi_tests): Print UNTESTED when MI interface
+       isn't available.  Start/stop instead of assuming GDB is running.
+       (MIFLAGS): Define.
+       * mi-simplerun.exp, mi-disassemble.exp, mi-break.exp,
+       mi-basics.exp, mi-watch.exp: Update.
+
+1999-11-26  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * mi-simplerun.exp: Move break-insert {-t, -r} from here.
+       * mi-break.exp: To here. New file.
+       * mi-watch.exp: New file. Tests for watchpoints.
+
+Wed Nov 24 17:42:07 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gdb.mi/ChangeLog-mi: MI entries moved to here.
+
+Wed Nov 24 17:31:04 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gdb.mi/mi-basics.exp, gdb.mi/mi-disassemble.exp,
+       gdb.mi/mi-simplerun.exp: Print warning message when test isn't
+       run.
+
+1999-11-23  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdb.mi/mi-simplerun.exp: Update output of break-list to account for
+       "times" field.
+
+1999-11-05  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdb.mi/mi-simplerun.exp: Add tests for temporary breakpoints
+       and bp based on regular expressions.
+       * gdb.mi/mi-disassemble.exp: Fix typo.
+
+1999-11-04  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdb.mi/mi-disassemble.exp: Update output of execution commands
+       to reflect new 'reason' field.
+       * gdb.mi/mi-simplerun.exp: Ditto.
+
+1999-10-25  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdb.mi/mi-simplerun.exp: Add more stack-list-frames tests.
+
+       * gdb.mi/mi-disassemble.exp: Update 'run to main' output.  
+
+       * gdb.mi/mi-simplerun.exp: Update execution commands
+       output. Update backtrace output.
+       
+1999-10-18  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdb.mi/mi-disassemble.exp: Add new tests for the new
+       disassembly command parameter, number of lines.
+
+Mon Oct 11 13:57:21 1999  Andrew Cagney  <cagney@amy.cygnus.com>
+
+       * lib/mi-support.exp: Break complicated gdb_expect containing
+       exp_continue into a while within an expect.  Don't attempt a start
+       more than three times.  Check return value from gdb_load.
+       
+1999-10-06  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>
+
+       * gdb.mi/mi-disassemble.exp: New file.
+
+Wed Oct  6 12:05:58 1999  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * lib/mi-support.exp (mi_run_cmd): Give up after two restart
+       attempts.
+
+1999-09290  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * gdb.mi/mi-basics.exp: Update to current syntax and output formats.
+       * gdb.mi/mi-simplerun.exp: Ditto.
+       * lib/mi-support.exp (mi_delete_breakpoints): Ditto.
+
+1999-06-30  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * gdb.mi/basics.c (main): Fix return code.  Add a print "Hello,
+       World".
+       * gdb.mi/mi-basics.exp: Fix message texts and numbering.
+       * gdb.mi/mi-simplerun.exp: Ditto. Also, add new tests and improve
+       some patterns.
+
+1999-06-30  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * lib/mi-support.exp (mi_gdb_reinitialize_dir): Remove query as an
+       acceptable response to the environment-dir command.
+
+1999-06-30  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * lib/mi-support.exp (mi_delete_breakpoints): Remove references to
+       gdb-cli.
+       (mi_run_cmd): Ditto.
+
+1999-06-25  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * lib/mi-support.exp (skip_mi_tests): Use gdb-version to check for
+       headless output format.
+
+1999-06-24  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * gdb.mi/mi-simplerun.exp (test_controlled_execution): Add global
+       spec for hex.
+
+1999-06-24  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * lib/mi-support.exp (mi_run_cmd): Fix pattern and add a timeout
+       clause.
+
+1999-06-24  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * lib/mi-support.exp: Use mi_gdb_prompt instead of a modified
+       gdb_prompt.  Remove uneeded loading of libgloss.
+       (mi_gdb_exit): Remove prompt argument.
+       (mi_uncatched_gdb_exit): Ditto.
+       (mi_run_cmd): New proc. MI version of gdb_run.
+       (skip_mi_tests): New proc. Check if gdb is capable of producing
+       headless formatted output.
+       * gdb.mi/mi-basics.exp: Use mi_gdb_prompt instead of a modified
+       gdb_prompt.  Eliminate parameter to mi_gdb_exit (as a result of
+       the above).  Test for skip_mi_tests before running.
+       Note: The above changes are interelated (need each other).
+       * gdb.mi/mi-simplerun.exp: Same changes as for mi-basics.exe
+       above.
+       (test_breakpoint_creation_and_listing): Remove insertion of
+       breakpoint at callee1 (and renumber tokens). Add tests for
+       break-list, break-disable and break-info.
+       (test_running_the_program): Use mi_run_cmd so it can run on remote
+       targets.
+       (test_controlled_execution): Fix broken test.
+       (test_program_termination): Test implemented.
+       * gdb.mi/basic.c (main): Small change to allow for testing of both
+       exec-next and exec-step operations.
+
+1999-06-22  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+        * lib/mi-support.exp (mi_gdb_test): New proc.  MI version of gdb_test.
+        * gdb.mi/mi-basics.exp: Use the above instead of gdb_test.
+        * gdb.mi/mi-simplerun.exp: Ditto.
+
+1999-06-22  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+        * gdb.mi/mi-simplerun.exp: New file. Tests simple debugging tasks. 
+        * gdb.mi/mi-basics.exp: Remove tests moved to above new file.
+        * lib/mi-support.exp: New file.  Support procedures for mi tests.
+
+1999-06-08  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * gdb.mi/mi-basics.exp: Skip all tests if the MI interpreter is
+       not active.
+
+1999-06-03  Fernando Nasser  <fnasser@totem.to.cygnus.com>
+
+       * gdb.mi: New directory.
+       * configure.in: Configure it.
+       * configure: Regenerate.
+       * gdb.mi/{Makefile.in,configure.in,configure}: New files.
+       * gdb.mi/{mi-basics.exp,basics.c,testcmds}: New files.
+
+\f
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/testsuite/gdb.mi/Makefile.in b/gdb/testsuite/gdb.mi/Makefile.in
new file mode 100644 (file)
index 0000000..6fedc18
--- /dev/null
@@ -0,0 +1,20 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+PROGS = basics c_variable cpp_variable var-cmd
+
+MISCELLANEOUS = testcmds
+
+all: 
+       @echo "Nothing to be done for all..."
+
+#### host, target, and site specific Makefile frags come in here.
+
+clean mostlyclean:
+       -rm -f *.ci *.o $(OBJS) $(PROGS) $(MISCELLANEOUS) *~ core
+
+distclean maintainer-clean realclean: clean
+       -rm -f Makefile config.status config.log
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+       $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.mi/basics.c b/gdb/testsuite/gdb.mi/basics.c
new file mode 100644 (file)
index 0000000..52fe0ed
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *     This simple program that passes different types of arguments
+ *      on function calls.  Useful to test printing frames, stepping, etc.
+ */
+
+callee4 (void)
+{
+  int A=1;
+  int B=2;
+  int C;
+
+  C = A + B;
+}
+
+callee3 (char *strarg)
+{
+  callee4 ();
+}
+
+callee2 (int intarg, char *strarg)
+{
+  callee3 (strarg);
+}
+
+callee1 (int intarg, char *strarg, double fltarg)
+{
+  callee2 (intarg, strarg);
+}
+
+main ()
+{
+  callee1 (2, "A string argument.", 3.5);
+  callee1 (2, "A string argument.", 3.5);
+
+  printf ("Hello, World!");
+
+  return 0;
+}
+
+
+
diff --git a/gdb/testsuite/gdb.mi/configure b/gdb/testsuite/gdb.mi/configure
new file mode 100755 (executable)
index 0000000..fd5d146
--- /dev/null
@@ -0,0 +1,902 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=mi-basics.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+#    configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+#    same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+#    as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:575: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:596: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+  case $nonopt in
+  NONE) target_alias=$host_alias ;;
+  *) target_alias=$nonopt ;;
+  esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:614: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[    `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.mi/configure.in b/gdb/testsuite/gdb.mi/configure.in
new file mode 100644 (file)
index 0000000..9427827
--- /dev/null
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory.  For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(mi-basics.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.mi/mi-basics.exp b/gdb/testsuite/gdb.mi/mi-basics.exp
new file mode 100644 (file)
index 0000000..acd905c
--- /dev/null
@@ -0,0 +1,177 @@
+#   Copyright (C) 1999 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# test basic Machine interface (MI) operations
+#
+# Verify that, using the MI, we can load a program and do
+# other basic things that are used by all test files through  mi_gdb_exit,
+# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
+# mi_gdb_load, so we can safely use those.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but the command syntax and correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# In this file we want to test if the operations needed by the following
+# procedures work, so it makes no sense using them here.
+
+# mi_delete_breakpoints
+# mi_gdb_reinitialize_dir $srcdir/$subdir
+# mi_gdb_load ${binfile}
+
+# Test if the MI interpreter has been configured
+
+proc test_mi_interpreter_selection {} {
+    global mi_gdb_prompt
+    global gdb_prompt
+
+    # All this test expects is to get the prompt back
+    # with no syntax error message
+    send_gdb "-gdb-version\n"
+    gdb_expect {
+           -re "GNU gdb .*\r\n$mi_gdb_prompt$" \
+               { pass "acceptance of MI operations" 
+                 return 1}
+           -re ".*\r\n$mi_gdb_prompt$" \
+               { fail "acceptance of MI operations"
+                 note "Skipping all other MI tests." }
+           -re "Undefined command.*$gdb_prompt $" \
+               { fail "acceptance of MI operations"
+                 note "Skipping all other MI tests." }
+           -re ".*$gdb_prompt $" \
+               { fail "acceptance of MI operations"
+                 note "Skipping all other MI tests." }
+           timeout { fail "acceptance of MI operations (timeout)"
+                     note "Skipping all other MI tests." }
+    }
+    return 0
+}
+
+proc test_exec_and_symbol_mi_operatons {} {
+    global mi_gdb_prompt
+    global binfile
+
+    # Load symbols and specify executable on a single operation
+    # Tests:
+    # -file-exec-and-symbols
+
+    # Can't use mi_gdb_test as if this doesn't work,
+    #  we must give up on the whole test file
+    send_gdb "-file-exec-and-symbols ${binfile}\n"
+    gdb_expect {
+           -re "\[\r\n\]*\\\^done\r\n$mi_gdb_prompt$" \
+               { pass "file-exec-and-symbols operation" }
+           timeout { fail "file-exec-and-symbols operation (timeout)"
+                     note "Skipping all other MI tests."
+                     return 0}
+    }
+
+    # The following is not used by mi-support.exp, but we test here so
+    # we get done with loading a program basics.
+
+    # Do it again, but now load symbols and specify executable with
+    # two separate operations
+    # Tests:
+    # -file-clear
+    # -file-exec-file
+    # -file-symbol-file
+
+    # FIXME: file-clear is not implemented yet.
+    mi_gdb_test "-file-clear" \
+             "\\\^done" \
+             "file-clear operation"
+
+    mi_gdb_test "-file-exec-file ${binfile}" \
+             "\\\^done" \
+             "file-exec-file operation"
+
+    mi_gdb_test "-file-symbol-file ${binfile}" \
+             "\\\^done" \
+             "file-symbol-file operation"
+
+    # FIXME: if we cannot load we have to skip all other tests.
+}
+
+proc test_breakpoints_deletion {} {
+    global mi_gdb_prompt
+    global srcfile
+
+    # Clear all breakpoints and list to confirm
+    # Tests:
+    # -break-delete (all)
+    # -break-list
+
+    # The all parameter is actually no parameter.
+    mi_gdb_test "200-break-delete" \
+             "\\\^done" \
+             "break-delete (all) operation"
+
+    mi_gdb_test "201-break-list" \
+             ".*\\\^done,BreakpointTable=\\\{\\\}" \
+             "all breakpoints removed"
+}
+
+proc test_dir_specification {} {
+    global mi_gdb_prompt
+    global srcdir
+    global subdir
+
+    # Clear the search directories, then specify one to be searched
+    # Tests:
+    # -environment-directory
+    # -environment-directory arg
+
+#exp_internal 1
+    mi_gdb_test "202-environment-directory" \
+             "\\\^done" \
+             "environment-directory operation"
+
+    mi_gdb_test "203-environment-directory ${srcdir}/${subdir}" \
+             "\\\^done" \
+             "environment-directory arg operation"
+#exp_internal 0
+}
+
+if [test_mi_interpreter_selection] {
+  test_exec_and_symbol_mi_operatons
+  test_breakpoints_deletion
+  test_dir_specification
+}
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
new file mode 100644 (file)
index 0000000..27c7e6b
--- /dev/null
@@ -0,0 +1,141 @@
+#   Copyright (C) 1999 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_tbreak_creation_and_listing {} {
+    global mi_gdb_prompt
+    global srcfile
+    global hex
+
+    # Insert some breakpoints and list them
+    # Also, disable some so they do not interfere with other tests
+    # Tests:
+    # -break-insert -t main
+    # -break-insert -t basics.c:callee2
+    # -break-insert -t basics.c:15
+    # -break-insert -t srcfile:6
+    # -break-list
+
+    mi_gdb_test "222-break-insert -t main" \
+             "222\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+             "break-insert -t operation"
+
+    mi_gdb_test "333-break-insert -t basics.c:callee2" \
+             "333\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
+             "insert temp breakpoint at basics.c:callee2"
+
+    mi_gdb_test "444-break-insert -t basics.c:15" \
+             "444\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \
+             "insert temp breakpoint at basics.c:15 (callee3)"
+
+    # Getting the quoting right is tricky.  That is "\"<file>\":6"
+    mi_gdb_test "555-break-insert -t \"\\\"${srcfile}\\\":6\"" \
+             "555\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \
+             "insert temp breakpoint at \"<fullfilename>\":6 (callee4)"
+
+    mi_gdb_test "666-break-list" \
+                "666\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+                "list of breakpoints"
+
+    mi_gdb_test "777-break-delete" \
+           "777\\^done" \
+           "delete temp breakpoints"
+}
+
+proc test_rbreak_creation_and_listing {} {
+    global mi_gdb_prompt
+    global srcfile
+    global hex
+
+    # Insert some breakpoints and list them
+    # Also, disable some so they do not interfere with other tests
+    # Tests:
+    # -break-insert -r main
+    # -break-insert -r callee2
+    # -break-insert -r callee
+    # -break-insert -r .*llee
+    # -break-list
+
+    setup_xfail "*-*-*"
+    mi_gdb_test "122-break-insert -r main" \
+             "122\\^done,bkpt=\{number=\"5\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \
+             "break-insert -r operation"
+
+    setup_xfail "*-*-*"
+    mi_gdb_test "133-break-insert -r callee2" \
+             "133\\^done,bkpt=\{number=\"6\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\}" \
+             "insert breakpoint with regexp callee2"
+
+    setup_xfail "*-*-*"
+    mi_gdb_test "144-break-insert -r callee" \
+           "144\\^done,bkpt=\{number=\"7\",addr=\"$hex\",file=\".*basics.c\",line=\"27\"\},bkpt=\{number=\"8\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\},bkpt=\{number=\"9\",addr=\"$hex\",file=\".*basics.c\",line=\"17\"\},bkpt=\{number=\"10\",addr=\"$hex\",file=\".*basics.c\",line=\"8\"\}" \
+             "insert breakpoint with regexp callee"
+
+    setup_xfail "*-*-*"
+    mi_gdb_test "155-break-insert -r \.\*llee" \
+           "155\\^done,bkpt=\{number=\"11\",addr=\"$hex\",file=\".*basics.c\",line=\"27\"\},bkpt=\{number=\"12\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\},bkpt=\{number=\"13\",addr=\"$hex\",file=\".*basics.c\",line=\"17\"\},bkpt=\{number=\"14\",addr=\"$hex\",file=\".*basics.c\",line=\"8\"\}" \
+             "insert breakpoint with regexp .*llee"
+
+    setup_xfail "*-*-*"
+    mi_gdb_test "166-break-list" \
+                "166\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+                "list of breakpoints"
+
+    mi_gdb_test "177-break-delete" \
+           "177\\^done" \
+           "delete temp breakpoints"
+}
+
+test_tbreak_creation_and_listing
+test_rbreak_creation_and_listing
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
diff --git a/gdb/testsuite/gdb.mi/mi-console.c b/gdb/testsuite/gdb.mi/mi-console.c
new file mode 100644 (file)
index 0000000..f0f2016
--- /dev/null
@@ -0,0 +1,20 @@
+void
+hello ()
+{
+  char *hello = "Hello \\\"!\r\n";
+  int i;
+  for (i = 0; hello[i]; i++)
+    write (1, hello + i, 1);
+}
+
+int
+main ()
+{
+  hello ();
+}
+/*
+Local variables: 
+change-log-default-name: "ChangeLog-mi"
+End: 
+*/
+
diff --git a/gdb/testsuite/gdb.mi/mi-console.exp b/gdb/testsuite/gdb.mi/mi-console.exp
new file mode 100644 (file)
index 0000000..f960ceb
--- /dev/null
@@ -0,0 +1,101 @@
+#   Copyright (C) 1999, 2000 Cygnus Solutions.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+# This test only works when talking to a target that routes its output
+# through GDB.  Check that we're either talking to a simulator or a
+# remote target.
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "mi-console"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+# Halt in main
+mi_gdb_test "200-break-insert main" \
+       "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*mi-console.c\",line=\"13\",times=\"0\"\}" \
+       "break-insert operation"
+mi_run_cmd
+gdb_expect {
+    -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*mi-console.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+           pass "run to main"
+    }
+    timeout {
+       fail "run to main (timeout)"
+    }
+}
+
+# Next over the hello() call which will produce lots of output
+send_gdb "47-exec-next\n"
+gdb_expect {
+    -re "47\\^running\r\n$mi_gdb_prompt" {
+       pass "Started step over hello"
+    }
+    timeout {
+       fail "Started step over hello (timeout)"
+    }
+}
+
+gdb_expect {
+    -re "@\"H\"\r\n.*@\"e\"\r\n.*@\"l\"\r\n.*@\"l\"\r\n.*@\"o\"\r\n.*@\" \"\r\n.*@\"\\\\\\\\\"\r\n.*@\"\\\\\"\"\r\n.*@\"!\"\r\n.*@\"\\\\r\"\r\n.*@\"\\\\n\"\r\n" {
+       pass "Hello message"
+    }
+    timeout {
+       fail "Hello message (timeout)"
+    }
+}
+    
+gdb_expect {
+    -re "47\\*stopped.*$mi_gdb_prompt$" {
+       pass "Finished step over hello"
+    }
+    timeout {
+       fail "Finished step over hello (timeout)"
+    }
+}
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
diff --git a/gdb/testsuite/gdb.mi/mi-disassemble.exp b/gdb/testsuite/gdb.mi/mi-disassemble.exp
new file mode 100644 (file)
index 0000000..cd7f023
--- /dev/null
@@ -0,0 +1,295 @@
+#   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test Machine interface (MI) operations for disassembly.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+    global mi_gdb_prompt
+    global srcfile
+    global hex
+
+    # Insert some breakpoints and list them
+    # Also, disable some so they do not interfere with other tests
+    # Tests:
+    # -break-insert
+    # -break-list
+    # -break-disable
+    # -break-info
+
+    mi_gdb_test "200-break-insert main" \
+             "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+             "break-insert operation"
+
+    mi_gdb_test "204-break-list" \
+                "204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}\}" \
+                "list of breakpoints"
+}
+
+proc test_running_the_program {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Run the program without args
+    # Tests:
+    # -exec-run
+
+    # mi_gdb_test cannot be used for asynchronous commands because there are
+    # two prompts involved and this can lead to a race condition.
+    # FIXME: We are accepting a duplicate file and line info temporarely.
+    # The following is equivalent to a send_gdb "000-exec-run\n"
+    mi_run_cmd
+    # The running part has been checked already by mi_run_cmd
+        gdb_expect {
+           -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+            pass "run to main"
+          }
+          -re ".*$mi_gdb_prompt$" {fail "run to main (2)"}
+          timeout {fail "run to main (timeout 2)"}
+        }
+}
+
+proc test_disassembly_only {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Test disassembly more only for the current function.
+    # Tests:
+    # -data-disassembly $pc 0 0 -1
+    # -data-disassembly main 0 0 -1
+    # -data-disassembly $pc $pc+8 0 -1
+    # -data-disassembly callee2 0 0 -1
+
+    mi_gdb_test "print/x \$pc" "" ""
+    mi_gdb_test "111-data-disassemble \$pc 0 0 -1" \
+           "111\\^done,asm_insns=\{\{address=\"$hex <main>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},.*\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
+             "data-disassemble from pc assembly only"
+
+    mi_gdb_test "222-data-disassemble main 0 0 -1" \
+           "222\\^done,asm_insns=\{\{address=\"$hex <main>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
+              "data-disassemble main assembly only"
+
+    mi_gdb_test "333-data-disassemble \$pc \$pc+8 0 -1" \
+           "333\\^done,asm_insns=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
+             "data-disassemble range assembly only"
+
+    mi_gdb_test "444-data-disassemble callee2 0 0 -1" \
+           "444\\^done,asm_insns=\{\{address=\"$hex <callee2\[0-9\]*>\",inst=\".*\"\},.*\{address=\"$hex <callee2\\+\[0-9\]*>\",inst=\".*\"\}\}" \
+             "data-disassemble callee2 assembly only"
+
+}
+
+proc test_disassembly_lines_limit {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Test disassembly more only for the current function.
+    # Tests:
+    # -data-disassembly $pc 0 0 2
+    # -data-disassembly main 0 0 1
+    # -data-disassembly main 0 0 0
+    # -data-disassembly $pc $pc+8 0 99
+    # -data-disassembly $pc $pc+12 0 2
+
+    mi_gdb_test "print/x \$pc" "" ""
+    mi_gdb_test "100-data-disassemble \$pc 0 0 2" \
+           "100\\^done,asm_insns=\{\{address=\"$hex <main\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
+             "data-disassemble from pc two lines - assembly only"
+
+    mi_gdb_test "200-data-disassemble main 0 0 1" \
+           "200\\^done,asm_insns=\{\{address=\"$hex <main\[0-9\]*>\",inst=\".*\"\}\}" \
+           "data-disassemble main 1 line - assembly only"
+
+    mi_gdb_test "300-data-disassemble main 0 0 0" \
+             "300\\^done,asm_insns=\{\}" \
+             "data-disassemble main zero lines - assembly only"
+
+    mi_gdb_test "400-data-disassemble \$pc \$pc+8 0 99" \
+           "400\\^done,asm_insns=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
+             "data-disassemble lines bigger than range - assembly only"
+
+    mi_gdb_test "500-data-disassemble \$pc \$pc+12 0 2" \
+           "500\\^done,asm_insns=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}" \
+             "data-disassemble lines less than range - assembly only"
+}
+
+proc test_disassembly_mixed {} {
+    global mi_gdb_prompt
+    global hex
+    global decimal
+
+    # Test disassembly more only for the current function.
+    # Tests:
+    # -data-disassembly main 0 1 -1
+    # -data-disassembly $pc $pc+8 1 -1
+    # -data-disassembly callee2 0 1 -1
+
+    mi_gdb_test "002-data-disassemble callee2 0 1 -1" \
+           "002\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <callee2\[0-9\]*>\",inst=\".*\"\}\}\},src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{.*\{address=\"$hex <callee2\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
+             "data-disassemble callee2 assembly mixed"
+
+    #
+    # In mixed mode, the lowest level of granularity is the source line.
+    # So we are going to get the disassembly for the source line at
+    # which we are now.
+    #
+    mi_gdb_test "003-data-disassemble \$pc \$pc+8 1 -1" \
+           "003\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}.*\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
+             "data-disassemble range assembly mixed"
+
+    mi_gdb_test "004-data-disassemble callee2 0 1 -1" \
+           "004\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <callee2\[0-9\]*>\",inst=\".*\"\}\}\},.*src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{.*\{address=\"$hex <callee2\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
+             "data-disassemble callee2 assembly mixed"
+}
+
+proc test_disassembly_mixed_lines_limit {} {
+    global mi_gdb_prompt
+    global hex
+    global decimal
+
+    # Test disassembly more only for the current function.
+    # Tests:
+    # -data-disassembly $pc 0 1 2
+    # -data-disassembly main 0 1 1
+    # -data-disassembly main 0 1 0
+    # -data-disassembly $pc $pc+4 1 99
+    # -data-disassembly $pc $pc+12 1 2
+
+    mi_gdb_test "print/x \$pc" "" ""
+    mi_gdb_test "100-data-disassemble \$pc 0 1 2" \
+           "100\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\[0-9\]*>\",inst=\".*\"\}\}\},src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
+             "data-disassemble from pc two lines - assembly mixed"
+
+    mi_gdb_test "200-data-disassemble main 0 1 1" \
+           "200\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
+           "data-disassemble main 1 line - assembly mixed"
+
+    mi_gdb_test "300-data-disassemble main 0 1 0" \
+           "300\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\}\}\}" \
+             "data-disassemble main zero lines - assembly mixed"
+
+    mi_gdb_test "400-data-disassemble \$pc \$pc+4 1 99" \
+           "400\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}.*\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
+             "data-disassemble lines bigger than range - assembly mixed"
+
+    mi_gdb_test "500-data-disassemble \$pc \$pc+12 1 2" \
+           "500\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\},\{address=\"$hex <main\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
+             "data-disassemble lines less than range - assembly mixed"
+}
+
+proc test_disassembly_bogus_args {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Test that bogus input to disassembly command is rejected.
+    # Tests:
+    # -data-disassembly 0 0 0 0
+    # -data-disassembly 0 0 0
+    # -data-disassembly 0 0 
+    # -data-disassembly 0
+
+    mi_gdb_test "123-data-disassemble 0 0 0 0" \
+             ".*123\\^error,msg=\"No function contains specified address\"" \
+             "data-disassemble bogus arguments"
+
+    mi_gdb_test "321-data-disassemble 0 0 0" \
+             "321\\^error,msg=\"mi_cmd_disassemble: Usage: start_address end_address mixed_mode num_of_lines.\"" \
+             "data-disassemble wrong num of args (3)"
+
+    mi_gdb_test "456-data-disassemble 0 0" \
+             "456\\^error,msg=\"mi_cmd_disassemble: Usage: start_address end_address mixed_mode num_of_lines.\"" \
+             "data-disassemble wrong num of args (2)"
+
+    mi_gdb_test "789-data-disassemble 0" \
+             "789\\^error,msg=\"mi_cmd_disassemble: Usage: start_address end_address mixed_mode num_of_lines.\"" \
+             "data-disassemble wrong num of args (1)"
+
+}
+
+proc test_disassembly_mixed_from_pc {} {
+    global mi_gdb_prompt
+    global hex
+    global decimal
+
+    # Test disassembly more only for the current function.
+    # Tests:
+    # -data-disassembly $pc 0 1 -1
+
+    mi_gdb_test "200-break-insert callee2" \
+             "200\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
+             "break-insert operation for mixed"
+
+    send_gdb "123-exec-continue\n"
+    gdb_expect {
+      -re "123\\^running\r\n$mi_gdb_prompt" {
+         gdb_expect {
+             -re "\[\r\n\]*123\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee2\",args=\{.*\},file=\".*basics.c\",line=\"22\"\}\r\n$mi_gdb_prompt$" {
+                 pass "run to callee2"
+             }
+             -re ".*$mi_gdb_prompt$" {fail "run to callee2 (2)"}
+             timeout {fail "run to callee2 (timeout 2)"}
+         }
+      }
+      -re ".*$mi_gdb_prompt$" {fail "continue to callee2 (1)"}
+      timeout {fail "continue to callee2 (timeout 1)"}
+    }
+
+    mi_gdb_test "001-data-disassemble \$pc 0 1 -1" \
+           "001\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex <callee2\[0-9\]*>\",inst=\".*\"\}\}\},src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{.*\{address=\"$hex <callee2\\+\[0-9\]*>\",inst=\".*\"\}\}\}\}" \
+             "data-disassemble from pc assembly mixed"
+
+}
+
+test_breakpoints_creation_and_listing
+test_running_the_program
+test_disassembly_only
+test_disassembly_mixed
+test_disassembly_bogus_args
+test_disassembly_lines_limit
+test_disassembly_mixed_lines_limit
+test_disassembly_mixed_from_pc
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
diff --git a/gdb/testsuite/gdb.mi/mi-eval.exp b/gdb/testsuite/gdb.mi/mi-eval.exp
new file mode 100644 (file)
index 0000000..bb527da
--- /dev/null
@@ -0,0 +1,105 @@
+#   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify -data-evaluate-expression. There are really minimal tests.
+
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_the_program {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Run the program without args, then specify srgs and rerun the program
+    # Tests:
+    # -exec-run
+
+    mi_gdb_test "300-break-insert callee4" \
+             "300\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+             "insert breakpoint at callee4"
+
+    # mi_gdb_test cannot be used for asynchronous commands because there are
+    # two prompts involved and this can lead to a race condition.
+    # The following is equivalent to a send_gdb "000-exec-run\n"
+    mi_run_cmd
+    # The running part has been checked already by mi_run_cmd
+        gdb_expect {
+           -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" \
+                   { pass "run to callee4" }
+          -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+          timeout {fail "run to callee4 (timeout 2)"}
+        }
+       
+       send_gdb "101-exec-next\n"
+        gdb_expect {
+           -re "101\\^running\r\n$mi_gdb_prompt" {
+               gdb_expect {
+                   -re "\[\r\n\]*101\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"9\"\}\r\n$mi_gdb_prompt$" \
+                   { pass "next in callee4" }
+           -re ".*$mi_gdb_prompt$" {fail "next in callee4 (2)"}
+           timeout {fail "next in callee4 (timeout 2)"}
+        }
+    }
+      -re ".*$mi_gdb_prompt$" {fail "next in callee4 (1)"}
+      timeout {fail "next in callee4 (timeout 1)"}
+    }
+
+}
+
+test_running_the_program
+
+mi_gdb_test "211-data-evaluate-expression A" "211\\^done,value=\"1\"" "eval A"
+
+mi_gdb_test "311-data-evaluate-expression &A" "311\\^done,value=\"$hex\"" "eval &A"
+
+mi_gdb_test "411-data-evaluate-expression A+3" "411\\^done,value=\"4\"" "eval A+3"
+
+mi_gdb_test "511-data-evaluate-expression \"A + 3\"" "511\\^done,value=\"4\"" "eval A + 3"
+
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
+
diff --git a/gdb/testsuite/gdb.mi/mi-hack-cli.exp b/gdb/testsuite/gdb.mi/mi-hack-cli.exp
new file mode 100644 (file)
index 0000000..521679f
--- /dev/null
@@ -0,0 +1,43 @@
+#   Copyright (C) 1999 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+# Some basic checks for the CLI.
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+mi_gdb_test "show architecture\n" \
+       "&\"show architecture\\\\n\"\r\n~\"The target architecture.*\"\r\n\\^done" \
+       "show architecture"
+
+mi_gdb_test "47show architecture\n" \
+       "&\"show architecture\\\\n\"\r\n~\"The target architecture.*\"\r\n47\\^done" \
+       "47show architecture"
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
diff --git a/gdb/testsuite/gdb.mi/mi-read-memory.c b/gdb/testsuite/gdb.mi/mi-read-memory.c
new file mode 100644 (file)
index 0000000..7a87c64
--- /dev/null
@@ -0,0 +1,20 @@
+static char bytes[256];
+
+static short shorts[256];
+
+static void
+initialize (void)
+{
+  int i;
+  for (i = 0; i < sizeof (bytes); i++)
+    {
+      bytes[i] = i;
+      shorts[i] = i * 2;
+    }
+}
+
+int
+main ()
+{
+  initialize ();
+}
diff --git a/gdb/testsuite/gdb.mi/mi-read-memory.exp b/gdb/testsuite/gdb.mi/mi-read-memory.exp
new file mode 100644 (file)
index 0000000..73dac1c
--- /dev/null
@@ -0,0 +1,103 @@
+#   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# test basic Machine interface (MI) operations
+#
+# Verify that, using the MI, we can load a program and do
+# other basic things that are used by all test files through  mi_gdb_exit,
+# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
+# mi_gdb_load, so we can safely use those.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but the command syntax and correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "mi-read-memory"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+mi_run_to_main
+
+#mi_next "do initialization"
+send_gdb "101-exec-next\n"
+gdb_expect {
+    -re "101\\^running\r\n$mi_gdb_prompt" {
+       gdb_expect {
+           -re "\[\r\n\]*101\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*mi-read-memory.c\",line=\"20\"\}.*$mi_gdb_prompt$" \
+                   { pass "do initialization" }
+           -re ".*$mi_gdb_prompt$" {fail "do initialization (2)"}
+           timeout {fail "do initialization (timeout 2)"}
+        }
+    }
+      -re ".*$mi_gdb_prompt$" {fail "do initialization (1)"}
+      timeout {fail "do initialization (timeout 1)"}
+}
+
+mi_gdb_test "1-data-read-memory" \
+       "1\\^error,msg=\".*\"" \
+       "no arguments"
+
+
+mi_gdb_test "2-data-read-memory bytes x 1 3 2" \
+       "2\\^done,addr=\"$hex\",nr-bytes=\"6\",total-bytes=\"6\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x00\",\"0x01\"}},{addr=\"$hex\",data={\"0x02\",\"0x03\"}},{addr=\"$hex\",data={\"0x04\",\"0x05\"}}}" \
+       "3x2, one byte"
+
+
+mi_gdb_test "9-data-read-memory -o -6 -- -0+bytes+6 x 1 3 2" \
+       "9\\^done,addr=\"$hex\",nr-bytes=\"6\",total-bytes=\"6\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x00\",\"0x01\"}},{addr=\"$hex\",data={\"0x02\",\"0x03\"}},{addr=\"$hex\",data={\"0x04\",\"0x05\"}}}" \
+       "3x2, one byte offset by -6"
+
+
+mi_gdb_test "3-data-read-memory \"(shorts + 128)\" x 2 1 2" \
+       "3\\^done,addr=\"$hex\",nr-bytes=\"4\",total-bytes=\"4\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x0100\",\"0x0102\"}}}" \
+       "expression in quotes"
+
+
+mi_gdb_test "4-data-read-memory bytes+16 x 1 8 4 x" \
+       "4\\^done,addr=\"$hex\",nr-bytes=\"32\",total-bytes=\"32\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x10\",\"0x11\",\"0x12\",\"0x13\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x14\",\"0x15\",\"0x16\",\"0x17\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x18\",\"0x19\",\"0x1a\",\"0x1b\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x1c\",\"0x1d\",\"0x1e\",\"0x1f\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x20\",\"0x21\",\"0x22\",\"0x23\"},ascii=\" !\\\\\"#\"},{addr=\"$hex\",data={\"0x24\",\"0x25\",\"0x26\",\"0x27\"},ascii=\"\\$%&'\"},{addr=\"$hex\",data={\"0x28\",\"0x29\",\"0x2a\",\"0x2b\"},ascii=\"().+\"},{addr=\"$hex\",data={\"0x2c\",\"0x2d\",\"0x2e\",\"0x2f\"},ascii=\",-\./\"}}" \
+       "ascii and data"
+
+
+mi_gdb_test "5-data-read-memory shorts+64 d 2 1 1" \
+       "5\\^done,addr=\"$hex\",nr-bytes=\"2\",total-bytes=\"2\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"128\"}}}" \
+       "decimal"
+
+mi_gdb_test "6-data-read-memory shorts+64 o 2 1 1" \
+       "6\\^done,addr=\"$hex\",nr-bytes=\"2\",total-bytes=\"2\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0200\"}}}" \
+       "octal"
+
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
diff --git a/gdb/testsuite/gdb.mi/mi-regs.exp b/gdb/testsuite/gdb.mi/mi-regs.exp
new file mode 100644 (file)
index 0000000..2fe6e7b
--- /dev/null
@@ -0,0 +1,183 @@
+#   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and look at registers.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+    global mi_gdb_prompt
+    global srcfile
+    global hex
+
+    # Insert some breakpoints and list them
+    # Also, disable some so they do not interfere with other tests
+    # Tests:
+    # -break-insert
+    # -break-list
+    # -break-disable
+    # -break-info
+
+    mi_gdb_test "200-break-insert main" \
+             "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+             "break-insert operation"
+
+    mi_gdb_test "204-break-list" \
+                "204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}\}" \
+                "list of breakpoints"
+}
+
+proc test_running_the_program {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Run the program without args
+    # Tests:
+    # -exec-run
+
+    # mi_gdb_test cannot be used for asynchronous commands because there are
+    # two prompts involved and this can lead to a race condition.
+    # FIXME: We are accepting a duplicate file and line info temporarely.
+    # The following is equivalent to a send_gdb "000-exec-run\n"
+    mi_run_cmd
+    # The running part has been checked already by mi_run_cmd
+        gdb_expect {
+           -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+            pass "run to main"
+          }
+          -re ".*$mi_gdb_prompt$" {fail "run to main (2)"}
+          timeout {fail "run to main (timeout 2)"}
+        }
+}
+
+proc sparc_register_tests_no_exec { } {
+       # Test the generic IDT chip.
+       mi_gdb_test "111-data-list-register-values" \
+               ".*111\\^error,msg=\"mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> \\\[<regnum1>...<regnumN>\\\]\"" \
+               "wrong arguments"
+
+       mi_gdb_test "111-data-list-register-values x" \
+               ".*111\\^error,msg=\"mi_cmd_data_list_register_values: No registers\.\"" \
+               "no executable"
+}
+
+# These tests exercise IDT-specific MIPS registers for several
+# different processor models.
+
+# This should detect the actual processor in use and change
+# the expected results appropriately.  FIXME
+
+proc sparc_register_tests { } {
+    global hex
+    global decimal
+    set octal "\[0-7\]+"
+    set binary "\[0-1\]+"
+    set float "-?\[0-9\]+(\.\[0-9\]+)?(e\[+\-\]\[0-9\]+)?"
+    set float2 "\-?\[0-9\]+"
+
+    mi_gdb_test "111-data-list-register-names" \
+           "111\\^done,register-names=\{\"g0\",\"g1\",\"g2\",\"g3\",\"g4\",\"g5\",\"g6\",\"g7\",\"o0\",\"o1\",\"o2\",\"o3\",\"o4\",\"o5\",\"sp\",\"o7\",\"l0\",\"l1\",\"l2\",\"l3\",\"l4\",\"l5\",\"l6\",\"l7\",\"i0\",\"i1\",\"i2\",\"i3\",\"i4\",\"i5\",\"fp\",\"i7\",\"f0\",\"f1\",\"f2\",\"f3\",\"f4\",\"f5\",\"f6\",\"f7\",\"f8\",\"f9\",\"f10\",\"f11\",\"f12\",\"f13\",\"f14\",\"f15\",\"f16\",\"f17\",\"f18\",\"f19\",\"f20\",\"f21\",\"f22\",\"f23\",\"f24\",\"f25\",\"f26\",\"f27\",\"f28\",\"f29\",\"f30\",\"f31\",\"y\",\"psr\",\"wim\",\"tbr\",\"pc\",\"npc\",\"fpsr\",\"cpsr\"\}" \
+           "list register names"
+
+    mi_gdb_test "222-data-list-register-values x" \
+           "222\\^done,register-values=\{\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\}" \
+           "register values x"
+
+    mi_gdb_test "333-data-list-register-values f" \
+           "333\\^done,register-values=\{\{number=\"0\",value=\"$float\"\},\{number=\"1\",value=\"$float\"\},.*\{number=\"71\",value=\"$float\"\}\}" \
+           "register values f"
+
+    mi_gdb_test "444-data-list-register-values d" \
+           "444\\^done,register-values=\{\{number=\"0\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\}" \
+           "register values d"
+
+    mi_gdb_test "555-data-list-register-values o" \
+           "555\\^done,register-values=\{\{number=\"0\",value=\"$octal\"\}.*\{number=\"71\",value=\"$octal\"\}\}" \
+           "register values o"
+
+    mi_gdb_test "666-data-list-register-values t" \
+           "666\\^done,register-values=\{\{number=\"0\",value=\"$binary\"\}.*\{number=\"71\",value=\"$binary\"\}\}" \
+           "register values t"
+
+    # On the sparc, registers 0-31 are int, 32-63 float, 64-71 int
+
+    mi_gdb_test "777-data-list-register-values N" \
+           "777\\^done,register-values=\{\{number=\"0\",value=\"$decimal\"\}.*\{number=\"31\",value=\"$decimal\"\},\{number=\"32\",value=\"$float\"\}.*\{number=\"63\",value=\"$float\"\},\{number=\"64\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\}" \
+           "register values N"
+
+    mi_gdb_test "888-data-list-register-values r" \
+           "888\\^done,register-values=\{\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\}" \
+           "register values r"
+
+    mi_gdb_test "999-data-list-register-names 68 69 70 71" \
+           "999\\^done,register-names=\{\"pc\",\"npc\",\"fpsr\",\"cpsr\"\}" \
+           "list names of some regs"
+
+    mi_gdb_test "001-data-list-register-values x 68 69 70 71" \
+           "001\\^done,register-values=\{\{number=\"68\",value=\"$hex\"\},\{number=\"69\",value=\"$hex\"\},\{number=\"70\",value=\"$hex\"\},\{number=\"71\",value=\"$hex\"\}\}" \
+           "list values of some regs"
+
+    # Don't know how useful this test is
+
+    mi_gdb_test "002-data-list-changed-registers" \
+           "002\\^done,changed-registers=\{\"1\",\"9\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"23\",\"24\",\"25\",\"26\",\"27\",\"28\",\"30\",\"31\",\"65\",\"68\",\"69\"\}" \
+           "list changed registers"
+}
+
+if [istarget "sparc-*-*"] then {
+    sparc_register_tests_no_exec
+    test_breakpoints_creation_and_listing
+    test_running_the_program
+    sparc_register_tests
+} else {
+    verbose "mi-regs.exp tests ignored for this target"
+}
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
+
+
+
diff --git a/gdb/testsuite/gdb.mi/mi-return.exp b/gdb/testsuite/gdb.mi/mi-return.exp
new file mode 100644 (file)
index 0000000..076be9b
--- /dev/null
@@ -0,0 +1,94 @@
+#   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations 
+# Verify that, using the MI, we can run a simple program and perform
+# exec-return.  
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.  
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_callee4 {} {
+    global mi_gdb_prompt
+    global hex
+
+    mi_gdb_test "200-break-insert callee4" \
+             "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+             "break-insert operation"
+
+    mi_run_cmd
+
+    gdb_expect {
+       -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
+           pass "run to callee4"
+       }
+       timeout {
+           fail "run to callee4 (timeout)"
+       }
+    }
+
+    mi_gdb_test "205-break-delete" \
+                "205\\^done.*" \
+                "delete all breakpoints"
+
+}
+
+proc test_return_simple {} {
+    global mi_gdb_prompt
+    global hex
+
+    send_gdb "111-exec-return\n"
+    gdb_expect {
+       -re "111\\^done,frame=\{level=\"0 \",addr=\"$hex\",func=\"callee3\",args=\{.*\},file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {pass "return from callee4 now"}
+       -re ".*\r\n$mi_gdb_prompt$" { fail "return from callee4 now" }
+       timeout { fail "return from callee4 now (timeout)"
+       }
+    }
+}
+
+test_running_to_callee4
+test_return_simple
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End:
diff --git a/gdb/testsuite/gdb.mi/mi-simplerun.exp b/gdb/testsuite/gdb.mi/mi-simplerun.exp
new file mode 100644 (file)
index 0000000..4b95c41
--- /dev/null
@@ -0,0 +1,232 @@
+#   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+    global mi_gdb_prompt
+    global srcfile
+    global hex
+
+    # Insert some breakpoints and list them
+    # Also, disable some so they do not interfere with other tests
+    # Tests:
+    # -break-insert
+    # -break-list
+    # -break-disable
+    # -break-info
+
+    mi_gdb_test "200-break-insert main" \
+             "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+             "break-insert operation"
+
+    mi_gdb_test "201-break-insert basics.c:callee2" \
+             "201\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
+             "insert breakpoint at basics.c:callee2"
+
+    mi_gdb_test "202-break-insert basics.c:15" \
+             "202\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \
+             "insert breakpoint at basics.c:15 (callee3)"
+
+    mi_gdb_test "203-break-insert \"\\\"${srcfile}\\\":6\"" \
+             "203\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \
+             "insert breakpoint at \"<fullfilename>\":6 (callee4)"
+
+    mi_gdb_test "204-break-list" \
+                "204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+                "list of breakpoints"
+
+    mi_gdb_test "205-break-disable 2 3 4" \
+                "205\\^done.*" \
+                "disabling of breakpoints"
+
+    mi_gdb_test "206-break-info 2" \
+                "206\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"2\",.*,enabled=\"n\",.*\}\}" \
+                "list of breakpoints, 16 disabled"
+}
+
+proc test_running_the_program {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Run the program without args, then specify srgs and rerun the program
+    # Tests:
+    # -exec-run
+    # -gdb-set
+
+    # mi_gdb_test cannot be used for asynchronous commands because there are
+    # two prompts involved and this can lead to a race condition.
+    # The following is equivalent to a send_gdb "000-exec-run\n"
+    mi_run_cmd
+    gdb_expect {
+       -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+           pass "run to main"
+       }
+       timeout {
+           fail "run to main (timeout)"
+       }
+    }
+}
+
+proc test_controlled_execution {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Continue execution until a breakpoint is reached, step into calls, verifying
+    # if the arguments are correctly shown, continue to the end of a called
+    # function, step over a call (next).
+    # Tests:
+    # -exec-continue
+    # -exec-next
+    # -exec-step
+    # -exec-finish
+
+    # mi_gdb_test cannot be used for asynchronous commands because there are
+    # two prompts involved and this can lead to a race condition.
+    send_gdb "220-exec-next\n"
+    gdb_expect {
+       -re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"33\"\}\r\n$mi_gdb_prompt$" {
+           pass "next at main"
+       }
+       timeout {
+           fail "next at main (timeout)"
+       }
+    }
+
+    # FIXME: A string argument is not printed right; should be fixed and
+    #        we should look for the right thing here.
+    # NOTE: The ``\\\\\"'' is for \".
+    send_gdb "221-exec-step\n"
+    gdb_expect {
+       -re "221\\^running\r\n${mi_gdb_prompt}221\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee1\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument\.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\},file=\".*basics.c\",line=\"27\"\}\r\n$mi_gdb_prompt$" {
+            pass "step at main"
+       }
+       timeout {
+           fail "step at main (timeout)"
+        }
+    }
+
+    # FIXME: A string argument is not printed right; should be fixed and
+    #        we should look for the right thing here.
+    send_gdb "222-exec-step 3\n"
+    gdb_expect 30 {
+       -re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
+            pass "step to callee4"
+       }
+       timeout {
+           fail "step to callee4 (timeout)"
+       }
+    }
+
+    # FIXME: A string argument is not printed right; should be fixed and
+    #        we should look for the right thing here.
+    # NOTE: The ``.'' is part of ``gdb-result-var="$1"''
+    send_gdb "223-exec-finish\n"
+    gdb_expect 30 {
+       -re "223\\^running\r\n${mi_gdb_prompt}223\\*stopped,reason=\"function-finished\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee3\",args=\{.*\},file=\".*basics.c\",line=\"18\"\},gdb-result-var=\".1\",return-value=\"0\"\r\n$mi_gdb_prompt$" {
+            pass "exec-finish"
+       }
+       timeout {
+           fail "exec-finish (timeout)"
+       }
+    }
+}
+
+proc test_controlling_breakpoints {} {
+    global mi_gdb_prompt
+
+    # Enable, delete, set ignore counts in breakpoints
+    # (disable was already tested above)
+    # Tests:
+    # -break-delete
+    # -break-enable
+    # -break-after
+    # -break-condition
+
+}
+
+proc test_program_termination {} {
+    global mi_gdb_prompt
+
+    # Run to completion: normal and forced
+    # Tests:
+    # -exec-abort
+    # (normal termination of inferior)
+
+    # FIXME: "stopped" doesn't seem appropriate.
+    # mi_gdb_test cannot be used for asynchronous commands because there are
+    # two prompts involved and this can lead to a race condition.
+    send_gdb "999-exec-continue\n"
+    gdb_expect {
+      -re "999\\^running\r\n$mi_gdb_prompt" {
+        gdb_expect {
+          -re "999\\*stopped,reason=\"exited-normally\"\r\n$mi_gdb_prompt$" {
+            pass "continue to end"
+          }
+          -re ".*$mi_gdb_prompt$" {fail "continue to end (2)"}
+          timeout {fail "continue to end (timeout 2)"}
+        }
+      }
+      -re ".*$mi_gdb_prompt$" {fail "continue to end (1)"}
+      timeout {fail "continue to end (timeout 1)"}
+    }
+}
+
+test_breakpoints_creation_and_listing
+test_running_the_program
+test_controlled_execution
+test_controlling_breakpoints
+test_program_termination
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
+
+
diff --git a/gdb/testsuite/gdb.mi/mi-stack.exp b/gdb/testsuite/gdb.mi/mi-stack.exp
new file mode 100644 (file)
index 0000000..f26a007
--- /dev/null
@@ -0,0 +1,222 @@
+#   Copyright (C) 1999 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that stack commands work.
+
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+
+mi_gdb_test "200-break-insert callee4" \
+       "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+       "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+    -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
+       pass "run to callee4"
+    }
+    -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+    timeout {fail "run to callee4 (timeout 2)"}
+}
+
+
+proc test_stack_frame_listing {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Obtain a stack trace
+    # Tests:
+    # -stack-list-frames
+    # -stack-list-frames 1 1
+    # -stack-list-frames 1 3
+
+    mi_gdb_test "231-stack-list-frames" \
+           "231\\^done,stack=\{frame=\{level=\"0 \",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\"\},frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\},frame=\{level=\"4 \",addr=\"$hex\",func=\"main\",.*\}\}" \
+                "stack frame listing"
+    mi_gdb_test "232-stack-list-frames 1 1" \
+           "232\\^done,stack=\{frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\}\}" \
+                "stack frame listing 1 1"
+    mi_gdb_test "233-stack-list-frames 1 3" \
+           "233\\^done,stack=\{frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\}\}" \
+                "stack frame listing 1 3"
+
+    mi_gdb_test "234-stack-list-frames 1" \
+           "234\\^error,msg=\"mi_cmd_stack_list_frames: Usage.*FRAME_LOW FRAME_HIGH.*\"" \
+           "stack frame listing wrong"
+}
+
+proc test_stack_args_listing {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Obtain lists for args for the stack frames
+    # Tests:
+    # -stack-list-arguments 0
+    # -stack-list-arguments 0 1 1
+    # -stack-list-arguments 0 1 3
+    # -stack-list-arguments 1
+    # -stack-list-arguments 1 1 1
+    # -stack-list-arguments 1 1 3
+    # -stack-list-arguments 
+
+    mi_gdb_test "231-stack-list-arguments 0" \
+           "231\\^done,stack-args=\{frame=\{level=\"0\",args=\{\}\},frame=\{level=\"1\",args=\{name=\"strarg\"\}\},frame=\{level=\"2\",args=\{name=\"intarg\",name=\"strarg\"\}\},frame=\{level=\"3\",args=\{name=\"intarg\",name=\"strarg\",name=\"fltarg\"\}\},frame=\{level=\"4\",args=\{\}\}\}" \
+                "stack args listing 0"
+
+    mi_gdb_test "232-stack-list-arguments 0 1 1" \
+           "232\\^done,stack-args=\{frame=\{level=\"1\",args=\{name=\"strarg\"\}\}\}" \
+                "stack args listing 0 1 1"
+
+    mi_gdb_test "233-stack-list-arguments 0 1 3" \
+           "233\\^done,stack-args=\{frame=\{level=\"1\",args=\{name=\"strarg\"\}\},frame=\{level=\"2\",args=\{name=\"intarg\",name=\"strarg\"\}\},frame=\{level=\"3\",args=\{name=\"intarg\",name=\"strarg\",name=\"fltarg\"\}\}\}" \
+                "stack args listing 0 1 3"
+
+    mi_gdb_test "231-stack-list-arguments 1" \
+           "231\\^done,stack-args=\{frame=\{level=\"0\",args=\{\}\},frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"2\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"3\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\}\},frame=\{level=\"4\",args=\{\}\}\}" \
+                "stack args listing 1"
+
+    mi_gdb_test "232-stack-list-arguments 1 1 1" \
+           "232\\^done,stack-args=\{frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\}\}" \
+                "stack args listing 1 1 1"
+
+    mi_gdb_test "233-stack-list-arguments 1 1 3" \
+           "233\\^done,stack-args=\{frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"2\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"3\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\}\}\}" \
+                "stack args listing 1 1 3"
+
+    mi_gdb_test "234-stack-list-arguments" \
+           "234\\^error,msg=\"mi_cmd_stack_list_args: Usage.*PRINT_VALUES.*FRAME_LOW FRAME_HIGH.*\"" \
+           "stack args listing wrong"
+}
+
+proc test_stack_info_depth {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Obtain depth of stack
+    # Tests:
+    # -stack-info-depth
+    # -stack-info-depth 3
+    # -stack-info-depth 99
+
+    mi_gdb_test "231-stack-info-depth" \
+           "231\\^done,depth=\"5\"" \
+                "stack info-depth"
+
+    mi_gdb_test "231-stack-info-depth 3" \
+           "231\\^done,depth=\"3\"" \
+                "stack info-depth 3"
+
+    mi_gdb_test "231-stack-info-depth 99" \
+           "231\\^done,depth=\"5\"" \
+                "stack info-depth 99"
+
+    mi_gdb_test "231-stack-info-depth 99 99" \
+           "231\\^error,msg=\"mi_cmd_stack_info_depth: Usage: .MAX_DEPTH.\"" \
+                "stack info-depth wrong usage"
+}
+
+proc test_stack_locals_listing {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Obtain lists for locals for the stack frames
+    # Tests:
+    # -stack-list-locals 0
+    # -stack-list-locals 1
+    # -stack-list-arguments 
+
+    mi_gdb_test "232-stack-list-locals 0" \
+           "232\\^done,locals=\{name=\"A\",name=\"B\",name=\"C\"\}" \
+                "stack locals listing 0"
+
+# step until A, B, C, have some reasonable values.
+send_gdb "-exec-next 3\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+       pass "next's in callee4"
+    }
+    timeout { fail "next in callee4 (timeout)" }
+}
+
+    mi_gdb_test "232-stack-list-locals 1" \
+           "232\\^done,locals=\{\{name=\"A\",value=\"1\"\},\{name=\"B\",value=\"2\"\},\{name=\"C\",value=\"3\"\}\}" \
+                "stack locals listing 1"
+
+    mi_gdb_test "234-stack-list-locals" \
+           "234\\^error,msg=\"mi_cmd_stack_list_locals: Usage.*PRINT_VALUES.*\"" \
+           "stack locals listing wrong"
+
+    mi_gdb_test "232-stack-select-frame 1" \
+           "232\\^done" \
+                "stack select frame 1"
+
+    mi_gdb_test "232-stack-list-locals 1" \
+           "232\\^done,locals=\{\}" \
+                "stack locals listing for new frame"
+
+# this should be a no-op
+
+    mi_gdb_test "232-stack-select-frame" \
+           "232\\^done" \
+                "stack select same frame"
+
+    mi_gdb_test "232-stack-list-locals 1" \
+           "232\\^done,locals=\{\}" \
+                "stack locals for same frame (level 1)"
+
+}
+
+test_stack_frame_listing
+test_stack_args_listing
+test_stack_locals_listing
+test_stack_info_depth
+
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
+
diff --git a/gdb/testsuite/gdb.mi/mi-stepi.exp b/gdb/testsuite/gdb.mi/mi-stepi.exp
new file mode 100644 (file)
index 0000000..5c218d9
--- /dev/null
@@ -0,0 +1,110 @@
+#   Copyright (C) 1999 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations 
+# Verify that, using the MI, we can run a simple program and perform
+# exec-step-instruction and exec-next-instruction.  
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.  
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_main {} {
+    global mi_gdb_prompt
+    global hex
+
+    mi_gdb_test "200-break-insert main" \
+             "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+             "break-insert operation"
+
+    mi_run_cmd
+
+    gdb_expect {
+       -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+           pass "run to main"
+       }
+       timeout {
+           fail "run to main (timeout)"
+       }
+    }
+}
+
+proc test_stepi_nexti {} {
+    global mi_gdb_prompt
+    global hex
+
+    send_gdb "111-exec-step-instruction\n"
+    gdb_expect {
+       -re "111\\^running\r\n${mi_gdb_prompt}111\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+           pass "step-instruction at main"
+       }
+       timeout {
+           fail "step-instruction at main (timeout)"
+       }
+    }
+    send_gdb "222-exec-next-instruction\n"
+    gdb_expect {
+       -re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+           pass "next-instruction at main"
+       }
+       timeout {
+           fail "next-instruction at main (timeout)"
+       }
+    }
+    send_gdb "333-exec-next-instruction\n"
+    gdb_expect {
+       -re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+           pass "next-instruction at main"
+       }
+       timeout {
+           fail "next-instruction at main (timeout)"
+       }
+    }
+}
+
+test_running_to_main
+test_stepi_nexti
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End:
+
diff --git a/gdb/testsuite/gdb.mi/mi-until.exp b/gdb/testsuite/gdb.mi/mi-until.exp
new file mode 100644 (file)
index 0000000..366dbaa
--- /dev/null
@@ -0,0 +1,127 @@
+#   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations 
+# Verify that, using the MI, we can run a simple program and perform
+# exec-until.  
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.  
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "until"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_foo {} {
+    global mi_gdb_prompt
+    global hex
+
+    mi_gdb_test "200-break-insert 10" \
+             "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"foo\",file=\".*until.c\",line=\"10\",times=\"0\"\}" \
+             "break-insert operation"
+
+    mi_run_cmd
+
+    gdb_expect {
+       -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"10\"\}\r\n$mi_gdb_prompt$" {
+           pass "run to main"
+       }
+       timeout {
+           fail "run to main (timeout)"
+       }
+    }
+
+    mi_gdb_test "100-break-delete 1" "100\\^done" "break-delete 1"
+
+}
+
+proc test_until {} {
+    global mi_gdb_prompt
+    global hex
+
+    send_gdb "111-exec-until\n"
+    gdb_expect {
+       -re "111\\^running\r\n${mi_gdb_prompt}111\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"12\"\}\r\n$mi_gdb_prompt$" {
+           pass "until after while loop"
+       }
+       timeout {
+           fail "until after while loop (timeout)"
+       }
+    }
+
+    send_gdb "222-exec-until 15\n"
+    gdb_expect {
+       -re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"location-reached\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"15\"\}\r\n$mi_gdb_prompt$" {
+           pass "until line number"
+       }
+       timeout {
+           fail "until line number (timeout)"
+       }
+    }
+
+    send_gdb "333-exec-until until.c:17\n"
+    gdb_expect {
+       -re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"location-reached\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"17\"\}\r\n$mi_gdb_prompt$" {
+           pass "until line number:file"
+       }
+       timeout {
+           fail "until line number:file (timeout)"
+       }
+    }
+
+    # This is supposed to NOT stop at line 25. It stops right after foo is over.
+
+    send_gdb "444-exec-until until.c:25\n"
+    gdb_expect {
+       -re "444\\^running\r\n${mi_gdb_prompt}444\\*stopped,reason=\"location-reached\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*until.c\",line=\"24\"\}\r\n$mi_gdb_prompt$" {
+           pass "until after current function"
+       }
+       timeout {
+           fail "until after current function (timeout)"
+       }
+    }
+
+}
+
+test_running_to_foo
+test_until
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End:
diff --git a/gdb/testsuite/gdb.mi/mi-var-block.exp b/gdb/testsuite/gdb.mi/mi-var-block.exp
new file mode 100644 (file)
index 0000000..7eb473d
--- /dev/null
@@ -0,0 +1,233 @@
+#   Copyright (C) 1999 2000 s Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert do_block_tests" \
+       "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_block_tests\",file=\".*var-cmd.c\",line=\"154\",times=\"0\"\}" \
+       "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+    -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"154\"\}\r\n$mi_gdb_prompt$" {
+       pass "run to do_block_tests"
+    }
+    -re ".*$mi_gdb_prompt$" {fail "run to do_block_tests (2)"}
+    timeout {fail "run to do_block_tests (timeout 2)"}
+}
+
+# Test: c_variable-3.2
+# Desc: create cb and foo
+mi_gdb_test "-var-create cb * cb" \
+       "\\^done,name=\"cb\",numchild=\"0\",type=\"int\"" \
+       "create local variable cb"
+
+mi_gdb_test "-var-create foo * foo" \
+       "&\"No symbol \\\\\"foo\\\\\" in current context.\\\\n\".*\\^error,msg=\"No symbol \\\\\"foo\\\\\" in current context.\"" \
+       "create local variable foo"
+
+# step to "foo = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"158\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_block_tests"
+    }
+    timeout {
+       fail "step at do_block_tests (timeout)"
+    }
+}
+
+
+# Be paranoid and assume 3.2 created foo
+mi_gdb_test "-var-delete foo" \
+       "&\"Variable object not found\\\\n\".*\\^error,msg=\"Variable object not found\"" \
+       "delete var foo"
+
+
+# Test: c_variable-3.3
+# Desc: create foo
+mi_gdb_test "-var-create foo * foo" \
+       "\\^done,name=\"foo\",numchild=\"0\",type=\"int\"" \
+       "create local variable foo"
+
+# step to "foo2 = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"161\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_block_tests"
+    }
+    timeout {
+       fail "step at do_block_tests (timeout)"
+    }
+}
+
+# Test: c_variable-3.4
+# Desc: check foo, cb changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"foo\",name=\"cb\"\}" \
+       "update all vars: cb foo changed"
+
+# step to "foo = 321;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"164\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_block_tests"
+    }
+    timeout {
+       fail "step at do_block_tests (timeout)"
+    }
+}
+
+# Test: c_variable-3.5
+# Desc: create inner block foo
+mi_gdb_test "-var-create inner_foo * foo" \
+       "\\^done,name=\"inner_foo\",numchild=\"0\",type=\"int\"" \
+       "create local variable inner_foo"
+
+# step to "foo2 = 0;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"166\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_block_tests"
+    }
+    timeout { fail "step at do_block_tests (timeout)" }
+}
+
+# Test: c_variable-3.6
+# Desc: create foo2
+mi_gdb_test "-var-create foo2 * foo2" \
+       "\\^done,name=\"foo2\",numchild=\"0\",type=\"int\"" \
+       "create local variable foo2"
+
+# Test: c_variable-3.7
+# Desc: check that outer foo in scope and inner foo out of scope
+# Note: also a known gdb problem
+setup_xfail *-*-*
+mi_gdb_test "-var-update inner_foo" \
+       "\\^done,changelist=\{FIXME\}" \
+       "update inner_foo: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+setup_xfail *-*-*
+mi_gdb_test "-var-evaluate-expression inner_foo" \
+       "\\^done,value=\{FIXME\}" \
+       "evaluate inner_foo: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+mi_gdb_test "-var-update foo" \
+       "\\^done,changelist=\{\}" \
+       "update foo: did not change"
+
+mi_gdb_test "-var-delete inner_foo" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var inner_foo"
+
+# step to "foo = 0;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"168\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_block_tests"
+    }
+    timeout { fail "step at do_block_tests (timeout)" }
+}
+
+# Test: c_variable-3.8
+# Desc: check that foo2 out of scope (known gdb problem)
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo2" \
+       "\\^done,changelist=\{FIXME\}" \
+       "update foo2: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+# step to "cb = 21;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"171\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_block_tests"
+    }
+    timeout { fail "step at do_block_tests (timeout)" }
+}
+
+
+# Test: c_variable-3.9
+# Desc: check that only cb is in scope (known gdb problem)
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo2" \
+       "\\^done,changelist=\{FIXME\}" \
+       "update foo2 should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo" \
+       "\\^done,changelist=\{FIXME\}" \
+       "update foo should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+mi_gdb_test "-var-update cb" \
+       "\\^done,changelist=\{\}" \
+       "update cb"
+
+# Test: c_variable-3.10
+# Desc: names of editable variables
+#gdbtk_test c_variable-3.10 {names of editable variables} {
+#  editable_variables
+#} {{foo cb foo2} {}}
+
+# Done with block tests
+mi_gdb_test "-var-delete foo" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var foo"
+
+mi_gdb_test "-var-delete foo2" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var foo2"
+
+mi_gdb_test "-var-delete cb" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var cb"
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End:
+
+
diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp
new file mode 100644 (file)
index 0000000..21a7cba
--- /dev/null
@@ -0,0 +1,1295 @@
+#   Copyright (C) 1999 2000 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert do_children_tests" \
+       "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"190\",times=\"0\"\}" \
+       "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+    -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"190\"\}\r\n$mi_gdb_prompt$" {
+       pass "run to do_children_tests"
+    }
+    -re ".*$mi_gdb_prompt$" {fail "run to do_children_tests (2)"}
+    timeout {fail "run to do_children_tests (timeout 2)"}
+}
+
+#####        #####
+#                #
+# children tests #
+#                #
+#####        #####
+
+
+# Test: c_variable-4.2
+# Desc: create variable "struct_declarations"
+mi_gdb_test "-var-create struct_declarations * struct_declarations" \
+       "\\^done,name=\"struct_declarations\",numchild=\"11\",type=\"struct _struct_decl\"" \
+       "create local variable struct_declarations"
+
+# Test: c_variable-4.3
+# Desc: children of struct_declarations
+mi_gdb_test "-var-list-children struct_declarations" \
+       "\\^done,numchild=\"11\",children=\{child=\{name=\"struct_declarations.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.char_ptr\",exp=\"char_ptr\",numchild=\"0\",type=\"char \\*\"\},child=\{name=\"struct_declarations.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"struct_declarations.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"struct_declarations.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\(\\)\"\},child=\{name=\"struct_declarations.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\(\\)\"\},child=\{name=\"struct_declarations.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\(\\)\"\},child=\{name=\"struct_declarations.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+       "get children of struct_declarations"
+
+#gdbtk_test c_variable-4.3 {children of struct_declarations} {
+#  get_children  struct_declarations
+#} {integer character char_ptr long_int int_ptr_ptr long_array func_ptr func_ptr_struct func_ptr_ptr u1 s2}
+
+# Test: c_variable-4.4
+# Desc: number of children of struct_declarations
+mi_gdb_test "-var-info-num-children struct_declarations" \
+       "\\^done,numchild=\"11\"" \
+       "get number of children of struct_declarations"
+
+# Test: c_variable-4.5
+# Desc: children of struct_declarations.integer
+mi_gdb_test "-var-list-children struct_declarations.integer" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.integer"
+
+# Test: c_variable-4.6
+# Desc: number of children of struct_declarations.integer
+mi_gdb_test "-var-info-num-children struct_declarations.integer" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.integer"
+
+# Test: c_variable-4.7
+# Desc: children of struct_declarations.character
+mi_gdb_test "-var-list-children struct_declarations.character" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.character"
+
+# Test: c_variable-4.8
+# Desc: number of children of struct_declarations.character
+mi_gdb_test "-var-info-num-children struct_declarations.character" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.character"
+
+# Test: c_variable-4.9
+# Desc: children of struct_declarations.char_ptr
+mi_gdb_test "-var-list-children struct_declarations.char_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.char_ptr"
+
+# Test: c_variable-4.10
+# Desc: number of children of struct_declarations.char_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.char_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.char_ptr"
+
+# Test: c_variable-4.11
+# Desc: children of struct_declarations.long_int
+mi_gdb_test "-var-list-children struct_declarations.long_int" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_int"
+
+# Test: c_variable-4.12
+# Desc: number of children of struct_declarations.long_int
+mi_gdb_test "-var-info-num-children struct_declarations.long_int" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_int"
+
+# Test: c_variable-4.13
+# Desc: children of int_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.int_ptr_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",exp=\"\\*int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+       "get children of struct_declarations.int_ptr_ptr"
+
+#gdbtk_test c_variable-4.13 {children of int_ptr_ptr} {
+#  get_children struct_declarations.int_ptr_ptr
+#} {*int_ptr_ptr}
+
+# Test: c_variable-4.14
+# Desc: number of children of int_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of struct_declarations.int_ptr_ptr"
+
+
+# Test: c_variable-4.15
+# Desc: children of struct_declarations.long_array
+mi_gdb_test "-var-list-children struct_declarations.long_array" \
+       "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.long_array.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+       "get children of struct_declarations.long_array"
+
+# Test: c_variable-4.16
+# Desc: number of children of struct_declarations.long_array
+mi_gdb_test "-var-info-num-children struct_declarations.long_array" \
+       "\\^done,numchild=\"10\"" \
+       "get number of children of struct_declarations.long_array"
+
+# Test: c_variable-4.17
+# Desc: children of struct_declarations.func_ptr
+mi_gdb_test "-var-list-children struct_declarations.func_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.func_ptr"
+
+
+# Test: c_variable-4.18
+# Desc: number of children of struct_declarations.func_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.func_ptr"
+
+
+# Test: c_variable-4.19
+# Desc: children of struct_declarations.func_ptr_struct
+mi_gdb_test "-var-list-children struct_declarations.func_ptr_struct" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.func_ptr_struct"
+
+# Test: c_variable-4.20
+# Desc: number of children of struct_declarations.func_ptr_struct
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr_struct" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.func_ptr_struct"
+
+
+# Test: c_variable-4.21
+# Desc: children of struct_declarations.func_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.func_ptr_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.func_ptr_ptr"
+
+# Test: c_variable-4.22
+# Desc: number of children of struct_declarations.func_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.func_ptr_ptr"
+
+
+# Test: c_variable-4.23
+# Desc: children of struct_declarations.u1
+mi_gdb_test "-var-list-children struct_declarations.u1" \
+       "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.u1.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.u1.b\",exp=\"b\",numchild=\"0\",type=\"char \\*\"\},child=\{name=\"struct_declarations.u1.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.u1.d\",exp=\"d\",numchild=\"0\",type=\"enum foo\"\}\}" \
+       "get children of struct_declarations.u1"
+
+# Test: c_variable-4.24
+# Desc: number of children of struct_declarations.u1
+mi_gdb_test "-var-info-num-children struct_declarations.u1" \
+       "\\^done,numchild=\"4\"" \
+       "get number of children of struct_declarations.u1"
+
+# Test: c_variable-4.25
+# Desc: children of struct_declarations.s2
+mi_gdb_test "-var-list-children struct_declarations.s2" \
+       "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.s2.u2\",exp=\"u2\",numchild=\"3\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2.g\",exp=\"g\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.s2.h\",exp=\"h\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.i\",exp=\"i\",numchild=\"10\",type=\"long int \\\[10\\\]\"\}\}" \
+       "get children of struct_declarations.s2"
+#gdbtk_test c_variable-4.25 {children of struct_declarations.s2} {
+#  get_children struct_declarations.s2
+#} {u2 g h i}
+
+# Test: c_variable-4.26
+# Desc: number of children of struct_declarations.s2
+mi_gdb_test "-var-info-num-children struct_declarations.s2" \
+       "\\^done,numchild=\"4\"" \
+       "get number of children of struct_declarations.s2"
+
+
+# Test: c_variable-4.27
+# Desc: children of struct_declarations.long_array.1
+mi_gdb_test "-var-list-children struct_declarations.long_array.1" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.1"
+
+# Test: c_variable-4.28
+# Desc: number of children of struct_declarations.long_array.1
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.1" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.1"
+
+# Test: c_variable-4.29
+# Desc: children of struct_declarations.long_array.2
+mi_gdb_test "-var-list-children struct_declarations.long_array.2" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.2"
+
+# Test: c_variable-4.30
+# Desc: number of children of struct_declarations.long_array.2
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.2" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.2"
+
+# Test: c_variable-4.31
+# Desc: children of struct_declarations.long_array.3
+mi_gdb_test "-var-list-children struct_declarations.long_array.3" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.3"
+
+# Test: c_variable-4.32
+# Desc: number of children of struct_declarations.long_array.3
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.3" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.3"
+
+# Test: c_variable-4.33 
+# Desc: children of struct_declarations.long_array.4
+mi_gdb_test "-var-list-children struct_declarations.long_array.4" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.4"
+
+# Test: c_variable-4.34
+# Desc: number of children of struct_declarations.long_array.4
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.4" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.4"
+
+# Test: c_variable-4.35
+# Desc: children of struct_declarations.long_array.5
+mi_gdb_test "-var-list-children struct_declarations.long_array.5" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.5"
+
+# Test: c_variable-4.36
+# Desc: number of children of struct_declarations.long_array.5
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.5" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.5"
+
+# Test: c_variable-4.37
+# Desc: children of struct_declarations.long_array.6
+mi_gdb_test "-var-list-children struct_declarations.long_array.6" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.6"
+
+# Test: c_variable-4.38
+# Desc: number of children of struct_declarations.long_array.6
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.6" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.6"
+
+# Test: c_variable-4.39
+# Desc: children of struct_declarations.long_array.7
+mi_gdb_test "-var-list-children struct_declarations.long_array.7" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.7"
+
+# Test: c_variable-4.40
+# Desc: number of children of struct_declarations.long_array.7
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.7" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.7"
+
+# Test: c_variable-4.41
+# Desc: children of struct_declarations.long_array.8
+mi_gdb_test "-var-list-children struct_declarations.long_array.8" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.8"
+
+# Test: c_variable-4.42
+# Desc: number of children of struct_declarations.long_array.8
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.8" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.8"
+
+
+# Test: c_variable-4.43
+# Desc: children of struct_declarations.long_array.9
+mi_gdb_test "-var-list-children struct_declarations.long_array.9" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.long_array.9"
+
+# Test: c_variable-4.44
+# Desc: number of children of struct_declarations.long_array.9
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.9" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.long_array.9"
+
+# Test: c_variable-4.45
+# Desc: children of struct_declarations.u1.a
+mi_gdb_test "-var-list-children struct_declarations.u1.a" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.u1.a"
+
+# Test: c_variable-4.46
+# Desc: number of children of struct_declarations.u1.a
+mi_gdb_test "-var-info-num-children struct_declarations.u1.a" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.u1.a"
+
+# Test: c_variable-4.47
+# Desc: children of struct_declarations.u1.b
+mi_gdb_test "-var-list-children struct_declarations.u1.b" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.u1.b"
+
+# Test: c_variable-4.48
+# Desc: number of children of struct_declarations.u1.b
+mi_gdb_test "-var-info-num-children struct_declarations.u1.b" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.u1.b"
+
+# Test: c_variable-4.49
+# Desc: children of struct_declarations.u1.c
+mi_gdb_test "-var-list-children struct_declarations.u1.c" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.u1.c"
+
+# Test: c_variable-4.50
+# Desc: number of children of struct_declarations.u1.c
+mi_gdb_test "-var-info-num-children struct_declarations.u1.c" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.u1.c"
+
+# Test: c_variable-4.51
+# Desc: children of struct_declarations.u1.d
+mi_gdb_test "-var-list-children struct_declarations.u1.d" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.u1.d"
+
+
+# Test: c_variable-4.52
+# Desc: number of children of struct_declarations.u1.d
+mi_gdb_test "-var-info-num-children struct_declarations.u1.d" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.u1.d"
+
+
+# Test: c_variable-4.53
+# Desc: children of struct_declarations.s2.u2
+mi_gdb_test "-var-list-children struct_declarations.s2.u2" \
+       "\\^done,numchild=\"3\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1\",exp=\"u1s1\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2.u2.f\",exp=\"f\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.u2.u1s2\",exp=\"u1s2\",numchild=\"2\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+       "get children of struct_declarations.s2.u2"
+
+# Test: c_variable-4.54
+# Desc: number of children of struct_declarations.s2.u2
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2" \
+       "\\^done,numchild=\"3\"" \
+       "get number of children of struct_declarations.s2.u2"
+
+# Test: c_variable-4.55
+# Desc: children of struct_declarations.s2.g
+mi_gdb_test "-var-list-children struct_declarations.s2.g" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.s2.g"
+
+# Test: c_variable-4.56
+# Desc: number of children of struct_declarations.s2.g
+mi_gdb_test "-var-info-num-children struct_declarations.s2.g" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.s2.g"
+
+
+# Test: c_variable-4.57
+# Desc: children of struct_declarations.s2.h
+mi_gdb_test "-var-list-children struct_declarations.s2.h" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.s2.h"
+
+# Test: c_variable-4.58
+# Desc: number of children of struct_declarations.s2.h
+mi_gdb_test "-var-info-num-children struct_declarations.s2.h" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.s2.h"
+
+
+# Test: c_variable-4.59
+# Desc: children of struct_declarations.s2.i
+mi_gdb_test "-var-list-children struct_declarations.s2.i" \
+       "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.s2.i.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+       "get children of struct_declarations.s2.i"
+
+# Test: c_variable-4.60
+# Desc: number of children of struct_declarations.s2.i
+mi_gdb_test "-var-info-num-children struct_declarations.s2.i" \
+       "\\^done,numchild=\"10\"" \
+       "get number of children of struct_declarations.s2.i"
+
+# Test: c_variable-4.61
+# Desc: children of struct_declarations.s2.u2.u1s1
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1" \
+       "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1.d\",exp=\"d\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e\",exp=\"e\",numchild=\"10\",type=\"char \\\[10\\\]\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.func\",exp=\"func\",numchild=\"0\",type=\"int \\*\\(\\*\\)\\(\\)\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.foo\",exp=\"foo\",numchild=\"0\",type=\"efoo\"\}\}" \
+       "get children of struct_declarations.s2.u2.u1s1"
+
+# Test: c_variable-4.62
+# Desc: number of children of struct_declarations.s2.u2.u1s1
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1" \
+       "\\^done,numchild=\"4\"" \
+       "get number of children of struct_declarations.s2.u2.u1s1"
+
+# Test: c_variable-4.63
+# Desc: children of struct_declarations.s2.u2.f
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.f" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.s2.u2.f"
+
+# Test: c_variable-4.64
+# Desc: number of children of struct_declarations.s2.u2.f
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.f" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.s2.u2.f"
+
+# Test: c_variable-4.65
+# Desc: children of struct_declarations.s2.u2.u1s2
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2" \
+       "\\^done,numchild=\"2\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s2.array_ptr\",exp=\"array_ptr\",numchild=\"2\",type=\"char \\\[2\\\]\"\},child=\{name=\"struct_declarations.s2.u2.u1s2.func\",exp=\"func\",numchild=\"0\",type=\"int \\(\\*\\)\\(\\)\"\}\}" \
+       "get children of struct_declarations.s2.u2.u1s2"
+
+# Test: c_variable-4.66
+# Desc: number of children of struct_declarations.s2.u2.u1s2
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2" \
+       "\\^done,numchild=\"2\"" \
+       "get number of children of struct_declarations.s2.u2.u1s2"
+
+# Test: c_variable-4.67
+# Desc: children of struct_declarations.s2.u2.u1s1.d
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.d" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.s2.u2.u1s1.d"
+
+# Test: c_variable-4.68
+# Desc: number of children of struct_declarations.s2.u2.u1s1.d
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.d" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.s2.u2.u1s1.d"
+
+# Test: c_variable-4.69
+# Desc: children of struct_declarations.s2.u2.u1s1.e
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.e" \
+       "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1.e.0\",exp=\"0\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.1\",exp=\"1\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.2\",exp=\"2\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.s2.u2.u1s1.e.3\",exp=\"3\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.4\",exp=\"4\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.5\",exp=\"5\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.6\",exp=\"6\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.7\",exp=\"7\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.8\",exp=\"8\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.9\",exp=\"9\",numchild=\"0\",type=\"char\"\}\}" \
+       "get children of struct_declarations.s2.u2.u1s1.e"
+
+# Test: c_variable-4.70
+# Desc: number of children of struct_declarations.s2.u2.u1s1.e
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.e" \
+       "\\^done,numchild=\"10\"" \
+       "get number of children of struct_declarations.s2.u2.u1s1.e"
+
+
+# Test: c_variable-4.71
+# Desc: children of struct_declarations.s2.u2.u1s1.func
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.func" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.s2.u2.u1s1.func"
+
+# Test: c_variable-4.72
+# Desc: number of children of struct_declarations.s2.u2.u1s1.func
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.func" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.s2.u2.u1s1.func"
+
+
+# Test: c_variable-4.73
+# Desc: children of struct_declarations.s2.u2.u1s1.foo
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.foo" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.s2.u2.u1s1.foo"
+
+# Test: c_variable-4.74
+# Desc: number of children of struct_declarations.s2.u2.u1s1.foo
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.foo" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.s2.u2.u1s1.foo"
+
+
+# Test: c_variable-4.75
+# Desc: children of struct_declarations.s2.u2.u1s2.array_ptr
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2.array_ptr" \
+       "\\^done,numchild=\"2\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s2.array_ptr.0\",exp=\"0\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.s2.u2.u1s2.array_ptr.1\",exp=\"1\",numchild=\"0\",type=\"char\"\}\}" \
+       "get children of struct_declarations.s2.u2.u1s2.array_ptr"
+
+# Test: c_variable-4.76
+# Desc: number of children of struct_declarations.s2.u2.u1s2.array_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2.array_ptr" \
+       "\\^done,numchild=\"2\"" \
+       "get number of children of struct_declarations.s2.u2.u1s2.array_ptr"
+
+# Test: c_variable-4.77
+# Desc: children of struct_declarations.s2.u2.u1s2.func
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2.func" \
+       "\\^done,numchild=\"0\"" \
+       "get children of struct_declarations.s2.u2.u1s2.func"
+
+# Test: c_variable-4.78
+# Desc: number of children of struct_declarations.s2.u2.u1s2.func
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2.func" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of struct_declarations.s2.u2.u1s2.func"
+
+# Test: c_variable-4.79
+# Desc: children of struct_declarations.int_ptr_ptr.*int_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.int_ptr_ptr.*int_ptr_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",exp=\"\\*\\*int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+       "get children of struct_declarations.int_ptr_ptr.*int_ptr_ptr"
+#} {**int_ptr_ptr}
+
+# Test: c_variable-4.80
+# Desc: Number of children of struct_declarations.int_ptr_ptr.*int_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr.*int_ptr_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of struct_declarations.int_ptr_ptr.*int_ptr_ptr"
+
+
+# Step to "struct_declarations.integer = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"192\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+
+# Test: c_variable-4.81
+# Desc: create local variable "weird"
+mi_gdb_test "-var-create weird * weird" \
+       "\\^done,name=\"weird\",numchild=\"11\",type=\"weird_struct \\*\"" \
+       "create local variable weird"
+
+# Test: c_variable-4.82
+# Desc: children of weird
+mi_gdb_test "-var-list-children weird" \
+       "\\^done,numchild=\"11\",children=\{child=\{name=\"weird.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"weird.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child=\{name=\"weird.char_ptr\",exp=\"char_ptr\",numchild=\"0\",type=\"char \\*\"\},child=\{name=\"weird.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"weird.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"weird.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\(\\)\"\},child=\{name=\"weird.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"weird.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+       "get children of weird"
+
+# Test: c_variable-4.83
+# Desc: number of children of weird
+mi_gdb_test "-var-info-num-children weird" \
+       "\\^done,numchild=\"11\"" \
+       "get number of children of weird"
+
+
+# Test: c_variable-4.84
+# Desc: children of weird->long_array
+mi_gdb_test "-var-list-children weird.long_array" \
+       "\\^done,numchild=\"10\",children=\{child=\{name=\"weird.long_array.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+       "get children of weird.long_array"
+#gdbtk_test c_variable-4.84 {children of weird->long_array} {
+#  get_children weird.long_array
+#} {0 1 2 3 4 5 6 7 8 9}
+
+# Test: c_variable-4.85
+# Desc: number of children of weird.long_array
+mi_gdb_test "-var-info-num-children weird.long_array" \
+       "\\^done,numchild=\"10\"" \
+       "get number of children of weird.long_array"
+
+# Test: c_variable-4.86
+# Desc: children of weird.int_ptr_ptr
+mi_gdb_test "-var-list-children weird.int_ptr_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"weird.int_ptr_ptr.\\*int_ptr_ptr\",exp=\"\\*int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+       "get children of weird.int_ptr_ptr"
+#gdbtk_test c_variable-4.86 {children of weird->int_ptr_ptr} {
+#  get_children weird.int_ptr_ptr
+#} {*int_ptr_ptr}
+
+# Test: c_variable-4.87
+# Desc: number of children of weird.int_ptr_ptr
+mi_gdb_test "-var-info-num-children weird.int_ptr_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of weird.int_ptr_ptr"
+
+# Test: c_variable-4.88
+# Desc: children of *weird->int_ptr_ptr
+mi_gdb_test "-var-list-children weird.int_ptr_ptr.*int_ptr_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"weird.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",exp=\"\\*\\*int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+       "get children of weird.int_ptr_ptr.*int_ptr_ptr"
+#gdbtk_test c_variable-4.88 {children of *weird->int_ptr_ptr} {
+#  get_children weird.int_ptr_ptr.*int_ptr_ptr
+#} {**int_ptr_ptr}
+
+# Test: c_variable-4.89
+# Desc: number of children *weird->int_ptr_ptr
+mi_gdb_test "-var-info-num-children weird.int_ptr_ptr.*int_ptr_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of weird.int_ptr_ptr.*int_ptr_ptr"
+
+# Test: c_variable-4.90
+# Desc: create weird->int_ptr_ptr
+mi_gdb_test "-var-create weird->int_ptr_ptr * weird->int_ptr_ptr" \
+       "\\^done,name=\"weird->int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"" \
+       "create local variable weird->int_ptr_ptr"
+
+# Test: c_variable-4.91
+# Desc: children of weird->int_ptr_ptr
+mi_gdb_test "-var-list-children weird->int_ptr_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",exp=\"\\*weird->int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+       "get children of weird->int_ptr_ptr"
+
+
+# Test: c_variable-4.92
+# Desc: number of children of (weird->int_ptr_ptr)
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of weird->int_ptr_ptr"
+
+# Test: c_variable-4.93
+# Desc: children of *(weird->int_ptr_ptr)
+mi_gdb_test "-var-list-children weird->int_ptr_ptr.*weird->int_ptr_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",exp=\"\\*\\*weird->int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+       "get children of weird->int_ptr_ptr.*weird->int_ptr_ptr"
+
+# Test: c_variable-4.94
+# Desc: number of children of *(weird->int_ptr_ptr)
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr.*weird->int_ptr_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of weird->int_ptr_ptr.*weird->int_ptr_ptr"
+
+# Test: c_variable-4.95
+# Desc: children of *(*(weird->int_ptr_ptr))
+mi_gdb_test "-var-list-children weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get children of weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr"
+
+# Test: c_variable-4.96
+# Desc: number of children of *(*(weird->int_ptr_ptr))
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr"
+
+# Test: c_variable-4.97
+# Desc: is weird editable
+mi_gdb_test "-var-show-attributes weird" \
+       "\\^done,attr=\"editable\"" \
+       "is weird editable"
+
+# Test: c_variable-4.98
+# Desc: is weird->int_ptr_ptr editable
+mi_gdb_test "-var-show-attributes weird->int_ptr_ptr" \
+       "\\^done,attr=\"editable\"" \
+       "is weird->int_ptr_ptr editable"
+
+# Test: c_variable-4.99
+# Desc: is *(weird->int_ptr_ptr) editable
+mi_gdb_test "-var-show-attributes weird.int_ptr_ptr.*int_ptr_ptr" \
+       "\\^done,attr=\"editable\"" \
+       "is weird.int_ptr_ptr.*int_ptr_ptr editable"
+
+# Test: c_variable-4.100
+# Desc: is *(*(weird->int_ptr_ptr)) editable
+mi_gdb_test "-var-show-attributes weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr" \
+       "\\^done,attr=\"editable\"" \
+       "is weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr editable"
+
+# Test: c_variable-4.101
+# Desc: is weird->u1 editable
+mi_gdb_test "-var-show-attributes weird.u1" \
+       "\\^done,attr=\"noneditable\"" \
+       "is weird.u1 editable"
+
+# Test: c_variable-4.102
+# Desc: is weird->s2 editable
+mi_gdb_test "-var-show-attributes weird.s2" \
+       "\\^done,attr=\"noneditable\"" \
+       "is weird.s2 editable"
+
+# Test: c_variable-4.103
+# Desc: is struct_declarations.u1.a editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.a" \
+       "\\^done,attr=\"editable\"" \
+       "is struct_declarations.u1.a editable"
+
+# Test: c_variable-4.104
+# Desc: is struct_declarations.u1.b editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.b" \
+       "\\^done,attr=\"editable\"" \
+       "is struct_declarations.u1.b editable"
+
+# Test: c_variable-4.105
+# Desc: is struct_declarations.u1.c editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.c" \
+       "\\^done,attr=\"editable\"" \
+       "is struct_declarations.u1.c editable"
+
+# Test: c_variable-4.106
+# Desc: is struct_declarations.long_array editable
+mi_gdb_test "-var-show-attributes struct_declarations.long_array" \
+       "\\^done,attr=\"noneditable\"" \
+       "is struct_declarations.long_array editable"
+
+# Test: c_variable-4.107
+# Desc: is struct_declarations.long_array[0] editable
+mi_gdb_test "-var-show-attributes struct_declarations.long_array.0" \
+       "\\^done,attr=\"editable\"" \
+       "is struct_declarations.long_array.0 editable"
+
+# Test: c_variable-4.108
+# Desc: is struct_declarations editable
+mi_gdb_test "-var-show-attributes struct_declarations" \
+       "\\^done,attr=\"noneditable\"" \
+       "is struct_declarations editable"
+
+mi_gdb_test "-var-delete weird" \
+       "\\^done,ndeleted=\"24\"" \
+       "delete var weird"
+
+#####                         #####
+#                                 #
+# children and update tests #
+#                                 #
+#####                         #####
+
+# Test: c_variable-5.1
+# Desc: check that nothing changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{\}" \
+       "update all vars. None changed"
+
+# Step over "struct_declarations.integer = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"193\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.2
+# Desc: check that integer changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"struct_declarations.integer\"\}" \
+       "update all vars struct_declarations.integer"
+
+# Step over:
+#    weird->char_ptr = "hello";
+#    bar = 2121;
+#    foo = &bar;
+
+send_gdb "-exec-step 3\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"196\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.3
+# Desc: check that char_ptr changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"struct_declarations.char_ptr\"\}" \
+       "update all vars struct_declarations.char_ptr"
+
+# Step over "struct_declarations.int_ptr_ptr = &foo;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"197\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.4
+# Desc: check that int_ptr_ptr and children changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"weird->int_ptr_ptr\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",name=\"struct_declarations.int_ptr_ptr\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\"\}" \
+       "update all vars int_ptr_ptr and children changed"
+
+# Step over "weird->long_array[0] = 1234;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"198\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.5
+# Desc: check that long_array[0] changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"struct_declarations.long_array.0\"\}" \
+       "update all vars struct_declarations.long_array.0 changed"
+
+# Step over "struct_declarations.long_array[1] = 2345;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"199\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.6
+# Desc: check that long_array[1] changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"struct_declarations.long_array.1\"\}" \
+       "update all vars struct_declarations.long_array.1 changed"
+
+# Step over "weird->long_array[2] = 3456;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"200\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.7
+# Desc: check that long_array[2] changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"struct_declarations.long_array.2\"\}" \
+       "update all vars struct_declarations.long_array.2 changed"
+
+# Step over:
+#    struct_declarations.long_array[3] = 4567;
+#    weird->long_array[4] = 5678;
+#    struct_declarations.long_array[5] = 6789;
+#    weird->long_array[6] = 7890;
+#    struct_declarations.long_array[7] = 8901;
+#    weird->long_array[8] = 9012;
+#    struct_declarations.long_array[9] = 1234;
+send_gdb "-exec-step 7\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"208\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.8
+# Desc: check that long_array[3-9] changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"struct_declarations.long_array.3\",name=\"struct_declarations.long_array.4\",name=\"struct_declarations.long_array.5\",name=\"struct_declarations.long_array.6\",name=\"struct_declarations.long_array.7\",name=\"struct_declarations.long_array.8\",name=\"struct_declarations.long_array.9\"\}" \
+       "update all vars struct_declarations.long_array.3-9 changed"
+
+
+# Step over "weird->func_ptr = nothing;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"211\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.9
+# Desc: check that func_ptr changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"struct_declarations.func_ptr\"\}" \
+       "update all vars struct_declarations.func_ptr changed"
+
+# Delete all variables
+mi_gdb_test "-var-delete struct_declarations" \
+       "\\^done,ndeleted=\"63\"" \
+       "delete var struct_declarations"
+
+mi_gdb_test "-var-delete weird->int_ptr_ptr" \
+       "\\^done,ndeleted=\"3\"" \
+       "delete var weird->int_ptr_ptr"
+
+# Step over all lines:
+# ...
+#   psnp = &snp0;
+send_gdb "-exec-step 43\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"254\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.10
+# Desc: create psnp->char_ptr
+mi_gdb_test "-var-create  psnp->char_ptr *  psnp->char_ptr" \
+       "\\^done,name=\"psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"" \
+       "create local variable  psnp->char_ptr"
+
+# Test: c_variable-5.11
+# Desc: children of psnp->char_ptr
+mi_gdb_test "-var-list-children psnp->char_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",exp=\"\\*psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\"\}\}" \
+       "get children of psnp->char_ptr"
+
+# Test: c_variable-5.12
+# Desc: number of children of psnp->char_ptr
+mi_gdb_test "-var-info-num-children psnp->char_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->char_ptr"
+
+# Test: c_variable-5.13
+# Desc: children of *(psnp->char_ptr)
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",exp=\"\\*\\*psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\"\}\}" \
+       "get children of psnp->char_ptr.*psnp->char_ptr"
+
+# Test: c_variable-5.14
+# Desc: number of children of *(psnp->char_ptr)
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->char_ptr.*psnp->char_ptr"
+
+# Test: c_variable-5.15
+# Desc: children of *(*(psnp->char_ptr))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",exp=\"\\*\\*\\*psnp->char_ptr\",numchild=\"0\",type=\"char \\*\"\}\}" \
+       "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr"
+
+# Test: c_variable-5.16
+# Desc: number of children of *(*(psnp->char_ptr))
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr"
+
+# Test: c_variable-5.17
+# Desc: children of *(*(*(psnp->char_ptr)))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr"
+
+# Test: c_variable-5.18
+# Desc: number of children of *(*(*(psnp->char_ptr)))
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr"
+
+
+# Test: c_variable-5.19
+# Desc: create psnp->long_ptr
+mi_gdb_test "-var-create  psnp->long_ptr *  psnp->long_ptr" \
+       "\\^done,name=\"psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"" \
+       "create local variable  psnp->long_ptr"
+
+# Test: c_variable-5.20
+# Desc: children of psnp->long_ptr
+mi_gdb_test "-var-list-children psnp->long_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",exp=\"\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\"\}\}" \
+       "get children of psnp->long_ptr"
+
+# Test: c_variable-5.21
+# Desc: number of children of psnp->long_ptr
+mi_gdb_test "-var-info-num-children psnp->long_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->long_ptr"
+
+# Test: c_variable-5.22
+# Desc: children of *(psnp->long_ptr)
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",exp=\"\\*\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\"\}\}" \
+       "get children of psnp->long_ptr.*psnp->long_ptr"
+
+
+# Test: c_variable-5.23
+# Desc: number of children of *(psnp->long_ptr)
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->long_ptr.*psnp->long_ptr"
+
+# Test: c_variable-5.24
+# Desc: children of *(*(psnp->long_ptr))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",exp=\"\\*\\*\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\"\}\}" \
+       "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr"
+
+# Test: c_variable-5.25
+# Desc: number of children of *(*(psnp->long_ptr))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr"
+
+# Test: c_variable-5.26
+# Desc: children of *(*(*(psnp->long_ptr)))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",exp=\"\\*\\*\\*\\*psnp->long_ptr\",numchild=\"0\",type=\"long int\"\}\}" \
+       "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr"
+
+# Test: c_variable-5.27
+# Desc: number of children of *(*(*(psnp->long_ptr)))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr"
+
+# Test: c_variable-5.28
+# Desc: children of *(*(*(*(psnp->long_ptr))))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr"
+
+# Test: c_variable-5.29
+# Desc: number of children of *(*(*(*(psnp->long_ptr))))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr"
+
+# Test: c_variable-5.30
+# Desc: create psnp->ptrs
+mi_gdb_test "-var-create  psnp->ptrs *  psnp->ptrs" \
+       "\\^done,name=\"psnp->ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"" \
+       "create local variable  psnp->ptrs"
+
+# Test: c_variable-5.31
+# Desc: children of psnp->ptrs
+mi_gdb_test "-var-list-children psnp->ptrs" \
+       "\\^done,numchild=\"3\",children=\{child=\{name=\"psnp->ptrs.0\",exp=\"0\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.1\",exp=\"1\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.2\",exp=\"2\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+       "get children of psnp->ptrs"
+
+# Test: c_variable-5.32
+# Desc: number of children of psnp->ptrs
+mi_gdb_test "-var-info-num-children psnp->ptrs" \
+       "\\^done,numchild=\"3\"" \
+       "get number of children of psnp->ptrs"
+
+# Test: c_variable-5.33
+# Desc: children of psnp->ptrs[0]
+mi_gdb_test "-var-list-children psnp->ptrs.0" \
+       "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+       "get children of psnp->ptrs.0"
+
+# Test: c_variable-5.34
+# Desc: number of children of psnp->ptrs[0]
+mi_gdb_test "-var-info-num-children psnp->ptrs.0" \
+       "\\^done,numchild=\"4\"" \
+       "get number of children of psnp->ptrs.0"
+
+# Test: c_variable-5.35
+# Desc: children of psnp->ptrs[0]->next
+mi_gdb_test "-var-list-children psnp->ptrs.0.next" \
+       "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+       "get children of psnp->ptrs.0.next"
+
+#} {char_ptr long_ptr ptrs next}
+
+# Test: c_variable-5.36
+# Desc: number of children of psnp->ptrs[0]->next
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next" \
+       "\\^done,numchild=\"4\"" \
+       "get number of children of psnp->ptrs.0.next"
+
+
+# Test: c_variable-5.37
+# Desc: children of psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",exp=\"\\*char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\"\}\}" \
+       "get children of psnp->ptrs.0.next.char_ptr"
+
+#gdbtk_test c_variable-5.37 {children of psnp->ptrs[0]->next->char_ptr} {
+#  get_children psnp->ptrs.0.next.char_ptr
+#} {*char_ptr}
+
+# Test: c_variable-5.38
+# Desc: number of children of psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->ptrs.0.next.char_ptr"
+
+# Test: c_variable-5.39
+# Desc: children of *psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",exp=\"\\*\\*char_ptr\",numchild=\"1\",type=\"char \\*\\*\"\}\}" \
+       "get children of psnp->ptrs.0.next.char_ptr.*char_ptr"
+
+# Test: c_variable-5.40
+# Desc: number of children of *psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr"
+
+# Test: c_variable-5.41
+# Desc: children of **psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr" \
+       "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",exp=\"\\*\\*\\*char_ptr\",numchild=\"0\",type=\"char \\*\"\}\}" \
+       "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr"
+
+# Test: c_variable-5.42
+# Desc: number of children of **psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr" \
+       "\\^done,numchild=\"1\"" \
+       "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr"
+
+# Test: c_variable-5.43
+# Desc: children of ***psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.44
+# Desc: number of children of ***psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.45
+# Desc: children of psnp->ptrs[0]->next->next
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.next" \
+       "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.next.next.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.next.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next.next.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+       "get children of psnp->ptrs.0.next.next"
+
+# Test: c_variable-5.46
+# Desc: children of psnp->ptrs[0]->next->next->ptrs
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.next.ptrs" \
+       "\\^done,numchild=\"3\",children=\{child=\{name=\"psnp->ptrs.0.next.next.ptrs.0\",exp=\"0\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs.1\",exp=\"1\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs.2\",exp=\"2\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+       "get children of psnp->ptrs.0.next.next.ptrs"
+
+#  Step over "snp0.char_ptr = &b3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"255\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.47
+# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"psnp->ptrs.0.char_ptr\",name=\"psnp->char_ptr\",name=\"psnp->char_ptr.\\*psnp->char_ptr\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\"\}" \
+       "update all vars psnp->char_ptr (and 0.char_ptr) changed"
+
+#  Step over "snp1.char_ptr = &c3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"256\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+
+# Test: c_variable-5.48
+# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"psnp->ptrs.0.next.char_ptr\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\"\}" \
+       "update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
+
+
+#  Step over "snp2.char_ptr = &a3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"257\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+
+# Test: c_variable-5.49
+# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.char_ptr\"\}" \
+       "update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
+
+
+#  Step over "snp0.long_ptr = &y3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"258\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+# Test: c_variable-5.50
+# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"psnp->ptrs.0.long_ptr\",name=\"psnp->long_ptr\",name=\"psnp->long_ptr.\\*psnp->long_ptr\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\"\}" \
+       "update all vars psnp->long_ptr (and 0.long_ptr) changed"
+
+
+#  Step over "snp1.long_ptr = &x3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"259\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+
+# Test: c_variable-5.51
+# Desc: check that psnp->next->long_ptr (and [1].long_ptr) changed
+mi_gdb_test "-var-update *" \
+       "FIXME\\^done,changelist=\{name=\"psnp->ptrs.0.next.long_ptr\"\}" \
+       "update all vars psnp->next->long_ptr (and 1.long_ptr) changed"
+
+# This command produces this error message:
+# &"warning: varobj_list: assertion failed - mycount <> 0\n"^M
+#
+
+#  Step over "snp2.long_ptr = &z3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"260\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_children_tests"
+    }
+    timeout {
+       fail "step at do_children_tests (timeout)"
+    }
+}
+
+
+# Test: c_variable-5.52
+# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.long_ptr\"\}" \
+       "update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
+
+
+
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End:
diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
new file mode 100644 (file)
index 0000000..7b4ebcc
--- /dev/null
@@ -0,0 +1,605 @@
+#   Copyright (C) 1999 2000 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+
+#####                   #####
+#                           #
+#  Variable Creation tests  #
+#                           #
+#####                   #####
+
+# Test:  c_variable-1.1
+# Desc:  Create global variable
+
+mi_gdb_test "111-var-create global_simple * global_simple" \
+       "111\\^done,name=\"global_simple\",numchild=\"6\",type=\"simpleton\"" \
+       "create global variable"
+
+# Test: c_variable-1.2
+# Desc: Create non-existent variable
+
+mi_gdb_test "112-var-create bogus_unknown_variable * bogus_unknown_variable" \
+       "&\"No symbol \\\\\"bogus_unknown_variable\\\\\" in current context.\\\\n\".*112\\^error,msg=\"No symbol \\\\\"bogus_unknown_variable\\\\\" in current context.\"" \
+       "create non-existent variable"
+
+# Test: c_variable-1.3
+# Desc: Create out of scope variable
+
+mi_gdb_test "113-var-create argc * argc" \
+       "&\"No symbol \\\\\"argc\\\\\" in current context.\\\\n\".*113\\^error,msg=\"No symbol \\\\\"argc\\\\\" in current context.\"" \
+       "create out of scope variable"
+
+mi_gdb_test "200-break-insert do_locals_tests" \
+       "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_locals_tests\",file=\".*var-cmd.c\",line=\"106\",times=\"0\"\}" \
+       "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+    -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"106\"\}\r\n$mi_gdb_prompt$" {
+       pass "run to do_locals_tests"
+    }
+    -re ".*$mi_gdb_prompt$" {fail "run todo_locals_tests (2)"}
+    timeout {fail "run to do_locals_tests (timeout 2)"}
+}
+
+# Test: c_variable-1.4
+# Desc: create local variables
+
+mi_gdb_test "-var-create linteger * linteger" \
+       "\\^done,name=\"linteger\",numchild=\"0\",type=\"int\"" \
+       "create local variable linteger"
+
+mi_gdb_test "-var-create lpinteger * lpinteger" \
+       "\\^done,name=\"lpinteger\",numchild=\"1\",type=\"int \\*\"" \
+       "create local variable lpinteger"
+
+mi_gdb_test "-var-create lcharacter * lcharacter" \
+       "\\^done,name=\"lcharacter\",numchild=\"0\",type=\"char\"" \
+       "create local variablelcharacter "
+
+mi_gdb_test "-var-create lpcharacter * lpcharacter" \
+       "\\^done,name=\"lpcharacter\",numchild=\"0\",type=\"char \\*\"" \
+       "create local variable lpcharacter"
+
+mi_gdb_test "-var-create llong * llong" \
+       "\\^done,name=\"llong\",numchild=\"0\",type=\"long int\"" \
+       "create local variable llong"
+
+mi_gdb_test "-var-create lplong * lplong" \
+       "\\^done,name=\"lplong\",numchild=\"1\",type=\"long int \\*\"" \
+       "create local variable lplong"
+
+mi_gdb_test "-var-create lfloat * lfloat" \
+       "\\^done,name=\"lfloat\",numchild=\"0\",type=\"float\"" \
+       "create local variable lfloat"
+
+mi_gdb_test "-var-create lpfloat * lpfloat" \
+       "\\^done,name=\"lpfloat\",numchild=\"1\",type=\"float \\*\"" \
+       "create local variable lpfloat"
+
+mi_gdb_test "-var-create ldouble * ldouble" \
+       "\\^done,name=\"ldouble\",numchild=\"0\",type=\"double\"" \
+       "create local variable ldouble"
+
+mi_gdb_test "-var-create lpdouble * lpdouble" \
+       "\\^done,name=\"lpdouble\",numchild=\"1\",type=\"double \\*\"" \
+       "create local variable lpdouble"
+
+mi_gdb_test "-var-create lsimple * lsimple" \
+       "\\^done,name=\"lsimple\",numchild=\"6\",type=\"struct _simple_struct\"" \
+       "create local variable lsimple"
+
+mi_gdb_test "-var-create lpsimple * lpsimple" \
+       "\\^done,name=\"lpsimple\",numchild=\"6\",type=\"struct _simple_struct \\*\"" \
+       "create local variable lpsimple"
+
+mi_gdb_test "-var-create func * func" \
+       "\\^done,name=\"func\",numchild=\"0\",type=\"void \\(\\*\\)\\(\\)\"" \
+       "create local variable func"
+
+# Test: c_variable-1.5
+# Desc: create lsimple.character
+mi_gdb_test "-var-create lsimple.character * lsimple.character" \
+       "\\^done,name=\"lsimple.character\",numchild=\"0\",type=\"char\"" \
+       "create lsimple.character"
+
+# Test: c_variable-1.6
+# Desc: create lpsimple->integer
+mi_gdb_test "-var-create lsimple->integer * lsimple->integer" \
+       "\\^done,name=\"lsimple->integer\",numchild=\"0\",type=\"int\"" \
+       "create lsimple->integer"
+
+# Test: c_variable-1.7
+# Desc: ceate lsimple.integer
+mi_gdb_test "-var-create lsimple.integer * lsimple.integer" \
+       "\\^done,name=\"lsimple.integer\",numchild=\"0\",type=\"int\"" \
+       "create lsimple->integer"
+
+
+# Test: c_variable-1.9
+# Desc: create type name
+#    Type names (like int, long, etc..) are all proper expressions to gdb.
+#    make sure variable code does not allow users to create variables, though.
+mi_gdb_test "-var-create int * int" \
+       "&\"Attempt to use a type name as an expression.mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+       "create int"
+
+
+#####             #####
+#                     #
+# Value changed tests #
+#                     #
+#####             #####
+
+# Test: c_variable-2.1
+# Desc: check whether values changed at do_block_tests
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{\}" \
+       "update all vars"
+
+# Step over "linteger = 1234;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"107\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_locals_tests"
+    }
+    timeout {
+       fail "step at do_locals_tests (timeout)"
+    }
+}
+
+# Test: c_variable-2.2
+# Desc: check whether only linteger changed values
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"linteger\"\}" \
+       "update all vars: linteger changed"
+
+# Step over "lpinteger = &linteger;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"108\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_locals_tests"
+    }
+    timeout {
+       fail "step at do_locals_tests (timeout)"
+    }
+}
+
+# Test: c_variable-2.3
+# Desc: check whether only lpinteger changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"lpinteger\"\}" \
+       "update all vars: lpinteger changed"
+
+# Step over "lcharacter = 'a';"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"109\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_locals_tests"
+    }
+    timeout {
+       fail "step at do_locals_tests (timeout)"
+    }
+}
+
+# Test: c_variable-2.4
+# Desc: check whether only lcharacter changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"lcharacter\"\}" \
+       "update all vars: lcharacter changed"
+
+# Step over "lpcharacter = &lcharacter;"
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"110\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_locals_tests"
+    }
+    timeout {
+       fail "step at do_locals_tests (timeout)"
+    }
+}
+
+# Test: c_variable-2.5
+# Desc: check whether only lpcharacter changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"lpcharacter\"\}" \
+       "update all vars: lpcharacter changed"
+
+
+# Step over:
+#  llong = 2121L;
+#  lplong = &llong;
+#  lfloat = 2.1;
+#  lpfloat = &lfloat;
+#  ldouble = 2.718281828459045;
+#  lpdouble = &ldouble;
+#  lsimple.integer = 1234;
+#  lsimple.unsigned_integer = 255;
+#  lsimple.character = 'a';
+
+send_gdb "-exec-step 9\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"119\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_locals_tests"
+    }
+    timeout {
+       fail "step at do_locals_tests (timeout)"
+    }
+}
+
+# Test: c_variable-2.6
+# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
+#       lsimple.unsigned_character lsimple.integer lsimple.character changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"lsimple.integer\",name=\"lsimple->integer\",name=\"lsimple.character\",name=\"lpdouble\",name=\"ldouble\",name=\"lpfloat\",name=\"lfloat\",name=\"lplong\",name=\"llong\"\}" \
+       "update all vars: many changed"
+
+# Step over:
+#  lsimple.signed_character = 21;
+#  lsimple.char_ptr = &lcharacter;
+#  lpsimple = &lsimple;
+#  func = nothing;
+
+send_gdb "-exec-step 4\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"125\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_locals_tests"
+    }
+    timeout {
+       fail "step at do_locals_tests (timeout)"
+    }
+}
+
+# Test: c_variable-2.7
+# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"func\",name=\"lpsimple\"\}" \
+       "update all vars: func and lpsimple changed"
+
+# Step over
+#  linteger = 4321;
+#  lcharacter = 'b';
+#  llong = 1212L;
+#  lfloat = 1.2;
+#  ldouble = 5.498548281828172;
+#  lsimple.integer = 255;
+#  lsimple.unsigned_integer = 4321;
+#  lsimple.character = 'b';
+
+send_gdb "-exec-step 8\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"133\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at do_locals_tests"
+    }
+    timeout {
+       fail "step at do_locals_tests (timeout)"
+    }
+}
+
+# Test: c_variable-2.8
+# Desc: check whether linteger, lcharacter, llong, lfoat, ldouble, lsimple.integer,
+#       lpsimple.integer lsimple.character changed
+# Note: this test also checks that lpsimple->integer and lsimple.integer have
+#       changed (they are the same)
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"lsimple.integer\",name=\"lsimple->integer\",name=\"lsimple.character\",name=\"ldouble\",name=\"lfloat\",name=\"llong\",name=\"lcharacter\",name=\"linteger\"\}" \
+       "update all vars: func and lpsimple changed"
+
+
+### 
+#
+# Test assignment to variables. More tests on assignment are in other files.
+#
+###
+mi_gdb_test "-var-assign global_simple 0" \
+       "&\"mi_cmd_var_assign: Variable object is not editable\\\\n\".*\\^error,msg=\"mi_cmd_var_assign: Variable object is not editable\"" \
+       "assign to global_simple"
+
+mi_gdb_test "-var-assign linteger 3333" \
+       "\\^done,value=\"3333\"" \
+       "assign to linteger"
+
+mi_gdb_test "-var-evaluate-expression linteger" \
+       "\\^done,value=\"3333\"" \
+       "eval linteger"
+
+mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
+       "\\^done,value=\"$hex\"" \
+       "assign to lpinteger"
+
+mi_gdb_test "-var-evaluate-expression lpinteger" \
+       "\\^done,value=\"$hex\"" \
+       "eval lpinteger"
+
+# reset the values to the original ones so that the rest of the file doesn't suffer.
+
+mi_gdb_test "-var-assign linteger 4321" \
+       "\\^done,value=\"4321\"" \
+       "assign to linteger"
+
+mi_gdb_test "-var-assign lpinteger &linteger" \
+       "\\^done,value=\"$hex\"" \
+       "assign to lpinteger"
+
+mi_gdb_test "-var-assign lcharacter 'z'" \
+       "\\^done,value=\"122 'z'\"" \
+       "assign to lcharacter"
+
+mi_gdb_test "-var-evaluate-expression lcharacter" \
+       "\\^done,value=\"122 'z'\"" \
+       "eval lcharacter"
+
+mi_gdb_test "-var-assign llong 1313L" \
+       "\\^done,value=\"1313\"" \
+       "assign to llong"
+mi_gdb_test "-var-evaluate-expression llong" \
+       "\\^done,value=\"1313\"" \
+       "eval llong"
+mi_gdb_test "-var-assign llong 1212L" \
+       "\\^done,value=\"1212\"" \
+       "assign to llong"
+
+mi_gdb_test "-var-assign lplong &llong+4" \
+       "\\^done,value=\"$hex\"" \
+       "assign to lplong"
+mi_gdb_test "-var-evaluate-expression lplong" \
+       "\\^done,value=\"$hex\"" \
+       "eval lplong"
+mi_gdb_test "-var-assign lplong &llong" \
+       "\\^done,value=\"$hex\"" \
+       "assign to lplong"
+
+mi_gdb_test "-var-assign lfloat 3.4" \
+       "\\^done,value=\"3.4.*\"" \
+       "assign to lfloat"
+mi_gdb_test "-var-evaluate-expression lfloat" \
+       "\\^done,value=\"3.4.*\"" \
+       "eval lfloat"
+mi_gdb_test "-var-assign lfloat 1.2" \
+       "\\^done,value=\"1.2.*\"" \
+       "assign to lfloat"
+
+mi_gdb_test "-var-assign lpfloat &lfloat+4" \
+       "\\^done,value=\"$hex\"" \
+       "assign to lpfloat"
+
+mi_gdb_test "-var-assign ldouble 5.333318284590435" \
+       "\\^done,value=\"5.333318284590435\"" \
+       "assign to ldouble"
+
+mi_gdb_test "-var-assign func do_block_tests" \
+       "\\^done,value=\"$hex <do_block_tests>\"" \
+       "assign to func"
+
+mi_gdb_test "-var-assign lsimple.character 'd'" \
+       "\\^done,value=\"100 'd'\"" \
+       "assign to lsimple.character"
+
+mi_gdb_test "-var-assign  lsimple->integer 222" \
+       "\\^done,value=\"222\"" \
+       "assign to lsimple->integer"
+
+mi_gdb_test "-var-assign lsimple.integer 333" \
+       "\\^done,value=\"333\"" \
+       "assign to lsimple.integer"
+
+######
+# End of assign tests 
+#####
+
+mi_gdb_test "-break-insert subroutine1" \
+       "\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"subroutine1\",file=\".*var-cmd.c\",line=\"146\",times=\"0\"\}" \
+       "break-insert subroutine1"
+send_gdb "-exec-continue\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"subroutine1\",args=\{\{name=\"i\",value=\"4321\"\},\{name=\"l\",value=\"$hex\"\}\},file=\".*var-cmd.c\",line=\"146\"\}\r\n$mi_gdb_prompt$" {
+       pass "continue to subroutine1"
+    }
+    timeout {
+       fail "continue to subroutine1 (timeout)"
+    }
+}
+
+# Test: c_variable-2.10
+# Desc: create variable for locals i,l in subroutine1
+mi_gdb_test "-var-create i  * i" \
+       "\\^done,name=\"i\",numchild=\"0\",type=\"int\"" \
+       "create i"
+
+mi_gdb_test "-var-create l * l" \
+       "\\^done,name=\"l\",numchild=\"1\",type=\"long int \\*\"" \
+       "create l"
+
+# Test: c_variable-2.11
+# Desc: create do_locals_tests local in subroutine1
+mi_gdb_test "-var-create linteger * linteger" \
+       "&\"No symbol \\\\\"linteger\\\\\" in current context.\\\\n\".*\\^error,msg=\"No symbol \\\\\"linteger\\\\\" in current context.\"" \
+       "create linteger"
+
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"subroutine1\",args=\{\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}\},file=\".*var-cmd.c\",line=\"147\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at subroutine1"
+    }
+    timeout {
+       fail "step at subroutine1 (timeout)"
+    }
+}
+
+# Test: c_variable-2.12
+# Desc: change global_simple.integer
+# Note: This also tests whether we are reporting changes in structs properly.
+#       gdb normally would say that global_simple has changed, but we
+#       special case that, since it is not what a human expects to see.
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{FIXME: WHAT IS CORRECT HERE\}" \
+       "update all vars: changed FIXME"
+
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"subroutine1\",args=\{\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}\},file=\".*var-cmd.c\",line=\"148\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at subroutine1"
+    }
+    timeout { fail "step at subroutine1 (timeout)" }
+}
+
+# Test: c_variable-2.13
+# Desc: change subroutine1 local i
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"i\"\}" \
+       "update all vars: i changed"
+
+send_gdb "-exec-step\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"subroutine1\",args=\{\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}\},file=\".*var-cmd.c\",line=\"149\"\}\r\n$mi_gdb_prompt$" {
+       pass "step at subroutine1"
+    }
+    timeout { fail "step at subroutine1 (timeout)" }
+}
+
+# Test: c_variable-2.14
+# Desc: change do_locals_tests local llong
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{name=\"llong\"\}" \
+       "update all vars: llong changed"
+
+send_gdb "-exec-next\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"136\"\}\r\n$mi_gdb_prompt$" {
+       pass "next out of subroutine1"
+    }
+    timeout { fail "next out of subroutine1 (timeout)" }
+}
+
+# Test: c_variable-2.15
+# Desc: check for out of scope subroutine1 locals
+mi_gdb_test "-var-update *" \
+       "\\^done,changelist=\{\}" \
+       "update all vars: none changed"
+
+# Done with locals/globals tests. Erase all variables
+#delete_all_variables
+mi_gdb_test "-var-delete global_simple" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var"
+
+mi_gdb_test "-var-delete linteger" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var linteger"
+
+mi_gdb_test "-var-delete lpinteger" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lpinteger"
+
+mi_gdb_test "-var-delete lcharacter" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lcharacter"
+
+mi_gdb_test "-var-delete lpcharacter" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lpcharacter"
+
+mi_gdb_test "-var-delete llong" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var llong"
+
+mi_gdb_test "-var-delete lplong" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lplong"
+
+mi_gdb_test "-var-delete lfloat" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lfloat"
+
+mi_gdb_test "-var-delete lpfloat" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lpfloat"
+
+mi_gdb_test "-var-delete ldouble" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var ldouble"
+
+mi_gdb_test "-var-delete lpdouble" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lpdouble"
+
+mi_gdb_test "-var-delete lsimple" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lsimple"
+
+mi_gdb_test "-var-delete lpsimple" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lpsimple"
+
+mi_gdb_test "-var-delete func" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var func"
+
+mi_gdb_test "-var-delete lsimple.character" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lsimple.character"
+
+mi_gdb_test "-var-delete  lsimple->integer" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var  lsimple->integer"
+
+mi_gdb_test "-var-delete lsimple.integer" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var lsimple.integer"
+
+mi_gdb_test "-var-delete i" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var i"
+
+mi_gdb_test "-var-delete l" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var l"
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End:
+
diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp
new file mode 100644 (file)
index 0000000..4f231d0
--- /dev/null
@@ -0,0 +1,628 @@
+#   Copyright (C) 1999 2000 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert 260" \
+       "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"260\",times=\"0\"\}" \
+       "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+    -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"260\"\}\r\n$mi_gdb_prompt$" {
+       pass "run to do_children_tests"
+    }
+    -re ".*$mi_gdb_prompt$" {fail "run to do_children_tests (2)"}
+    timeout {fail "run to do_children_tests (timeout 2)"}
+}
+
+#####       #####
+#               #
+# Display tests #
+#               #
+#####       #####
+
+# Test: c_variable-6.1
+# Desc: create variable bar
+mi_gdb_test "-var-create bar * bar" \
+       "\\^done,name=\"bar\",numchild=\"0\",type=\"int\"" \
+       "create local variable bar"
+
+# Test: c_variable-6.2
+# Desc: type of variable bar
+mi_gdb_test "-var-info-type bar" \
+       "\\^done,type=\"int\"" \
+       "info type variable bar"
+
+# Test: c_variable-6.3
+# Desc: format of variable bar
+mi_gdb_test "-var-show-format bar" \
+       "\\^done,format=\"natural\"" \
+       "show format variable bar"
+
+# Test: c_variable-6.4
+# Desc: value of variable bar
+mi_gdb_test "-var-evaluate-expression bar" \
+       "\\^done,value=\"2121\"" \
+       "eval variable bar"
+
+# Test: c_variable-6.5
+# Desc: change format of bar to hex
+mi_gdb_test "-var-set-format bar hexadecimal" \
+       "\\^done,format=\"hexadecimal\"" \
+       "set format variable bar"
+
+# Test: c_variable-6.6
+# Desc: value of bar with new format
+mi_gdb_test "-var-evaluate-expression bar" \
+       "\\^done,value=\"0x849\"" \
+       "eval variable bar with new format"
+
+# Test: c_variable-6.7
+# Desc: change value of bar
+mi_gdb_test "-var-assign bar 3" \
+       "\\^done,value=\"0x3\"" \
+       "assing to variable bar"
+
+mi_gdb_test "-var-set-format bar decimal" \
+       "\\^done,format=\"decimal\"" \
+       "set format variable bar"
+
+mi_gdb_test "-var-evaluate-expression bar" \
+       "\\^done,value=\"3\"" \
+       "eval variable bar with new value"
+
+mi_gdb_test "-var-delete bar" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var bar"
+
+# Test: c_variable-6.11
+# Desc: create variable foo
+mi_gdb_test "-var-create foo * foo" \
+       "\\^done,name=\"foo\",numchild=\"1\",type=\"int \\*\"" \
+       "create local variable foo"
+
+# Test: c_variable-6.12
+# Desc: type of variable foo
+mi_gdb_test "-var-info-type foo" \
+       "\\^done,type=\"int \\*\"" \
+       "info type variable foo"
+
+# Test: c_variable-6.13
+# Desc: format of variable foo
+mi_gdb_test "-var-show-format foo" \
+       "\\^done,format=\"natural\"" \
+       "show format variable foo"
+
+# Test: c_variable-6.14
+# Desc: value of variable foo
+mi_gdb_test "-var-evaluate-expression foo" \
+       "\\^done,value=\"$hex\"" \
+       "eval variable foo"
+
+# Test: c_variable-6.15
+# Desc: change format of var to octal
+mi_gdb_test "-var-set-format foo octal" \
+       "\\^done,format=\"octal\"" \
+       "set format variable foo"
+
+mi_gdb_test "-var-show-format foo" \
+       "\\^done,format=\"octal\"" \
+       "show format variable foo"
+
+# Test: c_variable-6.16
+# Desc: value of foo with new format
+mi_gdb_test "-var-evaluate-expression foo" \
+       "\\^done,value=\"\[0-7\]+\"" \
+       "eval variable foo"
+
+# Test: c_variable-6.17
+# Desc: change value of foo
+mi_gdb_test "-var-assign foo 3" \
+       "\\^done,value=\"03\"" \
+       "assing to variable foo"
+
+mi_gdb_test "-var-set-format foo decimal" \
+       "\\^done,format=\"decimal\"" \
+       "set format variable foo"
+
+# Test: c_variable-6.18
+# Desc: check new value of foo
+mi_gdb_test "-var-evaluate-expression foo" \
+       "\\^done,value=\"3\"" \
+       "eval variable foo"
+
+mi_gdb_test "-var-delete foo" \
+       "\\^done,ndeleted=\"1\"" \
+       "delete var foo"
+
+# Test: c_variable-6.21
+# Desc: create variable weird and children
+mi_gdb_test "-var-create weird * weird" \
+       "\\^done,name=\"weird\",numchild=\"11\",type=\"weird_struct \\*\"" \
+       "create local variable weird"
+
+mi_gdb_test "-var-list-children weird" \
+       "\\^done,numchild=\"11\",children=\{child=\{name=\"weird.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"weird.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child={name=\"weird.char_ptr\",exp=\"char_ptr\",numchild=\"0\",type=\"char \\*\"\},child=\{name=\"weird.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"weird.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"weird.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\(\\)\"\},child=\{name=\"weird.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"weird.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+       "get children local variable weird"
+
+
+# Test: c_variable-6.23
+# Desc: change format of weird.func_ptr and weird.func_ptr_ptr
+mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \
+       "\\^done,format=\"hexadecimal\"" \
+       "set format variable weird.func_ptr"
+
+mi_gdb_test "-var-show-format weird.func_ptr" \
+       "\\^done,format=\"hexadecimal\"" \
+       "show format variable weird.func_ptr"
+
+mi_gdb_test "-var-set-format weird.func_ptr_ptr hexadecimal" \
+       "\\^done,format=\"hexadecimal\"" \
+       "set format variable weird.func_ptr_ptr"
+
+mi_gdb_test "-var-show-format weird.func_ptr_ptr" \
+       "\\^done,format=\"hexadecimal\"" \
+       "show format variable weird.func_ptr_ptr"
+
+# Test: c_variable-6.24
+# Desc: format of weird and children
+mi_gdb_test "-var-set-format weird natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird"
+
+mi_gdb_test "-var-set-format weird.integer natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.integer"
+
+mi_gdb_test "-var-set-format weird.character natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.character"
+
+mi_gdb_test "-var-set-format weird.char_ptr natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.char_ptr"
+
+mi_gdb_test "-var-set-format weird.long_int natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.long_int"
+
+mi_gdb_test "-var-set-format weird.int_ptr_ptr natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.int_ptr_ptr"
+
+mi_gdb_test "-var-set-format weird.long_array natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.long_array"
+
+mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \
+       "\\^done,format=\"hexadecimal\"" \
+       "set format variable weird.func_ptr"
+
+mi_gdb_test "-var-set-format weird.func_ptr_struct hexadecimal" \
+       "\\^done,format=\"hexadecimal\"" \
+       "set format variable weird.func_ptr_struct"
+
+mi_gdb_test "-var-set-format weird.func_ptr_ptr natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.func_ptr_ptr"
+
+mi_gdb_test "-var-set-format weird.u1 natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.u1"
+
+mi_gdb_test "-var-set-format weird.s2 natural" \
+       "\\^done,format=\"natural\"" \
+       "set format variable weird.s2"
+
+# Test: c_variable-6.25
+# Desc: value of weird and children
+#gdbtk_test c_variable-6.25 {value of weird and children} {
+#  set values {}
+#  foreach v [lsort [array names var]] f [list x "" "" x x x x d d d d d] {
+#    lappend values [value $v $f]
+#  }
+
+#  set values
+#} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1}
+
+# Test: c_variable-6.26
+# Desc: change format of weird and children to octal
+#gdbtk_test c_variable-6.26 {change format of weird and children to octal} {
+#  set formats {}
+#  foreach v [lsort [array names var]] {
+#    $var($v) format octal
+#    lappend formats [$var($v) format]
+#  }
+
+#  set formats
+#} {octal octal octal octal octal octal octal octal octal octal octal octal}
+
+# Test: c_variable-6.27
+# Desc: value of weird and children with new format
+#gdbtk_test c_variable-6.27 {value of foo with new format} {
+#  set values {}
+#  foreach v [lsort [array names var]] {
+#    lappend values [value $v o]
+#  }
+
+#  set values
+#} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1}
+
+# Test: c_variable-6.30
+# Desc: create more children of weird
+#gdbtk_test c_variable-6.30 {create more children of weird} {
+#  foreach v [array names var] {
+#    get_children $v
+#  }
+
+#  # Do it twice to get more children
+#  foreach v [array names var] {
+#    get_children $v
+#  }
+
+#  lsort [array names var]
+#} {weird weird.char_ptr weird.character weird.func_ptr weird.func_ptr_ptr weird.func_ptr_struct weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.integer weird.long_array weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.long_int weird.s2 weird.s2.g weird.s2.h weird.s2.i weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9 weird.s2.u2 weird.s2.u2.f weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.u1 weird.u1.a weird.u1.b weird.u1.c weird.u1.d}
+
+# Test: c_variable-6.31
+# Desc: check that all children of weird change
+#       Ok, obviously things like weird.s2 and weird.u1 will not change!
+#gdbtk_test *c_variable-6.31 {check that all children of weird change (ops, we are now reporting array names as changed in this case - seems harmless though)} {
+#  $var(weird) value 0x2121
+#  check_update
+#} {{weird.integer weird.character weird.char_ptr weird.long_int weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.func_ptr weird.func_ptr_struct weird.func_ptr_ptr weird.u1.a weird.u1.b weird.u1.c weird.u1.d weird.s2.u2.f weird.s2.g weird.s2.h weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9} {weird.s2.i weird.s2.u2 weird weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.s2 weird.long_array weird.u1} {}}
+
+mi_gdb_test "-var-delete weird" \
+       "\\^done,ndeleted=\"12\"" \
+       "delete var weird"
+
+
+#####               #####
+#                       #
+# Special Display Tests #
+#                       #
+#####               #####
+
+# Stop in "do_special_tests"
+mi_gdb_test "200-break-insert do_special_tests" \
+       "200\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_special_tests\",file=\".*var-cmd.c\",line=\"282\",times=\"0\"\}" \
+       "break-insert operation"
+
+send_gdb "-exec-continue\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"do_special_tests\",args=\{\},file=\".*var-cmd.c\",line=\"282\"\}\r\n$mi_gdb_prompt$" {
+       pass "continue to do_special_tests"
+    }
+    timeout {
+       fail "continue to do_special_tests (timeout)"
+    }
+}
+
+# Test: c_variable-7.10
+# Desc: create union u
+mi_gdb_test "-var-create u * u" \
+       "\\^done,name=\"u\",numchild=\"2\",type=\"union named_union\"" \
+       "create local variable u"
+
+# Test: c_variable-7.11
+# Desc: value of u
+mi_gdb_test "-var-evaluate-expression u" \
+       "\\^done,value=\"\{\\.\\.\\.\}\"" \
+       "eval variable u"
+
+# Test: c_variable-7.12
+# Desc: type of u
+mi_gdb_test "-var-info-type u" \
+       "\\^done,type=\"union named_union\"" \
+       "info type variable u"
+
+# Test: c_variable-7.13
+# Desc: is u editable
+mi_gdb_test "-var-show-attributes u" \
+       "\\^done,attr=\"noneditable\"" \
+       "is u editable"
+
+# Test: c_variable-7.14
+# Desc: number of children of u
+mi_gdb_test "-var-info-num-children u" \
+       "\\^done,numchild=\"2\"" \
+       "get number of children of u"
+
+# Test: c_variable-7.15
+# Desc: children of u
+mi_gdb_test "-var-list-children u" \
+       "\\^done,numchild=\"2\",children=\{child=\{name=\"u.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"u.char_ptr\",exp=\"char_ptr\",numchild=\"0\",type=\"char \\*\"\}\}" \
+       "get children of u"
+
+# Test: c_variable-7.20
+# Desc: create anonu
+mi_gdb_test "-var-create anonu * anonu" \
+       "\\^done,name=\"anonu\",numchild=\"3\",type=\"union \{\\.\\.\\.\}\"" \
+       "create local variable anonu"
+
+# Test: c_variable-7.21
+# Desc: value of anonu
+mi_gdb_test "-var-evaluate-expression anonu" \
+       "\\^done,value=\"\{\\.\\.\\.\}\"" \
+       "eval variable anonu"
+
+# Test: c_variable-7.22
+# Desc: type of anonu
+mi_gdb_test "-var-info-type anonu" \
+       "\\^done,type=\"union \{\\.\\.\\.\}\"" \
+       "info type variable anonu"
+
+# Test: c_variable-7.23
+# Desc: is anonu editable
+mi_gdb_test "-var-show-attributes anonu" \
+       "\\^done,attr=\"noneditable\"" \
+       "is anonu editable"
+
+# Test: c_variable-7.24
+# Desc: number of children of anonu
+mi_gdb_test "-var-info-num-children anonu" \
+       "\\^done,numchild=\"3\"" \
+       "get number of children of anonu"
+
+# Test: c_variable-7.25
+# Desc: children of anonu
+mi_gdb_test "-var-list-children anonu" \
+       "\\^done,numchild=\"3\",children=\{child=\{name=\"anonu.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"anonu.b\",exp=\"b\",numchild=\"0\",type=\"char\"\},child=\{name=\"anonu.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\}\}" \
+       "get children of anonu"
+
+# Test: c_variable-7.30
+# Desc: create struct s
+mi_gdb_test "-var-create s * s" \
+       "\\^done,name=\"s\",numchild=\"6\",type=\"struct _simple_struct\"" \
+       "create local variable s"
+
+
+# Test: c_variable-7.31
+# Desc: value of s
+mi_gdb_test "-var-evaluate-expression s" \
+       "\\^done,value=\"\{\\.\\.\\.\}\"" \
+       "eval variable s"
+
+# Test: c_variable-7.32
+# Desc: type of s
+mi_gdb_test "-var-info-type s" \
+       "\\^done,type=\"struct _simple_struct\"" \
+       "info type variable s"
+
+# Test: c_variable-7.33
+# Desc: is s editable
+mi_gdb_test "-var-show-attributes s" \
+       "\\^done,attr=\"noneditable\"" \
+       "is s editable"
+
+# Test: c_variable-7.34
+# Desc: number of children of s
+mi_gdb_test "-var-info-num-children s" \
+       "\\^done,numchild=\"6\"" \
+       "get number of children of s"
+
+# Test: c_variable-7.35
+# Desc: children of s
+mi_gdb_test "-var-list-children s" \
+       "\\^done,numchild=\"6\",children=\{child=\{name=\"s.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"s.unsigned_integer\",exp=\"unsigned_integer\",numchild=\"0\",type=\"unsigned int\"\},child=\{name=\"s.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child=\{name=\"s.signed_character\",exp=\"signed_character\",numchild=\"0\",type=\"signed char\"\},child=\{name=\"s.char_ptr\",exp=\"char_ptr\",numchild=\"0\",type=\"char \\*\"\},child=\{name=\"s.array_of_10\",exp=\"array_of_10\",numchild=\"10\",type=\"int \\\[10\\\]\"\}\}" \
+       "get children of s"
+#} {integer unsigned_integer character signed_character char_ptr array_of_10}
+
+# Test: c_variable-7.40
+# Desc: create anons
+mi_gdb_test "-var-create anons * anons" \
+       "\\^done,name=\"anons\",numchild=\"3\",type=\"struct \{\\.\\.\\.\}\"" \
+       "create local variable anons"
+
+# Test: c_variable-7.41
+# Desc: value of anons
+mi_gdb_test "-var-evaluate-expression anons" \
+       "\\^done,value=\"\{\\.\\.\\.\}\"" \
+       "eval variable anons"
+
+# Test: c_variable-7.42
+# Desc: type of anons
+mi_gdb_test "-var-info-type anons" \
+       "\\^done,type=\"struct \{\\.\\.\\.\}\"" \
+       "info type variable anons"
+
+# Test: c_variable-7.43
+# Desc: is anons editable
+mi_gdb_test "-var-show-attributes anons" \
+       "\\^done,attr=\"noneditable\"" \
+       "is anons editable"
+
+# Test: c_variable-7.44
+# Desc: number of children of anons
+mi_gdb_test "-var-info-num-children anons" \
+       "\\^done,numchild=\"3\"" \
+       "get number of children of anons"
+
+# Test: c_variable-7.45
+# Desc: children of anons
+mi_gdb_test "-var-list-children anons" \
+       "\\^done,numchild=\"3\",children=\{child=\{name=\"anons.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"anons.b\",exp=\"b\",numchild=\"0\",type=\"char\"\},child=\{name=\"anons.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\}\}" \
+       "get children of anons"
+
+
+# Test: c_variable-7.50
+# Desc: create enum e
+mi_gdb_test "-var-create e * e" \
+       "\\^done,name=\"e\",numchild=\"0\",type=\"enum foo\"" \
+       "create local variable e"
+
+setup_xfail "*-*-*"
+# Test: c_variable-7.51
+# Desc: value of e
+mi_gdb_test "-var-evaluate-expression e" \
+       "\\^done,value=\"FIXME\"" \
+       "eval variable e"
+clear_xfail "*-*-*"
+
+# Test: c_variable-7.52
+# Desc: type of e
+mi_gdb_test "-var-info-type e" \
+       "\\^done,type=\"enum foo\"" \
+       "info type variable e"
+
+# Test: c_variable-7.53
+# Desc: is e editable
+mi_gdb_test "-var-show-attributes e" \
+       "\\^done,attr=\"editable\"" \
+       "is e editable"
+
+# Test: c_variable-7.54
+# Desc: number of children of e
+mi_gdb_test "-var-info-num-children e" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of e"
+
+# Test: c_variable-7.55
+# Desc: children of e
+mi_gdb_test "-var-list-children e" \
+       "\\^done,numchild=\"0\"" \
+       "get children of e"
+
+# Test: c_variable-7.60
+# Desc: create anone
+mi_gdb_test "-var-create anone * anone" \
+       "\\^done,name=\"anone\",numchild=\"0\",type=\"enum \{\\.\\.\\.\}\"" \
+       "create local variable anone"
+
+setup_xfail "*-*-*"
+# Test: c_variable-7.61
+# Desc: value of anone
+mi_gdb_test "-var-evaluate-expression anone" \
+       "\\^done,value=\"A\"" \
+       "eval variable anone"
+clear_xfail "*-*-*"
+
+
+# Test: c_variable-7.70
+# Desc: create anone
+mi_gdb_test "-var-create anone * anone" \
+       "&\"Duplicate variable object name\\\\n\".*\\^error,msg=\"Duplicate variable object name\"" \
+       "create duplicate local variable anone"
+
+
+# Test: c_variable-7.72
+# Desc: type of anone
+mi_gdb_test "-var-info-type anone" \
+       "\\^done,type=\"enum \{\\.\\.\\.\}\"" \
+       "info type variable anone"
+
+
+# Test: c_variable-7.73
+# Desc: is anone editable
+mi_gdb_test "-var-show-attributes anone" \
+       "\\^done,attr=\"editable\"" \
+       "is anone editable"
+
+# Test: c_variable-7.74
+# Desc: number of children of anone
+mi_gdb_test "-var-info-num-children anone" \
+       "\\^done,numchild=\"0\"" \
+       "get number of children of anone"
+
+# Test: c_variable-7.75
+# Desc: children of anone
+mi_gdb_test "-var-list-children anone" \
+       "\\^done,numchild=\"0\"" \
+       "get children of anone"
+
+
+# Record fp
+
+send_gdb "p/x \$fp\n"
+gdb_expect {
+    -re ".*($hex).*\\^done\r\n$mi_gdb_prompt$" { 
+       pass "print FP register"
+       set fp $expect_out(1,string) 
+    }
+#    -re ".*" { fail "print FP register"}
+    timeout { fail "print FP register (timeout)"}
+}
+
+mi_gdb_test "200-break-insert incr_a" \
+       "200\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"incr_a\",file=\".*var-cmd.c\",line=\"85\",times=\"0\"\}" \
+       "break-insert operation"
+send_gdb "-exec-continue\n"
+gdb_expect {
+    -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\{\{name=\"a\",value=\"2\.*\"\}\},file=\".*var-cmd.c\",line=\"85\"\}\r\n$mi_gdb_prompt$" {
+       pass "continue to incr_a"
+    }
+    timeout {
+       fail "continue to incr_a (timeout)"
+    }
+}
+
+# Test: c_variable-7.81
+# Desc: Create variables in different scopes
+mi_gdb_test "-var-create a1 * a" \
+       "\\^done,name=\"a1\",numchild=\"0\",type=\"char\"" \
+       "create local variable a1"
+
+mi_gdb_test "-var-create a2 $fp a" \
+       "\\^done,name=\"a2\",numchild=\"0\",type=\"int\"" \
+       "create variable a2 in different scope"
+
+#gdbtk_test c_variable-7.81 {create variables in different scopes} {
+#  set a1 [gdb_variable create -expr a]
+#  set a2 [gdb_variable create -expr a -frame $fp]
+
+#  set vals {}
+#  lappend vals [$a1 value]
+#  lappend vals [$a2 value]
+#  set vals
+#} {2 1}
+
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End:
+
+
+
+
diff --git a/gdb/testsuite/gdb.mi/mi-watch.exp b/gdb/testsuite/gdb.mi/mi-watch.exp
new file mode 100644 (file)
index 0000000..6c81106
--- /dev/null
@@ -0,0 +1,195 @@
+#   Copyright (C) 1999 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_watchpoint_creation_and_listing {} {
+    global mi_gdb_prompt
+    global srcfile
+    global hex
+
+    # Insert a watchpoint and list
+    # Tests:
+    # -break-watch C
+    # -break-list
+
+    mi_gdb_test "111-break-watch C" \
+             "111\\^done,wpt=\{number=\"2\",exp=\"C\"\}" \
+             "break-watch operation"
+
+    mi_gdb_test "222-break-list" \
+                "222\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"1\"\},bkpt=\{number=\"2\",type=\"watchpoint\",disp=\"keep\",enabled=\"y\",addr=\"\",what=\"C\",times=\"0\"\}\}" \
+                "list of watchpoints"
+
+}
+
+# UNUSED at the time
+proc test_awatch_creation_and_listing {} {
+    global mi_gdb_prompt
+    global srcfile
+    global hex
+
+    # Insert an access watchpoint and list it
+    # Tests:
+    # -break-watch -a A
+    # -break-list
+
+    mi_gdb_test "333-break-watch -a A" \
+             "333\\^done,bkpt=\{number=\"1\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \
+             "break-watch -a operation"
+
+    mi_gdb_test "444-break-list" \
+                "444\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"3\",type=\"watchpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+                "list of watchpoints awatch"
+
+    mi_gdb_test "777-break-delete 3" \
+           "777\\^done" \
+           "delete access watchpoint"
+}
+
+# UNUSED at the time
+proc test_rwatch_creation_and_listing {} {
+    global mi_gdb_prompt
+    global srcfile
+    global hex
+
+    # Insert a read watchpoint and list it.
+    # Tests:
+    # -break-insert -r B
+    # -break-list
+
+    mi_gdb_test "200-break-watch -r C" \
+             "200\\^done,bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+             "break-insert -r operation"
+
+    mi_gdb_test "300-break-list" \
+                "300\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+                "list of breakpoints"
+
+    mi_gdb_test "177-break-delete 4" \
+           "177\\^done" \
+           "delete read watchpoint"
+}
+
+proc test_running_the_program {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Run the program without args, then specify srgs and rerun the program
+    # Tests:
+    # -exec-run
+
+    mi_gdb_test "300-break-insert callee4" \
+             "300\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+             "insert breakpoint at callee4"
+
+    # mi_gdb_test cannot be used for asynchronous commands because there are
+    # two prompts involved and this can lead to a race condition.
+    # The following is equivalent to a send_gdb "000-exec-run\n"
+    mi_run_cmd
+    # The running part has been checked already by mi_run_cmd
+        gdb_expect {
+           -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" \
+                   { pass "run to callee4" }
+          -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+          timeout {fail "run to callee4 (timeout 2)"}
+        }
+}
+
+proc test_watchpoint_triggering {} {
+    global mi_gdb_prompt
+    global hex
+
+    # Continue execution until the watchpoint is reached,  continue again, 
+    # to see the watchpoint go out of scope.
+    # Does:
+    # -exec-continue (Here wp triggers)
+    # -exec-continue (Here wp goes out of scope)
+
+    send_gdb "222-exec-continue\n"
+    gdb_expect {
+      -re "222\\^running\r\n$mi_gdb_prompt" {
+        gdb_expect {
+           -re "222\\*stopped,reason=\"watchpoint-trigger\",wpt=\{number=\"2\",exp=\"C\"\},value=\{old=\".*\",new=\"3\"\},thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+            pass "watchpoint trigger"
+          }
+          -re ".*$mi_gdb_prompt$" {fail "watchpoint trigger (2)"}
+          timeout {fail "watchpoint trigger (timeout 2)"}
+        }
+      }
+      -re ".*$mi_gdb_prompt$" {fail "watchpoint trigger (1)"}
+      timeout {fail "watchpoint trigger (timeout 1)"}
+    }
+
+    send_gdb "223-exec-continue\n"
+    gdb_expect {
+      -re "223\\^running\r\n$mi_gdb_prompt" {
+        gdb_expect {
+           -re "\[\r\n\]*223\\*stopped,reason=\"watchpoint-scope\",wpnum=\"2\",thread-id=\"0\",frame=\{addr=\"$hex\",func=\"callee3\",args=\{.*\},file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {
+            pass "wp out of scope"
+          }
+          -re ".*$mi_gdb_prompt$" {fail "wp out of scope (2)"}
+          timeout {fail "wp out of scope (timeout 2)"}
+        }
+      }
+      -re ".*$mi_gdb_prompt$" {fail "wp out of scope (1)"}
+      timeout {fail "wp out of scope (timeout 1)"}
+    }
+}
+
+test_running_the_program
+test_watchpoint_creation_and_listing
+#test_rwatch_creation_and_listing
+#test_awatch_creation_and_listing
+test_watchpoint_triggering
+
+mi_gdb_exit
+return 0
+
+# Local variables: 
+# change-log-default-name: "ChangeLog-mi"
+# End: 
+
diff --git a/gdb/testsuite/gdb.mi/testcmds b/gdb/testsuite/gdb.mi/testcmds
new file mode 100644 (file)
index 0000000..28fa524
--- /dev/null
@@ -0,0 +1,25 @@
+# This is a (bogus) sample user command built to test the printing
+# of commands.
+define test
+set $a = 1
+set $b = 2
+if ($a > $b)
+ set $a = 1
+ set $b = 2
+ while ($a > $b)
+  set $a = 1
+  set $b = 2
+ end
+else
+ set $a = 1
+ set $b = 2
+end
+while ($a < $b)
+ set $a = $a + 1
+ set $c = $a
+ if ($a = $b)
+  set $c = 5
+ end
+ set $a = 1
+ set $b = 2
+end
diff --git a/gdb/testsuite/gdb.mi/until.c b/gdb/testsuite/gdb.mi/until.c
new file mode 100644 (file)
index 0000000..df4a68d
--- /dev/null
@@ -0,0 +1,26 @@
+foo (void)
+{
+ int i, x, y, z;
+
+ x = 0;
+ y = 1;
+ i = 0;
+
+ while (i < 2)
+   i++;
+
+ x = i;
+ y = 2 * x;
+ z = x + y;
+ y = x + z;
+ x = 9;
+ y = 10;
+}
+
+main ()
+{
+  int a = 1;
+  foo ();
+  a += 2;
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.mi/var-cmd.c b/gdb/testsuite/gdb.mi/var-cmd.c
new file mode 100644 (file)
index 0000000..42c2336
--- /dev/null
@@ -0,0 +1,296 @@
+struct _simple_struct {
+  int integer;
+  unsigned int unsigned_integer;
+  char character;
+  signed char signed_character;
+  char *char_ptr;
+  int array_of_10[10];
+};
+
+typedef struct _simple_struct simpleton;
+
+simpleton global_simple;
+
+enum foo {
+  bar = 1,
+  baz
+};
+
+typedef enum foo efoo;
+
+union named_union
+{
+  int integer;
+  char *char_ptr;
+};
+
+typedef struct _struct_decl {
+  int   integer;
+  char  character;
+  char *char_ptr;
+  long  long_int;
+  int  **int_ptr_ptr;
+  long  long_array[10];
+
+  void (*func_ptr) (void);
+  struct _struct_decl (*func_ptr_struct) (int, char *, long);
+  struct _struct_decl *(*func_ptr_ptr) (int, char *, long);
+  union {
+    int   a;
+    char *b;
+    long  c;
+    enum foo d;
+  } u1;
+
+  struct {
+    union {
+      struct {
+        int d;
+        char e[10];
+        int *(*func) (void);
+        efoo foo;
+      } u1s1;
+
+      long f;
+      struct {
+        char array_ptr[2];
+        int (*func) (int, char *);
+      } u1s2;
+    } u2;
+
+    int g;
+    char h;
+    long i[10];
+  } s2;
+} weird_struct;
+
+struct _struct_n_pointer {
+  char ****char_ptr;
+  long ****long_ptr;
+  struct _struct_n_pointer *ptrs[3];
+  struct _struct_n_pointer *next;
+};
+
+void do_locals_tests (void);
+void do_block_tests (void);
+void subroutine1 (int, long *);
+void nothing (void);
+void do_children_tests (void);
+void do_special_tests (void);
+void incr_a (char);
+
+void incr_a (char a)
+{
+  int b;
+  b = a;
+}
+
+void
+do_locals_tests ()
+{
+  int linteger;
+  int *lpinteger;
+  char lcharacter;
+  char *lpcharacter;
+  long llong;
+  long *lplong;
+  float lfloat;
+  float *lpfloat;
+  double ldouble;
+  double *lpdouble;
+  struct _simple_struct lsimple;
+  struct _simple_struct *lpsimple;
+  void (*func) (void);
+
+  /* Simple assignments */
+  linteger = 1234;
+  lpinteger = &linteger;
+  lcharacter = 'a';
+  lpcharacter = &lcharacter;
+  llong = 2121L;
+  lplong = &llong;
+  lfloat = 2.1;
+  lpfloat = &lfloat;
+  ldouble = 2.718281828459045;
+  lpdouble = &ldouble;
+  lsimple.integer = 1234;
+  lsimple.unsigned_integer = 255;
+  lsimple.character = 'a';
+  lsimple.signed_character = 21;
+  lsimple.char_ptr = &lcharacter;
+  lpsimple = &lsimple;
+  func = nothing;
+
+  /* Check pointers */
+  linteger = 4321;
+  lcharacter = 'b';
+  llong = 1212L;
+  lfloat = 1.2;
+  ldouble = 5.498548281828172;
+  lsimple.integer = 255;
+  lsimple.unsigned_integer = 4321;
+  lsimple.character = 'b';
+  lsimple.signed_character = 0;
+
+  subroutine1 (linteger, &llong);
+}
+
+void
+nothing ()
+{
+}
+
+void
+subroutine1 (int i, long *l)
+{
+  global_simple.integer = i + 3;
+  i = 212;
+  *l = 12;
+}
+
+void
+do_block_tests ()
+{
+  int cb = 12;
+
+  {
+    int foo;
+    foo = 123;
+    {
+      int foo2;
+      foo2 = 123;
+      {
+        int foo;
+        foo = 321;
+      }
+      foo2 = 0;
+    }
+    foo = 0;
+  }
+
+  cb = 21;
+}
+
+void
+do_children_tests (void)
+{
+  weird_struct *weird;
+  struct _struct_n_pointer *psnp;
+  struct _struct_n_pointer snp0, snp1, snp2;
+  char a0, *a1, **a2, ***a3;
+  char b0, *b1, **b2, ***b3;
+  char c0, *c1, **c2, ***c3;
+  long z0, *z1, **z2, ***z3;
+  long y0, *y1, **y2, ***y3;
+  long x0, *x1, **x2, ***x3;
+  int *foo;
+  int bar;
+
+  struct _struct_decl struct_declarations;
+  weird = &struct_declarations;
+
+  struct_declarations.integer = 123;
+  weird->char_ptr = "hello";
+  bar = 2121;
+  foo = &bar;
+  struct_declarations.int_ptr_ptr = &foo;
+  weird->long_array[0] = 1234;
+  struct_declarations.long_array[1] = 2345;
+  weird->long_array[2] = 3456;
+  struct_declarations.long_array[3] = 4567;
+  weird->long_array[4] = 5678;
+  struct_declarations.long_array[5] = 6789;
+  weird->long_array[6] = 7890;
+  struct_declarations.long_array[7] = 8901;
+  weird->long_array[8] = 9012;
+  struct_declarations.long_array[9] = 1234;
+
+  weird->func_ptr = nothing;
+
+  /* Struct/pointer/array tests */
+  a0 = '0';
+  a1 = &a0;
+  a2 = &a1;
+  a3 = &a2;
+  b0 = '1';
+  b1 = &b0;
+  b2 = &b1;
+  b3 = &b2;
+  c0 = '2';
+  c1 = &c0;
+  c2 = &c1;
+  c3 = &c2;
+  z0 = 0xdead + 0;
+  z1 = &z0;
+  z2 = &z1;
+  z3 = &z2;
+  y0 = 0xdead + 1;
+  y1 = &y0;
+  y2 = &y1;
+  y3 = &y2;
+  x0 = 0xdead + 2;
+  x1 = &x0;
+  x2 = &x1;
+  x3 = &x2;
+  snp0.char_ptr = &a3;
+  snp0.long_ptr = &z3;
+  snp0.ptrs[0] = &snp0;
+  snp0.ptrs[1] = &snp1;
+  snp0.ptrs[2] = &snp2;
+  snp0.next = &snp1;
+  snp1.char_ptr = &b3;
+  snp1.long_ptr = &y3;
+  snp1.ptrs[0] = &snp0;
+  snp1.ptrs[1] = &snp1;
+  snp1.ptrs[2] = &snp2;
+  snp1.next = &snp2;
+  snp2.char_ptr = &c3;
+  snp2.long_ptr = &x3;
+  snp2.ptrs[0] = &snp0;
+  snp2.ptrs[1] = &snp1;
+  snp2.ptrs[2] = &snp2;
+  snp2.next = 0x0;
+  psnp = &snp0;
+  snp0.char_ptr = &b3;
+  snp1.char_ptr = &c3;
+  snp2.char_ptr = &a3;
+  snp0.long_ptr = &y3;
+  snp1.long_ptr = &x3;
+  snp2.long_ptr = &z3;
+}
+
+void
+do_special_tests (void)
+{
+  union named_union u;
+  union {
+    int a;
+    char b;
+    long c;
+  } anonu;
+  struct _simple_struct s;
+  struct {
+    int a;
+    char b;
+    long c;
+  } anons;
+  enum foo e;
+  enum { A, B, C } anone;
+  int array[21];
+  int a;
+
+  a = 1;   
+  incr_a(2);
+}
+
+int
+main (int argc, char *argv [])
+{
+  do_locals_tests ();
+  do_block_tests ();
+  do_children_tests ();
+  do_special_tests ();
+  exit (0);
+}
+
+  
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
new file mode 100644 (file)
index 0000000..7d207df
--- /dev/null
@@ -0,0 +1,683 @@
+# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was based on a file written by Fred Fish. (fnf@cygnus.com)
+
+# Test setup routines that work with the MI interpreter.
+
+# The variable mi_gdb_prompt is a regexp which matches the gdb mi prompt.
+# Set it if it is not already set.
+global mi_gdb_prompt
+if ![info exists mi_gdb_prompt] then {
+    set mi_gdb_prompt "\[(\]gdb\[)\] \r\n"
+}
+
+set MIFLAGS "-i=mi"
+
+#
+# mi_gdb_exit -- exit the GDB, killing the target program if necessary
+#
+proc mi_gdb_exit {} {
+    catch mi_uncatched_gdb_exit
+}
+
+proc mi_uncatched_gdb_exit {} {
+    global GDB
+    global GDBFLAGS
+    global verbose
+    global gdb_spawn_id;
+    global gdb_prompt
+    global mi_gdb_prompt
+    global MIFLAGS
+
+    gdb_stop_suppressing_tests;
+
+    if { [info procs sid_exit] != "" } {
+       sid_exit
+    }
+
+    if ![info exists gdb_spawn_id] {
+       return;
+    }
+
+    verbose "Quitting $GDB $GDBFLAGS $MIFLAGS"
+
+    if { [is_remote host] && [board_info host exists fileid] } {
+       send_gdb "999-gdb-exit\n";
+       gdb_expect 10 {
+           -re "y or n" {
+               send_gdb "y\n";
+               exp_continue;
+           }
+            -re "Undefined command.*$gdb_prompt $" {
+                send_gdb "quit\n"
+               exp_continue;
+            }
+           -re "DOSEXIT code" { }
+           default { }
+       }
+    }
+
+    if ![is_remote host] {
+       remote_close host;
+    }
+    unset gdb_spawn_id
+}
+
+#
+# start gdb -- start gdb running, default procedure
+#
+# When running over NFS, particularly if running many simultaneous
+# tests on different hosts all using the same server, things can
+# get really slow.  Give gdb at least 3 minutes to start up.
+#
+proc mi_gdb_start { } {
+    global verbose
+    global GDB
+    global GDBFLAGS
+    global gdb_prompt
+    global mi_gdb_prompt
+    global timeout
+    global gdb_spawn_id;
+    global MIFLAGS
+
+    gdb_stop_suppressing_tests;
+
+    verbose "Spawning $GDB -nw $GDBFLAGS $MIFLAGS"
+
+    if [info exists gdb_spawn_id] {
+       return 0;
+    }
+
+    if ![is_remote host] {
+       if { [which $GDB] == 0 } then {
+           perror "$GDB does not exist."
+           exit 1
+       }
+    }
+    set res [remote_spawn host "$GDB -nw $GDBFLAGS $MIFLAGS [host_info gdb_opts]"];
+    if { $res < 0 || $res == "" } {
+       perror "Spawning $GDB failed."
+       return 1;
+    }
+    gdb_expect {
+       -re ".*UI_OUT.*$mi_gdb_prompt$" {
+           verbose "GDB initialized."
+       }
+       -re ".*$mi_gdb_prompt$" {
+           untested "Skip mi tests (output not in headless format)."
+           remote_close host;
+           return -1;
+       }
+       -re ".*$gdb_prompt $" {
+           untested "Skip mi tests (got non-mi prompt)."
+           remote_close host;
+           return -1;
+       }
+       timeout {
+           perror "(timeout) GDB never initialized after 10 seconds."
+           remote_close host;
+           return -1
+       }
+    }
+    set gdb_spawn_id -1;
+
+    # FIXME: mi output does not go through pagers, so these can be removed.
+    # force the height to "unlimited", so no pagers get used
+    send_gdb "100-gdb-set height 0\n"
+    gdb_expect 10 {
+       -re ".*100-gdb-set height 0\r\n100\\\^done\r\n$mi_gdb_prompt$" { 
+           verbose "Setting height to 0." 2
+       }
+       timeout {
+           warning "Couldn't set the height to 0"
+       }
+    }
+    # force the width to "unlimited", so no wraparound occurs
+    send_gdb "101-gdb-set width 0\n"
+    gdb_expect 10 {
+       -re ".*101-gdb-set width 0\r\n101\\\^done\r\n$mi_gdb_prompt$" {
+           verbose "Setting width to 0." 2
+       }
+       timeout {
+           warning "Couldn't set the width to 0."
+       }
+    }
+
+    # Finally start SID.
+    if { [info procs sid_start] != "" } {
+       verbose "Spawning SID"
+       sid_start
+    }
+
+    return 0;
+}
+
+# Many of the tests depend on setting breakpoints at various places and
+# running until that breakpoint is reached.  At times, we want to start
+# with a clean-slate with respect to breakpoints, so this utility proc 
+# lets us do this without duplicating this code everywhere.
+#
+
+proc mi_delete_breakpoints {} {
+    global mi_gdb_prompt
+
+# FIXME: The mi operation won't accept a prompt back and will use the 'all' arg
+    send_gdb "102-break-delete\n"
+    gdb_expect 30 {
+        -re "Delete all breakpoints.*y or n.*$" {
+           send_gdb "y\n";
+           exp_continue
+         }
+        -re ".*102-break-delete\r\n102\\\^done\r\n$mi_gdb_prompt$" {
+            # This happens if there were no breakpoints
+        }
+        timeout { perror "Delete all breakpoints in delete_breakpoints (timeout)" ; return }
+    }
+
+# The correct output is not "No breakpoints or watchpoints." but an
+# empty BreakpointTable. Also, a query is not acceptable with mi.
+    send_gdb "103-break-list\n"
+    gdb_expect 30 {
+        -re "103-break-list\r\n103\\\^done,BreakpointTable=\{\}\r\n$mi_gdb_prompt$" {}
+        -re "103-break-list\r\n103\\\^doneNo breakpoints or watchpoints.\r\n\r\n$mi_gdb_prompt$" {warning "Unexpected console text received"}
+        -re "$mi_gdb_prompt$" { perror "Breakpoints not deleted" ; return }
+        -re "Delete all breakpoints.*or n.*$" {
+           warning "Unexpected prompt for breakpoints deletion";
+           send_gdb "y\n";
+           exp_continue
+       }
+        timeout { perror "-break-list (timeout)" ; return }
+    }
+}
+
+proc mi_gdb_reinitialize_dir { subdir } {
+    global mi_gdb_prompt
+
+    global suppress_flag
+    if { $suppress_flag } {
+       return
+    }
+
+    if [is_remote host] {
+       return "";
+    }
+
+    send_gdb "104-environment-directory\n"
+    gdb_expect 60 {
+       -re ".*Reinitialize source path to empty.*y or n. " {
+            warning "Got confirmation prompt for dir reinitialization."
+           send_gdb "y\n"
+           gdb_expect 60 {
+               -re "$mi_gdb_prompt$" {}
+                timeout {error "Dir reinitialization failed (timeout)"}
+           }
+       }
+       -re "$mi_gdb_prompt$" {}
+        timeout {error "Dir reinitialization failed (timeout)"}
+    }
+
+    send_gdb "105-environment-directory $subdir\n"
+    gdb_expect 60 {
+       -re "Source directories searched.*$mi_gdb_prompt$" {
+           verbose "Dir set to $subdir"
+       }
+       -re "105\\\^done\r\n$mi_gdb_prompt$" {
+            # FIXME: We return just the prompt for now.
+           verbose "Dir set to $subdir"
+           # perror "Dir \"$subdir\" failed."
+       }
+    }
+}
+
+#
+# load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+proc mi_gdb_load { arg } {
+    global verbose
+    global loadpath
+    global loadfile
+    global GDB
+    global mi_gdb_prompt
+    upvar timeout timeout
+
+    # ``gdb_unload''
+
+    # ``gdb_file_cmd''
+# FIXME: Several of these patterns are only acceptable for console
+# output.  Queries are an error for mi.
+    send_gdb "105-file-exec-and-symbols $arg\n"
+    gdb_expect 120 {
+        -re "Reading symbols from.*done.*$mi_gdb_prompt$" {
+            verbose "\t\tLoaded $arg into the $GDB"
+            # All OK
+        }
+        -re "has no symbol-table.*$mi_gdb_prompt$" {
+            perror "$arg wasn't compiled with \"-g\""
+            return -1
+        }
+        -re "A program is being debugged already.*Kill it.*y or n. $" {
+            send_gdb "y\n"
+                verbose "\t\tKilling previous program being debugged"
+            exp_continue
+        }
+        -re "Load new symbol table from \".*\".*y or n. $" {
+            send_gdb "y\n"
+            gdb_expect 120 {
+                -re "Reading symbols from.*done.*$mi_gdb_prompt$" {
+                    verbose "\t\tLoaded $arg with new symbol table into $GDB"
+                    # All OK
+                }
+                timeout {
+                    perror "(timeout) Couldn't load $arg, other program already loaded."
+                    return -1
+                }
+            }
+       }
+        -re "No such file or directory.*$mi_gdb_prompt$" {
+            perror "($arg) No such file or directory\n"
+            return -1
+        }
+        -re "105-file-exec-and-symbols .*\r\n105\\\^done\r\n$mi_gdb_prompt$" {
+            # We are just giving the prompt back for now
+           # All OK
+            }
+        timeout {
+            perror "couldn't load $arg into $GDB (timed out)."
+            return -1
+        }
+        eof {
+            # This is an attempt to detect a core dump, but seems not to
+            # work.  Perhaps we need to match .* followed by eof, in which
+            # gdb_expect does not seem to have a way to do that.
+            perror "couldn't load $arg into $GDB (end of file)."
+            return -1
+        }
+    }
+    
+    # ``load''
+    if { [info procs send_target_sid] != "" } {
+       # For SID, things get complex
+       send_target_sid
+       gdb_expect 60 {
+           -re "\\^done,.*$mi_gdb_prompt$" {
+           }
+           timeout {
+               perror "Unable to connect to SID target"
+               return -1
+           }
+       }
+       send_gdb "48-target-download\n"
+       gdb_expect 10 {
+           -re "48\\^done.*$mi_gdb_prompt$" {
+           }
+           timeout {
+               perror "Unable to download to SID target"
+               return -1
+           }
+       }
+    } elseif { [target_info protocol] == "sim" } {
+       # For the simulator, just connect to it directly.
+       send_gdb "47-target-select sim\n"
+       gdb_expect 10 {
+           -re "47\\^connected.*$mi_gdb_prompt$" {
+           }
+           timeout {
+               perror "Unable to select sim target"
+               return -1
+           }
+       }
+       send_gdb "48-target-download\n"
+       gdb_expect 10 {
+           -re "48\\^done.*$mi_gdb_prompt$" {
+           }
+           timeout {
+               perror "Unable to download to sim target"
+               return -1
+           }
+       }
+    }
+    return 0
+}
+
+# mi_gdb_test COMMAND PATTERN MESSAGE -- send a command to gdb; test the result.
+#
+# COMMAND is the command to execute, send to GDB with send_gdb.  If
+#   this is the null string no command is sent.
+# PATTERN is the pattern to match for a PASS, and must NOT include
+#   the \r\n sequence immediately before the gdb prompt.
+# MESSAGE is an optional message to be printed.  If this is
+#   omitted, then the pass/fail messages use the command string as the
+#   message.  (If this is the empty string, then sometimes we don't
+#   call pass or fail at all; I don't understand this at all.)
+#
+# Returns:
+#    1 if the test failed,
+#    0 if the test passes,
+#   -1 if there was an internal error.
+#  
+proc mi_gdb_test { args } {
+    global verbose
+    global mi_gdb_prompt
+    global GDB
+    upvar timeout timeout
+
+    if [llength $args]>2 then {
+       set message [lindex $args 2]
+    } else {
+       set message [lindex $args 0]
+    }
+    set command [lindex $args 0]
+    set pattern [lindex $args 1]
+
+    if [llength $args]==5 {
+       set question_string [lindex $args 3];
+       set response_string [lindex $args 4];
+    } else {
+       set question_string "^FOOBAR$"
+    }
+
+    if $verbose>2 then {
+       send_user "Sending \"$command\" to gdb\n"
+       send_user "Looking to match \"$pattern\"\n"
+       send_user "Message is \"$message\"\n"
+    }
+
+    set result -1
+    set string "${command}\n";
+    if { $command != "" } {
+       while { "$string" != "" } {
+           set foo [string first "\n" "$string"];
+           set len [string length "$string"];
+           if { $foo < [expr $len - 1] } {
+               set str [string range "$string" 0 $foo];
+               if { [send_gdb "$str"] != "" } {
+                   global suppress_flag;
+
+                   if { ! $suppress_flag } {
+                       perror "Couldn't send $command to GDB.";
+                   }
+                   fail "$message";
+                   return $result;
+               }
+               gdb_expect 2 {
+                   -re "\[\r\n\]" { }
+                   timeout { }
+               }
+               set string [string range "$string" [expr $foo + 1] end];
+           } else {
+               break;
+           }
+       }
+       if { "$string" != "" } {
+           if { [send_gdb "$string"] != "" } {
+               global suppress_flag;
+
+               if { ! $suppress_flag } {
+                   perror "Couldn't send $command to GDB.";
+               }
+               fail "$message";
+               return $result;
+           }
+       }
+    }
+
+    if [info exists timeout] {
+       set tmt $timeout;
+    } else {
+       global timeout;
+       if [info exists timeout] {
+           set tmt $timeout;
+       } else {
+           set tmt 60;
+       }
+    }
+    gdb_expect $tmt {
+        -re "\\*\\*\\* DOSEXIT code.*" {
+            if { $message != "" } {
+                fail "$message";
+            }
+            gdb_suppress_entire_file "GDB died";
+            return -1;
+        }
+        -re "Ending remote debugging.*$mi_gdb_prompt\[ \]*$" {
+           if ![isnative] then {
+               warning "Can`t communicate to remote target."
+           }
+           gdb_exit
+           gdb_start
+           set result -1
+       }
+        -re "(${question_string})$" {
+           send_gdb "$response_string\n";
+           exp_continue;
+       }
+        -re "Undefined.* command:.*$mi_gdb_prompt\[ \]*$" {
+           perror "Undefined command \"$command\"."
+            fail "$message"
+           set result 1
+       }
+        -re "Ambiguous command.*$mi_gdb_prompt\[ \]*$" {
+           perror "\"$command\" is not a unique command name."
+            fail "$message"
+           set result 1
+       }
+        -re "\[\r\n\]*($pattern)\[\r\n\]+$mi_gdb_prompt\[ \]*$" {
+           if ![string match "" $message] then {
+               pass "$message"
+           }
+           set result 0
+       }
+        -re "Program exited with code \[0-9\]+.*$mi_gdb_prompt\[ \]*$" {
+           if ![string match "" $message] then {
+               set errmsg "$message: the program exited"
+           } else {
+               set errmsg "$command: the program exited"
+           }
+           fail "$errmsg"
+           return -1
+       }
+        -re "The program is not being run.*$mi_gdb_prompt\[ \]*$" {
+           if ![string match "" $message] then {
+               set errmsg "$message: the program is no longer running"
+           } else {
+               set errmsg "$command: the program is no longer running"
+           }
+           fail "$errmsg"
+           return -1
+       }
+        -re ".*$mi_gdb_prompt\[ \]*$" {
+           if ![string match "" $message] then {
+               fail "$message"
+           }
+           set result 1
+       }
+        "<return>" {
+           send_gdb "\n"
+           perror "Window too small."
+            fail "$message"
+       }
+        -re "\\(y or n\\) " {
+           send_gdb "n\n"
+           perror "Got interactive prompt."
+            fail "$message"
+       }
+        eof {
+            perror "Process no longer exists"
+            if { $message != "" } {
+                fail "$message"
+            }
+            return -1
+       }
+        full_buffer {
+           perror "internal buffer is full."
+            fail "$message"
+       }
+       timeout {
+           if ![string match "" $message] then {
+               fail "$message (timeout)"
+           }
+           set result 1
+       }
+    }
+    return $result
+}
+
+#
+# MI run command.  (A modified version of gdb_run_cmd)
+#
+
+# In patterns, the newline sequence ``\r\n'' is matched explicitly as
+# ``.*$'' could swallow up output that we attempt to match elsewhere.
+
+proc mi_run_cmd {args} {
+    global suppress_flag
+    if { $suppress_flag } {
+       return -1
+    }
+    global mi_gdb_prompt
+
+    if [target_info exists gdb_init_command] {
+       send_gdb "[target_info gdb_init_command]\n";
+       gdb_expect 30 {
+           -re "$mi_gdb_prompt$" { }
+           default {
+               perror "gdb_init_command for target failed";
+               return;
+           }
+       }
+    }
+
+    if [target_info exists use_gdb_stub] {
+       if [target_info exists gdb,do_reload_on_run] {
+           # Specifying no file, defaults to the executable
+           # currently being debugged.
+           if { [mi_gdb_load ""] < 0 } {
+               return;
+           }
+           send_gdb "000-exec-continue\n";
+           gdb_expect 60 {
+               -re "Continu\[^\r\n\]*\[\r\n\]" {}
+               default {}
+           }
+           return;
+       }
+    }
+
+    send_gdb "000-exec-run $args\n"
+    gdb_expect {
+       -re "000\\^running\r\n${mi_gdb_prompt}" {
+       }
+       timeout {
+           perror "Unable to start target"
+           return
+       }
+    }
+    # NOTE: Shortly after this there will be a ``000*stopping,...(gdb)''
+}
+
+#
+# Just like run-to-main but works with the MI interface
+#
+
+proc mi_run_to_main { } {
+    global suppress_flag
+    if { $suppress_flag } {
+       return -1
+    }
+
+    global mi_gdb_prompt
+    global hex
+    global decimal
+    global srcdir
+    global subdir
+    global binfile
+    global srcfile
+
+    set test "mi run-to-main"
+    mi_delete_breakpoints
+    mi_gdb_reinitialize_dir $srcdir/$subdir
+    mi_gdb_load ${binfile}
+
+    mi_gdb_test "200-break-insert main" \
+           "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*\",line=\"\[0-9\]*\",times=\"0\"\}" \
+           "breakpoint at main"
+
+    mi_run_cmd
+    gdb_expect {
+       -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
+           pass "$test"
+           return 0
+       }
+       timeout {
+           fail "$test (timeout)"
+           return -1
+       }
+    }
+}
+
+
+# Next to the next statement
+
+proc mi_next { test } {
+    global suppress_flag
+    if { $suppress_flag } {
+       return -1
+    }
+    global mi_gdb_prompt
+    send_gdb "220-exec-next\n"
+    gdb_expect {
+       -re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"end-stepping-range\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\{.*\},,file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
+           pass "$test"
+           return 0
+       }
+       timeout {
+           fail "$test"
+           return -1
+       }
+    }
+}
+
+
+# Step to the next statement
+
+proc mi_step { test } {
+    global suppress_flag
+    if { $suppress_flag } {
+       return -1
+    }
+    global mi_gdb_prompt
+    send_gdb "220-exec-step\n"
+    gdb_expect {
+       -re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"end-stepping-range\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\{.*\},,file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
+           pass "$test"
+           return 0
+       }
+       timeout {
+           fail "$test"
+           return -1
+       }
+    }
+}
+
+
+# Local variables: 
+# change-log-default-name: "../gdb.mi/ChangeLog-mi"
+# End: 
index 9747d49..6bd7648 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -801,6 +801,17 @@ gdb_init (argv0)
   uiout = cli_out_new (gdb_stdout);
 #endif
 
+#ifdef UI_OUT
+  /* All the interpreters should have had a look at things by now.
+     Initialize the selected interpreter. */
+  if (interpreter_p && !init_ui_hook)
+    {
+      fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n",
+                         interpreter_p);
+      exit (1);
+    }
+#endif
+
   if (init_ui_hook)
     init_ui_hook (argv0);
 }