]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/top.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / gdb / top.c
index 72fa4642765057720c1811b7d162561a166d4b21..189e3c395ef65fb15919724676078d2b3c8276eb 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1,5 +1,5 @@
 /* Top level stuff for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -16,7 +16,7 @@ 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.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "gdbcmd.h"
@@ -36,8 +36,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "top.h"
 
 /* readline include files */
-#include "readline.h"
-#include "history.h"
+#include <readline/readline.h>
+#include <readline/history.h>
 
 /* readline defines this.  */
 #undef savestring
@@ -47,20 +47,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <unistd.h>
 #endif
 
-#include <string.h>
-#ifndef        NO_SYS_FILE
-#include <sys/file.h>
-#endif
-#include <sys/param.h>
-#include <sys/stat.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
 #include <ctype.h>
 
-extern void initialize_targets PARAMS ((void));
-
 extern void initialize_utils PARAMS ((void));
 
 /* Prototypes for local functions */
 
+static void dont_repeat_command PARAMS ((char *, int));
+
+static void source_cleanup_lines PARAMS ((PTR));
+
+static void user_defined_command PARAMS ((char *, int));
+
+static void init_signals PARAMS ((void));
+
+#ifdef STOP_SIGNAL
+static void stop_sig PARAMS ((int));
+#endif
+
 static char * line_completion_function PARAMS ((char *, int, char *, int));
 
 static char * readline_line_completion_function PARAMS ((char *, int));
@@ -102,20 +108,6 @@ static void init_signals PARAMS ((void));
 
 static void set_verbose PARAMS ((char *, int, struct cmd_list_element *));
 
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
-static void set_endian PARAMS ((char *, int));
-
-static void set_endian_big PARAMS ((char *, int));
-
-static void set_endian_little PARAMS ((char *, int));
-
-static void set_endian_auto PARAMS ((char *, int));
-
-static void show_endian PARAMS ((char *, int));
-
-#endif
-
 static void show_history PARAMS ((char *, int));
 
 static void set_history PARAMS ((char *, int));
@@ -147,9 +139,11 @@ static void complete_command PARAMS ((char *, int));
 
 static void do_nothing PARAMS ((int));
 
-static int quit_cover PARAMS ((char *));
+#ifdef SIGHUP
+static int quit_cover PARAMS ((PTR));
 
 static void disconnect PARAMS ((int));
+#endif
 
 static void source_cleanup PARAMS ((FILE *));
 
@@ -209,6 +203,14 @@ struct cmd_list_element *enablelist;
 
 struct cmd_list_element *disablelist;
 
+/* Chain containing all defined toggle subcommands. */
+
+struct cmd_list_element *togglelist;
+
+/* Chain containing all defined stop subcommands. */
+
+struct cmd_list_element *stoplist;
+
 /* Chain containing all defined delete subcommands. */
 
 struct cmd_list_element *deletelist;
@@ -229,12 +231,6 @@ struct cmd_list_element *unsetlist;
 
 struct cmd_list_element *showlist;
 
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-/* Chain containing the \"set endian\" commands.  */
-
-struct cmd_list_element *endianlist;
-#endif
-
 /* Chain containing all defined \"set history\".  */
 
 struct cmd_list_element *sethistlist;
@@ -275,7 +271,7 @@ struct cmd_list_element *showchecklist;
 
 /* stdio stream that command input is being read from.  Set to stdin normally.
    Set by source_command to the file we are sourcing.  Set to NULL if we are
-   executing a user-defined command.  */
+   executing a user-defined command or interacting via a GUI.  */
 
 FILE *instream;
 
@@ -319,6 +315,10 @@ int server_command;
 
 int baud_rate = -1;
 
+/* Timeout limit for response from target. */
+
+int remote_timeout = 20;       /* Set default to 20 */
+
 /* Non-zero tells remote* modules to output debugging info.  */
 
 int remote_debug = 0;
@@ -366,16 +366,25 @@ static void stop_sig PARAMS ((int));
 /* Called after most modules have been initialized, but before taking users
    command file.  */
 
-void (*init_ui_hook) PARAMS ((void));
+void (*init_ui_hook) PARAMS ((char *argv0));
+#ifdef __CYGWIN32__
+void (*ui_loop_hook) PARAMS ((int));
+#endif
 
 /* Called instead of command_loop at top level.  Can be invoked via
    return_to_top_level.  */
 
 void (*command_loop_hook) PARAMS ((void));
 
+
 /* Called instead of fputs for all output.  */
 
-void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, FILE *stream));
+void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, GDB_FILE *stream));
+
+/* Called when the target says something to the host, which may
+   want to appear in a different window. */
+
+void (*target_output_hook) PARAMS ((char *));
 
 /* Called from print_frame_info to list the line we stopped in.  */
 
@@ -383,11 +392,30 @@ void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, int line,
                                               int stopline, int noerror));
 /* Replaces most of query.  */
 
-int (*query_hook) PARAMS (());
+int (*query_hook) PARAMS ((const char *, va_list));
+
+/* Replaces most of warning.  */
+
+void (*warning_hook) PARAMS ((const char *, va_list));
 
 /* Called from gdb_flush to flush output.  */
 
-void (*flush_hook) PARAMS ((FILE *stream));
+void (*flush_hook) PARAMS ((GDB_FILE *stream));
+
+/* These three functions support getting lines of text from the user.  They
+   are used in sequence.  First readline_begin_hook is called with a text
+   string that might be (for example) a message for the user to type in a
+   sequence of commands to be executed at a breakpoint.  If this function
+   calls back to a GUI, it might take this opportunity to pop up a text
+   interaction window with this message.  Next, readline_hook is called
+   with a prompt that is emitted prior to collecting the user input.
+   It can be called multiple times.  Finally, readline_end_hook is called
+   to notify the GUI that we are done with the interaction window and it
+   can close it. */
+
+void (*readline_begin_hook) PARAMS ((char *, ...));
+char * (*readline_hook) PARAMS ((char *));
+void (*readline_end_hook) PARAMS ((void));
 
 /* Called as appropriate to notify the interface of the specified breakpoint
    conditions.  */
