home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / utlsrc33.lzh / UTLSRC33 / CPLUSDEM.C < prev    next >
C/C++ Source or Header  |  1993-07-30  |  28KB  |  1,394 lines

  1. /* Demangler for GNU C++ 
  2.    Copyright (C) 1989, 1992 Free Software Foundation, Inc.
  3.    written by James Clark (jjc@jclark.uucp)
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /* This is for g++ 1.36.1 (November 6 version). It will probably
  20.    require changes for any other version.
  21.  
  22.    Modified for g++ 1.36.2 (November 18 version).
  23.  
  24.    Modified for g++ 1.90.06 (December 31 version).
  25.  
  26.    Modified for g++ 1.95.03 (November 13 verison).  */
  27.  
  28. /* This file exports one function
  29.  
  30.    char *cplus_demangle (const char *name)
  31.  
  32.    If NAME is a mangled function name produced by GNU C++, then
  33.    a pointer to a malloced string giving a C++ representation
  34.    of the name will be returned; otherwise NULL will be returned.
  35.    It is the caller's responsibility to free the string which
  36.    is returned.
  37.  
  38.    For example,
  39.    
  40.    cplus_demangle ("_foo__1Ai")
  41.    
  42.    returns
  43.  
  44.    "A::foo(int)"
  45.  
  46.    This file imports xmalloc and xrealloc, which are like malloc and
  47.    realloc except that they generate a fatal error if there is no
  48.    available memory. */
  49.  
  50. /* #define nounderscore 1 *//* define this is names don't start with _ */
  51.  
  52. #include <stdio.h>
  53. #include <ctype.h>
  54.  
  55. #ifdef USG
  56. #include <memory.h>
  57. #include <string.h>
  58. #else
  59. #include <strings.h>
  60. #define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
  61. #define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
  62. #define strchr index 
  63. #define strrchr rindex
  64. #endif
  65.  
  66. /* This is '$' on systems where the assembler can deal with that.
  67.    Where the assembler can't, it's '.' (but on many systems '.' is
  68.    used for other things).  */
  69. #if !defined (CPLUS_MARKER)
  70. #define CPLUS_MARKER '$'
  71. #endif
  72.  
  73. #ifndef __STDC__
  74. #define const
  75. #endif
  76.  
  77. #ifdef __STDC__
  78. extern char *cplus_demangle (const char *type);
  79. #else
  80. extern char *cplus_demangle ();
  81. #endif
  82.  
  83. #ifdef __STDC__
  84. extern char *xmalloc (int);
  85. extern char *xrealloc (char *, int);
  86. extern void free (char *);
  87. #else
  88. extern char *xmalloc ();
  89. extern char *xrealloc ();
  90. extern void free ();
  91. #endif
  92.  
  93. static char **typevec = 0;
  94. static int ntypes = 0;
  95. static int typevec_size = 0;
  96.  
  97. static struct {
  98.   const char *in;
  99.   const char *out;
  100. } optable[] = {
  101.   "nw", " new",            /* new (1.92, ansi) */
  102.   "dl", " delete",        /* new (1.92, ansi) */
  103.   "new", " new",        /* old (1.91) */
  104.   "delete", " delete",        /* old (1.91) */
  105.   "ne", "!=",            /* old, ansi */
  106.   "eq", "==",            /* old, ansi */
  107.   "ge", ">=",            /* old, ansi */
  108.   "gt", ">",            /* old, ansi */
  109.   "le", "<=",            /* old, ansi */
  110.   "lt", "<",            /* old, ansi */
  111.   "plus", "+",            /* old */
  112.   "pl", "+",            /* ansi */
  113.   "apl", "+=",            /* ansi */
  114.   "minus", "-",            /* old */
  115.   "mi", "-",            /* ansi */
  116.   "ami", "-=",            /* ansi */
  117.   "mult", "*",            /* old */
  118.   "ml", "*",            /* ansi */
  119.   "aml", "*=",            /* ansi */
  120.   "convert", "+",        /* old (unary +) */
  121.   "negate", "-",        /* old (unary -) */
  122.   "trunc_mod", "%",        /* old */
  123.   "md", "%",            /* ansi */
  124.   "amd", "%=",            /* ansi */
  125.   "trunc_div", "/",        /* old */
  126.   "dv", "/",            /* ansi */
  127.   "adv", "/=",            /* ansi */
  128.   "truth_andif", "&&",        /* old */
  129.   "aa", "&&",            /* ansi */
  130.   "truth_orif", "||",        /* old */
  131.   "oo", "||",            /* ansi */
  132.   "truth_not", "!",        /* old */
  133.   "nt", "!",            /* ansi */
  134.   "postincrement", "++",    /* old */
  135.   "pp", "++",            /* ansi */
  136.   "postdecrement", "--",    /* old */
  137.   "mm", "--",            /* ansi */
  138.   "bit_ior", "|",        /* old */
  139.   "or", "|",            /* ansi */
  140.   "aor", "|=",            /* ansi */
  141.   "bit_xor", "^",        /* old */
  142.   "er", "^",            /* ansi */
  143.   "aer", "^=",            /* ansi */
  144.   "bit_and", "&",        /* old */
  145.   "ad", "&",            /* ansi */
  146.   "aad", "&=",            /* ansi */
  147.   "bit_not", "~",        /* old */
  148.   "co", "~",            /* ansi */
  149.   "call", "()",            /* old */
  150.   "cl", "()",            /* ansi */
  151.   "cond", "?:",            /* old */
  152.   "alshift", "<<",        /* old */
  153.   "ls", "<<",            /* ansi */
  154.   "als", "<<=",            /* ansi */
  155.   "arshift", ">>",        /* old */
  156.   "rs", ">>",            /* ansi */
  157.   "ars", ">>=",            /* ansi */
  158.   "component", "->",        /* old */
  159.   "rf", "->",            /* ansi */
  160.   "indirect", "*",        /* old */
  161.   "method_call", "->()",    /* old */
  162.   "addr", "&",            /* old (unary &) */
  163.   "array", "[]",        /* old */
  164.   "vc", "[]",            /* ansi */
  165.   "compound", ",",        /* old */
  166.   "cm", ",",            /* ansi */
  167.   "nop", "",            /* old (for operator=) */
  168.   "as", "=",            /* ansi */
  169.   "cond", "?:",            /* old */
  170.   "cn", "?:",            /* psuedo-ansi */
  171.   "max", ">?",            /* old */
  172.   "mx", ">?",            /* psuedo-ansi */
  173.   "min", "<?",            /* old */
  174.   "mn", "<?",            /* psuedo-ansi */
  175. };
  176.  
  177. /* Beware: these aren't '\0' terminated. */
  178.  
  179. typedef struct {
  180.   char *b;            /* pointer to start of string */
  181.   char *p;            /* pointer after last character */
  182.   char *e;            /* pointer after end of allocated space */
  183. } string;
  184.  
  185. #ifdef __STDC__
  186. static void string_need (string *s, int n);
  187. static void string_delete (string *s);
  188. static void string_init (string *s);
  189. static void string_clear (string *s);
  190. static int string_empty (string *s);
  191. static void string_append (string *p, const char *s);
  192. static void string_appends (string *p, string *s);
  193. static void string_appendn (string *p, const char *s, int n);
  194. static void string_prepend (string *p, const char *s);
  195. static void string_prepends (string *p, string *s);
  196. static void string_prependn (string *p, const char *s, int n);
  197. static int get_count (const char **type, int *count);
  198. static int do_args (const char **type, string *decl);
  199. static int do_type (const char **type, string *result);
  200. static int do_arg (const char **type, string *result);
  201. static int do_args (const char **type, string *decl);
  202. static int do_cuv_prefix (const char **type, string *result, int *non_empty);
  203. static int do_builtin_type (const char **type, string *result, int *non_empty);
  204. static int do_template_args (const char **type, string *result);
  205. static void munge_function_name (string *name);
  206. static void remember_type (const char *type, int len);
  207. #else
  208. static void string_need ();
  209. static void string_delete ();
  210. static void string_init ();
  211. static void string_clear ();
  212. static int string_empty ();
  213. static void string_append ();
  214. static void string_appends ();
  215. static void string_appendn ();
  216. static void string_prepend ();
  217. static void string_prepends ();
  218. static void string_prependn ();
  219. static int get_count ();
  220. static int do_args ();
  221. static int do_type ();
  222. static int do_arg ();
  223. static int do_args ();
  224. static int do_cuv_prefix ();
  225. static int do_builtin_type ();
  226. static int do_template_args ();
  227. static void munge_function_name ();
  228. static void remember_type ();
  229. #endif
  230.  
  231. int
  232. get_simple_count (type, res)
  233.      char **type;
  234.      int *res;
  235. {
  236.   int n = 0, success = 1;;
  237.   
  238.   do
  239.     {
  240.       n *= 10;
  241.       n += **type - '0';
  242.       *type += 1;
  243.     } 
  244.   while (isdigit (**type));
  245.   if (strlen (*type) < n)
  246.     {
  247.       success = 0;
  248.     }
  249.  
  250.   *res = n;
  251.   return success;
  252. }
  253.  
  254. char *
  255. cplus_demangle (type)
  256.      const char *type;
  257. {
  258.   string decl;
  259.   int n;
  260.   int success = 0;
  261.   int constructor = 0;
  262.   int destructor = 0;
  263.   int static_type = 0;
  264.   int const_flag = 0;
  265.   int i;
  266.   const char *p;
  267. #ifndef LONGERNAMES
  268.   const char *premangle;
  269. #endif
  270.  
  271.   if (type == NULL || *type == '\0')
  272.     return NULL;
  273. #ifndef nounderscore
  274.   if (*type++ != '_')
  275.     return NULL;
  276. #endif
  277.   p = type;
  278.   while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  279.     p++;
  280.   if (*p == '\0')
  281.     {
  282.       /* destructor */
  283.       if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
  284.     {
  285.       destructor = 1;
  286.       p = type;
  287.     }
  288.       /* virtual table "_vt$"  */
  289.       else if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
  290.     {
  291.       int n = strlen (type + 4) + 14 + 1;
  292.       char *tem = (char *) xmalloc (n);
  293.       strcpy (tem, type + 4);
  294.       strcat (tem, " virtual table");
  295.       return tem;
  296.     }
  297.       /* static data member */
  298.       else if (type[0] == '_' && type[1] != '_' && (strchr (type, CPLUS_MARKER) != NULL))
  299.     {
  300.       static_type = 1;
  301.       p = type + 1;
  302.     }
  303.       else return NULL;
  304.     }
  305.  
  306.   string_init (&decl);
  307.  
  308.   if (static_type)
  309.     {
  310.       if (!isdigit (p[0]) && ('t' != p[0]))
  311.     {
  312.       string_delete (&decl);
  313.       return NULL;
  314.     }
  315.     }
  316.   else if (destructor)
  317.     {
  318.       if (!isdigit (p[3])&& ('t' != p[3]))
  319.     {
  320.       string_delete (&decl);
  321.       return NULL;
  322.     }
  323.       p += 3;
  324.     }
  325.   else if (p == type)
  326.     {
  327.       if (!isdigit (p[2]) && ('t' != p[2]))
  328.     {
  329.       p += 1;
  330.       while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  331.         p++;
  332.       string_appendn (&decl, type, p - type);      
  333.       string_appendn (&decl, "", 1);
  334.       munge_function_name (&decl);
  335.       if (decl.b[0] == '_')
  336.         decl.p--;
  337.       p += 2;
  338.     }
  339.       else
  340.     {
  341.       constructor = 1;
  342.       p += 2;
  343.     }
  344.     }
  345.   else
  346.     {
  347.       string_appendn (&decl, type, p - type);
  348.       decl.p[0] = '0';
  349.       munge_function_name (&decl);
  350.       p += 2;
  351.     }
  352.  
  353. #ifndef LONGERNAMES
  354.   premangle = p;
  355. #endif
  356.   switch (*p)
  357.     {
  358.     case 'C':
  359.       /* a const member function */
  360.       p += 1;
  361.       const_flag = 1;
  362.       if (*p == 't')
  363.     goto template;
  364.       if (!isdigit (*p))
  365.     {
  366.       string_delete (&decl);
  367.       return NULL;
  368.     }
  369.       /* fall through */
  370.     case '0':
  371.     case '1':
  372.     case '2':
  373.     case '3':
  374.     case '4':
  375.     case '5':
  376.     case '6':
  377.     case '7':
  378.     case '8':
  379.     case '9':
  380.       n = 0;
  381.       do
  382.     {
  383.       n *= 10;
  384.       n += *p - '0';
  385.       p += 1;
  386.     }
  387.       while (isdigit (*p));
  388.       if (strlen (p) < n)
  389.     {
  390.       string_delete (&decl);
  391.       return NULL;
  392.     }
  393.       if (constructor || destructor)
  394.     {
  395.       string_appendn (&decl, p, n);
  396.       string_append (&decl, "::");
  397.       if (destructor)
  398.         string_append(&decl, "~");
  399.       string_appendn (&decl, p, n);
  400.     }
  401.       else
  402.     {
  403.       string_prepend (&decl, "::");
  404.       string_prependn (&decl, p, n);
  405.     }
  406.       p += n;
  407. #ifndef LONGERNAMES
  408.       remember_type (premangle, p - premangle);
  409. #endif
  410.       if (static_type)
  411.     {
  412.       string_append(&decl, p+1);
  413.       p += strlen(p);
  414.       success = 1;
  415.     }
  416.       else
  417.     success = do_args (&p, &decl);
  418.       if (const_flag)
  419.     string_append (&decl, " const");
  420.       break;
  421.     case 'F':
  422.       p += 1;
  423.       success = do_args (&p, &decl);
  424.       break;
  425.     /* template additions */
  426.     case 't':
  427.     template:
  428.       p += 1;
  429.       {
  430.     int r;
  431.     string tname;
  432.     string trawname;
  433.     
  434.     string_init(&tname);
  435.     string_init(&trawname);
  436.  
  437.     /* get template name */
  438.     if (!get_simple_count (&p, &r))
  439.       {
  440.         success = 0;
  441.         break;
  442.       }
  443.     string_appendn (&tname, p, r);
  444.     string_appendn (&trawname, p, r);
  445.     p += r;
  446.     string_append (&tname, "<");
  447.     success = do_template_args (&p, &tname);
  448.     if (!success)
  449.       {
  450.         string_delete (&tname);
  451.         string_delete (&trawname);
  452.         break;
  453.       }
  454.     string_append (&tname, ">::");
  455.     if (destructor)
  456.       string_append(&tname, "~");
  457.     if (constructor || destructor)
  458.       string_appends (&tname, &trawname);
  459.     string_delete(&trawname);
  460.  
  461.     if (!success) {
  462.       string_delete(&tname);
  463.       return 0;
  464.     }
  465.     string_prepends (&decl, &tname);
  466.     string_delete (&tname);
  467.  
  468.     if (static_type)
  469.       {
  470.         string_append (&decl, p+1);
  471.         p += strlen (p);
  472.         success = 1;
  473.       }
  474.     else
  475.       success = do_args (&p, &decl);
  476.     if (const_flag)
  477.       string_append (&decl, " const");
  478.       }
  479.       break;
  480.     }
  481.  
  482.   for (i = 0; i < ntypes; i++)
  483.     if (typevec[i] != NULL)
  484.       free (typevec[i]);
  485.   ntypes = 0;
  486.   if (typevec != NULL)
  487.     {
  488.       free ((char *)typevec);
  489.       typevec = NULL;
  490.       typevec_size = 0;
  491.     }
  492.  
  493.   if (success)
  494.     {
  495.       string_appendn (&decl, "", 1);
  496.       return decl.b;
  497.     }
  498.   else
  499.     {
  500.       string_delete (&decl);
  501.       return NULL;
  502.     }
  503. }
  504.  
  505. static int
  506. get_count (type, count)
  507.      const char **type;
  508.      int *count;
  509. {
  510.   if (!isdigit (**type))
  511.     return 0;
  512.   *count = **type - '0';
  513.   *type += 1;
  514.   /* see flush_repeats in cp-method.c */
  515.   if (isdigit (**type))
  516.     {
  517.       const char *p = *type;
  518.       int n = *count;
  519.       do 
  520.     {
  521.       n *= 10;
  522.       n += *p - '0';
  523.       p += 1;
  524.     } 
  525.       while (isdigit (*p));
  526.       if (*p == '_')
  527.     {
  528.       *type = p + 1;
  529.       *count = n;
  530.     }
  531.     }
  532.   return 1;
  533. }
  534.  
  535. /* result will be initialised here; it will be freed on failure */
  536.  
  537. static int
  538. do_type (type, result)
  539.      const char **type;
  540.      string *result;
  541. {
  542.   int n;
  543.   int done;
  544.   int non_empty = 0;
  545.   int success;
  546.   string decl;
  547.   const char *remembered_type;
  548.  
  549.   string_init (&decl);
  550.   string_init (result);
  551.  
  552.   done = 0;
  553.   success = 1;
  554.   while (success && !done)
  555.     {
  556.       int member;
  557.       switch (**type)
  558.     {
  559.     case 'Q':
  560.       n = (*type)[1] - '0';
  561.       if (n < 0 || n > 9)
  562.         {
  563.           success = 0;
  564.           break;
  565.         }
  566.       *type += 2;
  567.       while (n-- > 0)
  568.         do_type (type, result);
  569.       break;
  570.  
  571.     case 'P':
  572.       *type += 1;
  573.       string_prepend (&decl, "*");
  574.       break;
  575.  
  576.     case 'R':
  577.       *type += 1;
  578.       string_prepend (&decl, "&");
  579.       break;
  580.  
  581.     case 'T':
  582.       *type += 1;
  583.       if (!get_count (type, &n) || n >= ntypes)
  584.         success = 0;
  585.       else
  586.         {
  587.           remembered_type = typevec[n];
  588.           type = &remembered_type;
  589.         }
  590.       break;
  591.  
  592.     case 'F':
  593.       *type += 1;
  594.       if (!string_empty (&decl) && decl.b[0] == '*')
  595.         {
  596.           string_prepend (&decl, "(");
  597.           string_append (&decl, ")");
  598.         }
  599.       if (!do_args (type, &decl) || **type != '_')
  600.         success = 0;
  601.       else
  602.         *type += 1;
  603.       break;
  604.  
  605.     case 'M':
  606.     case 'O':
  607.       {
  608.         int constp = 0;
  609.         int volatilep = 0;
  610.  
  611.         member = **type == 'M';
  612.         *type += 1;
  613.         if (!isdigit (**type))
  614.           {
  615.         success = 0;
  616.         break;
  617.           }
  618.         n = 0;
  619.         do
  620.           {
  621.         n *= 10;
  622.         n += **type - '0';
  623.         *type += 1;
  624.           } 
  625.         while (isdigit (**type));
  626.         if (strlen (*type) < n)
  627.           {
  628.         success = 0;
  629.         break;
  630.           }
  631.         string_append (&decl, ")");
  632.         string_prepend (&decl, "::");
  633.         string_prependn (&decl, *type, n);
  634.         string_prepend (&decl, "(");
  635.         *type += n;
  636.         if (member)
  637.           {
  638.         if (**type == 'C')
  639.           {
  640.             *type += 1;
  641.             constp = 1;
  642.           }
  643.         if (**type == 'V')
  644.           {
  645.             *type += 1;
  646.             volatilep = 1;
  647.           }
  648.         if (*(*type)++ != 'F')
  649.           {
  650.             success = 0;
  651.             break;
  652.           }
  653.           }
  654.         if ((member && !do_args (type, &decl)) || **type != '_')
  655.           {
  656.         success = 0;
  657.         break;
  658.           }
  659.         *type += 1;
  660.         if (constp)
  661.           {
  662.         if (non_empty)
  663.           string_append (&decl, " ");
  664.         else
  665.           non_empty = 1;
  666.         string_append (&decl, "const");
  667.           }
  668.         if (volatilep)
  669.           {
  670.         if (non_empty)
  671.           string_append (&decl, " ");
  672.         else
  673.           non_empty = 1;
  674.         string_append (&decl, "volatile");
  675.           }
  676.         break;
  677.       }
  678.  
  679.     case 'C':
  680.       if ((*type)[1] == 'P')
  681.         {
  682.           *type += 1;
  683.           if (!string_empty (&decl))
  684.         string_prepend (&decl, " ");
  685.           string_prepend (&decl, "const");
  686.           break;
  687.         }
  688.  
  689.       /* fall through */
  690.     default:
  691.       done = 1;
  692.       break;
  693.     }
  694.     }
  695.  
  696.   non_empty = 0;
  697.   if (success)
  698.     success = do_cuv_prefix (type, result, &non_empty);
  699.  
  700.   if (success)
  701.     success = do_builtin_type(type, result, &non_empty);
  702.   
  703.   if (success)
  704.     {
  705.       if (!string_empty (&decl))
  706.     {
  707.       string_append (result, " ");
  708.       string_appends (result, &decl);
  709.     }
  710.       string_delete (&decl);
  711.       return 1;
  712.     }
  713.   else
  714.     {
  715.       string_delete (&decl);
  716.       string_delete (result);
  717.       return 0;
  718.     }
  719. }
  720.  
  721. static int
  722. do_cuv_prefix (type, result, non_empty)
  723.      const char **type;
  724.      string* result;
  725.      int* non_empty;
  726. {
  727.   int success = 1;
  728.   int done = 0;
  729.   
  730.   while (success && !done)
  731.     {
  732.       switch (**type)
  733.     {
  734.     case 'C':
  735.       *type += 1;
  736.       if (*non_empty)
  737.         string_append (result, " ");
  738.       else
  739.         *non_empty = 1;
  740.       string_append (result, "const");
  741.       break;
  742.     case 'U':
  743.       *type += 1;
  744.       if (*non_empty)
  745.         string_append (result, " ");
  746.       else
  747.         *non_empty = 1;
  748.       string_append (result, "unsigned");
  749.       break;
  750.     case 'V':
  751.       *type += 1;
  752.       if (*non_empty)
  753.         string_append (result, " ");
  754.       else
  755.         *non_empty = 1;
  756.       string_append (result, "volatile");
  757.       break;
  758.     default:
  759.       done = 1;
  760.       break;
  761.     }
  762.     }
  763.   return success;
  764. }
  765.  
  766. static int
  767. do_builtin_type (type, result, non_empty)
  768.      const char **type;
  769.      string* result;
  770.      int *non_empty;
  771. {
  772.   int success = 1;
  773.   int n;
  774.   
  775.   switch (**type)
  776.     {
  777.     case '\0':
  778.     case '_':
  779.       break;
  780.     case 'v':
  781.       *type += 1;
  782.       if (*non_empty)
  783.     string_append (result, " ");
  784.       string_append (result, "void");
  785.       break;
  786.     case 'x':
  787.       *type += 1;
  788.       if (*non_empty)
  789.     string_append (result, " ");
  790.       string_append (result, "long long");
  791.       break;
  792.     case 'l':
  793.       *type += 1;
  794.       if (*non_empty)
  795.     string_append (result, " ");
  796.       string_append (result, "long");
  797.       break;
  798.     case 'i':
  799.       *type += 1;
  800.       if (*non_empty)
  801.     string_append (result, " ");
  802.       string_append (result, "int");
  803.       break;
  804.     case 's':
  805.       *type += 1;
  806.       if (*non_empty)
  807.     string_append (result, " ");
  808.       string_append (result, "short");
  809.       break;
  810.     case 'c':
  811.       *type += 1;
  812.       if (*non_empty)
  813.     string_append (result, " ");
  814.       string_append (result, "char");
  815.       break;
  816.     case 'r':
  817.       *type += 1;
  818.       if (*non_empty)
  819.     string_append (result, " ");
  820.       string_append (result, "long double");
  821.       break;
  822.     case 'd':
  823.       *type += 1;
  824.       if (*non_empty)
  825.     string_append (result, " ");
  826.       string_append (result, "double");
  827.       break;
  828.     case 'f':
  829.       *type += 1;
  830.       if (*non_empty)
  831.     string_append (result, " ");
  832.       string_append (result, "float");
  833.       break;
  834.     case 'G':
  835.       *type += 1;
  836.       if (!isdigit (**type))
  837.     {
  838.       success = 0;
  839.       break;
  840.     }
  841.       /* fall through */
  842.     case '0':
  843.     case '1':
  844.     case '2':
  845.     case '3':
  846.     case '4':
  847.     case '5':
  848.     case '6':
  849.     case '7':
  850.     case '8':
  851.     case '9':
  852.       n = 0;
  853.       do
  854.     {
  855.       n *= 10;
  856.       n += **type - '0';
  857.       *type += 1;
  858.     }
  859.       while (isdigit (**type));
  860.       if (strlen (*type) < n)
  861.     {
  862.       success = 0;
  863.       break;
  864.     }
  865.       if (*non_empty)
  866.     string_append (result, " ");
  867.       string_appendn (result, *type, n);
  868.       *type += n;
  869.       break;
  870.     case 't':
  871.       *type += 1;
  872.       /* get template name */
  873.       if (!get_simple_count (type, &n))
  874.     {
  875.       success = 0;
  876.       break;
  877.     }
  878.       if (*non_empty)
  879.     string_append (result, " ");
  880.       string_appendn (result, *type, n);
  881.       *type += n;
  882.       string_append (result, "<");
  883.       if (!do_template_args (type, result))
  884.     success = 0;
  885.       else
  886.     string_append (result, ">");
  887.       break;
  888.     default:
  889.       success = 0;
  890.       break;
  891.     }
  892.   return success;
  893. }
  894.  
  895. static int
  896. do_template_args (type, result)
  897.      const char **type;
  898.      string *result;
  899. {
  900.   int r, i;
  901.  
  902.   string temp;
  903.   int need_comma = 0;
  904.   int success;
  905.  
  906.   /* get size of template parameter list */
  907.   if (!get_count (type, &r))
  908.     return 0;
  909.   success = 1;
  910.   for (i = 0; i < r; i++)
  911.     {
  912.       if (need_comma)
  913.     string_append (result, ", ");
  914.       /* Z for type parameters */
  915.       if (**type == 'Z')
  916.     {
  917.       *type += 1;
  918.  
  919.       success = do_type (type, &temp);
  920.       if (success)
  921.         string_appends (result, &temp);
  922.       string_delete(&temp);
  923.       if (!success)
  924.         break;
  925.     }
  926.       /* otherwise, value parameter */
  927.       else
  928.     {
  929.       const char *old_p  = *type;
  930.       int is_pointer = 0;
  931.       int is_real = 0;
  932.       int is_integral = 0;
  933.       int done = 0;
  934.  
  935.       success = do_type (type, &temp);
  936.       if (success)
  937.         string_appends (result, &temp);
  938.       string_delete(&temp);
  939.       if (!success)
  940.         break;
  941.       string_append (result, "=");
  942.       while (*old_p && !done)
  943.         {    
  944.           switch (*old_p)
  945.         {
  946.         case 'P':
  947.         case 'R':
  948.           done = is_pointer = 1;
  949.           break;
  950.         case 'C':    /* const */
  951.         case 'U':    /* unsigned */
  952.         case 'V':    /* volatile */
  953.         case 'F':    /* function */
  954.         case 'M':    /* member function */
  955.         case 'O':    /* ??? */
  956.           old_p++;
  957.           continue;
  958.         case 'Q':    /* repetition of following */
  959.         case 'T':    /* remembered type */
  960.           abort();
  961.           break;
  962.         case 'v':    /* void */
  963.           abort();
  964.           break;
  965.         case 'x':    /* long long */
  966.         case 'l':    /* long */
  967.         case 'i':    /* int */
  968.         case 's':    /* short */
  969.         case 'c':    /* char */
  970.           done = is_integral = 1;
  971.           break;
  972.         case 'r':    /* long double */
  973.         case 'd':    /* double */
  974.         case 'f':    /* float */
  975.           done = is_real = 1;
  976.           break;
  977.         default:
  978.           abort();
  979.         }
  980.         }
  981.       if (is_integral)
  982.         {
  983.           if (**type == 'm')
  984.         {
  985.           string_appendn (result, "-", 1);
  986.           (*type)++;
  987.         }
  988.           while (isdigit (**type))    
  989.         {
  990.           string_appendn (result, *type, 1);
  991.           (*type)++;
  992.         }
  993.         }
  994.       else if (is_real)
  995.         {
  996.           if (**type == 'm')
  997.         {
  998.           string_appendn (result, "-", 1);
  999.           (*type)++;
  1000.         }
  1001.           while (isdigit (**type))    
  1002.         {
  1003.           string_appendn (result, *type, 1);
  1004.           (*type)++;
  1005.         }
  1006.           if (**type == '.')    /* fraction */
  1007.         {
  1008.           string_appendn (result, ".", 1);
  1009.           (*type)++;
  1010.           while (isdigit (**type))    
  1011.             {
  1012.               string_appendn (result, *type, 1);
  1013.               (*type)++;
  1014.             }
  1015.         }
  1016.           if (**type == 'e')    /* exponent */
  1017.         {
  1018.           string_appendn (result, "e", 1);
  1019.           (*type)++;
  1020.           while (isdigit (**type))    
  1021.             {
  1022.               string_appendn (result, *type, 1);
  1023.               (*type)++;
  1024.             }
  1025.         }
  1026.         }
  1027.       else if (is_pointer)
  1028.         {
  1029.           int symbol_len;
  1030.  
  1031.           if (!get_count (type, &symbol_len))
  1032.         {
  1033.           success = 0;
  1034.           break;
  1035.         }
  1036.           string_appendn (result, *type, symbol_len);
  1037.           *type += symbol_len;
  1038.         }
  1039.     }
  1040.       need_comma = 1;
  1041.     }
  1042.     return success;
  1043.  
  1044. }
  1045.  
  1046. /* `result' will be initialised in do_type; it will be freed on failure */
  1047.  
  1048. static int
  1049. do_arg (type, result)
  1050.      const char **type;
  1051.      string *result;
  1052. {
  1053.   const char *start = *type;
  1054.  
  1055.   if (!do_type (type, result))
  1056.     return 0;
  1057.   remember_type (start, *type - start);
  1058.   return 1;
  1059. }
  1060.  
  1061. static void
  1062. remember_type (start, len)
  1063.      const char *start;
  1064.      int len;
  1065. {
  1066.   char *tem;
  1067.  
  1068.   if (ntypes >= typevec_size)
  1069.     {
  1070.       if (typevec_size == 0)
  1071.     {
  1072.       typevec_size = 3;
  1073.       typevec = (char **) xmalloc (sizeof (char*)*typevec_size);
  1074.     }
  1075.       else
  1076.     {
  1077.       typevec_size *= 2;
  1078.       typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size);
  1079.     }
  1080.     }
  1081.   tem = (char *) xmalloc (len + 1);
  1082.   memcpy (tem, start, len);
  1083.   tem[len] = '\0';
  1084.   typevec[ntypes++] = tem;
  1085. }
  1086.  
  1087. /* `decl' must be already initialised, usually non-empty;
  1088.    it won't be freed on failure */
  1089.  
  1090. static int
  1091. do_args (type, decl)
  1092.      const char **type;
  1093.      string *decl;
  1094. {
  1095.   string arg;
  1096.   int need_comma = 0;
  1097.  
  1098.   string_append (decl, "(");
  1099.  
  1100.   while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
  1101.     {
  1102.       if (**type == 'N')
  1103.     {
  1104.       int r;
  1105.       int t;
  1106.       *type += 1;
  1107.       if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
  1108.         return 0;
  1109.       while (--r >= 0)
  1110.         {
  1111.           const char *tem = typevec[t];
  1112.           if (need_comma)
  1113.         string_append (decl, ", ");
  1114.           if (!do_arg (&tem, &arg))
  1115.         return 0;
  1116.           string_appends (decl, &arg);
  1117.           string_delete (&arg);
  1118.           need_comma = 1;
  1119.         }
  1120.     }
  1121.       else
  1122.     {
  1123.       if (need_comma)
  1124.         string_append (decl, ", ");
  1125.       if (!do_arg (type, &arg))
  1126.         return 0;
  1127.       string_appends (decl, &arg);
  1128.       string_delete (&arg);
  1129.       need_comma = 1;
  1130.     }
  1131.     }
  1132.  
  1133.   if (**type == 'v')
  1134.     *type += 1;
  1135.   else if (**type == 'e')
  1136.     {
  1137.       *type += 1;
  1138.       if (need_comma)
  1139.     string_append (decl, ",");
  1140.       string_append (decl, "...");
  1141.     }
  1142.  
  1143.   string_append (decl, ")");
  1144.   return 1;
  1145. }
  1146.  
  1147. static void
  1148. munge_function_name (name)
  1149.      string *name;
  1150. {
  1151.   if (string_empty (name))
  1152.     return;
  1153.  
  1154.   if (name->p - name->b >= 3 
  1155.       && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == CPLUS_MARKER)
  1156.     {
  1157.       int i;
  1158.       /* see if it's an assignment expression */
  1159.       if (name->p - name->b >= 10 /* op$assign_ */
  1160.       && memcmp (name->b + 3, "assign_", 7) == 0)
  1161.     {
  1162.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1163.         {
  1164.           int len = name->p - name->b - 10;
  1165.           if (strlen (optable[i].in) == len
  1166.           && memcmp (optable[i].in, name->b + 10, len) == 0)
  1167.         {
  1168.           string_clear (name);
  1169.           string_append (name, "operator");
  1170.           string_append (name, optable[i].out);
  1171.           string_append (name, "=");
  1172.           return;
  1173.         }
  1174.         }
  1175.     }
  1176.       else
  1177.     {
  1178.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1179.         {
  1180.           int len = name->p - name->b - 3;
  1181.           if (strlen (optable[i].in) == len 
  1182.           && memcmp (optable[i].in, name->b + 3, len) == 0)
  1183.         {
  1184.           string_clear (name);
  1185.           string_append (name, "operator");
  1186.           string_append (name, optable[i].out);
  1187.           return;
  1188.         }
  1189.         }
  1190.     }
  1191.       return;
  1192.     }
  1193.   else if (name->p - name->b >= 5 && memcmp (name->b, "type$", 5) == 0)
  1194.     {
  1195.       /* type conversion operator */
  1196.       string type;
  1197.       const char *tem = name->b + 5;
  1198.       if (do_type (&tem, &type))
  1199.     {
  1200.       string_clear (name);
  1201.       string_append (name, "operator ");
  1202.       string_appends (name, &type);
  1203.       string_delete (&type);
  1204.       return;
  1205.     }
  1206.     }
  1207.   /* ANSI.  */
  1208.   else if (name->b[2] == 'o' && name->b[3] == 'p')
  1209.     {
  1210.       /* type conversion operator.  */
  1211.       string type;
  1212.       const char *tem = name->b + 4;
  1213.       if (do_type (&tem, &type))
  1214.     {
  1215.       string_clear (name);
  1216.       string_append (name, "operator ");
  1217.       string_appends (name, &type);
  1218.       string_delete (&type);
  1219.       return;
  1220.     }
  1221.     }
  1222.   else if (name->b[2] >= 'a' && name->b[2] <= 'z'
  1223.        && name->b[3] >= 'a' && name->b[3] <= 'z')
  1224.     {
  1225.       int i;
  1226.  
  1227.       if (name->b[4] == '\0')
  1228.     {
  1229.       /* Operator.  */
  1230.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1231.         {
  1232.           if (strlen (optable[i].in) == 2
  1233.           && memcmp (optable[i].in, name->b + 2, 2) == 0)
  1234.         {
  1235.           string_clear (name);
  1236.           string_append (name, "operator");
  1237.           string_append (name, optable[i].out);
  1238.           return;
  1239.         }
  1240.         }
  1241.     }
  1242.       else
  1243.     {
  1244.       if (name->b[2] != 'a' || name->b[5] != '\0')
  1245.         return;
  1246.       /* Assignment.  */
  1247.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1248.         {
  1249.           if (strlen (optable[i].in) == 3
  1250.           && memcmp (optable[i].in, name->b + 2, 3) == 0)
  1251.         {
  1252.           string_clear (name);
  1253.           string_append (name, "operator");
  1254.           string_append (name, optable[i].out);
  1255.           return;
  1256.         }
  1257.         }
  1258.     }
  1259.     }
  1260. }
  1261.  
  1262. /* a mini string-handling package */
  1263.  
  1264. static void
  1265. string_need (s, n)
  1266.      string *s;
  1267.      int n;
  1268. {
  1269.   if (s->b == NULL)
  1270.     {
  1271.       if (n < 32)
  1272.     n = 32;
  1273.       s->p = s->b = (char *) xmalloc (n);
  1274.       s->e = s->b + n;
  1275.     }
  1276.   else if (s->e - s->p < n)
  1277.     {
  1278.       int tem = s->p - s->b;
  1279.       n += tem;
  1280.       n *= 2;
  1281.       s->b = (char *) xrealloc (s->b, n);
  1282.       s->p = s->b + tem;
  1283.       s->e = s->b + n;
  1284.     }
  1285. }
  1286.  
  1287. static void
  1288. string_delete (s)
  1289.      string *s;
  1290. {
  1291.   if (s->b != NULL)
  1292.     {
  1293.       free (s->b);
  1294.       s->b = s->e = s->p = NULL;
  1295.     }
  1296. }
  1297.  
  1298. static void
  1299. string_init (s)
  1300.      string *s;
  1301. {
  1302.   s->b = s->p = s->e = NULL;
  1303. }
  1304.  
  1305. static void 
  1306. string_clear (s)
  1307.      string *s;
  1308. {
  1309.   s->p = s->b;
  1310. }
  1311.  
  1312. static int
  1313. string_empty (s)
  1314.      string *s;
  1315. {
  1316.   return s->b == s->p;
  1317. }
  1318.  
  1319. static void
  1320. string_append (p, s)
  1321.      string *p;
  1322.      const char *s;
  1323. {
  1324.   int n;
  1325.   if (s == NULL || *s == '\0')
  1326.     return;
  1327.   n = strlen (s);
  1328.   string_need (p, n);
  1329.   memcpy (p->p, s, n);
  1330.   p->p += n;
  1331. }
  1332.  
  1333. static void
  1334. string_appends (p, s)
  1335.      string *p, *s;
  1336. {
  1337.   int n;
  1338.   if (s->b == s->p)
  1339.     return;
  1340.   n = s->p - s->b;
  1341.   string_need (p, n);
  1342.   memcpy (p->p, s->b, n);
  1343.   p->p += n;
  1344. }
  1345.  
  1346. static void
  1347. string_appendn (p, s, n)
  1348.      string *p;
  1349.      const char *s;
  1350.      int n;
  1351. {
  1352.   if (n == 0)
  1353.     return;
  1354.   string_need (p, n);
  1355.   memcpy (p->p, s, n);
  1356.   p->p += n;
  1357. }
  1358.  
  1359. static void
  1360. string_prepend (p, s)
  1361.      string *p;
  1362.      const char *s;
  1363. {
  1364.   if (s == NULL || *s == '\0')
  1365.     return;
  1366.   string_prependn (p, s, strlen (s));
  1367. }
  1368.  
  1369. static void
  1370. string_prepends (p, s)
  1371.      string *p, *s;
  1372. {
  1373.   if (s->b == s->p)
  1374.     return;
  1375.   string_prependn (p, s->b, s->p - s->b);
  1376. }
  1377.  
  1378. static void
  1379. string_prependn (p, s, n)
  1380.      string *p;
  1381.      const char *s;
  1382.      int n;
  1383. {
  1384.   char *q;
  1385.  
  1386.   if (n == 0)
  1387.     return;
  1388.   string_need (p, n);
  1389.   for (q = p->p - 1; q >= p->b; q--)
  1390.     q[n] = q[0];
  1391.   memcpy (p->b, s, n);
  1392.   p->p += n;
  1393. }
  1394.