* dbxread.c, i386-pinsn.c, i386-tdep.c, regex.c, solib.c, symmisc.c,
[deliverable/binutils-gdb.git] / gdb / main.c
index 35465258576f777f2039c3b1fac4d72ad61e51b0..544199f10c1e4bc14573d3c40a40d06ef8f8bca9 100644 (file)
@@ -1,5 +1,6 @@
 /* Top level `main' program for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -19,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "defs.h"
 #include "gdbcmd.h"
+#include "call-cmds.h"
 #include "symtab.h"
 #include "inferior.h"
 #include "signals.h"
@@ -648,7 +650,8 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
     }
 
   error_pre_print = "\n\n";
-  warning_pre_print = "\n\nwarning: ";
+  /* We may get more than one warning, don't double space all of them... */
+  warning_pre_print = "\nwarning: ";
 
   /* Now perform all the actions indicated by the arguments.  */
   if (cdarg != NULL)
@@ -664,7 +667,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
   for (i = 0; i < ndir; i++)
     if (!setjmp (to_top_level))
       directory_command (dirarg[i], 0);
-  free (dirarg);
+  free ((PTR)dirarg);
   do_cleanups (ALL_CLEANUPS);
 
   if (execarg != NULL
@@ -772,9 +775,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
        the same file (it should exist, also).  */
 
     if (!homedir
-       || bcmp ((char *) &homebuf,
-                (char *) &cwdbuf,
-                sizeof (struct stat)))
+       || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
       if (!inhibit_gdbinit && access (gdbinit, R_OK) == 0)
        if (!setjmp (to_top_level))
          source_command (gdbinit, 0);
@@ -790,7 +791,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
          source_command (cmdarg[i], !batch);
        do_cleanups (ALL_CLEANUPS);
       }
-  free (cmdarg);
+  free ((PTR)cmdarg);
 
   /* Read in the old history after all the command files have been read. */
   initialize_history();
@@ -1020,6 +1021,11 @@ static char *history_filename;
 /* Variables which are necessary for fancy command line editing.  */
 char *gdb_completer_word_break_characters =
   " \t\n!@#$%^&*()-+=|~`}{[]\"';:?/>.<,";
+/* Characters that can be used to quote completion strings.  Note that we
+   can't include '"' because the gdb C parser treats such quoted sequences
+   as strings. */
+char *gdb_completer_quote_characters =
+  "'";
 
 /* Functions that are used as part of the fancy command line editing.  */
 
@@ -1033,39 +1039,52 @@ noop_completer (text)
   return NULL;
 }
 
-/* Generate symbol names one by one for the completer.  If STATE is
-   zero, then we need to initialize, otherwise the initialization has
-   already taken place.  TEXT is what we expect the symbol to start
-   with.  RL_LINE_BUFFER is available to be looked at; it contains the
-   entire text of the line.  RL_POINT is the offset in that line of
-   the cursor.  You should pretend that the line ends at RL_POINT.
-   The result is NULL if there are no more completions, else a char
-   string which is a possible completion.  */
+/* Generate symbol names one by one for the completer.  Each time we are
+   called return another potential completion to the caller.
+
+   TEXT is what we expect the symbol to start with.
+
+   MATCHES is the number of matches that have currently been collected from
+   calling this completion function.  When zero, then we need to initialize,
+   otherwise the initialization has already taken place and we can just
+   return the next potential completion string.
 
+   Returns NULL if there are no more completions, else a pointer to a string
+   which is a possible completion.
+
+   RL_LINE_BUFFER is available to be looked at; it contains the entire text
+   of the line.  RL_POINT is the offset in that line of the cursor.  You
+   should pretend that the line ends at RL_POINT. */
+   
 static char *
-symbol_completion_function (text, state)
+symbol_completion_function (text, matches)
      char *text;