@@ -406,6 +434,14 @@ void (*interactive_hook) PARAMS ((void));
 
 void (*registers_changed_hook) PARAMS ((void));
 
+/* Tell the GUI someone changed the register REGNO. -1 means
+   that the caller does not know which register changed or
+   that several registers have changed (see value_assign).*/
+void (*register_changed_hook) PARAMS ((int regno));
+
+/* Tell the GUI someone changed LEN bytes of memory at ADDR */
+void (*memory_changed_hook) PARAMS ((CORE_ADDR addr, int len));
+
 /* Called when going to wait for the target.  Usually allows the GUI to run
    while waiting for target events.  */
 
@@ -417,17 +453,20 @@ int (*target_wait_hook) PARAMS ((int pid, struct target_waitstatus *status));
 void (*call_command_hook) PARAMS ((struct cmd_list_element *c, char *cmd,
                                   int from_tty));
 
+/* Called when the current thread changes.  Argument is thread id.  */
+
+void (*context_hook) PARAMS ((int id));
 
 /* Takes control from error ().  Typically used to prevent longjmps out of the
    middle of the GUI.  Usually used in conjunction with a catch routine.  */
 
-NORETURN void (*error_hook) PARAMS (()) ATTR_NORETURN;
+NORETURN void (*error_hook) PARAMS ((void)) ATTR_NORETURN;
 
 \f
 /* Where to go for return_to_top_level (RETURN_ERROR).  */
-jmp_buf error_return;
+SIGJMP_BUF error_return;
 /* Where to go for return_to_top_level (RETURN_QUIT).  */
-jmp_buf quit_return;
+SIGJMP_BUF quit_return;
 
 /* Return for reason REASON.  This generally gets back to the command
    loop, but can be caught via catch_errors.  */
@@ -457,7 +496,7 @@ return_to_top_level (reason)
        break;
       }
 
-  (NORETURN void) longjmp
+  (NORETURN void) SIGLONGJMP
     (reason == RETURN_ERROR ? error_return : quit_return, 1);
 }
 
@@ -482,14 +521,14 @@ return_to_top_level (reason)
 
 int
 catch_errors (func, args, errstring, mask)
