Use command style in "help" command

This changes the help command to use the new command style when
displaying text like:

    List of "catch" subcommands:

As a side effect, this mildly -- but not hugely -- cleans up some i18n
issues in help_list.  The header comment for that function is also
changed to the gdb style.

Finally, this function used to print something like:

    Type "help catch" followed by catch subcommand name for full documentation.

The second "catch" here seems redundant to me, so this patch removes
it.
This commit is contained in:
Tom Tromey
2025-01-11 14:11:01 -07:00
parent af16bf565f
commit 652e09d5c6
9 changed files with 80 additions and 70 deletions

View File

@@ -215,7 +215,7 @@ error_no_arg (const char *why)
static void
info_command (const char *arg, int from_tty)
{
help_list (infolist, "info ", all_commands, gdb_stdout);
help_list (infolist, "info", all_commands, gdb_stdout);
}
/* See cli/cli-cmds.h. */

View File

@@ -128,8 +128,10 @@ set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd,
cmd->completer_handle_brkchars = func;
}
/* See cli-decode.h. */
std::string
cmd_list_element::prefixname () const
cmd_list_element::prefixname_no_space () const
{
if (!this->is_prefix ())
/* Not a prefix command. */
@@ -137,14 +139,27 @@ cmd_list_element::prefixname () const
std::string prefixname;
if (this->prefix != nullptr)
prefixname = this->prefix->prefixname ();
{
prefixname = this->prefix->prefixname_no_space ();
prefixname += " ";
}
prefixname += this->name;
prefixname += " ";
return prefixname;
}
/* See cli-decode.h. */
std::string
cmd_list_element::prefixname () const
{
std::string result = prefixname_no_space ();
if (!result.empty ())
result += " ";
return result;
}
/* See cli/cli-decode.h. */
std::vector<std::string>
@@ -381,7 +396,7 @@ do_prefix_cmd (const char *args, int from_tty, struct cmd_list_element *c)
while (c->is_alias ())
c = c->alias_target;
help_list (*c->subcommands, c->prefixname ().c_str (),
help_list (*c->subcommands, c->prefixname_no_space ().c_str (),
all_commands, gdb_stdout);
}
@@ -1885,7 +1900,7 @@ help_cmd (const char *command, struct ui_file *stream)
/* If this is a prefix command, print it's subcommands. */
if (c->is_prefix ())
help_list (*c->subcommands, c->prefixname ().c_str (),
help_list (*c->subcommands, c->prefixname_no_space ().c_str (),
all_commands, stream);
/* If this is a class name, print all of the commands in the class. */
@@ -1906,54 +1921,48 @@ help_cmd (const char *command, struct ui_file *stream)
c->hook_post->name);
}
/*
* Get a specific kind of help on a command list.
*
* LIST is the list.
* CMDTYPE is the prefix to use in the title string.
* THECLASS is the class with which to list the nodes of this list (see
* documentation for help_cmd_list below), As usual, ALL_COMMANDS for
* everything, ALL_CLASSES for just classes, and non-negative for only things
* in a specific class.
* and STREAM is the output stream on which to print things.
* If you call this routine with a class >= 0, it recurses.
*/
/* Get a specific kind of help on a command list.
LIST is the list.
CMDTYPE is the prefix to use in the title string. It should not
end in a space.
THECLASS is the class with which to list the nodes of this list (see
documentation for help_cmd_list below), As usual, ALL_COMMANDS for
everything, ALL_CLASSES for just classes, and non-negative for only things
in a specific class.
and STREAM is the output stream on which to print things.
If you call this routine with a class >= 0, it recurses. */
void
help_list (struct cmd_list_element *list, const char *cmdtype,
enum command_class theclass, struct ui_file *stream)
{
int len;
char *cmdtype1, *cmdtype2;
/* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub".
*/
len = strlen (cmdtype);
cmdtype1 = (char *) alloca (len + 1);
cmdtype1[0] = 0;
cmdtype2 = (char *) alloca (len + 4);
cmdtype2[0] = 0;
if (len)
int len = strlen (cmdtype);
const char *space = "";
const char *prefix = "";
if (len > 0)
{
cmdtype1[0] = ' ';
memcpy (cmdtype1 + 1, cmdtype, len - 1);
cmdtype1[len] = 0;
memcpy (cmdtype2, cmdtype, len - 1);
strcpy (cmdtype2 + len - 1, " sub");
prefix = "sub";
space = " ";
}
if (theclass == all_classes)
gdb_printf (stream, "List of classes of %scommands:\n\n", cmdtype2);
gdb_printf (stream, "List of classes of %scommands:\n\n",
prefix);
else if (len == 0)
gdb_printf (stream, "List of commands:\n\n");
else
gdb_printf (stream, "List of %scommands:\n\n", cmdtype2);
gdb_printf (stream, "List of \"%ps\" %scommands:\n\n",
styled_string (command_style.style (), cmdtype),
prefix);
help_cmd_list (list, theclass, theclass >= 0, stream);
if (theclass == all_classes)
{
gdb_printf (stream, "\n\
Type \"%p[help%s%p]\" followed by a class name for a list of commands in ",
Type \"%p[help%s%s%p]\" followed by a class name for a list of commands in ",
command_style.style ().ptr (),
cmdtype1,
space, cmdtype,
nullptr);
stream->wrap_here (0);
gdb_printf (stream, "that class.");
@@ -1963,9 +1972,9 @@ Type \"%ps\" for the list of all commands.",
styled_string (command_style.style (), "help all"));
}
gdb_printf (stream, "\nType \"%p[help%s%p]\" followed by %scommand name ",
command_style.style ().ptr (), cmdtype1, nullptr,
cmdtype2);
gdb_printf (stream, "\nType \"%p[help%s%s%p]\" followed by %scommand name ",
command_style.style ().ptr (), space, cmdtype, nullptr,
prefix);
stream->wrap_here (0);
gdb_puts ("for ", stream);
stream->wrap_here (0);

