From 49c4e619f81a66545e2332dc218d9bf31bbb51ad Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 13 Jun 2012 15:47:16 +0000 Subject: [PATCH] * 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) : 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) : Remove. : 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. --- gdb/ChangeLog | 45 ++++++++++++++ gdb/ada-lang.c | 26 ++------ gdb/breakpoint.c | 4 +- gdb/cli/cli-cmds.c | 32 +++++----- gdb/cli/cli-decode.c | 94 +++++++---------------------- gdb/command.h | 13 ++-- gdb/completer.c | 137 +++++++++++++++++-------------------------- gdb/completer.h | 28 +++++---- gdb/f-lang.c | 2 +- gdb/interps.c | 39 ++++-------- gdb/language.h | 8 +-- gdb/python/py-cmd.c | 13 ++-- gdb/symtab.c | 107 +++++++++++---------------------- gdb/symtab.h | 16 ++--- 14 files changed, 230 insertions(+), 334 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d36c7641512..81bd9a94599 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,48 @@ +2012-06-13 Tom Tromey + + * 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) + : 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) : Remove. + : 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 * breakpoint.c (add_catch_command): Use completer_ftype. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index af0fdb5e53f..6f654720645 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 8e9029871e1..d76065dc4ed 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 e5fa20606c9..24d55c38807 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 2974d113f51..c337b43f813 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 eba3a5b9571..3064ce29a81 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 5939d08124e..b9f06997634 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 0f522459b16..680bc2dc1a0 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 3368d01c105..749214963b5 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 23e5a1051cd..9b24c59eb32 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 d612c70523a..38c48305c2d 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 605c8c002eb..d8e375c82ce 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 6133b5cc653..3efcb1b009f 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 526fe5a91bd..38472e05fff 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 */ -- 2.30.2