-     int (*func) PARAMS ((char *));
+     catch_errors_ftype *func;
      PTR args;
      char *errstring;
      return_mask mask;
 {
-  jmp_buf saved_error;
-  jmp_buf saved_quit;
-  jmp_buf tmp_jmp;
+  SIGJMP_BUF saved_error;
+  SIGJMP_BUF saved_quit;
+  SIGJMP_BUF tmp_jmp;
   int val;
   struct cleanup *saved_cleanup_chain;
   char *saved_error_pre_print;
@@ -501,21 +540,21 @@ catch_errors (func, args, errstring, mask)
 
   if (mask & RETURN_MASK_ERROR)
     {
-      memcpy ((char *)saved_error, (char *)error_return, sizeof (jmp_buf));
+      memcpy ((char *)saved_error, (char *)error_return, sizeof (SIGJMP_BUF));
       error_pre_print = errstring;
     }
   if (mask & RETURN_MASK_QUIT)
     {
-      memcpy (saved_quit, quit_return, sizeof (jmp_buf));
+      memcpy (saved_quit, quit_return, sizeof (SIGJMP_BUF));
       quit_pre_print = errstring;
     }
 
-  if (setjmp (tmp_jmp) == 0)
+  if (SIGSETJMP (tmp_jmp) == 0)
     {
       if (mask & RETURN_MASK_ERROR)
-       memcpy (error_return, tmp_jmp, sizeof (jmp_buf));
+       memcpy (error_return, tmp_jmp, sizeof (SIGJMP_BUF));
       if (mask & RETURN_MASK_QUIT)
-       memcpy (quit_return, tmp_jmp, sizeof (jmp_buf));
+       memcpy (quit_return, tmp_jmp, sizeof (SIGJMP_BUF));
       val = (*func) (args);
     }
   else
@@ -525,12 +564,12 @@ catch_errors (func, args, errstring, mask)
 
   if (mask & RETURN_MASK_ERROR)
     {
-      memcpy (error_return, saved_error, sizeof (jmp_buf));
+      memcpy (error_return, saved_error, sizeof (SIGJMP_BUF));
       error_pre_print = saved_error_pre_print;
     }
   if (mask & RETURN_MASK_QUIT)
     {
-      memcpy (quit_return, saved_quit, sizeof (jmp_buf));
+      memcpy (quit_return, saved_quit, sizeof (SIGJMP_BUF));
       quit_pre_print = saved_quit_pre_print;
     }
   return val;
@@ -538,6 +577,7 @@ catch_errors (func, args, errstring, mask)
 
 /* Handler for SIGHUP.  */
 
+#ifdef SIGHUP
 static void
 disconnect (signo)
 int signo;
@@ -552,13 +592,14 @@ int signo;
 
 static int
 quit_cover (s)
-char *s;
+     PTR s;
 {
   caution = 0;         /* Throw caution to the wind -- we're exiting.
                           This prevents asking the user dumb questions.  */
   quit_command((char *)0, 0);
   return 0;
 }
+#endif /* defined SIGHUP */
 \f
 /* Line number we are currently in in a file which is being sourced.  */
 static int source_line_number;
@@ -593,18 +634,19 @@ read_command_file (stream)
 {
   struct cleanup *cleanups;
 
-  cleanups = make_cleanup (source_cleanup, instream);
+  cleanups = make_cleanup ((make_cleanup_func) source_cleanup, instream);
   instream = stream;
   command_loop ();
   do_cleanups (cleanups);
 }
 \f
-extern void init_proc ();
+extern void init_proc PARAMS ((void));
 
 void (*pre_init_ui_hook) PARAMS ((void));
 
 void
-gdb_init ()
+gdb_init (argv0)
+     char *argv0;
 {
   if (pre_init_ui_hook)
     pre_init_ui_hook ();
@@ -630,7 +672,7 @@ gdb_init ()
   expected_language = current_language;        /* don't warn about the change.  */
 
   if (init_ui_hook)
-    init_ui_hook ();
+    init_ui_hook (argv0);
 }
 
 /* Allocate, initialize a new command line structure for one of the
@@ -643,6 +685,9 @@ build_command_line (type, args)
 {
   struct command_line *cmd;
 
+  if (args == NULL)
+    error ("if/while commands require arguments.\n");
+
   cmd = (struct command_line *)xmalloc (sizeof (struct command_line));
   cmd->next = NULL;
   cmd->control_type = type;
@@ -670,7 +715,7 @@ get_command_line (type, arg)
   /* Allocate and build a new command line structure.  */
   cmd = build_command_line (type, arg);
 
-  old_chain = make_cleanup (free_command_lines, &cmd);
+  old_chain = make_cleanup ((make_cleanup_func) free_command_lines, &cmd);
 
   /* Read in the body of this command.  */
   if (recurse_read_control_structure (cmd) == invalid_control)
@@ -775,6 +820,7 @@ execute_control_command (cmd)
   struct command_line *current;
   struct cleanup *old_chain = 0;
   value_ptr val;
+  value_ptr val_mark;
   int loop;
   enum command_control_type ret;
   char *new_line;
@@ -786,7 +832,8 @@ execute_control_command (cmd)
       new_line = insert_args (cmd->line);
       if (!new_line)
        return invalid_control;
-      old_chain = make_cleanup (free_current_contents, &new_line);
+      old_chain = make_cleanup ((make_cleanup_func) free_current_contents, 
+                                &new_line);
       execute_command (new_line, 0);
       ret = cmd->control_type;
       break;
@@ -804,21 +851,29 @@ execute_control_command (cmd)
        new_line = insert_args (cmd->line);
        if (!new_line)
          return invalid_control;
-       old_chain = make_cleanup (free_current_contents, &new_line);
+       old_chain = make_cleanup ((make_cleanup_func) free_current_contents, 
+                                  &new_line);
        expr = parse_expression (new_line);
-       make_cleanup (free_current_contents, &expr);
+       make_cleanup ((make_cleanup_func) free_current_contents, &expr);
        
        ret = simple_control;
-       loop = true;
+       loop = 1;
 
        /* Keep iterating so long as the expression is true.  */
-       while (loop == true)
+       while (loop == 1)
          {
+           int cond_result;
+
+           QUIT;
+
            /* Evaluate the expression.  */
+           val_mark = value_mark ();
            val = evaluate_expression (expr);
+           cond_result = value_true (val);
+           value_free_to_mark (val_mark);
 
            /* If the value is false, then break out of the loop.  */
-           if (!value_true (val))
+           if (!cond_result)
              break;
 
            /* Execute the body of the while statement.  */
@@ -831,7 +886,7 @@ execute_control_command (cmd)
                   looping.  */
                if (ret == invalid_control || ret == break_control)
                  {
-                   loop = false;
+                   loop = 0;
                    break;
                  }
 
@@ -857,15 +912,17 @@ execute_control_command (cmd)
        new_line = insert_args (cmd->line);
        if (!new_line)
          return invalid_control;
-       old_chain = make_cleanup (free_current_contents, &new_line);
+       old_chain = make_cleanup ((make_cleanup_func) free_current_contents, 
+                                  &new_line);
        /* Parse the conditional for the if statement.  */
        expr = parse_expression (new_line);
-       make_cleanup (free_current_contents, &expr);
+       make_cleanup ((make_cleanup_func) free_current_contents, &expr);
 
        current = NULL;
        ret = simple_control;
 
        /* Evaluate the conditional.  */
+       val_mark = value_mark ();
        val = evaluate_expression (expr);
 
        /* Choose which arm to take commands from based on the value of the
@@ -874,6 +931,7 @@ execute_control_command (cmd)
          current = *cmd->body_list;
        else if (cmd->body_count == 2)
          current = *(cmd->body_list + 1);
+       value_free_to_mark (val_mark);
 
        /* Execute commands in the given arm.  */
        while (current)
@@ -971,7 +1029,7 @@ setup_user_args (p)
   args->next = user_args;
   user_args = args;
 
-  old_chain = make_cleanup (arg_cleanup, 0);
+  old_chain = make_cleanup ((make_cleanup_func) arg_cleanup, 0);
 
   if (p == NULL)
     return old_chain;
@@ -979,6 +1037,9 @@ setup_user_args (p)
   while (*p)
     {
       char *start_arg;
+      int squote = 0;
+      int dquote = 0;
+      int bsquote = 0;
 
       if (arg_count >= MAXUSERARGS)
        {
@@ -996,8 +1057,36 @@ setup_user_args (p)
       user_args->a[arg_count].arg = p;
 
       /* Get to the end of this argument.  */
-      while (*p && *p != ' ' && *p != '\t')
-       p++;
+      while (*p)
+       {
+         if (((*p == ' ' || *p == '\t')) && !squote && !dquote && !bsquote)
+           break;
+         else
+           {
+             if (bsquote)
+               bsquote = 0;
+             else if (*p == '\\')
+               bsquote = 1;
+             else if (squote)
+               {
+                 if (*p == '\'')
+                   squote = 0;
+               }
+             else if (dquote)
+               {
+                 if (*p == '"')
+                   dquote = 0;
+               }
+             else
+               {
+                 if (*p == '\'')
+                   squote = 1;
+                 else if (*p == '"')
+                   dquote = 1;
+               }
+             p++;
+           }
+       }
 
       user_args->a[arg_count].len = p - start_arg;
       arg_count++;
@@ -1104,7 +1193,7 @@ execute_user_command (c, args)
 
   /* Set the instream to 0, indicating execution of a
      user-defined function.  */
-  old_chain = make_cleanup (source_cleanup, instream);
+  old_chain = make_cleanup ((make_cleanup_func) source_cleanup, instream);
   instream = (FILE *) 0;
   while (cmdlines)
     {
@@ -1130,13 +1219,21 @@ execute_command (p, from_tty)
   register struct cmd_list_element *c;
   register enum language flang;
   static int warned = 0;
+  /* FIXME: These should really be in an appropriate header file */
+  extern void serial_log_command PARAMS ((const char *));
 
   free_all_values ();
 
+  /* Force cleanup of any alloca areas if using C alloca instead of
+     a builtin alloca.  */
+  alloca (0);
+
   /* This can happen when command_line_input hits end of file.  */
   if (p == NULL)
       return;
 
+  serial_log_command (p);
+
   while (*p == ' ' || *p == '\t') p++;
   if (*p)
     {
@@ -1146,6 +1243,15 @@ execute_command (p, from_tty)
       /* Pass null arg rather than an empty one.  */
       arg = *p ? p : 0;
 
+      /* Clear off trailing whitespace, except for set and complete command.  */
+      if (arg && c->type != set_cmd && c->function.cfunc != complete_command)
+       {
+         p = arg + strlen (arg) - 1;
+         while (p >= arg && (*p == ' ' || *p == '\t'))
+           p--;
+         *(p + 1) = '\0';
+       }
+
       /* If this command has been hooked, run the hook first. */
       if (c->hook)
        execute_user_command (c->hook, (char *)0);
@@ -1207,21 +1313,40 @@ command_loop ()
   char *command;
   int stdin_is_tty = ISATTY (stdin);
   long time_at_cmd_start;
-  long space_at_cmd_start;
+#ifdef HAVE_SBRK
+  long space_at_cmd_start = 0;
+#endif
   extern int display_time;
   extern int display_space;
 
-  while (!feof (instream))
+  while (instream && !feof (instream))
     {
+#if defined(TUI)
+      extern int insert_mode;
+#endif
       if (window_hook && instream == stdin)
        (*window_hook) (instream, prompt);
 
       quit_flag = 0;
       if (instream == stdin && stdin_is_tty)
        reinitialize_more_filter ();
-      old_chain = make_cleanup (command_loop_marker, 0);
+      old_chain = make_cleanup ((make_cleanup_func) command_loop_marker, 0);
+
+#if defined(TUI)
+      /* A bit of paranoia: I want to make sure the "insert_mode" global
+       * is clear except when it is being used for command-line editing
+       * (see tuiIO.c, utils.c); otherwise normal output will
+       * get messed up in the TUI. So clear it before/after
+       * the command-line-input call. - RT
+       */
+      insert_mode = 0;
+#endif
+      /* Get a command-line. This calls the readline package. */
       command = command_line_input (instream == stdin ? prompt : (char *) NULL,
                                    instream == stdin, "prompt");
+#if defined(TUI)
+      insert_mode = 0;
+#endif
       if (command == 0)
        return;
 
@@ -1229,10 +1354,12 @@ command_loop ()
 
       if (display_space)
        {
+#ifdef HAVE_SBRK
          extern char **environ;
          char *lim = (char *) sbrk (0);
 
          space_at_cmd_start = (long) (lim - (char *) &environ);
+#endif
        }
 
       execute_command (command, instream == stdin);
@@ -1250,6 +1377,7 @@ command_loop ()
 
       if (display_space)
        {
+#ifdef HAVE_SBRK
          extern char **environ;
          char *lim = (char *) sbrk (0);
          long space_now = lim - (char *) &environ;
@@ -1259,6 +1387,7 @@ command_loop ()
                             space_now,
                             (space_diff >= 0 ? '+' : '-'),
                             space_diff);
+#endif
        }
     }
 }
@@ -1328,7 +1457,15 @@ gdb_readline (prrompt)
        }
 
       if (c == '\n')
+#ifndef CRLF_SOURCE_FILES
        break;
+#else
+       {
+         if (input_index > 0 && result[input_index - 1] == '\r')
+           input_index--;
+         break;
+       }
+#endif
 
       result[input_index++] = c;
       while (input_index >= result_size)
@@ -1400,7 +1537,7 @@ filename_completer (text, word)
      char *word;
 {
   /* From readline.  */
-  extern char *filename_completion_function ();
+  extern char *filename_completion_function PARAMS ((char *, int));
   int subsequent_name;
   char **return_val;
   int return_val_used;
@@ -1811,6 +1948,13 @@ static void
 do_nothing (signo)
 int signo;
 {
+  /* Under System V the default disposition of a signal is reinstated after
+     the signal is caught and delivered to an application process.  On such
+     systems one must restore the replacement signal handler if one wishes
+     to continue handling the signal in one's program.  On BSD systems this
+     is not needed but it is harmless, and it simplifies the code to just do
+     it unconditionally. */
+  signal (signo, do_nothing);
 }
 
 static void
@@ -1818,6 +1962,12 @@ init_signals ()
 {
   signal (SIGINT, request_quit);
 
+  /* If SIGTRAP was set to SIG_IGN, then the SIG_IGN will get passed
+     to the inferior and breakpoints will be ignored.  */
+#ifdef SIGTRAP
+  signal (SIGTRAP, SIG_DFL);
+#endif
+
   /* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get
      passed to the inferior, which we don't want.  It would be
      possible to do a "signal (SIGQUIT, SIG_DFL)" after we fork, but
@@ -1827,8 +1977,10 @@ init_signals ()
      a handler for SIGQUIT, when we call exec it will set the signal
      to SIG_DFL for us.  */
   signal (SIGQUIT, do_nothing);
+#ifdef SIGHUP
   if (signal (SIGHUP, do_nothing) != SIG_IGN)
     signal (SIGHUP, disconnect);
+#endif
   signal (SIGFPE, float_handler);
 
 #if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
@@ -1863,7 +2015,6 @@ command_line_input (prrompt, repeat, annotation_suffix)
   char *p1;
   char *rl;
   char *local_prompt = prrompt;
-  register int c;
   char *nline;
   char got_eof = 0;
 
@@ -1927,11 +2078,18 @@ command_line_input (prrompt, repeat, annotation_suffix)
        }
 
       /* Don't use fancy stuff if not talking to stdin.  */
-      if (command_editing_p && instream == stdin
-         && ISATTY (instream))
-       rl = readline (local_prompt);
+      if (readline_hook && instream == NULL)
+       {
+         rl = (*readline_hook) (local_prompt);
+       }
+      else if (command_editing_p && instream == stdin && ISATTY (instream))
+       {
+         rl = readline (local_prompt);
+       }
       else
-       rl = gdb_readline (local_prompt);
+       {
+         rl = gdb_readline (local_prompt);
+       }
 
       if (annotation_level > 1 && instream == stdin)
        {
@@ -2023,16 +2181,11 @@ command_line_input (prrompt, repeat, annotation_suffix)
   /* If we just got an empty line, and that is supposed
      to repeat the previous command, return the value in the
      global buffer.  */
-  if (repeat)
-    {
-      if (p == linebuffer)
-       return line;
-      p1 = linebuffer;
-      while (*p1 == ' ' || *p1 == '\t')
-       p1++;
-      if (!*p1)
-       return line;
-    }
+  if (repeat && p == linebuffer)
+    return line;
+  for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++) ;
+  if (repeat && !*p1)
+    return line;
 
   *p = 0;
 
@@ -2047,36 +2200,8 @@ command_line_input (prrompt, repeat, annotation_suffix)
      out the command and then later fetch it from the value history
      and remove the '#'.  The kill ring is probably better, but some
      people are in the habit of commenting things out.  */
-  p1 = linebuffer;
-  while ((c = *p1++) != '\0')
-    {
-      if (c == '"')
-       while ((c = *p1++) != '"')
-         {
-           /* Make sure an escaped '"' doesn't make us think the string
-              is ended.  */
-           if (c == '\\')
-             parse_escape (&p1);
-           if (c == '\0')
-             break;
-         }
-      else if (c == '\'')
-       while ((c = *p1++) != '\'')
-         {
-           /* Make sure an escaped '\'' doesn't make us think the string
-              is ended.  */
-           if (c == '\\')
-             parse_escape (&p1);
-           if (c == '\0')
-             break;
-         }
-      else if (c == '#')
-       {
-         /* Found a comment.  */
-         p1[-1] = '\0';
-         break;
-       }
-    }
+  if (*p1 == '#')
+    *p1 = '\0';  /* Found a comment. */
 
   /* Save into global buffer if appropriate.  */
   if (repeat)
@@ -2136,7 +2261,7 @@ read_next_line (command)
     error ("Control nesting too deep!\n");
 
   /* Set a prompt based on the nesting of the control commands.  */
-  if (instream == stdin)
+  if (instream == stdin || (instream == 0 && readline_hook != NULL))
     {
       for (i = 0; i < control_level; i++)
        control_prompt[i] = ' ';
@@ -2181,7 +2306,7 @@ read_next_line (command)
     *command = build_command_line (while_control, p + 6);
   else if (p1 - p > 2 && !strncmp (p, "if", 2))
     *command = build_command_line (if_control, p + 3);
-  else if (p1 - p == 5 && !strncmp (p, "loop_break", 5))
+  else if (p1 - p == 10 && !strncmp (p, "loop_break", 10))
     {
       *command = (struct command_line *)
        xmalloc (sizeof (struct command_line));
@@ -2191,7 +2316,7 @@ read_next_line (command)
       (*command)->body_count = 0;
       (*command)->body_list = NULL;
     }
-  else if (p1 - p == 8 && !strncmp (p, "loop_continue", 8))
+  else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13))
     {
       *command = (struct command_line *)
        xmalloc (sizeof (struct command_line));
@@ -2218,7 +2343,7 @@ read_next_line (command)
 }
 
 /* Recursively read in the control structures and create a command_line 
-   tructure from them.
+   structure from them.
 
    The parent_control parameter is the control structure in which the
    following commands are nested.  */
@@ -2231,9 +2356,7 @@ recurse_read_control_structure (current_cmd)
   enum misc_command_type val;
   enum command_control_type ret;
   struct command_line **body_ptr, *child_tail, *next;
-  struct cleanup *old_chains, *tmp_chains;
 
-  old_chains = NULL;
   child_tail = NULL;
   current_body = 1;
 
@@ -2302,19 +2425,12 @@ recurse_read_control_structure (current_cmd)
        }
       else
        {
-         /* We have just read the first line of the child's control
-            structure.  From now on, arrange to throw away the line
-            we have if we quit or get an error.  */
          body_ptr = current_cmd->body_list;
          for (i = 1; i < current_body; i++)
            body_ptr++;
 
          *body_ptr = next;
 
-         tmp_chains = make_cleanup (free_command_lines, body_ptr);
-
-         if (!old_chains)
-           old_chains = tmp_chains;
        }
 
       child_tail = next;
@@ -2334,27 +2450,38 @@ recurse_read_control_structure (current_cmd)
     }
 
   dont_repeat ();
-  if (ret == invalid_control && old_chains)
-    do_cleanups (old_chains);
-  else if (old_chains)
-    discard_cleanups (old_chains);
 
   return ret;
 }
 
