OSDN Git Service

In include,
[pf3gnuchains/gcc-fork.git] / libiberty / cplus-dem.c
index e834d2a..44d1196 100644 (file)
@@ -51,6 +51,14 @@ char * realloc ();
 
 #include "libiberty.h"
 
+#define min(X,Y) (((X) < (Y)) ? (X) : (Y))
+
+/* A value at least one greater than the maximum number of characters
+   that will be output when using the `%d' format with `printf'.  */
+#define INTBUF_SIZE 32
+
+extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
+
 static const char *mystrstr PARAMS ((const char *, const char *));
 
 static const char *
@@ -244,6 +252,55 @@ typedef enum type_kind_t
   tk_real
 } type_kind_t;
 
+struct demangler_engine libiberty_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"
+  }
+  ,
+  {
+    GNU_NEW_ABI_DEMANGLING_STYLE_STRING,
+    gnu_new_abi_demangling,
+    "GNU (g++) new-ABI-style demangling"
+  }
+  ,
+  {
+    NULL, unknown_demangling, NULL
+  }
+};
+
 #define STRING_EMPTY(str)      ((str) -> b == (str) -> p)
 #define PREPEND_BLANK(str)     {if (!STRING_EMPTY(str)) \
     string_prepend(str, " ");}
@@ -343,6 +400,9 @@ string_prepend PARAMS ((string *, const char *));
 static void
 string_prependn PARAMS ((string *, const char *, int));
 
+static void
+string_append_template_idx PARAMS ((string *, int));
+
 static int
 get_count PARAMS ((const char **, int *));
 
@@ -420,6 +480,25 @@ qualifier_string PARAMS ((int));
 static const char*
 demangle_qualifier PARAMS ((int));
 
+static int
+demangle_expression PARAMS ((struct work_stuff *, const char **, string *, 
+                            type_kind_t));
+
+static int
+demangle_integral_value PARAMS ((struct work_stuff *, const char **,
+                                string *));
+
+static int
+demangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
+
+static void
+demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
+                                 string *));
+
+static void
+recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
+                             int));
+
 /* Translate count to integer, consuming tokens in the process.
    Conversion terminates on the first non-digit character.
 
@@ -606,8 +685,8 @@ cplus_demangle_opname (opname, result, options)
        }
     }
   else if (opname[0] == '_' && opname[1] == '_'
-          && opname[2] >= 'a' && opname[2] <= 'z'
-          && opname[3] >= 'a' && opname[3] <= 'z')
+          && islower((unsigned char)opname[2])
+          && islower((unsigned char)opname[3]))
     {
       if (opname[4] == '\0')
        {
@@ -703,6 +782,7 @@ cplus_demangle_opname (opname, result, options)
   return ret;
 
 }
+
 /* Takes operator name as e.g. "++" and returns mangled
    operator name (e.g. "postincrement_expr"), or NULL if not found.
 
@@ -728,6 +808,40 @@ cplus_mangle_opname (opname, options)
   return (0);
 }
 
+/* Add a routine to set the demangling style to be sure it is valid and
+   allow for any demangler initialization that maybe necessary. */
+
+enum demangling_styles
+cplus_demangle_set_style (style)
+     enum demangling_styles style;
+{
+  struct demangler_engine *demangler = libiberty_demanglers; 
+
+  for (; demangler->demangling_style != unknown_demangling; ++demangler)
+    if (style == demangler->demangling_style)
+      {
+       current_demangling_style = style;
+       return current_demangling_style;
+      }
+
+  return unknown_demangling;
+}
+
+/* Do string name to style translation */
+
+enum demangling_styles
+cplus_demangle_name_to_style (name)
+     const char *name;
+{
+  struct demangler_engine *demangler = libiberty_demanglers; 
+
+  for (; demangler->demangling_style != unknown_demangling; ++demangler)
+    if (strcmp (name, demangler->demangling_style_name) == 0)
+      return demangler->demangling_style;
+
+  return unknown_demangling;
+}
+
 /* char *cplus_demangle (const char *mangled, int options)
 
    If MANGLED is a mangled function name produced by GNU C++, then
@@ -768,6 +882,10 @@ cplus_demangle (mangled, options)
   if ((work -> options & DMGL_STYLE_MASK) == 0)
     work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
 
+  /* The new-ABI demangling is implemented elsewhere.  */
+  if (GNU_NEW_ABI_DEMANGLING)
+    return cplus_demangle_new_abi (mangled);
+
   ret = internal_cplus_demangle (work, mangled);
   squangle_mop_up (work);
   return (ret);
