* Makefile.in (INSTALLED_LIBS, CLIBS, DEPFILES): Add support for
authorStu Grossman <grossman@cygnus>
Thu, 28 Jul 1994 22:07:02 +0000 (22:07 +0000)
committerStu Grossman <grossman@cygnus>
Thu, 28 Jul 1994 22:07:02 +0000 (22:07 +0000)
--enable-xxx configure option by adding ENABLE_{CLIBS DEPFILES}
where appropriate.

* General hackery to support alternate user-interface.
* breakpoint.c (mention, delete_breakpoint, enable_breakpoint,
disable_breakpoint):  Call hooks for alternate user-interface.
* defs.h:  Add declarations for alternate user-interface hooks.
* main.c (main):  Add --nw (and --nowindows) options to disable
the GUI.
* (near call to command_loop):  Call command_loop_hook if set.
* (fputs_unfiltered):  Call fputs_unfiltered_hook if set.
* stack.c:  Call print_frame_info_listing_hook if set.
* top.c (gdb_init):  Initialize targets.c and utils.c prior to
other files to make sure that calls to error and warning will
work.  Call init_ui_hook after everything else.
* utils.c (query):  Call query_hook if set.
* (gdb_flush):  Call flush_hook if set.
* Change _initialize_utils to initialize_utils cuz we don't use
automatic initialization of utils.c anymore.

* Support for TK GUI.
* Makefile.in:  Add rule for gdbtk.o.
* configure.in:  Add support for --enable-gdbtk.
* gdbtk.c:  New file.  Contains support routines for TK interface.
* gdbtk.tcl:  New file.  Implements GUI policy.

* remote.c:  Get rid of #ifdef DONT_USE_REMOTE.  It's no longer
necessary.

gdb/ChangeLog
gdb/Makefile.in
gdb/breakpoint.c
gdb/configure.in
gdb/defs.h
gdb/gdbtk.c [new file with mode: 0644]
gdb/gdbtk.tcl [new file with mode: 0644]
gdb/main.c
gdb/remote.c
gdb/top.c

index 1c78a09a9a5c19477205e133ee35742e914664af..07455cb2de062e38b2fdc2c286d4e0c5f71b33eb 100644 (file)
@@ -1,3 +1,35 @@
+Thu Jul 28 14:37:36 1994  Stu Grossman  (grossman@cygnus.com)
+
+       * Makefile.in (INSTALLED_LIBS, CLIBS, DEPFILES):  Add support for
+       --enable-xxx configure option by adding ENABLE_{CLIBS DEPFILES}
+       where appropriate.
+
+       * General hackery to support alternate user-interface.
+       * breakpoint.c (mention, delete_breakpoint, enable_breakpoint,
+       disable_breakpoint):  Call hooks for alternate user-interface.
+       * defs.h:  Add declarations for alternate user-interface hooks.
+       * main.c (main):  Add --nw (and --nowindows) options to disable
+       the GUI.
+       * (near call to command_loop):  Call command_loop_hook if set.
+       * (fputs_unfiltered):  Call fputs_unfiltered_hook if set.
+       * stack.c:  Call print_frame_info_listing_hook if set.
+       * top.c (gdb_init):  Initialize targets.c and utils.c prior to
+       other files to make sure that calls to error and warning will
+       work.  Call init_ui_hook after everything else.
+       * utils.c (query):  Call query_hook if set.
+       * (gdb_flush):  Call flush_hook if set.
+       * Change _initialize_utils to initialize_utils cuz we don't use
+       automatic initialization of utils.c anymore.
+
+       * Support for TK GUI.
+       * Makefile.in:  Add rule for gdbtk.o.
+       * configure.in:  Add support for --enable-gdbtk.
+       * gdbtk.c:  New file.  Contains support routines for TK interface.
+       * gdbtk.tcl:  New file.  Implements GUI policy.
+
+       * remote.c:  Get rid of #ifdef DONT_USE_REMOTE.  It's no longer
+       necessary.
+
 Thu Jul 28 14:52:01 1994  J.T. Conklin  (jtc@phishhead.cygnus.com)
 
        * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Use newlib if it is
index ca2c5008b77eb34a7da65d377230c72151c29660..cfbbd188247ac6158f5e985debc8fd092dbc21bf 100644 (file)
@@ -169,9 +169,10 @@ REGEX1 = regex.o
 # If you have the Cygnus libraries installed,
 # you can use 'CLIBS=$(INSTALLED_LIBS)' 'CDEPS='
 INSTALLED_LIBS=-lbfd -lreadline $(TERMCAP) -lopcodes -lmmalloc \
-       -liberty $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS)
+       -liberty $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(ENABLE_CLIBS)
 CLIBS = $(BFD) $(READLINE) $(OPCODES) $(MMALLOC) \
-       $(LIBIBERTY) $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS)
+       $(LIBIBERTY) $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) \
+       $(ENABLE_CLIBS)
 CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) \
        $(BFD) $(READLINE) $(OPCODES) $(MMALLOC) $(LIBIBERTY)
 
@@ -454,7 +455,8 @@ TARDIRS = doc gdbserver sparclite
 # variables analogous to SER_HARDWIRE which get defaulted in this
 # Makefile.in
 
-DEPFILES = $(TDEPFILES) $(XDEPFILES) $(SER_HARDWIRE) $(NATDEPFILES) $(REMOTE_O)
+DEPFILES = $(TDEPFILES) $(XDEPFILES) $(SER_HARDWIRE) $(NATDEPFILES) $(REMOTE_O) \
+          $(ENABLE_DEPFILES)
 
 SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES)
 # Don't include YYFILES (*.tab.c) because we already include *.y in SFILES,
@@ -1204,6 +1206,11 @@ findvar.o: findvar.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h
 fork-child.o: fork-child.c $(wait_h) $(defs_h) $(gdbcore_h) \
        $(inferior_h) target.h terminal.h thread.h
 
+gdbtk.o: gdbtk.c $(defs_h) $(symtab_h) $(inferior_h) $(command_h) \
+       $(bfd_h) symfile.h objfiles.h target.h
+       $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/gdbtk.c \
+                -DGDBTK_FILENAME=\"$(libdir)/gdbtk.tcl\"
+
 gdbtypes.o: gdbtypes.c $(bfd_h) complaints.h $(defs_h) $(expression_h) \
        $(gdbtypes_h) language.h objfiles.h symfile.h $(symtab_h) target.h \
        $(value_h)
