* ada-lang.c (ada_make_symbol_completion_list): Return a VEC.
authorTom Tromey <tromey@redhat.com>
Wed, 13 Jun 2012 15:47:16 +0000 (15:47 +0000)
committerTom Tromey <tromey@redhat.com>
Wed, 13 Jun 2012 15:47:16 +0000 (15:47 +0000)
* breakpoint.c (catch_syscall_completer): Return a VEC.
* cli/cli-cmds.c (complete_command): Update.
* cli/cli-decode.c (complete_on_cmdlist): Return a VEC.
(complete_on_enum): Likewise.
* command.h: Include gdb_vecs.h.
(completer_ftype): Change return type.
(complete_on_cmdlist, complete_on_enum): Likewise.
* completer.c (noop_completer, filename_completer)
(location_completer): Return a VEC.
(add_struct_fields): Remove 'nextp' argument.  Change 'output'
to a VEC.
(expression_completer, complete_line_internal, complete_line)
(command_completer): Return a VEC.
(gdb_completion_word_break_characters, line_completion_function):
Update.
* completer.h: Include gdb_vecs.h.
(complete_line, noop_completer, filename_completer)
(expression_completer, location_completer, command_completer):
Update.
* f-lang.c (f_word_break_characters): Return a VEC.
* interps.c (interpreter_completer): Return a VEC.
* language.h (struct language_defn)
<la_make_symbol_completion_list>: Return a VEC.
* python/py-cmd.c (cmdpy_completer): Return a VEC.
* symtab.c (free_completion_list): Take a VEC.
(return_val_size, return_val_index): Remove.
(return_val): Now a VEC.
(completion_list_add_name): Update.
(default_make_symbol_completion_list_break_on)
(default_make_symbol_completion_list, make_symbol_completion_list)
(make_symbol_completion_list_fn, make_file_symbol_completion_list):
Return a VEC.
(add_filename_to_list): Update.
(struct add_partial_filename_data) <list_used, list_alloced>: Remove.
<list>: Now a VEC.
(maybe_add_partial_symtab_filename): Update.
(make_source_files_completion_list): Return a VEC.
* symtab.h (default_make_symbol_completion_list_break_on)
(default_make_symbol_completion_list, make_symbol_completion_list)
(make_symbol_completion_list_fn, make_file_symbol_completion_list)
(make_source_files_completion_list): Update.

14 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/breakpoint.c
gdb/cli/cli-cmds.c
gdb/cli/cli-decode.c
gdb/command.h
gdb/completer.c
gdb/completer.h
gdb/f-lang.c
gdb/interps.c
gdb/language.h
gdb/python/py-cmd.c
gdb/symtab.c
gdb/symtab.h

index d36c764151256417302137b62e733de79019922e..81bd9a94599e0faf53579f579013469543bafec4 100644 (file)
@@ -1,3 +1,48 @@
+2012-06-13  Tom Tromey  <tromey@redhat.com>
+
+       * ada-lang.c (ada_make_symbol_completion_list): Return a VEC.
+       * breakpoint.c (catch_syscall_completer): Return a VEC.
+       * cli/cli-cmds.c (complete_command): Update.
+       * cli/cli-decode.c (complete_on_cmdlist): Return a VEC.
+       (complete_on_enum): Likewise.
+       * command.h: Include gdb_vecs.h.
+       (completer_ftype): Change return type.
+       (complete_on_cmdlist, complete_on_enum): Likewise.
+       * completer.c (noop_completer, filename_completer)
+       (location_completer): Return a VEC.
+       (add_struct_fields): Remove 'nextp' argument.  Change 'output'
+       to a VEC.
+       (expression_completer, complete_line_internal, complete_line)
+       (command_completer): Return a VEC.
+       (gdb_completion_word_break_characters, line_completion_function):
+       Update.
+       * completer.h: Include gdb_vecs.h.
+       (complete_line, noop_completer, filename_completer)
+       (expression_completer, location_completer, command_completer):
+       Update.
+       * f-lang.c (f_word_break_characters): Return a VEC.
+       * interps.c (interpreter_completer): Return a VEC.
+       * language.h (struct language_defn)
+       <la_make_symbol_completion_list>: Return a VEC.
+       * python/py-cmd.c (cmdpy_completer): Return a VEC.
+       * symtab.c (free_completion_list): Take a VEC.
+       (return_val_size, return_val_index): Remove.
+       (return_val): Now a VEC.
+       (completion_list_add_name): Update.
+       (default_make_symbol_completion_list_break_on)
+       (default_make_symbol_completion_list, make_symbol_completion_list)
+       (make_symbol_completion_list_fn, make_file_symbol_completion_list):
+       Return a VEC.
+       (add_filename_to_list): Update.
+       (struct add_partial_filename_data) <list_used, list_alloced>: Remove.
+       <list>: Now a VEC.
+       (maybe_add_partial_symtab_filename): Update.
+       (make_source_files_completion_list): Return a VEC.
+       * symtab.h (default_make_symbol_completion_list_break_on)
+       (default_make_symbol_completion_list, make_symbol_completion_list)
+       (make_symbol_completion_list_fn, make_file_symbol_completion_list)
+       (make_source_files_completion_list): Update.
+
 2012-06-13  Tom Tromey  <tromey@redhat.com>
 
        * breakpoint.c (add_catch_command): Use completer_ftype.
index af0fdb5e53f6d4beaed589becaeedcbe4a8ed930..6f654720645eef3316d50f56b0660684a7b870b7 100644 (file)
@@ -5797,11 +5797,10 @@ ada_expand_partial_symbol_name (const char *name, void *user_data)
                                   data->wild_match, data->encoded) != NULL;
 }
 
