From 7c05caf72d31d7382819f1113fdcf13c45729a8d Mon Sep 17 00:00:00 2001 From: Philippe Waroquiers Date: Sun, 10 May 2020 20:21:51 +0200 Subject: [PATCH] Fix/improve 'apropos' output Similarly to 'help CLASS', apropos possibly shows several times the same help (for the command and for each of its aliases). This patch changes 'apropos' so that the help for a command and all its aliases is shown once. So, apropos_cmd now skips all aliases/abbreviations, as these are printed as part of the help of the aliased command. When 'apropos' prints the help of a command, function 'help_cmd' now unconditionally print the command name and its possible aliases (as we must indicate to the user the command/aliases for which the help is printed). When 'help somecommand' prints the help of a command, if the command is not aliased, the command name is not printed (to avoid a useless first line), but if it has aliases, then the command name and all its aliases are now printed. In addition to provide to the user the choice of the best way to type a command, it also avoids the strange behaviour that the output of 'help somealias' does not mention somealias. gdb/ChangeLog 2020-05-15 Philippe Waroquiers * cli/cli-decode.c (apropos_cmd): Produce output for aliases when their aliased command is traversed. (help_cmd): Add fput_command_names_styled call to output command name and aliases when command has an alias. gdb/testsuite/ChangeLog 2020-05-15 Philippe Waroquiers * gdb.base/help.exp: Test apropos and help for commands having aliases. Fixed comments not starting with an upper-case letter or not finishing with a dot. --- gdb/ChangeLog | 7 +++++ gdb/cli/cli-decode.c | 37 ++++++++++++++++++------ gdb/testsuite/ChangeLog | 6 ++++ gdb/testsuite/gdb.base/help.exp | 51 +++++++++++++++++++-------------- 4 files changed, 71 insertions(+), 30 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2298843350b..f685addecd1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2020-05-15 Philippe Waroquiers + + * cli/cli-decode.c (apropos_cmd): Produce output for aliases + when their aliased command is traversed. + (help_cmd): Add fput_command_names_styled call to + output command name and aliases when command has an alias. + 2020-05-15 Philippe Waroquiers * cli/cli-decode.h (help_cmd_list): Remove declaration. diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c index 093692e7ac0..2b24e57d463 100644 --- a/gdb/cli/cli-decode.c +++ b/gdb/cli/cli-decode.c @@ -1078,9 +1078,7 @@ print_doc_of_command (struct cmd_list_element *c, const char *prefix, if (verbose) fputs_filtered ("\n", stream); - fprintf_styled (stream, title_style.style (), - "%s%s", prefix, c->name); - fputs_filtered (" -- ", stream); + fput_command_names_styled (c, true, " -- ", stream); if (verbose) fputs_highlighted (c->doc, highlight, stream); else @@ -1106,6 +1104,14 @@ apropos_cmd (struct ui_file *stream, /* Walk through the commands. */ for (c=commandlist;c;c=c->next) { + if (c->cmd_pointer != nullptr) + { + /* Command aliases/abbreviations are skipped to ensure we print the + doc of a command only once, when encountering the aliased + command. */ + continue; + } + returnvalue = -1; /* Needed to avoid double printing. */ if (c->name != NULL) { @@ -1115,6 +1121,17 @@ apropos_cmd (struct ui_file *stream, returnvalue = regex.search (c->name, name_len, 0, name_len, NULL); if (returnvalue >= 0) print_doc_of_command (c, prefix, verbose, regex, stream); + + /* Try to match against the name of the aliases. */ + for (cmd_list_element *iter = c->aliases; + returnvalue < 0 && iter; + iter = iter->alias_chain) + { + name_len = strlen (iter->name); + returnvalue = regex.search (iter->name, name_len, 0, name_len, NULL); + if (returnvalue >= 0) + print_doc_of_command (c, prefix, verbose, regex, stream); + } } if (c->doc != NULL && returnvalue < 0) { @@ -1124,10 +1141,8 @@ apropos_cmd (struct ui_file *stream, if (regex.search (c->doc, doc_len, 0, doc_len, NULL) >= 0) print_doc_of_command (c, prefix, verbose, regex, stream); } - /* Check if this command has subcommands and is not an - abbreviation. We skip listing subcommands of abbreviations - in order to avoid duplicates in the output. */ - if (c->prefixlist != NULL && !c->abbrev_flag) + /* Check if this command has subcommands. */ + if (c->prefixlist != NULL) { /* Recursively call ourselves on the subcommand list, passing the right prefix in. */ @@ -1150,7 +1165,7 @@ apropos_cmd (struct ui_file *stream, void help_cmd (const char *command, struct ui_file *stream) { - struct cmd_list_element *c; + struct cmd_list_element *c, *alias, *prefix_cmd, *c_cmd; if (!command) { @@ -1164,11 +1179,14 @@ help_cmd (const char *command, struct ui_file *stream) return; } + const char *orig_command = command; c = lookup_cmd (&command, cmdlist, "", 0, 0); if (c == 0) return; + lookup_cmd_composition (orig_command, &alias, &prefix_cmd, &c_cmd); + /* There are three cases here. If c->prefixlist is nonzero, we have a prefix command. Print its documentation, then list its subcommands. @@ -1181,6 +1199,9 @@ help_cmd (const char *command, struct ui_file *stream) number of this class so that the commands in the class will be listed. */ + /* If the user asked 'help somecommand' and there is no alias, + the false indicates to not output the (single) command name. */ + fput_command_names_styled (c, false, "\n", stream); fputs_filtered (c->doc, stream); fputs_filtered ("\n", stream); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 36afa3dbd3d..bf2b9384d26 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-05-15 Philippe Waroquiers + + * gdb.base/help.exp: Test apropos and help for commands + having aliases. Fixed comments not starting with an + upper-case letter or not finishing with a dot. + 2020-05-15 Philippe Waroquiers * gdb.base/alias.exp: Update help output check. diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp index 9316a705b1a..8ed0be45dbc 100644 --- a/gdb/testsuite/gdb.base/help.exp +++ b/gdb/testsuite/gdb.base/help.exp @@ -21,7 +21,7 @@ gdb_start -# disable pagination +# Disable pagination. gdb_test_no_output "set height 0" "disable pagination" # Test all the help classes. @@ -61,30 +61,30 @@ with_read1_timeout_factor 10 { # Test help of an abbreviated command. "break" is picked at random. set help_breakpoint_text "Set breakpoint at specified location\..*" - # test help breakpoint "b" abbreviation + # Test help breakpoint "b" abbreviation. gdb_test "help b" $help_breakpoint_text "help breakpoint \"b\" abbreviation" - # test help breakpoint "br" abbreviation + # Test help breakpoint "br" abbreviation. gdb_test "help br" $help_breakpoint_text "help breakpoint \"br\" abbreviation" - # test help breakpoint "bre" abbreviation + # Test help breakpoint "bre" abbreviation; gdb_test "help bre" $help_breakpoint_text "help breakpoint \"bre\" abbreviation" - # test help breakpoint "brea" abbreviation + # Test help breakpoint "brea" abbreviation. } gdb_test "help brea" $help_breakpoint_text "help breakpoint \"brea\" abbreviation" -# test help breakpoint "break" abbreviation +# Test help breakpoint "break" abbreviation. gdb_test "help break" $help_breakpoint_text "help breakpoint \"break\" abbreviation" # Test help of an aliased command. "bt" is picked at random. set help_backtrace_text "Print backtrace of all stack frames, or innermost COUNT frames\..*" -# test help backtrace "bt" abbreviation +# Test help backtrace "bt" abbreviation. gdb_test "help bt" $help_backtrace_text "help backtrace \"bt\" abbreviation" -# test help backtrace +# Test help backtrace. gdb_test "help backtrace" $help_backtrace_text -# test help commands +# Test help commands. gdb_test "help commands" "Set commands to be executed when the given breakpoints are hit\.\[\r\n\]+Give a space-separated breakpoint list as argument after \"commands\"\.\[\r\n\]+A list element can be a breakpoint number \\(e.g. `5'\\) or a range of numbers\[\r\n\]+\\(e.g. `5-7'\\)\.\[\r\n\]+With no argument, the targeted breakpoint is the last one set\.\[\r\n\]+The commands themselves follow starting on the next line\.\[\r\n\]+Type a line containing \"end\" to indicate the end of them\.\[\r\n\]+Give \"silent\" as the first line to make the breakpoint silent;\[\r\n\]+then no output is printed when it is hit, except what the commands print\." # Test a prefix command. "delete" is picked at random. -# test help delete "d" abbreviation +# Test help delete "d" abbreviation. set expected_help_delete { "Delete all or some breakpoints\.\[\r\n\]+" "Usage: delete \\\[BREAKPOINTNUM\\\]...\[\r\n\]+" @@ -93,36 +93,43 @@ set expected_help_delete { "Also a prefix command for deletion of other GDB objects\.\[\r\n\]+" } test_prefix_command_help {"d" "delete"} $expected_help_delete "help delete \"d\" abbreviation" -# test help delete +# Test help delete. test_prefix_command_help "delete" $expected_help_delete # Make sure help for help itself is present. -# test help help "h" abbreviation +# Test help help "h" abbreviation. gdb_test "help h" "Print list of commands\." "help help \"h\" abbreviation" -# test help help +# Test help help. gdb_test "help help" "Print list of commands\." # The startup banner refers to "show copying" and "show warranty", # might as well test for them. -# test help info copying +# Test help info copying. gdb_test "help show copying" "Conditions for redistributing copies of GDB\." -# test help info warranty +# Test help info warranty. gdb_test "help show warranty" "Various kinds of warranty you do not have\." # Test a few other random "help show" commands. -# test help show commands +# Test help show commands. gdb_test "help show commands" "Show the history of commands you typed\.\[\r\n\]+You can supply a command number to start with, or a `\[+\]' to start after\[\r\n\]+the previous command number shown\." -# test help show confirm +# Test help show confirm. gdb_test "help show confirm" "Show whether to confirm potentially dangerous operations\." -# test help info bogus-gdb-command +# Test help info bogus-gdb-command. gdb_test "help info bogus-gdb-command" "Undefined info command: \"bogus-gdb-command\"\. Try \"help info\"\." -# test help gotcha +# Test help gotcha. gdb_test "help gotcha" "Undefined command: \"gotcha\"\. Try \"help\"\." -# test apropos regex +# Test apropos regex. gdb_test "apropos \\\(print\[\^\[ bsiedf\\\".-\]\\\)" "handle -- Specify how to handle signals\." -# test apropos >1 word string +# Test apropos >1 word string. gdb_test "apropos handle signal" "handle -- Specify how to handle signals\." -# test apropos apropos +# Test apropos apropos. gdb_test "apropos apropos" "apropos -- Search for commands matching a REGEXP.*" + +# Test apropos for commands having aliases. +gdb_test "apropos Print backtrace of all stack frames, or innermost COUNT frames\." \ + "backtrace, where, bt -- Print backtrace of all stack frames, or innermost COUNT frames\." + +# Test help for commands having aliases. +gdb_test "help bt" "backtrace, where, bt\[\r\n\]+Print backtrace of all stack frames, or innermost COUNT frames\..*" -- 2.30.2