2000-11-30 Fernando Nasser <fnasser@redhat.com>
authorFernando Nasser <fnasser@redhat.com>
Fri, 1 Dec 2000 00:43:47 +0000 (00:43 +0000)
committerFernando Nasser <fnasser@redhat.com>
Fri, 1 Dec 2000 00:43:47 +0000 (00:43 +0000)
        * linespec.h: New file. Declarations for linespec.c.
        * linespec.c, alpha-tdep.c, breakpoint.c, parse.c, source.c,
        symtab.c, tracepoint.c: Include the above.
        * completer.c: New file. Line completion stuff for GDB.
        (get_gdb_completer_word_break_characters,
        get_gdb_completer_quote_characters): New functions. Accessors for
        useful completer internal data.
        (filename_completer, line_completion_function, skip_quoted): Moved
        here from top.c.
        * completer.h: New file. Declarations for the above.
        * linespec.c (decode_line_1): Use
        get_gdb_completer_word_break_characters and
        get_gdb_completer_quote_characters.
        * top.c: Include completer.h.
        (filename_completer, line_completion_function, skip_quoted):
        Moved to completer.c.
        * corefile.c, exec.c, source.c, symfile.c, linespec.c: Include
        completer.h.
        * Makefile.in (SFILES): Add completer.c.
        (COMMON_OBS): Add completer.o.
        (completer.o): New target.
        (linespec.o, alpha-tdep.o, breakpoint.o, parse.o, source.o,
        symtab.o, tracepoint.o): Add linespec.h to dependencies list.
        (corefile.o, exec.o, source.o, symfile.o, linespec.o): Add completer.h
        to dependencies list.

16 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/alpha-tdep.c
gdb/breakpoint.c
gdb/completer.c [new file with mode: 0644]
gdb/completer.h [new file with mode: 0644]
gdb/corefile.c
gdb/exec.c
gdb/linespec.c
gdb/linespec.h [new file with mode: 0644]
gdb/parse.c
gdb/source.c
gdb/symfile.c
gdb/symtab.c
gdb/top.c
gdb/tracepoint.c

index ff53a0331462920888ee23caedc084b11f496643..d52df9cb7b3b19790ba0c7c5463637f1b47b6571 100644 (file)
@@ -1,3 +1,31 @@
+2000-11-30  Fernando Nasser  <fnasser@redhat.com>
+
+       * linespec.h: New file. Declarations for linespec.c.
+       * linespec.c, alpha-tdep.c, breakpoint.c, parse.c, source.c,
+       symtab.c, tracepoint.c: Include the above.
+       * completer.c: New file. Line completion stuff for GDB.
+       (get_gdb_completer_word_break_characters,
+       get_gdb_completer_quote_characters): New functions. Accessors for
+       useful completer internal data.
+       (filename_completer, line_completion_function, skip_quoted): Moved
+       here from top.c.
+       * completer.h: New file. Declarations for the above.
+       * linespec.c (decode_line_1): Use
+       get_gdb_completer_word_break_characters and
+        get_gdb_completer_quote_characters.
+       * top.c: Include completer.h.
+       (filename_completer, line_completion_function, skip_quoted):
+       Moved to completer.c.
+       * corefile.c, exec.c, source.c, symfile.c, linespec.c: Include
+       completer.h.
+       * Makefile.in (SFILES): Add completer.c.
+       (COMMON_OBS): Add completer.o.
+       (completer.o): New target.
+       (linespec.o, alpha-tdep.o, breakpoint.o, parse.o, source.o,
+        symtab.o, tracepoint.o): Add linespec.h to dependencies list.
+       (corefile.o, exec.o, source.o, symfile.o, linespec.o): Add completer.h
+       to dependencies list.
+
 Thu Nov 30 13:19:16 2000  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * gdbarch.c: Regenerate.
index a21b147b26935475fd3b151c0cc92990b876f492..67d63d8d4c378b6ac24349bb779ac2307111e926 100644 (file)
@@ -477,7 +477,7 @@ TARGET_FLAGS_TO_PASS = \
 SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
        buildsym.c c-exp.y c-lang.c c-typeprint.c c-valprint.c \
        ch-exp.c ch-lang.c ch-typeprint.c ch-valprint.c coffread.c \
-       command.c complaints.c corefile.c cp-valprint.c dbxread.c \
+       command.c complaints.c completer.c corefile.c cp-valprint.c dbxread.c \
        demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \
        event-loop.c event-top.c \
        expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \
@@ -623,7 +623,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
        source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \
        symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o command.o \
        expprint.o environ.o stack.o thread.o \
-       event-loop.o event-top.o inf-loop.o \
+       event-loop.o event-top.o inf-loop.o completer.o \
        gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \
        mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
        kod.o kod-cisco.o \
@@ -1148,7 +1148,7 @@ a68v-nat.o: a68v-nat.c $(defs_h) $(gdbcore_h) $(inferior_h)
 alpha-nat.o: alpha-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h
 
 alpha-tdep.o: alpha-tdep.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
