|
|
1.1 root 1: /*ident "@(#)ctrans:demangler/c++filt.c 1.1"*/
2: /*
3: * C++ Demangler Source Code
4: * @(#)master 1.5
5: * 7/27/88 13:54:37
6: */
7: #include <stdio.h>
8: #include <ctype.h>
9: #include <assert.h>
10: extern char *demangle();
11: extern char *malloc(),*realloc();
12: #define TAB 8
13: #define START 10
14:
15: int mflag = 0, sflag = 0;
16:
17: char *
18: dem(c)
19: char *c;
20: {
21: char *d,*s = c;
22: #if vax || sun
23: if(*c == '_') c++;
24: #endif
25: d = demangle(c);
26: if(d == c)
27: return s;
28: else
29: return d;
30: }
31:
32: void
33: space(n)
34: int n;
35: {
36: while(n--) putchar(' ');
37: }
38:
39: void
40: subprint(c,i,l)
41: char *c;
42: int i,l;
43: {
44: int n;
45: for(n=i;n<l;n++)
46: putchar(c[n]);
47: }
48:
49: struct dlist { char *mname,*dname; } *ds;
50: int di = 2;
51: int dn = START;
52:
53: int
54: doline(c)
55: char *c;
56: {
57: int state = 0,q = 0,last=0;
58: register int i;
59:
60: for(i=0;c[i];i++) {
61:
62: /* if state is zero, we have not yet located
63: * a c identifier. If it is non-zero, we have.
64: */
65: if(state == 0) {
66: if(isalnum(c[i]) || c[i] == '_')
67: state++;
68: }
69: if(state == 1) {
70: char *x,*d;
71: int ln,n = i;
72:
73: /* find end of c identifier */
74: while(c[n] && (isalnum(c[n]) || c[n] == '_'))n++;
75: q = n;
76:
77: /* find end of spaces following identifier */
78: while(c[q] && c[q] == ' ') q++;
79:
80: /* extract the c identifier from the line */
81: x = malloc(n-i+1);
82: strncpy(x,c+i,n-i);
83: x[n-i] = 0;
84:
85: /* print out the line from the end of the
86: * last identifier+following spaces to the beginning of
87: * this identifier.
88: */
89: subprint(c,last,i);
90:
91: /* demangle the identifier */
92: d = dem(x);
93: if(d != x) {
94: int flag=0,ix;
95:
96: /* print out the demangled name.
97: * assure that it is followed by at least
98: * one space. More if there is room.
99: */
100: printf("%s",d);
101: ln = strlen(d);
102:
103: /* Print out mangled name if sflag is set.
104: * otherwise, just remember it.
105: */
106: if(sflag) {
107: int tab = 3*TAB - ln%(3*TAB);
108: space(tab);
109: ln += tab;
110: printf("%s",x);
111: ln += strlen(x);
112: ln++;
113: }
114:
115: if(q - i <= ln)
116: putchar(' ');
117: else
118: space(q - i - ln);
119:
120: if(mflag) {
121:
122: /* check to see if mangled name
123: * is already in the dlist (list of
124: * mangled-demangled names).
125: */
126: for(ix=0;ix<di;ix++) {
127: if(strcmp(x,ds[ix].mname)==0) {
128: flag++;
129: break;
130: }
131: }
132:
133: if(flag == 0) {
134:
135: /* assure that the list is
136: * big enough to accomodate the
137: * new names.
138: */
139: if(di >= dn) {
140: dn *= 2;
141: ds = (struct dlist *)realloc(ds,
142: sizeof(struct dlist)*(dn+1));
143: assert(ds != 0);
144: }
145:
146: /* enter the new names in the list. */
147: ds[di].mname = x;
148: ds[di].dname = malloc(ln+1);
149: strcpy(ds[di].dname,d);
150: di++;
151: } else free(x);
152: /* x is freed only if it is not
153: * put in the list.
154: */
155: }
156:
157: } else {
158: subprint(c,i,q);
159: free(x);
160: }
161:
162: /* move counter to the end
163: * of this (identifier + following spaces)
164: * and continue
165: */
166: last = i = q;
167:
168: /* counter the ++ of the for loop */
169: i--;
170: state = 0;
171: }
172: }
173:
174: /* print remainder of line */
175: printf("%s\n",c+q);
176: }
177:
178: main(argc,argv)
179: int argc;
180: char **argv;
181: {
182: int c;
183: char *s;
184: int i = 0;
185: int n = START;
186: int copt;
187: s = malloc(n+1);
188: *s = 0;
189:
190: /* The only argument to this command is
191: * -n. If it is given, the the C++ symbol
192: * map is not generated. Instead, the symbols
193: * are printed side by side on stdout.
194: */
195: while((copt = getopt(argc,argv,"smv")) != EOF) {
196: switch (copt) {
197: case 'm':
198: mflag = 1;
199: break;
200: case 's':
201: sflag = 1;
202: break;
203: case 'v':
204: fprintf(stderr,"Demangler Version 1.5, Date 7/27/88\n");
205: break;
206: default:
207: fprintf(stderr, "usage: %s [ -smv ]\n", argv[0]);
208: exit(1);
209: }
210: }
211: /* Initialize C++ symbol map. The column headings
212: * are entries in the table -- this assures that they
213: * will be alligned correctly.
214: */
215: if(mflag) {
216: ds = (struct dlist *)malloc(sizeof(struct dlist)*(dn+1));
217: ds[0].mname = "mangled:";
218: ds[0].dname = "demangled:";
219: ds[1].mname = ds[1].dname = "";
220: }
221:
222: while((c = getchar()) != EOF) {
223:
224: /* read one line at a time */
225: if(c != '\n') {
226:
227: /* expand tabs to spaces */
228: if(c == '\t') {
229: int nb = TAB - i%TAB;
230: c = ' ';
231: while(--nb) {
232: if(i >= n) {
233: n *= 2;
234: s = realloc(s,n+1);
235: assert(s != 0);
236: }
237: s[i++] = c;
238: s[i] = 0;
239: }
240: }
241:
242: /* append a character to the buffer */
243: /* make sure the buffer is big enough */
244: if(i >= n) {
245: n *= 2;
246: s = realloc(s,n+1);
247: assert(s != 0);
248: }
249: s[i++] = c;
250: s[i] = 0;
251:
252: } else {
253: doline(s);
254: s[i = 0] = 0;
255: }
256: }
257:
258: if(sflag || di <= 2)
259: return 0;
260:
261: printf("\nC++ symbol mapping\n");
262: {
263: int width = 0;
264: register int ix;
265:
266: /* determine size of columns */
267: for(ix=0;ix<di;ix++) {
268: int ln = strlen(ds[ix].dname);
269: if(ln > width) width = ln;
270: }
271:
272: width++;
273: for(ix=0;ix<di;ix++) {
274: printf("%s",ds[ix].dname);
275: space(width-strlen(ds[ix].dname));
276: printf("%s\n",ds[ix].mname);
277: }
278: }
279: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.