Add self to MAINTAINERS.
[deliverable/binutils-gdb.git] / gdb / top.c
index 7cdc4bdf0b1bb0653203044774977a9868580f0b..a2cee530c20be5e84f2318d6159d33b738f5ef83 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1,6 +1,8 @@
 /* Top level stuff for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -25,6 +27,7 @@
 #include "cli/cli-cmds.h"
 #include "cli/cli-script.h"
 #include "cli/cli-setshow.h"
+#include "cli/cli-decode.h"
 #include "symtab.h"
 #include "inferior.h"
 #include <signal.h>
 #include "gdb_string.h"
 #include "gdb_stat.h"
 #include <ctype.h>
-#ifdef UI_OUT
 #include "ui-out.h"
 #include "cli-out.h"
-#endif
 
 /* Default command line prompt.  This is overriden in some configs. */
 
@@ -182,7 +183,10 @@ static void stop_sig (int);
 /* Hooks for alternate command interfaces.  */
 
 /* Called after most modules have been initialized, but before taking users
-   command file.  */
+   command file.
+
+   If the UI fails to initialize and it wants GDB to continue
+   using the default UI, then it should clear this hook before returning. */
 
 void (*init_ui_hook) (char *argv0);
 
@@ -193,7 +197,7 @@ void (*init_ui_hook) (char *argv0);
 int (*ui_loop_hook) (int);
 
 /* Called instead of command_loop at top level.  Can be invoked via
-   return_to_top_level.  */
+   throw_exception().  */
 
 void (*command_loop_hook) (void);
 
@@ -295,13 +299,13 @@ NORETURN void (*error_hook) (void) ATTR_NORETURN;
 #define SIGLONGJMP(buf,val)    longjmp((buf), (val))
 #endif
 
-/* Where to go for return_to_top_level.  */
+/* Where to go for throw_exception().  */
 static SIGJMP_BUF *catch_return;
 
 /* Return for reason REASON to the nearest containing catch_errors().  */
 
 NORETURN void
-return_to_top_level (enum return_reason reason)
+throw_exception (enum return_reason reason)
 {
   quit_flag = 0;
   immediate_quit = 0;
@@ -337,7 +341,7 @@ return_to_top_level (enum return_reason reason)
 
 /* Call FUNC() with args FUNC_UIOUT and FUNC_ARGS, catching any
    errors.  Set FUNC_CAUGHT to an ``enum return_reason'' if the
-   function is aborted (using return_to_top_level() or zero if the
+   function is aborted (using throw_exception() or zero if the
    function returns normally.  Set FUNC_VAL to the value returned by
    the function or 0 if the function was aborted.
 
@@ -455,7 +459,7 @@ catcher (catch_exceptions_ftype *func,
   /* The caller didn't request that the event be caught, relay the
      event to the next containing catch_errors(). */
 
-  return_to_top_level (caught);
+  throw_exception (caught);
 }
 
 int
@@ -669,10 +673,19 @@ execute_command (char *p, int from_tty)
       /* Pass null arg rather than an empty one.  */
       arg = *p ? p : 0;
 
-      /* Clear off trailing whitespace, except for set and complete command.  */
+      /* FIXME: cagney/2002-02-02: The c->type test is pretty dodgy
+         while the is_complete_command(cfunc) test is just plain
+         bogus.  They should both be replaced by a test of the form
+         c->strip_trailing_white_space_p.  */
+      /* NOTE: cagney/2002-02-02: The function.cfunc in the below
+         can't be replaced with func.  This is because it is the
+         cfunc, and not the func, that has the value that the
+         is_complete_command hack is testing for.  */
+      /* Clear off trailing whitespace, except for set and complete
+         command.  */
       if (arg
          && c->type != set_cmd
-         && !is_complete_command (c->function.cfunc))
+         && !is_complete_command (c))
        {
          p = arg + strlen (arg) - 1;
          while (p >= arg && (*p == ' ' || *p == '\t'))
@@ -681,12 +694,7 @@ execute_command (char *p, int from_tty)
        }
 
       /* If this command has been pre-hooked, run the hook first. */
-      if ((c->hook_pre) && (!c->hook_in))
-      {
-        c->hook_in = 1; /* Prevent recursive hooking */
-        execute_user_command (c->hook_pre, (char *) 0);
-        c->hook_in = 0; /* Allow hook to work again once it is complete */
-      }
+      execute_cmd_pre_hook (c);
 
       if (c->flags & DEPRECATED_WARN_USER)
        deprecated_cmd_warning (&line);
@@ -695,20 +703,15 @@ execute_command (char *p, int from_tty)
        execute_user_command (c, arg);
       else if (c->type == set_cmd || c->type == show_cmd)
        do_setshow_command (arg, from_tty & caution, c);
-      else if (c->function.cfunc == NO_FUNCTION)
+      else if (!cmd_func_p (c))
        error ("That is not a command, just a help topic.");
       else if (call_command_hook)
        call_command_hook (c, arg, from_tty & caution);
       else