-       $(inferior_h) $(symtab_h) $(dis-asm.h) gdb_string.h
+       $(inferior_h) $(symtab_h) $(dis-asm.h) gdb_string.h linespec.h
 
 # OBSOLETE altos-xdep.o: altos-xdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
 
@@ -1170,7 +1170,7 @@ blockframe.o: blockframe.c $(defs_h) $(gdbcore_h) $(inferior_h) \
 
 breakpoint.o: breakpoint.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
        $(inferior_h) language.h target.h gdbthread.h gdb_string.h \
-       gdb-events.h
+       gdb-events.h linespec.h
 
 buildsym.o: buildsym.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
        objfiles.h symfile.h $(symtab_h) gdb_string.h
@@ -1238,7 +1238,7 @@ core-regset.o: core-regset.c $(command_h) $(defs_h) $(gdbcore_h) \
        $(inferior_h) target.h gdb_string.h
 
 corefile.o: corefile.c $(dis-asm_h) $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
-       $(inferior_h) target.h language.h gdb_string.h
+       $(inferior_h) target.h language.h gdb_string.h completer.h
 
 corelow.o: corelow.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
        target.h gdbthread.h gdb_string.h
@@ -1292,7 +1292,7 @@ inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(inf_loop_h) $(event_loop_h) \
         $(event_top_h)
 
 exec.o: exec.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) $(inferior_h) \
-       target.h language.h gdb_string.h
+       target.h language.h gdb_string.h completer.h
 
 expprint.o: expprint.c $(defs_h) $(expression_h) $(gdbtypes_h) \
        language.h parser-defs.h $(symtab_h) $(value_h)
@@ -1396,7 +1396,7 @@ v850-tdep.o: v850-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(obstack_h) \
 
 tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(tracepoint_h) \
        $(gdbtypes_h) $(expression_h) $(gdbcmd_h) $(value_h) target.h \
-       language.h gdb_string.h $(readline_headers) $(remote_h)
+       language.h gdb_string.h $(readline_headers) $(remote_h) linespec.h
 
 gdbarch.o: gdbarch.c $(defs_h) $(bfd_h) $(gdbcmd_h)
 
