gdb: add cmd_list_element::is_prefix

Same idea as the previous patch, but for prefix instead of alias.

gdb/ChangeLog:

	* cli/cli-decode.h (cmd_list_element) <is_prefix>: New, use it.

Change-Id: I76a9d2e82fc8d7429904424674d99ce6f9880e2b
This commit is contained in:
Simon Marchi 2021-05-14 15:38:49 -04:00
parent 1be99b11f8
commit 3d0b356410
11 changed files with 37 additions and 31 deletions

View file

@ -1465,7 +1465,7 @@ info_auto_load_cmd (const char *args, int from_tty)
{ {
ui_out_emit_tuple option_emitter (uiout, "option"); ui_out_emit_tuple option_emitter (uiout, "option");
gdb_assert (!list->subcommands); gdb_assert (!list->is_prefix ());
gdb_assert (list->type == not_set_cmd); gdb_assert (list->type == not_set_cmd);
uiout->field_string ("name", list->name); uiout->field_string ("name", list->name);

View file

@ -1625,7 +1625,7 @@ show_user (const char *args, int from_tty)
{ {
for (c = cmdlist; c; c = c->next) for (c = cmdlist; c; c = c->next)
{ {
if (cli_user_command_p (c) || c->subcommands != NULL) if (cli_user_command_p (c) || c->is_prefix ())
show_user_1 (c, "", c->name, gdb_stdout); show_user_1 (c, "", c->name, gdb_stdout);
} }
} }
@ -1900,7 +1900,7 @@ alias_command (const char *args, int from_tty)
/* We've already tried to look up COMMAND. */ /* We've already tried to look up COMMAND. */
gdb_assert (c_command != NULL gdb_assert (c_command != NULL
&& c_command != (struct cmd_list_element *) -1); && c_command != (struct cmd_list_element *) -1);
gdb_assert (c_command->subcommands != NULL); gdb_assert (c_command->is_prefix ());
c_alias = lookup_cmd_1 (& alias_prefix, cmdlist, NULL, NULL, 1); c_alias = lookup_cmd_1 (& alias_prefix, cmdlist, NULL, NULL, 1);
if (c_alias != c_command) if (c_alias != c_command)
error (_("ALIAS and COMMAND prefixes do not match.")); error (_("ALIAS and COMMAND prefixes do not match."));

View file

@ -69,8 +69,9 @@ lookup_cmd_with_subcommands (cmd_list_element **subcommands,
{ {
struct cmd_list_element *q; struct cmd_list_element *q;
if (p->subcommands == NULL) if (!p->is_prefix ())
continue; continue;
else if (p->subcommands == subcommands) else if (p->subcommands == subcommands)
{ {
/* If we found an alias, we must return the aliased /* If we found an alias, we must return the aliased
@ -163,7 +164,7 @@ set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd,
std::string std::string
cmd_list_element::prefixname () const cmd_list_element::prefixname () const
{ {
if (this->subcommands == nullptr) if (!this->is_prefix ())
/* Not a prefix command. */ /* Not a prefix command. */
return ""; return "";
@ -369,7 +370,7 @@ update_prefix_field_of_prefixed_commands (struct cmd_list_element *c)
'auto-load' command was not yet reachable by 'auto-load' command was not yet reachable by
lookup_cmd_for_subcommands (list, cmdlist) lookup_cmd_for_subcommands (list, cmdlist)
that searches from the top level 'cmdlist'. */ that searches from the top level 'cmdlist'. */
if (p->subcommands != nullptr) if (p->is_prefix ())
update_prefix_field_of_prefixed_commands (p); update_prefix_field_of_prefixed_commands (p);
} }
} }
@ -1184,7 +1185,7 @@ apropos_cmd (struct ui_file *stream,
print_doc_of_command (c, prefix, verbose, regex, stream); print_doc_of_command (c, prefix, verbose, regex, stream);
} }
/* Check if this command has subcommands. */ /* Check if this command has subcommands. */
if (c->subcommands != NULL) if (c->is_prefix ())
{ {
/* Recursively call ourselves on the subcommand list, /* Recursively call ourselves on the subcommand list,
passing the right prefix in. */ passing the right prefix in. */
@ -1249,12 +1250,13 @@ help_cmd (const char *command, struct ui_file *stream)
fputs_filtered (c->doc, stream); fputs_filtered (c->doc, stream);
fputs_filtered ("\n", stream); fputs_filtered ("\n", stream);
if (c->subcommands == 0 && c->func != NULL) if (!c->is_prefix () && c->func != NULL)
return; return;
fprintf_filtered (stream, "\n"); fprintf_filtered (stream, "\n");
/* If this is a prefix command, print it's subcommands. */ /* If this is a prefix command, print it's subcommands. */
if (c->subcommands) if (c->is_prefix ())
help_list (*c->subcommands, c->prefixname ().c_str (), help_list (*c->subcommands, c->prefixname ().c_str (),
all_commands, stream); all_commands, stream);
@ -1446,7 +1448,7 @@ print_help_for_command (struct cmd_list_element *c,
fput_aliases_definition_styled (c, stream); fput_aliases_definition_styled (c, stream);
if (recurse if (recurse
&& c->subcommands != 0 && c->is_prefix ()
&& c->abbrev_flag == 0) && c->abbrev_flag == 0)
/* Subcommands of a prefix command typically have 'all_commands' /* Subcommands of a prefix command typically have 'all_commands'
as class. If we pass CLASS to recursive invocation, as class. If we pass CLASS to recursive invocation,
@ -1516,7 +1518,7 @@ help_cmd_list (struct cmd_list_element *list, enum command_class theclass,
if (recurse if (recurse
&& (theclass == class_user || theclass == class_alias) && (theclass == class_user || theclass == class_alias)
&& c->subcommands != NULL) && c->is_prefix ())
{ {
/* User-defined commands or aliases may be subcommands. */ /* User-defined commands or aliases may be subcommands. */
help_cmd_list (*c->subcommands, theclass, recurse, stream); help_cmd_list (*c->subcommands, theclass, recurse, stream);
@ -1694,7 +1696,7 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
} }
/* If we found a prefix command, keep looking. */ /* If we found a prefix command, keep looking. */
if (found->subcommands) if (found->is_prefix ())
{ {
c = lookup_cmd_1 (text, *found->subcommands, result_list, default_args, c = lookup_cmd_1 (text, *found->subcommands, result_list, default_args,
ignore_help_classes, lookup_for_completion_p); ignore_help_classes, lookup_for_completion_p);
@ -1865,7 +1867,7 @@ lookup_cmd (const char **line, struct cmd_list_element *list,
while (**line == ' ' || **line == '\t') while (**line == ' ' || **line == '\t')
(*line)++; (*line)++;
if (c->subcommands && **line && !c->allow_unknown) if (c->is_prefix () && **line && !c->allow_unknown)
undef_cmd_error (c->prefixname ().c_str (), *line); undef_cmd_error (c->prefixname ().c_str (), *line);
/* Seems to be what he wants. Return it. */ /* Seems to be what he wants. Return it. */
@ -2056,7 +2058,7 @@ lookup_cmd_composition_1 (const char *text,
text += len; text += len;
text = skip_spaces (text); text = skip_spaces (text);
if ((*cmd)->subcommands != nullptr && *text != '\0') if ((*cmd)->is_prefix () && *text != '\0')
{ {
cur_list = *(*cmd)->subcommands; cur_list = *(*cmd)->subcommands;
*prefix_cmd = *cmd; *prefix_cmd = *cmd;
@ -2123,7 +2125,7 @@ complete_on_cmdlist (struct cmd_list_element *list,
if (!strncmp (ptr->name, text, textlen) if (!strncmp (ptr->name, text, textlen)
&& !ptr->abbrev_flag && !ptr->abbrev_flag
&& (!ignore_help_classes || ptr->func && (!ignore_help_classes || ptr->func
|| ptr->subcommands)) || ptr->is_prefix ()))
{ {
if (pass == 0) if (pass == 0)
{ {

View file

@ -83,6 +83,10 @@ struct cmd_list_element
bool is_alias () const bool is_alias () const
{ return this->alias_target != nullptr; } { return this->alias_target != nullptr; }
/* Return true if this command is a prefix command. */
bool is_prefix () const
{ return this->subcommands != nullptr; }
/* Points to next command in this list. */ /* Points to next command in this list. */
struct cmd_list_element *next = nullptr; struct cmd_list_element *next = nullptr;

View file

@ -1350,7 +1350,7 @@ validate_comname (const char **comname)
const char *tem = prefix.c_str (); const char *tem = prefix.c_str ();
c = lookup_cmd (&tem, cmdlist, "", NULL, 0, 1); c = lookup_cmd (&tem, cmdlist, "", NULL, 0, 1);
if (c->subcommands == NULL) if (!c->is_prefix ())
error (_("\"%s\" is not a prefix command."), prefix.c_str ()); error (_("\"%s\" is not a prefix command."), prefix.c_str ());
list = c->subcommands; list = c->subcommands;
@ -1414,7 +1414,7 @@ do_define_command (const char *comname, int from_tty,
/* if C is a prefix command that was previously defined, /* if C is a prefix command that was previously defined,
tell the user its subcommands will be kept, and ask tell the user its subcommands will be kept, and ask
if ok to redefine the command. */ if ok to redefine the command. */
if (c->subcommands != nullptr) if (c->is_prefix ())
q = (c->user_commands.get () == nullptr q = (c->user_commands.get () == nullptr
|| query (_("Keeping subcommands of prefix command \"%s\".\n" || query (_("Keeping subcommands of prefix command \"%s\".\n"
"Redefine command \"%s\"? "), c->name, c->name)); "Redefine command \"%s\"? "), c->name, c->name));
@ -1595,7 +1595,7 @@ define_prefix_command (const char *comname, int from_tty)
if (c != nullptr && c->theclass != class_user) if (c != nullptr && c->theclass != class_user)
error (_("Command \"%s\" is built-in."), comfull); error (_("Command \"%s\" is built-in."), comfull);
if (c != nullptr && c->subcommands != nullptr) if (c != nullptr && c->is_prefix ())
{ {
/* c is already a user defined prefix command. */ /* c is already a user defined prefix command. */
return; return;
@ -1665,7 +1665,7 @@ show_user_1 (struct cmd_list_element *c, const char *prefix, const char *name,
struct command_line *cmdlines = c->user_commands.get (); struct command_line *cmdlines = c->user_commands.get ();
fprintf_filtered (stream, "User %scommand \"", fprintf_filtered (stream, "User %scommand \"",
c->subcommands == NULL ? "" : "prefix "); c->is_prefix () ? "prefix" : "");
fprintf_styled (stream, title_style.style (), "%s%s", fprintf_styled (stream, title_style.style (), "%s%s",
prefix, name); prefix, name);
fprintf_filtered (stream, "\":\n"); fprintf_filtered (stream, "\":\n");
@ -1676,12 +1676,12 @@ show_user_1 (struct cmd_list_element *c, const char *prefix, const char *name,
} }
} }
if (c->subcommands != NULL) if (c->is_prefix ())
{ {
const std::string prefixname = c->prefixname (); const std::string prefixname = c->prefixname ();
for (c = *c->subcommands; c != NULL; c = c->next) for (c = *c->subcommands; c != NULL; c = c->next)
if (c->theclass == class_user || c->subcommands != NULL) if (c->theclass == class_user || c->is_prefix ())
show_user_1 (c, prefixname.c_str (), c->name, gdb_stdout); show_user_1 (c, prefixname.c_str (), c->name, gdb_stdout);
} }

View file

@ -740,7 +740,7 @@ cmd_show_list (struct cmd_list_element *list, int from_tty)
/* If we find a prefix, run its list, prefixing our output by its /* If we find a prefix, run its list, prefixing our output by its
prefix (with "show " skipped). */ prefix (with "show " skipped). */
if (list->subcommands && !list->is_alias ()) if (list->is_prefix () && !list->is_alias ())
{ {
ui_out_emit_tuple optionlist_emitter (uiout, "optionlist"); ui_out_emit_tuple optionlist_emitter (uiout, "optionlist");
std::string prefixname = list->prefixname (); std::string prefixname = list->prefixname ();
@ -758,7 +758,7 @@ cmd_show_list (struct cmd_list_element *list, int from_tty)
{ {
/* If we find a prefix, output it (with "show " skipped). */ /* If we find a prefix, output it (with "show " skipped). */
std::string prefixname = list->prefix->prefixname (); std::string prefixname = list->prefix->prefixname ();
prefixname = (list->prefix->subcommands == nullptr ? "" prefixname = (!list->prefix->is_prefix () ? ""
: strstr (prefixname.c_str (), "show ") + 5); : strstr (prefixname.c_str (), "show ") + 5);
uiout->text (prefixname.c_str ()); uiout->text (prefixname.c_str ());
} }

View file

@ -1456,7 +1456,7 @@ complete_line_internal_1 (completion_tracker &tracker,
{ {
/* The command is followed by whitespace; we need to /* The command is followed by whitespace; we need to
complete on whatever comes after command. */ complete on whatever comes after command. */
if (c->subcommands) if (c->is_prefix ())
{ {
/* It is a prefix command; what comes after it is /* It is a prefix command; what comes after it is
a subcommand (e.g. "info "). */ a subcommand (e.g. "info "). */
@ -1524,7 +1524,7 @@ complete_line_internal_1 (completion_tracker &tracker,
{ {
/* There is non-whitespace beyond the command. */ /* There is non-whitespace beyond the command. */
if (c->subcommands && !c->allow_unknown) if (c->is_prefix () && !c->allow_unknown)
{ {
/* It is an unrecognized subcommand of a prefix command, /* It is an unrecognized subcommand of a prefix command,
e.g. "info adsfkdj". */ e.g. "info adsfkdj". */

View file

@ -524,7 +524,7 @@ gdbscm_parse_command_name (const char *name,
gdbscm_scm_from_c_string (name), msg); gdbscm_scm_from_c_string (name), msg);
} }
if (elt->subcommands) if (elt->is_prefix ())
{ {
xfree (prefix_text); xfree (prefix_text);
*base_list = elt->subcommands; *base_list = elt->subcommands;

View file

@ -111,7 +111,7 @@ cmdpy_function (struct cmd_list_element *command,
error (_("Invalid invocation of Python command object.")); error (_("Invalid invocation of Python command object."));
if (! PyObject_HasAttr ((PyObject *) obj, invoke_cst)) if (! PyObject_HasAttr ((PyObject *) obj, invoke_cst))
{ {
if (obj->command->subcommands != nullptr) if (obj->command->is_prefix ())
{ {
/* A prefix command does not need an invoke method. */ /* A prefix command does not need an invoke method. */
return; return;
@ -393,7 +393,7 @@ gdbpy_parse_command_name (const char *name,
return NULL; return NULL;
} }
if (elt->subcommands) if (elt->is_prefix ())
{ {
*base_list = elt->subcommands; *base_list = elt->subcommands;
return result; return result;

View file

@ -647,7 +647,7 @@ execute_command (const char *p, int from_tty)
if (c->theclass == class_user && c->user_commands) if (c->theclass == class_user && c->user_commands)
execute_user_command (c, arg); execute_user_command (c, arg);
else if (c->theclass == class_user else if (c->theclass == class_user
&& c->subcommands && !c->allow_unknown) && c->is_prefix () && !c->allow_unknown)
/* If this is a user defined prefix that does not allow unknown /* If this is a user defined prefix that does not allow unknown
(in other words, C is a prefix command and not a command (in other words, C is a prefix command and not a command
that can be followed by its args), report the list of that can be followed by its args), report the list of

View file

@ -83,7 +83,7 @@ check_doc (struct cmd_list_element *commandlist, const char *prefix)
/* Check if this command has subcommands and is not an /* Check if this command has subcommands and is not an
abbreviation. We skip checking subcommands of abbreviations abbreviation. We skip checking subcommands of abbreviations
in order to avoid duplicates in the output. */ in order to avoid duplicates in the output. */
if (c->subcommands != NULL && !c->abbrev_flag) if (c->is_prefix () && !c->abbrev_flag)
{ {
/* Recursively call ourselves on the subcommand list, /* Recursively call ourselves on the subcommand list,
passing the right prefix in. */ passing the right prefix in. */
@ -155,7 +155,7 @@ traverse_command_structure (struct cmd_list_element **list,
{ {
/* If this command has subcommands and is not an alias, /* If this command has subcommands and is not an alias,
traverse the subcommands. */ traverse the subcommands. */
if (c->subcommands != NULL && !c->is_alias ()) if (c->is_prefix () && !c->is_alias ())
{ {
/* Recursively call ourselves on the subcommand list, /* Recursively call ourselves on the subcommand list,
passing the right prefix in. */ passing the right prefix in. */