-       (*c->function.cfunc) (arg, from_tty & caution);
+       cmd_func (c, arg, from_tty & caution);
        
       /* If this command has been post-hooked, run the hook last. */
-      if ((c->hook_post) && (!c->hook_in))
-      {
-        c->hook_in = 1; /* Prevent recursive hooking */
-        execute_user_command (c->hook_post, (char *) 0);
-        c->hook_in = 0; /* allow hook to work again once it is complete */
-      }
+      execute_cmd_post_hook (c);
 
     }
 
@@ -887,11 +890,6 @@ gdb_readline (char *prompt_arg)
          character position to be off, since the newline we read from
          the user is not accounted for.  */
       fputs_unfiltered (prompt_arg, gdb_stdout);
-      /* OBSOLETE #ifdef MPW */
-      /* OBSOLETE          Move to a new line so the entered line doesn't have a prompt */
-      /* OBSOLETE          on the front of it. */
-      /* OBSOLETE       fputs_unfiltered ("\n", gdb_stdout); */
-      /* OBSOLETE #endif  *//* MPW */
       gdb_flush (gdb_stdout);
     }
 
@@ -949,6 +947,29 @@ static int write_history_p;
 static int history_size;
 static char *history_filename;
 
+/* This is like readline(), but it has some gdb-specific behavior.
+   gdb can use readline in both the synchronous and async modes during
+   a single gdb invocation.  At the ordinary top-level prompt we might
+   be using the async readline.  That means we can't use
+   rl_pre_input_hook, since it doesn't work properly in async mode.
+   However, for a secondary prompt (" >", such as occurs during a
+   `define'), gdb just calls readline() directly, running it in
+   synchronous mode.  So for operate-and-get-next to work in this
+   situation, we have to switch the hooks around.  That is what
+   gdb_readline_wrapper is for.  */
+char *
+gdb_readline_wrapper (char *prompt)
+{
+  /* Set the hook that works in this case.  */
+  if (event_loop_p && after_char_processing_hook)
+    {
+      rl_pre_input_hook = (Function *) after_char_processing_hook;
+      after_char_processing_hook = NULL;
+    }
+
+  return readline (prompt);
+}
+
 \f
 #ifdef STOP_SIGNAL
 static void
@@ -1032,6 +1053,66 @@ init_signals (void)
 #endif
 }
 \f
+/* The current saved history number from operate-and-get-next.
+   This is -1 if not valid.  */
+static int operate_saved_history = -1;
+
+/* This is put on the appropriate hook and helps operate-and-get-next
+   do its work.  */
+void
+gdb_rl_operate_and_get_next_completion (void)
+{
+  int delta = where_history () - operate_saved_history;
+  /* The `key' argument to rl_get_previous_history is ignored.  */
+  rl_get_previous_history (delta, 0);
+  operate_saved_history = -1;
+
+  /* readline doesn't automatically update the display for us.  */
+  rl_redisplay ();
+
+  after_char_processing_hook = NULL;
+  rl_pre_input_hook = NULL;
+}
+
+/* This is a gdb-local readline command handler.  It accepts the
+   current command line (like RET does) and, if this command was taken
+   from the history, arranges for the next command in the history to
+   appear on the command line when the prompt returns.
+   We ignore the arguments.  */
+static int
+gdb_rl_operate_and_get_next (int count, int key)
+{
+  int where;
+
+  if (event_loop_p)
+    {
+      /* Use the async hook.  */
+      after_char_processing_hook = gdb_rl_operate_and_get_next_completion;
+    }
+  else
+    {
+      /* This hook only works correctly when we are using the
+        synchronous readline.  */
+      rl_pre_input_hook = (Function *) gdb_rl_operate_and_get_next_completion;
+    }
+
+  /* Find the current line, and find the next line to use.  */
+  where = where_history();
+
+  /* FIXME: kettenis/20020817: max_input_history is renamed into
+     history_max_entries in readline-4.2.  When we do a new readline
+     import, we should probably change it here too, even though
+     readline maintains backwards compatibility for now by still
+     defining max_input_history.  */
+  if ((history_is_stifled () && (history_length >= max_input_history)) ||
+      (where >= history_length - 1))
+    operate_saved_history = where;
+  else
+    operate_saved_history = where + 1;
+
+  return rl_newline (1, key);
+}
+\f
 /* Read one line from the command input stream `instream'
    into the local static buffer `linebuffer' (whose current length
    is `linelength').
@@ -1130,7 +1211,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
        }
       else if (command_editing_p && instream == stdin && ISATTY (instream))
        {
-         rl = readline (local_prompt);
+         rl = gdb_readline_wrapper (local_prompt);
        }
       else
        {
@@ -1272,16 +1353,11 @@ print_gdb_version (struct ui_file *stream)
      program to parse, and is just canonical program name and version
      number, which starts after last space. */
 
-#ifdef MI_OUT
-  /* Print it console style until a format is defined */
-  fprintf_filtered (stream, "GNU gdb %s (MI_OUT)\n", version);
-#else
   fprintf_filtered (stream, "GNU gdb %s\n", version);
