Allow . character as part of command names.
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sun, 8 Sep 2019 19:54:18 +0000 (21:54 +0200)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 30 Nov 2019 08:37:49 +0000 (09:37 +0100)
This patch adds . as an allowed character for user defined commands.
Combined with 'define-prefix', this allows to e.g. define a set of Valgrind
specific user command corresponding to the Valgrind monitor commands
(such as check_memory, v.info, v.set, ...).

gdb/ChangeLog
2019-11-30  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

* command.h (valid_cmd_char_p): Declare.
* cli/cli-decode.c (valid_cmd_char_p): New function factorizing
the check of valid command char.
(find_command_name_length, valid_user_defined_cmd_name_p): Use
valid_cmd_char_p.
* cli/cli-script.c (validate_comname): Likewise.
* completer.c (gdb_completer_command_word_break_characters):
Do not remove . from the word break char, update comments.
(complete_line_internal_1): Use valid_cmd_char_p.
* guile/scm-cmd.c (gdbscm_parse_command_name): Likewise.
* python/py-cmd.c (gdbpy_parse_command_name): Likewise.

gdb/testsuite/ChangeLog
2019-11-30  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

* gdb.base/define.exp: Test . in command names.
* gdb.base/setshow.exp: Update test, as . is now part of
command name.

gdb/ChangeLog
gdb/cli/cli-decode.c
gdb/cli/cli-script.c
gdb/command.h
gdb/completer.c
gdb/guile/scm-cmd.c
gdb/python/py-cmd.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/define.exp
gdb/testsuite/gdb.base/setshow.exp

index d123622a42460939fc43e507a90c42767b224abd..50de35d07a97857a9d83d90646515eab541643c7 100644 (file)
@@ -1,3 +1,17 @@
+2019-11-30  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
+
+       * command.h (valid_cmd_char_p): Declare.
+       * cli/cli-decode.c (valid_cmd_char_p): New function factorizing
+       the check of valid command char.
+       (find_command_name_length, valid_user_defined_cmd_name_p): Use
+       valid_cmd_char_p.
+       * cli/cli-script.c (validate_comname): Likewise.
+       * completer.c (gdb_completer_command_word_break_characters):
+       Do not remove . from the word break char, update comments.
+       (complete_line_internal_1): Use valid_cmd_char_p.
+       * guile/scm-cmd.c (gdbscm_parse_command_name): Likewise.
+       * python/py-cmd.c (gdbpy_parse_command_name): Likewise.
+
 2019-11-30  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
 
        * cli/cli-script.c (do_define_command): Ensure a redefined
index 7ace72fb7e7abb2a01a824f90493a089705a0db6..307fd1e8263ccdfe63e9edcde62e9855c307d289 100644 (file)
@@ -1372,7 +1372,7 @@ find_command_name_length (const char *text)
   if (*p == '!' || *p == '|')
     return 1;
 
-  while (isalnum (*p) || *p == '-' || *p == '_'
+  while (valid_cmd_char_p (*p)
         /* Characters used by TUI specific commands.  */
         || *p == '+' || *p == '<' || *p == '>' || *p == '$')
     p++;
@@ -1380,9 +1380,18 @@ find_command_name_length (const char *text)
   return p - text;
 }
 
-/* Return TRUE if NAME is a valid user-defined command name.
-   This is a stricter subset of all gdb commands,
-   see find_command_name_length.  */
+/* See command.h.  */
+
+bool
+valid_cmd_char_p (int c)
+{
+  /* Alas "42" is a legitimate user-defined command.
+     In the interests of not breaking anything we preserve that.  */
+
+  return isalnum (c) || c == '-' || c == '_' || c == '.';
+}
+
+/* See command.h.  */
 
 bool
 valid_user_defined_cmd_name_p (const char *name)
@@ -1392,14 +1401,9 @@ valid_user_defined_cmd_name_p (const char *name)
   if (*name == '\0')
     return false;
 
