mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 00:59:15 +08:00
gdb: improve command completion for 'print', 'x', and 'display'
The /FMT specification on the print command currently breaks command completion, so: (gdb) p var.<TAB><TAB> .... list of fields in var ..... But, (gdb) p/d var.<TAB><TAB> ..... list of all symbols ..... After this commit this issue is now resolved. There are some other details around tab-completion and /FMT which hopefully this commit improves. So, before: (gdb) p/<TAB><TAB> .... lists all symbols ..... After: (gdb) p/<TAB><TAB> # Nothing changes... The thinking here is that after a / the user must type a FMT, but we don't offer tab completion on FMT characters. Placing a symbol directly after a / will not do what the user expects, so offering that seems wrong. Similarly, before we had: (gdb) p/d<TAB><TAB> ... lists all symbols starting with 'd' .... But afterwards: (gdb) p/d<TAB><TAB> # Adds a single space, so we get: (gdb) p/d <CURSOR> As before, typing a symbol where FMT is expected will not do what the user expects. If the user has added a FMT string then upon tab completion GDB assumes the FMT string is complete and prepares the user to type an expression. In this commit I have also added completion functions for the 'x' and 'display' commands. These commands also support /FMT specifiers and so share some code with 'print'. gdb/ChangeLog: * printcmd.c: Include 'safe-ctype.c'. (skip_over_slash_fmt): New function. (print_command_completer): Call skip_over_slash_fmt. (display_and_x_command_completer): New function. (_initialize_printcmd): Add command completion for 'x' and 'display'. gdb/testsuite/ChangeLog: * gdb.base/completion.exp: Add new tests.
This commit is contained in:
@ -1,3 +1,12 @@
|
||||
2020-11-17 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* printcmd.c: Include 'safe-ctype.c'.
|
||||
(skip_over_slash_fmt): New function.
|
||||
(print_command_completer): Call skip_over_slash_fmt.
|
||||
(display_and_x_command_completer): New function.
|
||||
(_initialize_printcmd): Add command completion for 'x' and
|
||||
'display'.
|
||||
|
||||
2020-11-16 Pedro Alves <pedro@palves.net>
|
||||
|
||||
* frame.c (get_prev_frame): Move get_frame_id call from here ...
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "source.h"
|
||||
#include "gdbsupport/byte-vector.h"
|
||||
#include "gdbsupport/gdb_optional.h"
|
||||
#include "safe-ctype.h"
|
||||
|
||||
/* Last specified output format. */
|
||||
|
||||
@ -1233,6 +1234,62 @@ print_command_1 (const char *args, int voidprint)
|
||||
print_value (val, print_opts);
|
||||
}
|
||||
|
||||
/* Called from command completion function to skip over /FMT
|
||||
specifications, allowing the rest of the line to be completed. Returns
|
||||
true if the /FMT is at the end of the current line and there is nothing
|
||||
left to complete, otherwise false is returned.
|
||||
|
||||
In either case *ARGS can be updated to point after any part of /FMT that
|
||||
is present.
|
||||
|
||||
This function is designed so that trying to complete '/' will offer no
|
||||
completions, the user needs to insert the format specification
|
||||
themselves. Trying to complete '/FMT' (where FMT is any non-empty set
|
||||
of alpha-numeric characters) will cause readline to insert a single
|
||||
space, setting the user up to enter the expression. */
|
||||
|
||||
static bool
|
||||
skip_over_slash_fmt (completion_tracker &tracker, const char **args)
|
||||
{
|
||||
const char *text = *args;
|
||||
|
||||
if (text[0] == '/')
|
||||
{
|
||||
bool in_fmt;
|
||||
tracker.set_use_custom_word_point (true);
|
||||
|
||||
if (ISALNUM (text[1]) || ISSPACE (text[1]))
|
||||
{
|
||||
/* Skip over the actual format specification. */
|
||||
while (*text != '\0' && !ISSPACE (*text))
|
||||
++text;
|
||||
|
||||
if (*text == '\0')
|
||||
{
|
||||
in_fmt = true;
|
||||
tracker.add_completion (make_unique_xstrdup (text));
|
||||
}
|
||||
else
|
||||
{
|
||||
in_fmt = false;
|
||||
while (ISSPACE (*text))
|
||||
++text;
|
||||
}
|
||||
}
|
||||
else if (text[1] == '\0')
|
||||
{
|
||||
in_fmt = true;
|
||||
++text;
|
||||
}
|
||||
|
||||
tracker.advance_custom_word_point_by (text - *args);
|
||||
*args = text;
|
||||
return in_fmt;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* See valprint.h. */
|
||||
|
||||
void
|
||||
@ -1245,6 +1302,9 @@ print_command_completer (struct cmd_list_element *ignore,
|
||||
(tracker, &text, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group))
|
||||
return;
|
||||
|
||||
if (skip_over_slash_fmt (tracker, &text))
|
||||
return;
|
||||
|
||||
const char *word = advance_to_expression_complete_word_point (tracker, text);
|
||||
expression_completer (ignore, tracker, text, word);
|
||||
}
|
||||
@ -1735,6 +1795,21 @@ x_command (const char *exp, int from_tty)
|
||||
set_internalvar (lookup_internalvar ("__"), last_examine_value.get ());
|
||||
}
|
||||
}
|
||||
|
||||
/* Command completion for the 'display' and 'x' commands. */
|
||||
|
||||
static void
|
||||
display_and_x_command_completer (struct cmd_list_element *ignore,
|
||||
completion_tracker &tracker,
|
||||
const char *text, const char * /*word*/)
|
||||
{
|
||||
if (skip_over_slash_fmt (tracker, &text))
|
||||
return;
|
||||
|
||||
const char *word = advance_to_expression_complete_word_point (tracker, text);
|
||||
expression_completer (ignore, tracker, text, word);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Add an expression to the auto-display chain.
|
||||
@ -2713,7 +2788,7 @@ Describe what symbol is at location ADDR.\n\
|
||||
Usage: info symbol ADDR\n\
|
||||
Only for symbols with fixed locations (global or static scope)."));
|
||||
|
||||
add_com ("x", class_vars, x_command, _("\
|
||||
c = add_com ("x", class_vars, x_command, _("\
|
||||
Examine memory: x/FMT ADDRESS.\n\
|
||||
ADDRESS is an expression for the memory address to examine.\n\
|
||||
FMT is a repeat count followed by a format letter and a size letter.\n\
|
||||
@ -2727,6 +2802,7 @@ examined backward from the address.\n\n\
|
||||
Defaults for format and size letters are those previously used.\n\
|
||||
Default count is 1. Default address is following last thing printed\n\
|
||||
with this command or \"print\"."));
|
||||
set_cmd_completer_handle_brkchars (c, display_and_x_command_completer);
|
||||
|
||||
add_info ("display", info_display_command, _("\
|
||||
Expressions to display when program stops, with code numbers.\n\
|
||||
@ -2741,7 +2817,7 @@ No argument means cancel all automatic-display expressions.\n\
|
||||
Do \"info display\" to see current list of code numbers."),
|
||||
&cmdlist);
|
||||
|
||||
add_com ("display", class_vars, display_command, _("\
|
||||
c = add_com ("display", class_vars, display_command, _("\
|
||||
Print value of expression EXP each time the program stops.\n\
|
||||
Usage: display[/FMT] EXP\n\
|
||||
/FMT may be used before EXP as in the \"print\" command.\n\
|
||||
@ -2750,6 +2826,7 @@ as in the \"x\" command, and then EXP is used to get the address to examine\n\
|
||||
and examining is done as in the \"x\" command.\n\n\
|
||||
With no argument, display all currently requested auto-display expressions.\n\
|
||||
Use \"undisplay\" to cancel display requests previously made."));
|
||||
set_cmd_completer_handle_brkchars (c, display_and_x_command_completer);
|
||||
|
||||
add_cmd ("display", class_vars, enable_display_command, _("\
|
||||
Enable some expressions to be displayed when program stops.\n\
|
||||
|
@ -1,3 +1,7 @@
|
||||
2020-11-17 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* gdb.base/completion.exp: Add new tests.
|
||||
|
||||
2020-11-16 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* gdb.dwarf2/data-loc.exp: Update expected output. Remove C
|
||||
|
@ -172,6 +172,11 @@ if { ![readline_is_used] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
# The bulk of this test script pre-dates the completion-support
|
||||
# library, and should probably (where possible) be converted.
|
||||
# However, for now, new tests are being added using this library.
|
||||
load_lib completion-support.exp
|
||||
|
||||
set test "complete 'hfgfh'"
|
||||
send_gdb "hfgfh\t"
|
||||
gdb_test_multiple "" "$test" {
|
||||
@ -922,3 +927,27 @@ gdb_test_multiple "" "$test" {
|
||||
pass "$test"
|
||||
}
|
||||
}
|
||||
|
||||
# Test completion of 'p', 'x', and 'display' all using a /FMT.
|
||||
foreach_with_prefix spc { " " "" } {
|
||||
test_gdb_complete_multiple "p${spc}/d some_union_global." "" "f" {
|
||||
"f1"
|
||||
"f2"
|
||||
}
|
||||
|
||||
test_gdb_complete_none "p${spc}/"
|
||||
test_gdb_complete_unique "p${spc}/d" "p${spc}/d"
|
||||
|
||||
test_gdb_complete_unique "x${spc}/1w values\[0\].b"\
|
||||
"x${spc}/1w values\[0\].b_field"
|
||||
|
||||
test_gdb_complete_unique "display${spc}/x values\[0\].z"\
|
||||
"display${spc}/x values\[0\].z_field"
|
||||
}
|
||||
|
||||
# Test 'p' using both options and /FMT.
|
||||
test_gdb_complete_multiple "p -array on -- /d some_union_global." \
|
||||
"" "f" {
|
||||
"f1"
|
||||
"f2"
|
||||
}
|
||||
|
Reference in New Issue
Block a user