[v2] Rename "maint demangle" as "demangle".

Message ID m3wq52nqfn.fsf@sspiff.org
State New, archived
Headers

Commit Message

Doug Evans Jan. 4, 2015, 10:15 p.m. UTC
  Doug Evans <xdje42@gmail.com> writes:
> Hi.
>
> This has been talked about before, and I'd like to make it happen.
>
> Plain users have legitimate reasons for wanting to demangle names,
> not just developers.  This patch renames "maint demangle" as "demangle".
>
> While testing the patch I noticed that "maint demangle" was getting
> interpreted as "maint demangler-warning" which artificially creates
> an internal gdb error.  For those whose muscle memory makes them type
> "maint demangle" I thought it was excessively unfriendly to let that
> happen, so I kept "maint demangle" as a no-op.  One could have it also
> invoke the demangler, but this is a maint command, and developers can
> switch over today, we don't need to ease them into the switch (beyond
> not letting "maint demangle" make one scratch one's head as to why
> that caused an internal error).
>
> Regression tested on amd64-linux.

Sorry for the followup, I found pr 15830 and added
the ability to specify a language.

I thought of using buildargv here, but for compatibility with
the previous version just in case name could have a space
(seems unlikely, just being cautious - I can change this to use
buildargv if y'all want).

2015-01-04  Doug Evans  <xdje42@gmail.com>

	PR gdb/15830
	* NEWS: The "maint demangle" command is renamed as "demangle".
	* demangle.c: #include cli/cli-utils.h, language.h.
	(demangle_command): New function.
	(_initialize_demangle): Add new command "demangle".
	* maint.c (maintenance_demangle): Stub out.
	(_initialize_maint_cmds): Update help text for "maint demangle".

	doc/
	* gdb.texinfo (Debugging C Plus Plus): Mention "demangle".
	(Symbols): Ditto.
	(Maintenance Commands): Delete docs for "maint demangle".

	testsuite/
	* gdb.base/maint.exp: Remove references to "maint demangle".
	* gdb.cp/demangle.exp: Update.  "maint demangle" -> "demangle".
	Add tests for explicitly specifying language to demangle in.
	* gdb.dlang/demangle.exp: Ditto.
  

Comments

Pedro Alves Jan. 5, 2015, 4:53 p.m. UTC | #1
On 01/04/2015 10:15 PM, Doug Evans wrote:

> Sorry for the followup, I found pr 15830 and added
> the ability to specify a language.

Excellent, thanks!

> +      else if (strncmp (arg_start, "--", p - arg_start) == 0)
> +	processing_args = 0;

I think this should be:

      else if (strncmp (arg_start, "--", p - arg_start) == 0)
               && isspace (arg_start[3]))
	processing_args = 0;

>  static void
> @@ -1012,8 +988,7 @@ _initialize_maint_cmds (void)
>    add_prefix_cmd ("maintenance", class_maintenance, maintenance_command, _("\
>  Commands for use by GDB maintainers.\n\
>  Includes commands to dump specific internal GDB structures in\n\
> -a human readable form, to cause GDB to deliberately dump core,\n\
> -to test internal functions such as the C++/ObjC demangler, etc."),
> +a human readable form, to cause GDB to deliberately dump core, etc."),
>  		  &maintenancelist, "maintenance ", 0,
>  		  &cmdlist);
>  
> @@ -1083,9 +1058,7 @@ Cause GDB to behave as if a demangler warning was reported."),
>  	   &maintenancelist);
>  
>    add_cmd ("demangle", class_maintenance, maintenance_demangle, _("\
> -Demangle a C++/ObjC mangled name.\n\
> -Call internal GDB demangler routine to demangle a C++ link name\n\
> -and prints the result."),
> +This command has been moved to \"demangle\"."),
>  	   &maintenancelist);

If you call deprecate_cmd on the old command then GDB
will hide it from e.g., tab command completion.

