int ignore_help_classes,
int *nfound);
+static void help_cmd_list (struct cmd_list_element *list,
+ enum command_class theclass,
+ bool recurse,
+ struct ui_file *stream);
+
static void help_all (struct ui_file *stream);
/* Look up a command whose 'prefixlist' is KEY. Return the command if found,
}
static void
-print_help_for_command (struct cmd_list_element *c, const char *prefix,
- int recurse, struct ui_file *stream);
+print_help_for_command (struct cmd_list_element *c,
+ bool recurse, struct ui_file *stream);
\f
/* Set the callback function for the specified command. For each both
return add_cmd (name, theclass, fun, doc, &cmdlist);
}
-/* Add an alias or abbreviation command to the list of commands. */
+/* Add an alias or abbreviation command to the list of commands.
+ For aliases predefined by GDB (such as bt), THECLASS must be
+ different of class_alias, as class_alias is used to identify
+ user defined aliases. */
struct cmd_list_element *
add_com_alias (const char *name, const char *oldname, enum command_class theclass,
&cmdlist, suppress_notification);
}
+/* Print the prefix of C followed by name of C in title style. */
+
+static void
+fput_command_name_styled (struct cmd_list_element *c, struct ui_file *stream)
+{
+ const char *prefixname
+ = c->prefix == nullptr ? "" : c->prefix->prefixname;
+
+ fprintf_styled (stream, title_style.style (), "%s%s", prefixname, c->name);
+}
+
+/* If C has one or more aliases, style print the name of C and
+ the name of its aliases, separated by commas.
+ If ALWAYS_FPUT_C_NAME, print the name of C even if it has no aliases.
+ If one or more names are printed, POSTFIX is printed after the last name.
+*/
+
+static void
+fput_command_names_styled (struct cmd_list_element *c,
+ bool always_fput_c_name, const char *postfix,
+ struct ui_file *stream)
+{
+ if (always_fput_c_name || c->aliases != nullptr)
+ fput_command_name_styled (c, stream);
+ if (c->aliases != nullptr)
+ {
+ for (cmd_list_element *iter = c->aliases; iter; iter = iter->alias_chain)
+ {
+ fputs_filtered (", ", stream);
+ wrap_here (" ");
+ fput_command_name_styled (iter, stream);
+ }
+ }
+ if (always_fput_c_name || c->aliases != nullptr)
+ fputs_filtered (postfix, stream);
+}
+
/* If VERBOSE, print the full help for command C and highlight the
documentation parts matching HIGHLIGHT,
otherwise print only one-line help for command C. */
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
/* 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)
{
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)
{
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. */
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)
{
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.
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);
else
fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2);
- help_cmd_list (list, theclass, cmdtype, (int) theclass >= 0, stream);
+ help_cmd_list (list, theclass, theclass >= 0, stream);
if (theclass == all_classes)
{
if (c->func == NULL)
{
fprintf_filtered (stream, "\nCommand class: %s\n\n", c->name);
- help_cmd_list (cmdlist, c->theclass, "", 1, stream);
+ help_cmd_list (cmdlist, c->theclass, true, stream);
}
}
fprintf_filtered (stream, "\nUnclassified commands\n\n");
seen_unclassified = 1;
}
- print_help_for_command (c, "", 1, stream);
+ print_help_for_command (c, 1, stream);
}
}
If RECURSE is non-zero, also print one-line descriptions
of all prefixed subcommands. */
static void
-print_help_for_command (struct cmd_list_element *c, const char *prefix,
- int recurse, struct ui_file *stream)
+print_help_for_command (struct cmd_list_element *c,
+ bool recurse, struct ui_file *stream)
{
- fprintf_styled (stream, title_style.style (),
- "%s%s", prefix, c->name);
- fputs_filtered (" -- ", stream);
+ fput_command_names_styled (c, true, " -- ", stream);
print_doc_line (stream, c->doc, false);
fputs_filtered ("\n", stream);
/* Subcommands of a prefix command typically have 'all_commands'
as class. If we pass CLASS to recursive invocation,
most often we won't see anything. */
- help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 1, stream);
+ help_cmd_list (*c->prefixlist, all_commands, true, stream);
}
/*
* Implement a help command on command list LIST.
* RECURSE should be non-zero if this should be done recursively on
* all sublists of LIST.
- * PREFIX is the prefix to print before each command name.
* STREAM is the stream upon which the output should be written.
* THECLASS should be:
* A non-negative class number to list only commands in that
- * class.
* ALL_COMMANDS to list all commands in list.
* ALL_CLASSES to list all classes in list.
*
+ * Note that aliases are only shown when THECLASS is class_alias.
+ * In the other cases, the aliases will be shown together with their
+ * aliased command.
+ *
* Note that RECURSE will be active on *all* sublists, not just the
* ones selected by the criteria above (ie. the selection mechanism
* is at the low level, not the high-level).
*/
-void
+
+static void
help_cmd_list (struct cmd_list_element *list, enum command_class theclass,
- const char *prefix, int recurse, struct ui_file *stream)
+ bool recurse, struct ui_file *stream)
{
struct cmd_list_element *c;
for (c = list; c; c = c->next)
{
- if (c->abbrev_flag == 0
- && !c->cmd_deprecated
- && (theclass == all_commands
- || (theclass == all_classes && c->func == NULL)
- || (theclass == c->theclass && c->func != NULL)))
+ if (c->abbrev_flag == 1 || c->cmd_deprecated)
{
- print_help_for_command (c, prefix, recurse, stream);
+ /* Do not show abbreviations or deprecated commands. */
+ continue;
}
- else if (c->abbrev_flag == 0
- && recurse
- && !c->cmd_deprecated
- && theclass == class_user && c->prefixlist != NULL)
- /* User-defined commands may be subcommands. */
- help_cmd_list (*c->prefixlist, theclass, c->prefixname,
- recurse, stream);
+
+ if (c->cmd_pointer != nullptr && theclass != class_alias)
+ {
+ /* Do not show an alias, unless specifically showing the
+ list of aliases: for all other classes, an alias is
+ shown (if needed) together with its aliased command. */
+ continue;
+ }
+
+ if (theclass == all_commands
+ || (theclass == all_classes && c->func == NULL)
+ || (theclass == c->theclass && c->func != NULL))
+ {
+ /* show C when
+ - showing all commands
+ - showing all classes and C is a help class
+ - showing commands of THECLASS and C is not the help class */
+
+ /* If we show the class_alias and C is an alias, do not recurse,
+ as this would show the (possibly very long) not very useful
+ list of sub-commands of the aliased command. */
+ print_help_for_command
+ (c,
+ recurse && (theclass != class_alias || c->cmd_pointer == nullptr),
+ stream);
+ continue;
+ }
+
+ if (recurse
+ && (theclass == class_user || theclass == class_alias)
+ && c->prefixlist != NULL)
+ {
+ /* User-defined commands or aliases may be subcommands. */
+ help_cmd_list (*c->prefixlist, theclass, recurse, stream);
+ continue;
+ }
+
+ /* Do not show C or recurse on C, e.g. because C does not belong to
+ THECLASS or because C is a help class. */
}
}
\f