@@ -1326,87 +1444,155 @@ demangle_template_template_parm (work, mangled, tname)
 }
 
 static int
-demangle_integral_value (work, mangled, s)
+demangle_expression (work, mangled, s, tk)
      struct work_stuff *work;
      const char** mangled;
      string* s;
+     type_kind_t tk;
 {
+  int need_operator = 0;
   int success;
 
-  if (**mangled == 'E')
+  success = 1;
+  string_appendn (s, "(", 1);
+  (*mangled)++;
+  while (success && **mangled != 'W' && **mangled != '\0')
     {
-      int need_operator = 0;
-
-      success = 1;
-      string_appendn (s, "(", 1);
-      (*mangled)++;
-      while (success && **mangled != 'W' && **mangled != '\0')
+      if (need_operator)
        {
-         if (need_operator)
-           {
-             size_t i;
-             size_t len;
+         size_t i;
+         size_t len;
 
-             success = 0;
+         success = 0;
 
-             len = strlen (*mangled);
+         len = strlen (*mangled);
 
-             for (i = 0;
-                  i < sizeof (optable) / sizeof (optable [0]);
-                  ++i)
-               {
-                 size_t l = strlen (optable[i].in);
+         for (i = 0;
+              i < sizeof (optable) / sizeof (optable [0]);
+              ++i)
+           {
+             size_t l = strlen (optable[i].in);
 
-                 if (l <= len
-                     && memcmp (optable[i].in, *mangled, l) == 0)
-                   {
-                     string_appendn (s, " ", 1);
-                     string_append (s, optable[i].out);
-                     string_appendn (s, " ", 1);
-                     success = 1;
-                     (*mangled) += l;
-                     break;
-                   }
+             if (l <= len
+                 && memcmp (optable[i].in, *mangled, l) == 0)
+               {
+                 string_appendn (s, " ", 1);
+                 string_append (s, optable[i].out);
+                 string_appendn (s, " ", 1);
+                 success = 1;
+                 (*mangled) += l;
+                 break;
                }
-
-             if (!success)
-               break;
            }
-         else
-           need_operator = 1;
 
-         success = demangle_template_value_parm (work, mangled, s,
-                                                 tk_integral);
+         if (!success)
+           break;
        }
-
-      if (**mangled != 'W')
-         success = 0;
       else
-       {
-         string_appendn (s, ")", 1);
-         (*mangled)++;
-       }
+       need_operator = 1;
+
+      success = demangle_template_value_parm (work, mangled, s, tk);
     }
+
+  if (**mangled != 'W')
+    success = 0;
+  else
+    {
+      string_appendn (s, ")", 1);
+      (*mangled)++;
+    }
+
+  return success;
+}
+
+static int
+demangle_integral_value (work, mangled, s)
+     struct work_stuff *work;
+     const char** mangled;
+     string* s;
+{
+  int success;
+
+  if (**mangled == 'E')
+    success = demangle_expression (work, mangled, s, tk_integral);
   else if (**mangled == 'Q' || **mangled == 'K')
     success = demangle_qualified (work, mangled, s, 0, 1);
   else
     {
+      int value;
+
       success = 0;
 
+      /* Negative numbers are indicated with a leading `m'.  */
       if (**mangled == 'm')
        {
          string_appendn (s, "-", 1);
          (*mangled)++;
        }
+
+      /* Read the rest of the number.  */
+      value = consume_count_with_underscores (mangled);
+      if (value != -1)
+       {
+         char buf[INTBUF_SIZE];
+         sprintf (buf, "%d", value);
+         string_append (s, buf);
+
+         /* If the next character is an underscore, skip it.  */
+         if (**mangled == '_')
+           (*mangled)++;
+
+         /* All is well.  */
+         success = 1;
+       }
+    }
+
+  return success;
+}
+
+/* Demangle the real value in MANGLED.  */
+
+static int
+demangle_real_value (work, mangled, s)
+     struct work_stuff *work;
+     const char **mangled;
+     string* s;
+{
+  if (**mangled == 'E')
+    return demangle_expression (work, mangled, s, tk_real);
+
+  if (**mangled == 'm')
+    {
+      string_appendn (s, "-", 1);
+      (*mangled)++;
+    }
+  while (isdigit ((unsigned char)**mangled))
+    {
+      string_appendn (s, *mangled, 1);
+      (*mangled)++;
+    }
+  if (**mangled == '.') /* fraction */
+    {
+      string_appendn (s, ".", 1);
+      (*mangled)++;
+      while (isdigit ((unsigned char)**mangled))
+       {
+         string_appendn (s, *mangled, 1);
+         (*mangled)++;
+       }
+    }
+  if (**mangled == 'e') /* exponent */
+    {
+      string_appendn (s, "e", 1);
+      (*mangled)++;
       while (isdigit ((unsigned char)**mangled))
        {
          string_appendn (s, *mangled, 1);
          (*mangled)++;
-         success = 1;
        }
     }
 
-  return success;
+  return 1;
 }
 
 static int
@@ -1432,11 +1618,7 @@ demangle_template_value_parm (work, mangled, s, tk)
       if (work->tmpl_argvec)
        string_append (s, work->tmpl_argvec[idx]);
       else
-       {
-         char buf[10];
-         sprintf(buf, "T%d", idx);
-         string_append (s, buf);
-       }
+       string_append_template_idx (s, idx);
     }
   else if (tk == tk_integral)
     success = demangle_integral_value (work, mangled, s);
@@ -1472,38 +1654,7 @@ demangle_template_value_parm (work, mangled, s, tk)
        success = 0;
     }
   else if (tk == tk_real)