> +    # Verify specifying demangle language.
> +    gdb_test_no_output "set language unknown"
> +    set_demangling_style "auto"
> +    gdb_test_exact "demangle -l c++ -- _ZSt4cout" "std::cout"
> +    gdb_test_exact "demangle -l c -- _ZSt4cout" "Can't demangle \"_ZSt4cout\""
> +    gdb_test_exact "demangle -l garbage xyzdje" "Unknown language \"garbage\""

It might be good to also test explicitly specifying a
valid language and not using the double dash.  Like, e.g.,

    gdb_test_exact "demangle -l c++ _ZSt4cout" "std::cout"

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index 9a668c4..f476970 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -47,6 +47,12 @@ 
 
 * New commands
 
+demangle [-l language] [--] name
+  Demangle "name" in the specified language, or the current language
+  if elided.  This command is renamed from the "maint demangle" command.
+  The latter is kept as a no-op to avoid "maint demangle" being interpreted
+  as "maint demangler-warning".
+
 queue-signal signal-name-or-number
   Queue a signal to be delivered to the thread when it is resumed.
 
diff --git a/gdb/demangle.c b/gdb/demangle.c
index 7b5fa55..c0027be 100644
--- a/gdb/demangle.c
+++ b/gdb/demangle.c
@@ -24,10 +24,13 @@ 
    to a styles of demangling, and GDB specific.  */
 
 #include "defs.h"
+#include "cli/cli-utils.h" /* for skip_to_space */
 #include "command.h"
 #include "gdbcmd.h"
 #include "demangle.h"
 #include "gdb-demangle.h"
+#include "language.h"
+
 /* Select the default C++ demangling style to use.  The default is "auto",
    which allows gdb to attempt to pick an appropriate demangling style for
    the executable it has loaded.  It can be set to a specific style ("gnu",
@@ -40,6 +43,8 @@ 
 #define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
 #endif
 
+static void demangle_command (char *, int);
+
 /* See documentation in gdb-demangle.h.  */
 int demangle = 1;
 
@@ -151,6 +156,77 @@  is_cplus_marker (int c)
   return c && strchr (cplus_markers, c) != NULL;
 }
 
+/* Demangle the given string in the current language.  */
+
+static void
+demangle_command (char *args, int from_tty)
+{
+  char *demangled, *name, *lang_name = NULL;
+  char *arg_buf, *arg_start;
+  int processing_args = 1;
+  const struct language_defn *lang;
+  struct cleanup *cleanups;
+
+  arg_buf = xstrdup (args != NULL ? args : "");
+  cleanups = make_cleanup (xfree, arg_buf);
+  arg_start = arg_buf;
+
+  while (processing_args
+	 && *arg_start == '-')
+    {
+      char *p = skip_to_space (arg_start);
+
+      if (strncmp (arg_start, "-l", p - arg_start) == 0)
+	{
+	  char *lang_name_end;
+
+	  lang_name = skip_spaces (p);
+	  lang_name_end = skip_to_space (lang_name);
+	  lang_name = savestring (lang_name, lang_name_end - lang_name);
+	  make_cleanup (xfree, lang_name);
+	  p = lang_name_end;
+	}
+      else if (strncmp (arg_start, "--", p - arg_start) == 0)
+	processing_args = 0;
+      else
+	{
+	  *p = '\0';
+	  error (_("Unrecognized option '%s' to demangle command.  "
+		   "Try \"help demangle\"."), arg_start);
+	}
+
+      arg_start = skip_spaces (p);
+    }
+
+  name = arg_start;
+
+  if (*name == '\0')
+    error (_("Usage: demangle [-l language] [--] name"));
+
+  if (lang_name != NULL)
+    {
+      enum language lang_enum;
+
+      lang_enum = language_enum (lang_name);
+      if (lang_enum == language_unknown)
+	error (_("Unknown language \"%s\""), lang_name);
+      lang = language_def (lang_enum);
+    }
+  else
+    lang = current_language;
+
+  demangled = language_demangle (lang, name, DMGL_ANSI | DMGL_PARAMS);
+  if (demangled != NULL)
+    {
+      printf_filtered ("%s\n", demangled);
+      xfree (demangled);
+    }
+  else
+    error (_("Can't demangle \"%s\""), name);
+
+  do_cleanups (cleanups);
+}
+
 extern initialize_file_ftype _initialize_demangler; /* -Wmissing-prototypes */
 
 void
