[RFA,03/10] Fix problem that alias can be defined or not depending on the order.

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

Commit Message

H.J. Lu via Gdb-patches May 10, 2020, 8:55 p.m.
When an alias name starts with the name of another alias,
GDB was accepting to define the aliases in one order (short first, long after),
but refused it the other way around.

So, fix the logic to recognise an already existing alias by using
lookup_cmd_composition.

Also, this revealed a bug in lookup_cmd_composition:
when the searched command is a prefix command, lookup_cmd_composition
was not returning the fact that a command was found even if the
TEXT to parse was fully consumed.

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

	* cli/cli-cmds.c (alias_command): Check for an existing alias
	using lookup_cmd_composition, as valid_command_p is too strict
	and forbids aliases that are the prefix of an existing alias
	or command.
	* cli/cli-decode.c (lookup_cmd_composition): Ensure a prefix
	command is properly recognised as a valid command.

gdb/testsuite/ChangeLog
YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* gdb.base/alias.exp: Test aliases starting with a prefix of
	another alias.
---
 gdb/cli/cli-cmds.c               | 25 +++++++++++++++++++++++--
 gdb/cli/cli-decode.c             | 15 ++++++++-------
 gdb/testsuite/gdb.base/alias.exp |  6 ++++++
 3 files changed, 37 insertions(+), 9 deletions(-)

-- 
2.20.1

Comments

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


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

Philippe> 	* cli/cli-cmds.c (alias_command): Check for an existing alias
Philippe> 	using lookup_cmd_composition, as valid_command_p is too strict
Philippe> 	and forbids aliases that are the prefix of an existing alias
Philippe> 	or command.
Philippe> 	* cli/cli-decode.c (lookup_cmd_composition): Ensure a prefix
Philippe> 	command is properly recognised as a valid command.

Philippe> gdb/testsuite/ChangeLog
Philippe> YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

Philippe> 	* gdb.base/alias.exp: Test aliases starting with a prefix of
Philippe> 	another alias.

Thank you for the patch.  This looks good to me.

Tom

Patch

diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index d34395f0a4..ee07c300c9 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1683,8 +1683,29 @@  alias_command (const char *args, int from_tty)
   /* ALIAS must not exist.  */
   std::string alias_string (argv_to_string (alias_argv, alias_argc));
   alias = alias_string.c_str ();
-  if (valid_command_p (alias))
-    error (_("Alias already exists: %s"), alias);
+  {
+    cmd_list_element *alias_cmd, *prefix_cmd, *cmd;
+
+    if (lookup_cmd_composition (alias, &alias_cmd, &prefix_cmd, &cmd))
+      {
+	const char *alias_name = alias_argv[alias_argc-1];
+
+	/* If we found an existing ALIAS_CMD, check that the prefix differ or
+	   the name differ.  */
+
+	if (alias_cmd != nullptr
+	    && alias_cmd->prefix == prefix_cmd
+	    && strcmp (alias_name, alias_cmd->name) == 0)
+	  error (_("Alias already exists: %s"), alias);
+
+	/* Check ALIAS differs from the found CMD.  */
+
+	if (cmd->prefix == prefix_cmd
+	    && strcmp (alias_name, cmd->name) == 0)
+	  error (_("Alias %s is the name of an existing command"), alias);
+      }
+  }
+
 
   /* If ALIAS is one word, it is an alias for the entire COMMAND.
      Example: alias spe = set print elements
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index d951ead1c9..78b8901084 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -1843,6 +1843,8 @@  lookup_cmd_composition (const char *text,
 
   cur_list = cmdlist;
 
+  text = skip_spaces (text);
+
   while (1)
     {
       /* Go through as many command lists as we need to,
@@ -1850,9 +1852,6 @@  lookup_cmd_composition (const char *text,
 
       prev_cmd = *cmd;
 
-      while (*text == ' ' || *text == '\t')
-	(text)++;
-
       /* Identify the name of the command.  */
       len = find_command_name_length (text);
 
@@ -1861,7 +1860,7 @@  lookup_cmd_composition (const char *text,
 	return 0;
 
       /* TEXT is the start of the first command word to lookup (and
-	 it's length is len).  We copy this into a local temporary.  */
+	 it's length is LEN).  We copy this into a local temporary.  */
 
       command = (char *) alloca (len + 1);
       memcpy (command, text, len);
@@ -1890,12 +1889,14 @@  lookup_cmd_composition (const char *text,
 	    }
 	  *prefix_cmd = prev_cmd;
 	}
-      if ((*cmd)->prefixlist)
+
+      text += len;
+      text = skip_spaces (text);
+
+      if ((*cmd)->prefixlist && *text != '\0')
 	cur_list = *(*cmd)->prefixlist;
       else
 	return 1;
-
-      text += len;
     }
 }
 
diff --git a/gdb/testsuite/gdb.base/alias.exp b/gdb/testsuite/gdb.base/alias.exp
index be78d9e936..9a9557668e 100644
--- a/gdb/testsuite/gdb.base/alias.exp
+++ b/gdb/testsuite/gdb.base/alias.exp
@@ -116,3 +116,9 @@  gdb_test "show print elements" "Limit .* is 56\[.\]" "verify 56"
 
 gdb_test_no_output "set print max-elements 57"
 gdb_test "show print elements" "Limit .* is 57\[.\]" "verify 57"
+
+# Test aliases having a common prefix.
+gdb_test_no_output "alias abcd  = backtrace"
+gdb_test_no_output "alias abcde = backtrace"
+gdb_test_no_output "alias fghij = backtrace"
+gdb_test_no_output "alias fghi  = backtrace"