* spu-tdep.c: Update for unwinder changes.
[deliverable/binutils-gdb.git] / gdb / demangle.c
index 9c5e521d928a4c8d0f04ca5a30cc629bea89de8b..1a65af06396eb24c9b76bac626bf627dfd57fb2d 100644 (file)
@@ -1,26 +1,28 @@
 /* Basic C++ demangling support for GDB.
-   Copyright 1991, 1992, 1996 Free Software Foundation, Inc.
+
+   Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+   2003, 2007, 2008 Free Software Foundation, Inc.
+
    Written by Fred Fish at Cygnus Support.
 
-This file is part of GDB.
+   This file is part of GDB.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 /*  This file contains support code for C++ demangling that is common
-    to a styles of demangling, and GDB specific. */
+   to a styles of demangling, and GDB specific. */
 
 #include "defs.h"
 #include "command.h"
@@ -37,57 +39,41 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    the appropriate target configuration file. */
 
 #ifndef DEFAULT_DEMANGLING_STYLE
-# define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
+#define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
 #endif
 
-/* String name for the current demangling style.  Set by the "set demangling"
-   command, printed as part of the output by the "show demangling" command. */
+extern void _initialize_demangler (void);
+
+/* String name for the current demangling style.  Set by the
+   "set demangle-style" command, printed as part of the output by the
+   "show demangle-style" command. */
 
 static char *current_demangling_style_string;
 
-/* List of supported demangling styles.  Contains the name of the style as
-   seen by the user, and the enum value that corresponds to that style. */
-   
-static const struct demangler
-{
-  char *demangling_style_name;
-  enum demangling_styles demangling_style;
-  char *demangling_style_doc;
-} demanglers [] =
-{
-  {AUTO_DEMANGLING_STYLE_STRING,
-     auto_demangling,
-     "Automatic selection based on executable"},
-  {GNU_DEMANGLING_STYLE_STRING,
-     gnu_demangling,
-     "GNU (g++) style demangling"},
-  {LUCID_DEMANGLING_STYLE_STRING,
-     lucid_demangling,
-     "Lucid (lcc) style demangling"},
-  {ARM_DEMANGLING_STYLE_STRING,
-     arm_demangling,
-     "ARM style demangling"},
-  {HP_DEMANGLING_STYLE_STRING,
-     hp_demangling,
-     "HP (aCC) style demangling"},
-  {EDG_DEMANGLING_STYLE_STRING,
-     edg_demangling,
-     "EDG style demangling"},
-  {NULL, unknown_demangling, NULL}
-};
+/* The array of names of the known demanglyng styles.  Generated by
+   _initialize_demangler from libiberty_demanglers[] array.  */
 
+static const char **demangling_style_names;
 static void
-set_demangling_command PARAMS ((char *, int, struct cmd_list_element *));
+show_demangling_style_names(struct ui_file *file, int from_tty,
+                           struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("The current C++ demangling style is \"%s\".\n"),
+                   value);
+}
+
+
+static void set_demangling_command (char *, int, struct cmd_list_element *);
 
-/* set current demangling style.  called by the "set demangling" command
-   after it has updated the current_demangling_style_string to match
-   what the user has entered.
+/* Set current demangling style.  Called by the "set demangle-style"
+   command after it has updated the current_demangling_style_string to
+   match what the user has entered.
 
-   if the user has entered a string that matches a known demangling style
+   If the user has entered a string that matches a known demangling style
    name in the demanglers[] array then just leave the string alone and update
    the current_demangling_style enum value to match.
 
-   if the user has entered a string that doesn't match, including an empty
+   If the user has entered a string that doesn't match, including an empty
    string, then print a list of the currently known styles and restore
    the current_demangling_style_string to match the current_demangling_style
    enum value.
@@ -96,24 +82,23 @@ set_demangling_command PARAMS ((char *, int, struct cmd_list_element *));
    a malloc'd string, even if it is a null-string. */
 
 static void