-#endif
 
   /* Second line is a copyright notice. */
 
-  fprintf_filtered (stream, "Copyright 2001 Free Software Foundation, Inc.\n");
+  fprintf_filtered (stream, "Copyright 2002 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
@@ -1344,7 +1420,7 @@ get_prompt_1 (void *data)
     /* formatted prompt */
     {
       char fmt[40], *promptp, *outp, *tmp;
-      value_ptr arg_val;
+      struct value *arg_val;
       DOUBLEST doubleval;
       LONGEST longval;
       CORE_ADDR addrval;
@@ -1396,7 +1472,7 @@ get_prompt_1 (void *data)
 
                  if (*promptp != gdb_prompt_escape)
                    error ("Syntax error at prompt position %d",
-                          promptp - local_prompt);
+                          (int) (promptp - local_prompt));
                  else
                    {
                      promptp++;        /* skip second escape char */
@@ -1542,7 +1618,7 @@ get_prompt_1 (void *data)
                  break;        /* void type -- no output */
                default:
                  error ("bad data type at prompt position %d",
-                        promptp - local_prompt);
+                        (int) (promptp - local_prompt));
                  break;
                }
              outp += strlen (outp);
@@ -1626,7 +1702,7 @@ quit_force (char *args, int from_tty)
      value of that expression. */
   if (args)
     {
-      value_ptr val = parse_and_eval (args);
+      struct value *val = parse_and_eval (args);
 
       exit_code = (int) value_as_long (val);
     }
@@ -1882,6 +1958,10 @@ init_main (void)
   rl_completer_quote_characters = get_gdb_completer_quote_characters ();
   rl_readline_name = "gdb";
 
+  /* The name for this defun comes from Bash, where it originated.
+     15 is Control-o, the same binding this function has in Bash.  */
+  rl_add_defun ("operate-and-get-next", gdb_rl_operate_and_get_next, 15);
+
   /* The set prompt command is different depending whether or not the
      async version is run. NOTE: this difference is going to
      disappear as we make the event loop be the default engine of
@@ -1900,7 +1980,7 @@ init_main (void)
                       (char *) &new_async_prompt, "Set gdb's prompt",
                       &setlist);
       add_show_from_set (c, &showlist);
-      c->function.sfunc = set_async_prompt;
+      set_cmd_sfunc (c, set_async_prompt);
     }
 
   add_show_from_set
@@ -1936,7 +2016,7 @@ Without an argument, command line editing is enabled.  To edit, use\n\
 EMACS-like or VI-like commands like control-P or ESC.", &setlist);
 
       add_show_from_set (c, &showlist);
-      c->function.sfunc = set_async_editing_command;
+      set_cmd_sfunc (c, set_async_editing_command);
     }
 
   add_show_from_set
@@ -1947,16 +2027,16 @@ Without an argument, saving is enabled.", &sethistlist),
      &showhistlist);
 
   c = add_set_cmd ("size", no_class, var_integer, (char *) &history_size,
-                  "Set the size of the command history, \n\
+                  "Set the size of the command history,\n\
 ie. the number of previous commands to keep a record of.", &sethistlist);
   add_show_from_set (c, &showhistlist);
-  c->function.sfunc = set_history_size_command;
+  set_cmd_sfunc (c, set_history_size_command);
 
   c = add_set_cmd ("filename", no_class, var_filename,
                   (char *) &history_filename,
                   "Set the filename in which to record the command history\n\
- (the list of previous commands of which a record is kept).", &sethistlist);
-  c->completer = filename_completer;
+(the list of previous commands of which a record is kept).", &sethistlist);
+  set_cmd_completer (c, filename_completer);
   add_show_from_set (c, &showhistlist);
 
   add_show_from_set
@@ -1987,7 +2067,7 @@ ie. the number of previous commands to keep a record of.", &sethistlist);
 2 == output annotated suitably for use by programs that control GDB.",
                       &setlist);
       add_show_from_set (c, &showlist);
-      c->function.sfunc = set_async_annotation_level;
+      set_cmd_sfunc (c, set_async_annotation_level);
     }
   if (event_loop_p)
     {
@@ -2039,7 +2119,11 @@ gdb_init (char *argv0)
   set_language (language_c);
   expected_language = current_language;                /* don't warn about the change.  */
 
-#ifdef UI_OUT
+  /* Allow another UI to initialize. If the UI fails to initialize, and
+     it wants GDB to revert to the CLI, it should clear init_ui_hook. */
+  if (init_ui_hook)
+    init_ui_hook (argv0);
+
   /* Install the default UI */
   if (!init_ui_hook)
     {
@@ -2054,8 +2138,4 @@ gdb_init (char *argv0)
          exit (1);
        }
     }
-#endif
-
-  if (init_ui_hook)
-    init_ui_hook (argv0);
 }
This page took 0.054835 seconds and 4 git commands to generate.