aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog45
-rw-r--r--gdb/ada-lang.c26
-rw-r--r--gdb/breakpoint.c4
-rw-r--r--gdb/cli/cli-cmds.c32
-rw-r--r--gdb/cli/cli-decode.c94
-rw-r--r--gdb/command.h13
-rw-r--r--gdb/completer.c137
-rw-r--r--gdb/completer.h28
-rw-r--r--gdb/f-lang.c2
-rw-r--r--gdb/interps.c39
-rw-r--r--gdb/language.h8
-rw-r--r--gdb/python/py-cmd.c13
-rw-r--r--gdb/symtab.c107
-rw-r--r--gdb/symtab.h16
14 files changed, 230 insertions, 334 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d36c764..81bd9a9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,50 @@
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.
* breakpoint.h: Include command.h.
(add_catch_command): Use completer_ftype.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index af0fdb5..6f65472 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -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 */
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 8e90298..d76065d 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -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);
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index e5fa206..24d55c3 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -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);
}
}
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 2974d11..c337b43 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -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;
}
diff --git a/gdb/command.h b/gdb/command.h
index eba3a5b..3064ce2 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -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. */
diff --git a/gdb/completer.c b/gdb/completer.c
index 5939d08..b9f0699 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -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++;
}
}
diff --git a/gdb/completer.h b/gdb/completer.h
index 0f52245..680bc2d 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -17,27 +17,29 @@
#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);
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 3368d01..7492149 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -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, ":");
diff --git a/gdb/interps.c b/gdb/interps.c
index 23e5a10..9b24c59 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -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;
}
diff --git a/gdb/language.h b/gdb/language.h
index d612c70..38c4830 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -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 *,
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 605c8c0..d8e375c 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -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))
{
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 6133b5c..3efcb1b 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -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);
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 526fe5a..38472e0 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -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 */