-    {
-      if (**mangled == 'm')
-       {
-         string_appendn (s, "-", 1);
-         (*mangled)++;
-       }
-      while (isdigit ((unsigned char)**mangled))
-       {
-         string_appendn (s, *mangled, 1);
-         (*mangled)++;
-       }
-      if (**mangled == '.') /* fraction */
-       {
-         string_appendn (s, ".", 1);
-         (*mangled)++;
-         while (isdigit ((unsigned char)**mangled))
-           {
-             string_appendn (s, *mangled, 1);
-             (*mangled)++;
-           }
-       }
-      if (**mangled == 'e') /* exponent */
-       {
-         string_appendn (s, "e", 1);
-         (*mangled)++;
-         while (isdigit ((unsigned char)**mangled))
-           {
-             string_appendn (s, *mangled, 1);
-             (*mangled)++;
-           }
-       }
-    }
+    success = demangle_real_value (work, mangled, s);
   else if (tk == tk_pointer || tk == tk_reference)
     {
       if (**mangled == 'Q')
@@ -1601,11 +1752,9 @@ demangle_template (work, mangled, tname, trawname, is_type, remember)
            }
          else
            {
-             char buf[10];
-             sprintf(buf, "T%d", idx);
-             string_append (tname, buf);
+             string_append_template_idx (tname, idx);
              if (trawname)
-               string_append (trawname, buf);
+               string_append_template_idx (trawname, idx);
            }
        }
       else
@@ -2446,7 +2595,7 @@ gnu_special (work, mangled, declp)
          break;
        default:
          n = consume_count (mangled);
