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

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

unix.superglobalmegacorp.com

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