View File

@@ -83,6 +83,9 @@ struct cmd_list_element
For non-prefix commands, return an empty string. */
std::string prefixname () const;
/* Like prefixname, but do not append a trailing space. */
std::string prefixname_no_space () const;
/* Return a vector of strings describing the components of the full name
of this command. For example, if this command is 'set AA BB CC',
then the vector will contain 4 elements 'set', 'AA', 'BB', and 'CC'

View File

@@ -311,7 +311,7 @@ gdb_test_multiple "" "$test" {
-re "^info $" {
send_gdb "\n"
gdb_test_multiple "" "$test" {
-re "List of info subcommands.*$gdb_prompt $" {
-re "List of \"info\" subcommands.*$gdb_prompt $" {
pass "$test"
}
}
@@ -324,7 +324,7 @@ gdb_test_multiple "" "$test" {
-re "^info \\\x07$" {
send_gdb "\n"
gdb_test_multiple "" "$test" {
-re "List of info subcommands:\r\n\r\n.*$gdb_prompt $" {
-re "List of \"info\" subcommands:\r\n\r\n.*$gdb_prompt $" {
pass "$test"
}
}

View File

@@ -31,8 +31,8 @@ set timeout 60
gdb_test "add-symbol-file" "add-symbol-file takes a file name and an address"
# test append
gdb_test "append" "List of append subcommands:.*"
gdb_test "append binary" "List of append binary subcommands:.*"
gdb_test "append" "List of \"append\" subcommands:.*"
gdb_test "append binary" "List of \"append binary\" subcommands:.*"
gdb_test "append memory" "Missing filename\."
gdb_test "append value" "Missing filename\."
gdb_test "append binary memory" "Missing filename\."
@@ -79,7 +79,7 @@ gdb_test "call" "The history is empty..*"
#test catch
gdb_test "catch" "List of catch subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help catch\" followed by catch subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
gdb_test "catch" "List of \"catch\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help catch\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
#test cd
gdb_test "cd" "Working directory \[^\r\n\]*\(\r\n \\(canonically \[^\r\n\]*\\)\)?\\."
@@ -148,12 +148,12 @@ gdb_test "down" "No stack.*"
#test down-silently
gdb_test "down-silently" "No stack."
# test dump
gdb_test "dump" "List of dump subcommands:.*"
gdb_test "dump binary" "List of dump binary subcommands:.*"
gdb_test "dump ihex" "List of dump ihex subcommands:.*"
gdb_test "dump" "List of \"dump\" subcommands:.*"
gdb_test "dump binary" "List of \"dump binary\" subcommands:.*"
gdb_test "dump ihex" "List of \"dump ihex\" subcommands:.*"
gdb_test "dump memory" "Missing filename\."
gdb_test "dump srec" "List of dump srec subcommands:.*"
gdb_test "dump tekhex" "List of dump tekhex subcommands:.*"
gdb_test "dump srec" "List of \"dump srec\" subcommands:.*"
gdb_test "dump tekhex" "List of \"dump tekhex\" subcommands:.*"
gdb_test "dump value" "Missing filename\."
gdb_test "dump binary memory" "Missing filename\."
gdb_test "dump binary value" "Missing filename\."
@@ -254,9 +254,9 @@ gdb_test "help" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- Use
#test handle
gdb_test "handle" "Argument required .signal to handle.*"
#test info "i" abbreviation
gdb_test "i" "List of info subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by info subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "info \"i\" abbreviation"
gdb_test "i" "List of \"info\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "info \"i\" abbreviation"
#test info
gdb_test "info" "List of info subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by info subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
gdb_test "info" "List of \"info\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
#test ignore
gdb_test "ignore" "Argument required .a breakpoint number.*"
#test info address
@@ -459,7 +459,7 @@ gdb_test "nexti" "The program is not being run."
gdb_test "output" "Argument required .expression to compute.*"
#test overlay
gdb_test "overlay" "List of overlay subcommands:.*"
gdb_test "overlay" "List of \"overlay\" subcommands:.*"
#test a non-existant overlay subcommand
gdb_test "overlay on" "Undefined overlay command.* Try \"help overlay\"."
gdb_test_no_output "overlay manual" "overlay manual #1"
@@ -556,7 +556,7 @@ gdb_test_no_output "set args" "set args"
# Test set check abbreviations
foreach x {"c" "ch" "check"} {
gdb_test "set $x" "List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set strict type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." \
gdb_test "set $x" "List of \"set check\" subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set strict type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." \
"set check \"$x\" abbreviation"
}
@@ -586,17 +586,17 @@ gdb_test_no_output "set history save" "set history save"
#test set history size
gdb_test "set history size" "Argument required .integer to set it to.*"
#test set history
gdb_test "set history" "List of set history subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by set history subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
gdb_test "set history" "List of \"set history\" subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
#test set language
gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, asm, c, c.., d, fortran, go, minimal, modula-2, objective-c, opencl, pascal, rust."
#test set listsize
gdb_test "set listsize" "Argument required .integer to set it to.*"
#test set print "p" abbreviation
gdb_test "set p" "List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"p\" abbreviation"
gdb_test "set p" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"p\" abbreviation"
#test set print "pr" abbreviation
gdb_test "set pr" "List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"pr\" abbreviation"
gdb_test "set pr" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"pr\" abbreviation"
#test set print
gdb_test "set print" "List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
gdb_test "set print" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
#test set print address
gdb_test_no_output "set print address" "set print address"
#test set print array
@@ -886,7 +886,7 @@ gdb_expect {
}
#test target
gdb_test "target" "List of target subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help target\" followed by target subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
gdb_test "target" "List of \"target\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help target\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
#test tbreak
gdb_test "tbreak" "No default breakpoint address now."
#test thread
@@ -919,7 +919,7 @@ gdb_test "unset environment" \
"y"
#test unset
gdb_test "unset" "List of unset subcommands:(\[^\r\n\]*\[\r\n\])+unset environment -- Cancel environment variable VAR for the program(\[^\r\n\]*\[\r\n\])+Type \"help unset\" followed by unset subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
gdb_test "unset" "List of \"unset\" subcommands:(\[^\r\n\]*\[\r\n\])+unset environment -- Cancel environment variable VAR for the program(\[^\r\n\]*\[\r\n\])+Type \"help unset\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
#test up
#test up-silently
gdb_test "up-silently" "No stack."

View File

@@ -42,9 +42,9 @@ proc test_junk { arg junk current } {
gdb_test "show record btrace cpu" "btrace cpu is 'auto'\." "default cpu"
gdb_test "set record" \
"List of set record subcommands.*"
"List of \"set record\" subcommands.*"
gdb_test "set record btrace" \
"List of set record btrace subcommands.*"
"List of \"set record btrace\" subcommands.*"
test_bad "" "auto"
test_good "intel: 0/0"

View File

@@ -32,7 +32,7 @@ proc test_help {} {
"C\\+\\+ maintenance commands.\r\n\r\n"
}
set multiple_help_body "List of maintenance cplus subcommands:.*Command name abbreviations are allowed if unambiguous."
set multiple_help_body "List of \"maintenance cplus\" subcommands:.*Command name abbreviations are allowed if unambiguous."
gdb_test "maint cp" $multiple_help_body

View File

@@ -8708,8 +8708,8 @@ proc test_prefix_command_help { command_list expected_initial_lines args } {
# Use 'list' and not just {} because we want variables to
# be expanded in this list.
set l_stock_body [list\
"List of $full_command subcommands\:.*\[\r\n\]+"\
"Type \"help $full_command\" followed by $full_command subcommand name for full documentation\.\[\r\n\]+"]
"List of \"$full_command\" subcommands\:.*\[\r\n\]+"\
"Type \"help $full_command\" followed by subcommand name for full documentation\.\[\r\n\]+"]
set l_entire_body [concat $expected_initial_lines $l_stock_body $help_list_trailer]
if {[llength $args]>0} {
help_test_raw "help ${command}" $l_entire_body [lindex $args 0]

View File

@@ -545,12 +545,10 @@ execute_command (const char *p, int from_tty)
that can be followed by its args), report the list of
subcommands. */
{
std::string prefixname = c->prefixname ();
std::string prefixname_no_space
= prefixname.substr (0, prefixname.length () - 1);
std::string prefixname = c->prefixname_no_space ();
gdb_printf
("\"%s\" must be followed by the name of a subcommand.\n",
prefixname_no_space.c_str ());
prefixname.c_str ());
help_list (*c->subcommands, prefixname.c_str (), all_commands,
gdb_stdout);
}