xref: /csrg-svn/old/dbx/printsym.c (revision 26478)
121619Sdist /*
221619Sdist  * Copyright (c) 1983 Regents of the University of California.
321619Sdist  * All rights reserved.  The Berkeley software License Agreement
421619Sdist  * specifies the terms and conditions for redistribution.
521619Sdist  */
69676Slinton 
721619Sdist #ifndef lint
8*26478Ssam static char sccsid[] = "@(#)printsym.c	5.3 (Berkeley) 03/05/86";
921619Sdist #endif not lint
109676Slinton 
1118229Slinton static char rcsid[] = "$Header: printsym.c,v 1.5 84/12/26 10:41:28 linton Exp $";
1218229Slinton 
139676Slinton /*
149676Slinton  * Printing of symbolic information.
159676Slinton  */
169676Slinton 
179676Slinton #include "defs.h"
189676Slinton #include "symbols.h"
199676Slinton #include "languages.h"
209676Slinton #include "printsym.h"
219676Slinton #include "tree.h"
229676Slinton #include "eval.h"
239676Slinton #include "mappings.h"
249676Slinton #include "process.h"
259676Slinton #include "runtime.h"
269676Slinton #include "machine.h"
279676Slinton #include "names.h"
2818229Slinton #include "keywords.h"
299676Slinton #include "main.h"
309676Slinton 
319676Slinton #ifndef public
329676Slinton #endif
339676Slinton 
349676Slinton /*
3511863Slinton  * Maximum number of arguments to a function.
3611863Slinton  * This is used as a check for the possibility that the stack has been
3711863Slinton  * overwritten and therefore a saved argument pointer might indicate
3811863Slinton  * to an absurdly large number of arguments.
3911863Slinton  */
4011863Slinton 
4111863Slinton #define MAXARGSPASSED 20
4211863Slinton 
4311863Slinton /*
449676Slinton  * Return a pointer to the string for the name of the class that
459676Slinton  * the given symbol belongs to.
469676Slinton  */
479676Slinton 
489676Slinton private String clname[] = {
4918229Slinton     "bad use", "constant", "type", "variable", "array", "@dynarray",
5018229Slinton     "@subarray", "fileptr", "record", "field",
5118229Slinton     "procedure", "function", "funcvar",
529676Slinton     "ref", "pointer", "file", "set", "range", "label", "withptr",
539676Slinton     "scalar", "string", "program", "improper", "variant",
5416616Ssam     "procparam", "funcparam", "module", "tag", "common", "extref", "typeref"
559676Slinton };
569676Slinton 
579676Slinton public String classname(s)
589676Slinton Symbol s;
599676Slinton {
609676Slinton     return clname[ord(s->class)];
619676Slinton }
629676Slinton 
639676Slinton /*
649676Slinton  * Note the entry of the given block, unless it's the main program.
659676Slinton  */
669676Slinton 
679676Slinton public printentry(s)
689676Slinton Symbol s;
699676Slinton {
709676Slinton     if (s != program) {
7118229Slinton 	printf("\nentering %s ", classname(s));
7218229Slinton 	printname(stdout, s);
7318229Slinton 	printf("\n");
749676Slinton     }
759676Slinton }
769676Slinton 
779676Slinton /*
789676Slinton  * Note the exit of the given block
799676Slinton  */
809676Slinton 
819676Slinton public printexit(s)
829676Slinton Symbol s;
839676Slinton {
849676Slinton     if (s != program) {
8518229Slinton 	printf("leaving %s ", classname(s));
8618229Slinton 	printname(stdout, s);
8718229Slinton 	printf("\n\n");
889676Slinton     }
899676Slinton }
909676Slinton 
919676Slinton /*
929676Slinton  * Note the call of s from t.
939676Slinton  */
949676Slinton 
959676Slinton public printcall(s, t)
969676Slinton Symbol s, t;
979676Slinton {
9818229Slinton     printf("calling ");
9918229Slinton     printname(stdout, s);
1009676Slinton     printparams(s, nil);
10118229Slinton     printf(" from %s ", classname(t));
10218229Slinton     printname(stdout, t);
10318229Slinton     printf("\n");
1049676Slinton }
1059676Slinton 
1069676Slinton /*
1079676Slinton  * Note the return from s.  If s is a function, print the value
1089676Slinton  * it is returning.  This is somewhat painful, since the function
1099676Slinton  * has actually just returned.
1109676Slinton  */
1119676Slinton 
1129676Slinton public printrtn(s)
1139676Slinton Symbol s;
1149676Slinton {
1159676Slinton     register Symbol t;
1169676Slinton     register int len;
1179676Slinton     Boolean isindirect;
1189676Slinton 
1199676Slinton     printf("returning ");
12012628Scsvaf     if (s->class == FUNC && (!istypename(s->type,"void"))) {
1219676Slinton 	len = size(s->type);
1229676Slinton 	if (canpush(len)) {
1239676Slinton 	    t = rtype(s->type);
1249676Slinton 	    isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
1259676Slinton 	    pushretval(len, isindirect);
1269676Slinton 	    printval(s->type);
1279676Slinton 	    putchar(' ');
1289676Slinton 	} else {
1299676Slinton 	    printf("(value too large) ");
1309676Slinton 	}
1319676Slinton     }
13218229Slinton     printf("from ");
13318229Slinton     printname(stdout, s);
13418229Slinton     printf("\n");
1359676Slinton }
1369676Slinton 
1379676Slinton /*
1389676Slinton  * Print the values of the parameters of the given procedure or function.
1399676Slinton  * The frame distinguishes recursive instances of a procedure.
14016616Ssam  *
14116616Ssam  * If the procedure or function is internal, the argument count is
14216616Ssam  * not valid so we ignore it.
1439676Slinton  */
1449676Slinton 
1459676Slinton public printparams(f, frame)
1469676Slinton Symbol f;
1479676Slinton Frame frame;
1489676Slinton {
1499676Slinton     Symbol param;
1509676Slinton     int n, m, s;
1519676Slinton 
1529676Slinton     n = nargspassed(frame);
15316616Ssam     if (isinternal(f)) {
15416616Ssam 	n = 0;
15516616Ssam     }
15618229Slinton     printf("(");
1579676Slinton     param = f->chain;
1589676Slinton     if (param != nil or n > 0) {
1599676Slinton 	m = n;
1609676Slinton 	if (param != nil) {
1619676Slinton 	    for (;;) {
16218229Slinton 		s = psize(param) div sizeof(Word);
1639676Slinton 		if (s == 0) {
1649676Slinton 		    s = 1;
1659676Slinton 		}
1669676Slinton 		m -= s;
16718229Slinton 		if (showaggrs) {
16818229Slinton 		    printv(param, frame);
16918229Slinton 		} else {
17018229Slinton 		    printparamv(param, frame);
17118229Slinton 		}
1729676Slinton 		param = param->chain;
1739676Slinton 	    if (param == nil) break;
1749676Slinton 		printf(", ");
1759676Slinton 	    }
1769676Slinton 	}
1779676Slinton 	if (m > 0) {
17811863Slinton 	    if (m > MAXARGSPASSED) {
17911863Slinton 		m = MAXARGSPASSED;
18011863Slinton 	    }
1819676Slinton 	    if (f->chain != nil) {
1829676Slinton 		printf(", ");
1839676Slinton 	    }
1849676Slinton 	    for (;;) {
1859676Slinton 		--m;
1869676Slinton 		printf("0x%x", argn(n - m, frame));
1879676Slinton 	    if (m <= 0) break;
1889676Slinton 		printf(", ");
1899676Slinton 	    }
1909676Slinton 	}
1919676Slinton     }
19218229Slinton     printf(")");
1939676Slinton }
1949676Slinton 
1959676Slinton /*
1969676Slinton  * Test if a symbol should be printed.  We don't print files,
1979676Slinton  * for example, simply because there's no good way to do it.
1989676Slinton  * The symbol must be within the given function.
1999676Slinton  */
2009676Slinton 
2019676Slinton public Boolean should_print(s)
2029676Slinton Symbol s;
2039676Slinton {
2049676Slinton     Boolean b;
2059676Slinton     register Symbol t;
2069676Slinton 
2079676Slinton     switch (s->class) {
2089676Slinton 	case VAR:
2099676Slinton 	case FVAR:
21014339Slinton 	    if (isparam(s)) {
21114339Slinton 		b = false;
21214339Slinton 	    } else {
21314339Slinton 		t = rtype(s->type);
21414339Slinton 		if (t == nil) {
21514339Slinton 		    b = false;
21614339Slinton 		} else {
21714339Slinton 		    switch (t->class) {
21814339Slinton 			case FILET:
21914339Slinton 			case SET:
22014339Slinton 			case BADUSE:
22114339Slinton 			    b = false;
22214339Slinton 			    break;
22314339Slinton 
22414339Slinton 			default:
22514339Slinton 			    b = true;
22614339Slinton 			    break;
22714339Slinton 		    }
22814339Slinton 		}
22914339Slinton 	    }
2309676Slinton 	    break;
2319676Slinton 
2329676Slinton 	default:
2339676Slinton 	    b = false;
2349676Slinton 	    break;
2359676Slinton     }
2369676Slinton     return b;
2379676Slinton }
2389676Slinton 
2399676Slinton /*
24018229Slinton  * Print out a parameter value.
24118229Slinton  *
24218229Slinton  * Since this is intended to be printed on a single line with other information
24318229Slinton  * aggregate values are not printed.
24418229Slinton  */
24518229Slinton 
24618229Slinton public printparamv (p, frame)
24718229Slinton Symbol p;
24818229Slinton Frame frame;
24918229Slinton {
25018229Slinton     Symbol t;
25118229Slinton 
25218229Slinton     t = rtype(p->type);
25318229Slinton     switch (t->class) {
25418229Slinton 	case ARRAY:
25518229Slinton 	case DYNARRAY:
25618229Slinton 	case SUBARRAY:
25718229Slinton 	    t = rtype(t->type);
25818229Slinton 	    if (compatible(t, t_char)) {
25918229Slinton 		printv(p, frame);
26018229Slinton 	    } else {
26118229Slinton 		printf("%s = (...)", symname(p));
26218229Slinton 	    }
26318229Slinton 	    break;
26418229Slinton 
26518229Slinton 	case RECORD:
26618229Slinton 	    printf("%s = (...)", symname(p));
26718229Slinton 	    break;
26818229Slinton 
26918229Slinton 	default:
27018229Slinton 	    printv(p, frame);
27118229Slinton 	    break;
27218229Slinton     }
27318229Slinton }
27418229Slinton 
27518229Slinton /*
2769676Slinton  * Print the name and value of a variable.
2779676Slinton  */
2789676Slinton 
2799676Slinton public printv(s, frame)
2809676Slinton Symbol s;
2819676Slinton Frame frame;
2829676Slinton {
2839676Slinton     Address addr;
2849676Slinton     int len;
2859676Slinton 
2869676Slinton     if (isambiguous(s) and ismodule(container(s))) {
2879676Slinton 	printname(stdout, s);
2889676Slinton 	printf(" = ");
2899676Slinton     } else {
2909676Slinton 	printf("%s = ", symname(s));
2919676Slinton     }
29218229Slinton     if (isvarparam(s) and not isopenarray(s)) {
29318229Slinton 	rpush(address(s, frame), sizeof(Address));
29418229Slinton 	addr = pop(Address);
2959676Slinton     } else {
29618229Slinton 	addr = address(s, frame);
29718229Slinton     }
29818229Slinton     len = size(s);
29924554Smckusick     if (not canpush(len)) {
30024554Smckusick 	printf("*** expression too large ***");
30124554Smckusick     } else if (isreg(s)) {
30224554Smckusick 	push(Address, addr);
30324554Smckusick 	printval(s->type);
30424554Smckusick     } else {
30518229Slinton 	rpush(addr, len);
30618229Slinton 	printval(s->type);
30718229Slinton     }
3089676Slinton }
3099676Slinton 
3109676Slinton /*
3119676Slinton  * Print out the name of a symbol.
3129676Slinton  */
3139676Slinton 
3149676Slinton public printname(f, s)
3159676Slinton File f;
3169676Slinton Symbol s;
3179676Slinton {
3189676Slinton     if (s == nil) {
3199676Slinton 	fprintf(f, "(noname)");
32016616Ssam     } else if (s == program) {
32116616Ssam 	fprintf(f, ".");
3229676Slinton     } else if (isredirected() or isambiguous(s)) {
3239676Slinton 	printwhich(f, s);
3249676Slinton     } else {
3259676Slinton 	fprintf(f, "%s", symname(s));
3269676Slinton     }
3279676Slinton }
3289676Slinton 
3299676Slinton /*
3309676Slinton  * Print the fully specified variable that is described by the given identifer.
3319676Slinton  */
3329676Slinton 
3339676Slinton public printwhich(f, s)
3349676Slinton File f;
3359676Slinton Symbol s;
3369676Slinton {
3379676Slinton     printouter(f, container(s));
3389676Slinton     fprintf(f, "%s", symname(s));
3399676Slinton }
3409676Slinton 
3419676Slinton /*
3429676Slinton  * Print the fully qualified name of each symbol that has the same name
3439676Slinton  * as the given symbol.
3449676Slinton  */
3459676Slinton 
3469676Slinton public printwhereis(f, s)
3479676Slinton File f;
3489676Slinton Symbol s;
3499676Slinton {
3509676Slinton     register Name n;
3519676Slinton     register Symbol t;
3529676Slinton 
3539676Slinton     checkref(s);
3549676Slinton     n = s->name;
3559676Slinton     t = lookup(n);
3569676Slinton     printwhich(f, t);
3579676Slinton     t = t->next_sym;
3589676Slinton     while (t != nil) {
3599676Slinton 	if (t->name == n) {
3609676Slinton 	    putc(' ', f);
3619676Slinton 	    printwhich(f, t);
3629676Slinton 	}
3639676Slinton 	t = t->next_sym;
3649676Slinton     }
3659676Slinton     putc('\n', f);
3669676Slinton }
3679676Slinton 
3689676Slinton private printouter(f, s)
3699676Slinton File f;
3709676Slinton Symbol s;
3719676Slinton {
3729676Slinton     Symbol outer;
3739676Slinton 
3749676Slinton     if (s != nil) {
3759676Slinton 	outer = container(s);
3769676Slinton 	if (outer != nil and outer != program) {
3779676Slinton 	    printouter(f, outer);
3789676Slinton 	}
3799676Slinton 	fprintf(f, "%s.", symname(s));
3809676Slinton     }
3819676Slinton }
3829676Slinton 
3839676Slinton public printdecl(s)
3849676Slinton Symbol s;
3859676Slinton {
38618229Slinton     Language lang;
38718229Slinton 
3889676Slinton     checkref(s);
38918229Slinton     if (s->language == nil or s->language == primlang) {
39018229Slinton 	lang = findlanguage(".s");
39118229Slinton     } else {
39218229Slinton 	lang = s->language;
39318229Slinton     }
39418229Slinton     (*language_op(lang, L_PRINTDECL))(s);
3959676Slinton }
3969676Slinton 
3979676Slinton /*
3989676Slinton  * Straight dump of symbol information.
3999676Slinton  */
4009676Slinton 
4019676Slinton public psym(s)
4029676Slinton Symbol s;
4039676Slinton {
4049676Slinton     printf("name\t%s\n", symname(s));
4059676Slinton     printf("lang\t%s\n", language_name(s->language));
4069676Slinton     printf("level\t%d\n", s->level);
4079676Slinton     printf("class\t%s\n", classname(s));
4089676Slinton     printf("type\t0x%x", s->type);
4099676Slinton     if (s->type != nil and s->type->name != nil) {
4109676Slinton 	printf(" (%s)", symname(s->type));
4119676Slinton     }
4129676Slinton     printf("\nchain\t0x%x", s->chain);
4139676Slinton     if (s->chain != nil and s->chain->name != nil) {
4149676Slinton 	printf(" (%s)", symname(s->chain));
4159676Slinton     }
4169676Slinton     printf("\nblock\t0x%x", s->block);
4179676Slinton     if (s->block->name != nil) {
4189676Slinton 	printf(" (");
4199676Slinton 	printname(stdout, s->block);
4209676Slinton 	putchar(')');
4219676Slinton     }
4229676Slinton     putchar('\n');
4239676Slinton     switch (s->class) {
42418229Slinton 	case TYPE:
42518229Slinton 	    printf("size\t%d\n", size(s));
42618229Slinton 	    break;
42718229Slinton 
4289676Slinton 	case VAR:
4299676Slinton 	case REF:
4309676Slinton 	    if (s->level >= 3) {
4319676Slinton 		printf("address\t0x%x\n", s->symvalue.offset);
4329676Slinton 	    } else {
4339676Slinton 		printf("offset\t%d\n", s->symvalue.offset);
4349676Slinton 	    }
43512545Scsvaf 	    printf("size\t%d\n", size(s));
4369676Slinton 	    break;
4379676Slinton 
4389676Slinton 	case RECORD:
4399676Slinton 	case VARNT:
4409676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
4419676Slinton 	    break;
4429676Slinton 
4439676Slinton 	case FIELD:
4449676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
4459676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
4469676Slinton 	    break;
4479676Slinton 
44814381Slinton 	case PROG:
4499676Slinton 	case PROC:
4509676Slinton 	case FUNC:
4519676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
45214438Slinton 	    if (isinline(s)) {
45314440Slinton 		printf("inline procedure\n");
45414438Slinton 	    }
45511863Slinton 	    if (nosource(s)) {
45611863Slinton 		printf("does not have source information\n");
45711863Slinton 	    } else {
45811863Slinton 		printf("has source information\n");
45911863Slinton 	    }
4609676Slinton 	    break;
4619676Slinton 
4629676Slinton 	case RANGE:
46314381Slinton 	    prangetype(s->symvalue.rangev.lowertype);
4649676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
46514381Slinton 	    prangetype(s->symvalue.rangev.uppertype);
4669676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
4679676Slinton 	    break;
4689676Slinton 
4699676Slinton 	default:
4709676Slinton 	    /* do nothing */
4719676Slinton 	    break;
4729676Slinton     }
4739676Slinton }
4749676Slinton 
47514381Slinton private prangetype(r)
47614381Slinton Rangetype r;
47714381Slinton {
47814381Slinton     switch (r) {
47914381Slinton 	case R_CONST:
48014381Slinton 	    printf("CONST");
48114381Slinton 	    break;
48214381Slinton 
48314381Slinton 	case R_ARG:
48414381Slinton 	    printf("ARG");
48514381Slinton 	    break;
48614381Slinton 
48714381Slinton 	case R_TEMP:
48814381Slinton 	    printf("TEMP");
48914381Slinton 	    break;
49014381Slinton 
49114381Slinton 	case R_ADJUST:
49214381Slinton 	    printf("ADJUST");
49314381Slinton 	    break;
49414381Slinton     }
49514381Slinton }
49614381Slinton 
4979676Slinton /*
4989676Slinton  * Print out the value on top of the stack according to the given type.
4999676Slinton  */
5009676Slinton 
5019676Slinton public printval(t)
5029676Slinton Symbol t;
5039676Slinton {
5049676Slinton     Symbol s;
5059676Slinton 
5069676Slinton     checkref(t);
50716616Ssam     if (t->class == TYPEREF) {
50816616Ssam 	resolveRef(t);
50916616Ssam     }
5109676Slinton     switch (t->class) {
5119676Slinton 	case PROC:
5129676Slinton 	case FUNC:
5139676Slinton 	    s = pop(Symbol);
5149676Slinton 	    printf("%s", symname(s));
5159676Slinton 	    break;
5169676Slinton 
5179676Slinton 	default:
51818229Slinton 	    if (t->language == nil or t->language == primlang) {
519*26478Ssam 		(*language_op(findlanguage(".c"), L_PRINTVAL))(t);
5209676Slinton 	    } else {
5219676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
5229676Slinton 	    }
5239676Slinton 	    break;
5249676Slinton     }
5259676Slinton }
5269676Slinton 
5279676Slinton /*
5289676Slinton  * Print out the value of a record, field by field.
5299676Slinton  */
5309676Slinton 
5319676Slinton public printrecord(s)
5329676Slinton Symbol s;
5339676Slinton {
53416616Ssam     Symbol f;
53516616Ssam 
5369676Slinton     if (s->chain == nil) {
5379676Slinton 	error("record has no fields");
5389676Slinton     }
5399676Slinton     printf("(");
5409676Slinton     sp -= size(s);
54116616Ssam     f = s->chain;
54216616Ssam     if (f != nil) {
54316616Ssam 	for (;;) {
54416616Ssam 	    printfield(f);
54516616Ssam 	    f = f->chain;
54616616Ssam 	if (f == nil) break;
54716616Ssam 	    printf(", ");
54816616Ssam 	}
54916616Ssam     }
5509676Slinton     printf(")");
5519676Slinton }
5529676Slinton 
5539676Slinton /*
55416616Ssam  * Print out a field.
5559676Slinton  */
5569676Slinton 
55716616Ssam private printfield(f)
55816616Ssam Symbol f;
5599676Slinton {
5609676Slinton     Stack *savesp;
56116616Ssam     register int off, len;
5629676Slinton 
56316616Ssam     printf("%s = ", symname(f));
5649676Slinton     savesp = sp;
56516616Ssam     off = f->symvalue.field.offset;
56616616Ssam     len = f->symvalue.field.length;
56716616Ssam     sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE);
56816616Ssam     printval(f);
5699676Slinton     sp = savesp;
5709676Slinton }
5719676Slinton 
5729676Slinton /*
5739676Slinton  * Print out the contents of an array.
5749676Slinton  * Haven't quite figured out what the best format is.
5759676Slinton  *
5769676Slinton  * This is rather inefficient.
5779676Slinton  *
5789676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
5799676Slinton  */
5809676Slinton 
5819676Slinton public printarray(a)
5829676Slinton Symbol a;
5839676Slinton {
5849676Slinton     Stack *savesp, *newsp;
5859676Slinton     Symbol eltype;
5869676Slinton     long elsize;
5879676Slinton     String sep;
5889676Slinton 
5899676Slinton     savesp = sp;
59012544Scsvaf     sp -= (size(a));
5919676Slinton     newsp = sp;
5929676Slinton     eltype = rtype(a->type);
5939676Slinton     elsize = size(eltype);
5949676Slinton     printf("(");
5959676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
5969676Slinton       eltype->class == VARNT) {
5979676Slinton 	sep = "\n";
5989676Slinton 	putchar('\n');
5999676Slinton     } else {
6009676Slinton 	sep = ", ";
6019676Slinton     }
6029676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
6039676Slinton 	if (sp - elsize != newsp) {
6049676Slinton 	    fputs(sep, stdout);
6059676Slinton 	}
6069676Slinton 	printval(eltype);
6079676Slinton     }
6089676Slinton     sp = newsp;
6099676Slinton     if (streq(sep, "\n")) {
6109676Slinton 	putchar('\n');
6119676Slinton     }
6129676Slinton     printf(")");
6139676Slinton }
6149676Slinton 
6159676Slinton /*
6169676Slinton  * Print out the value of a real number in Pascal notation.
6179676Slinton  * This is, unfortunately, different than what one gets
6189676Slinton  * from "%g" in printf.
6199676Slinton  */
6209676Slinton 
6219676Slinton public prtreal(r)
6229676Slinton double r;
6239676Slinton {
6249676Slinton     extern char *index();
6259676Slinton     char buf[256];
6269676Slinton 
6279676Slinton     sprintf(buf, "%g", r);
6289676Slinton     if (buf[0] == '.') {
6299676Slinton 	printf("0%s", buf);
6309676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
6319676Slinton 	printf("-0%s", &buf[1]);
6329676Slinton     } else {
6339676Slinton 	printf("%s", buf);
6349676Slinton     }
6359676Slinton     if (index(buf, '.') == nil) {
6369676Slinton 	printf(".0");
6379676Slinton     }
6389676Slinton }
6399676Slinton 
6409676Slinton /*
6419676Slinton  * Print out a character using ^? notation for unprintables.
6429676Slinton  */
6439676Slinton 
6449676Slinton public printchar(c)
6459676Slinton char c;
6469676Slinton {
6479676Slinton     if (c == 0) {
6489676Slinton 	putchar('\\');
6499676Slinton 	putchar('0');
6509676Slinton     } else if (c == '\n') {
6519676Slinton 	putchar('\\');
6529676Slinton 	putchar('n');
6539676Slinton     } else if (c > 0 and c < ' ') {
6549676Slinton 	putchar('^');
6559676Slinton 	putchar(c - 1 + 'A');
65616616Ssam     } else if (c >= ' ' && c <= '~') {
65716616Ssam 	putchar(c);
6589676Slinton     } else {
65916616Ssam 	printf("\\0%o",c);
6609676Slinton     }
6619676Slinton }
66218229Slinton 
66318229Slinton /*
66418229Slinton  * Print out a value for a range type (integer, char, or boolean).
66518229Slinton  */
66618229Slinton 
66718229Slinton public printRangeVal (val, t)
66818229Slinton long val;
66918229Slinton Symbol t;
67018229Slinton {
67118229Slinton     if (t == t_boolean->type or istypename(t->type, "boolean")) {
67218229Slinton 	if ((boolean) val) {
67318229Slinton 	    printf("true");
67418229Slinton 	} else {
67518229Slinton 	    printf("false");
67618229Slinton 	}
67718229Slinton     } else if (t == t_char->type or istypename(t->type, "char")) {
67818229Slinton 	if (varIsSet("$hexchars")) {
67918229Slinton 	    printf("0x%lx", val);
68018229Slinton 	} else {
68118229Slinton 	    putchar('\'');
68218229Slinton 	    printchar(val);
68318229Slinton 	    putchar('\'');
68418229Slinton 	}
68518229Slinton     } else if (varIsSet("$hexints")) {
68618229Slinton 	printf("0x%lx", val);
68718229Slinton     } else if (t->symvalue.rangev.lower >= 0) {
68818229Slinton 	printf("%lu", val);
68918229Slinton     } else {
69018229Slinton 	printf("%ld", val);
69118229Slinton     }
69218229Slinton }
69318229Slinton 
69418229Slinton /*
69518229Slinton  * Print out an enumerated value by finding the corresponding
69618229Slinton  * name in the enumeration list.
69718229Slinton  */
69818229Slinton 
69918229Slinton public printEnum (i, t)
70018229Slinton integer i;
70118229Slinton Symbol t;
70218229Slinton {
70318229Slinton     register Symbol e;
70418229Slinton 
70518229Slinton     e = t->chain;
70618229Slinton     while (e != nil and e->symvalue.constval->value.lcon != i) {
70718229Slinton 	e = e->chain;
70818229Slinton     }
70918229Slinton     if (e != nil) {
71018229Slinton 	printf("%s", symname(e));
71118229Slinton     } else {
71218229Slinton 	printf("%d", i);
71318229Slinton     }
71418229Slinton }
71518229Slinton 
71618229Slinton /*
71718229Slinton  * Print out a null-terminated string (pointer to char)
71818229Slinton  * starting at the given address.
71918229Slinton  */
72018229Slinton 
72118229Slinton public printString (addr, quotes)
72218229Slinton Address addr;
72318229Slinton boolean quotes;
72418229Slinton {
72518229Slinton     register Address a;
72618229Slinton     register integer i, len;
72718229Slinton     register boolean endofstring;
72818229Slinton     union {
72918229Slinton 	char ch[sizeof(Word)];
73018229Slinton 	int word;
73118229Slinton     } u;
73218229Slinton 
73318229Slinton     if (varIsSet("$hexstrings")) {
73418229Slinton 	printf("0x%x", addr);
73518229Slinton     } else {
73618229Slinton 	if (quotes) {
73718229Slinton 	    putchar('"');
73818229Slinton 	}
73918229Slinton 	a = addr;
74018229Slinton 	endofstring = false;
74118229Slinton 	while (not endofstring) {
74218229Slinton 	    dread(&u, a, sizeof(u));
74318229Slinton 	    i = 0;
74418229Slinton 	    do {
74518229Slinton 		if (u.ch[i] == '\0') {
74618229Slinton 		    endofstring = true;
74718229Slinton 		} else {
74818229Slinton 		    printchar(u.ch[i]);
74918229Slinton 		}
75018229Slinton 		++i;
75118229Slinton 	    } while (i < sizeof(Word) and not endofstring);
75218229Slinton 	    a += sizeof(Word);
75318229Slinton 	}
75418229Slinton 	if (quotes) {
75518229Slinton 	    putchar('"');
75618229Slinton 	}
75718229Slinton     }
75818229Slinton }
759