index acdeff2798e82da360c2b0359a2d7da577542e4b..a23afd442f2c13d73644690fd949d30ae13020aa 100644 (file)
@@ -2149,6 +2149,9 @@ mention (b)
 {
   int say_where = 0;
 
+  if (create_breakpoint_hook)
+    create_breakpoint_hook (b);
+
   switch (b->type)
     {
     case bp_watchpoint:
@@ -3181,6 +3184,9 @@ delete_breakpoint (bpt)
   register struct breakpoint *b;
   register bpstat bs;
 
+  if (delete_breakpoint_hook)
+    delete_breakpoint_hook (bpt);
+
   if (bpt->inserted)
     remove_breakpoint (bpt);
       
@@ -3539,6 +3545,9 @@ enable_breakpoint (bpt)
   int target_resources_ok, other_type_used;
   struct value *mark;
   
+  if (enable_breakpoint_hook)
+    enable_breakpoint_hook (bpt);
+
   if (bpt->type == bp_hardware_breakpoint)
     {
       int i;
@@ -3644,6 +3653,9 @@ disable_breakpoint (bpt)
   if (bpt->type == bp_watchpoint_scope)
     return;
 
+  if (disable_breakpoint_hook)
+    disable_breakpoint_hook (bpt);
+
   bpt->enable = disabled;
 
   breakpoints_changed ();
index f52ce11952eb91dc105e1ee1dfa0dad471590ea0..c8e77752d4cac9277981a29a87fc7632123d11cb 100644 (file)
@@ -397,6 +397,12 @@ else
        links="${links} nm.h"
 fi
 
+# Make it possible to use the GUI without doing a full install
+if [ "${enable_gdbtk}" = "yes" ] ; then
+       files="${files} gdbtk.tcl"
+       links="${links} gdbtk.tcl"
+fi
+
 # post-target:
 
 case ${srcdir} in
@@ -413,6 +419,15 @@ if [ "${nativefile}" = "" ] ; then
        mv -f Makefile.tem Makefile
 fi
 
+if [ "${enable_gdbtk}" = "yes" ] ; then
+       sed -e '/# End of host and/i\
+\
+ENABLE_DEPFILES = gdbtk.o\
+ENABLE_CLIBS = -ltcl -ltk -lX11 -lm
+' < Makefile > Makefile.tem
+       mv -f Makefile.tem Makefile
+fi
+
 sed -e '/^TM_FILE[     ]*=/s,^TM_FILE[         ]*=[    ]*,&config/'"${gdb_target_cpu}"'/,
 /^XM_FILE[     ]*=/s,^XM_FILE[         ]*=[    ]*,&config/'"${gdb_host_cpu}"'/,
 /^NAT_FILE[    ]*=/s,^NAT_FILE[        ]*=[    ]*,&config/'"${gdb_host_cpu}"'/,' <Makefile >Makefile.tmp
index 4b7b0c379e62e223fb749167bd5d408504aaf05c..6bbf019cff25bb1406c25f882ac51107c229e14c 100644 (file)
@@ -92,7 +92,8 @@ enum language
    language_c,                         /* C */
    language_cplus,             /* C++ */
    language_chill,             /* Chill */
-   language_m2                 /* Modula-2 */
+   language_m2,                        /* Modula-2 */
+   language_asm                        /* Assembly language */
 };
 
 /* the cleanup list records things that have to be undone
@@ -342,9 +343,6 @@ command_line_input PARAMS ((char *, int, char *));
 extern void
 print_prompt PARAMS ((void));
 
-extern int
-batch_mode PARAMS ((void));
-
 extern int
 input_from_terminal_p PARAMS ((void));
 
@@ -357,7 +355,7 @@ extern void
 print_address_symbolic PARAMS ((CORE_ADDR, GDB_FILE *, int, char *));
 
 extern void
-print_address_numeric PARAMS ((CORE_ADDR, GDB_FILE *));
+print_address_numeric PARAMS ((CORE_ADDR, int, GDB_FILE *));
 
 extern void
 print_address PARAMS ((CORE_ADDR, GDB_FILE *));
@@ -941,4 +939,27 @@ push_word PARAMS ((CORE_ADDR, unsigned LONGEST));
 #define MAINTENANCE_CMDS 1
 #endif
 
+/* Hooks for alternate command interfaces.  */
+
+#ifdef __STDC__
+struct symtab;
+struct breakpoint;
+#endif
+
+void (*init_ui_hook) PARAMS ((void));
+void (*command_loop_hook) PARAMS ((void));
+void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer));
+void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, int line,
+                                              int stopline, int noerror));
+int (*query_hook) PARAMS (());
+void (*flush_hook) PARAMS ((FILE *stream));
+void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b));
+void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
+void (*enable_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
+void (*disable_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
+
+/* Inhibit window interface if non-zero. */
+
+extern int no_windows;
+
 #endif /* !defined (DEFS_H) */
diff --git a/gdb/gdbtk.c b/gdb/gdbtk.c
new file mode 100644 (file)
index 0000000..4746f2a
--- /dev/null
@@ -0,0 +1,424 @@
+/* TK interface routines.
+   Copyright 1994 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "inferior.h"
+#include "command.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "target.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <varargs.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/filio.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/errno.h>
+#include <termios.h>
+#include <string.h>
+#include <tcl.h>
+#include <tk.h>
+
+/* Non-zero means that we're doing the gdbtk interface. */
+int gdbtk = 0;
+
+/* Non-zero means we are reloading breakpoints, etc from the
+   Gdbtk kernel, and we should suppress various messages */
+static int gdbtk_reloading = 0;
+
+/* Handle for TCL interpreter */
+static Tcl_Interp *interp = NULL;
+
+/* Handle for TK main window */
+static Tk_Window mainWindow = NULL;
+
+static void
+null_routine(arg)
+     int arg;
+{
+}
+
+\f
+/* This routine redirects the output of fputs_unfiltered so that
+   the user can see what's going on in his debugger window. */
+
+static void
+gdbtk_fputs (ptr)
+     const char *ptr;
+{
+  Tcl_VarEval (interp, "gdbtk_tcl_fputs ", "{", ptr, "}", NULL);
+}
+
+static void
+gdbtk_flush (stream)
+     FILE *stream;
+{
+  Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
+}
+
+static int
+gdbtk_query (args)
+     va_list args;
+{
+  char *query;
+  char buf[200];
+  long val;
+
+  query = va_arg (args, char *);
+
+  vsprintf(buf, query, args);
+  Tcl_VarEval (interp, "gdbtk_tcl_query ", "{", buf, "}", NULL);
+
+  val = atol (interp->result);
+  return val;
+}
+\f
+static char *
+full_filename(symtab)
+     struct symtab *symtab;
+{
+  int pathlen;
+  char *filename;
+
+  if (!symtab)
+    return NULL;
+
+  if (symtab->fullname)
+    return savestring(symtab->fullname, strlen(symtab->fullname));
+
+  if (symtab->filename[0] == '/')
+    return savestring(symtab->filename, strlen(symtab->filename));
+
+  if (symtab->dirname)
+    pathlen = strlen(symtab->dirname);
+  else
+    pathlen = 0;
+  if (symtab->filename)
+    pathlen += strlen(symtab->filename);
+
+  filename = xmalloc(pathlen+1);
+
+  if (symtab->dirname)
+    strcpy(filename, symtab->dirname);
+  else
+    *filename = '\000';
+  if (symtab->filename)
+    strcat(filename, symtab->filename);
+
+  return filename;
+}
+\f
+static void
+breakpoint_notify(b, action)
+     struct breakpoint *b;
+     const char *action;
+{
+  struct symbol *sym;
+  char bpnum[50], line[50];
+  struct symtab_and_line sal;
+  char *filename;
+  int v;
+
+  if (b->type != bp_breakpoint)
+    return;
+
+  sal = find_pc_line (b->address, 0);
+
+  filename = full_filename (sal.symtab);
+
+  sprintf (bpnum, "%d", b->number);
+  sprintf (line, "%d", sal.line);
+  v = Tcl_VarEval (interp,
+                  "gdbtk_tcl_breakpoint ",
+                  action,
+                  " ", bpnum,
+                  " ", filename,
+                  " ", line,
+                  NULL);
+
+  if (v != TCL_OK)
+    {
+      gdbtk_fputs (interp->result);
+      gdbtk_fputs ("\n");
+    }
+
+  if (filename)
+    free (filename);
+}
+
+static void
+gdbtk_create_breakpoint(b)
+     struct breakpoint *b;
+{
+  breakpoint_notify(b, "create");
+}
+
+static void
+gdbtk_delete_breakpoint(b)
+     struct breakpoint *b;
+{
+  breakpoint_notify(b, "delete");
+}
+
+static void
+gdbtk_enable_breakpoint(b)
+     struct breakpoint *b;
+{
+  breakpoint_notify(b, "enable");
+}
+
+static void
+gdbtk_disable_breakpoint(b)
+     struct breakpoint *b;
+{
+  breakpoint_notify(b, "disable");
+}
+\f
+/* This implements the TCL command `gdb_loc', which returns a list consisting
+   of the source and line number associated with the current pc. */
+
+static int
+gdb_loc (clientData, interp, argc, argv)
+     ClientData clientData;
+     Tcl_Interp *interp;
+     int argc;
+     char *argv[];
+{
+  char *filename;
+  char buf[100];
+  struct symtab_and_line sal;
+  char *funcname;
+
+  if (argc == 1)
+    {
+      struct frame_info *frame;
+      struct symbol *func;
+      CORE_ADDR pc;
+
+      frame = get_frame_info (selected_frame);
+      pc = frame ? frame->pc : stop_pc;
+      func = find_pc_function (pc);
+      funcname = func ? SYMBOL_NAME (func) : "";
+      sal = find_pc_line (pc, 0);
+    }
+  else if (argc == 2)
+    {
+      struct cleanup *old_chain;
+      struct symtabs_and_lines sals;
+
+      sals = decode_line_spec (argv[1], 1);
+
+      if (sals.nelts != 1)
+       {
+         Tcl_SetResult (interp, "Ambiguous line spec", TCL_STATIC);
+         free (sals.sals);
+         return TCL_ERROR;
+       }
+
+      sal = sals.sals[0];
+      free (sals.sals);
+      funcname = "*";
+    }
+  else
+    {
+      Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
+      return TCL_ERROR;
+    }
+
+  filename = full_filename (sal.symtab);
+
+  sprintf (buf, "%d", sal.line);
+
+  if (sal.symtab)
+    Tcl_AppendElement (interp, sal.symtab->filename);
+  else
+    Tcl_AppendElement (interp, "");
+  Tcl_AppendElement (interp, funcname);
+  Tcl_AppendElement (interp, filename);
+  Tcl_AppendElement (interp, buf); /* line number */
+
+  if (filename)
+    free(filename);
+
+  return TCL_OK;
+}
+\f
+static int
+gdb_cmd_stub (cmd)
+     char *cmd;
+{
+  execute_command (cmd, 1);
+
+  return 1;                    /* Indicate success */
+}
+
+/* This implements the TCL command `gdb_cmd', which sends it's argument into
+   the GDB command scanner.  */
+
+static int
+gdb_cmd (clientData, interp, argc, argv)
+     ClientData clientData;
+     Tcl_Interp *interp;
+     int argc;
+     char *argv[];
+{
+  int val;
+  struct cleanup *old_chain;
+
+  if (argc != 2)
+    {
+      Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
+      return TCL_ERROR;
+    }
+
+  old_chain = make_cleanup (null_routine, 0);
+
+  val = catch_errors (gdb_cmd_stub, argv[1], "", RETURN_MASK_ERROR);
+
+  bpstat_do_actions (&stop_bpstat);
+  do_cleanups (old_chain);
+
+  /* We could base the return value on val, but that would require most users
+     to use catch.  Since GDB errors are already being handled elsewhere, I
+     see no reason to pass them up to the caller. */
+
+  return TCL_OK;
+}
+
+static int
+gdb_listfiles (clientData, interp, argc, argv)
+     ClientData clientData;
+     Tcl_Interp *interp;
+     int argc;
+     char *argv[];
+{
+  int val;
+  struct objfile *objfile;
+  struct partial_symtab *psymtab;
+
+  ALL_PSYMTABS (objfile, psymtab)
+    Tcl_AppendElement (interp, psymtab->filename);
+
+  return TCL_OK;
+}
+\f
+static void
+tk_command (cmd, from_tty)
+     char *cmd;
+     int from_tty;
+{
+  Tcl_VarEval (interp, cmd, NULL);
+
+  gdbtk_fputs (interp->result);
+  gdbtk_fputs ("\n");
+}
+
+static void
+cleanup_init (ignored)
+     int ignored;
+{
+  if (mainWindow != NULL)
+    Tk_DestroyWindow (mainWindow);
+  mainWindow = NULL;
+
+  if (interp != NULL)
+    Tcl_DeleteInterp (interp);
+  interp = NULL;
+}
+
+static void
+gdbtk_init ()
+{
+  struct cleanup *old_chain;
+  char *gdbtk_filename;
+
+  old_chain = make_cleanup (cleanup_init, 0);
+
+  /* First init tcl and tk. */
+
+  interp = Tcl_CreateInterp ();
+
+  if (!interp)
+    error ("Tcl_CreateInterp failed");
+
+  mainWindow = Tk_CreateMainWindow (interp, NULL, "gdb", "Gdb");
+
+  if (!mainWindow)
+    return;                    /* DISPLAY probably not set */
+
+  if (Tcl_Init(interp) != TCL_OK)
+    error ("Tcl_Init failed: %s", interp->result);
+
+  if (Tk_Init(interp) != TCL_OK)
+    error ("Tk_Init failed: %s", interp->result);
+
+  Tcl_CreateCommand (interp, "gdb_cmd", gdb_cmd, NULL, NULL);
+  Tcl_CreateCommand (interp, "gdb_loc", gdb_loc, NULL, NULL);
+  Tcl_CreateCommand (interp, "gdb_listfiles", gdb_listfiles, NULL, NULL);
+
+  gdbtk_filename = getenv ("GDBTK_FILENAME");
+  if (gdbtk_filename)
+    {
+      if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK)
+       error ("Failure reading %s: %s", gdbtk_filename, interp->result);
+    }
+  else
+    {
+      if (Tcl_EvalFile (interp, "gdbtk.tcl") != TCL_OK)
+       {
+         Tcl_ResetResult (interp);
+         if (Tcl_EvalFile (interp, GDBTK_FILENAME) != TCL_OK)
+           error ("Failure reading %s: %s", GDBTK_FILENAME, interp->result);
+       }
+    }
+
+  command_loop_hook = Tk_MainLoop;
+  fputs_unfiltered_hook = gdbtk_fputs;
+  print_frame_info_listing_hook = null_routine;
+  query_hook = gdbtk_query;
+  flush_hook = gdbtk_flush;
+  create_breakpoint_hook = gdbtk_create_breakpoint;
+  delete_breakpoint_hook = gdbtk_delete_breakpoint;
+  enable_breakpoint_hook = gdbtk_enable_breakpoint;
+  disable_breakpoint_hook = gdbtk_disable_breakpoint;
+
+  discard_cleanups (old_chain);
+
+  add_com ("tk", class_obscure, tk_command,
+          "Send a command directly into tk.");
+}
+
+/* Come here during initialze_all_files () */
+
+void
+_initialize_gdbtk ()
+{
+  if (no_windows)
+    return;
+
+  /* Tell the rest of the world that Gdbtk is now set up. */
+
+  init_ui_hook = gdbtk_init;
+}
diff --git a/gdb/gdbtk.tcl b/gdb/gdbtk.tcl
new file mode 100644 (file)
index 0000000..425041e
--- /dev/null
@@ -0,0 +1,399 @@
+# GDB GUI setup
+
+set cfile Blank
+set wins($cfile) .text
+set current_label {}
+set screen_height 0
+set screen_top 0
+set screen_bot 0
+
+proc test {} {
+       update_listing {termcap.c foo /etc/termcap 200}
+}
+
+proc echo string {puts stdout $string}
+
+proc gdbtk_tcl_fputs {arg} {
+       .command.text insert end "$arg"
+       .command.text yview -pickplace end
+}
+
+proc gdbtk_tcl_flush {} {update idletasks}
+
+proc gdbtk_tcl_query {message} {
+       tk_dialog .query "gdb : query" "$message" {} 1 "No" "Yes"
+       }
+
+if [info exists env(EDITOR)] then {
+       set editor $env(EDITOR)
+       } else {
+       set editor emacs
+}
+
+proc gdbtk_tcl_start_variable_annotation {valaddr ref_type stor_cl cum_expr field type_cast} {
+       echo "gdbtk_tcl_start_variable_annotation $valaddr $ref_type $stor_cl $cum_expr $field $type_cast"
+}
+
+proc gdbtk_tcl_end_variable_annotation {} {
+       echo gdbtk_tcl_end_variable_annotation
+}
+
+proc insert_breakpoint_tag {win line} {
+       $win configure -state normal
+       $win delete $line.0
+       $win insert $line.0 "B"
+       $win tag add $line $line.0
+       $win tag bind $line <1> {
+#              echo "tag %W %X %Y %x"
+#              echo "tag names [$wins($cfile) tag names]"
+       }
+
+       $win configure -state disabled
+}
+
+proc delete_breakpoint_tag {win line} {
+       $win configure -state normal
+       $win delete $line.0
+       $win insert $line.0 " "
+       $win tag delete $line
+       $win configure -state disabled
+}
+
+# Callback from GDB to notify us of breakpoint creation.
+
+proc create_breakpoint {bpnum file line} {
+       global wins
+       global breakpoint_file
+       global breakpoint_line
+
+# Record breakpoint locations
+
+       set breakpoint_file($bpnum) $file
+       set breakpoint_line($bpnum) $line
+       
+# If there isn't a window for this file, don't try to update it
+
+       if [info exists wins($file)] {
+               insert_breakpoint_tag $wins($file) $line
+       }
+}
+
+proc delete_breakpoint {bpnum file line} {
+       global wins
+       global breakpoint_file
+       global breakpoint_line
+
+# Save line number for later
+
+       set line $breakpoint_line($bpnum)
+
+# Reset breakpoint annotation info
+
+       unset breakpoint_file($bpnum)
+       unset breakpoint_line($bpnum)
+
+# If there isn't a window for this file, don't try to update it
+
+       if [info exists wins($file)] {
+               delete_breakpoint_tag $wins($file) $line
+       }
+}
+
+# This is a callback from C code to notify us of breakpoint changes.  ACTION
+# can be one of create, delete, enable, or disable.
+
+proc gdbtk_tcl_breakpoint {action bpnum file line} {
+       ${action}_breakpoint $bpnum $file $line
+}
+
+# Create the popup listing window menu
+
+menu .breakpoint -cursor hand2
+.breakpoint add command -label Break
+.breakpoint add separator
+.breakpoint add command -label "Edit" -command {exec $editor +$selected_line $selected_file &}
+.breakpoint add command -label "Set breakpoint" -command {gdb_cmd "break $selected_file:$selected_line"}
+#.breakpoint add command -label "Clear breakpoint" -command {echo "Clear"}
+#.breakpoint add command -label "Enable breakpoint" -command {echo "Enable"}
+#.breakpoint add command -label "Disable breakpoint" -command {echo "Disable"}
+
+# Come here when button is released in the popup menu
+
+bind .breakpoint <Any-ButtonRelease-1> {
+       global selected_win
+
+# First, remove the menu, and release the pointer
+
+       .breakpoint unpost
+       grab release .breakpoint
+
+# Unhighlight the selected line
+
+       $selected_win tag delete breaktag
+#      echo "after deleting $selected_win [$selected_win tag names]"
+#      echo "grab [grab current]"
+
+# Actually invoke the menubutton here!
+
+       tk_invokeMenu %W
+#      destroy .breakpoint
+       grab release $selected_win
+}
+
+# Button 1 has been pressed in a listing window.  Pop up a menu.
+
+proc breakpoint_menu {win x y xrel yrel} {
+       global wins
+       global win_to_file
+       global file_to_debug_file
+       global highlight
+       global selected_line
+       global selected_file
+       global selected_win
+
+       grab $win
+
+#      echo "bpm grab current [grab current]"
+
+# Map TK window name back to file name.
+
+       set file $win_to_file($win)
+
+       set pos [$win index @$xrel,$yrel]
+
+# Record selected file and line for menu button actions
+
+       set selected_file $file_to_debug_file($file)
+       set selected_line [lindex [split $pos .] 0]
+       set selected_win $win
+
+# Highlight the selected line
+
+       eval $win tag config breaktag $highlight
+       $win tag add breaktag "$pos linestart" "$pos linestart + 1l"
+
+# Post the menu near the pointer, (and grab it)
+
+       .breakpoint post [expr $x-[winfo width .breakpoint]/2] [expr $y-10]
+       grab .breakpoint
+#      echo "after grab [grab current]"
+}
+
+proc do_nothing {} {}
+
+proc create_file_win {filename} {
+       global breakpoint_file
+       global breakpoint_line
+
+       regsub -all {\.|/} $filename {} temp
+       set win .text$temp
+       text $win -height 25 -width 80 -relief raised -borderwidth 2 -yscrollcommand textscrollproc -setgrid true -cursor hand2
+       bind $win <Enter> {focus %W}
+#      bind $win <1> {breakpoint_menu %W %X %Y %x %y}
+       bind $win <B1-Motion> do_nothing
+       bind $win n {gdb_cmd next ; update_ptr}
+       bind $win s {gdb_cmd step ; update_ptr}
+       bind $win c {gdb_cmd continue ; update_ptr}
+       bind $win f {gdb_cmd finish ; update_ptr}
+       bind $win u {gdb_cmd up ; update_ptr}
+       bind $win d {gdb_cmd down ; update_ptr}
+       set fh [open $filename]
+       $win delete 0.0 end
+       $win insert 0.0 [read $fh]
+       close $fh
+       set numlines [$win index end]
+       set numlines [lindex [split $numlines .] 0]
+       for {set i 1} {$i <= $numlines} {incr i} {
+               $win insert $i.0 [format "   %4d " $i]
+               }
+
+       $win tag add wholebuf 0.0 end
+       $win tag bind wholebuf <1> {breakpoint_menu %W %X %Y %x %y}
+       foreach bpnum [array names breakpoint_file] {
+               if {$breakpoint_file($bpnum) == $filename} {
+                       insert_breakpoint_tag $win $breakpoint_line($bpnum)
+                       }
+               }
+
+       $win configure -state disabled
+       return $win
+}
+
+proc update_listing {linespec} {
+       global pointers
+       global screen_height
+       global screen_top
+       global screen_bot
+       global wins cfile
+       global current_label
+       global win_to_file
+       global file_to_debug_file
+
+       set line [lindex $linespec 3]
+       set filename [lindex $linespec 2]
+       set funcname [lindex $linespec 1]
+       set debug_file [lindex $linespec 0]
+
+       if {$filename == ""} {set filename Blank}
+
+       if {$filename != $cfile} then {
+               pack forget $wins($cfile)
+               set cfile $filename
+               if ![info exists wins($cfile)] then {
+                       set wins($cfile) [create_file_win $cfile]
+                       set win_to_file($wins($cfile)) $cfile
+                       set file_to_debug_file($cfile) $debug_file
+                       set pointers($cfile) 1.1
+                       }
+
+               pack $wins($cfile) -side left -expand yes -in .listing -fill both -after .label
+               $wins($cfile) yview [expr $line - $screen_height / 2]
+               }
+
+       if {$current_label != "$filename.$funcname"} then {
+               set tail [expr [string last / $filename] + 1]
+               .label configure -text "[string range $filename $tail end] : ${funcname}()"
+               set current_label $filename.$funcname
+               }
+
+       if [info exists pointers($cfile)] then {
+               $wins($cfile) configure -state normal
+               set pointer_pos $pointers($cfile)
+               $wins($cfile) configure -state normal
+               $wins($cfile) delete $pointer_pos
+               $wins($cfile) insert $pointer_pos " "
+
+               set pointer_pos [$wins($cfile) index $line.1]
+               set pointers($cfile) $pointer_pos
+
+               $wins($cfile) delete $pointer_pos
+               $wins($cfile) insert $pointer_pos "\xbb"
+
+               if {$line < $screen_top + 1
+                   || $line > $screen_bot} then {
+                       $wins($cfile) yview [expr $line - $screen_height / 2]
+                       }
+
+               $wins($cfile) configure -state disabled
+               }
+}
+
+proc update_ptr {} {update_listing [gdb_loc]}
+
+# Setup listing window
+
+frame .listing
+
+wm minsize . 1 1
+
+label .label -text "*No file*" -borderwidth 2 -relief raised
+text $wins($cfile) -height 25 -width 80 -relief raised -borderwidth 2 -yscrollcommand textscrollproc -setgrid true -cursor hand2
+scrollbar .scroll -orient vertical -command {$wins($cfile) yview}
+
+if {[tk colormodel .text] == "color"} {
+       set highlight "-background red2 -borderwidth 2 -relief sunk"
+} else {
+       set fg [lindex [.text config -foreground] 4]
+       set bg [lindex [.text config -background] 4]
+       set highlight "-foreground $bg -background $fg -borderwidth 0"
+}
+
+proc textscrollproc {args} {global screen_height screen_top screen_bot
+                           eval ".scroll set $args"
+                           set screen_height [lindex $args 1]
+                           set screen_top [lindex $args 2]
+                           set screen_bot [lindex $args 3]}
+
+$wins($cfile) insert 0.0 "  This page intentionally left blank."
+$wins($cfile) configure -state disabled
+
+pack .label -side bottom -fill x -in .listing
+pack $wins($cfile) -side left -expand yes -in .listing -fill both
+pack .scroll -side left -fill y -in .listing
+
+button .start -text Start -command \
+       {gdb_cmd {break main}
+        gdb_cmd {enable delete $bpnum}
+        gdb_cmd run
+        update_ptr }
+button .step -text Step -command {gdb_cmd step ; update_ptr}
+button .next -text Next -command {gdb_cmd next ; update_ptr}
+button .continue -text Continue -command {gdb_cmd continue ; update_ptr}
+button .finish -text Finish -command {gdb_cmd finish ; update_ptr}
+#button .test -text Test -command {echo [info var]}
+button .exit -text Exit -command {gdb_cmd quit}
+button .up -text Up -command {gdb_cmd up ; update_ptr}
+button .down -text Down -command {gdb_cmd down ; update_ptr}
+button .bottom -text "Bottom" -command {gdb_cmd {frame 0} ; update_ptr}
+
+proc files_command {} {
+       toplevel .files_window
+
+       wm minsize .files_window 1 1
+#      wm overrideredirect .files_window true
+       listbox .files_window.list -geometry 30x20 -setgrid true
+       button .files_window.close -text Close -command {destroy .files_window}
+       tk_listboxSingleSelect .files_window.list
+       eval .files_window.list insert 0 [lsort [gdb_listfiles]]
+       pack .files_window.list -side top -fill both -expand yes
+       pack .files_window.close -side bottom -fill x -expand no -anchor s
+       bind .files_window.list <Any-ButtonRelease-1> {
+               set file [%W get [%W curselection]]
+               gdb_cmd "list $file:1,0"
+               update_listing [gdb_loc $file:1]
+               destroy .files_window}
+}
+
+button .files -text Files -command files_command
+
+pack .listing -side bottom -fill both -expand yes
+#pack .test -side bottom -fill x
+pack .start .step .next .continue .finish .up .down .bottom .files .exit -side left
+toplevel .command
+
+# Setup command window
+
+label .command.label -text "* Command Buffer *" -borderwidth 2 -relief raised
+text .command.text -height 25 -width 80 -relief raised -borderwidth 2 -setgrid true -cursor hand2
+
+pack .command.label -side top -fill x
+pack .command.text -side top -expand yes -fill both
+
+set command_line {}
+
+gdb_cmd {set language c}
+gdb_cmd {set height 0}
+gdb_cmd {set width 0}
+
+bind .command.text <Any-Key> {
+       global command_line
+
+       %W insert end %A
+       %W yview -pickplace end
+       append command_line %A
+       }
+bind .command.text <Key-Return> {
+       global command_line
+
+       %W insert end \n
+       %W yview -pickplace end
+       gdb_cmd $command_line
+       set command_line {}
+       update_ptr
+       %W insert end "(gdb) "
+       %W yview -pickplace end
+       }
+bind .command.text <Enter> {focus %W}
+bind .command.text <Delete> {delete_char %W}
+bind .command.text <BackSpace> {delete_char %W}
+proc delete_char {win} {
+       global command_line
+
+       tk_textBackspace $win
+       $win yview -pickplace insert
+       set tmp [expr [string length $command_line] - 2]
+       set command_line [string range $command_line 0 $tmp]
+}
+
+wm minsize .command 1 1
+
index ce21c83dc9a6e8a4d7784617b65d022155ca9835..e7c8070a1cd408d2c2b9bd547ceb26f9eccf568a 100644 (file)
@@ -174,6 +174,8 @@ main (argc, argv)
        {"tty", required_argument, 0, 't'},
        {"baud", required_argument, 0, 'b'},
        {"b", required_argument, 0, 'b'},
+       {"nw", no_argument, &no_windows, 1},
+       {"nowindows", no_argument, &no_windows, 1},
 /* Allow machine descriptions to add more options... */
 #ifdef ADDITIONAL_OPTIONS
        ADDITIONAL_OPTIONS
@@ -350,6 +352,7 @@ Options:\n\
   -b BAUDRATE        Set serial port baud rate used for remote debugging.\n\
   --mapped           Use mapped symbol files if supported on this system.\n\
   --readnow          Fully read symbol files on first access.\n\
+  --nw              Do not use a window interface.\n\
 ", gdb_stdout);
 /* start-sanitize-mpw */
 #endif /* MPW_C */
@@ -410,7 +413,7 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
       stat (gdbinit, &cwdbuf); /* We'll only need this if
                                       homedir was set.  */
     }
