xref: /csrg-svn/old/dbx/printsym.c (revision 18229)
19676Slinton /* Copyright (c) 1982 Regents of the University of California */
29676Slinton 
3*18229Slinton static	char sccsid[] = "@(#)printsym.c	1.14 (Berkeley) 03/01/85";
49676Slinton 
5*18229Slinton static char rcsid[] = "$Header: printsym.c,v 1.5 84/12/26 10:41:28 linton Exp $";
6*18229Slinton 
79676Slinton /*
89676Slinton  * Printing of symbolic information.
99676Slinton  */
109676Slinton 
119676Slinton #include "defs.h"
129676Slinton #include "symbols.h"
139676Slinton #include "languages.h"
149676Slinton #include "printsym.h"
159676Slinton #include "tree.h"
169676Slinton #include "eval.h"
179676Slinton #include "mappings.h"
189676Slinton #include "process.h"
199676Slinton #include "runtime.h"
209676Slinton #include "machine.h"
219676Slinton #include "names.h"
22*18229Slinton #include "keywords.h"
239676Slinton #include "main.h"
249676Slinton 
259676Slinton #ifndef public
269676Slinton #endif
279676Slinton 
289676Slinton /*
2911863Slinton  * Maximum number of arguments to a function.
3011863Slinton  * This is used as a check for the possibility that the stack has been
3111863Slinton  * overwritten and therefore a saved argument pointer might indicate
3211863Slinton  * to an absurdly large number of arguments.
3311863Slinton  */
3411863Slinton 
3511863Slinton #define MAXARGSPASSED 20
3611863Slinton 
3711863Slinton /*
389676Slinton  * Return a pointer to the string for the name of the class that
399676Slinton  * the given symbol belongs to.
409676Slinton  */
419676Slinton 
429676Slinton private String clname[] = {
43*18229Slinton     "bad use", "constant", "type", "variable", "array", "@dynarray",
44*18229Slinton     "@subarray", "fileptr", "record", "field",
45*18229Slinton     "procedure", "function", "funcvar",
469676Slinton     "ref", "pointer", "file", "set", "range", "label", "withptr",
479676Slinton     "scalar", "string", "program", "improper", "variant",
4816616Ssam     "procparam", "funcparam", "module", "tag", "common", "extref", "typeref"
499676Slinton };
509676Slinton 
519676Slinton public String classname(s)
529676Slinton Symbol s;
539676Slinton {
549676Slinton     return clname[ord(s->class)];
559676Slinton }
569676Slinton 
579676Slinton /*
589676Slinton  * Note the entry of the given block, unless it's the main program.
599676Slinton  */
609676Slinton 
619676Slinton public printentry(s)
629676Slinton Symbol s;
639676Slinton {
649676Slinton     if (s != program) {
65*18229Slinton 	printf("\nentering %s ", classname(s));
66*18229Slinton 	printname(stdout, s);
67*18229Slinton 	printf("\n");
689676Slinton     }
699676Slinton }
709676Slinton 
719676Slinton /*
729676Slinton  * Note the exit of the given block
739676Slinton  */
749676Slinton 
759676Slinton public printexit(s)
769676Slinton Symbol s;
779676Slinton {
789676Slinton     if (s != program) {
79*18229Slinton 	printf("leaving %s ", classname(s));
80*18229Slinton 	printname(stdout, s);
81*18229Slinton 	printf("\n\n");
829676Slinton     }
839676Slinton }
849676Slinton 
859676Slinton /*
869676Slinton  * Note the call of s from t.
879676Slinton  */
889676Slinton 
899676Slinton public printcall(s, t)
909676Slinton Symbol s, t;
919676Slinton {
92*18229Slinton     printf("calling ");
93*18229Slinton     printname(stdout, s);
949676Slinton     printparams(s, nil);
95*18229Slinton     printf(" from %s ", classname(t));
96*18229Slinton     printname(stdout, t);
97*18229Slinton     printf("\n");
989676Slinton }
999676Slinton 
1009676Slinton /*
1019676Slinton  * Note the return from s.  If s is a function, print the value
1029676Slinton  * it is returning.  This is somewhat painful, since the function
1039676Slinton  * has actually just returned.
1049676Slinton  */
1059676Slinton 
1069676Slinton public printrtn(s)
1079676Slinton Symbol s;
1089676Slinton {
1099676Slinton     register Symbol t;
1109676Slinton     register int len;
1119676Slinton     Boolean isindirect;
1129676Slinton 
1139676Slinton     printf("returning ");
11412628Scsvaf     if (s->class == FUNC && (!istypename(s->type,"void"))) {
1159676Slinton 	len = size(s->type);
1169676Slinton 	if (canpush(len)) {
1179676Slinton 	    t = rtype(s->type);
1189676Slinton 	    isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
1199676Slinton 	    pushretval(len, isindirect);
1209676Slinton 	    printval(s->type);
1219676Slinton 	    putchar(' ');
1229676Slinton 	} else {
1239676Slinton 	    printf("(value too large) ");
1249676Slinton 	}
1259676Slinton     }
126*18229Slinton     printf("from ");
127*18229Slinton     printname(stdout, s);
128*18229Slinton     printf("\n");
1299676Slinton }
1309676Slinton 
1319676Slinton /*
1329676Slinton  * Print the values of the parameters of the given procedure or function.
1339676Slinton  * The frame distinguishes recursive instances of a procedure.
13416616Ssam  *
13516616Ssam  * If the procedure or function is internal, the argument count is
13616616Ssam  * not valid so we ignore it.
1379676Slinton  */
1389676Slinton 
1399676Slinton public printparams(f, frame)
1409676Slinton Symbol f;
1419676Slinton Frame frame;
1429676Slinton {
1439676Slinton     Symbol param;
1449676Slinton     int n, m, s;
1459676Slinton 
1469676Slinton     n = nargspassed(frame);
14716616Ssam     if (isinternal(f)) {
14816616Ssam 	n = 0;
14916616Ssam     }
150*18229Slinton     printf("(");
1519676Slinton     param = f->chain;
1529676Slinton     if (param != nil or n > 0) {
1539676Slinton 	m = n;
1549676Slinton 	if (param != nil) {
1559676Slinton 	    for (;;) {
156*18229Slinton 		s = psize(param) div sizeof(Word);
1579676Slinton 		if (s == 0) {
1589676Slinton 		    s = 1;
1599676Slinton 		}
1609676Slinton 		m -= s;
161*18229Slinton 		if (showaggrs) {
162*18229Slinton 		    printv(param, frame);
163*18229Slinton 		} else {
164*18229Slinton 		    printparamv(param, frame);
165*18229Slinton 		}
1669676Slinton 		param = param->chain;
1679676Slinton 	    if (param == nil) break;
1689676Slinton 		printf(", ");
1699676Slinton 	    }
1709676Slinton 	}
1719676Slinton 	if (m > 0) {
17211863Slinton 	    if (m > MAXARGSPASSED) {
17311863Slinton 		m = MAXARGSPASSED;
17411863Slinton 	    }
1759676Slinton 	    if (f->chain != nil) {
1769676Slinton 		printf(", ");
1779676Slinton 	    }
1789676Slinton 	    for (;;) {
1799676Slinton 		--m;
1809676Slinton 		printf("0x%x", argn(n - m, frame));
1819676Slinton 	    if (m <= 0) break;
1829676Slinton 		printf(", ");
1839676Slinton 	    }
1849676Slinton 	}
1859676Slinton     }
186*18229Slinton     printf(")");
1879676Slinton }
1889676Slinton 
1899676Slinton /*
1909676Slinton  * Test if a symbol should be printed.  We don't print files,
1919676Slinton  * for example, simply because there's no good way to do it.
1929676Slinton  * The symbol must be within the given function.
1939676Slinton  */
1949676Slinton 
1959676Slinton public Boolean should_print(s)
1969676Slinton Symbol s;
1979676Slinton {
1989676Slinton     Boolean b;
1999676Slinton     register Symbol t;
2009676Slinton 
2019676Slinton     switch (s->class) {
2029676Slinton 	case VAR:
2039676Slinton 	case FVAR:
20414339Slinton 	    if (isparam(s)) {
20514339Slinton 		b = false;
20614339Slinton 	    } else {
20714339Slinton 		t = rtype(s->type);
20814339Slinton 		if (t == nil) {
20914339Slinton 		    b = false;
21014339Slinton 		} else {
21114339Slinton 		    switch (t->class) {
21214339Slinton 			case FILET:
21314339Slinton 			case SET:
21414339Slinton 			case BADUSE:
21514339Slinton 			    b = false;
21614339Slinton 			    break;
21714339Slinton 
21814339Slinton 			default:
21914339Slinton 			    b = true;
22014339Slinton 			    break;
22114339Slinton 		    }
22214339Slinton 		}
22314339Slinton 	    }
2249676Slinton 	    break;
2259676Slinton 
2269676Slinton 	default:
2279676Slinton 	    b = false;
2289676Slinton 	    break;
2299676Slinton     }
2309676Slinton     return b;
2319676Slinton }
2329676Slinton 
2339676Slinton /*
234*18229Slinton  * Print out a parameter value.
235*18229Slinton  *
236*18229Slinton  * Since this is intended to be printed on a single line with other information
237*18229Slinton  * aggregate values are not printed.
238*18229Slinton  */
239*18229Slinton 
240*18229Slinton public printparamv (p, frame)
241*18229Slinton Symbol p;
242*18229Slinton Frame frame;
243*18229Slinton {
244*18229Slinton     Symbol t;
245*18229Slinton 
246*18229Slinton     t = rtype(p->type);
247*18229Slinton     switch (t->class) {
248*18229Slinton 	case ARRAY:
249*18229Slinton 	case DYNARRAY:
250*18229Slinton 	case SUBARRAY:
251*18229Slinton 	    t = rtype(t->type);
252*18229Slinton 	    if (compatible(t, t_char)) {
253*18229Slinton 		printv(p, frame);
254*18229Slinton 	    } else {
255*18229Slinton 		printf("%s = (...)", symname(p));
256*18229Slinton 	    }
257*18229Slinton 	    break;
258*18229Slinton 
259*18229Slinton 	case RECORD:
260*18229Slinton 	    printf("%s = (...)", symname(p));
261*18229Slinton 	    break;
262*18229Slinton 
263*18229Slinton 	default:
264*18229Slinton 	    printv(p, frame);
265*18229Slinton 	    break;
266*18229Slinton     }
267*18229Slinton }
268*18229Slinton 
269*18229Slinton /*
2709676Slinton  * Print the name and value of a variable.
2719676Slinton  */
2729676Slinton 
2739676Slinton public printv(s, frame)
2749676Slinton Symbol s;
2759676Slinton Frame frame;
2769676Slinton {
2779676Slinton     Address addr;
2789676Slinton     int len;
27916616Ssam     Symbol t;
2809676Slinton 
2819676Slinton     if (isambiguous(s) and ismodule(container(s))) {
2829676Slinton 	printname(stdout, s);
2839676Slinton 	printf(" = ");
2849676Slinton     } else {
2859676Slinton 	printf("%s = ", symname(s));
2869676Slinton     }
287*18229Slinton     if (isvarparam(s) and not isopenarray(s)) {
288*18229Slinton 	rpush(address(s, frame), sizeof(Address));
289*18229Slinton 	addr = pop(Address);
2909676Slinton     } else {
291*18229Slinton 	addr = address(s, frame);
292*18229Slinton     }
293*18229Slinton     len = size(s);
294*18229Slinton     if (canpush(len)) {
295*18229Slinton 	rpush(addr, len);
296*18229Slinton 	printval(s->type);
297*18229Slinton     } else {
298*18229Slinton 	printf("*** expression too large ***");
299*18229Slinton     }
3009676Slinton }
3019676Slinton 
3029676Slinton /*
3039676Slinton  * Print out the name of a symbol.
3049676Slinton  */
3059676Slinton 
3069676Slinton public printname(f, s)
3079676Slinton File f;
3089676Slinton Symbol s;
3099676Slinton {
3109676Slinton     if (s == nil) {
3119676Slinton 	fprintf(f, "(noname)");
31216616Ssam     } else if (s == program) {
31316616Ssam 	fprintf(f, ".");
3149676Slinton     } else if (isredirected() or isambiguous(s)) {
3159676Slinton 	printwhich(f, s);
3169676Slinton     } else {
3179676Slinton 	fprintf(f, "%s", symname(s));
3189676Slinton     }
3199676Slinton }
3209676Slinton 
3219676Slinton /*
3229676Slinton  * Print the fully specified variable that is described by the given identifer.
3239676Slinton  */
3249676Slinton 
3259676Slinton public printwhich(f, s)
3269676Slinton File f;
3279676Slinton Symbol s;
3289676Slinton {
3299676Slinton     printouter(f, container(s));
3309676Slinton     fprintf(f, "%s", symname(s));
3319676Slinton }
3329676Slinton 
3339676Slinton /*
3349676Slinton  * Print the fully qualified name of each symbol that has the same name
3359676Slinton  * as the given symbol.
3369676Slinton  */
3379676Slinton 
3389676Slinton public printwhereis(f, s)
3399676Slinton File f;
3409676Slinton Symbol s;
3419676Slinton {
3429676Slinton     register Name n;
3439676Slinton     register Symbol t;
3449676Slinton 
3459676Slinton     checkref(s);
3469676Slinton     n = s->name;
3479676Slinton     t = lookup(n);
3489676Slinton     printwhich(f, t);
3499676Slinton     t = t->next_sym;
3509676Slinton     while (t != nil) {
3519676Slinton 	if (t->name == n) {
3529676Slinton 	    putc(' ', f);
3539676Slinton 	    printwhich(f, t);
3549676Slinton 	}
3559676Slinton 	t = t->next_sym;
3569676Slinton     }
3579676Slinton     putc('\n', f);
3589676Slinton }
3599676Slinton 
3609676Slinton private printouter(f, s)
3619676Slinton File f;
3629676Slinton Symbol s;
3639676Slinton {
3649676Slinton     Symbol outer;
3659676Slinton 
3669676Slinton     if (s != nil) {
3679676Slinton 	outer = container(s);
3689676Slinton 	if (outer != nil and outer != program) {
3699676Slinton 	    printouter(f, outer);
3709676Slinton 	}
3719676Slinton 	fprintf(f, "%s.", symname(s));
3729676Slinton     }
3739676Slinton }
3749676Slinton 
3759676Slinton public printdecl(s)
3769676Slinton Symbol s;
3779676Slinton {
378*18229Slinton     Language lang;
379*18229Slinton 
3809676Slinton     checkref(s);
381*18229Slinton     if (s->language == nil or s->language == primlang) {
382*18229Slinton 	lang = findlanguage(".s");
383*18229Slinton     } else {
384*18229Slinton 	lang = s->language;
385*18229Slinton     }
386*18229Slinton     (*language_op(lang, L_PRINTDECL))(s);
3879676Slinton }
3889676Slinton 
3899676Slinton /*
3909676Slinton  * Straight dump of symbol information.
3919676Slinton  */
3929676Slinton 
3939676Slinton public psym(s)
3949676Slinton Symbol s;
3959676Slinton {
3969676Slinton     printf("name\t%s\n", symname(s));
3979676Slinton     printf("lang\t%s\n", language_name(s->language));
3989676Slinton     printf("level\t%d\n", s->level);
3999676Slinton     printf("class\t%s\n", classname(s));
4009676Slinton     printf("type\t0x%x", s->type);
4019676Slinton     if (s->type != nil and s->type->name != nil) {
4029676Slinton 	printf(" (%s)", symname(s->type));
4039676Slinton     }
4049676Slinton     printf("\nchain\t0x%x", s->chain);
4059676Slinton     if (s->chain != nil and s->chain->name != nil) {
4069676Slinton 	printf(" (%s)", symname(s->chain));
4079676Slinton     }
4089676Slinton     printf("\nblock\t0x%x", s->block);
4099676Slinton     if (s->block->name != nil) {
4109676Slinton 	printf(" (");
4119676Slinton 	printname(stdout, s->block);
4129676Slinton 	putchar(')');
4139676Slinton     }
4149676Slinton     putchar('\n');
4159676Slinton     switch (s->class) {
416*18229Slinton 	case TYPE:
417*18229Slinton 	    printf("size\t%d\n", size(s));
418*18229Slinton 	    break;
419*18229Slinton 
4209676Slinton 	case VAR:
4219676Slinton 	case REF:
4229676Slinton 	    if (s->level >= 3) {
4239676Slinton 		printf("address\t0x%x\n", s->symvalue.offset);
4249676Slinton 	    } else {
4259676Slinton 		printf("offset\t%d\n", s->symvalue.offset);
4269676Slinton 	    }
42712545Scsvaf 	    printf("size\t%d\n", size(s));
4289676Slinton 	    break;
4299676Slinton 
4309676Slinton 	case RECORD:
4319676Slinton 	case VARNT:
4329676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
4339676Slinton 	    break;
4349676Slinton 
4359676Slinton 	case FIELD:
4369676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
4379676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
4389676Slinton 	    break;
4399676Slinton 
44014381Slinton 	case PROG:
4419676Slinton 	case PROC:
4429676Slinton 	case FUNC:
4439676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
44414438Slinton 	    if (isinline(s)) {
44514440Slinton 		printf("inline procedure\n");
44614438Slinton 	    }
44711863Slinton 	    if (nosource(s)) {
44811863Slinton 		printf("does not have source information\n");
44911863Slinton 	    } else {
45011863Slinton 		printf("has source information\n");
45111863Slinton 	    }
4529676Slinton 	    break;
4539676Slinton 
4549676Slinton 	case RANGE:
45514381Slinton 	    prangetype(s->symvalue.rangev.lowertype);
4569676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
45714381Slinton 	    prangetype(s->symvalue.rangev.uppertype);
4589676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
4599676Slinton 	    break;
4609676Slinton 
4619676Slinton 	default:
4629676Slinton 	    /* do nothing */
4639676Slinton 	    break;
4649676Slinton     }
4659676Slinton }
4669676Slinton 
46714381Slinton private prangetype(r)
46814381Slinton Rangetype r;
46914381Slinton {
47014381Slinton     switch (r) {
47114381Slinton 	case R_CONST:
47214381Slinton 	    printf("CONST");
47314381Slinton 	    break;
47414381Slinton 
47514381Slinton 	case R_ARG:
47614381Slinton 	    printf("ARG");
47714381Slinton 	    break;
47814381Slinton 
47914381Slinton 	case R_TEMP:
48014381Slinton 	    printf("TEMP");
48114381Slinton 	    break;
48214381Slinton 
48314381Slinton 	case R_ADJUST:
48414381Slinton 	    printf("ADJUST");
48514381Slinton 	    break;
48614381Slinton     }
48714381Slinton }
48814381Slinton 
4899676Slinton /*
4909676Slinton  * Print out the value on top of the stack according to the given type.
4919676Slinton  */
4929676Slinton 
4939676Slinton public printval(t)
4949676Slinton Symbol t;
4959676Slinton {
4969676Slinton     Symbol s;
4979676Slinton 
4989676Slinton     checkref(t);
49916616Ssam     if (t->class == TYPEREF) {
50016616Ssam 	resolveRef(t);
50116616Ssam     }
5029676Slinton     switch (t->class) {
5039676Slinton 	case PROC:
5049676Slinton 	case FUNC:
5059676Slinton 	    s = pop(Symbol);
5069676Slinton 	    printf("%s", symname(s));
5079676Slinton 	    break;
5089676Slinton 
5099676Slinton 	default:
510*18229Slinton 	    if (t->language == nil or t->language == primlang) {
51116616Ssam 		(*language_op(findlanguage(".c"), L_PRINTVAL))(t);
5129676Slinton 	    } else {
5139676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
5149676Slinton 	    }
5159676Slinton 	    break;
5169676Slinton     }
5179676Slinton }
5189676Slinton 
5199676Slinton /*
5209676Slinton  * Print out the value of a record, field by field.
5219676Slinton  */
5229676Slinton 
5239676Slinton public printrecord(s)
5249676Slinton Symbol s;
5259676Slinton {
52616616Ssam     Symbol f;
52716616Ssam 
5289676Slinton     if (s->chain == nil) {
5299676Slinton 	error("record has no fields");
5309676Slinton     }
5319676Slinton     printf("(");
5329676Slinton     sp -= size(s);
53316616Ssam     f = s->chain;
53416616Ssam     if (f != nil) {
53516616Ssam 	for (;;) {
53616616Ssam 	    printfield(f);
53716616Ssam 	    f = f->chain;
53816616Ssam 	if (f == nil) break;
53916616Ssam 	    printf(", ");
54016616Ssam 	}
54116616Ssam     }
5429676Slinton     printf(")");
5439676Slinton }
5449676Slinton 
5459676Slinton /*
54616616Ssam  * Print out a field.
5479676Slinton  */
5489676Slinton 
54916616Ssam private printfield(f)
55016616Ssam Symbol f;
5519676Slinton {
5529676Slinton     Stack *savesp;
55316616Ssam     register int off, len;
5549676Slinton 
55516616Ssam     printf("%s = ", symname(f));
5569676Slinton     savesp = sp;
55716616Ssam     off = f->symvalue.field.offset;
55816616Ssam     len = f->symvalue.field.length;
55916616Ssam     sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE);
56016616Ssam     printval(f);
5619676Slinton     sp = savesp;
5629676Slinton }
5639676Slinton 
5649676Slinton /*
5659676Slinton  * Print out the contents of an array.
5669676Slinton  * Haven't quite figured out what the best format is.
5679676Slinton  *
5689676Slinton  * This is rather inefficient.
5699676Slinton  *
5709676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
5719676Slinton  */
5729676Slinton 
5739676Slinton public printarray(a)
5749676Slinton Symbol a;
5759676Slinton {
5769676Slinton     Stack *savesp, *newsp;
5779676Slinton     Symbol eltype;
5789676Slinton     long elsize;
5799676Slinton     String sep;
5809676Slinton 
5819676Slinton     savesp = sp;
58212544Scsvaf     sp -= (size(a));
5839676Slinton     newsp = sp;
5849676Slinton     eltype = rtype(a->type);
5859676Slinton     elsize = size(eltype);
5869676Slinton     printf("(");
5879676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
5889676Slinton       eltype->class == VARNT) {
5899676Slinton 	sep = "\n";
5909676Slinton 	putchar('\n');
5919676Slinton     } else {
5929676Slinton 	sep = ", ";
5939676Slinton     }
5949676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
5959676Slinton 	if (sp - elsize != newsp) {
5969676Slinton 	    fputs(sep, stdout);
5979676Slinton 	}
5989676Slinton 	printval(eltype);
5999676Slinton     }
6009676Slinton     sp = newsp;
6019676Slinton     if (streq(sep, "\n")) {
6029676Slinton 	putchar('\n');
6039676Slinton     }
6049676Slinton     printf(")");
6059676Slinton }
6069676Slinton 
6079676Slinton /*
6089676Slinton  * Print out the value of a real number in Pascal notation.
6099676Slinton  * This is, unfortunately, different than what one gets
6109676Slinton  * from "%g" in printf.
6119676Slinton  */
6129676Slinton 
6139676Slinton public prtreal(r)
6149676Slinton double r;
6159676Slinton {
6169676Slinton     extern char *index();
6179676Slinton     char buf[256];
6189676Slinton 
6199676Slinton     sprintf(buf, "%g", r);
6209676Slinton     if (buf[0] == '.') {
6219676Slinton 	printf("0%s", buf);
6229676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
6239676Slinton 	printf("-0%s", &buf[1]);
6249676Slinton     } else {
6259676Slinton 	printf("%s", buf);
6269676Slinton     }
6279676Slinton     if (index(buf, '.') == nil) {
6289676Slinton 	printf(".0");
6299676Slinton     }
6309676Slinton }
6319676Slinton 
6329676Slinton /*
6339676Slinton  * Print out a character using ^? notation for unprintables.
6349676Slinton  */
6359676Slinton 
6369676Slinton public printchar(c)
6379676Slinton char c;
6389676Slinton {
6399676Slinton     if (c == 0) {
6409676Slinton 	putchar('\\');
6419676Slinton 	putchar('0');
6429676Slinton     } else if (c == '\n') {
6439676Slinton 	putchar('\\');
6449676Slinton 	putchar('n');
6459676Slinton     } else if (c > 0 and c < ' ') {
6469676Slinton 	putchar('^');
6479676Slinton 	putchar(c - 1 + 'A');
64816616Ssam     } else if (c >= ' ' && c <= '~') {
64916616Ssam 	putchar(c);
6509676Slinton     } else {
65116616Ssam 	printf("\\0%o",c);
6529676Slinton     }
6539676Slinton }
654*18229Slinton 
655*18229Slinton /*
656*18229Slinton  * Print out a value for a range type (integer, char, or boolean).
657*18229Slinton  */
658*18229Slinton 
659*18229Slinton public printRangeVal (val, t)
660*18229Slinton long val;
661*18229Slinton Symbol t;
662*18229Slinton {
663*18229Slinton     if (t == t_boolean->type or istypename(t->type, "boolean")) {
664*18229Slinton 	if ((boolean) val) {
665*18229Slinton 	    printf("true");
666*18229Slinton 	} else {
667*18229Slinton 	    printf("false");
668*18229Slinton 	}
669*18229Slinton     } else if (t == t_char->type or istypename(t->type, "char")) {
670*18229Slinton 	if (varIsSet("$hexchars")) {
671*18229Slinton 	    printf("0x%lx", val);
672*18229Slinton 	} else {
673*18229Slinton 	    putchar('\'');
674*18229Slinton 	    printchar(val);
675*18229Slinton 	    putchar('\'');
676*18229Slinton 	}
677*18229Slinton     } else if (varIsSet("$hexints")) {
678*18229Slinton 	printf("0x%lx", val);
679*18229Slinton     } else if (t->symvalue.rangev.lower >= 0) {
680*18229Slinton 	printf("%lu", val);
681*18229Slinton     } else {
682*18229Slinton 	printf("%ld", val);
683*18229Slinton     }
684*18229Slinton }
685*18229Slinton 
686*18229Slinton /*
687*18229Slinton  * Print out an enumerated value by finding the corresponding
688*18229Slinton  * name in the enumeration list.
689*18229Slinton  */
690*18229Slinton 
691*18229Slinton public printEnum (i, t)
692*18229Slinton integer i;
693*18229Slinton Symbol t;
694*18229Slinton {
695*18229Slinton     register Symbol e;
696*18229Slinton 
697*18229Slinton     e = t->chain;
698*18229Slinton     while (e != nil and e->symvalue.constval->value.lcon != i) {
699*18229Slinton 	e = e->chain;
700*18229Slinton     }
701*18229Slinton     if (e != nil) {
702*18229Slinton 	printf("%s", symname(e));
703*18229Slinton     } else {
704*18229Slinton 	printf("%d", i);
705*18229Slinton     }
706*18229Slinton }
707*18229Slinton 
708*18229Slinton /*
709*18229Slinton  * Print out a null-terminated string (pointer to char)
710*18229Slinton  * starting at the given address.
711*18229Slinton  */
712*18229Slinton 
713*18229Slinton public printString (addr, quotes)
714*18229Slinton Address addr;
715*18229Slinton boolean quotes;
716*18229Slinton {
717*18229Slinton     register Address a;
718*18229Slinton     register integer i, len;
719*18229Slinton     register boolean endofstring;
720*18229Slinton     union {
721*18229Slinton 	char ch[sizeof(Word)];
722*18229Slinton 	int word;
723*18229Slinton     } u;
724*18229Slinton 
725*18229Slinton     if (varIsSet("$hexstrings")) {
726*18229Slinton 	printf("0x%x", addr);
727*18229Slinton     } else {
728*18229Slinton 	if (quotes) {
729*18229Slinton 	    putchar('"');
730*18229Slinton 	}
731*18229Slinton 	a = addr;
732*18229Slinton 	endofstring = false;
733*18229Slinton 	while (not endofstring) {
734*18229Slinton 	    dread(&u, a, sizeof(u));
735*18229Slinton 	    i = 0;
736*18229Slinton 	    do {
737*18229Slinton 		if (u.ch[i] == '\0') {
738*18229Slinton 		    endofstring = true;
739*18229Slinton 		} else {
740*18229Slinton 		    printchar(u.ch[i]);
741*18229Slinton 		}
742*18229Slinton 		++i;
743*18229Slinton 	    } while (i < sizeof(Word) and not endofstring);
744*18229Slinton 	    a += sizeof(Word);
745*18229Slinton 	}
746*18229Slinton 	if (quotes) {
747*18229Slinton 	    putchar('"');
748*18229Slinton 	}
749*18229Slinton     }
750*18229Slinton }
751