namespace command_structure_tests {
+/* Nr of commands in which a duplicated list is found. */
unsigned int nr_duplicates = 0;
+/* Nr of commands in a list having no valid prefix cmd. */
+unsigned int nr_invalid_prefixcmd = 0;
/* A map associating a list with the prefix leading to it. */
std::map<cmd_list_element **, const char *> lists;
/* Store each command list in lists, associated with the prefix to reach it. A
- list must only be found once. */
+ list must only be found once.
+
+ Verifies that all elements of the list have the same non-null prefix
+ command. */
static void
traverse_command_structure (struct cmd_list_element **list,
const char *prefix)
{
- struct cmd_list_element *c;
+ struct cmd_list_element *c, *prefixcmd;
auto dupl = lists.find (list);
if (dupl != lists.end ())
lists.insert ({list, prefix});
+ /* All commands of *list must have a prefix command equal to PREFIXCMD,
+ the prefix command of the first command. */
+ if (*list == nullptr)
+ prefixcmd = nullptr; /* A prefix command with an empty subcommand list. */
+ else
+ prefixcmd = (*list)->prefix;
+
/* Walk through the commands. */
for (c = *list; c; c = c->next)
{
passing the right prefix in. */
traverse_command_structure (c->prefixlist, c->prefixname);
}
+ if (prefixcmd != c->prefix
+ || (prefixcmd == nullptr && *list != cmdlist))
+ {
+ if (c->prefix == nullptr)
+ fprintf_filtered (gdb_stdout,
+ "list %p reachable via prefix '%s'."
+ " command '%s' has null prefixcmd\n",
+ list,
+ prefix, c->name);
+ else
+ fprintf_filtered (gdb_stdout,
+ "list %p reachable via prefix '%s'."
+ " command '%s' has a different prefixcmd\n",
+ list,
+ prefix, c->name);
+ nr_invalid_prefixcmd++;
+ }
}
}
command_structure_invariants_tests ()
{
nr_duplicates = 0;
+ nr_invalid_prefixcmd = 0;
+
traverse_command_structure (&cmdlist, "");
/* Release memory, be ready to be re-run. */
lists.clear ();
SELF_CHECK (nr_duplicates == 0);
+ SELF_CHECK (nr_invalid_prefixcmd == 0);
}
}