-  
+
   /* Now perform all the actions indicated by the arguments.  */
   if (cdarg != NULL)
     {
@@ -526,18 +529,13 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
       if (!SET_TOP_LEVEL ())
        {
          do_cleanups (ALL_CLEANUPS);           /* Do complete cleanup */
-/* start-sanitize-mpw */
-#ifdef MPW
-         /* If we're being a Mac application, go into a Mac-specific
-            event-handling loop instead.  We still want to be inside
-            the outer loop, because that will catch longjmps resulting
-            from some command executions. */
-         if (mac_app)
-           mac_command_loop ();
+         /* 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 (command_loop_hook)
+           command_loop_hook ();
          else
-#endif /* MPW */
-/* end-sanitize-mpw */
-         command_loop ();
+           command_loop ();
           quit_command ((char *)0, instream == stdin);
        }
     }
@@ -570,5 +568,11 @@ fputs_unfiltered (linebuffer, stream)
      const char *linebuffer;
      FILE *stream;
 {
+  if (fputs_unfiltered_hook)
+    {
+      fputs_unfiltered_hook (linebuffer);
+      return;
+    }
+
   fputs (linebuffer, stream);
 }
index 40536ef5f4464366493a6b2126697d1a9dabb6e2..d5b677e4eea67b2f7baed44a1aae243d65a2511e 100644 (file)
@@ -122,6 +122,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
        general set     QXXXX=yyyy      Set value of XXXX to yyyy.
        query sect offs qOffsets        Get section offsets.  Reply is
                                        Text=xxx;Data=yyy;Bss=zzz