+/* Read lines from the input stream and accumulate them in a chain of
+   struct command_line's, which is then returned.  For input from a
+   terminal, the special command "end" is used to mark the end of the
+   input, and is not included in the returned chain of commands. */
 
-/* Read lines from the input stream
-   and accumulate them in a chain of struct command_line's
-   which is then returned.  */
+#define END_MESSAGE "End with a line saying just \"end\"."
 
 struct command_line *
-read_command_lines ()
+read_command_lines (prompt, from_tty)
+char *prompt;
+int from_tty;
 {
   struct command_line *head, *tail, *next;
   struct cleanup *old_chain;
   enum command_control_type ret;
   enum misc_command_type val;
 
+  if (readline_begin_hook)
+    {
+      /* Note - intentional to merge messages with no newline */
+      (*readline_begin_hook) ("%s  %s\n", prompt, END_MESSAGE);
+    }
+  else if (from_tty && input_from_terminal_p ())
+    {
+      printf_unfiltered ("%s\n%s\n", prompt, END_MESSAGE);
+      gdb_flush (gdb_stdout);
+    }
+
   head = tail = NULL;
   old_chain = NULL;
 
@@ -2396,7 +2523,8 @@ read_command_lines ()
       else
        {
          head = next;
-         old_chain = make_cleanup (free_command_lines, &head);
+         old_chain = make_cleanup ((make_cleanup_func) free_command_lines, 
+                                    &head);
        }
       tail = next;
     }
