|
|
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.