@@ -200,4 +276,10 @@  Use `set demangle-style' without arguments for a list of demangling styles."),
 			set_demangling_command,
 			show_demangling_style_names,
 			&setlist, &showlist);
+
+  add_cmd ("demangle", class_support, demangle_command, _("\
+Demangle a mangled name.\n\
+Usage: demangle [-l language] [--] name\n\
+If LANGUAGE is not specified, NAME is demangled in the current language."),
+	   &cmdlist);
 }
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index f4d7132..b059ac2 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -14215,6 +14215,11 @@  method tables of the object computed by @var{expression}.  This shows
 one entry per virtual table; there may be multiple virtual tables when
 multiple inheritance is in use.
 
+@cindex C@t{++} demangling
+@item demangle @var{name}
+Demangle @var{name}.
+@xref{Symbols}, for a more complete description of the @code{demangle} command.
+
 @cindex C@t{++} symbol display
 @item set print demangle
 @itemx show print demangle
@@ -16070,6 +16075,19 @@  _start + 5 in section .text of /tmp/a.out
 __read_nocancel + 6 in section .text of /usr/lib64/libc.so.6
 @end smallexample
 
+@kindex demangle
+@cindex demangle
+@item demangle @r{[}-l @var{language}@r{]} @r{[}@var{--}@r{]} @var{name}
+Demangle @var{name}.
+If @var{language} is provided it is the name of the language to demangle
+@var{name} in.  Otherwise @var{name} is demangled in the current language.
+
+The @samp{--} option specifies the end of options,
+and is useful when @var{name} begins with a dash.
+
+The parameter @code{demangle-style} specifies how to interpret the kind
+of mangling used. @xref{Print Settings}.
+
 @kindex whatis
 @item whatis[/@var{flags}] [@var{arg}]
 Print the data type of @var{arg}, which can be either an expression
@@ -33470,10 +33488,6 @@  Print the first C@t{++} class/namespace component of @var{name}.
 @item maint cplus namespace
 Print the list of possible C@t{++} namespaces.
 
-@kindex maint demangle
-@item maint demangle @var{name}
-Demangle a C@t{++} or Objective-C mangled @var{name}.
-
 @kindex maint deprecate
 @kindex maint undeprecate
 @cindex deprecated commands
diff --git a/gdb/maint.c b/gdb/maint.c
index b325856..4ad0dd1 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -139,38 +139,14 @@  maintenance_demangler_warning (char *args, int from_tty)
   demangler_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
 }
 
-/* Someday we should allow demangling for things other than just
-   explicit strings.  For example, we might want to be able to specify
-   the address of a string in either GDB's process space or the
-   debuggee's process space, and have gdb fetch and demangle that
-   string.  If we have a char* pointer "ptr" that points to a string,
-   we might want to be able to given just the name and have GDB
-   demangle and print what it points to, etc.  (FIXME)  */
+/* Old command to demangle a string.  The command has been moved to "demangle".
+   It is kept for now because otherwise "mt demangle" gets interpreted as
+   "mt demangler-warning" which artificially creates an internal gdb error.  */
 
 static void
 maintenance_demangle (char *args, int from_tty)
 {
-  char *demangled;
-
-  if (args == NULL || *args == '\0')
-    {
-      printf_unfiltered (_("\"maintenance demangle\" takes "
-			   "an argument to demangle.\n"));
-    }
-  else
-    {
-      demangled = language_demangle (current_language, args, 
-				     DMGL_ANSI | DMGL_PARAMS);
-      if (demangled != NULL)
-	{
-	  printf_unfiltered ("%s\n", demangled);
-	  xfree (demangled);
-	}
-      else
-	{
-	  printf_unfiltered (_("Can't demangle \"%s\"\n"), args);
-	}
-    }
+  printf_filtered (_("This command has been moved to \"demangle\".\n"));
 }
 
 static void
@@ -1012,8 +988,7 @@  _initialize_maint_cmds (void)
   add_prefix_cmd ("maintenance", class_maintenance, maintenance_command, _("\
 Commands for use by GDB maintainers.\n\
 Includes commands to dump specific internal GDB structures in\n\
-a human readable form, to cause GDB to deliberately dump core,\n\
-to test internal functions such as the C++/ObjC demangler, etc."),
+a human readable form, to cause GDB to deliberately dump core, etc."),
 		  &maintenancelist, "maintenance ", 0,
 		  &cmdlist);
 
@@ -1083,9 +1058,7 @@  Cause GDB to behave as if a demangler warning was reported."),
 	   &maintenancelist);
 
   add_cmd ("demangle", class_maintenance, maintenance_demangle, _("\
-Demangle a C++/ObjC mangled name.\n\
-Call internal GDB demangler routine to demangle a C++ link name\n\
-and prints the result."),
+This command has been moved to \"demangle\"."),
 	   &maintenancelist);
 
   add_prefix_cmd ("per-command", class_maintenance, set_per_command_cmd, _("\
diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp
index 1573710..e203207 100644
--- a/gdb/testsuite/gdb.base/maint.exp
+++ b/gdb/testsuite/gdb.base/maint.exp
@@ -25,7 +25,6 @@ 
 #maintenance expand-symtabs -- Expand symtabs matching a file regexp
 #maintenance set -- Set GDB internal variables used by the GDB maintainer
 #maintenance show -- Show GDB internal variables used by the GDB maintainer
-#maintenance demangle -- Demangle a C++ mangled name
 #maintenance dump-me -- Get fatal error; make debugger dump its core
 #maintenance print -- Maintenance command for printing GDB internal state
 #maintenance info -- Commands for showing internal info about the program being debugged
@@ -136,13 +135,6 @@  gdb_test "pwd" \
     "Command execution time: \[0-9.\]+ \\(cpu\\), \[0-9.\]+ \\(wall\\)\[\r\n\]+Space used: $decimal \\(\\+$decimal for this command\\)\[\r\n\]+#symtabs: $decimal \\(\\+$decimal\\), #compunits: $decimal \\(\\+$decimal\\), #blocks: $decimal \\(\\+$decimal\\)"
 gdb_test_no_output "maint set per-command off"
 
-gdb_test "maint demangle" \
-    "\"maintenance demangle\" takes an argument to demangle\\."
-
-gdb_test "maint demangle main" "Can't demangle \"main\""
-
-
-
 # The timeout value is raised, because printing all the symbols and
 # statistical information about Cygwin and Windows libraries takes a lot
 # of time.
@@ -484,7 +476,7 @@  set timeout $oldtimeout
 #============test help on maint commands
 
 gdb_test "help maint" \
-    "Commands for use by GDB maintainers\\..*Includes commands to dump specific internal GDB structures in.*a human readable form, to cause GDB to deliberately dump core,.*to test internal functions such as the C../ObjC demangler, etc\\..*List of maintenance subcommands:.*maintenance info.*maintenance internal-error.*maintenance print.*maintenance set.*maintenance show.*Type.*help maintenance.*followed by maintenance subcommand name for full documentation\\..*Command name abbreviations are allowed if unambiguous\\..*" 
+    "Commands for use by GDB maintainers\\..*Includes commands to dump specific internal GDB structures in.*a human readable form, to cause GDB to deliberately dump core, etc\\..*List of maintenance subcommands:.*maintenance info.*maintenance internal-error.*maintenance print.*maintenance set.*maintenance show.*Type.*help maintenance.*followed by maintenance subcommand name for full documentation\\..*Command name abbreviations are allowed if unambiguous\\..*" 
 
 gdb_test "help maint info" \
     "Commands for showing internal info about the program being debugged.*unambiguous\\..*"
@@ -496,8 +488,7 @@  test_prefix_command_help {"maint print" "maintenance print"} {
 test_prefix_command_help {"maint" "maintenance"} {
     "Commands for use by GDB maintainers\\.\[\r\n\]+"
     "Includes commands to dump specific internal GDB structures in\[\r\n\]+"
-    "a human readable form, to cause GDB to deliberately dump core,\[\r\n\]+"
-    "to test internal functions such as the C\\+\\+/ObjC demangler, etc\\.\[\r\n\]+"
+    "a human readable form, to cause GDB to deliberately dump core, etc\\.\[\r\n\]+"
 }
 
 #set oldtimeout $timeout
diff --git a/gdb/testsuite/gdb.cp/demangle.exp b/gdb/testsuite/gdb.cp/demangle.exp
index 0ac855b..d5ba04f 100644
--- a/gdb/testsuite/gdb.cp/demangle.exp
+++ b/gdb/testsuite/gdb.cp/demangle.exp
@@ -73,7 +73,7 @@  proc test_demangling_core {tester test result} {
 	set_demangling_style $style
     }
 
-    $tester "maintenance demangle $name" $result $test
+    $tester "demangle $name" $result $test
 }
 
 ### Demangle an identifier, and check that the result matches a pattern.
@@ -527,7 +527,7 @@  proc test_gnu_style_demangling {} {
     ## 1999-04-19: "Fix from Dale Hawkins".  Shouldn't segfault.
     # Accept even a dubious demangling; the string is ambiguous.
 
-    gdb_test_multiple "maintenance demangle __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator" "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator" {
+    gdb_test_multiple "demangle __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator" "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator" {
 	-re "virtual function thunk \\(delta:-64\\) for CosNaming::_proxy_NamingContext::_0RL__list\\(unsigned long, _CORBA_Unbounded_Sequence<CosNaming::Binding> \\*\\&, CosNaming::BindingIterator \\*\\&\\)\r\n$gdb_prompt $" {
 	    pass "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator"
 	}
@@ -1557,6 +1557,13 @@  proc do_tests {} {
     catch_demangling_errors test_gnu_style_demangling
     catch_demangling_errors test_arm_style_demangling
     catch_demangling_errors test_hp_style_demangling
+
+    # Verify specifying demangle language.
+    gdb_test_no_output "set language unknown"
+    set_demangling_style "auto"
+    gdb_test_exact "demangle -l c++ -- _ZSt4cout" "std::cout"
+    gdb_test_exact "demangle -l c -- _ZSt4cout" "Can't demangle \"_ZSt4cout\""
+    gdb_test_exact "demangle -l garbage xyzdje" "Unknown language \"garbage\""
 }
 
 do_tests
diff --git a/gdb/testsuite/gdb.dlang/demangle.exp b/gdb/testsuite/gdb.dlang/demangle.exp
index 5a9d9a4..9eb6054 100644
--- a/gdb/testsuite/gdb.dlang/demangle.exp
+++ b/gdb/testsuite/gdb.dlang/demangle.exp
@@ -23,7 +23,7 @@  if { [skip_d_tests] } { continue }
 
 ### Utility function for test_demangling and test_demangling_exact.
 proc test_demangling {test result} {
-    gdb_test_exact "maintenance demangle $test" $result $test
+    gdb_test_exact "demangle $test" $result $test
 }
 
 proc test_d_demangling {} {
@@ -201,6 +201,9 @@  if [set_lang_d] {
     gdb_test_no_output "set width 0"
 
     test_d_demangling
+
+    # Verify we can specify the d language to demangle.
+    gdb_test_exact "demangle -l d -- _Dmain" "D main"
 } else {
     warning "D demangling tests suppressed."
 }