|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.