Index: trunk/src/binutils/libiberty/cplus-dem.c
===================================================================
--- trunk/src/binutils/libiberty/cplus-dem.c	(revision 952)
+++ trunk/src/binutils/libiberty/cplus-dem.c	(revision 953)
@@ -505,5 +505,5 @@
 
 static int
-demangle_expression PARAMS ((struct work_stuff *, const char **, string *, 
+demangle_expression PARAMS ((struct work_stuff *, const char **, string *,
 			     type_kind_t));
 
@@ -845,5 +845,5 @@
      enum demangling_styles style;
 {
-  const struct demangler_engine *demangler = libiberty_demanglers; 
+  const struct demangler_engine *demangler = libiberty_demanglers;
 
   for (; demangler->demangling_style != unknown_demangling; ++demangler)
@@ -863,5 +863,5 @@
      const char *name;
 {
-  const struct demangler_engine *demangler = libiberty_demanglers; 
+  const struct demangler_engine *demangler = libiberty_demanglers;
 
   for (; demangler->demangling_style != unknown_demangling; ++demangler)
@@ -980,5 +980,5 @@
   int changed;
   size_t demangled_size = 0;
-  
+
   changed = 0;
 
@@ -988,8 +988,8 @@
       changed = 1;
     }
-  
+
   if (mangled[0] == '_' || mangled[0] == '<')
     goto Suppress;
-  
+
   p = strstr (mangled, "___");
   if (p == NULL)
@@ -1005,10 +1005,10 @@
 	goto Suppress;
     }
-  
+
   /* Make demangled big enough for possible expansion by operator name.  */
   grow_vect (&demangled,
 	     &demangled_size,  2 * len0 + 1,
 	     sizeof (char));
-  
+
   if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
     for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
@@ -1025,14 +1025,14 @@
       }
   }
-  
+
   for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
        i += 1, j += 1)
     demangled[j] = mangled[i];
