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>
|
2020-11-16 Pedro Alves <pedro@palves.net>
|
||||||
|
|
||||||
* frame.c (get_prev_frame): Move get_frame_id call from here ...
|
* frame.c (get_prev_frame): Move get_frame_id call from here ...
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "gdbsupport/byte-vector.h"
|
#include "gdbsupport/byte-vector.h"
|
||||||
#include "gdbsupport/gdb_optional.h"
|
#include "gdbsupport/gdb_optional.h"
|
||||||
|
#include "safe-ctype.h"
|
||||||
|
|
||||||
/* Last specified output format. */
|
/* Last specified output format. */
|
||||||
|
|
||||||
@ -1233,6 +1234,62 @@ print_command_1 (const char *args, int voidprint)
|
|||||||
print_value (val, print_opts);
|
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. */
|
/* See valprint.h. */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1245,6 +1302,9 @@ print_command_completer (struct cmd_list_element *ignore,
|
|||||||
(tracker, &text, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group))
|
(tracker, &text, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_over_slash_fmt (tracker, &text))
|
||||||
|
return;
|
||||||
|
|
||||||
const char *word = advance_to_expression_complete_word_point (tracker, text);
|
const char *word = advance_to_expression_complete_word_point (tracker, text);
|
||||||
expression_completer (ignore, tracker, text, word);
|
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 ());
|
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.
|
/* 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\
|
Usage: info symbol ADDR\n\
|
||||||
Only for symbols with fixed locations (global or static scope)."));
|
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\
|
Examine memory: x/FMT ADDRESS.\n\
|
||||||
ADDRESS is an expression for the memory address to examine.\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\
|
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\
|
Defaults for format and size letters are those previously used.\n\
|
||||||
Default count is 1. Default address is following last thing printed\n\
|
Default count is 1. Default address is following last thing printed\n\
|
||||||
with this command or \"print\"."));
|
with this command or \"print\"."));
|
||||||
|
set_cmd_completer_handle_brkchars (c, display_and_x_command_completer);
|
||||||
|
|
||||||
add_info ("display", info_display_command, _("\
|
add_info ("display", info_display_command, _("\
|
||||||
Expressions to display when program stops, with code numbers.\n\
|
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."),
|
Do \"info display\" to see current list of code numbers."),
|
||||||
&cmdlist);
|
&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\
|
Print value of expression EXP each time the program stops.\n\
|
||||||
Usage: display[/FMT] EXP\n\
|
Usage: display[/FMT] EXP\n\
|
||||||
/FMT may be used before EXP as in the \"print\" command.\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\
|
and examining is done as in the \"x\" command.\n\n\
|
||||||
With no argument, display all currently requested auto-display expressions.\n\
|
With no argument, display all currently requested auto-display expressions.\n\
|
||||||
Use \"undisplay\" to cancel display requests previously made."));
|
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, _("\
|
add_cmd ("display", class_vars, enable_display_command, _("\
|
||||||
Enable some expressions to be displayed when program stops.\n\
|
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>
|
2020-11-16 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
* gdb.dwarf2/data-loc.exp: Update expected output. Remove C
|
* gdb.dwarf2/data-loc.exp: Update expected output. Remove C
|
||||||
|
@ -172,6 +172,11 @@ if { ![readline_is_used] } {
|
|||||||
return -1
|
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'"
|
set test "complete 'hfgfh'"
|
||||||
send_gdb "hfgfh\t"
|
send_gdb "hfgfh\t"
|
||||||
gdb_test_multiple "" "$test" {
|
gdb_test_multiple "" "$test" {
|
||||||
@ -922,3 +927,27 @@ gdb_test_multiple "" "$test" {
|
|||||||
pass "$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