@@ -1652,7 +1652,7 @@ hp-symtab-read.o: hp-symtab-read.c hpread.h $(bfd_h) buildsym.h complaints.h \
 
 parse.o: parse.c $(command_h) $(defs_h) $(expression_h) $(frame_h) \
        $(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
-       gdb_string.h
+       gdb_string.h linespec.h
 
 ppc-bdm.o: ppc-bdm.c $(defs_h) $(gdbcore_h) gdb_string.h $(frame_h) \
        $(inferior_h) $(bfd_h) symfile.h target.h gdb_wait.h $(gdbcmd_h) \
@@ -1848,7 +1848,7 @@ solib-svr4.o: solib.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
 
 source.o: source.c $(defs_h) $(expression_h) $(frame_h) $(gdbcmd_h) \
        $(gdbcore_h) language.h objfiles.h gnu-regex.h symfile.h $(symtab_h) \
-       gdb_string.h source.h
+       gdb_string.h source.h completer.h linespec.h
 
 sparc-nat.o: sparc-nat.c $(bfd_h) $(defs_h) $(inferior_h) $(gdbcore_h) \
        target.h
@@ -1884,7 +1884,7 @@ sun386-nat.o: sun386-nat.c $(defs_h) $(inferior_h) $(gdbcore_h)
 symfile.o: symfile.c $(breakpoint_h) complaints.h $(defs_h) \
        $(expression_h) $(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) \
        language.h objfiles.h symfile.h $(symtab_h) target.h \
-       gdb_string.h
+       gdb_string.h completer.h
 
 symm-tdep.o: symm-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
 
@@ -1897,10 +1897,11 @@ symmisc.o: symmisc.c $(bfd_h) $(breakpoint_h) $(command_h) $(defs_h) \
 symtab.o: symtab.c call-cmds.h $(defs_h) $(expression_h) $(frame_h) \
        $(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) language.h objfiles.h \
        gnu-regex.h symfile.h $(symtab_h) target.h $(value_h) \
-       gdb_string.h
+       gdb_string.h linespec.h
 
-linespec.o: linespec.c $(defs_h) $(gdbcmd_h) $(gdbtypes_h) objfiles.h \
-       symfile.h $(symtab_h) $(INCLUDE_DIR)/demangle.h inferior.h
+linespec.o: linespec.c linespec.h $(defs_h) $(frame_h) $(value_h) \
+       objfiles.h symfile.h completer.h $(symtab_h) \
+       $(INCLUDE_DIR)/demangle.h command.h
 
 # OBSOLETE tahoe-tdep.o: tahoe-tdep.c $(OP_INCLUDE)/tahoe.h $(defs_h) \
 # OBSOLETE     $(symtab_h)
@@ -1912,9 +1913,13 @@ target.o: target.c $(bfd_h) $(defs_h) $(gdbcmd_h) $(inferior_h) \
 
 thread.o: thread.c $(defs_h) gdbthread.h $(gdbcmd_h) target.h
 
+completer.o: completer.c completer.h $(gdbtypes_h) $(symtab_h) \
+       $(defs_h) $(gdbcmd_h) $(expression_h) $(readline_headers)
+
 top.o: top.c top.h $(bfd_h) $(getopt_h) $(readline_headers) call-cmds.h \
        $(defs_h) $(gdbcmd_h) $(inferior_h) language.h signals.h \
-       $(remote_utils_h) gdb_string.h $(event_loop_h) $(event_top_h) $(version_h)
+       $(remote_utils_h) gdb_string.h $(event_loop_h) $(event_top_h) \
+       completer.h $(version_h)
 
 typeprint.o: typeprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
        $(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \
index 3897cd669e30f185004d4096142e847a9c857aea..45c4bc0f7aa3f7dd1fabb72370570ab8a0911804 100644 (file)
@@ -29,6 +29,7 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "gdb_string.h"
+#include "linespec.h"
 
 /* FIXME: Some of this code should perhaps be merged with mips-tdep.c.  */
 
index d7b128ce506a430de0d9e2ea7434c72f37d3c03b..d2a2a75e639bc5eb45e3030db625bb9b759ed588 100644 (file)
@@ -39,6 +39,7 @@
 #include "annotate.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "linespec.h"
 #ifdef UI_OUT
 #include "ui-out.h"
 #endif
diff --git a/gdb/completer.c b/gdb/completer.c
new file mode 100644 (file)
index 0000000..bd23ca8
--- /dev/null
@@ -0,0 +1,470 @@
+/* Line completion stuff for GDB, the GNU debugger.
+   Copyright 2000 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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+
+/* FIXME: This is needed because of lookup_cmd_1().
+   We should be calling a hook instead so we eliminate the CLI dependency. */
+#include "gdbcmd.h"
+
+/* Needed for rl_completer_word_break_characters() */
+#include <readline/readline.h>
+
+/* readline defines this.  */
+#undef savestring
+
+#include "completer.h"
+
+/* Prototypes for local functions */
+
+/* readline uses the word breaks for two things:
+   (1) In figuring out where to point the TEXT parameter to the
+   rl_completion_entry_function.  Since we don't use TEXT for much,
+   it doesn't matter a lot what the word breaks are for this purpose, but
+   it does affect how much stuff M-? lists.
+   (2) If one of the matches contains a word break character, readline
+   will quote it.  That's why we switch between
+   gdb_completer_word_break_characters and
+   gdb_completer_command_word_break_characters.  I'm not sure when
+   we need this behavior (perhaps for funky characters in C++ symbols?).  */
+
+/* Variables which are necessary for fancy command line editing.  */
+static char *gdb_completer_word_break_characters =
+" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-";
+
+/* When completing on command names, we remove '-' from the list of
+   word break characters, since we use it in command names.  If the
+   readline library sees one in any of the current completion strings,
+   it thinks that the string needs to be quoted and automatically supplies
+   a leading quote. */
+static char *gdb_completer_command_word_break_characters =
+" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,";
+
+/* When completing on file names, we remove from the list of word
+   break characters any characters that are commonly used in file
+   names, such as '-', '+', '~', etc.  Otherwise, readline displays
+   incorrect completion candidates.  */
+static char *gdb_completer_file_name_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. */
+static char *gdb_completer_quote_characters = "'";
+\f
+/* Accessor for some completer data that may interest other files. */
+
+char *
+get_gdb_completer_word_break_characters (void)
+{
+  return gdb_completer_word_break_characters;
+}
+
+char *
+get_gdb_completer_quote_characters (void)
+{
+  return gdb_completer_quote_characters;
+}
+
+/* Complete on filenames.  */
+char **
+filename_completer (char *text, char *word)
+{
+  /* From readline.  */
+extern char *filename_completion_function (char *, int);
+  int subsequent_name;
+  char **return_val;
+  int return_val_used;
+  int return_val_alloced;
+
+  return_val_used = 0;
+  /* Small for testing.  */
+  return_val_alloced = 1;
+  return_val = (char **) xmalloc (return_val_alloced * sizeof (char *));
+
+  subsequent_name = 0;
+  while (1)
+    {
+      char *p;
+      p = filename_completion_function (text, subsequent_name);
+      if (return_val_used >= return_val_alloced)
+       {
+         return_val_alloced *= 2;
+         return_val =
+           (char **) xrealloc (return_val,
+                               return_val_alloced * sizeof (char *));
+       }
+      if (p == NULL)
+       {
+         return_val[return_val_used++] = p;
+         break;
+       }
+      /* We need to set subsequent_name to a non-zero value before the
+        continue line below, because otherwise, if the first file seen
+        by GDB is a backup file whose name ends in a `~', we will loop
+        indefinitely.  */
+      subsequent_name = 1;
+      /* Like emacs, don't complete on old versions.  Especially useful
+         in the "source" command.  */
+      if (p[strlen (p) - 1] == '~')
+       continue;
+
+      {
+       char *q;
+       if (word == text)
+         /* Return exactly p.  */
+         return_val[return_val_used++] = p;
+       else if (word > text)
+         {
+           /* Return some portion of p.  */
+           q = xmalloc (strlen (p) + 5);
+           strcpy (q, p + (word - text));
+           return_val[return_val_used++] = q;
+           free (p);
+         }
+       else
+         {
+           /* Return some of TEXT plus p.  */
+           q = xmalloc (strlen (p) + (text - word) + 5);
+           strncpy (q, word, text - word);
+           q[text - word] = '\0';
+           strcat (q, p);
+           return_val[return_val_used++] = q;
+           free (p);
+         }
+      }
+    }
+#if 0
+  /* There is no way to do this just long enough to affect quote inserting
+     without also affecting the next completion.  This should be fixed in
+     readline.  FIXME.  */
+  /* Insure that readline does the right thing
+     with respect to inserting quotes.  */
+  rl_completer_word_break_characters = "";
+#endif
+  return return_val;
+}
+
+/* Here are some useful test cases for completion.  FIXME: These should
+   be put in the test suite.  They should be tested with both M-? and TAB.
+
+   "show output-" "radix"
+   "show output" "-radix"
+   "p" ambiguous (commands starting with p--path, print, printf, etc.)
+   "p "  ambiguous (all symbols)
+   "info t foo" no completions
+   "info t " no completions
+   "info t" ambiguous ("info target", "info terminal", etc.)
+   "info ajksdlfk" no completions
+   "info ajksdlfk " no completions
+   "info" " "
+   "info " ambiguous (all info commands)
+   "p \"a" no completions (string constant)
+   "p 'a" ambiguous (all symbols starting with a)
+   "p b-a" ambiguous (all symbols starting with a)
+   "p b-" ambiguous (all symbols)
+   "file Make" "file" (word break hard to screw up here)
+   "file ../gdb.stabs/we" "ird" (needs to not break word at slash)
+ */
+
+/* Generate completions one by one for the completer.  Each time we are
+   called return another potential completion to the caller.
+   line_completion just completes on commands or passes the buck to the
+   command's completer function, the stuff specific to symbol completion
+   is in make_symbol_completion_list.
+
+   TEXT is the caller's idea of the "word" we are looking at.
+
+   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.
+
+   LINE_BUFFER is available to be looked at; it contains the entire text
+   of the line.  POINT is the offset in that line of the cursor.  You
+   should pretend that the line ends at POINT.
+
+   Returns NULL if there are no more completions, else a pointer to a string
+   which is a possible completion, it is the caller's responsibility to
+   free the string.  */
+
+char *
+line_completion_function (char *text, int matches, char *line_buffer, int point)
+{
+  static char **list = (char **) NULL; /* Cache of completions */
+  static int index;            /* Next cached completion */
+  char *output = NULL;
+  char *tmp_command, *p;
+  /* Pointer within tmp_command which corresponds to text.  */
+  char *word;
+  struct cmd_list_element *c, *result_list;
+
+  if (matches == 0)
+    {
+      /* 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 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;
+
+      /* Choose the default set of word break characters to break completions.
+         If we later find out that we are doing completions on command strings
+         (as opposed to strings supplied by the individual command completer
+         functions, which can be any string) then we will switch to the
+         special word break set for command strings, which leaves out the
+         '-' character used in some commands.  */
+
+      rl_completer_word_break_characters =
+       gdb_completer_word_break_characters;
+
+      /* Decide whether to complete on a list of gdb commands or on symbols. */
+      tmp_command = (char *) alloca (point + 1);
+      p = tmp_command;
+
+      strncpy (tmp_command, line_buffer, point);
+      tmp_command[point] = '\0';
+      /* Since text always contains some number of characters leading up
+         to point, we can find the equivalent position in tmp_command
+         by subtracting that many characters from the end of tmp_command.  */
+      word = tmp_command + point - strlen (text);
+
+      if (point == 0)
+       {
+         /* 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);
+       }
+
+      /* Move p up to the next interesting thing.  */
+      while (*p == ' ' || *p == '\t')
+       {
+         p++;
+       }
+
+      if (!c)
+       {
+         /* It is an unrecognized command.  So there are no
+            possible completions.  */
+         list = NULL;
+       }
+      else if (c == (struct cmd_list_element *) -1)
+       {
+         char *q;
+
+         /* lookup_cmd_1 advances p up to the first ambiguous thing, but
+            doesn't advance over that thing itself.  Do so now.  */
+         q = p;
+         while (*q && (isalnum (*q) || *q == '-' || *q == '_'))
+           ++q;
+         if (q != tmp_command + point)
+           {
+             /* There is something beyond the ambiguous
+                command, so there are no possible completions.  For
+                example, "info t " or "info t foo" does not complete
+                to anything, because "info t" can be "info target" or
+                "info terminal".  */
+             list = NULL;
+           }
+         else
+           {
+             /* We're trying to complete on the command which was ambiguous.
+                This we can deal with.  */
+             if (result_list)
+               {
+                 list = complete_on_cmdlist (*result_list->prefixlist, p,
+                                             word);
+               }
+             else
+               {
+                 list = complete_on_cmdlist (cmdlist, p, word);
+               }
+             /* Insure that readline does the right thing with respect to
+                inserting quotes.  */
+             rl_completer_word_break_characters =
+               gdb_completer_command_word_break_characters;
+           }
+       }
+      else
+       {
+         /* We've recognized a full command.  */
+
+         if (p == tmp_command + point)
+           {
+             /* There is no non-whitespace in the line beyond the command.  */
+
+             if (p[-1] == ' ' || p[-1] == '\t')
+               {
+                 /* The command is followed by whitespace; we need to complete
+                    on whatever comes after command.  */
+                 if (c->prefixlist)
+                   {
+                     /* It is a prefix command; what comes after it is
+                        a subcommand (e.g. "info ").  */
+                     list = complete_on_cmdlist (*c->prefixlist, p, word);
+
+                     /* Insure that readline does the right thing
+                        with respect to inserting quotes.  */
+                     rl_completer_word_break_characters =
+                       gdb_completer_command_word_break_characters;
+                   }
+                 else if (c->enums)
+                   {
+                     list = complete_on_enum (c->enums, p, word);
+                     rl_completer_word_break_characters =
+                       gdb_completer_command_word_break_characters;
+                   }
+                 else
+                   {
+                     /* It is a normal command; what comes after it is
+                        completed by the command's completer function.  */
+                     list = (*c->completer) (p, word);
+                     if (c->completer == filename_completer)
+                       rl_completer_word_break_characters =
+                         gdb_completer_file_name_break_characters;
+                   }
+               }
+             else
+               {
+                 /* The command is not followed by whitespace; we need to
+                    complete on the command itself.  e.g. "p" which is a
+                    command itself but also can complete to "print", "ptype"
+                    etc.  */
+                 char *q;
+
+                 /* Find the command we are completing on.  */
+                 q = p;
+                 while (q > tmp_command)
+                   {
+                     if (isalnum (q[-1]) || q[-1] == '-' || q[-1] == '_')
+                       --q;
+                     else
+                       break;
+                   }
+
+                 list = complete_on_cmdlist (result_list, q, word);
+
+                 /* Insure that readline does the right thing
+                    with respect to inserting quotes.  */
+                 rl_completer_word_break_characters =
+                   gdb_completer_command_word_break_characters;
+               }
+           }
+         else
+           {
+             /* There is non-whitespace beyond the command.  */
+
+             if (c->prefixlist && !c->allow_unknown)
+               {
+                 /* It is an unrecognized subcommand of a prefix command,
+                    e.g. "info adsfkdj".  */
+                 list = NULL;
+               }
+             else if (c->enums)
+               {
+                 list = complete_on_enum (c->enums, p, word);
+               }
+             else
+               {
+                 /* It is a normal command.  */
+                 list = (*c->completer) (p, word);
+                 if (c->completer == filename_completer)
+                   rl_completer_word_break_characters =
+                     gdb_completer_file_name_break_characters;
+               }
+           }
+       }
+    }
+
+  /* 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. */
+
+  if (list)
+    {
+      output = list[index];
+      if (output)
+       {
+         index++;
+       }
+    }
+
+#if 0
+  /* Can't do this because readline hasn't yet checked the word breaks
+     for figuring out whether to insert a quote.  */
+  if (output == NULL)
+    /* Make sure the word break characters are set back to normal for the
+       next time that readline tries to complete something.  */
+    rl_completer_word_break_characters =
+      gdb_completer_word_break_characters;
+#endif
+
+  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 (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);
+}
+
diff --git a/gdb/completer.h b/gdb/completer.h
new file mode 100644 (file)
index 0000000..518b300
--- /dev/null
@@ -0,0 +1,34 @@
+/* Header for GDB line completion.
+   Copyright 2000 Free Software Foundation.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#if !defined (COMPLETER_H)
+#define COMPLETER_H 1
+
+extern char *line_completion_function (char *, int, char *, int);
+
+extern char **filename_completer (char *, char *);
+
+extern char *get_gdb_completer_word_break_characters (void); 
+
+extern char *get_gdb_completer_quote_characters (void);
+
+/* Exported to linespec.c */
+
+extern char *skip_quoted (char *str);
+
+#endif /* defined (COMPLETER_H) */
index 5c816b125e772873d07515c988983f54fe82613f..38bef9a27fe8fae7a954f1da2f850876e49dafa3 100644 (file)
@@ -37,6 +37,7 @@
 #include "gdb_stat.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "completer.h"
 
 /* Local function declarations.  */
 
index 2051d1ebded1b5092ff614bdd1fa5ae4f5a08699..4a91fb169ef465cc9198d6b69d8c41025a0e8dc2 100644 (file)
@@ -27,6 +27,7 @@
 #include "language.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "completer.h"
 
 #ifdef USG
 #include <sys/types.h>
index 4d3af751df9d2e9cc0fab8b37d996dc785bb426a..d6c330255c798fbb9fe26e2ab4f3668754ff4e4f 100644 (file)
 
 #include "defs.h"
 #include "symtab.h"
-#include "gdbtypes.h"
+#include "frame.h"
+#include "command.h"
 #include "symfile.h"
 #include "objfiles.h"
-#include "gdbcmd.h"
 #include "demangle.h"
-#include "inferior.h"
+#include "value.h"
+#include "completer.h"
 
 /* Prototype for one function in parser-defs.h,
    instead of including that entire file. */
@@ -573,7 +574,8 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */
 
   is_quoted = (**argptr
-              && strchr (gdb_completer_quote_characters, **argptr) != NULL);
+              && strchr (get_gdb_completer_quote_characters (),
+                         **argptr) != NULL);
 
   has_parens = ((pp = strchr (*argptr, '(')) != NULL
                && (pp = strrchr (pp, ')')) != NULL);
@@ -727,7 +729,8 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
                  /* Arg token is not digits => try it as a function name
                     Find the next token(everything up to end or next blank). */
                  if (**argptr
-                     && strchr (gdb_completer_quote_characters, **argptr) != NULL)
+                     && strchr (get_gdb_completer_quote_characters (),
+                                **argptr) != NULL)
                    {
                      p = skip_quoted (*argptr);
                      *argptr = *argptr + 1;
@@ -766,7 +769,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
                    copy[p - *argptr] = '\0';
                    if (p != *argptr
                        && copy[p - *argptr - 1]
-                       && strchr (gdb_completer_quote_characters,
+                       && strchr (get_gdb_completer_quote_characters (),
                                   copy[p - *argptr - 1]) != NULL)
                      copy[p - *argptr - 1] = '\0';
                  }
@@ -1097,7 +1100,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   if (p != *argptr
       && copy[0]
       && copy[0] == copy[p - *argptr - 1]
-      && strchr (gdb_completer_quote_characters, copy[0]) != NULL)
+      && strchr (get_gdb_completer_quote_characters (), copy[0]) != NULL)
     {
       copy[p - *argptr - 1] = '\0';
       copy++;
diff --git a/gdb/linespec.h b/gdb/linespec.h
new file mode 100644 (file)
index 0000000..4c5d021
--- /dev/null
@@ -0,0 +1,27 @@
+/* Header for GDB line completion.
+   Copyright 2000 Free Software Foundation.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#if !defined (LINESPEC_H)
+#define LINESPEC_H 1
+
+extern struct symtabs_and_lines
+       decode_line_1 (char **argptr, int funfirstline,
+                      struct symtab *default_symtab, int default_line,
+                      char ***canonical);
+
+#endif /* defined (LINESPEC_H) */
index 5ea053459ca33218cdddb3509514c243ca327888..693ab95a7cac57a351037dcdb7cd77a9e05a84f7 100644 (file)
@@ -41,6 +41,7 @@
 #include "command.h"
 #include "language.h"
 #include "parser-defs.h"
+#include "linespec.h"
 #include "gdbcmd.h"
 #include "symfile.h"           /* for overlay functions */
 #include "inferior.h"          /* for NUM_PSEUDO_REGS.  NOTE: replace 
index 49eb3bce6fe258a463389a2e29aa5f715186814b..b1bafeea954602cce3547200e244b751a1f7ca96 100644 (file)
@@ -38,6 +38,8 @@
 #include "objfiles.h"
 #include "annotate.h"
 #include "gdbtypes.h"
+#include "linespec.h"
+#include "completer.h"
 #ifdef UI_OUT
 #include "ui-out.h"
 #endif
index 05fd4fbacf1aaf237e5cc0aecc5af5ed7c4b769f..60978181bb38ce3c77ee3944809f1ca97a340701 100644 (file)
@@ -36,6 +36,7 @@
 #include "inferior.h"          /* for write_pc */
 #include "gdb-stabs.h"
 #include "obstack.h"
+#include "completer.h"
 
 #include <assert.h>
 #include <sys/types.h>
index be021dd33910d6f3c8c55ece931924803e84ffd0..9f6fb56cf2060895dd21ea71fc2aa6588da801c0 100644 (file)
@@ -35,6 +35,7 @@
 #include "language.h"
 #include "demangle.h"
 #include "inferior.h"
+#include "linespec.h"
 
 #include "obstack.h"
 
index 1022f840d6bd8e697087301d5c260a526c07f2d1..c2db730e2a3854110b2afd3b585308f73514c801 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -32,6 +32,7 @@
 #include "language.h"
 #include "terminal.h"          /* For job_control.  */
 #include "annotate.h"
+#include "completer.h"
 #include "top.h"
 #include "version.h"
 
@@ -69,8 +70,6 @@ static void init_signals (void);
 static void stop_sig (int);
 #endif
 
-static char *line_completion_function (char *, int, char *, int);
-
 static char *readline_line_completion_function (char *, int);
 
 static void while_command (char *, int);
@@ -1832,355 +1831,6 @@ noop_completer (char *text, char *prefix)
   return NULL;
 }
 
-/* Complete on filenames.  */
-char **
-filename_completer (char *text, char *word)
-{
-  /* From readline.  */
-extern char *filename_completion_function (char *, int);
-  int subsequent_name;
-  char **return_val;
-  int return_val_used;
-  int return_val_alloced;
-
-  return_val_used = 0;
-  /* Small for testing.  */
-  return_val_alloced = 1;
-  return_val = (char **) xmalloc (return_val_alloced * sizeof (char *));
-
-  subsequent_name = 0;
-  while (1)
-    {
-      char *p;
-      p = filename_completion_function (text, subsequent_name);
-      if (return_val_used >= return_val_alloced)
-       {
-         return_val_alloced *= 2;
-         return_val =
-           (char **) xrealloc (return_val,
-                               return_val_alloced * sizeof (char *));
-       }
-      if (p == NULL)
-       {
-         return_val[return_val_used++] = p;
-         break;
-       }
-      /* We need to set subsequent_name to a non-zero value before the
-        continue line below, because otherwise, if the first file seen
-        by GDB is a backup file whose name ends in a `~', we will loop
-        indefinitely.  */
-      subsequent_name = 1;
-      /* Like emacs, don't complete on old versions.  Especially useful
-         in the "source" command.  */
-      if (p[strlen (p) - 1] == '~')
-       continue;
-
-      {
-       char *q;
-       if (word == text)
-         /* Return exactly p.  */
-         return_val[return_val_used++] = p;
-       else if (word > text)
-         {
-           /* Return some portion of p.  */
-           q = xmalloc (strlen (p) + 5);
-           strcpy (q, p + (word - text));
-           return_val[return_val_used++] = q;
-           free (p);
-         }
-       else
-         {
-           /* Return some of TEXT plus p.  */
-           q = xmalloc (strlen (p) + (text - word) + 5);
-           strncpy (q, word, text - word);
-           q[text - word] = '\0';
-           strcat (q, p);
-           return_val[return_val_used++] = q;
-           free (p);
-         }
-      }
-    }
-#if 0
-  /* There is no way to do this just long enough to affect quote inserting
-     without also affecting the next completion.  This should be fixed in
-     readline.  FIXME.  */
-  /* Insure that readline does the right thing
-     with respect to inserting quotes.  */
-  rl_completer_word_break_characters = "";
-#endif
-  return return_val;
-}
-
-/* Here are some useful test cases for completion.  FIXME: These should
-   be put in the test suite.  They should be tested with both M-? and TAB.
-
-   "show output-" "radix"
-   "show output" "-radix"
-   "p" ambiguous (commands starting with p--path, print, printf, etc.)
-   "p "  ambiguous (all symbols)
-   "info t foo" no completions
-   "info t " no completions
-   "info t" ambiguous ("info target", "info terminal", etc.)
-   "info ajksdlfk" no completions
-   "info ajksdlfk " no completions
-   "info" " "
-   "info " ambiguous (all info commands)
-   "p \"a" no completions (string constant)
-   "p 'a" ambiguous (all symbols starting with a)
-   "p b-a" ambiguous (all symbols starting with a)
-   "p b-" ambiguous (all symbols)
-   "file Make" "file" (word break hard to screw up here)
-   "file ../gdb.stabs/we" "ird" (needs to not break word at slash)
- */
-
-/* Generate completions one by one for the completer.  Each time we are
-   called return another potential completion to the caller.
-   line_completion just completes on commands or passes the buck to the
-   command's completer function, the stuff specific to symbol completion
-   is in make_symbol_completion_list.
-
-   TEXT is the caller's idea of the "word" we are looking at.
-
-   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.
-
-   LINE_BUFFER is available to be looked at; it contains the entire text
-   of the line.  POINT is the offset in that line of the cursor.  You
-   should pretend that the line ends at POINT.
-
-   Returns NULL if there are no more completions, else a pointer to a string
-   which is a possible completion, it is the caller's responsibility to
-   free the string.  */
-
-static char *
-line_completion_function (char *text, int matches, char *line_buffer, int point)
-{
-  static char **list = (char **) NULL; /* Cache of completions */
-  static int index;            /* Next cached completion */
-  char *output = NULL;
-  char *tmp_command, *p;
-  /* Pointer within tmp_command which corresponds to text.  */
-  char *word;
-  struct cmd_list_element *c, *result_list;
-
-  if (matches == 0)
-    {
-      /* 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 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;
-
-      /* Choose the default set of word break characters to break completions.
-         If we later find out that we are doing completions on command strings
-         (as opposed to strings supplied by the individual command completer
-         functions, which can be any string) then we will switch to the
-         special word break set for command strings, which leaves out the
-         '-' character used in some commands.  */
-
-      rl_completer_word_break_characters =
-       gdb_completer_word_break_characters;
-
-      /* Decide whether to complete on a list of gdb commands or on symbols. */
-      tmp_command = (char *) alloca (point + 1);
-      p = tmp_command;
-
-      strncpy (tmp_command, line_buffer, point);
-      tmp_command[point] = '\0';
-      /* Since text always contains some number of characters leading up
-         to point, we can find the equivalent position in tmp_command
-         by subtracting that many characters from the end of tmp_command.  */
-      word = tmp_command + point - strlen (text);
-
-      if (point == 0)
-       {
-         /* 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);
-       }
-
-      /* Move p up to the next interesting thing.  */
-      while (*p == ' ' || *p == '\t')
-       {
-         p++;
-       }
-
-      if (!c)
-       {
-         /* It is an unrecognized command.  So there are no
-            possible completions.  */
-         list = NULL;
-       }
-      else if (c == (struct cmd_list_element *) -1)
-       {
-         char *q;
-
-         /* lookup_cmd_1 advances p up to the first ambiguous thing, but
-            doesn't advance over that thing itself.  Do so now.  */
-         q = p;
-         while (*q && (isalnum (*q) || *q == '-' || *q == '_'))
-           ++q;
-         if (q != tmp_command + point)
-           {
-             /* There is something beyond the ambiguous
-                command, so there are no possible completions.  For
-                example, "info t " or "info t foo" does not complete
-                to anything, because "info t" can be "info target" or
-                "info terminal".  */
-             list = NULL;
-           }
-         else
-           {
-             /* We're trying to complete on the command which was ambiguous.
-                This we can deal with.  */
-             if (result_list)
-               {
-                 list = complete_on_cmdlist (*result_list->prefixlist, p,
-                                             word);
-               }
-             else
-               {
-                 list = complete_on_cmdlist (cmdlist, p, word);
-               }
-             /* Insure that readline does the right thing with respect to
-                inserting quotes.  */
-             rl_completer_word_break_characters =
-               gdb_completer_command_word_break_characters;
-           }
-       }
-      else
-       {
-         /* We've recognized a full command.  */
-
-         if (p == tmp_command + point)
-           {
-             /* There is no non-whitespace in the line beyond the command.  */
-
-             if (p[-1] == ' ' || p[-1] == '\t')
-               {
-                 /* The command is followed by whitespace; we need to complete
-                    on whatever comes after command.  */
-                 if (c->prefixlist)
-                   {
-                     /* It is a prefix command; what comes after it is
-                        a subcommand (e.g. "info ").  */
-                     list = complete_on_cmdlist (*c->prefixlist, p, word);
-
-                     /* Insure that readline does the right thing
-                        with respect to inserting quotes.  */
-                     rl_completer_word_break_characters =
-                       gdb_completer_command_word_break_characters;
-                   }
-                 else if (c->enums)
-                   {
-                     list = complete_on_enum (c->enums, p, word);
-                     rl_completer_word_break_characters =
-                       gdb_completer_command_word_break_characters;
-                   }
-                 else
-                   {
-                     /* It is a normal command; what comes after it is
-                        completed by the command's completer function.  */
-                     list = (*c->completer) (p, word);
-                     if (c->completer == filename_completer)
-                       rl_completer_word_break_characters =
-                         gdb_completer_file_name_break_characters;
-                   }
-               }
-             else
-               {
-                 /* The command is not followed by whitespace; we need to
-                    complete on the command itself.  e.g. "p" which is a
-                    command itself but also can complete to "print", "ptype"
-                    etc.  */
-                 char *q;
-
-                 /* Find the command we are completing on.  */
-                 q = p;
-                 while (q > tmp_command)
-                   {
-                     if (isalnum (q[-1]) || q[-1] == '-' || q[-1] == '_')
-                       --q;
-                     else
-                       break;
-                   }
-
-                 list = complete_on_cmdlist (result_list, q, word);
-
-                 /* Insure that readline does the right thing
-                    with respect to inserting quotes.  */
-                 rl_completer_word_break_characters =
-                   gdb_completer_command_word_break_characters;
-               }
-           }
-         else
-           {
-             /* There is non-whitespace beyond the command.  */
-
-             if (c->prefixlist && !c->allow_unknown)
-               {
-                 /* It is an unrecognized subcommand of a prefix command,
-                    e.g. "info adsfkdj".  */
-                 list = NULL;
-               }
-             else if (c->enums)
-               {
-                 list = complete_on_enum (c->enums, p, word);
-               }
-             else
-               {
-                 /* It is a normal command.  */
-                 list = (*c->completer) (p, word);
-                 if (c->completer == filename_completer)
-                   rl_completer_word_break_characters =
-                     gdb_completer_file_name_break_characters;
-               }
-           }
-       }
-    }
-
-  /* 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. */
-
-  if (list)
-    {
-      output = list[index];
-      if (output)
-       {
-         index++;
-       }
-    }
-
-#if 0
-  /* Can't do this because readline hasn't yet checked the word breaks
-     for figuring out whether to insert a quote.  */
-  if (output == NULL)
-    /* Make sure the word break characters are set back to normal for the
-       next time that readline tries to complete something.  */
-    rl_completer_word_break_characters =
-      gdb_completer_word_break_characters;
-#endif
-
-  return (output);
-}
-
 /* Line completion interface function for readline.  */
 
 static char *
@@ -2189,42 +1839,7 @@ readline_line_completion_function (char *text, int matches)
   return line_completion_function (text, matches, rl_line_buffer, rl_point);
 }
 
-/* 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 (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
 stop_sig (int signo)
index 6ac375950b09d90076c6b7022d1f6f6d49074928..c33e552e2184ec59cebeb941045a1fafb7e606ca 100644 (file)
@@ -31,6 +31,7 @@
 #include "inferior.h"
 #include "tracepoint.h"
 #include "remote.h"
+#include "linespec.h"
 
 #include "ax.h"
 #include "ax-gdb.h"