-  
+
   at_start_name = 1;
   while (i < len0)
     {
       at_start_name = 0;
-      
+
       if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
 	{
@@ -1048,5 +1048,5 @@
     }
   demangled[j] = '\000';
-  
+
   for (i = 0; demangled[i] != '\0'; i += 1)
     if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
@@ -1057,5 +1057,5 @@
   else
     return demangled;
-  
+
  Suppress:
   grow_vect (&demangled,
@@ -1980,5 +1980,5 @@
       if (**mangled == 'Q')
 	success = demangle_qualified (work, mangled, s,
-				      /*isfuncname=*/0, 
+				      /*isfuncname=*/0,
 				      /*append=*/1);
       else
@@ -3645,5 +3645,5 @@
 	      {
 		success = demangle_qualified (work, mangled, &decl,
-					      /*isfuncnam=*/0, 
+					      /*isfuncnam=*/0,
 					      /*append=*/0);
 		if (!success)
@@ -4890,2 +4890,340 @@
   string_append (s, buf);
 }
+
+/* bird: This was put back since we're building some older gcc, remove
+         when going for gcc which doesn't expect MAIN and main().
+ */
+
+/* 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
+   prints the result on stdout.  */
+
+#ifdef MAIN
+
+#include "getopt.h"
+
+static const char *program_name;
+static const char *program_version = VERSION;
+static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
+
+static void demangle_it 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)
+     char *mangled_name;
+{
+  char *result;
+
+  /* For command line args, also try to demangle type encodings.  */
+  result = cplus_demangle (mangled_name, flags | DMGL_TYPES);
+  if (result == NULL)
+    {
+      printf ("%s\n", mangled_name);
+    }
+  else
+    {
+      printf ("%s\n", result);
+      free (result);
+    }
+}
+
+static void
+print_demangler_list (stream)
+     FILE *stream;
+{
+  const 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] [--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);
+}
+
+#define MBUF_SIZE 32767
+char mbuffer[MBUF_SIZE];
+
+/* Defined in the automatically-generated underscore.c.  */
+extern int prepends_underscore;
+
+int strip_underscore = 0;
+
+static const struct option long_options[] = {
+  {"strip-underscores", no_argument, 0, '_'},
+  {"format", required_argument, 0, 's'},
+  {"help", no_argument, 0, 'h'},
+  {"no-strip-underscores", no_argument, 0, 'n'},
+  {"version", no_argument, 0, 'v'},
+  {0, no_argument, 0, 0}
+};
+
+/* More 'friendly' abort that prints the line and file.
+   config.h can #define abort fancy_abort if you like that sort of thing.  */
+
+void
+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_v3_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 C++ V3 ABI mangling
+   scheme.  */
+
+static const char *
+gnu_v3_symbol_characters ()
+{
+  return "_$.";
+}
+
+
+extern int main PARAMS ((int, char **));
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  char *result;
+  int c;
+  const char *valid_symbols;
+  enum demangling_styles style = auto_demangling;
+
+  program_name = argv[0];
+
+  strip_underscore = prepends_underscore;
+
+  while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
+    {
+      switch (c)
+	{
+	case '?':
+	  usage (stderr, 1);
+	  break;
+	case 'h':
+	  usage (stdout, 0);
+	case 'n':
+	  strip_underscore = 0;
+	  break;
+	case 'v':
+	  printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
+	  return (0);
+	case '_':
+	  strip_underscore = 1;
+	  break;
+	case 's':
+	  {
+	    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;
+	}
+    }
+
+  if (optind < argc)
+    {
+      for ( ; optind < argc; optind++)
+	{
+	  demangle_it (argv[optind]);
+	}
+    }
+  else
+    {
+      switch (current_demangling_style)
+	{
+	case gnu_demangling:
+	case lucid_demangling:
+	case arm_demangling:
+	case java_demangling:
+	case edg_demangling:
+	case gnat_demangling:
+	case auto_demangling:
+	  valid_symbols = standard_symbol_characters ();
+	  break;
+	case hp_demangling:
+	  valid_symbols = hp_symbol_characters ();
+	  break;
+	case gnu_v3_demangling:
+	  valid_symbols = gnu_v3_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) || strchr (valid_symbols, c)))
+	    {
+	      if (i >= MBUF_SIZE-1)
+		break;
+	      mbuffer[i++] = c;
+	      c = getchar ();
+	    }
+	  if (i > 0)
+	    {
+	      int skip_first = 0;
+
+	      if (mbuffer[0] == '.' || mbuffer[0] == '$')
+		++skip_first;
+	      if (strip_underscore && mbuffer[skip_first] == '_')
+		++skip_first;
+
+	      if (skip_first > i)
+		skip_first = i;
+
+	      mbuffer[i] = 0;
+	      flags |= (int) style;
+	      result = cplus_demangle (mbuffer + skip_first, flags);
+	      if (result)
+		{
+		  if (mbuffer[0] == '.')
+		    putc ('.', stdout);
+		  fputs (result, stdout);
+		  free (result);
+		}
+	      else
+		fputs (mbuffer, stdout);
+
+	      fflush (stdout);
+	    }
+	  if (c == EOF)
+	    break;
+	  putchar (c);
+	  fflush (stdout);
+	}
+    }
+
+  return (0);
+}
+
+static void
+fatal (str)
+     const char *str;
+{
+  fprintf (stderr, "%s: %s\n", program_name, str);
+  exit (1);
+}
+
+PTR
+xmalloc (size)
+  size_t size;
+{
+  register PTR value = (PTR) malloc (size);
+  if (value == 0)
+    fatal ("virtual memory exhausted");
+  return value;
+}
+
+PTR
+xrealloc (ptr, size)
+  PTR ptr;
+  size_t size;
+{
+  register PTR value = (PTR) realloc (ptr, size);
+  if (value == 0)
+    fatal ("virtual memory exhausted");
+  return value;
+}
+#endif	/* main */
