gdb: improve the warning given for deprecated aliases with a prefix
authorAndrew Burgess <andrew.burgess@embecosm.com>
Thu, 10 Dec 2020 16:03:31 +0000 (16:03 +0000)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Fri, 11 Dec 2020 22:10:50 +0000 (22:10 +0000)
Consider this GDB session:

  (gdb) define set xxx_yyy
  Type commands for definition of "set xxx_yyy".
  End with a line saying just "end".
  >echo in set xxx_yyy command\n
  >end
  (gdb) alias set qqq_aaa=set xxx_yyy
  (gdb) maintenance deprecate set qqq_aaa
  (gdb) set qqq_aaa
  Warning: 'qqq_aaa', an alias for the command 'xxx_yyy' is deprecated.
  No alternative known.

  in set xxx_yyy command
  (gdb)

Notice the warning mentions 'qqq_aaa' and 'xxx_yyy', I consider this
to be wrong.  I think the proper warning should read:

  (gdb) set qqq_aaa
  Warning: 'set qqq_aaa', an alias for the command 'set xxx_yyy', is deprecated.
  No alternative known.

With the 'set' prefixes added and a comma before the final 'is
deprecated'.  That is what this patch does.  The expected results are
updated as needed.

gdb/ChangeLog:

* cli/cli-decode.c (deprecated_cmd_warning): Ignore the prefix
result from lookup_cmd_composition_1, use the prefixes from both
the command and the alias instead.
(lookup_cmd_composition_1): Initial prefix command is the based on
the search list being passed in.  Simplify the logic for tracking
the prefix command.  Replace a use of alloca with a local
std::string.

gdb/testsuite/ChangeLog:

* gdb.base/commands.exp: Update expected results.

gdb/ChangeLog
gdb/cli/cli-decode.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/commands.exp

index 5a35eb20f45619578941ba08f896c5c30bc4e327..d2105e5cf02452db08fb184250f0f36c0037ad99 100644 (file)
@@ -1,3 +1,13 @@
+2020-12-11  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * cli/cli-decode.c (deprecated_cmd_warning): Ignore the prefix
+       result from lookup_cmd_composition_1, use the prefixes from both
+       the command and the alias instead.
+       (lookup_cmd_composition_1): Initial prefix command is the based on
+       the search list being passed in.  Simplify the logic for tracking
+       the prefix command.  Replace a use of alloca with a local
+       std::string.
+
 2020-12-11  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * cli/cli-decode.c (deprecated_cmd_warning): Use nullptr instead