@@ -2408,13 +2536,16 @@ read_command_lines ()
       if (ret != invalid_control)
        {
          discard_cleanups (old_chain);
-         return head;
        }
       else
        do_cleanups (old_chain);
     }
 
-  return NULL;
+  if (readline_end_hook)
+    {
+      (*readline_end_hook) ();
+    }
+  return (head);
 }
 
 /* Free a chain of struct command_line's.  */
@@ -2568,7 +2699,7 @@ validate_comname (comname)
   p = comname;
   while (*p)
     {
-      if (!isalnum(*p) && *p != '-')
+      if (!isalnum(*p) && *p != '-' && *p != '_')
        error ("Junk in argument list: \"%s\"", p);
       p++;
     }
@@ -2590,6 +2721,7 @@ define_command (comname, from_tty)
   register struct command_line *cmds;
   register struct cmd_list_element *c, *newc, *hookc = 0;
   char *tem = comname;
+  char tmpbuf[128];
 #define        HOOK_STRING     "hook-"
 #define        HOOK_LEN 5
 
@@ -2637,15 +2769,9 @@ define_command (comname, from_tty)
   for (tem = comname; *tem; tem++)
     if (isupper(*tem)) *tem = tolower(*tem);
 
-  if (from_tty)
-    {
-      printf_unfiltered ("Type commands for definition of \"%s\".\n\
-End with a line saying just \"end\".\n", comname);
-      gdb_flush (gdb_stdout);
-    }
-
   control_level = 0;
