[RFA,04/10] command-def-selftests.c: detect missing or wrong prefix cmd in subcommands.

Message ID 20200510205530.21923-5-philippe.waroquiers@skynet.be
State Superseded
Headers show
Series
  • fix/improve cmd structure, class_alias, help, apropos
Related show

Commit Message

Hannes Domani via Gdb-patches May 10, 2020, 8:55 p.m.
This test reveals a number of problems fixed in the next commit.

YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* unittests/command-def-selftests.c (traverse_command_structure):
	Verify all commands of a list have the same prefix command and
	that only the top cmdlist commands have a null prefix.
---
 gdb/unittests/command-def-selftests.c | 35 +++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

-- 
2.20.1

Comments

Tom Tromey May 14, 2020, 3:54 p.m. | #1
>>>>> "Philippe" == Philippe Waroquiers via Gdb-patches <gdb-patches@sourceware.org> writes:


Thank you for the patch.

Philippe> This test reveals a number of problems fixed in the next commit.

It's best (IME) to develop in this order, but then to either combine the
test and the fix, or to put the fix before the test when submitting.
The reason for this is that it helps avoid failures when bisecting.

Philippe> +  SELF_CHECK (nr_invalid_prefixcmd == 0);

This code should reset nr_invalid_prefixcmd as well.

Tom

Patch

diff --git a/gdb/unittests/command-def-selftests.c b/gdb/unittests/command-def-selftests.c
index 55e1278fc3..d8489d8bcd 100644
--- a/gdb/unittests/command-def-selftests.c
+++ b/gdb/unittests/command-def-selftests.c
@@ -106,20 +106,26 @@  help_doc_invariants_tests ()
 
 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-full 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 ())
@@ -137,6 +143,13 @@  traverse_command_structure (struct cmd_list_element **list,
 
   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)
     {
@@ -148,6 +161,23 @@  traverse_command_structure (struct cmd_list_element **list,
 	     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++;
+	}
     }
 }
 
@@ -163,6 +193,7 @@  command_structure_invariants_tests ()
   lists.clear ();
 
   SELF_CHECK (nr_duplicates == 0);
+  SELF_CHECK (nr_invalid_prefixcmd == 0);
 }
 
 }