+       console output  Otext           Send text to stdout.  Only comes from
+                                       remote target.
 
        Responses can be run-length encoded to save space.  A '*' means that
        the next two characters are hex digits giving a repeat count which
@@ -145,7 +147,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "dcache.h"
 
-#if !defined(DONT_USE_REMOTE)
 #ifdef USG
 #include <sys/types.h>
 #endif
@@ -199,7 +200,7 @@ static void
 remote_send PARAMS ((char *buf));
 
 static int
-readchar PARAMS ((void));
+readchar PARAMS ((int timeout));
 
 static int remote_wait PARAMS ((int pid, struct target_waitstatus *status));
 
@@ -227,7 +228,7 @@ extern struct target_ops remote_ops;        /* Forward decl */
    Unless this is going though some terminal server or multiplexer or
    other form of hairy serial connection, I would think 2 seconds would
    be plenty.  */
-static int timeout = 2;
+static int remote_timeout = 2;
 
 #if 0
 int icache;
@@ -448,7 +449,6 @@ fromhex (a)
     return a - 'a' + 10;
   else
     error ("Reply contains invalid hex digit");
-  return -1;
 }
 
 /* Convert number NIB to a hex digit.  */
@@ -558,75 +558,82 @@ remote_wait (pid, status)
       getpkt ((char *) buf, 1);
       signal (SIGINT, ofunc);
 
