xref: /csrg-svn/old/dbx/printsym.c (revision 12628)
19676Slinton /* Copyright (c) 1982 Regents of the University of California */
29676Slinton 
3*12628Scsvaf static char sccsid[] = "@(#)printsym.c 1.7 05/20/83";
49676Slinton 
59676Slinton /*
69676Slinton  * Printing of symbolic information.
79676Slinton  */
89676Slinton 
99676Slinton #include "defs.h"
109676Slinton #include "symbols.h"
119676Slinton #include "languages.h"
129676Slinton #include "printsym.h"
139676Slinton #include "tree.h"
149676Slinton #include "eval.h"
159676Slinton #include "mappings.h"
169676Slinton #include "process.h"
179676Slinton #include "runtime.h"
189676Slinton #include "machine.h"
199676Slinton #include "names.h"
209676Slinton #include "main.h"
219676Slinton 
229676Slinton #ifndef public
239676Slinton #endif
249676Slinton 
259676Slinton /*
2611863Slinton  * Maximum number of arguments to a function.
2711863Slinton  * This is used as a check for the possibility that the stack has been
2811863Slinton  * overwritten and therefore a saved argument pointer might indicate
2911863Slinton  * to an absurdly large number of arguments.
3011863Slinton  */
3111863Slinton 
3211863Slinton #define MAXARGSPASSED 20
3311863Slinton 
3411863Slinton /*
359676Slinton  * Return a pointer to the string for the name of the class that
369676Slinton  * the given symbol belongs to.
379676Slinton  */
389676Slinton 
399676Slinton private String clname[] = {
409676Slinton     "bad use", "constant", "type", "variable", "array", "fileptr",
419676Slinton     "record", "field", "procedure", "function", "funcvar",
429676Slinton     "ref", "pointer", "file", "set", "range", "label", "withptr",
439676Slinton     "scalar", "string", "program", "improper", "variant",
4412544Scsvaf     "procparam", "funcparam", "module", "tag", "common", "typeref"
459676Slinton };
469676Slinton 
479676Slinton public String classname(s)
489676Slinton Symbol s;
499676Slinton {
509676Slinton     return clname[ord(s->class)];
519676Slinton }
529676Slinton 
539676Slinton /*
549676Slinton  * Note the entry of the given block, unless it's the main program.
559676Slinton  */
569676Slinton 
579676Slinton public printentry(s)
589676Slinton Symbol s;
599676Slinton {
609676Slinton     if (s != program) {
619676Slinton 	printf("\nentering %s %s\n", classname(s), symname(s));
629676Slinton     }
639676Slinton }
649676Slinton 
659676Slinton /*
669676Slinton  * Note the exit of the given block
679676Slinton  */
689676Slinton 
699676Slinton public printexit(s)
709676Slinton Symbol s;
719676Slinton {
729676Slinton     if (s != program) {
739676Slinton 	printf("leaving %s %s\n\n", classname(s), symname(s));
749676Slinton     }
759676Slinton }
769676Slinton 
779676Slinton /*
789676Slinton  * Note the call of s from t.
799676Slinton  */
809676Slinton 
819676Slinton public printcall(s, t)
829676Slinton Symbol s, t;
839676Slinton {
849676Slinton     printf("calling %s", symname(s));
859676Slinton     printparams(s, nil);
869676Slinton     printf(" from %s %s\n", classname(t), symname(t));
879676Slinton }
889676Slinton 
899676Slinton /*
909676Slinton  * Note the return from s.  If s is a function, print the value
919676Slinton  * it is returning.  This is somewhat painful, since the function
929676Slinton  * has actually just returned.
939676Slinton  */
949676Slinton 
959676Slinton public printrtn(s)
969676Slinton Symbol s;
979676Slinton {
989676Slinton     register Symbol t;
999676Slinton     register int len;
1009676Slinton     Boolean isindirect;
1019676Slinton 
1029676Slinton     printf("returning ");
103*12628Scsvaf     if (s->class == FUNC && (!istypename(s->type,"void"))) {
1049676Slinton 	len = size(s->type);
1059676Slinton 	if (canpush(len)) {
1069676Slinton 	    t = rtype(s->type);
1079676Slinton 	    isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
1089676Slinton 	    pushretval(len, isindirect);
1099676Slinton 	    printval(s->type);
1109676Slinton 	    putchar(' ');
1119676Slinton 	} else {
1129676Slinton 	    printf("(value too large) ");
1139676Slinton 	}
1149676Slinton     }
1159676Slinton     printf("from %s\n", symname(s));
1169676Slinton }
1179676Slinton 
1189676Slinton /*
1199676Slinton  * Print the values of the parameters of the given procedure or function.
1209676Slinton  * The frame distinguishes recursive instances of a procedure.
1219676Slinton  */
1229676Slinton 
1239676Slinton public printparams(f, frame)
1249676Slinton Symbol f;
1259676Slinton Frame frame;
1269676Slinton {
1279676Slinton     Symbol param;
1289676Slinton     int n, m, s;
1299676Slinton 
1309676Slinton     n = nargspassed(frame);
1319676Slinton     param = f->chain;
1329676Slinton     if (param != nil or n > 0) {
1339676Slinton 	printf("(");
1349676Slinton 	m = n;
1359676Slinton 	if (param != nil) {
1369676Slinton 	    for (;;) {
1379676Slinton 		s = size(param) div sizeof(Word);
1389676Slinton 		if (s == 0) {
1399676Slinton 		    s = 1;
1409676Slinton 		}
1419676Slinton 		m -= s;
1429676Slinton 		printv(param, frame);
1439676Slinton 		param = param->chain;
1449676Slinton 	    if (param == nil) break;
1459676Slinton 		printf(", ");
1469676Slinton 	    }
1479676Slinton 	}
1489676Slinton 	if (m > 0) {
14911863Slinton 	    if (m > MAXARGSPASSED) {
15011863Slinton 		m = MAXARGSPASSED;
15111863Slinton 	    }
1529676Slinton 	    if (f->chain != nil) {
1539676Slinton 		printf(", ");
1549676Slinton 	    }
1559676Slinton 	    for (;;) {
1569676Slinton 		--m;
1579676Slinton 		printf("0x%x", argn(n - m, frame));
1589676Slinton 	    if (m <= 0) break;
1599676Slinton 		printf(", ");
1609676Slinton 	    }
1619676Slinton 	}
1629676Slinton 	printf(")");
1639676Slinton     }
1649676Slinton }
1659676Slinton 
1669676Slinton /*
1679676Slinton  * Test if a symbol should be printed.  We don't print files,
1689676Slinton  * for example, simply because there's no good way to do it.
1699676Slinton  * The symbol must be within the given function.
1709676Slinton  */
1719676Slinton 
1729676Slinton public Boolean should_print(s)
1739676Slinton Symbol s;
1749676Slinton {
1759676Slinton     Boolean b;
1769676Slinton     register Symbol t;
1779676Slinton 
1789676Slinton     switch (s->class) {
1799676Slinton 	case VAR:
1809676Slinton 	case FVAR:
1819676Slinton 	    t = rtype(s->type);
1829676Slinton 	    b = (Boolean) (
1839676Slinton 		not isparam(s) and
1849676Slinton 		t != nil and t->class != FILET and t->class != SET
1859676Slinton 	    );
1869676Slinton 	    break;
1879676Slinton 
1889676Slinton 	default:
1899676Slinton 	    b = false;
1909676Slinton 	    break;
1919676Slinton     }
1929676Slinton     return b;
1939676Slinton }
1949676Slinton 
1959676Slinton /*
1969676Slinton  * Print the name and value of a variable.
1979676Slinton  */
1989676Slinton 
1999676Slinton public printv(s, frame)
2009676Slinton Symbol s;
2019676Slinton Frame frame;
2029676Slinton {
2039676Slinton     Address addr;
2049676Slinton     int len;
2059676Slinton 
2069676Slinton     if (isambiguous(s) and ismodule(container(s))) {
2079676Slinton 	printname(stdout, s);
2089676Slinton 	printf(" = ");
2099676Slinton     } else {
2109676Slinton 	printf("%s = ", symname(s));
2119676Slinton     }
212*12628Scsvaf     if(s->type->class == ARRAY && (! istypename(s->type->type,"char")) ) {
213*12628Scsvaf 	printf(" ARRAY ");
2149676Slinton     } else {
215*12628Scsvaf        if (isvarparam(s)) {
216*12628Scsvaf 	   rpush(address(s, frame), sizeof(Address));
217*12628Scsvaf 	   addr = pop(Address);
218*12628Scsvaf 	   len = size(s->type);
219*12628Scsvaf        } else {
220*12628Scsvaf 	   addr = address(s, frame);
221*12628Scsvaf 	   len = size(s);
222*12628Scsvaf        }
223*12628Scsvaf        if (canpush(len)) {
224*12628Scsvaf 	   rpush(addr, len);
225*12628Scsvaf 	   printval(s->type);
226*12628Scsvaf        } else {
227*12628Scsvaf 	   printf("*** expression too large ***");
228*12628Scsvaf        }
229*12628Scsvaf    }
2309676Slinton }
2319676Slinton 
2329676Slinton /*
2339676Slinton  * Print out the name of a symbol.
2349676Slinton  */
2359676Slinton 
2369676Slinton public printname(f, s)
2379676Slinton File f;
2389676Slinton Symbol s;
2399676Slinton {
2409676Slinton     if (s == nil) {
2419676Slinton 	fprintf(f, "(noname)");
2429676Slinton     } else if (isredirected() or isambiguous(s)) {
2439676Slinton 	printwhich(f, s);
2449676Slinton     } else {
2459676Slinton 	fprintf(f, "%s", symname(s));
2469676Slinton     }
2479676Slinton }
2489676Slinton 
2499676Slinton /*
2509676Slinton  * Print the fully specified variable that is described by the given identifer.
2519676Slinton  */
2529676Slinton 
2539676Slinton public printwhich(f, s)
2549676Slinton File f;
2559676Slinton Symbol s;
2569676Slinton {
2579676Slinton     printouter(f, container(s));
2589676Slinton     fprintf(f, "%s", symname(s));
2599676Slinton }
2609676Slinton 
2619676Slinton /*
2629676Slinton  * Print the fully qualified name of each symbol that has the same name
2639676Slinton  * as the given symbol.
2649676Slinton  */
2659676Slinton 
2669676Slinton public printwhereis(f, s)
2679676Slinton File f;
2689676Slinton Symbol s;
2699676Slinton {
2709676Slinton     register Name n;
2719676Slinton     register Symbol t;
2729676Slinton 
2739676Slinton     checkref(s);
2749676Slinton     n = s->name;
2759676Slinton     t = lookup(n);
2769676Slinton     printwhich(f, t);
2779676Slinton     t = t->next_sym;
2789676Slinton     while (t != nil) {
2799676Slinton 	if (t->name == n) {
2809676Slinton 	    putc(' ', f);
2819676Slinton 	    printwhich(f, t);
2829676Slinton 	}
2839676Slinton 	t = t->next_sym;
2849676Slinton     }
2859676Slinton     putc('\n', f);
2869676Slinton }
2879676Slinton 
2889676Slinton private printouter(f, s)
2899676Slinton File f;
2909676Slinton Symbol s;
2919676Slinton {
2929676Slinton     Symbol outer;
2939676Slinton 
2949676Slinton     if (s != nil) {
2959676Slinton 	outer = container(s);
2969676Slinton 	if (outer != nil and outer != program) {
2979676Slinton 	    printouter(f, outer);
2989676Slinton 	}
2999676Slinton 	fprintf(f, "%s.", symname(s));
3009676Slinton     }
3019676Slinton }
3029676Slinton 
3039676Slinton public printdecl(s)
3049676Slinton Symbol s;
3059676Slinton {
3069676Slinton     checkref(s);
3079676Slinton     (*language_op(s->language, L_PRINTDECL))(s);
3089676Slinton }
3099676Slinton 
3109676Slinton /*
3119676Slinton  * Straight dump of symbol information.
3129676Slinton  */
3139676Slinton 
3149676Slinton public psym(s)
3159676Slinton Symbol s;
3169676Slinton {
3179676Slinton     printf("name\t%s\n", symname(s));
3189676Slinton     printf("lang\t%s\n", language_name(s->language));
3199676Slinton     printf("level\t%d\n", s->level);
3209676Slinton     printf("class\t%s\n", classname(s));
3219676Slinton     printf("type\t0x%x", s->type);
3229676Slinton     if (s->type != nil and s->type->name != nil) {
3239676Slinton 	printf(" (%s)", symname(s->type));
3249676Slinton     }
3259676Slinton     printf("\nchain\t0x%x", s->chain);
3269676Slinton     if (s->chain != nil and s->chain->name != nil) {
3279676Slinton 	printf(" (%s)", symname(s->chain));
3289676Slinton     }
3299676Slinton     printf("\nblock\t0x%x", s->block);
3309676Slinton     if (s->block->name != nil) {
3319676Slinton 	printf(" (");
3329676Slinton 	printname(stdout, s->block);
3339676Slinton 	putchar(')');
3349676Slinton     }
3359676Slinton     putchar('\n');
3369676Slinton     switch (s->class) {
3379676Slinton 	case VAR:
3389676Slinton 	case REF:
3399676Slinton 	    if (s->level >= 3) {
3409676Slinton 		printf("address\t0x%x\n", s->symvalue.offset);
3419676Slinton 	    } else {
3429676Slinton 		printf("offset\t%d\n", s->symvalue.offset);
3439676Slinton 	    }
34412545Scsvaf 	    printf("size\t%d\n", size(s));
3459676Slinton 	    break;
3469676Slinton 
3479676Slinton 	case RECORD:
3489676Slinton 	case VARNT:
3499676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
3509676Slinton 	    break;
3519676Slinton 
3529676Slinton 	case FIELD:
3539676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
3549676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
3559676Slinton 	    break;
3569676Slinton 
3579676Slinton 	case PROC:
3589676Slinton 	case FUNC:
3599676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
36011863Slinton 	    if (nosource(s)) {
36111863Slinton 		printf("does not have source information\n");
36211863Slinton 	    } else {
36311863Slinton 		printf("has source information\n");
36411863Slinton 	    }
3659676Slinton 	    break;
3669676Slinton 
3679676Slinton 	case RANGE:
36812544Scsvaf             switch(s->symvalue.rangev.lowertype) {
36912544Scsvaf 
37012544Scsvaf 	      case R_CONST :  printf("CONST");
37112544Scsvaf 		              break;
37212544Scsvaf 	      case R_ARG :    printf("ARG");
37312544Scsvaf 			      break;
37412544Scsvaf 	      case R_TEMP :   printf("TEMP");
37512544Scsvaf 			      break;
37612544Scsvaf 	      case R_ADJUST : printf("ADJUST");
37712544Scsvaf 			      break;
37812544Scsvaf             }
3799676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
38012544Scsvaf 
38112544Scsvaf             switch(s->symvalue.rangev.uppertype) {
38212544Scsvaf 
38312544Scsvaf 	      case R_CONST :  printf("CONST");
38412544Scsvaf 		              break;
38512544Scsvaf 	      case R_ARG :    printf("ARG");
38612544Scsvaf 			      break;
38712544Scsvaf 	      case R_TEMP :   printf("TEMP");
38812544Scsvaf 			      break;
38912544Scsvaf 	      case R_ADJUST : printf("ADJUST");
39012544Scsvaf 			      break;
39112544Scsvaf             }
39212544Scsvaf 
3939676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
3949676Slinton 	    break;
3959676Slinton 
3969676Slinton 	default:
3979676Slinton 	    /* do nothing */
3989676Slinton 	    break;
3999676Slinton     }
4009676Slinton }
4019676Slinton 
4029676Slinton /*
4039676Slinton  * Print out the value on top of the stack according to the given type.
4049676Slinton  */
4059676Slinton 
4069676Slinton public printval(t)
4079676Slinton Symbol t;
4089676Slinton {
4099676Slinton     Symbol s;
4109676Slinton 
4119676Slinton     checkref(t);
4129676Slinton     switch (t->class) {
4139676Slinton 	case PROC:
4149676Slinton 	case FUNC:
4159676Slinton 	    s = pop(Symbol);
4169676Slinton 	    printf("%s", symname(s));
4179676Slinton 	    break;
4189676Slinton 
4199676Slinton 	default:
4209676Slinton 	    if (t->language == nil) {
4219676Slinton 		error("unknown language");
4229676Slinton 	    } else {
4239676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
4249676Slinton 	    }
4259676Slinton 	    break;
4269676Slinton     }
4279676Slinton }
4289676Slinton 
4299676Slinton /*
4309676Slinton  * Print out the value of a record, field by field.
4319676Slinton  */
4329676Slinton 
4339676Slinton public printrecord(s)
4349676Slinton Symbol s;
4359676Slinton {
4369676Slinton     if (s->chain == nil) {
4379676Slinton 	error("record has no fields");
4389676Slinton     }
4399676Slinton     printf("(");
4409676Slinton     sp -= size(s);
4419676Slinton     printfield(s->chain);
4429676Slinton     printf(")");
4439676Slinton }
4449676Slinton 
4459676Slinton /*
4469676Slinton  * Print out a field, first printing out other fields.
4479676Slinton  * This is done because the fields are chained together backwards.
4489676Slinton  */
4499676Slinton 
4509676Slinton private printfield(s)
4519676Slinton Symbol s;
4529676Slinton {
4539676Slinton     Stack *savesp;
4549676Slinton 
4559676Slinton     if (s->chain != nil) {
4569676Slinton 	printfield(s->chain);
4579676Slinton 	printf(", ");
4589676Slinton     }
4599676Slinton     printf("%s = ", symname(s));
4609676Slinton     savesp = sp;
4619676Slinton     sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type));
4629676Slinton     printval(s);
4639676Slinton     sp = savesp;
4649676Slinton }
4659676Slinton 
4669676Slinton /*
4679676Slinton  * Print out the contents of an array.
4689676Slinton  * Haven't quite figured out what the best format is.
4699676Slinton  *
4709676Slinton  * This is rather inefficient.
4719676Slinton  *
4729676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
4739676Slinton  */
4749676Slinton 
4759676Slinton public printarray(a)
4769676Slinton Symbol a;
4779676Slinton {
4789676Slinton     Stack *savesp, *newsp;
4799676Slinton     Symbol eltype;
4809676Slinton     long elsize;
4819676Slinton     String sep;
4829676Slinton 
4839676Slinton     savesp = sp;
48412544Scsvaf     sp -= (size(a));
4859676Slinton     newsp = sp;
4869676Slinton     eltype = rtype(a->type);
4879676Slinton     elsize = size(eltype);
4889676Slinton     printf("(");
4899676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
4909676Slinton       eltype->class == VARNT) {
4919676Slinton 	sep = "\n";
4929676Slinton 	putchar('\n');
4939676Slinton     } else {
4949676Slinton 	sep = ", ";
4959676Slinton     }
4969676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
4979676Slinton 	if (sp - elsize != newsp) {
4989676Slinton 	    fputs(sep, stdout);
4999676Slinton 	}
5009676Slinton 	printval(eltype);
5019676Slinton     }
5029676Slinton     sp = newsp;
5039676Slinton     if (streq(sep, "\n")) {
5049676Slinton 	putchar('\n');
5059676Slinton     }
5069676Slinton     printf(")");
5079676Slinton }
5089676Slinton 
5099676Slinton /*
5109676Slinton  * Print out the value of a real number in Pascal notation.
5119676Slinton  * This is, unfortunately, different than what one gets
5129676Slinton  * from "%g" in printf.
5139676Slinton  */
5149676Slinton 
5159676Slinton public prtreal(r)
5169676Slinton double r;
5179676Slinton {
5189676Slinton     extern char *index();
5199676Slinton     char buf[256];
5209676Slinton 
5219676Slinton     sprintf(buf, "%g", r);
5229676Slinton     if (buf[0] == '.') {
5239676Slinton 	printf("0%s", buf);
5249676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
5259676Slinton 	printf("-0%s", &buf[1]);
5269676Slinton     } else {
5279676Slinton 	printf("%s", buf);
5289676Slinton     }
5299676Slinton     if (index(buf, '.') == nil) {
5309676Slinton 	printf(".0");
5319676Slinton     }
5329676Slinton }
5339676Slinton 
5349676Slinton /*
5359676Slinton  * Print out a character using ^? notation for unprintables.
5369676Slinton  */
5379676Slinton 
5389676Slinton public printchar(c)
5399676Slinton char c;
5409676Slinton {
5419676Slinton     if (c == 0) {
5429676Slinton 	putchar('\\');
5439676Slinton 	putchar('0');
5449676Slinton     } else if (c == '\n') {
5459676Slinton 	putchar('\\');
5469676Slinton 	putchar('n');
5479676Slinton     } else if (c > 0 and c < ' ') {
5489676Slinton 	putchar('^');
5499676Slinton 	putchar(c - 1 + 'A');
5509676Slinton     } else {
5519676Slinton 	putchar(c);
5529676Slinton     }
5539676Slinton }
554