Annotation of researchv10no/cmd/cfront/demangle/demangle.c, revision 1.1.1.1

1.1       root        1: /*ident        "@(#)ctrans:demangler/demangle.c        1.1"*/
                      2: /*
                      3:  * C++ Demangler Source Code
                      4:  * @(#)master  1.5
                      5:  * 7/27/88 13:54:37
                      6:  */
                      7: #include "String.h"
                      8: #include <ctype.h>
                      9: 
                     10: /* The variable "hold" contains the pointer to the
                     11:  * array initially handed to demangle.  It is returned
                     12:  * if it is not possible to demangle the string.  Thus
                     13:  * one can do the following:
                     14:  *
                     15:  * char *mn = "Some mangled name";
                     16:  * char *dm = mangle(mn);
                     17:  * if(dm == mn)
                     18:  *             printf("name could not be demangled\n");
                     19:  * else
                     20:  *             printf("demangled name is: %s\n",dm);
                     21:  */
                     22: static char *hold;
                     23: 
                     24: /* this String is the working buffer for the demangle
                     25:  * routine.  A pointer into this String is returned
                     26:  * from demangle when it is possible to demangle the
                     27:  * String.  For this reason, the pointer should not
                     28:  * be saved between calls of demangle(), nor freed.
                     29:  */
                     30: static String *s = 0;
                     31: 
                     32: static int
                     33: getint(c)
                     34: char **c;
                     35: {
                     36:        int n = 0;
                     37:        while(isdigit(**c)) {
                     38:                n = n * 10 + (**c) - '0';
                     39:                (*c)++;
                     40:        }
                     41:        return n;
                     42: }
                     43: 
                     44: /* If a mangled name has a __
                     45:  * that is not at the very beginning
                     46:  * of the string, then this routine
                     47:  * is called to demangle that part
                     48:  * of the name.  All overloaded functions,
                     49:  * and class members fall into this category.
                     50:  */
                     51: static char *
                     52: second(c)
                     53: char *c;
                     54: {
                     55:        int n;
                     56:        if(strncmp(c,"__",2))
                     57:                return hold;
                     58:        c += 2;
                     59: 
                     60:        if(!(isdigit(*c) || *c == 'F'))
                     61:                return hold;
                     62: 
                     63:        /* a member? */
                     64:        if(isdigit(*c)) {
                     65:                int ln;
                     66:                n = getint(&c);
                     67:                if(n == 0)
                     68:                        return hold;
                     69:                s = prep_String("::",s);
                     70:                ln = strlen(PTR(s));
                     71:                s = nprep_String(c,s,n);
                     72:                if(ln + n != strlen(PTR(s)))
                     73:                        return hold;
                     74:                c += n;
                     75:        }
                     76: 
                     77:        /* an overloaded function? */
                     78:        if(*c == 'F') {
                     79:                if(c[1] == 0)
                     80:                        return hold;
                     81:                if(strcmp(c,"Fv")==0)
                     82:                        s = app_String(s,"()");
                     83:                else if(demangle_doargs(&s,c+1) < 0)
                     84:                        return hold;
                     85:        }
                     86:        return PTR(s);
                     87: }
                     88: 
                     89: char *
                     90: demangle(c)
                     91: char *c;
                     92: {
                     93:        register int i = 0;
                     94:        hold = c;
                     95:        s = mk_String(s);
                     96:        s = set_String(s,"");
                     97: 
                     98:        if(c == 0 || *c == 0)
                     99:                return hold;
                    100: 
                    101:        if(strncmp(c,"__",2) == 0) {
                    102:                char *x;
                    103:                c += 2;
                    104: 
                    105:                /* For automatic variables, or internal static
                    106:                 * variables, a __(number) is prepended to the
                    107:                 * name.  If this is encountered, strip this off
                    108:                 * and return.
                    109:                 */
                    110:                if(isdigit(*c)) {
                    111:                        while(isdigit(*c))
                    112:                                c++;
                    113:                        return c;
                    114:                }
                    115: 
                    116:                /* Handle operator functions -- this
                    117:                 * automatically calls second, since
                    118:                 * all operator functions are overloaded.
                    119:                 */
                    120:                if(x = findop(c)) {
                    121:                        s = app_String(s,"operator");
                    122:                        s = app_String(s,x);
                    123:                        c += oplen;
                    124:                        return second(c);
                    125:                }
                    126: 
                    127:                /* Operator cast does not fit the mould
                    128:                 * of the other operators.  Its type name
                    129:                 * is encoded.  The cast function must
                    130:                 * take a void as an argument.
                    131:                 */
                    132:                if(strncmp(c,"op",2) == 0) {
                    133:                        int r;
                    134:                        s = app_String(s,"operator ");
                    135:                        c += 2;
                    136:                        r = demangle_doarg(&s,c);
                    137:                        if(r < 0)
                    138:                                return hold;
                    139:                        c += r;
                    140:                        return second(c);
                    141:                }
                    142: 
                    143:                /* Constructors and Destructors are also
                    144:                 * a special case of operator name.  Note
                    145:                 * that the destructor, while overloaded,
                    146:                 * must always take the same arguments --
                    147:                 * none.
                    148:                 */
                    149:                if(strncmp(c,"ct__",4) == 0 || strncmp(c,"dt__",4) == 0) {
                    150:                        int n;
                    151:                        char *c2 = c+2;
                    152:                        char x = c[0];
                    153:                        c += 4;
                    154:                        n = getint(&c);
                    155:                        if(n == 0)
                    156:                                return hold;
                    157:                        if(x == 'd' && strcmp(c+n,"Fv"))
                    158:                                return hold;
                    159:                        s = napp_String(s,c,n);
                    160:                        if(x == 'd') {
                    161:                                s = app_String(s,"::~");
                    162:                                s = napp_String(s,c,n);
                    163:                                s = app_String(s,"()");
                    164:                                return PTR(s);
                    165:                        } else {
                    166:                                return second(c2);
                    167:                        }
                    168:                }
                    169: 
                    170:                return hold;
                    171:        }
                    172: 
                    173:        /* If a name does not begin with a __
                    174:         * but it does contain one, it is either
                    175:         * a member or an overloaded function.
                    176:         */
                    177:        while(c[i] && strncmp(c+i,"__",2))
                    178:                i++;
                    179:        while(c[i] && strncmp(1+c+i,"__",2) == 0)
                    180:                i++;
                    181: 
                    182:        if(strncmp(c+i,"__",2) == 0) {
                    183:                s = napp_String(s,c,i);
                    184:                return second(c+i);
                    185:        } else
                    186:                return hold;
                    187: }

unix.superglobalmegacorp.com

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