-         if (n < 0 || n > strlen (*mangled))
+         if (n < 0 || n > (long) strlen (*mangled))
            {
              success = 0;
              break;
@@ -2613,7 +2762,7 @@ arm_special (mangled, declp)
        {
          n = consume_count (mangled);
           if (n == -1
-             || n > strlen (*mangled))
+             || n > (long) strlen (*mangled))
            return 0;
          string_prependn (declp, *mangled, n);
          (*mangled) += n;
@@ -2674,7 +2823,6 @@ demangle_qualified (work, mangled, result, isfuncname, append)
 {
   int qualifiers = 0;
   int success = 1;
-  const char *p;
   char num[2];
   string temp;
   string last_name;
@@ -2706,19 +2854,10 @@ demangle_qualified (work, mangled, result, isfuncname, append)
       /* GNU mangled name with more than 9 classes.  The count is preceded
         by an underscore (to distinguish it from the <= 9 case) and followed
         by an underscore.  */
-      p = *mangled + 2;
-      qualifiers = atoi (p);
-      if (!isdigit ((unsigned char)*p) || *p == '0')
-       success = 0;
-
-      /* Skip the digits.  */
-      while (isdigit ((unsigned char)*p))
-       ++p;
-
-      if (*p != '_')
+      (*mangled)++;
+      qualifiers = consume_count_with_underscores (mangled);
+      if (qualifiers == -1)
        success = 0;
-
-      *mangled = p + 1;
       break;
 
     case '1':
@@ -2909,9 +3048,7 @@ get_count (type, count)
   int n;
 
   if (!isdigit ((unsigned char)**type))
-    {
-      return (0);
-    }
+    return (0);
   else
     {
       *count = **type - '0';
@@ -3050,7 +3187,12 @@ do_type (work, mangled, result)
            (*mangled)++;
 
            string_append (&decl, ")");
-           string_prepend (&decl, SCOPE_STRING (work));
+
+           /* We don't need to prepend `::' for a qualified name;
+              demangle_qualified will do that for us.  */
+           if (**mangled != 'Q')
+             string_prepend (&decl, SCOPE_STRING (work));
+
            if (isdigit ((unsigned char)**mangled))
              {
                n = consume_count (mangled);
@@ -3083,6 +3225,14 @@ do_type (work, mangled, result)
                else
                  break;
              }
+           else if (**mangled == 'Q')
+             {
+               success = demangle_qualified (work, mangled, &decl,
+                                             /*isfuncnam=*/0, 
+                                             /*append=*/0);
+               if (!success)
+                 break;
+             }
            else
              {
                success = 0;
@@ -3195,11 +3345,7 @@ do_type (work, mangled, result)
        if (work->tmpl_argvec)
          string_append (result, work->tmpl_argvec[idx]);
        else
-         {
-           char buf[10];
-           sprintf(buf, "T%d", idx);
-           string_append (result, buf);
-         }
+         string_append_template_idx (result, idx);
 
        success = 1;
       }
@@ -3373,14 +3519,14 @@ demangle_fund_type (work, mangled, result)
          break;
        }
     case 'I':
-      ++(*mangled);
+      (*mangled)++;
       if (**mangled == '_')
        {
          int i;
-         ++(*mangled);
+         (*mangled)++;
          for (i = 0;
-              (i < sizeof (buf) - 1 && **mangled && **mangled != '_');
-              ++(*mangled), ++i)
+              i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
+              (*mangled)++, i++)
            buf[i] = **mangled;
          if (**mangled != '_')
            {
@@ -3388,13 +3534,13 @@ demangle_fund_type (work, mangled, result)
              break;
            }
          buf[i] = '\0';
-         ++(*mangled);
+         (*mangled)++;
        }
       else
        {
          strncpy (buf, *mangled, 2);
          buf[2] = '\0';
-         *mangled += 2;
+         *mangled += min (strlen (*mangled), 2);
        }
       sscanf (buf, "%x", &dec);
       sprintf (buf, "int%i_t", dec);
@@ -3448,7 +3594,7 @@ demangle_fund_type (work, mangled, result)
 
 static int
 do_hpacc_template_const_value (work, mangled, result)
-     struct work_stuff *work;
+     struct work_stuff *work ATTRIBUTE_UNUSED;
      const char **mangled;
      string *result;
 {
@@ -4130,8 +4276,8 @@ demangle_function_name (work, mangled, declp, scan)
        }
     }
   else if (declp->b[0] == '_' && declp->b[1] == '_'
-          && declp->b[2] >= 'a' && declp->b[2] <= 'z'
-          && declp->b[3] >= 'a' && declp->b[3] <= 'z')
+          && islower((unsigned char)declp->b[2])
+          && islower((unsigned char)declp->b[3]))
     {
       if (declp->b[4] == '\0')
        {
@@ -4318,6 +4464,16 @@ string_prependn (p, s, n)
     }
 }
 
