Annotation of gcc/cp-dem.c, revision 1.1.1.2

1.1       root        1: /* Demangler for GNU C++ 
                      2:    Copyright (C) 1989, 1992 Free Software Foundation, Inc.
                      3:    written by James Clark ([email protected])
                      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: 
1.1.1.2 ! root       26:    Modified for g++ 1.95.03 (November 13 version).  */
1.1       root       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=) */
1.1.1.2 ! root      168:   "as", "=",                   /* ansi */
1.1       root      169: };
                    170: 
                    171: /* Beware: these aren't '\0' terminated. */
                    172: 
                    173: typedef struct {
                    174:   char *b;                     /* pointer to start of string */
                    175:   char *p;                     /* pointer after last character */
                    176:   char *e;                     /* pointer after end of allocated space */
                    177: } string;
                    178: 
                    179: #ifdef __STDC__
                    180: static void string_need (string *s, int n);
                    181: static void string_delete (string *s);
                    182: static void string_init (string *s);
                    183: static void string_clear (string *s);
                    184: static int string_empty (string *s);
                    185: static void string_append (string *p, const char *s);
                    186: static void string_appends (string *p, string *s);
                    187: static void string_appendn (string *p, const char *s, int n);
                    188: static void string_prepend (string *p, const char *s);
                    189: #if 0
                    190: static void string_prepends (string *p, string *s);
                    191: #endif
                    192: static void string_prependn (string *p, const char *s, int n);
                    193: static int get_count (const char **type, int *count);
                    194: static int do_args (const char **type, string *decl);
                    195: static int do_type (const char **type, string *result);
                    196: static int do_arg (const char **type, string *result);
                    197: static int do_args (const char **type, string *decl);
                    198: static void munge_function_name (string *name);
                    199: static void remember_type (const char *type, int len);
                    200: #else
                    201: static void string_need ();
                    202: static void string_delete ();
                    203: static void string_init ();
                    204: static void string_clear ();
                    205: static int string_empty ();
                    206: static void string_append ();
                    207: static void string_appends ();
                    208: static void string_appendn ();
                    209: static void string_prepend ();
                    210: static void string_prepends ();
                    211: static void string_prependn ();
                    212: static int get_count ();
                    213: static int do_args ();
                    214: static int do_type ();
                    215: static int do_arg ();
                    216: static int do_args ();
                    217: static void munge_function_name ();
                    218: static void remember_type ();
                    219: #endif
                    220: 
                    221: int
                    222: get_simple_count (type, res)
                    223:      char **type;
                    224:      int *res;
                    225: {
                    226:   int n = 0, success = 1;;
                    227:   
                    228:   do
                    229:     {
                    230:       n *= 10;
                    231:       n += **type - '0';
                    232:       *type += 1;
                    233:     } 
                    234:   while (isdigit (**type));
                    235:   if (strlen (*type) < n)
                    236:     {
                    237:       success = 0;
                    238:     }
                    239: 
                    240:   *res = n;
                    241:   return success;
                    242: }
                    243: 
                    244: char *
                    245: cplus_demangle (type)
                    246:      const char *type;
                    247: {
                    248:   string decl;
                    249:   int n;
                    250:   int success = 0;
                    251:   int constructor = 0;
                    252:   int destructor = 0;
                    253:   int static_type = 0;
                    254:   int const_flag = 0;
                    255:   int i;
                    256:   const char *p;
                    257: #ifndef LONGERNAMES
                    258:   const char *premangle;
                    259: #endif
                    260: 
                    261:   if (type == NULL || *type == '\0')
                    262:     return NULL;
                    263: #ifndef nounderscore
                    264:   if (*type++ != '_')
                    265:     return NULL;
                    266: #endif
                    267:   p = type;
                    268:   while (*p != '\0' && !(*p == '_' && p[1] == '_'))
                    269:     p++;
                    270:   if (*p == '\0')
                    271:     {
                    272:       /* destructor */
                    273:       if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
                    274:        {
                    275:          destructor = 1;
                    276:          p = type;
                    277:        }
                    278:       /* static data member */
                    279:       else if (*type != '_' && (strchr (type, CPLUS_MARKER) != NULL))
                    280:        {
                    281:          static_type = 1;
                    282:          p = type;
                    283:        }
                    284:       /* virtual table "_vt$"  */
                    285:       else if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
                    286:        {
                    287:          int n = strlen (type + 4) + 14 + 1;
                    288:          char *tem = (char *) xmalloc (n);
                    289:          strcpy (tem, type + 4);
                    290:          strcat (tem, " virtual table");
                    291:          return tem;
                    292:        }
                    293:       else return NULL;
                    294:     }
                    295: 
                    296:   string_init (&decl);
                    297: 
                    298:   if (static_type)
                    299:     {
                    300:       if (!isdigit (p[0]) && ('t' != p[0]))
                    301:        {
                    302:          string_delete (&decl);
                    303:          return NULL;
                    304:        }
                    305:     }
                    306:   else if (destructor)
                    307:     {
                    308:       if (!isdigit (p[3])&& ('t' != p[3]))
                    309:        {
                    310:          string_delete (&decl);
                    311:          return NULL;
                    312:        }
                    313:       p += 3;
                    314:     }
                    315:   else if (p == type)
                    316:     {
                    317:       if (!isdigit (p[2]) && ('t' != p[2]))
                    318:        {
                    319:          p += 1;
                    320:          while (*p != '\0' && !(*p == '_' && p[1] == '_'))
                    321:            p++;
                    322:          string_appendn (&decl, type, p - type);         
                    323:          string_appendn (&decl, "", 1);
                    324:          munge_function_name (&decl);
                    325:          if (decl.b[0] == '_')
                    326:            {
                    327:              string_delete (&decl);
                    328:              return NULL;
                    329:            }
                    330:          else
                    331:            p += 2;
                    332:        }
                    333:       else
                    334:        {
                    335:          constructor = 1;
                    336:          p += 2;
                    337:        }
                    338:     }
                    339:   else
                    340:     {
                    341:       string_appendn (&decl, type, p - type);
                    342:       decl.p[0] = '0';
                    343:       munge_function_name (&decl);
                    344:       p += 2;
                    345:     }
                    346: 
                    347: #ifndef LONGERNAMES
                    348:   premangle = p;
                    349: #endif
                    350:   switch (*p)
                    351:     {
                    352:     case 'C':
                    353:       /* a const member function */
                    354:       if (!isdigit (p[1]))
                    355:        {
                    356:          string_delete (&decl);
                    357:          return NULL;
                    358:        }
                    359:       p += 1;
                    360:       const_flag = 1;
                    361:       /* fall through */
                    362:     case '0':
                    363:     case '1':
                    364:     case '2':
                    365:     case '3':
                    366:     case '4':
                    367:     case '5':
                    368:     case '6':
                    369:     case '7':
                    370:     case '8':
                    371:     case '9':
                    372:       n = 0;
                    373:       do
                    374:        {
                    375:          n *= 10;
                    376:          n += *p - '0';
                    377:          p += 1;
                    378:        }
                    379:       while (isdigit (*p));
                    380:       if (strlen (p) < n)
                    381:        {
                    382:          string_delete (&decl);
                    383:          return NULL;
                    384:        }
                    385:       if (constructor || destructor)
                    386:        {
                    387:          string_appendn (&decl, p, n);
                    388:          string_append (&decl, "::");
                    389:          if (destructor)
                    390:            string_append(&decl, "~");
                    391:          string_appendn (&decl, p, n);
                    392:        }
                    393:       else
                    394:        {
                    395:          string_prepend (&decl, "::");
                    396:          string_prependn (&decl, p, n);
                    397:        }
                    398:       p += n;
                    399: #ifndef LONGERNAMES
                    400:       remember_type (premangle, p - premangle);
                    401: #endif
                    402:       if (static_type)
                    403:        {
                    404:          string_append(&decl, p+1);
                    405:          p += strlen(p);
                    406:          success = 1;
                    407:        }
                    408:       else
                    409:        success = do_args (&p, &decl);
                    410:       if (const_flag)
                    411:        string_append (&decl, " const");
                    412:       break;
                    413:     case 'F':
                    414:       p += 1;
                    415:       success = do_args (&p, &decl);
                    416:       break;
                    417:     /* template additions */
                    418:     case 't':
                    419:       p += 1;
                    420:       {
                    421:        int r, i;
                    422:        int non_empty = 0;
                    423:        string tname;
                    424:        string trawname;
                    425:        
                    426:        string temp;
                    427:        int need_comma = 0;
                    428:        
                    429:        string_init(&tname);
                    430:        string_init(&trawname);
                    431:        
                    432:        /* get template name */
                    433:        if (!get_simple_count (&p, &r))
                    434:          {
                    435:            string_delete (&decl);
                    436:            return 0;
                    437:          }
                    438:        string_appendn (&tname, p, r);
                    439:        string_appendn (&trawname, p, r);
                    440:        string_appendn (&trawname, "", 1);
                    441:        p += r;
                    442:        string_append (&tname, "<");
                    443:        /* get size of template parameter list */
                    444:        if (!get_count (&p, &r))
                    445:          return 0;
                    446:        for (i = 0; i < r; i++)
                    447:          {
                    448:            if (need_comma)
                    449:              string_append (&tname, ", ");
                    450:            /* Z for type parameters */
                    451:            if (*p == 'Z')
                    452:              {
                    453:                p += 1;
                    454:                
                    455:                success = do_type (&p, &temp);
                    456:                string_appendn (&temp, "", 1);
                    457:                if (success)
                    458:                  string_append (&tname, temp.b);
                    459:                string_delete(&temp);
                    460:                if (!success)
                    461:                  break;
                    462:              }
                    463:            /* otherwise, value parameter */
                    464:            else
                    465:              {
                    466:                const char *old_p  = p;
                    467:                int is_pointer = 0;
                    468:                int is_real = 0;
                    469:                int is_integral = 0;
                    470:                int done = 0;
                    471: 
                    472:                success = do_type (&p, &temp);
                    473:                string_appendn (&temp, "", 1);
                    474:                if (success)
                    475:                  string_append (&tname, temp.b);
                    476:                string_delete(&temp);
                    477:                if (!success)
                    478:                  break;
                    479:                string_append (&tname, "=");
                    480:                while (*old_p && !done)
                    481:                  {     
                    482:                    switch (*old_p)
                    483:                      {
                    484:                      case 'P':
                    485:                      case 'R':
                    486:                        done = is_pointer = 1;
                    487:                        break;
                    488:                      case 'C': /* const */
                    489:                      case 'U': /* unsigned */
                    490:                      case 'V': /* volatile */
                    491:                      case 'F': /* function */
                    492:                      case 'M': /* member function */
                    493:                      case 'O': /* ??? */
                    494:                        old_p++;
                    495:                        continue;
                    496:                      case 'Q': /* repetition of following */
                    497:                      case 'T': /* remembered type */
                    498:                        abort();
                    499:                        break;
                    500:                      case 'v': /* void */
                    501:                        abort();
                    502:                        break;
                    503:                      case 'x': /* long long */
                    504:                      case 'l': /* long */
                    505:                      case 'i': /* int */
                    506:                      case 's': /* short */
                    507:                      case 'c': /* char */
                    508:                        done = is_integral = 1;
                    509:                        break;
                    510:                      case 'r': /* long double */
                    511:                      case 'd': /* double */
                    512:                      case 'f': /* float */
                    513:                        done = is_real = 1;
                    514:                        break;
                    515:                      default:
                    516:                        abort();
                    517:                      }
                    518:                  }
                    519:                if (is_integral)
                    520:                  {
                    521:                    if (*p == 'm')
                    522:                      {
                    523:                        string_appendn (&tname, "-", 1);
                    524:                        p++;
                    525:                      }
                    526:                    while (isdigit (*p))        
                    527:                      {
                    528:                        string_appendn (&tname, p, 1);
                    529:                        p++;
                    530:                      }
                    531:                  }
                    532:                else if (is_real)
                    533:                  {
                    534:                    if (*p == 'm')
                    535:                      {
                    536:                        string_appendn (&tname, "-", 1);
                    537:                        p++;
                    538:                      }
                    539:                    while (isdigit (*p))        
                    540:                      {
                    541:                        string_appendn (&tname, p, 1);
                    542:                        p++;
                    543:                      }
                    544:                    if (*p == '.') /* fraction */
                    545:                      {
                    546:                        string_appendn (&tname, ".", 1);
                    547:                        p++;
                    548:                        while (isdigit (*p))    
                    549:                          {
                    550:                            string_appendn (&tname, p, 1);
                    551:                            p++;
                    552:                          }
                    553:                      }
                    554:                    if (*p == 'e') /* exponent */
                    555:                      {
                    556:                        string_appendn (&tname, "e", 1);
                    557:                        p++;
                    558:                        while (isdigit (*p))    
                    559:                          {
                    560:                            string_appendn (&tname, p, 1);
                    561:                            p++;
                    562:                          }
                    563:                      }
                    564:                  }
                    565:                else if (is_pointer)
                    566:                  {
                    567:                    int symbol_len;
                    568:                    
                    569:                    if (!get_count (&p, &symbol_len))
                    570:                      {
                    571:                        success = 0;
                    572:                        break;
                    573:                      }
                    574:                    string_appendn (&tname, p, symbol_len);
                    575:                    p += symbol_len;
                    576:                  }
                    577:              }
                    578:            need_comma = 1;
                    579:          }
                    580:        string_append (&tname, ">::");
                    581:        if (destructor)
                    582:          string_append(&tname, "~");
                    583:        if (constructor || destructor) {
                    584:          string_appendn (&trawname, "", 1);
                    585:          string_append (&tname, trawname.b);
                    586:        }
                    587:        string_delete(&trawname);
                    588:        
                    589:        if (!success) {
                    590:          string_delete(&tname);
                    591:          return 0;
                    592:        }
                    593:        string_appendn (&tname, "", 1);
                    594:        string_prepend (&decl, tname.b);
                    595:        string_delete (&tname);
                    596: 
                    597:        if (static_type)
                    598:          {
                    599:            string_append (&decl, p+1);
                    600:            p += strlen (p);
                    601:            success = 1;
                    602:          }
                    603:        else
                    604:          success = do_args (&p, &decl);
                    605:        break;
                    606:       }
                    607:     }
                    608: 
                    609:   for (i = 0; i < ntypes; i++)
                    610:     if (typevec[i] != NULL)
                    611:       free (typevec[i]);
                    612:   ntypes = 0;
                    613:   if (typevec != NULL)
                    614:     {
                    615:       free ((char *)typevec);
                    616:       typevec = NULL;
                    617:       typevec_size = 0;
                    618:     }
                    619: 
                    620:   if (success)
                    621:     {
                    622:       string_appendn (&decl, "", 1);
                    623:       return decl.b;
                    624:     }
                    625:   else
                    626:     {
                    627:       string_delete (&decl);
                    628:       return NULL;
                    629:     }
                    630: }
                    631: 
                    632: static int
                    633: get_count (type, count)
                    634:      const char **type;
                    635:      int *count;
                    636: {
                    637:   if (!isdigit (**type))
                    638:     return 0;
                    639:   *count = **type - '0';
                    640:   *type += 1;
                    641:   /* see flush_repeats in cp-method.c */
                    642:   if (isdigit (**type))
                    643:     {
                    644:       const char *p = *type;
                    645:       int n = *count;
                    646:       do 
                    647:        {
                    648:          n *= 10;
                    649:          n += *p - '0';
                    650:          p += 1;
                    651:        } 
                    652:       while (isdigit (*p));
                    653:       if (*p == '_')
                    654:        {
                    655:          *type = p + 1;
                    656:          *count = n;
                    657:        }
                    658:     }
                    659:   return 1;
                    660: }
                    661: 
                    662: /* result will be initialised here; it will be freed on failure */
                    663: 
                    664: static int
                    665: do_type (type, result)
                    666:      const char **type;
                    667:      string *result;
                    668: {
                    669:   int n;
                    670:   int done;
                    671:   int non_empty = 0;
                    672:   int success;
                    673:   string decl;
                    674:   const char *remembered_type;
                    675: 
                    676:   string_init (&decl);
                    677:   string_init (result);
                    678: 
                    679:   done = 0;
                    680:   success = 1;
                    681:   while (success && !done)
                    682:     {
                    683:       int member;
                    684:       switch (**type)
                    685:        {
                    686:        case 'Q':
                    687:          n = (*type)[1] - '0';
                    688:          if (n < 0 || n > 9)
                    689:            success = 0;
                    690:          *type += 2;
                    691:          while (n-- > 0)
                    692:            do_type (type, result);
                    693:          break;
                    694: 
                    695:        case 'P':
                    696:          *type += 1;
                    697:          string_prepend (&decl, "*");
                    698:          break;
                    699: 
                    700:        case 'R':
                    701:          *type += 1;
                    702:          string_prepend (&decl, "&");
                    703:          break;
                    704: 
                    705:        case 'T':
                    706:          *type += 1;
                    707:          if (!get_count (type, &n) || n >= ntypes)
                    708:            success = 0;
                    709:          else
                    710:            {
                    711:              remembered_type = typevec[n];
                    712:              type = &remembered_type;
                    713:            }
                    714:          break;
                    715: 
                    716:        case 'F':
                    717:          *type += 1;
                    718:          if (!string_empty (&decl) && decl.b[0] == '*')
                    719:            {
                    720:              string_prepend (&decl, "(");
                    721:              string_append (&decl, ")");
                    722:            }
                    723:          if (!do_args (type, &decl) || **type != '_')
                    724:            success = 0;
                    725:          else
                    726:            *type += 1;
                    727:          break;
                    728: 
                    729:        case 'M':
                    730:        case 'O':
                    731:          {
                    732:            int constp = 0;
                    733:            int volatilep = 0;
                    734: 
                    735:            member = **type == 'M';
                    736:            *type += 1;
                    737:            if (!isdigit (**type))
                    738:              {
                    739:                success = 0;
                    740:                break;
                    741:              }
                    742:            n = 0;
                    743:            do
                    744:              {
                    745:                n *= 10;
                    746:                n += **type - '0';
                    747:                *type += 1;
                    748:              } 
                    749:            while (isdigit (**type));
                    750:            if (strlen (*type) < n)
                    751:              {
                    752:                success = 0;
                    753:                break;
                    754:              }
                    755:            string_append (&decl, ")");
                    756:            string_prepend (&decl, "::");
                    757:            string_prependn (&decl, *type, n);
                    758:            string_prepend (&decl, "(");
                    759:            *type += n;
                    760:            if (member)
                    761:              {
                    762:                if (**type == 'C')
                    763:                  {
                    764:                    *type += 1;
                    765:                    constp = 1;
                    766:                  }
                    767:                if (**type == 'V')
                    768:                  {
                    769:                    *type += 1;
                    770:                    volatilep = 1;
                    771:                  }
                    772:                if (*(*type)++ != 'F')
                    773:                  {
                    774:                    success = 0;
                    775:                    break;
                    776:                  }
                    777:              }
                    778:            if ((member && !do_args (type, &decl)) || **type != '_')
                    779:              {
                    780:                success = 0;
                    781:                break;
                    782:              }
                    783:            *type += 1;
                    784:            if (constp)
                    785:              {
                    786:                if (non_empty)
                    787:                  string_append (&decl, " ");
                    788:                else
                    789:                  non_empty = 1;
                    790:                string_append (&decl, "const");
                    791:              }
                    792:            if (volatilep)
                    793:              {
                    794:                if (non_empty)
                    795:                  string_append (&decl, " ");
                    796:                else
                    797:                  non_empty = 1;
                    798:                string_append (&decl, "volatile");
                    799:              }
                    800:            break;
                    801:          }
                    802: 
                    803:        case 'C':
                    804:          if ((*type)[1] == 'P')
                    805:            {
                    806:              *type += 1;
                    807:              if (!string_empty (&decl))
                    808:                string_prepend (&decl, " ");
                    809:              string_prepend (&decl, "const");
                    810:              break;
                    811:            }
                    812: 
                    813:          /* fall through */
                    814:        default:
                    815:          done = 1;
                    816:          break;
                    817:        }
                    818:     }
                    819: 
                    820:   non_empty = 0;
                    821:   if (success)
                    822:     success = do_cuv_prefix (type, result, &non_empty);
                    823: 
                    824:   if (success)
                    825:     success = do_builtin_type(type, result, &non_empty);
                    826:   
                    827:   if (success)
                    828:     {
                    829:       if (!string_empty (&decl))
                    830:        {
                    831:          string_append (result, " ");
                    832:          string_appends (result, &decl);
                    833:        }
                    834:       string_delete (&decl);
                    835:       return 1;
                    836:     }
                    837:   else
                    838:     {
                    839:       string_delete (&decl);
                    840:       string_delete (result);
                    841:       return 0;
                    842:     }
                    843: }
                    844: 
                    845: int
                    846: do_cuv_prefix (type, result, non_empty)
                    847:      char **type;
                    848:      string* result;
                    849:      int* non_empty;
                    850: {
                    851:   int success = 1;
                    852:   int done = 0;
                    853:   
                    854:   while (success && !done)
                    855:     {
                    856:       switch (**type)
                    857:        {
                    858:        case 'C':
                    859:          *type += 1;
                    860:          if (*non_empty)
                    861:            string_append (result, " ");
                    862:          else
                    863:            *non_empty = 1;
                    864:          string_append (result, "const");
                    865:          break;
                    866:        case 'U':
                    867:          *type += 1;
                    868:          if (*non_empty)
                    869:            string_append (result, " ");
                    870:          else
                    871:            *non_empty = 1;
                    872:          string_append (result, "unsigned");
                    873:          break;
                    874:        case 'V':
                    875:          *type += 1;
                    876:          if (*non_empty)
                    877:            string_append (result, " ");
                    878:          else
                    879:            *non_empty = 1;
                    880:          string_append (result, "volatile");
                    881:          break;
                    882:        default:
                    883:          done = 1;
                    884:          break;
                    885:        }
                    886:     }
                    887:   return success;
                    888: }
                    889: 
                    890: int
                    891: do_builtin_type (type, result, non_empty)
                    892:      char **type;
                    893:      string* result;
                    894:      int *non_empty;
                    895: {
                    896:   int success = 1;
                    897:   int n;
                    898:   
                    899:   switch (**type)
                    900:     {
                    901:     case '\0':
                    902:     case '_':
                    903:       break;
                    904:     case 'v':
                    905:       *type += 1;
                    906:       if (*non_empty)
                    907:        string_append (result, " ");
                    908:       string_append (result, "void");
                    909:       break;
                    910:     case 'x':
                    911:       *type += 1;
                    912:       if (*non_empty)
                    913:        string_append (result, " ");
                    914:       string_append (result, "long long");
                    915:       break;
                    916:     case 'l':
                    917:       *type += 1;
                    918:       if (*non_empty)
                    919:        string_append (result, " ");
                    920:       string_append (result, "long");
                    921:       break;
                    922:     case 'i':
                    923:       *type += 1;
                    924:       if (*non_empty)
                    925:        string_append (result, " ");
                    926:       string_append (result, "int");
                    927:       break;
                    928:     case 's':
                    929:       *type += 1;
                    930:       if (*non_empty)
                    931:        string_append (result, " ");
                    932:       string_append (result, "short");
                    933:       break;
                    934:     case 'c':
                    935:       *type += 1;
                    936:       if (*non_empty)
                    937:        string_append (result, " ");
                    938:       string_append (result, "char");
                    939:       break;
                    940:     case 'r':
                    941:       *type += 1;
                    942:       if (*non_empty)
                    943:        string_append (result, " ");
                    944:       string_append (result, "long double");
                    945:       break;
                    946:     case 'd':
                    947:       *type += 1;
                    948:       if (*non_empty)
                    949:        string_append (result, " ");
                    950:       string_append (result, "double");
                    951:       break;
                    952:     case 'f':
                    953:       *type += 1;
                    954:       if (*non_empty)
                    955:        string_append (result, " ");
                    956:       string_append (result, "float");
                    957:       break;
                    958:     case 'G':
                    959:       *type += 1;
                    960:       if (!isdigit (**type))
                    961:        {
                    962:          success = 0;
                    963:          break;
                    964:        }
                    965:       /* fall through */
                    966:     case '0':
                    967:     case '1':
                    968:     case '2':
                    969:     case '3':
                    970:     case '4':
                    971:     case '5':
                    972:     case '6':
                    973:     case '7':
                    974:     case '8':
                    975:     case '9':
                    976:       n = 0;
                    977:       do
                    978:        {
                    979:          n *= 10;
                    980:          n += **type - '0';
                    981:          *type += 1;
                    982:        }
                    983:       while (isdigit (**type));
                    984:       if (strlen (*type) < n)
                    985:        {
                    986:          success = 0;
                    987:          break;
                    988:        }
                    989:       if (*non_empty)
                    990:        string_append (result, " ");
                    991:       string_appendn (result, *type, n);
                    992:       *type += n;
                    993:       break;
                    994:     default:
                    995:       success = 0;
                    996:       break;
                    997:     }
                    998:   return success;
                    999: }
                   1000: 
                   1001: /* `result' will be initialised in do_type; it will be freed on failure */
                   1002: 
                   1003: static int
                   1004: do_arg (type, result)
                   1005:      const char **type;
                   1006:      string *result;
                   1007: {
                   1008:   const char *start = *type;
                   1009: 
                   1010:   if (!do_type (type, result))
                   1011:     return 0;
                   1012:   remember_type (start, *type - start);
                   1013:   return 1;
                   1014: }
                   1015: 
                   1016: static void
                   1017: remember_type (start, len)
                   1018:      const char *start;
                   1019:      int len;
                   1020: {
                   1021:   char *tem;
                   1022: 
                   1023:   if (ntypes >= typevec_size)
                   1024:     {
                   1025:       if (typevec_size == 0)
                   1026:        {
                   1027:          typevec_size = 3;
                   1028:          typevec = (char **) xmalloc (sizeof (char*)*typevec_size);
                   1029:        }
                   1030:       else
                   1031:        {
                   1032:          typevec_size *= 2;
                   1033:          typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size);
                   1034:        }
                   1035:     }
                   1036:   tem = (char *) xmalloc (len + 1);
                   1037:   memcpy (tem, start, len);
                   1038:   tem[len] = '\0';
                   1039:   typevec[ntypes++] = tem;
                   1040: }
                   1041: 
                   1042: /* `decl' must be already initialised, usually non-empty;
                   1043:    it won't be freed on failure */
                   1044: 
                   1045: static int
                   1046: do_args (type, decl)
                   1047:      const char **type;
                   1048:      string *decl;
                   1049: {
                   1050:   string arg;
                   1051:   int need_comma = 0;
                   1052: 
                   1053:   string_append (decl, "(");
                   1054: 
                   1055:   while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
                   1056:     {
                   1057:       if (**type == 'N')
                   1058:        {
                   1059:          int r;
                   1060:          int t;
                   1061:          *type += 1;
                   1062:          if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
                   1063:            return 0;
                   1064:          while (--r >= 0)
                   1065:            {
                   1066:              const char *tem = typevec[t];
                   1067:              if (need_comma)
                   1068:                string_append (decl, ", ");
                   1069:              if (!do_arg (&tem, &arg))
                   1070:                return 0;
                   1071:              string_appends (decl, &arg);
                   1072:              string_delete (&arg);
                   1073:              need_comma = 1;
                   1074:            }
                   1075:        }
                   1076:       else
                   1077:        {
                   1078:          if (need_comma)
                   1079:            string_append (decl, ", ");
                   1080:          if (!do_arg (type, &arg))
                   1081:            return 0;
                   1082:          string_appends (decl, &arg);
                   1083:          string_delete (&arg);
                   1084:          need_comma = 1;
                   1085:        }
                   1086:     }
                   1087: 
                   1088:   if (**type == 'v')
                   1089:     *type += 1;
                   1090:   else if (**type == 'e')
                   1091:     {
                   1092:       *type += 1;
                   1093:       if (need_comma)
                   1094:        string_append (decl, ",");
                   1095:       string_append (decl, "...");
                   1096:     }
                   1097: 
                   1098:   string_append (decl, ")");
                   1099:   return 1;
                   1100: }
                   1101: 
                   1102: static void
                   1103: munge_function_name (name)
                   1104:      string *name;
                   1105: {
                   1106:   if (string_empty (name))
                   1107:     return;
                   1108: 
                   1109:   if (name->p - name->b >= 3 
                   1110:       && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == CPLUS_MARKER)
                   1111:     {
                   1112:       int i;
                   1113:       /* see if it's an assignment expression */
                   1114:       if (name->p - name->b >= 10 /* op$assign_ */
                   1115:          && memcmp (name->b + 3, "assign_", 7) == 0)
                   1116:        {
                   1117:          for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
                   1118:            {
                   1119:              int len = name->p - name->b - 10;
                   1120:              if (strlen (optable[i].in) == len
                   1121:                  && memcmp (optable[i].in, name->b + 10, len) == 0)
                   1122:                {
                   1123:                  string_clear (name);
                   1124:                  string_append (name, "operator");
                   1125:                  string_append (name, optable[i].out);
                   1126:                  string_append (name, "=");
                   1127:                  return;
                   1128:                }
                   1129:            }
                   1130:        }
                   1131:       else
                   1132:        {
                   1133:          for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
                   1134:            {
                   1135:              int len = name->p - name->b - 3;
                   1136:              if (strlen (optable[i].in) == len 
                   1137:                  && memcmp (optable[i].in, name->b + 3, len) == 0)
                   1138:                {
                   1139:                  string_clear (name);
                   1140:                  string_append (name, "operator");
                   1141:                  string_append (name, optable[i].out);
                   1142:                  return;
                   1143:                }
                   1144:            }
                   1145:        }
                   1146:       return;
                   1147:     }
                   1148:   else if (name->p - name->b >= 5 && memcmp (name->b, "type$", 5) == 0)
                   1149:     {
                   1150:       /* type conversion operator */
                   1151:       string type;
                   1152:       const char *tem = name->b + 5;
                   1153:       if (do_type (&tem, &type))
                   1154:        {
                   1155:          string_clear (name);
                   1156:          string_append (name, "operator ");
                   1157:          string_appends (name, &type);
                   1158:          string_delete (&type);
                   1159:          return;
                   1160:        }
                   1161:     }
                   1162:   /* ANSI.  */
                   1163:   else if (name->b[2] == 'o' && name->b[3] == 'p')
                   1164:     {
                   1165:       /* type conversion operator.  */
                   1166:       string type;
                   1167:       const char *tem = name->b + 4;
                   1168:       if (do_type (&tem, &type))
                   1169:        {
                   1170:          string_clear (name);
                   1171:          string_append (name, "operator ");
                   1172:          string_appends (name, &type);
                   1173:          string_delete (&type);
                   1174:          return;
                   1175:        }
                   1176:     }
                   1177:   else if (name->b[2] >= 'a' && name->b[2] <= 'z'
                   1178:           && name->b[3] >= 'a' && name->b[3] <= 'z')
                   1179:     {
                   1180:       int i;
                   1181: 
                   1182:       if (name->b[4] == '\0')
                   1183:        {
                   1184:          /* Operator.  */
                   1185:          for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
                   1186:            {
                   1187:              if (strlen (optable[i].in) == 2
                   1188:                  && memcmp (optable[i].in, name->b + 2, 2) == 0)
                   1189:                {
                   1190:                  string_clear (name);
                   1191:                  string_append (name, "operator");
                   1192:                  string_append (name, optable[i].out);
                   1193:                  return;
                   1194:                }
                   1195:            }
                   1196:        }
                   1197:       else
                   1198:        {
                   1199:          if (name->b[2] != 'a' || name->b[5] != '\0')
                   1200:            return;
                   1201:          /* Assignment.  */
                   1202:          for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
                   1203:            {
                   1204:              if (strlen (optable[i].in) == 3
                   1205:                  && memcmp (optable[i].in, name->b + 2, 3) == 0)
                   1206:                {
                   1207:                  string_clear (name);
                   1208:                  string_append (name, "operator");
                   1209:                  string_append (name, optable[i].out);
                   1210:                  return;
                   1211:                }
                   1212:            }
                   1213:        }
                   1214:     }
                   1215: }
                   1216: 
                   1217: /* a mini string-handling package */
                   1218: 
                   1219: static void
                   1220: string_need (s, n)
                   1221:      string *s;
                   1222:      int n;
                   1223: {
                   1224:   if (s->b == NULL)
                   1225:     {
                   1226:       if (n < 32)
                   1227:        n = 32;
                   1228:       s->p = s->b = (char *) xmalloc (n);
                   1229:       s->e = s->b + n;
                   1230:     }
                   1231:   else if (s->e - s->p < n)
                   1232:     {
                   1233:       int tem = s->p - s->b;
                   1234:       n += tem;
                   1235:       n *= 2;
                   1236:       s->b = (char *) xrealloc (s->b, n);
                   1237:       s->p = s->b + tem;
                   1238:       s->e = s->b + n;
                   1239:     }
                   1240: }
                   1241: 
                   1242: static void
                   1243: string_delete (s)
                   1244:      string *s;
                   1245: {
                   1246:   if (s->b != NULL)
                   1247:     {
                   1248:       free (s->b);
                   1249:       s->b = s->e = s->p = NULL;
                   1250:     }
                   1251: }
                   1252: 
                   1253: static void
                   1254: string_init (s)
                   1255:      string *s;
                   1256: {
                   1257:   s->b = s->p = s->e = NULL;
                   1258: }
                   1259: 
                   1260: static void 
                   1261: string_clear (s)
                   1262:      string *s;
                   1263: {
                   1264:   s->p = s->b;
                   1265: }
                   1266: 
                   1267: static int
                   1268: string_empty (s)
                   1269:      string *s;
                   1270: {
                   1271:   return s->b == s->p;
                   1272: }
                   1273: 
                   1274: static void
                   1275: string_append (p, s)
                   1276:      string *p;
                   1277:      const char *s;
                   1278: {
                   1279:   int n;
                   1280:   if (s == NULL || *s == '\0')
                   1281:     return;
                   1282:   n = strlen (s);
                   1283:   string_need (p, n);
                   1284:   memcpy (p->p, s, n);
                   1285:   p->p += n;
                   1286: }
                   1287: 
                   1288: static void
                   1289: string_appends (p, s)
                   1290:      string *p, *s;
                   1291: {
                   1292:   int n;
                   1293:   if (s->b == s->p)
                   1294:     return;
                   1295:   n = s->p - s->b;
                   1296:   string_need (p, n);
                   1297:   memcpy (p->p, s->b, n);
                   1298:   p->p += n;
                   1299: }
                   1300: 
                   1301: static void
                   1302: string_appendn (p, s, n)
                   1303:      string *p;
                   1304:      const char *s;
                   1305:      int n;
                   1306: {
                   1307:   if (n == 0)
                   1308:     return;
                   1309:   string_need (p, n);
                   1310:   memcpy (p->p, s, n);
                   1311:   p->p += n;
                   1312: }
                   1313: 
                   1314: static void
                   1315: string_prepend (p, s)
                   1316:      string *p;
                   1317:      const char *s;
                   1318: {
                   1319:   if (s == NULL || *s == '\0')
                   1320:     return;
                   1321:   string_prependn (p, s, strlen (s));
                   1322: }
                   1323: 
                   1324: #if 0
                   1325: static void
                   1326: string_prepends (p, s)
                   1327:      string *p, *s;
                   1328: {
                   1329:   if (s->b == s->p)
                   1330:     return;
                   1331:   string_prependn (p, s->b, s->p - s->b);
                   1332: }
                   1333: #endif
                   1334: 
                   1335: static void
                   1336: string_prependn (p, s, n)
                   1337:      string *p;
                   1338:      const char *s;
                   1339:      int n;
                   1340: {
                   1341:   char *q;
                   1342: 
                   1343:   if (n == 0)
                   1344:     return;
                   1345:   string_need (p, n);
                   1346:   for (q = p->p - 1; q >= p->b; q--)
                   1347:     q[n] = q[0];
                   1348:   memcpy (p->b, s, n);
                   1349:   p->p += n;
                   1350: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.