From 3d0b35641081d0f57d32583093f3297ff39b7379 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Fri, 14 May 2021 15:38:49 -0400 Subject: 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) : New, use it. Change-Id: I76a9d2e82fc8d7429904424674d99ce6f9880e2b --- gdb/auto-load.c | 2 +- gdb/cli/cli-cmds.c | 4 ++-- gdb/cli/cli-decode.c | 26 ++++++++++++++------------ gdb/cli/cli-decode.h | 4 ++++ gdb/cli/cli-script.c | 12 ++++++------ gdb/cli/cli-setshow.c | 4 ++-- gdb/completer.c | 4 ++-- gdb/guile/scm-cmd.c | 2 +- gdb/python/py-cmd.c | 4 ++-- gdb/top.c | 2 +- gdb/unittests/command-def-selftests.c | 4 ++-- 11 files changed, 37 insertions(+), 31 deletions(-) diff --git a/gdb/auto-load.c b/gdb/auto-load.c index 7745aa6..9cd70f1 100644 --- a/gdb/auto-load.c +++ b/gdb/auto-load.c @@ -1465,7 +1465,7 @@ info_auto_load_cmd (const char *args, int from_tty) { ui_out_emit_tuple option_emitter (uiout, "option"); - gdb_assert (!list->subcommands); + gdb_assert (!list->is_prefix ()); gdb_assert (list->type == not_set_cmd); uiout->field_string ("name", list->name); diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index c29e597..0bf418e 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -1625,7 +1625,7 @@ show_user (const char *args, int from_tty) { 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); } } @@ -1900,7 +1900,7 @@ alias_command (const char *args, int from_tty) /* We've already tried to look up COMMAND. */ gdb_assert (c_command != NULL && 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); if (c_alias != c_command) error (_("ALIAS and COMMAND prefixes do not match.")); diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c index 29b4ed2..785e726a 100644 --- a/gdb/cli/cli-decode.c +++ b/gdb/cli/cli-decode.c @@ -69,8 +69,9 @@ lookup_cmd_with_subcommands (cmd_list_element **subcommands, { struct cmd_list_element *q; - if (p->subcommands == NULL) + if (!p->is_prefix ()) continue; + else if (p->subcommands == subcommands) { /* 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 cmd_list_element::prefixname () const { - if (this->subcommands == nullptr) + if (!this->is_prefix ()) /* Not a prefix command. */ return ""; @@ -369,7 +370,7 @@ update_prefix_field_of_prefixed_commands (struct cmd_list_element *c) 'auto-load' command was not yet reachable by lookup_cmd_for_subcommands (list, cmdlist) that searches from the top level 'cmdlist'. */ - if (p->subcommands != nullptr) + if (p->is_prefix ()) 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); } /* Check if this command has subcommands. */ - if (c->subcommands != NULL) + if (c->is_prefix ()) { /* Recursively call ourselves on the subcommand list, 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 ("\n", stream); - if (c->subcommands == 0 && c->func != NULL) + if (!c->is_prefix () && c->func != NULL) return; + fprintf_filtered (stream, "\n"); /* 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 (), all_commands, stream); @@ -1446,7 +1448,7 @@ print_help_for_command (struct cmd_list_element *c, fput_aliases_definition_styled (c, stream); if (recurse - && c->subcommands != 0 + && c->is_prefix () && c->abbrev_flag == 0) /* Subcommands of a prefix command typically have 'all_commands' 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 && (theclass == class_user || theclass == class_alias) - && c->subcommands != NULL) + && c->is_prefix ()) { /* User-defined commands or aliases may be subcommands. */ 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 (found->subcommands) + if (found->is_prefix ()) { c = lookup_cmd_1 (text, *found->subcommands, result_list, default_args, 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') (*line)++; - if (c->subcommands && **line && !c->allow_unknown) + if (c->is_prefix () && **line && !c->allow_unknown) undef_cmd_error (c->prefixname ().c_str (), *line); /* Seems to be what he wants. Return it. */ @@ -2056,7 +2058,7 @@ lookup_cmd_composition_1 (const char *text, text += len; text = skip_spaces (text); - if ((*cmd)->subcommands != nullptr && *text != '\0') + if ((*cmd)->is_prefix () && *text != '\0') { cur_list = *(*cmd)->subcommands; *prefix_cmd = *cmd; @@ -2123,7 +2125,7 @@ complete_on_cmdlist (struct cmd_list_element *list, if (!strncmp (ptr->name, text, textlen) && !ptr->abbrev_flag && (!ignore_help_classes || ptr->func - || ptr->subcommands)) + || ptr->is_prefix ())) { if (pass == 0) { diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h index 8caf602..6204ed7 100644 --- a/gdb/cli/cli-decode.h +++ b/gdb/cli/cli-decode.h @@ -83,6 +83,10 @@ struct cmd_list_element bool is_alias () const { 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. */ struct cmd_list_element *next = nullptr; diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c index 5ddfab9..ff93523 100644 --- a/gdb/cli/cli-script.c +++ b/gdb/cli/cli-script.c @@ -1350,7 +1350,7 @@ validate_comname (const char **comname) const char *tem = prefix.c_str (); 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 ()); 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, tell the user its subcommands will be kept, and ask if ok to redefine the command. */ - if (c->subcommands != nullptr) + if (c->is_prefix ()) q = (c->user_commands.get () == nullptr || query (_("Keeping subcommands of prefix command \"%s\".\n" "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) 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. */ 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 (); fprintf_filtered (stream, "User %scommand \"", - c->subcommands == NULL ? "" : "prefix "); + c->is_prefix () ? "prefix" : ""); fprintf_styled (stream, title_style.style (), "%s%s", prefix, name); 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 (); 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); } diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c index 7e93a70..82008ca 100644 --- a/gdb/cli/cli-setshow.c +++ b/gdb/cli/cli-setshow.c @@ -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 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"); 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). */ std::string prefixname = list->prefix->prefixname (); - prefixname = (list->prefix->subcommands == nullptr ? "" + prefixname = (!list->prefix->is_prefix () ? "" : strstr (prefixname.c_str (), "show ") + 5); uiout->text (prefixname.c_str ()); } diff --git a/gdb/completer.c b/gdb/completer.c index 6d39435..6ad788b 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -1456,7 +1456,7 @@ complete_line_internal_1 (completion_tracker &tracker, { /* The command is followed by whitespace; we need to complete on whatever comes after command. */ - if (c->subcommands) + if (c->is_prefix ()) { /* It is a prefix command; what comes after it is a subcommand (e.g. "info "). */ @@ -1524,7 +1524,7 @@ complete_line_internal_1 (completion_tracker &tracker, { /* 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, e.g. "info adsfkdj". */ diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c index fc7dc2b..39c915e 100644 --- a/gdb/guile/scm-cmd.c +++ b/gdb/guile/scm-cmd.c @@ -524,7 +524,7 @@ gdbscm_parse_command_name (const char *name, gdbscm_scm_from_c_string (name), msg); } - if (elt->subcommands) + if (elt->is_prefix ()) { xfree (prefix_text); *base_list = elt->subcommands; diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index c2c0df5..4f01fc0 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -111,7 +111,7 @@ cmdpy_function (struct cmd_list_element *command, error (_("Invalid invocation of Python command object.")); 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. */ return; @@ -393,7 +393,7 @@ gdbpy_parse_command_name (const char *name, return NULL; } - if (elt->subcommands) + if (elt->is_prefix ()) { *base_list = elt->subcommands; return result; diff --git a/gdb/top.c b/gdb/top.c index a391e93..a1a932a 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -647,7 +647,7 @@ execute_command (const char *p, int from_tty) if (c->theclass == class_user && c->user_commands) execute_user_command (c, arg); 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 (in other words, C is a prefix command and not a command that can be followed by its args), report the list of diff --git a/gdb/unittests/command-def-selftests.c b/gdb/unittests/command-def-selftests.c index 4a6b678..e99eb9b 100644 --- a/gdb/unittests/command-def-selftests.c +++ b/gdb/unittests/command-def-selftests.c @@ -83,7 +83,7 @@ check_doc (struct cmd_list_element *commandlist, const char *prefix) /* Check if this command has subcommands and is not an abbreviation. We skip checking subcommands of abbreviations 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, 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, traverse the subcommands. */ - if (c->subcommands != NULL && !c->is_alias ()) + if (c->is_prefix () && !c->is_alias ()) { /* Recursively call ourselves on the subcommand list, passing the right prefix in. */ -- cgit v1.1