-     int state;
+     int matches;
 {
-  static char **list = (char **)NULL;
-  static int index;
-  char *output;
-  extern char *rl_line_buffer;
-  extern int rl_point;
+  static char **list = (char **)NULL;          /* Cache of completions */
+  static int index;                            /* Next cached completion */
+  char *output = NULL;
   char *tmp_command, *p;
   struct cmd_list_element *c, *result_list;
+  extern char *rl_line_buffer;
+  extern int rl_point;
 
-  if (!state)
+  if (matches == 0)
     {
-      /* Free the storage used by LIST, but not by the strings inside.  This is
-        because rl_complete_internal () frees the strings. */
+      /* The caller is beginning to accumulate a new set of completions, so
+        we need to find all of them now, and cache them for returning one at
+        a time on future calls. */
+
       if (list)
-       free (list);
+       {
+         /* Free the storage used by LIST, but not by the strings inside.
+            This is because rl_complete_internal () frees the strings. */
+         free ((PTR)list);
+       }
       list = 0;
       index = 0;
 
-      /* Decide whether to complete on a list of gdb commands or on
-        symbols.  */
+      /* Decide whether to complete on a list of gdb commands or on symbols. */
       tmp_command = (char *) alloca (rl_point + 1);
       p = tmp_command;
       
@@ -1074,21 +1093,27 @@ symbol_completion_function (text, state)
 
       if (rl_point == 0)
        {
-         /* An empty line we want to consider ambiguous; that is,
-            it could be any command.  */
+         /* An empty line we want to consider ambiguous; that is, it
+            could be any command.  */
          c = (struct cmd_list_element *) -1;
          result_list = 0;
        }
       else
-       c = lookup_cmd_1 (&p, cmdlist, &result_list, 1);
+       {
+         c = lookup_cmd_1 (&p, cmdlist, &result_list, 1);
+       }
 
       /* Move p up to the next interesting thing.  */
       while (*p == ' ' || *p == '\t')
-       p++;
+       {
+         p++;
+       }
 
       if (!c)
-       /* He's typed something unrecognizable.  Sigh.  */
-       list = (char **) 0;
+       {
+         /* He's typed something unrecognizable.  Sigh.  */
+         list = NULL;
+       }
       else if (c == (struct cmd_list_element *) -1)
        {
          /* If we didn't recognize everything up to the thing that
@@ -1096,25 +1121,34 @@ symbol_completion_function (text, state)
             yet, we are in trouble.  Part of the trouble might be
             that the list of delimiters used by readline includes
             '-', which we use in commands.  Check for this.  */
-         if (p + strlen(text) != tmp_command + rl_point) {
-           if (tmp_command[rl_point - strlen(text) - 1] == '-')
-             text = p;
-           else {
-             /* This really should not produce an error.  Better would
-                be to pretend to hit RETURN here; this would produce a
-                response like "Ambiguous command: foo, foobar, etc",
-                and leave the line available for re-entry with ^P.  Instead,
-                this error blows away the user's typed input without
-                any way to get it back.  */
-             error ("  Unrecognized command.");
+
+         if (p + strlen(text) != tmp_command + rl_point)
+           {
+             if (tmp_command[rl_point - strlen(text) - 1] == '-')
+               {
+                 text = p;
+               }
+             else
+               {
+                 /* This really should not produce an error.  Better would
+                    be to pretend to hit RETURN here; this would produce a
+                    response like "Ambiguous command: foo, foobar, etc",
+                    and leave the line available for re-entry with ^P.
+                    Instead, this error blows away the user's typed input
+                    without any way to get it back.  */
+                 error ("  Unrecognized command.");
+               }
            }
-         }
          
          /* He's typed something ambiguous.  This is easier.  */
          if (result_list)
-           list = complete_on_cmdlist (*result_list->prefixlist, text);
+           {
+             list = complete_on_cmdlist (*result_list->prefixlist, text);
+           }
          else
-           list = complete_on_cmdlist (cmdlist, text);
+           {
+             list = complete_on_cmdlist (cmdlist, text);
+           }
        }
       else
        {
@@ -1128,48 +1162,91 @@ symbol_completion_function (text, state)
             command.   */
 
          if (!*p && *text)
-           /* Always (might be longer versions of thie command).  */
-           list = complete_on_cmdlist (result_list, text);
+           {
+             /* Always (might be longer versions of thie command).  */
+             list = complete_on_cmdlist (result_list, text);
+           }
          else if (!*p && !*text)
            {
              if (c->prefixlist)
-               list = complete_on_cmdlist (*c->prefixlist, "");
+               {
+                 list = complete_on_cmdlist (*c->prefixlist, "");
+               }
              else
-               list = (*c->completer) ("");
+               {
+                 list = (*c->completer) ("");
+               }
            }
          else
            {
              if (c->prefixlist && !c->allow_unknown)
                {
-#if 0
-                 /* Something like "info adsfkdj".  But error() is not
-                    the proper response; just return no completions
-                    instead.  */
-                 *p = '\0';
-                 error ("\"%s\" command requires a subcommand.",
-                        tmp_command);
-#else
+                 /* Something like "info adsfkdj".  But error() is not the
+                    proper response; just return no completions instead. */
                  list = NULL;
-#endif
                }
              else
-               list = (*c->completer) (text);
+               {
+                 list = (*c->completer) (text);
+               }
            }
        }
     }
 
-  /* If the debugged program wasn't compiled with symbols, or if we're
-     clearly completing on a command and no command matches, return
-     NULL.  */
-  if (!list)
-    return ((char *)NULL);
+  /* If we found a list of potential completions during initialization then
+     dole them out one at a time.  The vector of completions is NULL
+     terminated, so after returning the last one, return NULL (and continue
+     to do so) each time we are called after that, until a new list is
+     available. */
 
-  output = list[index];
-  if (output)
-    index++;
+  if (list)
+    {
+      output = list[index];
+      if (output)
+       {
+         index++;
+       }
+    }
 
   return (output);
 }
+
+/* Skip over a possibly quoted word (as defined by the quote characters
+   and word break characters the completer uses).  Returns pointer to the
+   location after the "word". */
+
+char *
+skip_quoted (str)
+     char *str;
+{
+  char quote_char = '\0';
+  char *scan;
+
+  for (scan = str; *scan != '\0'; scan++)
+    {
+      if (quote_char != '\0')
+       {
+         /* Ignore everything until the matching close quote char */
+         if (*scan == quote_char)
+           {
+             /* Found matching close quote. */
+             scan++;
+             break;
+           }
+       }
+      else if (strchr (gdb_completer_quote_characters, *scan))
+       {
+         /* Found start of a quoted string. */
+         quote_char = *scan;
+       }
+      else if (strchr (gdb_completer_word_break_characters, *scan))
+       {
+         break;
+       }
+    }
+  return (scan);
+}
+
 \f
 #ifdef STOP_SIGNAL
 static void
@@ -1492,7 +1569,7 @@ free_command_lines (lptr)
     {
       next = l->next;
       free (l->line);
-      free (l);
+      free ((PTR)l);
       l = next;
     }
 }
@@ -1601,6 +1678,14 @@ validate_comname (comname)
     }
 }
 
+/* This is just a placeholder in the command data structures.  */
+static void
+user_defined_command (ignore, from_tty)
+     char *ignore;
+     int from_tty;
+{
+}
+
 static void
 define_command (comname, from_tty)
      char *comname;
@@ -1646,7 +1731,7 @@ End with a line saying just \"end\".\n", comname);
   if (c && c->class == class_user)
     free_command_lines (&c->user_commands);
 
-  newc = add_cmd (comname, class_user, not_just_help_class_command,
+  newc = add_cmd (comname, class_user, user_defined_command,
           (c && c->class == class_user)
           ? c->doc : savestring ("User-defined.", 13), &cmdlist);
   newc->user_commands = cmds;
@@ -2151,6 +2236,7 @@ initialize_main ()
   /* Setup important stuff for command line editing.  */
   rl_completion_entry_function = (int (*)()) symbol_completion_function;
   rl_completer_word_break_characters = gdb_completer_word_break_characters;
+  rl_completer_quote_characters = gdb_completer_quote_characters;
   rl_readline_name = "gdb";
 
   /* Define the classes of commands.
This page took 0.027397 seconds and 4 git commands to generate.