-      if (buf[0] == 'E')
-       warning ("Remote failure reply: %s", buf);
-      else if (buf[0] == 'T')
+      switch (buf[0])
        {
-         int i;
-         long regno;
-         char regs[MAX_REGISTER_RAW_SIZE];
+       case 'E':               /* Error of some sort */
+         warning ("Remote failure reply: %s", buf);
+         continue;
+       case 'T':               /* Status with PC, SP, FP, ... */
+         {
+           int i;
+           long regno;
+           char regs[MAX_REGISTER_RAW_SIZE];
 
-         /* Expedited reply, containing Signal, {regno, reg} repeat */
-         /*  format is:  'Tssn...:r...;n...:r...;n...:r...;#cc', where
-             ss = signal number
-             n... = register number
-             r... = register contents
-             */
+           /* Expedited reply, containing Signal, {regno, reg} repeat */
+           /*  format is:  'Tssn...:r...;n...:r...;n...:r...;#cc', where
+               ss = signal number
+               n... = register number
+               r... = register contents
+               */
 
-         p = &buf[3];          /* after Txx */
+           p = &buf[3];        /* after Txx */
 
-         while (*p)
-           {
-             unsigned char *p1;
+           while (*p)
+             {
+               unsigned char *p1;
 
-             regno = strtol (p, &p1, 16); /* Read the register number */
+               regno = strtol (p, &p1, 16); /* Read the register number */
 
-             if (p1 == p)
-               warning ("Remote sent badly formed register number: %s\nPacket: '%s'\n",
-                        p1, buf);
+               if (p1 == p)
+                 warning ("Remote sent badly formed register number: %s\nPacket: '%s'\n",
+                          p1, buf);
 
-             p = p1;
+               p = p1;
 
-             if (*p++ != ':')
-               warning ("Malformed packet (missing colon): %s\nPacket: '%s'\n",
-                        p, buf);
+               if (*p++ != ':')
+                 warning ("Malformed packet (missing colon): %s\nPacket: '%s'\n",
+                          p, buf);
 
-             if (regno >= NUM_REGS)
-               warning ("Remote sent bad register number %d: %s\nPacket: '%s'\n",
-                        regno, p, buf);
+               if (regno >= NUM_REGS)
+                 warning ("Remote sent bad register number %d: %s\nPacket: '%s'\n",
+                          regno, p, buf);
 
-             for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
-               {
-                 if (p[0] == 0 || p[1] == 0)
-                   warning ("Remote reply is too short: %s", buf);
-                 regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
-                 p += 2;
-               }
+               for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
+                 {
+                   if (p[0] == 0 || p[1] == 0)
+                     warning ("Remote reply is too short: %s", buf);
+                   regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
+                   p += 2;
+                 }
 
-             if (*p++ != ';')
-               warning ("Remote register badly formatted: %s", buf);
+               if (*p++ != ';')
+                 warning ("Remote register badly formatted: %s", buf);
+
+               supply_register (regno, regs);
+             }
+         }
+         /* fall through */
+       case 'S':               /* Old style status, just signal only */
+         status->kind = TARGET_WAITKIND_STOPPED;
+         status->value.sig = (enum target_signal)
+           (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
 
-             supply_register (regno, regs);
-           }
-         break;
-       }
-      else if (buf[0] == 'W')
-       {
-         /* The remote process exited.  */
-         status->kind = TARGET_WAITKIND_EXITED;
-         status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
          return 0;
+       case 'W':               /* Target exited */
+         {
+           /* The remote process exited.  */
+           status->kind = TARGET_WAITKIND_EXITED;
+           status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
+           return 0;
+         }
+       case 'O':               /* Console output */
+         fputs_filtered (buf + 1, gdb_stdout);
+         continue;
+       default:
+         warning ("Invalid remote reply: %s", buf);
+         continue;
        }
-      else if (buf[0] == 'S')
-       break;
-      else
-       warning ("Invalid remote reply: %s", buf);
     }