-/* Return a list of possible symbol names completing TEXT0.  The list
-   is NULL terminated.  WORD is the entire command on which completion
-   is made.  */
+/* Return a list of possible symbol names completing TEXT0.  WORD is
+   the entire command on which completion is made.  */
 
-static char **
+static VEC (char_ptr) *
 ada_make_symbol_completion_list (char *text0, char *word)
 {
   char *text;
@@ -5914,24 +5913,7 @@ ada_make_symbol_completion_list (char *text0, char *word)
     }
   }
 
-  /* Append the closing NULL entry.  */
-  VEC_safe_push (char_ptr, completions, NULL);
-
-  /* Make a copy of the COMPLETIONS VEC before we free it, and then
-     return the copy.  It's unfortunate that we have to make a copy
-     of an array that we're about to destroy, but there is nothing much
-     we can do about it.  Fortunately, it's typically not a very large
-     array.  */
-  {
-    const size_t completions_size = 
-      VEC_length (char_ptr, completions) * sizeof (char *);
-    char **result = xmalloc (completions_size);
-    
-    memcpy (result, VEC_address (char_ptr, completions), completions_size);
-
-    VEC_free (char_ptr, completions);
-    return result;
-  }
+  return completions;
 }
 
                                 /* Field Access */
index 8e9029871e1ae909c174e4f985ce2334fa261fde..d76065dc4ed5bc332bc157a0bc709f41c6bebd2e 100644 (file)
@@ -14578,12 +14578,12 @@ catching_syscall_number (int syscall_number)
 }
 
 /* Complete syscall names.  Used by "catch syscall".  */
-static char **
+static VEC (char_ptr) *
 catch_syscall_completer (struct cmd_list_element *cmd,
                          char *text, char *word)
 {
   const char **list = get_syscall_names ();
-  char **retlist
+  VEC (char_ptr) *retlist
     = (list == NULL) ? NULL : complete_on_enum (list, text, word);
 
   xfree (list);
index e5fa20606c9cd2c80d623403f261dc624aed134d..24d55c388073b428511863297c9387c201fc7a23 100644 (file)
@@ -254,7 +254,8 @@ static void
 complete_command (char *arg, int from_tty)
 {
   int argpoint;
-  char **completions, *point, *arg_prefix;
+  char *point, *arg_prefix;
+  VEC (char_ptr) *completions;
 
   dont_repeat ();
 
@@ -282,33 +283,30 @@ complete_command (char *arg, int from_tty)
 
   if (completions)
     {
-      int item, size;
+      int ix, size = VEC_length (char_ptr, completions);
+      char *item, *prev = NULL;
 
-      for (size = 0; completions[size]; ++size)
-       ;
-      qsort (completions, size, sizeof (char *), compare_strings);
+      qsort (VEC_address (char_ptr, completions), size,
+            sizeof (char *), compare_strings);
 
       /* We do extra processing here since we only want to print each
         unique item once.  */
-      item = 0;
-      while (item < size)
+      for (ix = 0; VEC_iterate (char_ptr, completions, ix, item); ++ix)
        {
          int next_item;
 
-         printf_unfiltered ("%s%s\n", arg_prefix, completions[item]);
-         next_item = item + 1;
-         while (next_item < size
-                && ! strcmp (completions[item], completions[next_item]))
+         if (prev == NULL || strcmp (item, prev) != 0)
            {
-             xfree (completions[next_item]);
-             ++next_item;
+             printf_unfiltered ("%s%s\n", arg_prefix, item);
+             xfree (prev);
+             prev = item;
            }
-
-         xfree (completions[item]);
-         item = next_item;
+         else
+           xfree (item);
        }
 
-      xfree (completions);
+      xfree (prev);
+      VEC_free (char_ptr, completions);
     }
 }
 
index 2974d113f51bf1b369c5881574ab54e7442bcb48..c337b43f813240ea46bd77f9a456a2cb2cb7536e 100644 (file)
@@ -1637,26 +1637,20 @@ lookup_cmd_composition (char *text,
    "foo" and we want to complete to "foobar".  If WORD is "oo", return
    "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
 
-char **
+VEC (char_ptr) *
 complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
 {
   struct cmd_list_element *ptr;
-  char **matchlist;
-  int sizeof_matchlist;
-  int matches;
+  VEC (char_ptr) *matchlist = NULL;
   int textlen = strlen (text);
   int pass;
   int saw_deprecated_match = 0;
 
-  sizeof_matchlist = 10;
-  matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
-  matches = 0;
-
   /* We do one or two passes.  In the first pass, we skip deprecated
      commands.  If we see no matching commands in the first pass, and
      if we did happen to see a matching deprecated command, we do
      another loop to collect those.  */
-  for (pass = 0; matches == 0 && pass < 2; ++pass)
+  for (pass = 0; matchlist == 0 && pass < 2; ++pass)
     {
       for (ptr = list; ptr; ptr = ptr->next)
        if (!strncmp (ptr->name, text, textlen)
@@ -1664,6 +1658,8 @@ complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
            && (ptr->func
                || ptr->prefixlist))
          {
+           char *match;
+
            if (pass == 0)
              {
                if ((ptr->flags & CMD_DEPRECATED) != 0)
@@ -1673,31 +1669,22 @@ complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
                  }
              }
 
-           if (matches == sizeof_matchlist)
-             {
-               sizeof_matchlist *= 2;
-               matchlist = (char **) xrealloc ((char *) matchlist,
-                                               (sizeof_matchlist
-                                                * sizeof (char *)));
-             }
-
-           matchlist[matches] = (char *)
-             xmalloc (strlen (word) + strlen (ptr->name) + 1);
+           match = (char *) xmalloc (strlen (word) + strlen (ptr->name) + 1);
            if (word == text)
-             strcpy (matchlist[matches], ptr->name);
+             strcpy (match, ptr->name);
            else if (word > text)
              {
                /* Return some portion of ptr->name.  */
-               strcpy (matchlist[matches], ptr->name + (word - text));
+               strcpy (match, ptr->name + (word - text));
              }
            else
              {
                /* Return some of text plus ptr->name.  */
-               strncpy (matchlist[matches], word, text - word);
-               matchlist[matches][text - word] = '\0';
-               strcat (matchlist[matches], ptr->name);
+               strncpy (match, word, text - word);
+               match[text - word] = '\0';
+               strcat (match, ptr->name);
              }
-           ++matches;
+           VEC_safe_push (char_ptr, matchlist, match);
          }
       /* If we saw no matching deprecated commands in the first pass,
         just bail out.  */
@@ -1705,18 +1692,6 @@ complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
        break;
     }
 
-  if (matches == 0)
-    {
-      xfree (matchlist);
-      matchlist = 0;
-    }
-  else
-    {
-      matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
-                                                       * sizeof (char *)));
-      matchlist[matches] = (char *) 0;
-    }
-
   return matchlist;
 }
 