-set_demangling_command (ignore, from_tty, c)
-     char *ignore;
-     int from_tty;
-     struct cmd_list_element *c;
+set_demangling_command (char *ignore, int from_tty, struct cmd_list_element *c)
 {
-  const struct demangler *dem;
+  const struct demangler_engine *dem;
 
   /*  First just try to match whatever style name the user supplied with
-      one of the known ones.  Don't bother special casing for an empty
-      name, we just treat it as any other style name that doesn't match.
-      If we match, update the current demangling style enum. */
+     one of the known ones.  Don't bother special casing for an empty
+     name, we just treat it as any other style name that doesn't match.
+     If we match, update the current demangling style enum. */
 
-  for (dem = demanglers; dem -> demangling_style_name != NULL; dem++)
+  for (dem = libiberty_demanglers; 
+       dem->demangling_style != unknown_demangling; 
+       dem++)
     {
-      if (STREQ (current_demangling_style_string,
-                 dem -> demangling_style_name))
+      if (strcmp (current_demangling_style_string,
+                 dem->demangling_style_name) == 0)
        {
-         current_demangling_style = dem -> demangling_style;
+         current_demangling_style = dem->demangling_style;
          break;
        }
     }
@@ -122,24 +107,26 @@ set_demangling_command (ignore, from_tty, c)
      style name and supply a list of valid ones.  FIXME:  This should
      probably be done with some sort of completion and with help. */
 
-  if (dem -> demangling_style_name == NULL)
+  if (dem->demangling_style == unknown_demangling)
     {
       if (*current_demangling_style_string != '\0')
        {
-         printf_unfiltered ("Unknown demangling style `%s'.\n",
-                 current_demangling_style_string);
+         printf_unfiltered (_("Unknown demangling style `%s'.\n"),
+                            current_demangling_style_string);
        }
-      printf_unfiltered ("The currently understood settings are:\n\n");
-      for (dem = demanglers; dem -> demangling_style_name != NULL; dem++)
+      printf_unfiltered (_("The currently understood settings are:\n\n"));
+      for (dem = libiberty_demanglers; 
+          dem->demangling_style != unknown_demangling; 
+          dem++)
        {
-         printf_unfiltered ("%-10s %s\n", dem -> demangling_style_name,
-                 dem -> demangling_style_doc);
-         if (dem -> demangling_style == current_demangling_style)
+         printf_unfiltered ("%-10s %s\n", dem->demangling_style_name,
+                            dem->demangling_style_doc);
+         if (dem->demangling_style == current_demangling_style)
            {
-             free (current_demangling_style_string);
+             xfree (current_demangling_style_string);
              current_demangling_style_string =
-               savestring (dem -> demangling_style_name,
-                           strlen (dem -> demangling_style_name));
+               savestring (dem->demangling_style_name,
+                           strlen (dem->demangling_style_name));
            }
        }
       if (current_demangling_style == unknown_demangling)
@@ -147,69 +134,81 @@ set_demangling_command (ignore, from_tty, c)
          /* This can happen during initialization if gdb is compiled with
             a DEMANGLING_STYLE value that is unknown, so pick the first
             one as the default. */
-         current_demangling_style = demanglers[0].demangling_style;
+         current_demangling_style = libiberty_demanglers[0].demangling_style;
          current_demangling_style_string =
-           savestring (demanglers[0].demangling_style_name,
-                       strlen (demanglers[0].demangling_style_name));
-         warning ("`%s' style demangling chosen as the default.\n",
+           savestring (
+              libiberty_demanglers[0].demangling_style_name,
+             strlen (libiberty_demanglers[0].demangling_style_name));
+         warning (_("`%s' style demangling chosen as the default."),
                   current_demangling_style_string);
        }
     }
 }
 
-/* Fake a "set demangling" command. */
+/* Fake a "set demangle-style" command. */
 
 void