-  cmds = read_command_lines ();
+  sprintf (tmpbuf, "Type commands for definition of \"%s\".", comname);
+  cmds = read_command_lines (tmpbuf, from_tty);
 
   if (c && c->class == class_user)
     free_command_lines (&c->user_commands);
@@ -2672,6 +2798,7 @@ document_command (comname, from_tty)
   struct command_line *doclines;
   register struct cmd_list_element *c;
   char *tem = comname;
+  char tmpbuf[128];
 
   validate_comname (comname);
 
@@ -2680,11 +2807,8 @@ document_command (comname, from_tty)
   if (c->class != class_user)
     error ("Command \"%s\" is built-in.", comname);
 
-  if (from_tty)
-    printf_unfiltered ("Type documentation for \"%s\".\n\
-End with a line saying just \"end\".\n", comname);
-
-  doclines = read_command_lines ();
+  sprintf (tmpbuf, "Type documentation for \"%s\".", comname);
+  doclines = read_command_lines (tmpbuf, from_tty);
 
   if (c->doc) free (c->doc);
 
@@ -2709,29 +2833,44 @@ End with a line saying just \"end\".\n", comname);
   free_command_lines (&doclines);
 }
 \f
-void
-print_gnu_advertisement ()
-{
-    printf_unfiltered ("\
-GDB is free software and you are welcome to distribute copies of it\n\
- under certain conditions; type \"show copying\" to see the conditions.\n\
-There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\
-");
-}
-
+/* Print the GDB banner. */
 void
 print_gdb_version (stream)
   GDB_FILE *stream;
 {
+  /* From GNU coding standards, first line is meant to be easy for a
+     program to parse, and is just canonical program name and version
+     number, which starts after last space. */
+
+  fprintf_filtered (stream, "GNU gdb %s\n", version);
+
+  /* Second line is a copyright notice. */
+
+  fprintf_filtered (stream, "Copyright 1998 Free Software Foundation, Inc.\n");
+
+  /* Following the copyright is a brief statement that the program is
+     free software, that users are free to copy and change it on
+     certain conditions, that it is covered by the GNU GPL, and that
+     there is no warranty. */
+
   fprintf_filtered (stream, "\
-GDB %s (%s", version, host_name);
+GDB is free software, covered by the GNU General Public License, and you are\n\
+welcome to change it and/or distribute copies of it under certain conditions.\n\
+Type \"show copying\" to see the conditions.\n\
+There is absolutely no warranty for GDB.  Type \"show warranty\" for details.\n");
 
-  if (!STREQ (host_name, target_name))
-    fprintf_filtered (stream, " --target %s", target_name);
+  /* After the required info we print the configuration information. */
 
-  fprintf_filtered (stream, "), ");
-  wrap_here("");
-  fprintf_filtered (stream, "Copyright 1995 Free Software Foundation, Inc.");
+  fprintf_filtered (stream, "This GDB was configured as \"");
+  if (!STREQ (host_name, target_name))
+    {
+      fprintf_filtered (stream, "--host=%s --target=%s", host_name, target_name);
+    }
+  else
+    {
+      fprintf_filtered (stream, "%s", host_name);
+    }
+  fprintf_filtered (stream, "\".");
 }
 
 /* ARGSUSED */