@@ -1730,64 +1705,39 @@ complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
    and we want to complete to "foobar".  If WORD is "oo", return
    "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
 
-char **
+VEC (char_ptr) *
 complete_on_enum (const char *const *enumlist,
                  char *text,
                  char *word)
 {
-  char **matchlist;
-  int sizeof_matchlist;
-  int matches;
+  VEC (char_ptr) *matchlist = NULL;
   int textlen = strlen (text);
   int i;
   const char *name;
 
-  sizeof_matchlist = 10;
-  matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
-  matches = 0;
-
   for (i = 0; (name = enumlist[i]) != NULL; i++)
     if (strncmp (name, text, textlen) == 0)
       {
-       if (matches == sizeof_matchlist)
-         {
-           sizeof_matchlist *= 2;
-           matchlist = (char **) xrealloc ((char *) matchlist,
-                                           (sizeof_matchlist
-                                            * sizeof (char *)));
-         }
+       char *match;
 
-       matchlist[matches] = (char *)
-         xmalloc (strlen (word) + strlen (name) + 1);
+       match = (char *) xmalloc (strlen (word) + strlen (name) + 1);
        if (word == text)
-         strcpy (matchlist[matches], name);
+         strcpy (match, name);
        else if (word > text)
          {
            /* Return some portion of name.  */
-           strcpy (matchlist[matches], name + (word - text));
+           strcpy (match, name + (word - text));
          }
        else
          {
            /* Return some of text plus name.  */
-           strncpy (matchlist[matches], word, text - word);
-           matchlist[matches][text - word] = '\0';
-           strcat (matchlist[matches], name);
+           strncpy (match, word, text - word);
+           match[text - word] = '\0';
+           strcat (match, name);
          }
-       ++matches;
+       VEC_safe_push (char_ptr, matchlist, match);
       }
 
-  if (matches == 0)
-    {
-      xfree (matchlist);
-      matchlist = 0;
-    }
-  else
-    {
-      matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
-                                                          * sizeof (char *)));
-      matchlist[matches] = (char *) 0;
-    }
-
   return matchlist;
 }
 
index eba3a5b9571540c38b69a796a01f4a5613ccb993..3064ce29a8125f8893126f271a8e9cbd7a8b18ae 100644 (file)
@@ -19,6 +19,8 @@
 #if !defined (COMMAND_H)
 #define COMMAND_H 1
 
+#include "gdb_vecs.h"
+
 /* This file defines the public interface for any code wanting to
    create commands.  */
 
