diff options
author | Tom Tromey <tromey@redhat.com> | 2008-06-06 20:58:08 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2008-06-06 20:58:08 +0000 |
commit | 65d12d83a581c833b3c09acead57dd1134154e46 (patch) | |
tree | 5115b47443ba264269ce3c9445015317a78ceeea /gdb/completer.c | |
parent | 90aa6a4044aa608595b9a97944e27541bdd4ebf7 (diff) | |
download | gdb-65d12d83a581c833b3c09acead57dd1134154e46.zip gdb-65d12d83a581c833b3c09acead57dd1134154e46.tar.gz gdb-65d12d83a581c833b3c09acead57dd1134154e46.tar.bz2 |
gdb
* value.h (evaluate_subexpression_type, extract_field_op):
Declare.
* printcmd.c (_initialize_printcmd): Use expression_completer for
'p', 'inspect', 'call'.
* parser-defs.h (parse_field_expression): Declare.
* parse.c: Include exceptions.h.
(in_parse_field, expout_last_struct): New globals.
(mark_struct_expression): New function.
(prefixify_expression): Return int.
(prefixify_subexp): Return int. Use expout_last_struct.
(parse_exp_1): Update.
(parse_exp_in_context): Add 'out_subexp' argument. Handle
in_parse_field.
(parse_field_expression): New function.
* expression.h (parse_field_expression): Declare.
(in_parse_field): Likewise.
* eval.c (evaluate_subexpression_type): New function.
(extract_field_op): Likewise.
* completer.h (expression_completer): Declare.
* completer.c (expression_completer): New function.
(count_struct_fields, add_struct_fields): New functions.
* c-exp.y (yyparse): Redefine.
(COMPLETE): New token.
(exp): New productions.
(saw_name_at_eof, last_was_structop): New globals.
(yylex): Return COMPLETE when needed. Recognize in_parse_field.
(c_parse): New function.
* breakpoint.c (_initialize_breakpoint): Use expression_completer
for watch, awatch, and rwatch.
* Makefile.in (parse.o): Depend on exceptions_h.
gdb/testsuite
* gdb.base/break1.c (struct some_struct): New struct.
(values): New global.
* gdb.base/completion.exp: Add field name completion test.
gdb/doc
* gdb.texinfo (Completion): Add field name example.
Diffstat (limited to 'gdb/completer.c')
-rw-r--r-- | gdb/completer.c | 90 |
1 files changed, 88 insertions, 2 deletions
diff --git a/gdb/completer.c b/gdb/completer.c index 3d3d34c..163a9dc 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -338,6 +338,90 @@ location_completer (char *text, char *word) return list; } +/* Helper for expression_completer which recursively counts the number + of named fields 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)) + ++result; + } + return result; +} + +/* Helper for expression_completer which recursively adds field names + from TYPE, a struct or union type, to the array OUTPUT. This + function assumes that OUTPUT is correctly-sized. */ +static void +add_struct_fields (struct type *type, int *nextp, char **output, + char *fieldname, int namelen) +{ + int i; + + CHECK_TYPEDEF (type); + for (i = 0; i < TYPE_NFIELDS (type); ++i) + { + if (i < TYPE_N_BASECLASSES (type)) + add_struct_fields (TYPE_BASECLASS (type, i), nextp, output, + fieldname, namelen); + else if (TYPE_FIELD_NAME (type, i) + && ! strncmp (TYPE_FIELD_NAME (type, i), fieldname, namelen)) + { + output[*nextp] = xstrdup (TYPE_FIELD_NAME (type, i)); + ++*nextp; + } + } +} + +/* Complete on expressions. Often this means completing on symbol + names, but some language parsers also have support for completing + field names. */ +char ** +expression_completer (char *text, char *word) +{ + struct type *type; + char *fieldname; + + /* Perform a tentative parse of the expression, to see whether a + field completion is required. */ + fieldname = NULL; + type = parse_field_expression (text, &fieldname); + if (fieldname && type) + { + for (;;) + { + CHECK_TYPEDEF (type); + if (TYPE_CODE (type) != TYPE_CODE_PTR + && TYPE_CODE (type) != TYPE_CODE_REF) + break; + type = TYPE_TARGET_TYPE (type); + } + + if (TYPE_CODE (type) == TYPE_CODE_UNION + || TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + int alloc = count_struct_fields (type); + int flen = strlen (fieldname); + int out = 0; + char **result = (char **) xmalloc ((alloc + 1) * sizeof (char *)); + + add_struct_fields (type, &out, result, fieldname, flen); + result[out] = NULL; + return result; + } + } + + /* Not ideal but it is what we used to do before... */ + return location_completer (text, word); +} + /* Complete on command names. Used by "help". */ char ** command_completer (char *text, char *word) @@ -520,7 +604,8 @@ complete_line (const char *text, char *line_buffer, int point) rl_completer_word_break_characters = gdb_completer_file_name_break_characters; } - else if (c->completer == location_completer) + else if (c->completer == location_completer + || c->completer == expression_completer) { /* Commands which complete on locations want to see the entire argument. */ @@ -588,7 +673,8 @@ complete_line (const char *text, char *line_buffer, int point) rl_completer_word_break_characters = gdb_completer_file_name_break_characters; } - else if (c->completer == location_completer) + else if (c->completer == location_completer + || c->completer == expression_completer) { for (p = word; p > tmp_command |