@@ -2741,7 +2880,6 @@ show_version (args, from_tty)
      int from_tty;
 {
   immediate_quit++;
-  print_gnu_advertisement ();
   print_gdb_version (gdb_stdout);
   printf_filtered ("\n");
   immediate_quit--;
@@ -2756,9 +2894,59 @@ print_prompt ()
   printf_unfiltered ("%s", prompt);
   gdb_flush (gdb_stdout);
 }
+
+/* This replaces the above for the frontends: it returns a pointer
+   to the prompt. */
+char *
+get_prompt ()
+{
+  return prompt;
+}
+
+void
+set_prompt (s)
+     char *s;
+{
+/* ??rehrauer: I don't know why this fails, since it looks as though
+   assignments to prompt are wrapped in calls to savestring...
+  if (prompt != NULL)
+    free (prompt);
+*/
+  prompt = savestring (s, strlen (s));
+}
+
 \f
+/* If necessary, make the user confirm that we should quit.  Return
+   non-zero if we should quit, zero if we shouldn't.  */
+
+int
+quit_confirm ()
+{
+  if (inferior_pid != 0 && target_has_execution)
+    {
+      char *s;
+
+      /* This is something of a hack.  But there's no reliable way to
+        see if a GUI is running.  The `use_windows' variable doesn't
+        cut it.  */
+      if (init_ui_hook)
+       s = "A debugging session is active.\nDo you still want to close the debugger?";
+      else if (attach_flag)
+       s = "The program is running.  Quit anyway (and detach it)? ";
+      else
+       s = "The program is running.  Exit anyway? ";
+
+      if (! query (s))
+       return 0;
+    }
+
+  return 1;
+}
+
+/* Quit without asking for confirmation.  */
+
 void
-quit_command (args, from_tty)
+quit_force (args, from_tty)
      char *args;
      int from_tty;
 {
@@ -2776,20 +2964,11 @@ quit_command (args, from_tty)
   if (inferior_pid != 0 && target_has_execution)
     {
       if (attach_flag)
-       {
-         if (query ("The program is running.  Quit anyway (and detach it)? "))
-           target_detach (args, from_tty);
-         else
-           error ("Not confirmed.");
-       }
+       target_detach (args, from_tty);
       else
-       {
-         if (query ("The program is running.  Quit anyway (and kill it)? "))
-           target_kill ();
-         else
-           error ("Not confirmed.");
-       }
+       target_kill ();
     }
+
   /* UDI wants this, to kill the TIP.  */
   target_close (1);
 
@@ -2797,9 +2976,33 @@ quit_command (args, from_tty)
   if (write_history_p && history_filename)
     write_history (history_filename);
 
+  do_final_cleanups(ALL_CLEANUPS);     /* Do any final cleanups before exiting */
+
+#if defined(TUI)
+  /* tuiDo((TuiOpaqueFuncPtr)tuiCleanUp); */
+  /* The above does not need to be inside a tuiDo(), since
+   * it is not manipulating the curses screen, but rather,
+   * it is tearing it down.
+   */
+  if (tui_version)
+    tuiCleanUp();
+#endif
+
   exit (exit_code);
 }
 
+/* Handle the quit command.  */
+
+void
+quit_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  if (! quit_confirm ())
+    error ("Not confirmed.");
+  quit_force (args, from_tty);
+}
+
 /* Returns whether GDB is running on a terminal and whether the user
    desires that questions be asked of them on that terminal.  */
 
@@ -2947,10 +3150,13 @@ source_command (args, from_tty)
   old_cleanups = make_cleanup (free, file);
 
   stream = fopen (file, FOPEN_RT);
-  if (stream == 0)
-    perror_with_name (file);
+  if (!stream)
+    if (from_tty)
+      perror_with_name (file);
+    else
+      return;
 
-  make_cleanup (fclose, stream);
+  make_cleanup ((make_cleanup_func) fclose, stream);
 
   old_lines.old_line = source_line_number;
   old_lines.old_file = source_file_name;
@@ -3015,102 +3221,14 @@ echo_command (text, from_tty)
   gdb_flush (gdb_stdout);
 }
 
-\f
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
-/* Functions to manipulate the endianness of the target.  */
-
-#ifndef TARGET_BYTE_ORDER_DEFAULT
-#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN
-#endif
-
-int target_byte_order = TARGET_BYTE_ORDER_DEFAULT;
-
-static int target_byte_order_auto = 1;
-
-/* Called if the user enters ``set endian'' without an argument.  */
-static void
-set_endian (args, from_tty)
-     char *args;
-     int from_tty;
-{
-  printf_unfiltered ("\"set endian\" must be followed by \"auto\", \"big\" or \"little\".\n");
-  show_endian (args, from_tty);
-}
-
-/* Called by ``set endian big''.  */
-static void
-set_endian_big (args, from_tty)
-     char *args;
-     int from_tty;
-{
-  target_byte_order = BIG_ENDIAN;
-  target_byte_order_auto = 0;
-}
-
-/* Called by ``set endian little''.  */
-static void
-set_endian_little (args, from_tty)
-     char *args;
-     int from_tty;
-{
-  target_byte_order = LITTLE_ENDIAN;
-  target_byte_order_auto = 0;
-}
-
-/* Called by ``set endian auto''.  */
-static void
-set_endian_auto (args, from_tty)
-     char *args;
-     int from_tty;
-{
-  target_byte_order_auto = 1;
-}
-
-/* Called by ``show endian''.  */
+/* ARGSUSED */
 static void