+static void
+string_append_template_idx (s, idx)
+     string *s;
+     int idx;
+{
+  char buf[INTBUF_SIZE + 1 /* 'T' */];
+  sprintf(buf, "T%d", idx);
+  string_append (s, buf);
+}
+
 /* To generate a standalone demangler program for testing purposes,
    just compile and link this file with -DMAIN and libiberty.a.  When
    run, it demangles each command line arg, or each stdin string, and
@@ -4327,13 +4483,14 @@ string_prependn (p, s, n)
 
 #include "getopt.h"
 
-static char *program_name;
-static char *program_version = VERSION;
+static const char *program_name;
+static const char *program_version = VERSION;
 static int flags = DMGL_PARAMS | DMGL_ANSI;
 
 static void demangle_it PARAMS ((char *));
-static void usage PARAMS ((FILE *, int));
-static void fatal PARAMS ((char *));
+static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
+static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
+static void print_demangler_list PARAMS ((FILE *));
 
 static void
 demangle_it (mangled_name)
@@ -4353,16 +4510,43 @@ demangle_it (mangled_name)
     }
 }
 
+static void 
+print_demangler_list (stream)
+     FILE *stream;
+{
+  struct demangler_engine *demangler; 
+
+  fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
+  
+  for (demangler = libiberty_demanglers + 1;
+       demangler->demangling_style != unknown_demangling;
+       ++demangler)
+    fprintf (stream, ",%s", demangler->demangling_style_name);
+
+  fprintf (stream, "}");
+}
+
 static void
 usage (stream, status)
      FILE *stream;
      int status;
 {
   fprintf (stream, "\
-Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
-       [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
-      [--help] [--version] [arg...]\n",
+Usage: %s [-_] [-n] [--strip-underscores] [--no-strip-underscores] \n",
           program_name);
+
+  fprintf (stream, "\
+       [-s ");
+  print_demangler_list (stream);
+  fprintf (stream, "]\n");
+
+  fprintf (stream, "\
+       [--format ");
+  print_demangler_list (stream);
+  fprintf (stream, "]\n");
+
+  fprintf (stream, "\
+       [--help] [--version] [arg...]\n");
   exit (status);
 }
 
@@ -4393,6 +4577,77 @@ fancy_abort ()
   fatal ("Internal gcc abort.");
 }
 
+
+static const char *
+standard_symbol_characters PARAMS ((void));
+
+static const char *
+hp_symbol_characters PARAMS ((void));
+
+static const char *
+gnu_new_abi_symbol_characters PARAMS ((void));
+
+/* Return the string of non-alnum characters that may occur 
+   as a valid symbol component, in the standard assembler symbol
+   syntax.  */
+
+static const char *
+standard_symbol_characters ()
+{
+  return "_$.";
+}
+
+
+/* Return the string of non-alnum characters that may occur
+   as a valid symbol name component in an HP object file.
+
+   Note that, since HP's compiler generates object code straight from
+   C++ source, without going through an assembler, its mangled
+   identifiers can use all sorts of characters that no assembler would
+   tolerate, so the alphabet this function creates is a little odd.
+   Here are some sample mangled identifiers offered by HP:
+
+       typeid*__XT24AddressIndExpClassMember_
+       [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
+       __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
+
+   This still seems really weird to me, since nowhere else in this
+   file is there anything to recognize curly brackets, parens, etc.
+   I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
+   this is right, but I still strongly suspect that there's a
+   misunderstanding here.
+
+   If we decide it's better for c++filt to use HP's assembler syntax
+   to scrape identifiers out of its input, here's the definition of
+   the symbol name syntax from the HP assembler manual:
+
+       Symbols are composed of uppercase and lowercase letters, decimal
+       digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
+       underscore (_). A symbol can begin with a letter, digit underscore or
+       dollar sign. If a symbol begins with a digit, it must contain a
+       non-digit character.
+
+   So have fun.  */
+static const char *
+hp_symbol_characters ()
+{
+  return "_$.<>#,*&[]:(){}";
+}
+
+
+/* Return the string of non-alnum characters that may occur 
+   as a valid symbol component in the GNU standard C++ ABI mangling
+   scheme.  */
+
+static const char *
+gnu_new_abi_symbol_characters ()
+{
+  return "_";
+}
+
+
+extern int main PARAMS ((int, char **));
+
 int
 main (argc, argv)
      int argc;