-  /* Alas "42" is a legitimate user-defined command.
-     In the interests of not breaking anything we preserve that.  */
-
   for (p = name; *p != '\0'; ++p)
     {
-      if (isalnum (*p)
-         || *p == '-'
-         || *p == '_')
+      if (valid_cmd_char_p (*p))
        ; /* Ok.  */
       else
        return false;
index 55dcb3435b02360de939fc34981f2c1580582c80..10824a3daffd321d32c4319b4deacaaf10ce7a88 100644 (file)
@@ -1342,7 +1342,7 @@ validate_comname (const char **comname)
   p = *comname;
   while (*p)
     {
-      if (!isalnum (*p) && *p != '-' && *p != '_')
+      if (!valid_cmd_char_p (*p))
        error (_("Junk in argument list: \"%s\""), p);
       p++;
     }
index cf190ef649d26bfe726969ce8493902036f18d2c..5384a0a6747a2063a46cc390a73eb2750728756b 100644 (file)
@@ -133,8 +133,16 @@ extern struct cli_suppress_notification cli_suppress_notification;
 
 /* API to the manipulation of command lists.  */
 
+/* Return TRUE if NAME is a valid user-defined command name.
+   This is a stricter subset of all gdb commands,
+   see find_command_name_length.  */
+
 extern bool valid_user_defined_cmd_name_p (const char *name);
 
+/* Return TRUE if C is a valid command character.  */
+
+extern bool valid_cmd_char_p (int c);
+
 /* Const-correct variant of the above.  */
 
 extern struct cmd_list_element *add_cmd (const char *, enum command_class,
index b34b7762c629d76591934782610e379a0c400fd5..6658da6d7fb7d7e36c4b3d377658692935efa4b3 100644 (file)
@@ -102,13 +102,13 @@ enum explicit_location_match_type
 
 /* Variables which are necessary for fancy command line editing.  */
 
-/* When completing on command names, we remove '-' from the list of
+/* When completing on command names, we remove '-' and '.' from the list of
    word break characters, since we use it in command names.  If the
    readline library sees one in any of the current completion strings,
    it thinks that the string needs to be quoted and automatically
    supplies a leading quote.  */
 static const char gdb_completer_command_word_break_characters[] =
-" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,";
+" \t\n!@#$%^&*()+=|~`}{[]\"';:?/><,";
 
 /* When completing on file names, we remove from the list of word
    break characters any characters that are commonly used in file
@@ -1284,7 +1284,7 @@ complete_line_internal_1 (completion_tracker &tracker,
      on command strings (as opposed to strings supplied by the
      individual command completer functions, which can be any string)
      then we will switch to the special word break set for command
-     strings, which leaves out the '-' character used in some
+     strings, which leaves out the '-' and '.' character used in some
      commands.  */
   set_rl_completer_word_break_characters
     (current_language->la_word_break_characters());
@@ -1347,7 +1347,7 @@ complete_line_internal_1 (completion_tracker &tracker,
       /* lookup_cmd_1 advances p up to the first ambiguous thing, but
         doesn't advance over that thing itself.  Do so now.  */
       q = p;
-      while (*q && (isalnum (*q) || *q == '-' || *q == '_'))
+      while (valid_cmd_char_p (*q))
        ++q;
       if (q != tmp_command + point)
        {
@@ -1435,7 +1435,7 @@ complete_line_internal_1 (completion_tracker &tracker,
              q = p;
              while (q > tmp_command)
                {
-                 if (isalnum (q[-1]) || q[-1] == '-' || q[-1] == '_')
+                 if (valid_cmd_char_p (q[-1]))
                    --q;
                  else
                    break;
index f2fa40e453b8bb132c8a07d8e54a22fdb201bd60..3b8195b8b4191ffe344227108d039009f3e40674 100644 (file)
@@ -492,10 +492,7 @@ gdbscm_parse_command_name (const char *name,
   lastchar = i;
 
   /* Find first character of the final word.  */
-  for (; i > 0 && (isalnum (name[i - 1])
-                  || name[i - 1] == '-'
-                  || name[i - 1] == '_');
-       --i)
+  for (; i > 0 && valid_cmd_char_p (name[i - 1]); --i)
     ;
   result = (char *) xmalloc (lastchar - i + 2);
   memcpy (result, &name[i], lastchar - i + 1);
index 38973401a8fc0de1ceb7275e9e02f02fed098129..8d6f01b78fc259009815d0406dcd93e7afe9c40f 100644 (file)
@@ -372,10 +372,7 @@ gdbpy_parse_command_name (const char *name,
   lastchar = i;
 
   /* Find first character of the final word.  */
-  for (; i > 0 && (isalnum (name[i - 1])
-                  || name[i - 1] == '-'
-                  || name[i - 1] == '_');
-       --i)
+  for (; i > 0 && valid_cmd_char_p (name[i - 1]); --i)
     ;
   result = (char *) xmalloc (lastchar - i + 2);
   memcpy (result, &name[i], lastchar - i + 1);
index a88c54538930a4dede695b7a8cc6384612609ff4..1f52d01df7efa2bcc74aa4b621800edc2974c60d 100644 (file)
@@ -1,3 +1,9 @@
+2019-11-30  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
+
+       * gdb.base/define.exp: Test . in command names.
+       * gdb.base/setshow.exp: Update test, as . is now part of
+       command name.
+
 2019-11-30  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
 
        * gdb.base/define-prefix.exp: New file.
index d7d4fd03ba528d1f93e05a677387c927280148cc..b5183eceecc3a800b7f52292170043acf8b0f026 100644 (file)
@@ -130,6 +130,31 @@ gdb_test "help nextwhere" \
     "   A next command that first shows you where you're stepping from.*" \
     "preserve whitespace in help string"
 
+# Verify that GDB allows a user to use . in a command name.
+#
+gdb_test_multiple "define dot.command" "define user command: dot.command" {
+    -re "Type commands for definition of \"dot.command\".\r\nEnd with a line saying just \"end\".\r\n>$" {
+       gdb_test "echo dot command\\n\nend" "" \
+           "define user command: dot.command"
+    }
+}
+
+# Verify that dot.command works.
+#
+gdb_test "dot.command" \
+    "dot command" \
+    "full name dot.command"
+gdb_test "dot" \
+    "dot command" \
+    "partial name dot"
+gdb_test "dot." \
+    "dot command" \
+    "partial name dot."
+gdb_test "dot.c" \
+    "dot command" \
+    "partial name dot.c"
+
+
 # Verify that the command parser doesn't require a space after an 'if'
 # command in a user defined function.
 #
index 717bcc327066e597b3d5469c3ff0689f305a3ec8..394967babf35491ca3adb16b50337f61f0bd45d4 100644 (file)
@@ -355,7 +355,7 @@ gdb_test_no_output "set verbose off" "set verbose off"
 gdb_test "show verbose" "Verbosity is off..*" "show verbose (off)" 
 #test argument must be preceded by space
 foreach x {"history file" "solib-search-path" "data-directory"} {
-    foreach y {"/home/" "." "~/home" "=home"} {
+    foreach y {"/home/" "~/home" "=home"} {
         gdb_test "set $x$y" "Argument must be preceded by space." \
             "$x is not set to $y"
     }