| Index: gdb/completer.c
|
| diff --git a/gdb/completer.c b/gdb/completer.c
|
| index b9f069976340724f692c43ecb5a9fb9d06b80e83..91bf81272ecbc476bf61811b3bfdef466716008c 100644
|
| --- a/gdb/completer.c
|
| +++ b/gdb/completer.c
|
| @@ -1,5 +1,5 @@
|
| /* Line completion stuff for GDB, the GNU debugger.
|
| - Copyright (C) 2000-2001, 2007-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -24,6 +24,7 @@
|
| #include "language.h"
|
| #include "gdb_assert.h"
|
| #include "exceptions.h"
|
| +#include "gdb_signals.h"
|
|
|
| #include "cli/cli-decode.h"
|
|
|
| @@ -106,7 +107,7 @@ readline_line_completion_function (const char *text, int matches)
|
| symbols but don't want to complete on anything else either. */
|
| VEC (char_ptr) *
|
| noop_completer (struct cmd_list_element *ignore,
|
| - char *text, char *prefix)
|
| + const char *text, const char *prefix)
|
| {
|
| return NULL;
|
| }
|
| @@ -114,7 +115,7 @@ noop_completer (struct cmd_list_element *ignore,
|
| /* Complete on filenames. */
|
| VEC (char_ptr) *
|
| filename_completer (struct cmd_list_element *ignore,
|
| - char *text, char *word)
|
| + const char *text, const char *word)
|
| {
|
| int subsequent_name;
|
| VEC (char_ptr) *return_val = NULL;
|
| @@ -183,22 +184,22 @@ filename_completer (struct cmd_list_element *ignore,
|
|
|
| VEC (char_ptr) *
|
| location_completer (struct cmd_list_element *ignore,
|
| - char *text, char *word)
|
| + const char *text, const char *word)
|
| {
|
| int n_syms, n_files, ix;
|
| VEC (char_ptr) *fn_list = NULL;
|
| VEC (char_ptr) *list = NULL;
|
| - char *p;
|
| + const char *p;
|
| int quote_found = 0;
|
| int quoted = *text == '\'' || *text == '"';
|
| int quote_char = '\0';
|
| - char *colon = NULL;
|
| + const char *colon = NULL;
|
| char *file_to_match = NULL;
|
| - char *symbol_start = text;
|
| - char *orig_text = text;
|
| + const char *symbol_start = text;
|
| + const char *orig_text = text;
|
| size_t text_len;
|
|
|
| - /* Do we have an unquoted colon, as in "break foo.c::bar"? */
|
| + /* Do we have an unquoted colon, as in "break foo.c:bar"? */
|
| for (p = text; *p != '\0'; ++p)
|
| {
|
| if (*p == '\\' && p[1] == '\'')
|
| @@ -284,8 +285,10 @@ location_completer (struct cmd_list_element *ignore,
|
| }
|
| else
|
| {
|
| - for (ix = 0; VEC_iterate (char_ptr, fn_list, ix, p); ++ix)
|
| - VEC_safe_push (char_ptr, list, p);
|
| + char *fn;
|
| +
|
| + for (ix = 0; VEC_iterate (char_ptr, fn_list, ix, fn); ++ix)
|
| + VEC_safe_push (char_ptr, list, fn);
|
| VEC_free (char_ptr, fn_list);
|
| }
|
|
|
| @@ -295,6 +298,8 @@ location_completer (struct cmd_list_element *ignore,
|
| }
|
| else if (n_files)
|
| {
|
| + char *fn;
|
| +
|
| /* If we only have file names as possible completion, we should
|
| bring them in sync with what rl_complete expects. The
|
| problem is that if the user types "break /foo/b TAB", and the
|
| @@ -310,10 +315,10 @@ 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 (ix = 0; VEC_iterate (char_ptr, list, ix, p); ++ix)
|
| + for (ix = 0; VEC_iterate (char_ptr, list, ix, fn); ++ix)
|
| {
|
| - memmove (p, p + (word - text),
|
| - strlen (p) + 1 - (word - text));
|
| + memmove (fn, fn + (word - text),
|
| + strlen (fn) + 1 - (word - text));
|
| }
|
| }
|
| else if (!n_syms)
|
| @@ -326,39 +331,6 @@ location_completer (struct cmd_list_element *ignore,
|
| return list;
|
| }
|
|
|
| -/* Helper for expression_completer which recursively counts the number
|
| - of named fields and methods in a structure or union type. */
|
| -static int
|
| -count_struct_fields (struct type *type)
|
| -{
|
| - int i, result = 0;
|
| -
|
| - CHECK_TYPEDEF (type);
|
| - for (i = 0; i < TYPE_NFIELDS (type); ++i)
|
| - {
|
| - if (i < TYPE_N_BASECLASSES (type))
|
| - result += count_struct_fields (TYPE_BASECLASS (type, i));
|
| - else if (TYPE_FIELD_NAME (type, i))
|
| - {
|
| - if (TYPE_FIELD_NAME (type, i)[0] != '\0')
|
| - ++result;
|
| - else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION)
|
| - {
|
| - /* Recurse into anonymous unions. */
|
| - result += count_struct_fields (TYPE_FIELD_TYPE (type, i));
|
| - }
|
| - }
|
| - }
|
| -
|
| - for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
|
| - {
|
| - if (TYPE_FN_FIELDLIST_NAME (type, i))
|
| - ++result;
|
| - }
|
| -
|
| - return result;
|
| -}
|
| -
|
| /* Helper for expression_completer which recursively adds field and
|
| method names from TYPE, a struct or union type, to the array
|
| OUTPUT. */
|
| @@ -417,18 +389,20 @@ add_struct_fields (struct type *type, VEC (char_ptr) **output,
|
| field names. */
|
| VEC (char_ptr) *
|
| expression_completer (struct cmd_list_element *ignore,
|
| - char *text, char *word)
|
| + const char *text, const char *word)
|
| {
|
| struct type *type = NULL;
|
| - char *fieldname, *p;
|
| + char *fieldname;
|
| + const char *p;
|
| volatile struct gdb_exception except;
|
| + enum type_code code = TYPE_CODE_UNDEF;
|
|
|
| /* Perform a tentative parse of the expression, to see whether a
|
| field completion is required. */
|
| fieldname = NULL;
|
| TRY_CATCH (except, RETURN_MASK_ERROR)
|
| {
|
| - type = parse_field_expression (text, &fieldname);
|
| + type = parse_expression_for_completion (text, &fieldname, &code);
|
| }
|
| if (except.reason < 0)
|
| return NULL;
|
| @@ -446,7 +420,6 @@ expression_completer (struct cmd_list_element *ignore,
|
| if (TYPE_CODE (type) == TYPE_CODE_UNION
|
| || TYPE_CODE (type) == TYPE_CODE_STRUCT)
|
| {
|
| - int alloc = count_struct_fields (type);
|
| int flen = strlen (fieldname);
|
| VEC (char_ptr) *result = NULL;
|
|
|
| @@ -455,6 +428,15 @@ expression_completer (struct cmd_list_element *ignore,
|
| return result;
|
| }
|
| }
|
| + else if (fieldname && code != TYPE_CODE_UNDEF)
|
| + {
|
| + VEC (char_ptr) *result;
|
| + struct cleanup *cleanup = make_cleanup (xfree, fieldname);
|
| +
|
| + result = make_symbol_completion_type (fieldname, fieldname, code);
|
| + do_cleanups (cleanup);
|
| + return result;
|
| + }
|
| xfree (fieldname);
|
|
|
| /* Commands which complete on locations want to see the entire
|
| @@ -529,11 +511,13 @@ complete_line_internal_reason;
|
|
|
| static VEC (char_ptr) *
|
| complete_line_internal (const char *text,
|
| - char *line_buffer, int point,
|
| + const char *line_buffer, int point,
|
| complete_line_internal_reason reason)
|
| {
|
| VEC (char_ptr) *list = NULL;
|
| - char *tmp_command, *p;
|
| + char *tmp_command;
|
| + const char *p;
|
| + int ignore_help_classes;
|
| /* Pointer within tmp_command which corresponds to text. */
|
| char *word;
|
| struct cmd_list_element *c, *result_list;
|
| @@ -553,6 +537,9 @@ complete_line_internal (const char *text,
|
| tmp_command = (char *) alloca (point + 1);
|
| p = tmp_command;
|
|
|
| + /* The help command should complete help aliases. */
|
| + ignore_help_classes = reason != handle_help;
|
| +
|
| strncpy (tmp_command, line_buffer, point);
|
| tmp_command[point] = '\0';
|
| /* Since text always contains some number of characters leading up
|
| @@ -569,7 +556,7 @@ complete_line_internal (const char *text,
|
| }
|
| else
|
| {
|
| - c = lookup_cmd_1 (&p, cmdlist, &result_list, 1);
|
| + c = lookup_cmd_1 (&p, cmdlist, &result_list, ignore_help_classes);
|
| }
|
|
|
| /* Move p up to the next interesting thing. */
|
| @@ -586,7 +573,7 @@ complete_line_internal (const char *text,
|
| }
|
| else if (c == CMD_LIST_AMBIGUOUS)
|
| {
|
| - char *q;
|
| + const char *q;
|
|
|
| /* lookup_cmd_1 advances p up to the first ambiguous thing, but
|
| doesn't advance over that thing itself. Do so now. */
|
| @@ -610,12 +597,13 @@ complete_line_internal (const char *text,
|
| {
|
| if (reason != handle_brkchars)
|
| list = complete_on_cmdlist (*result_list->prefixlist, p,
|
| - word);
|
| + word, ignore_help_classes);
|
| }
|
| else
|
| {
|
| if (reason != handle_brkchars)
|
| - list = complete_on_cmdlist (cmdlist, p, word);
|
| + list = complete_on_cmdlist (cmdlist, p, word,
|
| + ignore_help_classes);
|
| }
|
| /* Ensure that readline does the right thing with respect to
|
| inserting quotes. */
|
| @@ -641,7 +629,8 @@ complete_line_internal (const char *text,
|
| /* It is a prefix command; what comes after it is
|
| a subcommand (e.g. "info "). */
|
| if (reason != handle_brkchars)
|
| - list = complete_on_cmdlist (*c->prefixlist, p, word);
|
| + list = complete_on_cmdlist (*c->prefixlist, p, word,
|
| + ignore_help_classes);
|
|
|
| /* Ensure that readline does the right thing
|
| with respect to inserting quotes. */
|
| @@ -699,7 +688,7 @@ complete_line_internal (const char *text,
|
| complete on the command itself, e.g. "p" which is a
|
| command itself but also can complete to "print", "ptype"
|
| etc. */
|
| - char *q;
|
| + const char *q;
|
|
|
| /* Find the command we are completing on. */
|
| q = p;
|
| @@ -712,7 +701,8 @@ complete_line_internal (const char *text,
|
| }
|
|
|
| if (reason != handle_brkchars)
|
| - list = complete_on_cmdlist (result_list, q, word);
|
| + list = complete_on_cmdlist (result_list, q, word,
|
| + ignore_help_classes);
|
|
|
| /* Ensure that readline does the right thing
|
| with respect to inserting quotes. */
|
| @@ -791,12 +781,42 @@ complete_line (const char *text, char *line_buffer, int point)
|
| /* Complete on command names. Used by "help". */
|
| VEC (char_ptr) *
|
| command_completer (struct cmd_list_element *ignore,
|
| - char *text, char *word)
|
| + const char *text, const char *word)
|
| {
|
| return complete_line_internal (word, text,
|
| strlen (text), handle_help);
|
| }
|
|
|
| +/* Complete on signals. */
|
| +
|
| +VEC (char_ptr) *
|
| +signal_completer (struct cmd_list_element *ignore,
|
| + const char *text, const char *word)
|
| +{
|
| + VEC (char_ptr) *return_val = NULL;
|
| + size_t len = strlen (word);
|
| + enum gdb_signal signum;
|
| + const char *signame;
|
| +
|
| + for (signum = GDB_SIGNAL_FIRST; signum != GDB_SIGNAL_LAST; ++signum)
|
| + {
|
| + /* Can't handle this, so skip it. */
|
| + if (signum == GDB_SIGNAL_0)
|
| + continue;
|
| +
|
| + signame = gdb_signal_to_name (signum);
|
| +
|
| + /* Ignore the unknown signal case. */
|
| + if (!signame || strcmp (signame, "?") == 0)
|
| + continue;
|
| +
|
| + if (strncasecmp (signame, word, len) == 0)
|
| + VEC_safe_push (char_ptr, return_val, xstrdup (signame));
|
| + }
|
| +
|
| + return return_val;
|
| +}
|
| +
|
| /* Get the list of chars that are considered as word breaks
|
| for the current command. */
|
|
|
| @@ -891,11 +911,12 @@ line_completion_function (const char *text, int matches,
|
| QUOTECHARS or BREAKCHARS is NULL, use the same values used by the
|
| completer. */
|
|
|
| -char *
|
| -skip_quoted_chars (char *str, char *quotechars, char *breakchars)
|
| +const char *
|
| +skip_quoted_chars (const char *str, const char *quotechars,
|
| + const char *breakchars)
|
| {
|
| char quote_char = '\0';
|
| - char *scan;
|
| + const char *scan;
|
|
|
| if (quotechars == NULL)
|
| quotechars = gdb_completer_quote_characters;
|
| @@ -933,8 +954,8 @@ skip_quoted_chars (char *str, char *quotechars, char *breakchars)
|
| characters and word break characters used by the completer).
|
| Returns pointer to the location after the "word". */
|
|
|
| -char *
|
| -skip_quoted (char *str)
|
| +const char *
|
| +skip_quoted (const char *str)
|
| {
|
| return skip_quoted_chars (str, NULL, NULL);
|
| }
|
|
|