@@ -4400,6 +4655,7 @@ main (argc, argv)
 {
   char *result;
   int c;
+  const char *valid_symbols;
 
   program_name = argv[0];
 
@@ -4419,7 +4675,7 @@ main (argc, argv)
          break;
        case 'v':
          printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
-         exit (0);
+         return (0);
        case '_':
          strip_underscore = 1;
          break;
@@ -4427,32 +4683,19 @@ main (argc, argv)
          flags |= DMGL_JAVA;
          break;
        case 's':
-         if (strcmp (optarg, "gnu") == 0)
-           {
-             current_demangling_style = gnu_demangling;
-           }
-         else if (strcmp (optarg, "lucid") == 0)
-           {
-             current_demangling_style = lucid_demangling;
-           }
-         else if (strcmp (optarg, "arm") == 0)
-           {
-             current_demangling_style = arm_demangling;
-           }
-         else if (strcmp (optarg, "hp") == 0)
-           {
-             current_demangling_style = hp_demangling;
-           }
-          else if (strcmp (optarg, "edg") == 0)
-            {
-              current_demangling_style = edg_demangling;
-            }
-         else
-           {
-             fprintf (stderr, "%s: unknown demangling style `%s'\n",
-                      program_name, optarg);
-             exit (1);
-           }
+         {
+           enum demangling_styles style;
+
+           style = cplus_demangle_name_to_style (optarg);
+           if (style == unknown_demangling)
+             {
+               fprintf (stderr, "%s: unknown demangling style `%s'\n",
+                        program_name, optarg);
+               return (1);
+             }
+           else
+             cplus_demangle_set_style (style);
+         }
          break;
        }
     }
@@ -4466,16 +4709,33 @@ main (argc, argv)
     }
   else
     {
+      switch (current_demangling_style)
+       {
+       case gnu_demangling:
+       case lucid_demangling:
+       case arm_demangling:
+       case edg_demangling:
+         valid_symbols = standard_symbol_characters ();
+         break;
+       case hp_demangling:
+         valid_symbols = hp_symbol_characters ();
+         break;
+       case gnu_new_abi_demangling:
+         valid_symbols = gnu_new_abi_symbol_characters ();
+         break;
+       default:
+         /* Folks should explicitly indicate the appropriate alphabet for
+            each demangling.  Providing a default would allow the
+            question to go unconsidered.  */
+         abort ();
+       }
+
       for (;;)
        {
          int i = 0;
          c = getchar ();
          /* Try to read a label.  */
-         while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.' ||
-                              c == '<' || c == '>' || c == '#' || c == ',' || c == '*' || c == '&' ||
-                              c == '[' || c == ']' || c == ':' || c == '(' || c == ')'))
-                              /* the ones in the 2nd & 3rd lines were added to handle
-                                 HP aCC template specialization manglings */
+         while (c != EOF && (isalnum (c) || strchr (valid_symbols, c)))
            {
              if (i >= MBUF_SIZE-1)
                break;
@@ -4515,12 +4775,12 @@ main (argc, argv)
        }
     }
 
-  exit (0);
+  return (0);
 }
 
 static void
 fatal (str)
-     char *str;
+     const char *str;
 {
   fprintf (stderr, "%s: %s\n", program_name, str);
   exit (1);