* 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.
This commit is contained in:
Tom Tromey
2012-06-13 15:47:16 +00:00
parent 625e8578d7
commit 49c4e619f8
14 changed files with 230 additions and 334 deletions

View 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> 2012-06-13 Tom Tromey <tromey@redhat.com>
* breakpoint.c (add_catch_command): Use completer_ftype. * breakpoint.c (add_catch_command): Use completer_ftype.

View File

@ -5797,11 +5797,10 @@ ada_expand_partial_symbol_name (const char *name, void *user_data)
data->wild_match, data->encoded) != NULL; data->wild_match, data->encoded) != NULL;
} }
/* Return a list of possible symbol names completing TEXT0. The list /* Return a list of possible symbol names completing TEXT0. WORD is
is NULL terminated. WORD is the entire command on which completion the entire command on which completion is made. */
is made. */
static char ** static VEC (char_ptr) *
ada_make_symbol_completion_list (char *text0, char *word) ada_make_symbol_completion_list (char *text0, char *word)
{ {
char *text; char *text;
@ -5914,24 +5913,7 @@ ada_make_symbol_completion_list (char *text0, char *word)
} }
} }
/* Append the closing NULL entry. */ return completions;
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;
}
} }
/* Field Access */ /* Field Access */

View File

@ -14578,12 +14578,12 @@ catching_syscall_number (int syscall_number)
} }
/* Complete syscall names. Used by "catch syscall". */ /* Complete syscall names. Used by "catch syscall". */
static char ** static VEC (char_ptr) *
catch_syscall_completer (struct cmd_list_element *cmd, catch_syscall_completer (struct cmd_list_element *cmd,
char *text, char *word) char *text, char *word)
{ {
const char **list = get_syscall_names (); const char **list = get_syscall_names ();
char **retlist VEC (char_ptr) *retlist
= (list == NULL) ? NULL : complete_on_enum (list, text, word); = (list == NULL) ? NULL : complete_on_enum (list, text, word);
xfree (list); xfree (list);

View File

@ -254,7 +254,8 @@ static void
complete_command (char *arg, int from_tty) complete_command (char *arg, int from_tty)
{ {
int argpoint; int argpoint;
char **completions, *point, *arg_prefix; char *point, *arg_prefix;
VEC (char_ptr) *completions;
dont_repeat (); dont_repeat ();
@ -282,33 +283,30 @@ complete_command (char *arg, int from_tty)
if (completions) if (completions)
{ {
int item, size; int ix, size = VEC_length (char_ptr, completions);
char *item, *prev = NULL;
for (size = 0; completions[size]; ++size) qsort (VEC_address (char_ptr, completions), size,
; sizeof (char *), compare_strings);
qsort (completions, size, sizeof (char *), compare_strings);
/* We do extra processing here since we only want to print each /* We do extra processing here since we only want to print each
unique item once. */ unique item once. */
item = 0; for (ix = 0; VEC_iterate (char_ptr, completions, ix, item); ++ix)
while (item < size)
{ {
int next_item; int next_item;
printf_unfiltered ("%s%s\n", arg_prefix, completions[item]); if (prev == NULL || strcmp (item, prev) != 0)
next_item = item + 1;
while (next_item < size
&& ! strcmp (completions[item], completions[next_item]))
{ {
xfree (completions[next_item]); printf_unfiltered ("%s%s\n", arg_prefix, item);
++next_item; xfree (prev);
prev = item;
} }
else
xfree (completions[item]); xfree (item);
item = next_item;
} }
xfree (completions); xfree (prev);
VEC_free (char_ptr, completions);
} }
} }

View File

@ -1637,26 +1637,20 @@ lookup_cmd_composition (char *text,
"foo" and we want to complete to "foobar". If WORD is "oo", return "foo" and we want to complete to "foobar". If WORD is "oo", return
"oobar"; if WORD is "baz/foo", return "baz/foobar". */ "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) complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
{ {
struct cmd_list_element *ptr; struct cmd_list_element *ptr;
char **matchlist; VEC (char_ptr) *matchlist = NULL;
int sizeof_matchlist;
int matches;
int textlen = strlen (text); int textlen = strlen (text);
int pass; int pass;
int saw_deprecated_match = 0; 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 /* 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 commands. If we see no matching commands in the first pass, and
if we did happen to see a matching deprecated command, we do if we did happen to see a matching deprecated command, we do
another loop to collect those. */ 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) for (ptr = list; ptr; ptr = ptr->next)
if (!strncmp (ptr->name, text, textlen) 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->func
|| ptr->prefixlist)) || ptr->prefixlist))
{ {
char *match;
if (pass == 0) if (pass == 0)
{ {
if ((ptr->flags & CMD_DEPRECATED) != 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) match = (char *) xmalloc (strlen (word) + strlen (ptr->name) + 1);
{
sizeof_matchlist *= 2;
matchlist = (char **) xrealloc ((char *) matchlist,
(sizeof_matchlist
* sizeof (char *)));
}
matchlist[matches] = (char *)
xmalloc (strlen (word) + strlen (ptr->name) + 1);
if (word == text) if (word == text)
strcpy (matchlist[matches], ptr->name); strcpy (match, ptr->name);
else if (word > text) else if (word > text)
{ {
/* Return some portion of ptr->name. */ /* Return some portion of ptr->name. */
strcpy (matchlist[matches], ptr->name + (word - text)); strcpy (match, ptr->name + (word - text));
} }
else else
{ {
/* Return some of text plus ptr->name. */ /* Return some of text plus ptr->name. */
strncpy (matchlist[matches], word, text - word); strncpy (match, word, text - word);
matchlist[matches][text - word] = '\0'; match[text - word] = '\0';
strcat (matchlist[matches], ptr->name); strcat (match, ptr->name);
} }
++matches; VEC_safe_push (char_ptr, matchlist, match);
} }
/* If we saw no matching deprecated commands in the first pass, /* If we saw no matching deprecated commands in the first pass,
just bail out. */ just bail out. */
@ -1705,18 +1692,6 @@ complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
break; break;
} }
if (matches == 0)
{
xfree (matchlist);
matchlist = 0;
}
else
{
matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
* sizeof (char *)));
matchlist[matches] = (char *) 0;
}
return matchlist; 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 and we want to complete to "foobar". If WORD is "oo", return
"oobar"; if WORD is "baz/foo", return "baz/foobar". */ "oobar"; if WORD is "baz/foo", return "baz/foobar". */
char ** VEC (char_ptr) *
complete_on_enum (const char *const *enumlist, complete_on_enum (const char *const *enumlist,
char *text, char *text,
char *word) char *word)
{ {
char **matchlist; VEC (char_ptr) *matchlist = NULL;
int sizeof_matchlist;
int matches;
int textlen = strlen (text); int textlen = strlen (text);
int i; int i;
const char *name; const char *name;
sizeof_matchlist = 10;
matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
matches = 0;
for (i = 0; (name = enumlist[i]) != NULL; i++) for (i = 0; (name = enumlist[i]) != NULL; i++)
if (strncmp (name, text, textlen) == 0) if (strncmp (name, text, textlen) == 0)
{ {
if (matches == sizeof_matchlist) char *match;
{
sizeof_matchlist *= 2;
matchlist = (char **) xrealloc ((char *) matchlist,
(sizeof_matchlist
* sizeof (char *)));
}
matchlist[matches] = (char *) match = (char *) xmalloc (strlen (word) + strlen (name) + 1);
xmalloc (strlen (word) + strlen (name) + 1);
if (word == text) if (word == text)
strcpy (matchlist[matches], name); strcpy (match, name);
else if (word > text) else if (word > text)
{ {
/* Return some portion of name. */ /* Return some portion of name. */
strcpy (matchlist[matches], name + (word - text)); strcpy (match, name + (word - text));
} }
else else
{ {
/* Return some of text plus name. */ /* Return some of text plus name. */
strncpy (matchlist[matches], word, text - word); strncpy (match, word, text - word);
matchlist[matches][text - word] = '\0'; match[text - word] = '\0';
strcat (matchlist[matches], name); 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; return matchlist;
} }

View File

@ -19,6 +19,8 @@
#if !defined (COMMAND_H) #if !defined (COMMAND_H)
#define COMMAND_H 1 #define COMMAND_H 1
#include "gdb_vecs.h"
/* This file defines the public interface for any code wanting to /* This file defines the public interface for any code wanting to
create commands. */ 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, extern void set_cmd_sfunc (struct cmd_list_element *cmd,
cmd_sfunc_ftype *sfunc); 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 *); 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 struct cmd_list_element *add_info_alias (char *, char *, int);
extern char **complete_on_cmdlist (struct cmd_list_element *, extern VEC (char_ptr) *complete_on_cmdlist (struct cmd_list_element *,
char *, char *); char *, char *);
extern char **complete_on_enum (const char *const *enumlist, extern VEC (char_ptr) *complete_on_enum (const char *const *enumlist,
char *, char *); char *, char *);
/* Functions that implement commands about CLI commands. */ /* Functions that implement commands about CLI commands. */

View 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 /* This can be used for functions which don't want to complete on
symbols but don't want to complete on anything else either. */ symbols but don't want to complete on anything else either. */
char ** VEC (char_ptr) *
noop_completer (struct cmd_list_element *ignore, noop_completer (struct cmd_list_element *ignore,
char *text, char *prefix) char *text, char *prefix)
{ {
@ -112,19 +112,12 @@ noop_completer (struct cmd_list_element *ignore,
} }
/* Complete on filenames. */ /* Complete on filenames. */
char ** VEC (char_ptr) *
filename_completer (struct cmd_list_element *ignore, filename_completer (struct cmd_list_element *ignore,
char *text, char *word) char *text, char *word)
{ {
int subsequent_name; int subsequent_name;
char **return_val; VEC (char_ptr) *return_val = NULL;
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; subsequent_name = 0;
while (1) while (1)
@ -132,18 +125,8 @@ filename_completer (struct cmd_list_element *ignore,
char *p, *q; char *p, *q;
p = rl_filename_completion_function (text, subsequent_name); 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) if (p == NULL)
{ break;
return_val[return_val_used++] = p;
break;
}
/* We need to set subsequent_name to a non-zero value before the /* We need to set subsequent_name to a non-zero value before the
continue line below, because otherwise, if the first file continue line below, because otherwise, if the first file
seen by GDB is a backup file whose name ends in a `~', we 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) if (word == text)
/* Return exactly p. */ /* Return exactly p. */
return_val[return_val_used++] = p; q = p;
else if (word > text) else if (word > text)
{ {
/* Return some portion of p. */ /* Return some portion of p. */
q = xmalloc (strlen (p) + 5); q = xmalloc (strlen (p) + 5);
strcpy (q, p + (word - text)); strcpy (q, p + (word - text));
return_val[return_val_used++] = q;
xfree (p); xfree (p);
} }
else else
@ -175,9 +157,9 @@ filename_completer (struct cmd_list_element *ignore,
strncpy (q, word, text - word); strncpy (q, word, text - word);
q[text - word] = '\0'; q[text - word] = '\0';
strcat (q, p); strcat (q, p);
return_val[return_val_used++] = q;
xfree (p); xfree (p);
} }
VEC_safe_push (char_ptr, return_val, q);
} }
#if 0 #if 0
/* There is no way to do this just long enough to affect quote /* 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 This is intended to be used in commands that set breakpoints
etc. */ etc. */
char ** VEC (char_ptr) *
location_completer (struct cmd_list_element *ignore, location_completer (struct cmd_list_element *ignore,
char *text, char *word) char *text, char *word)
{ {
int n_syms = 0, n_files = 0; int n_syms, n_files, ix;
char ** fn_list = NULL; VEC (char_ptr) *fn_list = NULL;
char ** list = NULL; VEC (char_ptr) *list = NULL;
char *p; char *p;
int quote_found = 0; int quote_found = 0;
int quoted = *text == '\'' || *text == '"'; int quoted = *text == '\'' || *text == '"';
@ -290,21 +272,26 @@ location_completer (struct cmd_list_element *ignore,
fn_list = make_source_files_completion_list (text, text); fn_list = make_source_files_completion_list (text, text);
} }
/* How many completions do we have in both lists? */ n_syms = VEC_length (char_ptr, list);
if (fn_list) n_files = VEC_length (char_ptr, fn_list);
for ( ; fn_list[n_files]; n_files++)
; /* Catenate fn_list[] onto the end of list[]. */
if (list) if (!n_syms)
for ( ; list[n_syms]; 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) if (n_syms && n_files)
{ {
list = xrealloc (list, (n_syms + n_files + 1) * sizeof (char *)); /* Nothing. */
memcpy (list + n_syms, fn_list, (n_files + 1) * sizeof (char *));
xfree (fn_list);
} }
else if (n_files) else if (n_files)
{ {
@ -323,23 +310,18 @@ location_completer (struct cmd_list_element *ignore,
completion, because rl_complete will prepend "/foo/" to each completion, because rl_complete will prepend "/foo/" to each
candidate completion. The loop below removes that leading candidate completion. The loop below removes that leading
part. */ 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), memmove (p, p + (word - text),
strlen (fn_list[n_files]) + 1 - (word - text)); strlen (p) + 1 - (word - text));
} }
/* Return just the file-name list as the result. */
list = fn_list;
} }
else if (!n_syms) else if (!n_syms)
{ {
/* No completions at all. As the final resort, try completing /* No completions at all. As the final resort, try completing
on the entire text as a symbol. */ on the entire text as a symbol. */
list = make_symbol_completion_list (orig_text, word); list = make_symbol_completion_list (orig_text, word);
xfree (fn_list);
} }
else
xfree (fn_list);
return list; return list;
} }
@ -379,9 +361,9 @@ count_struct_fields (struct type *type)
/* Helper for expression_completer which recursively adds field and /* Helper for expression_completer which recursively adds field and
method names from TYPE, a struct or union type, to the array method names from TYPE, a struct or union type, to the array
OUTPUT. This function assumes that OUTPUT is correctly-sized. */ OUTPUT. */
static void 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) char *fieldname, int namelen)
{ {
int i; int i;
@ -392,7 +374,7 @@ add_struct_fields (struct type *type, int *nextp, char **output,
for (i = 0; i < TYPE_NFIELDS (type); ++i) for (i = 0; i < TYPE_NFIELDS (type); ++i)
{ {
if (i < TYPE_N_BASECLASSES (type)) if (i < TYPE_N_BASECLASSES (type))
add_struct_fields (TYPE_BASECLASS (type, i), nextp, add_struct_fields (TYPE_BASECLASS (type, i),
output, fieldname, namelen); output, fieldname, namelen);
else if (TYPE_FIELD_NAME (type, i)) 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), if (! strncmp (TYPE_FIELD_NAME (type, i),
fieldname, namelen)) fieldname, namelen))
{ VEC_safe_push (char_ptr, *output,
output[*nextp] = xstrdup (TYPE_FIELD_NAME (type, i)); xstrdup (TYPE_FIELD_NAME (type, i)));
++*nextp;
}
} }
else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION) else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION)
{ {
/* Recurse into anonymous unions. */ /* Recurse into anonymous unions. */
add_struct_fields (TYPE_FIELD_TYPE (type, i), nextp, add_struct_fields (TYPE_FIELD_TYPE (type, i),
output, fieldname, namelen); output, fieldname, namelen);
} }
} }
@ -427,10 +407,7 @@ add_struct_fields (struct type *type, int *nextp, char **output,
} }
/* Omit constructors from the completion list. */ /* Omit constructors from the completion list. */
if (!type_name || strcmp (type_name, name)) if (!type_name || strcmp (type_name, name))
{ VEC_safe_push (char_ptr, *output, xstrdup (name));
output[*nextp] = xstrdup (name);
++*nextp;
}
} }
} }
} }
@ -438,7 +415,7 @@ add_struct_fields (struct type *type, int *nextp, char **output,
/* Complete on expressions. Often this means completing on symbol /* Complete on expressions. Often this means completing on symbol
names, but some language parsers also have support for completing names, but some language parsers also have support for completing
field names. */ field names. */
char ** VEC (char_ptr) *
expression_completer (struct cmd_list_element *ignore, expression_completer (struct cmd_list_element *ignore,
char *text, char *word) char *text, char *word)
{ {
@ -471,11 +448,9 @@ expression_completer (struct cmd_list_element *ignore,
{ {
int alloc = count_struct_fields (type); int alloc = count_struct_fields (type);
int flen = strlen (fieldname); int flen = strlen (fieldname);
int out = 0; VEC (char_ptr) *result = NULL;
char **result = (char **) xmalloc ((alloc + 1) * sizeof (char *));
add_struct_fields (type, &out, result, fieldname, flen); add_struct_fields (type, &result, fieldname, flen);
result[out] = NULL;
xfree (fieldname); xfree (fieldname);
return result; return result;
} }
@ -552,12 +527,12 @@ complete_line_internal_reason;
once sub-command completions are exhausted, we simply return NULL. once sub-command completions are exhausted, we simply return NULL.
*/ */
static char ** static VEC (char_ptr) *
complete_line_internal (const char *text, complete_line_internal (const char *text,
char *line_buffer, int point, char *line_buffer, int point,
complete_line_internal_reason reason) complete_line_internal_reason reason)
{ {
char **list = NULL; VEC (char_ptr) *list = NULL;
char *tmp_command, *p; char *tmp_command, *p;
/* Pointer within tmp_command which corresponds to text. */ /* Pointer within tmp_command which corresponds to text. */
char *word; char *word;
@ -794,9 +769,9 @@ complete_line_internal (const char *text,
return list; return list;
} }
/* Generate completions all at once. Returns a NULL-terminated array /* Generate completions all at once. Returns a vector of strings.
of strings. Both the array and each element are allocated with Each element is allocated with xmalloc. It can also return NULL if
xmalloc. It can also return NULL if there are no completions. there are no completions.
TEXT is the caller's idea of the "word" we are looking at. 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 POINT is the offset in that line of the cursor. You
should pretend that the line ends at POINT. */ should pretend that the line ends at POINT. */
char ** VEC (char_ptr) *
complete_line (const char *text, char *line_buffer, int point) complete_line (const char *text, char *line_buffer, int point)
{ {
return complete_line_internal (text, line_buffer, 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". */ /* Complete on command names. Used by "help". */
char ** VEC (char_ptr) *
command_completer (struct cmd_list_element *ignore, command_completer (struct cmd_list_element *ignore,
char *text, char *word) char *text, char *word)
{ {
@ -828,7 +803,7 @@ command_completer (struct cmd_list_element *ignore,
char * char *
gdb_completion_word_break_characters (void) gdb_completion_word_break_characters (void)
{ {
char **list; VEC (char_ptr) *list;
list = complete_line_internal (rl_line_buffer, rl_line_buffer, rl_point, list = complete_line_internal (rl_line_buffer, rl_line_buffer, rl_point,
handle_brkchars); handle_brkchars);
@ -861,7 +836,7 @@ static char *
line_completion_function (const char *text, int matches, line_completion_function (const char *text, int matches,
char *line_buffer, int point) 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. */ static int index; /* Next cached completion. */
char *output = NULL; char *output = NULL;
@ -877,24 +852,22 @@ line_completion_function (const char *text, int matches,
inside. This is because rl_complete_internal () frees inside. This is because rl_complete_internal () frees
the strings. As complete_line may abort by calling the strings. As complete_line may abort by calling
`error' clear LIST now. */ `error' clear LIST now. */
xfree (list); VEC_free (char_ptr, list);
list = NULL;
} }
index = 0; index = 0;
list = complete_line (text, line_buffer, point); list = complete_line (text, line_buffer, point);
} }
/* If we found a list of potential completions during initialization /* If we found a list of potential completions during initialization
then dole them out one at a time. The vector of completions is then dole them out one at a time. After returning the last one,
NULL terminated, so after returning the last one, return NULL return NULL (and continue to do so) each time we are called after
(and continue to do so) each time we are called after that, until that, until a new list is available. */
a new list is available. */
if (list) if (list)
{ {
output = list[index]; if (index < VEC_length (char_ptr, list))
if (output)
{ {
output = VEC_index (char_ptr, list, index);
index++; index++;
} }
} }

View File

@ -17,27 +17,29 @@
#if !defined (COMPLETER_H) #if !defined (COMPLETER_H)
#define COMPLETER_H 1 #define COMPLETER_H 1
extern char **complete_line (const char *text, #include "gdb_vecs.h"
char *line_buffer,
int point); extern VEC (char_ptr) *complete_line (const char *text,
char *line_buffer,
int point);
extern char *readline_line_completion_function (const char *text, extern char *readline_line_completion_function (const char *text,
int matches); int matches);
extern char **noop_completer (struct cmd_list_element *, extern VEC (char_ptr) *noop_completer (struct cmd_list_element *,
char *, char *); char *, char *);
extern char **filename_completer (struct cmd_list_element *, extern VEC (char_ptr) *filename_completer (struct cmd_list_element *,
char *, char *); char *, char *);
extern char **expression_completer (struct cmd_list_element *, extern VEC (char_ptr) *expression_completer (struct cmd_list_element *,
char *, char *); char *, char *);
extern char **location_completer (struct cmd_list_element *, extern VEC (char_ptr) *location_completer (struct cmd_list_element *,
char *, char *); char *, char *);
extern char **command_completer (struct cmd_list_element *, extern VEC (char_ptr) *command_completer (struct cmd_list_element *,
char *, char *); char *, char *);
extern char *get_gdb_completer_quote_characters (void); extern char *get_gdb_completer_quote_characters (void);

View File

@ -263,7 +263,7 @@ f_word_break_characters (void)
/* Consider the modules separator :: as a valid symbol name character /* Consider the modules separator :: as a valid symbol name character
class. */ class. */
static char ** static VEC (char_ptr) *
f_make_symbol_completion_list (char *text, char *word) f_make_symbol_completion_list (char *text, char *word)
{ {
return default_make_symbol_completion_list_break_on (text, word, ":"); return default_make_symbol_completion_list_break_on (text, word, ":");

View File

@ -73,8 +73,6 @@ struct interp
/* Functions local to this file. */ /* Functions local to this file. */
static void initialize_interps (void); 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. */ /* 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. */ /* 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) interpreter_completer (struct cmd_list_element *ignore, char *text, char *word)
{ {
int alloced = 0;
int textlen; int textlen;
int num_matches; VEC (char_ptr) *matches = NULL;
char **matches;
struct interp *interp; 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); textlen = strlen (text);
for (interp = interp_list; interp != NULL; interp = interp->next) for (interp = interp_list; interp != NULL; interp = interp->next)
{ {
if (strncmp (interp->name, text, textlen) == 0) if (strncmp (interp->name, text, textlen) == 0)
{ {
matches[num_matches] = char *match;
(char *) xmalloc (strlen (word) + strlen (interp->name) + 1);
match = (char *) xmalloc (strlen (word) + strlen (interp->name) + 1);
if (word == text) if (word == text)
strcpy (matches[num_matches], interp->name); strcpy (match, interp->name);
else if (word > text) else if (word > text)
{ {
/* Return some portion of interp->name. */ /* Return some portion of interp->name. */
strcpy (matches[num_matches], interp->name + (word - text)); strcpy (match, interp->name + (word - text));
} }
else else
{ {
/* Return some of text plus interp->name. */ /* Return some of text plus interp->name. */
strncpy (matches[num_matches], word, text - word); strncpy (match, word, text - word);
matches[num_matches][text - word] = '\0'; match[text - word] = '\0';
strcat (matches[num_matches], interp->name); strcat (match, interp->name);
} }
++num_matches; VEC_safe_push (char_ptr, matches, match);
} }
} }
if (num_matches == 0)
{
xfree (matches);
matches = NULL;
}
return matches; return matches;
} }

View File

@ -306,10 +306,10 @@ struct language_defn
/* The list of characters forming word boundaries. */ /* The list of characters forming word boundaries. */
char *(*la_word_break_characters) (void); char *(*la_word_break_characters) (void);
/* Should return a NULL terminated array of all symbols which /* Should return a vector of all symbols which are possible
are possible completions for TEXT. WORD is the entire command completions for TEXT. WORD is the entire command on which the
on which the completion is being made. */ completion is being made. */
char **(*la_make_symbol_completion_list) (char *text, char *word); VEC (char_ptr) *(*la_make_symbol_completion_list) (char *text, char *word);
/* The per-architecture (OS/ABI) language information. */ /* The per-architecture (OS/ABI) language information. */
void (*la_language_arch_info) (struct gdbarch *, void (*la_language_arch_info) (struct gdbarch *,

View File

@ -206,12 +206,12 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
/* Called by gdb for command completion. */ /* Called by gdb for command completion. */
static char ** static VEC (char_ptr) *
cmdpy_completer (struct cmd_list_element *command, char *text, char *word) cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
{ {
cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command); cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
PyObject *textobj, *wordobj, *resultobj = NULL; PyObject *textobj, *wordobj, *resultobj = NULL;
char **result = NULL; VEC (char_ptr) *result = NULL;
struct cleanup *cleanup; struct cleanup *cleanup;
cleanup = ensure_python_env (get_current_arch (), current_language); 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) if (len < 0)
goto done; goto done;
result = (char **) xmalloc ((len + 1) * sizeof (char *));
for (i = out = 0; i < len; ++i) for (i = out = 0; i < len; ++i)
{ {
PyObject *elt = PySequence_GetItem (resultobj, i); PyObject *elt = PySequence_GetItem (resultobj, i);
char *item;
if (elt == NULL || ! gdbpy_is_string (elt)) if (elt == NULL || ! gdbpy_is_string (elt))
{ {
@ -264,16 +264,15 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
PyErr_Clear (); PyErr_Clear ();
continue; continue;
} }
result[out] = python_string_to_host_string (elt); item = python_string_to_host_string (elt);
if (result[out] == NULL) if (item == NULL)
{ {
/* Skip problem elements. */ /* Skip problem elements. */
PyErr_Clear (); PyErr_Clear ();
continue; continue;
} }
++out; VEC_safe_push (char_ptr, result, item);
} }
result[out] = NULL;
} }
else if (PyInt_Check (resultobj)) else if (PyInt_Check (resultobj))
{ {

View 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. */ /* Free any memory associated with a completion list. */
static void static void
free_completion_list (char ***list_ptr) free_completion_list (VEC (char_ptr) **list_ptr)
{ {
int i = 0; int i;
char **list = *list_ptr; char *p;
while (list[i] != NULL) for (i = 0; VEC_iterate (char_ptr, *list_ptr, i, p); ++i)
{ xfree (p);
xfree (list[i]); VEC_free (char_ptr, *list_ptr);
i++;
}
xfree (list);
} }
/* Callback for make_cleanup. */ /* Callback for make_cleanup. */
@ -3904,9 +3901,7 @@ do_free_completion_list (void *list)
/* Helper routine for make_symbol_completion_list. */ /* Helper routine for make_symbol_completion_list. */
static int return_val_size; static VEC (char_ptr) *return_val;
static int return_val_index;
static char **return_val;
#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \ #define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
completion_list_add_name \ completion_list_add_name \
@ -3953,13 +3948,7 @@ completion_list_add_name (const char *symname,
strcat (new, symname); strcat (new, symname);
} }
if (return_val_index + 3 > return_val_size) VEC_safe_push (char_ptr, return_val, new);
{
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;
} }
} }
@ -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); 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, default_make_symbol_completion_list_break_on (char *text, char *word,
const char *break_on) 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 /* A double-quoted string is never a symbol, nor does it make sense
to complete it any other way. */ to complete it any other way. */
{ {
return_val = (char **) xmalloc (sizeof (char *)); return NULL;
return_val[0] = NULL;
return return_val;
} }
else 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] == '('); gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '(');
return_val_size = 100; return_val = NULL;
return_val_index = 0;
return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
return_val[0] = NULL;
back_to = make_cleanup (do_free_completion_list, &return_val); back_to = make_cleanup (do_free_completion_list, &return_val);
datum.sym_text = sym_text; datum.sym_text = sym_text;
@ -4334,17 +4318,17 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
return (return_val); return (return_val);
} }
char ** VEC (char_ptr) *
default_make_symbol_completion_list (char *text, char *word) default_make_symbol_completion_list (char *text, char *word)
{ {
return default_make_symbol_completion_list_break_on (text, word, ""); return default_make_symbol_completion_list_break_on (text, word, "");
} }
/* Return a NULL terminated array of all symbols (regardless of class) /* Return a vector of all symbols (regardless of class) which begin by
which begin by matching TEXT. If the answer is no symbols, then matching TEXT. If the answer is no symbols, then the return value
the return value is an array which contains only a NULL pointer. */ is NULL. */
char ** VEC (char_ptr) *
make_symbol_completion_list (char *text, char *word) make_symbol_completion_list (char *text, char *word)
{ {
return current_language->la_make_symbol_completion_list (text, 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 /* Like make_symbol_completion_list, but suitable for use as a
completion function. */ completion function. */
char ** VEC (char_ptr) *
make_symbol_completion_list_fn (struct cmd_list_element *ignore, make_symbol_completion_list_fn (struct cmd_list_element *ignore,
char *text, char *word) 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 /* Like make_symbol_completion_list, but returns a list of symbols
defined in a source file FILE. */ defined in a source file FILE. */
char ** VEC (char_ptr) *
make_file_symbol_completion_list (char *text, char *word, char *srcfile) make_file_symbol_completion_list (char *text, char *word, char *srcfile)
{ {
struct symbol *sym; 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 /* A double-quoted string is never a symbol, nor does it make sense
to complete it any other way. */ to complete it any other way. */
{ {
return_val = (char **) xmalloc (sizeof (char *)); return NULL;
return_val[0] = NULL;
return return_val;
} }
else else
{ {
@ -4422,10 +4404,7 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
sym_text_len = strlen (sym_text); sym_text_len = strlen (sym_text);
return_val_size = 10; return_val = NULL;
return_val_index = 0;
return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
return_val[0] = NULL;
/* Find the symtab for SRCFILE (this loads it if it was not yet read /* Find the symtab for SRCFILE (this loads it if it was not yet read
in). */ in). */
@ -4468,18 +4447,11 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
static void static void
add_filename_to_list (const char *fname, char *text, char *word, 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; char *new;
size_t fnlen = strlen (fname); 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) if (word == text)
{ {
/* Return exactly fname. */ /* Return exactly fname. */
@ -4500,8 +4472,7 @@ add_filename_to_list (const char *fname, char *text, char *word,
new[text - word] = '\0'; new[text - word] = '\0';
strcat (new, fname); strcat (new, fname);
} }
(*list)[*list_used] = new; VEC_safe_push (char_ptr, *list, new);
(*list)[++*list_used] = NULL;
} }
static int static int
@ -4529,9 +4500,7 @@ struct add_partial_filename_data
char *text; char *text;
char *word; char *word;
int text_len; int text_len;
char ***list; VEC (char_ptr) **list;
int *list_used;
int *list_alloced;
}; };
/* A callback for map_partial_symbol_filenames. */ /* 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 /* This file matches for a completion; add it to the
current list of matches. */ current list of matches. */
add_filename_to_list (filename, data->text, data->word, add_filename_to_list (filename, data->text, data->word, data->list);
data->list, data->list_used, data->list_alloced);
} }
else else
{ {
@ -4559,32 +4527,27 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
if (base_name != filename if (base_name != filename
&& !filename_seen (base_name, 1, data->first) && !filename_seen (base_name, 1, data->first)
&& filename_ncmp (base_name, data->text, data->text_len) == 0) && filename_ncmp (base_name, data->text, data->text_len) == 0)
add_filename_to_list (base_name, data->text, data->word, add_filename_to_list (base_name, data->text, data->word, data->list);
data->list, data->list_used, data->list_alloced);
} }
} }
/* Return a NULL terminated array of all source files whose names /* Return a vector of all source files whose names begin with matching
begin with matching TEXT. The file names are looked up in the TEXT. The file names are looked up in the symbol tables of this
symbol tables of this program. If the answer is no matchess, then program. If the answer is no matchess, then the return value is
the return value is an array which contains only a NULL pointer. */ NULL. */
char ** VEC (char_ptr) *
make_source_files_completion_list (char *text, char *word) make_source_files_completion_list (char *text, char *word)
{ {
struct symtab *s; struct symtab *s;
struct objfile *objfile; struct objfile *objfile;
int first = 1; int first = 1;
int list_alloced = 1;
int list_used = 0;
size_t text_len = strlen (text); size_t text_len = strlen (text);
char **list = (char **) xmalloc (list_alloced * sizeof (char *)); VEC (char_ptr) *list = NULL;
const char *base_name; const char *base_name;
struct add_partial_filename_data datum; struct add_partial_filename_data datum;
struct cleanup *back_to; struct cleanup *back_to;
list[0] = NULL;
if (!have_full_symbols () && !have_partial_symbols ()) if (!have_full_symbols () && !have_partial_symbols ())
return list; 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 /* This file matches for a completion; add it to the current
list of matches. */ list of matches. */
add_filename_to_list (s->filename, text, word, add_filename_to_list (s->filename, text, word, &list);
&list, &list_used, &list_alloced);
} }
else else
{ {
@ -4612,8 +4574,7 @@ make_source_files_completion_list (char *text, char *word)
if (base_name != s->filename if (base_name != s->filename
&& !filename_seen (base_name, 1, &first) && !filename_seen (base_name, 1, &first)
&& filename_ncmp (base_name, text, text_len) == 0) && filename_ncmp (base_name, text, text_len) == 0)
add_filename_to_list (base_name, text, word, add_filename_to_list (base_name, text, word, &list);
&list, &list_used, &list_alloced);
} }
} }
@ -4622,8 +4583,6 @@ make_source_files_completion_list (char *text, char *word)
datum.word = word; datum.word = word;
datum.text_len = text_len; datum.text_len = text_len;
datum.list = &list; datum.list = &list;
datum.list_used = &list_used;
datum.list_alloced = &list_alloced;
map_partial_symbol_filenames (maybe_add_partial_symtab_filename, &datum, map_partial_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
0 /*need_fullname*/); 0 /*need_fullname*/);
discard_cleanups (back_to); discard_cleanups (back_to);

View File

@ -22,6 +22,7 @@
#define SYMTAB_H 1 #define SYMTAB_H 1
#include "vec.h" #include "vec.h"
#include "gdb_vecs.h"
/* Opaque declarations. */ /* Opaque declarations. */
struct ui_file; struct ui_file;
@ -1150,16 +1151,17 @@ extern void forget_cached_source_info (void);
extern void select_source_symtab (struct symtab *); 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); (char *text, char *word, const char *break_on);
extern char **default_make_symbol_completion_list (char *, char *); extern VEC (char_ptr) *default_make_symbol_completion_list (char *, char *);
extern char **make_symbol_completion_list (char *, char *); extern VEC (char_ptr) *make_symbol_completion_list (char *, char *);
extern char **make_symbol_completion_list_fn (struct cmd_list_element *, extern VEC (char_ptr) *make_symbol_completion_list_fn (struct cmd_list_element *,
char *, char *); 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 */ /* symtab.c */