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

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

unix.superglobalmegacorp.com

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