-
-  status->kind = TARGET_WAITKIND_STOPPED;
-  status->value.sig = (enum target_signal)
-    (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
-
   return 0;
 }
 
@@ -1039,16 +1046,24 @@ remote_files_info (ignore)
 /* Read a single character from the remote end, masking it down to 7 bits. */
 
 static int
-readchar ()
+readchar (timeout)
+     int timeout;
 {
   int ch;
 
   ch = SERIAL_READCHAR (remote_desc, timeout);
 
-  if (ch < 0)
-    return ch;
-
-  return ch & 0x7f;
+  switch (ch)
+    {
+    case SERIAL_EOF:
+      error ("Remote connection closed");
+    case SERIAL_ERROR:
+      perror_with_name ("Remote communication error");
+    case SERIAL_TIMEOUT:
+      return ch;
+    default:
+      return ch & 0x7f;
+    }
 }
 
 /* Send the command in BUF to the remote machine,
@@ -1117,7 +1132,7 @@ putpkt (buf)
       /* read until either a timeout occurs (-2) or '+' is read */
       while (1)
        {
-         ch = readchar ();
+         ch = readchar (remote_timeout);
 
          if (remote_debug)
            {
@@ -1125,8 +1140,6 @@ putpkt (buf)
                {
                case '+':
                case SERIAL_TIMEOUT:
-               case SERIAL_ERROR:
-               case SERIAL_EOF:
                case '$':
                  if (started_error_output)
                    {
@@ -1144,10 +1157,6 @@ putpkt (buf)
              return;
            case SERIAL_TIMEOUT:
              break;            /* Retransmit buffer */
-           case SERIAL_ERROR:
-             perror_with_name ("putpkt: couldn't read ACK");
-           case SERIAL_EOF:
-             error ("putpkt: EOF while trying to read ACK");
            case '$':
              {
                unsigned char junkbuf[PBUFSIZ];
@@ -1187,151 +1196,157 @@ putpkt (buf)
     }
 }
 
+/* Come here after finding the start of the frame.  Collect the rest into BUF,
+   verifying the checksum, length, and handling run-length compression.
+   Returns 0 on any error, 1 on success.  */
+
+static int
+read_frame (buf)
+     char *buf;
+{
+  unsigned char csum;
+  char *bp;
+  int c;
+
+  csum = 0;
+  bp = buf;
+
+  while (1)
+    {
+      c = readchar (remote_timeout);
+
+      switch (c)
+       {
+       case SERIAL_TIMEOUT:
+         if (remote_debug)
+           puts_filtered ("Timeout in mid-packet, retrying\n");
+         return 0;
+       case '$':
+         if (remote_debug)
+           puts_filtered ("Saw new packet start in middle of old one\n");
+         return 0;             /* Start a new packet, count retries */
+       case '#':
+         {
+           unsigned char pktcsum;
+
+           *bp = '\000';
+
+           pktcsum = fromhex (readchar (remote_timeout)) << 4
+             | fromhex (readchar (remote_timeout));
+
+           if (csum == pktcsum)
+             return 1;
+
+           printf_filtered ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
+                            pktcsum, csum);
+           puts_filtered (buf);
+           puts_filtered ("\n");
+
+           return 0;
+         }
+       case '*':               /* Run length encoding */
+         c = readchar (remote_timeout);
+         csum += c;
+         c = c - ' ' + 3;      /* Compute repeat count */
+
+         if (bp + c - 1 < buf + PBUFSIZ - 1)
+           {
+             memset (bp, *(bp - 1), c);
+             bp += c;
+             continue;
+           }
+
+         *bp = '\0';
+         printf_filtered ("Repeat count %d too large for buffer: ", c);
+         puts_filtered (buf);
+         puts_filtered ("\n");
+
+         return 0;
+       default:
+         if (bp < buf + PBUFSIZ - 1)
+           {
+             *bp++ = c;
+             csum += c;
+             continue;
+           }
+
+         *bp = '\0';
+         puts_filtered ("Remote packet too long: ");
+         puts_filtered (buf);
+         puts_filtered ("\n");
+
+         return 0;
+       }
+    }
+}
+
 /* Read a packet from the remote machine, with error checking,
    and store it in BUF.  BUF is expected to be of size PBUFSIZ.
    If FOREVER, wait forever rather than timing out; this is used
    while the target is executing user code.  */
 
 static void
-getpkt (retbuf, forever)
-     char *retbuf;
+getpkt (buf, forever)
+     char *buf;
      int forever;
 {
   char *bp;
-  unsigned char csum;
-  int c = 0;
-  unsigned char c1, c2;
-  int retries = 0;
-  char buf[PBUFSIZ];
+  int c;
+  int tries;
+  int timeout;
+  int val;
 
-#define MAX_RETRIES    10
+  if (forever)
+    timeout = -1;
+  else
+    timeout = remote_timeout;
 
-  while (1)
-    {
-#if 0
-      /* This is wrong.  If doing a long backtrace, the user should be
-        able to get out time next we call QUIT, without anything as violent
-        as interrupt_query.  If we want to provide a way out of here
-        without getting to the next QUIT, it should be based on hitting
-        ^C twice as in remote_wait.  */
-      if (quit_flag)
-       {
-         quit_flag = 0;
-         interrupt_query ();
-       }
-#endif
+#define MAX_TRIES 10
 
+  for (tries = 1; tries <= MAX_TRIES; tries++)
+    {
       /* This can loop forever if the remote side sends us characters
         continuously, but if it pauses, we'll get a zero from readchar
         because of timeout.  Then we'll count that as a retry.  */
 
-      c = readchar();
-      if (c > 0 && c != '$')
-       continue;
+      /* Note that we will only wait forever prior to the start of a packet.
+        After that, we expect characters to arrive at a brisk pace.  They
+        should show up within remote_timeout intervals.  */
 
-      if (c == SERIAL_TIMEOUT)
+      do
        {
-         if (forever)
-           continue;
-         if (remote_debug)
-           puts_filtered ("Timed out.\n");
-         goto whole;
-       }
-
-      if (c == SERIAL_EOF)
-       error ("Remote connection closed");
-      if (c == SERIAL_ERROR)
-       perror_with_name ("Remote communication error");
+         c = readchar (timeout);
 
-      /* Force csum to be zero here because of possible error retry.  */
-      csum = 0;
-      bp = buf;
-
-      while (1)
-       {
-         c = readchar ();
          if (c == SERIAL_TIMEOUT)
            {
              if (remote_debug)
-               puts_filtered ("Timeout in mid-packet, retrying\n");
-             goto whole;               /* Start a new packet, count retries */
-           } 
-         if (c == '$')
-           {
-             if (remote_debug)
-               puts_filtered ("Saw new packet start in middle of old one\n");
-             goto whole;               /* Start a new packet, count retries */
+               puts_filtered ("Timed out.\n");
+             goto retry;
            }
-         if (c == '#')
-           break;
-         if (bp >= buf+PBUFSIZ-1)
-         {
-           *bp = '\0';
-           puts_filtered ("Remote packet too long: ");
-           puts_filtered (buf);
-           puts_filtered ("\n");
-           goto whole;
-         }
-         *bp++ = c;
-         csum += c;
        }
-      *bp = 0;
+      while (c != '$');
 
-      c1 = fromhex (readchar ());
-      c2 = fromhex (readchar ());
-      if ((csum & 0xff) == (c1 << 4) + c2)
-       break;
-      printf_filtered ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
-             (c1 << 4) + c2, csum & 0xff);
-      puts_filtered (buf);
-      puts_filtered ("\n");
+      /* We've found the start of a packet, now collect the data.  */
 
-      /* Try the whole thing again.  */
-whole:
-      if (++retries < MAX_RETRIES)
-       {
-         SERIAL_WRITE (remote_desc, "-", 1);
-       }
-      else
+      val = read_frame (buf);
+
+      if (val == 1)
        {
-         printf_unfiltered ("Ignoring packet error, continuing...\n");
-         break;
+         if (remote_debug)
+           fprintf_unfiltered (gdb_stderr, "Packet received: %s\n", buf);
+         SERIAL_WRITE (remote_desc, "+", 1);
+         return;
        }
+
+      /* Try the whole thing again.  */
+retry:
+      SERIAL_WRITE (remote_desc, "-", 1);
     }
 
-  /* Deal with run-length encoding.  */
-  {
-    char *src = buf;
-    char *dest = retbuf;
-    int i;
-    int repeat;
-    do {
-      if (*src == '*')
-       {
-         if (src[1] == '\0' || src[2] == '\0')
-           {
-             if (remote_debug)
-               puts_filtered ("Packet too short, retrying\n");
-             goto whole;
-           }
-         repeat = (fromhex (src[1]) << 4) + fromhex (src[2]);
-         for (i = 0; i < repeat; ++i)
-           {
-             *dest++ = src[-1];
-           }
-         src += 2;
-       }
-      else
-       {
-         *dest++ = *src;
-       }
-    } while (*src++ != '\0');
-  }
+  /* We have tried hard enough, and just can't receive the packet.  Give up. */
 
+  printf_unfiltered ("Ignoring packet error, continuing...\n");
   SERIAL_WRITE (remote_desc, "+", 1);
-
-  if (remote_debug)
-    fprintf_unfiltered (gdb_stderr,"Packet received: %s\n", buf);
 }
 \f
 static void
@@ -1443,12 +1458,9 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",  /* to_doc */
   NULL,                                /* sections_end */
   OPS_MAGIC                    /* to_magic */
 };
-#endif /* Use remote.  */
 
 void
 _initialize_remote ()
 {
-#if !defined(DONT_USE_REMOTE)
   add_target (&remote_ops);
-#endif
 }
index 8e6d56c95952c9fc752d1a2824c02714f4e05e6c..75acd4a337e939a63555077d25cbc22e8d5f4534 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -146,6 +146,10 @@ source_cleanup PARAMS ((FILE *));
 char gdbinit[] = GDBINIT_FILENAME;
 int inhibit_gdbinit = 0;
 
+/* Disable windows if non-zero */
+
+int no_windows = 0;
+
 /* Version number of GDB, as a string.  */
 
 extern char *version;
@@ -488,6 +492,8 @@ gdb_init ()
   current_directory = gdb_dirbuf;
 
   init_cmd_lists ();   /* This needs to be done first */
+  initialize_targets (); /* Setup target_terminal macros for utils.c */
+  initialize_utils (); /* Make errors and warnings possible */
   initialize_all_files ();
   init_main ();                /* But that omits this file!  Do it now */
   init_signals ();
@@ -499,6 +505,9 @@ gdb_init ()
      or implicitly set by reading an executable during startup. */
   set_language (language_c);
   expected_language = current_language;        /* don't warn about the change.  */
+
+  if (init_ui_hook)
+    init_ui_hook ();
 }
 
 void