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