-show_endian (args, from_tty)
-     char *args;
+dont_repeat_command (ignored, from_tty)
+     char *ignored;
      int from_tty;
 {
-  const char *msg =
-    (target_byte_order_auto
-     ? "The target endianness is set automatically (currently %s endian)\n"
-     : "The target is assumed to be %s endian\n");
-  printf_unfiltered ((char *) msg, TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-}
-
-#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
-/* Set the endianness from a BFD.  */
-void
-set_endian_from_file (abfd)
-     bfd *abfd;
-{
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-  int want;
-
-  if (abfd->xvec->byteorder_big_p)
-    want = BIG_ENDIAN;
-  else
-    want = LITTLE_ENDIAN;
-  if (target_byte_order_auto)
-    target_byte_order = want;
-  else if (target_byte_order != want)
-    warning ("%s endian file does not match %s endian target.",
-            want == BIG_ENDIAN ? "big" : "little",
-            TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-
-#else /* ! defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
-  if (abfd->xvec->byteorder_big_p
-      ? TARGET_BYTE_ORDER != BIG_ENDIAN
-      : TARGET_BYTE_ORDER == BIG_ENDIAN)
-    warning ("%s endian file does not match %s endian target.",
-            abfd->xvec->byteorder_big_p ? "big" : "little",
-            TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-
-#endif /* ! defined (TARGET_BYTE_ORDER_SELECTABLE) */
+  *line = 0;           /* Can't call dont_repeat here because we're not
+                          necessarily reading from stdin.  */
 }
 \f
 /* Functions to manipulate command line editing control variables.  */
@@ -3277,14 +3395,13 @@ init_cmd_lists ()
   infolist = NULL;
   enablelist = NULL;
   disablelist = NULL;
+  togglelist = NULL;
+  stoplist = NULL;
   deletelist = NULL;
   enablebreaklist = NULL;
   setlist = NULL;
   unsetlist = NULL;
   showlist = NULL;
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-  endianlist = NULL;
-#endif
   sethistlist = NULL;
   showhistlist = NULL;
   unsethistlist = NULL;
@@ -3335,22 +3452,6 @@ init_main ()
 {
   struct cmd_list_element *c;
 
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
-  add_prefix_cmd ("endian", class_support, set_endian,
-                 "Set endianness of target.",
-                 &endianlist, "set endian ", 0, &setlist);
-  add_cmd ("big", class_support, set_endian_big,
-          "Set target as being big endian.", &endianlist);
-  add_cmd ("little", class_support, set_endian_little,
-          "Set target as being little endian.", &endianlist);
-  add_cmd ("auto", class_support, set_endian_auto,
-          "Select target endianness automatically.", &endianlist);
-  add_cmd ("endian", class_support, show_endian,
-          "Show endianness of target.", &showlist);
-
-#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
 #ifdef DEFAULT_PROMPT
   prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
 #else
@@ -3383,7 +3484,8 @@ well documented as user commands.",
 The commands in this class are those defined by the user.\n\
 Use the \"define\" command to define a command.", &cmdlist);
   add_cmd ("support", class_support, NO_FUNCTION, "Support facilities.", &cmdlist);
-  add_cmd ("status", class_info, NO_FUNCTION, "Status inquiries.", &cmdlist);
+  if (!dbx_commands)
+    add_cmd ("status", class_info, NO_FUNCTION, "Status inquiries.", &cmdlist);
   add_cmd ("files", class_files, NO_FUNCTION, "Specifying and examining files.", &cmdlist);
   add_cmd ("breakpoints", class_breakpoint, NO_FUNCTION, "Making program stop at certain points.", &cmdlist);
   add_cmd ("data", class_vars, NO_FUNCTION, "Examining data.", &cmdlist);
@@ -3449,6 +3551,9 @@ when gdb is started.", &cmdlist);
   add_com_alias ("q", "quit", class_support, 1);
   add_com_alias ("h", "help", class_support, 1);
 
+  add_com ("dont-repeat", class_support, dont_repeat_command, "Don't repeat this command.\n\
+Primarily used inside of user-defined commands that should not be repeated when\n\
+hitting return.");
 
   c = add_set_cmd ("verbose", class_support, var_boolean, (char *)&info_verbose,
                   "Set ",
@@ -3460,7 +3565,7 @@ when gdb is started.", &cmdlist);
   add_show_from_set
     (add_set_cmd ("editing", class_support, var_boolean, (char *)&command_editing_p,
           "Set editing of command lines as they are typed.\n\
-Use \"on\" to enable to enable the editing, and \"off\" to disable it.\n\
+Use \"on\" to enable the editing, and \"off\" to disable it.\n\
 Without an argument, command line editing is enabled.  To edit, use\n\
 EMACS-like or VI-like commands like control-P or ESC.", &setlist),
      &showlist);
@@ -3481,7 +3586,7 @@ Without an argument, history expansion is enabled.", &sethistlist),
   add_show_from_set
     (add_set_cmd ("save", no_class, var_boolean, (char *)&write_history_p,
           "Set saving of the history record on exit.\n\
-Use \"on\" to enable to enable the saving, and \"off\" to disable it.\n\
+Use \"on\" to enable the saving, and \"off\" to disable it.\n\
 Without an argument, saving is enabled.", &sethistlist),
      &showhistlist);
 
@@ -3555,4 +3660,18 @@ using remote targets.", &setlist),
 When enabled, each packet sent or received with the remote target\n\
 is displayed.", &setlist),
                     &showlist);
+
+  add_show_from_set (
+    add_set_cmd ("remotetimeout", no_class, var_integer, (char *)&remote_timeout,
+                  "Set timeout limit to wait for target to respond.\n\
+This value is used to set the time limit for gdb to wait for a response\n\
+from the target.", &setlist),
+                    &showlist);
+
+  c = add_set_cmd ("annotate", class_obscure, var_zinteger, 
+                  (char *)&annotation_level, "Set annotation_level.\n\
+0 == normal;     1 == fullname (for use when running under emacs)\n\
+2 == output annotated suitably for use by programs that control GDB.",
+                &setlist);
+  c = add_show_from_set (c, &showlist);
 }