xref: /csrg-svn/old/dbx/printsym.c (revision 9676)
1*9676Slinton /* Copyright (c) 1982 Regents of the University of California */
2*9676Slinton 
3*9676Slinton static char sccsid[] = "@(#)@(#)printsym.c 1.1 12/15/82";
4*9676Slinton 
5*9676Slinton /*
6*9676Slinton  * Printing of symbolic information.
7*9676Slinton  */
8*9676Slinton 
9*9676Slinton #include "defs.h"
10*9676Slinton #include "symbols.h"
11*9676Slinton #include "languages.h"
12*9676Slinton #include "printsym.h"
13*9676Slinton #include "tree.h"
14*9676Slinton #include "eval.h"
15*9676Slinton #include "mappings.h"
16*9676Slinton #include "process.h"
17*9676Slinton #include "runtime.h"
18*9676Slinton #include "machine.h"
19*9676Slinton #include "names.h"
20*9676Slinton #include "main.h"
21*9676Slinton 
22*9676Slinton #ifndef public
23*9676Slinton #endif
24*9676Slinton 
25*9676Slinton /*
26*9676Slinton  * Return a pointer to the string for the name of the class that
27*9676Slinton  * the given symbol belongs to.
28*9676Slinton  */
29*9676Slinton 
30*9676Slinton private String clname[] = {
31*9676Slinton     "bad use", "constant", "type", "variable", "array", "fileptr",
32*9676Slinton     "record", "field", "procedure", "function", "funcvar",
33*9676Slinton     "ref", "pointer", "file", "set", "range", "label", "withptr",
34*9676Slinton     "scalar", "string", "program", "improper", "variant",
35*9676Slinton     "procparam", "funcparam", "module", "typeref", "tag"
36*9676Slinton };
37*9676Slinton 
38*9676Slinton public String classname(s)
39*9676Slinton Symbol s;
40*9676Slinton {
41*9676Slinton     return clname[ord(s->class)];
42*9676Slinton }
43*9676Slinton 
44*9676Slinton /*
45*9676Slinton  * Note the entry of the given block, unless it's the main program.
46*9676Slinton  */
47*9676Slinton 
48*9676Slinton public printentry(s)
49*9676Slinton Symbol s;
50*9676Slinton {
51*9676Slinton     if (s != program) {
52*9676Slinton 	printf("\nentering %s %s\n", classname(s), symname(s));
53*9676Slinton     }
54*9676Slinton }
55*9676Slinton 
56*9676Slinton /*
57*9676Slinton  * Note the exit of the given block
58*9676Slinton  */
59*9676Slinton 
60*9676Slinton public printexit(s)
61*9676Slinton Symbol s;
62*9676Slinton {
63*9676Slinton     if (s != program) {
64*9676Slinton 	printf("leaving %s %s\n\n", classname(s), symname(s));
65*9676Slinton     }
66*9676Slinton }
67*9676Slinton 
68*9676Slinton /*
69*9676Slinton  * Note the call of s from t.
70*9676Slinton  */
71*9676Slinton 
72*9676Slinton public printcall(s, t)
73*9676Slinton Symbol s, t;
74*9676Slinton {
75*9676Slinton     printf("calling %s", symname(s));
76*9676Slinton     printparams(s, nil);
77*9676Slinton     printf(" from %s %s\n", classname(t), symname(t));
78*9676Slinton }
79*9676Slinton 
80*9676Slinton /*
81*9676Slinton  * Note the return from s.  If s is a function, print the value
82*9676Slinton  * it is returning.  This is somewhat painful, since the function
83*9676Slinton  * has actually just returned.
84*9676Slinton  */
85*9676Slinton 
86*9676Slinton public printrtn(s)
87*9676Slinton Symbol s;
88*9676Slinton {
89*9676Slinton     register Symbol t;
90*9676Slinton     register int len;
91*9676Slinton     Boolean isindirect;
92*9676Slinton 
93*9676Slinton     printf("returning ");
94*9676Slinton     if (s->class == FUNC) {
95*9676Slinton 	len = size(s->type);
96*9676Slinton 	if (canpush(len)) {
97*9676Slinton 	    t = rtype(s->type);
98*9676Slinton 	    isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
99*9676Slinton 	    pushretval(len, isindirect);
100*9676Slinton 	    printval(s->type);
101*9676Slinton 	    putchar(' ');
102*9676Slinton 	} else {
103*9676Slinton 	    printf("(value too large) ");
104*9676Slinton 	}
105*9676Slinton     }
106*9676Slinton     printf("from %s\n", symname(s));
107*9676Slinton }
108*9676Slinton 
109*9676Slinton /*
110*9676Slinton  * Print the values of the parameters of the given procedure or function.
111*9676Slinton  * The frame distinguishes recursive instances of a procedure.
112*9676Slinton  */
113*9676Slinton 
114*9676Slinton public printparams(f, frame)
115*9676Slinton Symbol f;
116*9676Slinton Frame frame;
117*9676Slinton {
118*9676Slinton     Symbol param;
119*9676Slinton     int n, m, s;
120*9676Slinton 
121*9676Slinton     n = nargspassed(frame);
122*9676Slinton     param = f->chain;
123*9676Slinton     if (param != nil or n > 0) {
124*9676Slinton 	printf("(");
125*9676Slinton 	m = n;
126*9676Slinton 	if (param != nil) {
127*9676Slinton 	    for (;;) {
128*9676Slinton 		s = size(param) div sizeof(Word);
129*9676Slinton 		if (s == 0) {
130*9676Slinton 		    s = 1;
131*9676Slinton 		}
132*9676Slinton 		m -= s;
133*9676Slinton 		printv(param, frame);
134*9676Slinton 		param = param->chain;
135*9676Slinton 	    if (param == nil) break;
136*9676Slinton 		printf(", ");
137*9676Slinton 	    }
138*9676Slinton 	}
139*9676Slinton 	if (m > 0) {
140*9676Slinton 	    if (f->chain != nil) {
141*9676Slinton 		printf(", ");
142*9676Slinton 	    }
143*9676Slinton 	    for (;;) {
144*9676Slinton 		--m;
145*9676Slinton 		printf("0x%x", argn(n - m, frame));
146*9676Slinton 	    if (m <= 0) break;
147*9676Slinton 		printf(", ");
148*9676Slinton 	    }
149*9676Slinton 	}
150*9676Slinton 	printf(")");
151*9676Slinton     }
152*9676Slinton }
153*9676Slinton 
154*9676Slinton /*
155*9676Slinton  * Test if a symbol should be printed.  We don't print files,
156*9676Slinton  * for example, simply because there's no good way to do it.
157*9676Slinton  * The symbol must be within the given function.
158*9676Slinton  */
159*9676Slinton 
160*9676Slinton public Boolean should_print(s)
161*9676Slinton Symbol s;
162*9676Slinton {
163*9676Slinton     Boolean b;
164*9676Slinton     register Symbol t;
165*9676Slinton 
166*9676Slinton     switch (s->class) {
167*9676Slinton 	case VAR:
168*9676Slinton 	case FVAR:
169*9676Slinton 	    t = rtype(s->type);
170*9676Slinton 	    b = (Boolean) (
171*9676Slinton 		not isparam(s) and
172*9676Slinton 		t != nil and t->class != FILET and t->class != SET
173*9676Slinton 	    );
174*9676Slinton 	    break;
175*9676Slinton 
176*9676Slinton 	default:
177*9676Slinton 	    b = false;
178*9676Slinton 	    break;
179*9676Slinton     }
180*9676Slinton     return b;
181*9676Slinton }
182*9676Slinton 
183*9676Slinton /*
184*9676Slinton  * Print the name and value of a variable.
185*9676Slinton  */
186*9676Slinton 
187*9676Slinton public printv(s, frame)
188*9676Slinton Symbol s;
189*9676Slinton Frame frame;
190*9676Slinton {
191*9676Slinton     Address addr;
192*9676Slinton     int len;
193*9676Slinton 
194*9676Slinton     if (isambiguous(s) and ismodule(container(s))) {
195*9676Slinton 	printname(stdout, s);
196*9676Slinton 	printf(" = ");
197*9676Slinton     } else {
198*9676Slinton 	printf("%s = ", symname(s));
199*9676Slinton     }
200*9676Slinton     if (isvarparam(s)) {
201*9676Slinton 	rpush(address(s, frame), sizeof(Address));
202*9676Slinton 	addr = pop(Address);
203*9676Slinton 	len = size(s->type);
204*9676Slinton     } else {
205*9676Slinton 	addr = address(s, frame);
206*9676Slinton 	len = size(s);
207*9676Slinton     }
208*9676Slinton     if (canpush(len)) {
209*9676Slinton 	rpush(addr, len);
210*9676Slinton 	printval(s->type);
211*9676Slinton     } else {
212*9676Slinton 	printf("*** expression too large ***");
213*9676Slinton     }
214*9676Slinton }
215*9676Slinton 
216*9676Slinton /*
217*9676Slinton  * Print out the name of a symbol.
218*9676Slinton  */
219*9676Slinton 
220*9676Slinton public printname(f, s)
221*9676Slinton File f;
222*9676Slinton Symbol s;
223*9676Slinton {
224*9676Slinton     if (s == nil) {
225*9676Slinton 	fprintf(f, "(noname)");
226*9676Slinton     } else if (isredirected() or isambiguous(s)) {
227*9676Slinton 	printwhich(f, s);
228*9676Slinton     } else {
229*9676Slinton 	fprintf(f, "%s", symname(s));
230*9676Slinton     }
231*9676Slinton }
232*9676Slinton 
233*9676Slinton /*
234*9676Slinton  * Print the fully specified variable that is described by the given identifer.
235*9676Slinton  */
236*9676Slinton 
237*9676Slinton public printwhich(f, s)
238*9676Slinton File f;
239*9676Slinton Symbol s;
240*9676Slinton {
241*9676Slinton     printouter(f, container(s));
242*9676Slinton     fprintf(f, "%s", symname(s));
243*9676Slinton }
244*9676Slinton 
245*9676Slinton /*
246*9676Slinton  * Print the fully qualified name of each symbol that has the same name
247*9676Slinton  * as the given symbol.
248*9676Slinton  */
249*9676Slinton 
250*9676Slinton public printwhereis(f, s)
251*9676Slinton File f;
252*9676Slinton Symbol s;
253*9676Slinton {
254*9676Slinton     register Name n;
255*9676Slinton     register Symbol t;
256*9676Slinton 
257*9676Slinton     checkref(s);
258*9676Slinton     n = s->name;
259*9676Slinton     t = lookup(n);
260*9676Slinton     printwhich(f, t);
261*9676Slinton     t = t->next_sym;
262*9676Slinton     while (t != nil) {
263*9676Slinton 	if (t->name == n) {
264*9676Slinton 	    putc(' ', f);
265*9676Slinton 	    printwhich(f, t);
266*9676Slinton 	}
267*9676Slinton 	t = t->next_sym;
268*9676Slinton     }
269*9676Slinton     putc('\n', f);
270*9676Slinton }
271*9676Slinton 
272*9676Slinton private printouter(f, s)
273*9676Slinton File f;
274*9676Slinton Symbol s;
275*9676Slinton {
276*9676Slinton     Symbol outer;
277*9676Slinton 
278*9676Slinton     if (s != nil) {
279*9676Slinton 	outer = container(s);
280*9676Slinton 	if (outer != nil and outer != program) {
281*9676Slinton 	    printouter(f, outer);
282*9676Slinton 	}
283*9676Slinton 	fprintf(f, "%s.", symname(s));
284*9676Slinton     }
285*9676Slinton }
286*9676Slinton 
287*9676Slinton public printdecl(s)
288*9676Slinton Symbol s;
289*9676Slinton {
290*9676Slinton     checkref(s);
291*9676Slinton     (*language_op(s->language, L_PRINTDECL))(s);
292*9676Slinton }
293*9676Slinton 
294*9676Slinton /*
295*9676Slinton  * Straight dump of symbol information.
296*9676Slinton  */
297*9676Slinton 
298*9676Slinton public psym(s)
299*9676Slinton Symbol s;
300*9676Slinton {
301*9676Slinton     printf("name\t%s\n", symname(s));
302*9676Slinton     printf("lang\t%s\n", language_name(s->language));
303*9676Slinton     printf("level\t%d\n", s->level);
304*9676Slinton     printf("class\t%s\n", classname(s));
305*9676Slinton     printf("type\t0x%x", s->type);
306*9676Slinton     if (s->type != nil and s->type->name != nil) {
307*9676Slinton 	printf(" (%s)", symname(s->type));
308*9676Slinton     }
309*9676Slinton     printf("\nchain\t0x%x", s->chain);
310*9676Slinton     if (s->chain != nil and s->chain->name != nil) {
311*9676Slinton 	printf(" (%s)", symname(s->chain));
312*9676Slinton     }
313*9676Slinton     printf("\nblock\t0x%x", s->block);
314*9676Slinton     if (s->block->name != nil) {
315*9676Slinton 	printf(" (");
316*9676Slinton 	printname(stdout, s->block);
317*9676Slinton 	putchar(')');
318*9676Slinton     }
319*9676Slinton     putchar('\n');
320*9676Slinton     switch (s->class) {
321*9676Slinton 	case VAR:
322*9676Slinton 	case REF:
323*9676Slinton 	    if (s->level >= 3) {
324*9676Slinton 		printf("address\t0x%x\n", s->symvalue.offset);
325*9676Slinton 	    } else {
326*9676Slinton 		printf("offset\t%d\n", s->symvalue.offset);
327*9676Slinton 	    }
328*9676Slinton 	    break;
329*9676Slinton 
330*9676Slinton 	case RECORD:
331*9676Slinton 	case VARNT:
332*9676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
333*9676Slinton 	    break;
334*9676Slinton 
335*9676Slinton 	case FIELD:
336*9676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
337*9676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
338*9676Slinton 	    break;
339*9676Slinton 
340*9676Slinton 	case PROC:
341*9676Slinton 	case FUNC:
342*9676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
343*9676Slinton 	    break;
344*9676Slinton 
345*9676Slinton 	case RANGE:
346*9676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
347*9676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
348*9676Slinton 	    break;
349*9676Slinton 
350*9676Slinton 	default:
351*9676Slinton 	    /* do nothing */
352*9676Slinton 	    break;
353*9676Slinton     }
354*9676Slinton }
355*9676Slinton 
356*9676Slinton /*
357*9676Slinton  * Print out the value on top of the stack according to the given type.
358*9676Slinton  */
359*9676Slinton 
360*9676Slinton public printval(t)
361*9676Slinton Symbol t;
362*9676Slinton {
363*9676Slinton     Symbol s;
364*9676Slinton 
365*9676Slinton     checkref(t);
366*9676Slinton     switch (t->class) {
367*9676Slinton 	case PROC:
368*9676Slinton 	case FUNC:
369*9676Slinton 	    s = pop(Symbol);
370*9676Slinton 	    printf("%s", symname(s));
371*9676Slinton 	    break;
372*9676Slinton 
373*9676Slinton 	default:
374*9676Slinton 	    if (t->language == nil) {
375*9676Slinton 		error("unknown language");
376*9676Slinton 	    } else {
377*9676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
378*9676Slinton 	    }
379*9676Slinton 	    break;
380*9676Slinton     }
381*9676Slinton }
382*9676Slinton 
383*9676Slinton /*
384*9676Slinton  * Print out the value of a record, field by field.
385*9676Slinton  */
386*9676Slinton 
387*9676Slinton public printrecord(s)
388*9676Slinton Symbol s;
389*9676Slinton {
390*9676Slinton     if (s->chain == nil) {
391*9676Slinton 	error("record has no fields");
392*9676Slinton     }
393*9676Slinton     printf("(");
394*9676Slinton     sp -= size(s);
395*9676Slinton     printfield(s->chain);
396*9676Slinton     printf(")");
397*9676Slinton }
398*9676Slinton 
399*9676Slinton /*
400*9676Slinton  * Print out a field, first printing out other fields.
401*9676Slinton  * This is done because the fields are chained together backwards.
402*9676Slinton  */
403*9676Slinton 
404*9676Slinton private printfield(s)
405*9676Slinton Symbol s;
406*9676Slinton {
407*9676Slinton     Stack *savesp;
408*9676Slinton 
409*9676Slinton     if (s->chain != nil) {
410*9676Slinton 	printfield(s->chain);
411*9676Slinton 	printf(", ");
412*9676Slinton     }
413*9676Slinton     printf("%s = ", symname(s));
414*9676Slinton     savesp = sp;
415*9676Slinton     sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type));
416*9676Slinton     printval(s);
417*9676Slinton     sp = savesp;
418*9676Slinton }
419*9676Slinton 
420*9676Slinton /*
421*9676Slinton  * Print out the contents of an array.
422*9676Slinton  * Haven't quite figured out what the best format is.
423*9676Slinton  *
424*9676Slinton  * This is rather inefficient.
425*9676Slinton  *
426*9676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
427*9676Slinton  */
428*9676Slinton 
429*9676Slinton public printarray(a)
430*9676Slinton Symbol a;
431*9676Slinton {
432*9676Slinton     Stack *savesp, *newsp;
433*9676Slinton     Symbol eltype;
434*9676Slinton     long elsize;
435*9676Slinton     String sep;
436*9676Slinton 
437*9676Slinton     savesp = sp;
438*9676Slinton     sp -= size(a);
439*9676Slinton     newsp = sp;
440*9676Slinton     eltype = rtype(a->type);
441*9676Slinton     elsize = size(eltype);
442*9676Slinton     printf("(");
443*9676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
444*9676Slinton       eltype->class == VARNT) {
445*9676Slinton 	sep = "\n";
446*9676Slinton 	putchar('\n');
447*9676Slinton     } else {
448*9676Slinton 	sep = ", ";
449*9676Slinton     }
450*9676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
451*9676Slinton 	if (sp - elsize != newsp) {
452*9676Slinton 	    fputs(sep, stdout);
453*9676Slinton 	}
454*9676Slinton 	printval(eltype);
455*9676Slinton     }
456*9676Slinton     sp = newsp;
457*9676Slinton     if (streq(sep, "\n")) {
458*9676Slinton 	putchar('\n');
459*9676Slinton     }
460*9676Slinton     printf(")");
461*9676Slinton }
462*9676Slinton 
463*9676Slinton /*
464*9676Slinton  * Print out the value of a real number in Pascal notation.
465*9676Slinton  * This is, unfortunately, different than what one gets
466*9676Slinton  * from "%g" in printf.
467*9676Slinton  */
468*9676Slinton 
469*9676Slinton public prtreal(r)
470*9676Slinton double r;
471*9676Slinton {
472*9676Slinton     extern char *index();
473*9676Slinton     char buf[256];
474*9676Slinton 
475*9676Slinton     sprintf(buf, "%g", r);
476*9676Slinton     if (buf[0] == '.') {
477*9676Slinton 	printf("0%s", buf);
478*9676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
479*9676Slinton 	printf("-0%s", &buf[1]);
480*9676Slinton     } else {
481*9676Slinton 	printf("%s", buf);
482*9676Slinton     }
483*9676Slinton     if (index(buf, '.') == nil) {
484*9676Slinton 	printf(".0");
485*9676Slinton     }
486*9676Slinton }
487*9676Slinton 
488*9676Slinton /*
489*9676Slinton  * Print out a character using ^? notation for unprintables.
490*9676Slinton  */
491*9676Slinton 
492*9676Slinton public printchar(c)
493*9676Slinton char c;
494*9676Slinton {
495*9676Slinton     if (c == 0) {
496*9676Slinton 	putchar('\\');
497*9676Slinton 	putchar('0');
498*9676Slinton     } else if (c == '\n') {
499*9676Slinton 	putchar('\\');
500*9676Slinton 	putchar('n');
501*9676Slinton     } else if (c > 0 and c < ' ') {
502*9676Slinton 	putchar('^');
503*9676Slinton 	putchar(c - 1 + 'A');
504*9676Slinton     } else {
505*9676Slinton 	putchar(c);
506*9676Slinton     }
507*9676Slinton }
508