@@ -149,7 +151,8 @@ typedef void cmd_sfunc_ftype (char *args, int from_tty,
 extern void set_cmd_sfunc (struct cmd_list_element *cmd,
                           cmd_sfunc_ftype *sfunc);
 
-typedef char **completer_ftype (struct cmd_list_element *, char *, char *);
+typedef VEC (char_ptr) *completer_ftype (struct cmd_list_element *,
+                                        char *, char *);
 
 extern void set_cmd_completer (struct cmd_list_element *, completer_ftype *);
 
@@ -208,11 +211,11 @@ extern struct cmd_list_element *add_info (char *,
 
 extern struct cmd_list_element *add_info_alias (char *, char *, int);
 
-extern char **complete_on_cmdlist (struct cmd_list_element *,
-                                  char *, char *);
+extern VEC (char_ptr) *complete_on_cmdlist (struct cmd_list_element *,
+                                           char *, char *);
 
-extern char **complete_on_enum (const char *const *enumlist,
-                               char *, char *);
+extern VEC (char_ptr) *complete_on_enum (const char *const *enumlist,
+                                        char *, char *);
 
 /* Functions that implement commands about CLI commands.  */
 
index 5939d08124e442b58ed3250af8184392a692c3a7..b9f069976340724f692c43ecb5a9fb9d06b80e83 100644 (file)
@@ -104,7 +104,7 @@ readline_line_completion_function (const char *text, int matches)
 
 /* This can be used for functions which don't want to complete on
    symbols but don't want to complete on anything else either.  */
-char **
+VEC (char_ptr) *
 noop_completer (struct cmd_list_element *ignore, 
                char *text, char *prefix)
 {
@@ -112,19 +112,12 @@ noop_completer (struct cmd_list_element *ignore,
 }
 
 /* Complete on filenames.  */
-char **
+VEC (char_ptr) *
 filename_completer (struct cmd_list_element *ignore, 
                    char *text, char *word)
 {
   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 *));
+  VEC (char_ptr) *return_val = NULL;
 
   subsequent_name = 0;
   while (1)
@@ -132,18 +125,8 @@ filename_completer (struct cmd_list_element *ignore,
       char *p, *q;
 
       p = rl_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;
-       }
+       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
@@ -159,13 +142,12 @@ filename_completer (struct cmd_list_element *ignore,
 
       if (word == text)
        /* Return exactly p.  */
-       return_val[return_val_used++] = p;
+       q = 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;
          xfree (p);
        }
       else
@@ -175,9 +157,9 @@ filename_completer (struct cmd_list_element *ignore,
          strncpy (q, word, text - word);
          q[text - word] = '\0';
          strcat (q, p);
-         return_val[return_val_used++] = q;
          xfree (p);
        }
+      VEC_safe_push (char_ptr, return_val, q);
     }
 #if 0
   /* There is no way to do this just long enough to affect quote
@@ -199,13 +181,13 @@ filename_completer (struct cmd_list_element *ignore,
    This is intended to be used in commands that set breakpoints
    etc.  */
 
-char **
+VEC (char_ptr) *
 location_completer (struct cmd_list_element *ignore, 
                    char *text, char *word)
 {
-  int n_syms = 0, n_files = 0;
-  char ** fn_list = NULL;
-  char ** list = NULL;
+  int n_syms, n_files, ix;
+  VEC (char_ptr) *fn_list = NULL;
+  VEC (char_ptr) *list = NULL;
   char *p;
   int quote_found = 0;
   int quoted = *text == '\'' || *text == '"';
@@ -290,21 +272,26 @@ location_completer (struct cmd_list_element *ignore,
        fn_list = make_source_files_completion_list (text, text);
     }
 
-  /* How many completions do we have in both lists?  */
-  if (fn_list)
-    for ( ; fn_list[n_files]; n_files++)
-      ;
-  if (list)
-    for ( ; list[n_syms]; n_syms++)
-      ;
+  n_syms = VEC_length (char_ptr, list);
+  n_files = VEC_length (char_ptr, fn_list);
+
+  /* Catenate fn_list[] onto the end of list[].  */
+  if (!n_syms)
+    {
+      VEC_free (char_ptr, list); /* Paranoia.  */
+      list = fn_list;
+      fn_list = NULL;
+    }
+  else
+    {
+      for (ix = 0; VEC_iterate (char_ptr, fn_list, ix, p); ++ix)
+       VEC_safe_push (char_ptr, list, p);
+      VEC_free (char_ptr, fn_list);
+    }
 
-  /* Make list[] large enough to hold both lists, then catenate
-     fn_list[] onto the end of list[].  */
   if (n_syms && n_files)
     {
-      list = xrealloc (list, (n_syms + n_files + 1) * sizeof (char *));
-      memcpy (list + n_syms, fn_list, (n_files + 1) * sizeof (char *));
-      xfree (fn_list);
+      /* Nothing.  */
     }
   else if (n_files)
     {
@@ -323,23 +310,18 @@ location_completer (struct cmd_list_element *ignore,
         completion, because rl_complete will prepend "/foo/" to each
         candidate completion.  The loop below removes that leading
         part.  */
-      for (n_files = 0; fn_list[n_files]; n_files++)
+      for (ix = 0; VEC_iterate (char_ptr, list, ix, p); ++ix)
        {
-         memmove (fn_list[n_files], fn_list[n_files] + (word - text),
-                  strlen (fn_list[n_files]) + 1 - (word - text));
+         memmove (p, p + (word - text),
+                  strlen (p) + 1 - (word - text));
        }
-      /* Return just the file-name list as the result.  */
-      list = fn_list;
     }
   else if (!n_syms)
     {
       /* No completions at all.  As the final resort, try completing
         on the entire text as a symbol.  */
       list = make_symbol_completion_list (orig_text, word);
-      xfree (fn_list);
     }
-  else
-    xfree (fn_list);
 
   return list;
 }
@@ -379,9 +361,9 @@ count_struct_fields (struct type *type)
 
 /* Helper for expression_completer which recursively adds field and
    method names from TYPE, a struct or union type, to the array
-   OUTPUT.  This function assumes that OUTPUT is correctly-sized.  */
+   OUTPUT.  */
 static void
-add_struct_fields (struct type *type, int *nextp, char **output,
+add_struct_fields (struct type *type, VEC (char_ptr) **output,
                   char *fieldname, int namelen)
 {
   int i;
@@ -392,7 +374,7 @@ add_struct_fields (struct type *type, int *nextp, char **output,
   for (i = 0; i < TYPE_NFIELDS (type); ++i)
     {
       if (i < TYPE_N_BASECLASSES (type))
-       add_struct_fields (TYPE_BASECLASS (type, i), nextp,
+       add_struct_fields (TYPE_BASECLASS (type, i),
                           output, fieldname, namelen);
       else if (TYPE_FIELD_NAME (type, i))
        {
@@ -400,15 +382,13 @@ add_struct_fields (struct type *type, int *nextp, char **output,
            {
              if (! strncmp (TYPE_FIELD_NAME (type, i), 
                             fieldname, namelen))
-               {
-                 output[*nextp] = xstrdup (TYPE_FIELD_NAME (type, i));
-                 ++*nextp;
-               }
+               VEC_safe_push (char_ptr, *output,
+                              xstrdup (TYPE_FIELD_NAME (type, i)));
            }
          else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION)
            {
              /* Recurse into anonymous unions.  */
-             add_struct_fields (TYPE_FIELD_TYPE (type, i), nextp, 
+             add_struct_fields (TYPE_FIELD_TYPE (type, i),
                                 output, fieldname, namelen);
            }
        }
@@ -427,10 +407,7 @@ add_struct_fields (struct type *type, int *nextp, char **output,
            }
          /* Omit constructors from the completion list.  */
          if (!type_name || strcmp (type_name, name))
-           {
-             output[*nextp] = xstrdup (name);
-             ++*nextp;
-           }
+           VEC_safe_push (char_ptr, *output, xstrdup (name));
        }
     }
 }
@@ -438,7 +415,7 @@ add_struct_fields (struct type *type, int *nextp, char **output,
 /* Complete on expressions.  Often this means completing on symbol
    names, but some language parsers also have support for completing
    field names.  */
-char **
+VEC (char_ptr) *
 expression_completer (struct cmd_list_element *ignore, 
                      char *text, char *word)
 {
@@ -471,11 +448,9 @@ expression_completer (struct cmd_list_element *ignore,
        {
          int alloc = count_struct_fields (type);
          int flen = strlen (fieldname);
-         int out = 0;
-         char **result = (char **) xmalloc ((alloc + 1) * sizeof (char *));
+         VEC (char_ptr) *result = NULL;
 
-         add_struct_fields (type, &out, result, fieldname, flen);
-         result[out] = NULL;
+         add_struct_fields (type, &result, fieldname, flen);
          xfree (fieldname);
          return result;
        }
@@ -552,12 +527,12 @@ complete_line_internal_reason;
    once sub-command completions are exhausted, we simply return NULL.
  */
 
-static char **
+static VEC (char_ptr) *
 complete_line_internal (const char *text, 
                        char *line_buffer, int point,
                        complete_line_internal_reason reason)
 {
-  char **list = NULL;
+  VEC (char_ptr) *list = NULL;
   char *tmp_command, *p;
   /* Pointer within tmp_command which corresponds to text.  */
   char *word;
@@ -794,9 +769,9 @@ complete_line_internal (const char *text,
 
   return list;
 }
-/* Generate completions all at once.  Returns a NULL-terminated array
-   of strings.  Both the array and each element are allocated with
-   xmalloc.  It can also return NULL if there are no completions.
+/* Generate completions all at once.  Returns a vector of strings.
+   Each element is allocated with xmalloc.  It can also return NULL if
+   there are no completions.
 
    TEXT is the caller's idea of the "word" we are looking at.
 
@@ -806,7 +781,7 @@ complete_line_internal (const char *text,
    POINT is the offset in that line of the cursor.  You
    should pretend that the line ends at POINT.  */
 
-char **
+VEC (char_ptr) *
 complete_line (const char *text, char *line_buffer, int point)
 {
   return complete_line_internal (text, line_buffer, 
@@ -814,7 +789,7 @@ complete_line (const char *text, char *line_buffer, int point)
 }
 
 /* Complete on command names.  Used by "help".  */
-char **
+VEC (char_ptr) *
 command_completer (struct cmd_list_element *ignore, 
                   char *text, char *word)
 {
@@ -828,7 +803,7 @@ command_completer (struct cmd_list_element *ignore,
 char *
 gdb_completion_word_break_characters (void)
 {
-  char **list;
+  VEC (char_ptr) *list;
 
   list = complete_line_internal (rl_line_buffer, rl_line_buffer, rl_point,
                                 handle_brkchars);
@@ -861,7 +836,7 @@ static char *
 line_completion_function (const char *text, int matches, 
                          char *line_buffer, int point)
 {
-  static char **list = (char **) NULL; /* Cache of completions.  */
+  static VEC (char_ptr) *list = NULL;  /* Cache of completions.  */
   static int index;                    /* Next cached completion.  */
   char *output = NULL;
 
@@ -877,24 +852,22 @@ line_completion_function (const char *text, int matches,
             inside.  This is because rl_complete_internal () frees
             the strings.  As complete_line may abort by calling
             `error' clear LIST now.  */
-         xfree (list);
-         list = NULL;
+         VEC_free (char_ptr, list);
        }
       index = 0;
       list = complete_line (text, line_buffer, point);
     }
 
   /* 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.  */
+     then dole them out one at a time.  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)
+      if (index < VEC_length (char_ptr, list))
        {
+         output = VEC_index (char_ptr, list, index);
          index++;
        }
     }
index 0f522459b16751d9e14ba5a5fb9edf345ddb0eb7..680bc2dc1a0fb8da820d6e335f595b1919c7eb50 100644 (file)
 #if !defined (COMPLETER_H)
 #define COMPLETER_H 1
 
-extern char **complete_line (const char *text,
-                            char *line_buffer,
-                            int point);
+#include "gdb_vecs.h"
+
+extern VEC (char_ptr) *complete_line (const char *text,
+                                     char *line_buffer,
+                                     int point);
 
 extern char *readline_line_completion_function (const char *text,
                                                int matches);
 
-extern char **noop_completer (struct cmd_list_element *,
-                             char *, char *);
+extern VEC (char_ptr) *noop_completer (struct cmd_list_element *,
+                                      char *, char *);
 
-extern char **filename_completer (struct cmd_list_element *,
-                                 char *, char *);
+extern VEC (char_ptr) *filename_completer (struct cmd_list_element *,
+                                          char *, char *);
 
-extern char **expression_completer (struct cmd_list_element *,
-                                   char *, char *);
+extern VEC (char_ptr) *expression_completer (struct cmd_list_element *,
+                                            char *, char *);
 
-extern char **location_completer (struct cmd_list_element *,
-                                 char *, char *);
+extern VEC (char_ptr) *location_completer (struct cmd_list_element *,
+                                          char *, char *);
 
-extern char **command_completer (struct cmd_list_element *,
-                                char *, char *);
+extern VEC (char_ptr) *command_completer (struct cmd_list_element *,
+                                         char *, char *);
 
 extern char *get_gdb_completer_quote_characters (void);
 
index 3368d01c105ee0c3a8b5e9258c13a4afeb29297d..749214963b5402240177007c99dbc1ac5e591009 100644 (file)
@@ -263,7 +263,7 @@ f_word_break_characters (void)
 /* Consider the modules separator :: as a valid symbol name character
    class.  */
 
-static char **
+static VEC (char_ptr) *
 f_make_symbol_completion_list (char *text, char *word)
 {
   return default_make_symbol_completion_list_break_on (text, word, ":");
index 23e5a1051cd54817255c9f68e4cf7c06cc19e585..9b24c59eb32fd56a11465f98eeaf097a0fdd7d52 100644 (file)
@@ -73,8 +73,6 @@ struct interp
 
 /* Functions local to this file.  */
 static void initialize_interps (void);
-static char **interpreter_completer (struct cmd_list_element *cmd,
-                                    char *text, char *word);
 
 /* The magic initialization routine for this module.  */
 
@@ -445,54 +443,39 @@ interpreter_exec_cmd (char *args, int from_tty)
 }
 
 /* List the possible interpreters which could complete the given text.  */
-static char **
+static VEC (char_ptr) *
 interpreter_completer (struct cmd_list_element *ignore, char *text, char *word)
 {
-  int alloced = 0;
   int textlen;
-  int num_matches;
-  char **matches;
+  VEC (char_ptr) *matches = NULL;
   struct interp *interp;
 
-  /* We expect only a very limited number of interpreters, so just
-     allocate room for all of them plus one for the last that must be NULL
-     to correctly end the list.  */
-  for (interp = interp_list; interp != NULL; interp = interp->next)
-    ++alloced;
-  matches = (char **) xcalloc (alloced + 1, sizeof (char *));
-
-  num_matches = 0;
   textlen = strlen (text);
   for (interp = interp_list; interp != NULL; interp = interp->next)
     {
       if (strncmp (interp->name, text, textlen) == 0)
        {
-         matches[num_matches] =
-           (char *) xmalloc (strlen (word) + strlen (interp->name) + 1);
+         char *match;
+
+         match = (char *) xmalloc (strlen (word) + strlen (interp->name) + 1);
          if (word == text)
-           strcpy (matches[num_matches], interp->name);
+           strcpy (match, interp->name);
          else if (word > text)
            {
              /* Return some portion of interp->name.  */
-             strcpy (matches[num_matches], interp->name + (word - text));
+             strcpy (match, interp->name + (word - text));
            }
          else
            {
              /* Return some of text plus interp->name.  */
-             strncpy (matches[num_matches], word, text - word);
-             matches[num_matches][text - word] = '\0';
-             strcat (matches[num_matches], interp->name);
+             strncpy (match, word, text - word);
+             match[text - word] = '\0';
+             strcat (match, interp->name);
            }
-         ++num_matches;
+         VEC_safe_push (char_ptr, matches, match);
        }
     }
 
-  if (num_matches == 0)
-    {
-      xfree (matches);
-      matches = NULL;
-    }
-
   return matches;
 }
 
index d612c70523a3654d01e37a44d976d85771d8a67c..38c48305c2dbe962973b773ffb47ac82119f1234 100644 (file)
@@ -306,10 +306,10 @@ struct language_defn
     /* The list of characters forming word boundaries.  */
     char *(*la_word_break_characters) (void);
 
-    /* Should return a NULL terminated array of all symbols which
-       are possible completions for TEXT.  WORD is the entire command
-       on which the completion is being made.  */
-    char **(*la_make_symbol_completion_list) (char *text, char *word);
+    /* Should return a vector of all symbols which are possible
+       completions for TEXT.  WORD is the entire command on which the
+       completion is being made.  */
+    VEC (char_ptr) *(*la_make_symbol_completion_list) (char *text, char *word);
 
     /* The per-architecture (OS/ABI) language information.  */
     void (*la_language_arch_info) (struct gdbarch *,
index 605c8c002eb797d939648b0045e0d01e649b5bd6..d8e375c82ceee8b93030f476f93402eb165c2771 100644 (file)
@@ -206,12 +206,12 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
 
 /* Called by gdb for command completion.  */
 
-static char **
+static VEC (char_ptr) *
 cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
 {
   cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
   PyObject *textobj, *wordobj, *resultobj = NULL;
-  char **result = NULL;
+  VEC (char_ptr) *result = NULL;
   struct cleanup *cleanup;
 
   cleanup = ensure_python_env (get_current_arch (), current_language);
@@ -253,10 +253,10 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
       if (len < 0)
        goto done;
 
-      result = (char **) xmalloc ((len + 1) * sizeof (char *));
       for (i = out = 0; i < len; ++i)
        {
          PyObject *elt = PySequence_GetItem (resultobj, i);
+         char *item;
 
          if (elt == NULL || ! gdbpy_is_string (elt))
            {
@@ -264,16 +264,15 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
              PyErr_Clear ();
              continue;
            }
-         result[out] = python_string_to_host_string (elt);
-         if (result[out] == NULL)
+         item = python_string_to_host_string (elt);
+         if (item == NULL)
            {
              /* Skip problem elements.  */
              PyErr_Clear ();
              continue;
            }
-         ++out;
+         VEC_safe_push (char_ptr, result, item);
        }
-      result[out] = NULL;
     }
   else if (PyInt_Check (resultobj))
     {
index 6133b5cc653b7659acd9cf3d56d70cd7538c6d60..3efcb1b009f2de14adbdc8478d014a1c03517585 100644 (file)
@@ -3881,17 +3881,14 @@ compare_symbol_name (const char *name, const char *sym_text, int sym_text_len)
 /* Free any memory associated with a completion list.  */
 
 static void
-free_completion_list (char ***list_ptr)
+free_completion_list (VEC (char_ptr) **list_ptr)
 {
-  int i = 0;
-  char **list = *list_ptr;
+  int i;
+  char *p;
 
-  while (list[i] != NULL)
-    {
-      xfree (list[i]);
-      i++;
-    }
-  xfree (list);
+  for (i = 0; VEC_iterate (char_ptr, *list_ptr, i, p); ++i)
+    xfree (p);
+  VEC_free (char_ptr, *list_ptr);
 }
 
 /* Callback for make_cleanup.  */
@@ -3904,9 +3901,7 @@ do_free_completion_list (void *list)
 
 /* Helper routine for make_symbol_completion_list.  */
 
-static int return_val_size;
-static int return_val_index;
-static char **return_val;
+static VEC (char_ptr) *return_val;
 
 #define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
       completion_list_add_name \
@@ -3953,13 +3948,7 @@ completion_list_add_name (const char *symname,
        strcat (new, symname);
       }
 
-    if (return_val_index + 3 > return_val_size)
-      {
-       newsize = (return_val_size *= 2) * sizeof (char *);
-       return_val = (char **) xrealloc ((char *) return_val, newsize);
-      }
-    return_val[return_val_index++] = new;
-    return_val[return_val_index] = NULL;
+    VEC_safe_push (char_ptr, return_val, new);
   }
 }
 
@@ -4123,7 +4112,7 @@ expand_partial_symbol_name (const char *name, void *user_data)
   return compare_symbol_name (name, datum->sym_text, datum->sym_text_len);
 }
 
-char **
+VEC (char_ptr) *
 default_make_symbol_completion_list_break_on (char *text, char *word,
                                              const char *break_on)
 {
@@ -4178,9 +4167,7 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
       /* A double-quoted string is never a symbol, nor does it make sense
          to complete it any other way.  */
       {
-       return_val = (char **) xmalloc (sizeof (char *));
-       return_val[0] = NULL;
-       return return_val;
+       return NULL;
       }
     else
       {
@@ -4216,10 +4203,7 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
     }
   gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '(');
 
-  return_val_size = 100;
-  return_val_index = 0;
-  return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
-  return_val[0] = NULL;
+  return_val = NULL;
   back_to = make_cleanup (do_free_completion_list, &return_val);
 
   datum.sym_text = sym_text;
@@ -4334,17 +4318,17 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
   return (return_val);
 }
 
-char **
+VEC (char_ptr) *
 default_make_symbol_completion_list (char *text, char *word)
 {
   return default_make_symbol_completion_list_break_on (text, word, "");
 }
 
-/* Return a NULL terminated array of all symbols (regardless of class)
-   which begin by matching TEXT.  If the answer is no symbols, then
-   the return value is an array which contains only a NULL pointer.  */
+/* Return a vector of all symbols (regardless of class) which begin by
+   matching TEXT.  If the answer is no symbols, then the return value
+   is NULL.  */
 
-char **
+VEC (char_ptr) *
 make_symbol_completion_list (char *text, char *word)
 {
   return current_language->la_make_symbol_completion_list (text, word);
@@ -4353,7 +4337,7 @@ make_symbol_completion_list (char *text, char *word)
 /* Like make_symbol_completion_list, but suitable for use as a
    completion function.  */
 
-char **
+VEC (char_ptr) *
 make_symbol_completion_list_fn (struct cmd_list_element *ignore,
                                char *text, char *word)
 {
@@ -4363,7 +4347,7 @@ make_symbol_completion_list_fn (struct cmd_list_element *ignore,
 /* Like make_symbol_completion_list, but returns a list of symbols
    defined in a source file FILE.  */
 
-char **
+VEC (char_ptr) *
 make_file_symbol_completion_list (char *text, char *word, char *srcfile)
 {
   struct symbol *sym;
@@ -4409,9 +4393,7 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
       /* A double-quoted string is never a symbol, nor does it make sense
          to complete it any other way.  */
       {
-       return_val = (char **) xmalloc (sizeof (char *));
-       return_val[0] = NULL;
-       return return_val;
+       return NULL;
       }
     else
       {
@@ -4422,10 +4404,7 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
 
   sym_text_len = strlen (sym_text);
 
-  return_val_size = 10;
-  return_val_index = 0;
-  return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
-  return_val[0] = NULL;
+  return_val = NULL;
 
   /* Find the symtab for SRCFILE (this loads it if it was not yet read
      in).  */
@@ -4468,18 +4447,11 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
 
 static void
 add_filename_to_list (const char *fname, char *text, char *word,
-                     char ***list, int *list_used, int *list_alloced)
+                     VEC (char_ptr) **list)
 {
   char *new;
   size_t fnlen = strlen (fname);
 
-  if (*list_used + 1 >= *list_alloced)
-    {
-      *list_alloced *= 2;
-      *list = (char **) xrealloc ((char *) *list,
-                                 *list_alloced * sizeof (char *));
-    }
-
   if (word == text)
     {
       /* Return exactly fname.  */
@@ -4500,8 +4472,7 @@ add_filename_to_list (const char *fname, char *text, char *word,
       new[text - word] = '\0';
       strcat (new, fname);
     }
-  (*list)[*list_used] = new;
-  (*list)[++*list_used] = NULL;
+  VEC_safe_push (char_ptr, *list, new);
 }
 
 static int
@@ -4529,9 +4500,7 @@ struct add_partial_filename_data
   char *text;
   char *word;
   int text_len;
-  char ***list;
-  int *list_used;
-  int *list_alloced;
+  VEC (char_ptr) **list;
 };
 
 /* A callback for map_partial_symbol_filenames.  */
@@ -4549,8 +4518,7 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
     {
       /* This file matches for a completion; add it to the
         current list of matches.  */
-      add_filename_to_list (filename, data->text, data->word,
-                           data->list, data->list_used, data->list_alloced);
+      add_filename_to_list (filename, data->text, data->word, data->list);
     }
   else
     {
@@ -4559,32 +4527,27 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
       if (base_name != filename
          && !filename_seen (base_name, 1, data->first)
          && filename_ncmp (base_name, data->text, data->text_len) == 0)
-       add_filename_to_list (base_name, data->text, data->word,
-                             data->list, data->list_used, data->list_alloced);
+       add_filename_to_list (base_name, data->text, data->word, data->list);
     }
 }
 
-/* Return a NULL terminated array of all source files whose names
-   begin with matching TEXT.  The file names are looked up in the
-   symbol tables of this program.  If the answer is no matchess, then
-   the return value is an array which contains only a NULL pointer.  */
+/* Return a vector of all source files whose names begin with matching
+   TEXT.  The file names are looked up in the symbol tables of this
+   program.  If the answer is no matchess, then the return value is
+   NULL.  */
 
-char **
+VEC (char_ptr) *
 make_source_files_completion_list (char *text, char *word)
 {
   struct symtab *s;
   struct objfile *objfile;
   int first = 1;
-  int list_alloced = 1;
-  int list_used = 0;
   size_t text_len = strlen (text);
-  char **list = (char **) xmalloc (list_alloced * sizeof (char *));
+  VEC (char_ptr) *list = NULL;
   const char *base_name;
   struct add_partial_filename_data datum;
   struct cleanup *back_to;
 
-  list[0] = NULL;
-
   if (!have_full_symbols () && !have_partial_symbols ())
     return list;
 
@@ -4599,8 +4562,7 @@ make_source_files_completion_list (char *text, char *word)
        {
          /* This file matches for a completion; add it to the current
             list of matches.  */
-         add_filename_to_list (s->filename, text, word,
-                               &list, &list_used, &list_alloced);
+         add_filename_to_list (s->filename, text, word, &list);
        }
       else
        {
@@ -4612,8 +4574,7 @@ make_source_files_completion_list (char *text, char *word)
          if (base_name != s->filename
              && !filename_seen (base_name, 1, &first)
              && filename_ncmp (base_name, text, text_len) == 0)
-           add_filename_to_list (base_name, text, word,
-                                 &list, &list_used, &list_alloced);
+           add_filename_to_list (base_name, text, word, &list);
        }
     }
 
@@ -4622,8 +4583,6 @@ make_source_files_completion_list (char *text, char *word)
   datum.word = word;
   datum.text_len = text_len;
   datum.list = &list;
-  datum.list_used = &list_used;
-  datum.list_alloced = &list_alloced;
   map_partial_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
                                0 /*need_fullname*/);
   discard_cleanups (back_to);
index 526fe5a91bdf15d7b0e11ec9f4fb0003208304a4..38472e05fff09ea76a77c952cc3e0417b58ec154 100644 (file)
@@ -22,6 +22,7 @@
 #define SYMTAB_H 1
 
 #include "vec.h"
+#include "gdb_vecs.h"
 
 /* Opaque declarations.  */
 struct ui_file;
@@ -1150,16 +1151,17 @@ extern void forget_cached_source_info (void);
 
 extern void select_source_symtab (struct symtab *);
 
-extern char **default_make_symbol_completion_list_break_on
+extern VEC (char_ptr) *default_make_symbol_completion_list_break_on
   (char *text, char *word, const char *break_on);
-extern char **default_make_symbol_completion_list (char *, char *);
-extern char **make_symbol_completion_list (char *, char *);
-extern char **make_symbol_completion_list_fn (struct cmd_list_element *,
-                                             char *, char *);
+extern VEC (char_ptr) *default_make_symbol_completion_list (char *, char *);
+extern VEC (char_ptr) *make_symbol_completion_list (char *, char *);
+extern VEC (char_ptr) *make_symbol_completion_list_fn (struct cmd_list_element *,
+                                                      char *, char *);
 
-extern char **make_file_symbol_completion_list (char *, char *, char *);
+extern VEC (char_ptr) *make_file_symbol_completion_list (char *,
+                                                        char *, char *);
 
-extern char **make_source_files_completion_list (char *, char *);
+extern VEC (char_ptr) *make_source_files_completion_list (char *, char *);
 
 /* symtab.c */