|
|
1.1 ! root 1: /*ident "@(#)ctrans:demangler/args.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: /* This structure is used to keep ! 11: * track of pointers to argument ! 12: * descriptions in the mangled string. ! 13: * This is needed for N and T encodings ! 14: * to work. ! 15: */ ! 16: typedef struct { ! 17: char *list[10]; ! 18: int pos; ! 19: } Place; ! 20: ! 21: Place here; ! 22: ! 23: /* Strings and flags needed by ! 24: * the argument demangles. ! 25: */ ! 26: typedef struct { ! 27: String *arg,*ptr; ! 28: int Sign,Uns,Cons,Vol; ! 29: } Arg_Remem; ! 30: ! 31: /* initialize Arg_Remem */ ! 32: static void ! 33: mkar(r) ! 34: Arg_Remem *r; ! 35: { ! 36: r->arg = mk_String(0); ! 37: r->ptr = mk_String(0); ! 38: r->Sign = r->Uns = r->Cons = r->Vol = 0; ! 39: } ! 40: ! 41: /* free data for Arg_Remem */ ! 42: static void ! 43: delar(r) ! 44: Arg_Remem *r; ! 45: { ! 46: free_String(r->ptr); ! 47: free_String(r->arg); ! 48: } ! 49: ! 50: /* This routine formats a single argument ! 51: * on the buffer sptr. ! 52: */ ! 53: static void ! 54: setarg(sptr,r,c) ! 55: String **sptr; ! 56: Arg_Remem *r; ! 57: char *c; ! 58: { ! 59: if(r->Cons) ! 60: r->arg = prep_String("const ",r->arg); ! 61: if(r->Vol) ! 62: r->arg = prep_String("volatile ",r->arg); ! 63: if(r->Uns) ! 64: r->arg = prep_String("unsigned ",r->arg); ! 65: if(r->Sign) ! 66: r->arg = prep_String("signed ",r->arg); ! 67: r->arg = app_String(r->arg,c); ! 68: r->arg = app_String(r->arg,PTR(r->ptr)); ! 69: (*sptr) = app_String(*sptr,PTR(r->arg)); ! 70: delar(r); ! 71: } ! 72: ! 73: ! 74: /* Demangle a single function argument */ ! 75: int ! 76: demangle_doarg(sptr,c) ! 77: String **sptr; ! 78: char *c; ! 79: { ! 80: register int i; ! 81: Arg_Remem ar; ! 82: mkar(&ar); ! 83: ! 84: if(here.pos < 10 && here.pos >= 0) ! 85: here.list[here.pos++] = c; ! 86: ! 87: for(i=0;c[i];i++) { ! 88: switch(c[i]) { ! 89: ! 90: case 'T': ! 91: { ! 92: Place tmp; ! 93: tmp = here; ! 94: here.pos = c[1] - '1'; ! 95: if(here.pos < 0 || here.pos >= tmp.pos-1) { ! 96: delar(&ar); ! 97: return -1; ! 98: } ! 99: demangle_doarg(sptr,here.list[here.pos]); ! 100: here = tmp; ! 101: delar(&ar); ! 102: return 2; ! 103: } ! 104: case 'N': ! 105: { ! 106: Place tmp; ! 107: int cycles,pos; ! 108: cycles = c[1] - '0'; pos = c[2] - '1'; ! 109: tmp = here; ! 110: if(cycles < 1 || cycles > 9 || pos < 0 || pos >= tmp.pos-1) { ! 111: delar(&ar); ! 112: return -1; ! 113: } ! 114: while(cycles--) { ! 115: here = tmp; ! 116: here.pos = pos; ! 117: demangle_doarg(sptr,here.list[here.pos]); ! 118: (*sptr) = app_String(*sptr,","); ! 119: } ! 120: (*sptr)->data[--(*sptr)->sg.end] = '\0'; ! 121: here = tmp; ! 122: delar(&ar); ! 123: return 3; ! 124: } ! 125: ! 126: /* Class encodings */ ! 127: case '1': ! 128: case '2': ! 129: case '3': ! 130: case '4': ! 131: case '5': ! 132: case '6': ! 133: case '7': ! 134: case '8': ! 135: case '9': ! 136: { ! 137: int n = 0,cnt = 0; ! 138: while(isdigit(c[i+n])) { ! 139: cnt = cnt * 10 + c[i+n] - '0'; ! 140: n++; ! 141: } ! 142: i += n; ! 143: if(strlen(c+i) < cnt) { ! 144: delar(&ar); ! 145: return -1; ! 146: } ! 147: ar.arg = napp_String(ar.arg,c+i,cnt); ! 148: i += cnt; ! 149: setarg(sptr,&ar,""); ! 150: return i; ! 151: } ! 152: ! 153: /* Qualifiers to type names */ ! 154: case 'S': ! 155: ar.Sign++; ! 156: break; ! 157: case 'U': ! 158: ar.Uns++; ! 159: break; ! 160: case 'C': ! 161: ar.Cons++; ! 162: break; ! 163: case 'V': ! 164: ar.Vol++; ! 165: break; ! 166: ! 167: /* Pointers, references, and Member Pointers */ ! 168: case 'P': ! 169: case 'R': ! 170: case 'M': ! 171: if(ar.Cons) { ! 172: ar.ptr = prep_String(" const",ar.ptr); ! 173: ar.Cons = 0; ! 174: } ! 175: if(ar.Vol) { ! 176: ar.ptr = prep_String(" volatile",ar.ptr); ! 177: ar.Vol = 0; ! 178: } ! 179: if(c[i] == 'P') ! 180: ar.ptr = prep_String("*",ar.ptr); ! 181: else if(c[i] == 'R') ! 182: ar.ptr = prep_String("&",ar.ptr); ! 183: else { ! 184: int n = 1,cnt = 0; ! 185: ar.ptr = prep_String("::*",ar.ptr); ! 186: while(isdigit(c[i+n])) { ! 187: cnt = cnt * 10 + c[i+n] - '0'; ! 188: n++; ! 189: } ! 190: i += n; ! 191: ar.ptr = nprep_String(c+i,ar.ptr,cnt); ! 192: ar.ptr = prep_String(" ",ar.ptr); ! 193: i += cnt; ! 194: i--; ! 195: } ! 196: break; ! 197: ! 198: /* Demangle for basic built-in types */ ! 199: case 'i': ! 200: setarg(sptr,&ar,"int"); ! 201: return ++i; ! 202: case 'c': ! 203: setarg(sptr,&ar,"char"); ! 204: return ++i; ! 205: case 's': ! 206: setarg(sptr,&ar,"short"); ! 207: return ++i; ! 208: case 'l': ! 209: setarg(sptr,&ar,"long"); ! 210: return ++i; ! 211: case 'f': ! 212: setarg(sptr,&ar,"float"); ! 213: return ++i; ! 214: case 'd': ! 215: setarg(sptr,&ar,"double"); ! 216: return ++i; ! 217: case 'r': ! 218: setarg(sptr,&ar,"long double"); ! 219: return ++i; ! 220: ! 221: /* Ellipsis and void */ ! 222: case 'e': ! 223: (*sptr) = app_String(*sptr,"..."); ! 224: delar(&ar); ! 225: if(ar.Cons || ar.Vol || ar.Uns || ar.Sign) ! 226: return -1; ! 227: return ++i; ! 228: case 'v': ! 229: (*sptr) = app_String(*sptr,"void"); ! 230: (*sptr) = app_String(*sptr,PTR(ar.ptr)); ! 231: delar(&ar); ! 232: if(ar.Cons || ar.Vol || ar.Uns || ar.Sign) ! 233: return -1; ! 234: return ++i; ! 235: ! 236: /* Arrays */ ! 237: case 'A': ! 238: if(*PTR(ar.ptr)) { ! 239: ar.ptr = prep_String("(",ar.ptr); ! 240: ar.ptr = app_String(ar.ptr,")"); ! 241: } ! 242: ar.ptr = app_String(ar.ptr,"["); ! 243: { ! 244: int cnt = 0; ! 245: i++; ! 246: while(isdigit(c[i+cnt])) ! 247: cnt++; ! 248: ar.ptr = napp_String(ar.ptr,c+i,cnt); ! 249: i += cnt; ! 250: if(c[i] != '_') { ! 251: delar(&ar); ! 252: return -1; ! 253: } ! 254: } ! 255: ar.ptr = app_String(ar.ptr,"]"); ! 256: break; ! 257: ! 258: /* Functins ! 259: * This will always be called as a pointer ! 260: * to a function. ! 261: */ ! 262: case 'F': ! 263: ar.ptr = prep_String("(",ar.ptr); ! 264: ar.ptr = app_String(ar.ptr,")"); ! 265: { ! 266: Place tmp; ! 267: tmp = here; ! 268: i++; ! 269: i += demangle_doargs(&ar.ptr,c+i); ! 270: if(c[i] != '_') { ! 271: delar(&ar); ! 272: return -1; ! 273: } ! 274: here = tmp; ! 275: } ! 276: break; ! 277: ! 278: /* Needed when this is called to demangle ! 279: * an argument of a pointer to a function. ! 280: */ ! 281: case '_': ! 282: delar(&ar); ! 283: return 0; ! 284: ! 285: default: ! 286: delar(&ar); ! 287: return -1; ! 288: } ! 289: } ! 290: ! 291: /* Did the argument list terminate properly? */ ! 292: { ! 293: int rc = 0; ! 294: if(*PTR(ar.ptr) || ar.Uns || ar.Sign || ar.Cons || ar.Vol) ! 295: rc = -1; ! 296: delar(&ar); ! 297: return rc; ! 298: } ! 299: } ! 300: ! 301: /* This function is called to demangle ! 302: * an argument list. ! 303: */ ! 304: int ! 305: demangle_doargs(sptr,c) ! 306: String **sptr; ! 307: char *c; ! 308: { ! 309: int i,n = 0; ! 310: here.pos = 0; ! 311: ! 312: (*sptr) = app_String(*sptr,"("); ! 313: while(*c && (i = demangle_doarg(sptr,c)) > 0) { ! 314: c += i; ! 315: n += i; ! 316: (*sptr) = app_String(*sptr,","); ! 317: } ! 318: ! 319: if(i < 0) ! 320: return -1; ! 321: ! 322: (*sptr)->data[(*sptr)->sg.end - 1] = ')'; ! 323: return n; ! 324: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.