index 2ad7717fbc63664f8ccdac6701a1c2ad521eb282..13260ac44e654825dcede458cb31ff27b458b565 100644 (file)
@@ -1901,12 +1901,21 @@ void
 deprecated_cmd_warning (const char *text, struct cmd_list_element *list)
 {
   struct cmd_list_element *alias = nullptr;
-  struct cmd_list_element *prefix_cmd = nullptr;
   struct cmd_list_element *cmd = nullptr;
 
-  /* Return if text doesn't evaluate to a command.  */
-  if (!lookup_cmd_composition_1 (text, &alias, &prefix_cmd, &cmd, list))
-    return;
+  /* Return if text doesn't evaluate to a command.  We place this lookup
+     within its own scope so that the PREFIX_CMD local is not visible
+     later in this function.  The value returned in PREFIX_CMD is based on
+     the prefix found in TEXT, and is our case this prefix can be missing
+     in some situations (when LIST is not the global CMDLIST).
+
+     It is better for our purposes to use the prefix commands directly from
+     the ALIAS and CMD results.  */
+  {
+    struct cmd_list_element *prefix_cmd = nullptr;
+    if (!lookup_cmd_composition_1 (text, &alias, &prefix_cmd, &cmd, list))
+      return;
+  }
 
   /* Return if nothing is deprecated.  */
   if (!((alias != nullptr ? alias->deprecated_warn_user : 0)
@@ -1915,21 +1924,27 @@ deprecated_cmd_warning (const char *text, struct cmd_list_element *list)
 
   /* Join command prefix (if any) and the command name.  */
   std::string tmp_cmd_str;
-  if (prefix_cmd != nullptr)
-    tmp_cmd_str += std::string (prefix_cmd->prefixname);
+  if (cmd->prefix != nullptr)
+    tmp_cmd_str += std::string (cmd->prefix->prefixname);
   tmp_cmd_str += std::string (cmd->name);
 
   /* Display the appropriate first line, this warns that the thing the user
      entered is deprecated.  */
   if (alias != nullptr)
     {
+      /* Join the alias prefix (if any) and the alias name.  */
+      std::string tmp_alias_str;
+      if (alias->prefix != nullptr)
+       tmp_alias_str += std::string (alias->prefix->prefixname);
+      tmp_alias_str += std::string (alias->name);
+
       if (cmd->cmd_deprecated)
        printf_filtered (_("Warning: command '%s' (%s) is deprecated.\n"),
-                        tmp_cmd_str.c_str (), alias->name);
+                        tmp_cmd_str.c_str (), tmp_alias_str.c_str ());
       else
-       printf_filtered (_("Warning: '%s', an alias for the command '%s' "
+       printf_filtered (_("Warning: '%s', an alias for the command '%s', "
                           "is deprecated.\n"),
-                        alias->name, tmp_cmd_str.c_str ());
+                        tmp_alias_str.c_str (), tmp_cmd_str.c_str ());
     }
   else
     printf_filtered (_("Warning: command '%s' is deprecated.\n"),
@@ -1976,25 +1991,18 @@ lookup_cmd_composition_1 (const char *text,
                          struct cmd_list_element **cmd,
                          struct cmd_list_element *cur_list)
 {
-  char *command;
-  int len, nfound;
-  struct cmd_list_element *prev_cmd;
-
-  *alias = NULL;
-  *prefix_cmd = NULL;
-  *cmd = NULL;
+  *alias = nullptr;
+  *prefix_cmd = cur_list->prefix;
+  *cmd = nullptr;
 
   text = skip_spaces (text);
 
+  /* Go through as many command lists as we need to, to find the command
+     TEXT refers to.  */
   while (1)
     {
-      /* Go through as many command lists as we need to,
-        to find the command TEXT refers to.  */
-
-      prev_cmd = *cmd;
-
       /* Identify the name of the command.  */
-      len = find_command_name_length (text);
+      int len = find_command_name_length (text);
 
       /* If nothing but whitespace, return.  */
       if (len == 0)
@@ -2002,40 +2010,34 @@ lookup_cmd_composition_1 (const char *text,
 
       /* TEXT is the start of the first command word to lookup (and
         it's length is LEN).  We copy this into a local temporary.  */
-
-      command = (char *) alloca (len + 1);
-      memcpy (command, text, len);
-      command[len] = '\0';
+      std::string command (text, len);
 
       /* Look it up.  */
-      *cmd = 0;
-      nfound = 0;
-      *cmd = find_cmd (command, len, cur_list, 1, &nfound);
-
-      if (*cmd == CMD_LIST_AMBIGUOUS)
-       {
-         return 0;              /* ambiguous */
-       }
+      int nfound = 0;
+      *cmd = find_cmd (command.c_str (), len, cur_list, 1, &nfound);
 
-      if (*cmd == NULL)
-       return 0;                /* nothing found */
+      /* We only handle the case where a single command was found.  */
+      if (*cmd == CMD_LIST_AMBIGUOUS || *cmd == nullptr)
+       return 0;
       else
        {
          if ((*cmd)->cmd_pointer)
            {
-             /* cmd was actually an alias, we note that an alias was
-                used (by assigning *ALIAS) and we set *CMD.  */
+             /* If the command was actually an alias, we note that an
+                alias was used (by assigning *ALIAS) and we set *CMD.  */
              *alias = *cmd;
              *cmd = (*cmd)->cmd_pointer;
            }
-         *prefix_cmd = prev_cmd;
        }
 
       text += len;
       text = skip_spaces (text);
 
-      if ((*cmd)->prefixlist && *text != '\0')
-       cur_list = *(*cmd)->prefixlist;
+      if ((*cmd)->prefixlist != nullptr && *text != '\0')
+       {
+         cur_list = *(*cmd)->prefixlist;
+         *prefix_cmd = *cmd;
+       }
       else
        return 1;
     }
index 0eb3ce680e5e8abd662862bb1ebe3a441db3416a..5796e61688bec5d6c44ce90b03a9e7769d9331f1 100644 (file)
@@ -1,3 +1,7 @@
+2020-12-11  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * gdb.base/commands.exp: Update expected results.
+
 2020-12-11  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        PR cli/15104
index 19f712c46f31741ad2a422e3e736e60dfdf433ae..f621815e4b69b4d50c346b2ca591539288001e23 100644 (file)
@@ -663,7 +663,7 @@ proc_with_prefix deprecated_command_test {} {
 
     gdb_test_no_output "maintenance deprecate p \"new_p\"" "maintenance deprecate p \"new_p\" /1/"
     gdb_test "p 5" \
-           "Warning: 'p', an alias for the command 'print' is deprecated.*Use 'new_p'.*" \
+           "Warning: 'p', an alias for the command 'print', is deprecated.*Use 'new_p'.*" \
            "p deprecated warning, with replacement"
     gdb_test "p 5" ".\[0-9\]* = 5.*" "deprecated warning goes away /1/"
 
@@ -704,7 +704,7 @@ maintenance deprecate set qqq_aaa"
     gdb_test_no_output "source $file1" \
        "source file containing xxx_yyy command and its alias"
     gdb_test "set qqq_aaa" \
-       "Warning: 'qqq_aaa', an alias for the command 'xxx_yyy' is deprecated\\.\r\n.*No alternative known\\..*" \
+       "Warning: 'set qqq_aaa', an alias for the command 'set xxx_yyy', is deprecated\\.\r\n.*No alternative known\\..*" \
        "deprecated alias with prefix give a warning"
 
     file delete $file1