-set_demangling_style (style)
-     char *style;
+set_demangling_style (char *style)
 {
   if (current_demangling_style_string != NULL)
     {
-      free (current_demangling_style_string);
+      xfree (current_demangling_style_string);
     }
   current_demangling_style_string = savestring (style, strlen (style));
   set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL);
 }
 
-/* In order to allow a single demangler executable to demangle strings
-   using various common values of CPLUS_MARKER, as well as any specific
-   one set at compile time, we maintain a string containing all the
-   commonly used ones, and check to see if the marker we are looking for
-   is in that string.  CPLUS_MARKER is usually '$' on systems where the
-   assembler can deal with that.  Where the assembler can't, it's usually
-   '.' (but on many systems '.' is used for other things).  We put the
-   current defined CPLUS_MARKER first (which defaults to '$'), followed
-   by the next most common value, followed by an explicit '$' in case
-   the value of CPLUS_MARKER is not '$'.
+/* G++ uses a special character to indicate certain internal names.  Which
+   character it is depends on the platform:
+   - Usually '$' on systems where the assembler will accept that
+   - Usually '.' otherwise (this includes most sysv4-like systems and most
+     ELF targets)
+   - Occasionally '_' if neither of the above is usable
 
-   We could avoid this if we could just get g++ to tell us what the actual
-   cplus marker character is as part of the debug information, perhaps by
-   ensuring that it is the character that terminates the gcc<n>_compiled
-   marker symbol (FIXME). */
+   We check '$' first because it is the safest, and '.' often has another
+   meaning.  We don't currently try to handle '_' because the precise forms
+   of the names are different on those targets.  */
 
-static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
+static char cplus_markers[] = {'$', '.', '\0'};
 
 int
-is_cplus_marker (c)
-     int c;
+is_cplus_marker (int c)
 {
   return c && strchr (cplus_markers, c) != NULL;
 }
 
 void
-_initialize_demangler ()
+_initialize_demangler (void)
 {
-   struct cmd_list_element *set, *show;
-
-   set = add_set_cmd ("demangle-style", class_support, var_string_noescape,
-                     (char *) &current_demangling_style_string,
-                     "Set the current C++ demangling style.\n\
-Use `set demangle-style' without arguments for a list of demangling styles.",
-                     &setlist);
-   show = add_show_from_set (set, &showlist);
-   set -> function.sfunc = set_demangling_command;
-
-   /* Set the default demangling style chosen at compilation time. */
-   set_demangling_style (DEFAULT_DEMANGLING_STYLE);
-   set_cplus_marker_for_demangling (CPLUS_MARKER);
+  struct cmd_list_element *set, *show;
+  int i, ndems;
+
+  /* Fill the demangling_style_names[] array.  */
+  for (ndems = 0;
+       libiberty_demanglers[ndems].demangling_style != unknown_demangling; 
+       ndems++)
+    ;
+  demangling_style_names = xcalloc (ndems + 1, sizeof (char *));
+  for (i = 0;
+       libiberty_demanglers[i].demangling_style != unknown_demangling; 
+       i++)
+    demangling_style_names[i] =
+      xstrdup (libiberty_demanglers[i].demangling_style_name);
+
+  /* FIXME: cagney/2005-02-20: The code implementing this variable are
+     malloc-ing and free-ing current_demangling_style_string when it
+     should instead just point to an element of
+     demangling_style_names.  */
+  add_setshow_enum_cmd ("demangle-style", class_support,
+                       demangling_style_names,
+                       (const char **) &current_demangling_style_string, _("\
+Set the current C++ demangling style."), _("\
+Show the current C++ demangling style."), _("\
+Use `set demangle-style' without arguments for a list of demangling styles."),
+                       set_demangling_command,
+                       show_demangling_style_names,
+                       &setlist, &showlist);
+
+  /* Set the default demangling style chosen at compilation time. */
+  set_demangling_style (DEFAULT_DEMANGLING_STYLE);
 }
This page took 0.030869 seconds and 4 git commands to generate.