xref: /csrg-svn/old/dbx/printsym.c (revision 21619)
1*21619Sdist /*
2*21619Sdist  * Copyright (c) 1983 Regents of the University of California.
3*21619Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21619Sdist  * specifies the terms and conditions for redistribution.
5*21619Sdist  */
69676Slinton 
7*21619Sdist #ifndef lint
8*21619Sdist static char sccsid[] = "@(#)printsym.c	5.1 (Berkeley) 05/31/85";
9*21619Sdist #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;
28516616Ssam     Symbol t;
2869676Slinton 
2879676Slinton     if (isambiguous(s) and ismodule(container(s))) {
2889676Slinton 	printname(stdout, s);
2899676Slinton 	printf(" = ");
2909676Slinton     } else {
2919676Slinton 	printf("%s = ", symname(s));
2929676Slinton     }
29318229Slinton     if (isvarparam(s) and not isopenarray(s)) {
29418229Slinton 	rpush(address(s, frame), sizeof(Address));
29518229Slinton 	addr = pop(Address);
2969676Slinton     } else {
29718229Slinton 	addr = address(s, frame);
29818229Slinton     }
29918229Slinton     len = size(s);
30018229Slinton     if (canpush(len)) {
30118229Slinton 	rpush(addr, len);
30218229Slinton 	printval(s->type);
30318229Slinton     } else {
30418229Slinton 	printf("*** expression too large ***");
30518229Slinton     }
3069676Slinton }
3079676Slinton 
3089676Slinton /*
3099676Slinton  * Print out the name of a symbol.
3109676Slinton  */
3119676Slinton 
3129676Slinton public printname(f, s)
3139676Slinton File f;
3149676Slinton Symbol s;
3159676Slinton {
3169676Slinton     if (s == nil) {
3179676Slinton 	fprintf(f, "(noname)");
31816616Ssam     } else if (s == program) {
31916616Ssam 	fprintf(f, ".");
3209676Slinton     } else if (isredirected() or isambiguous(s)) {
3219676Slinton 	printwhich(f, s);
3229676Slinton     } else {
3239676Slinton 	fprintf(f, "%s", symname(s));
3249676Slinton     }
3259676Slinton }
3269676Slinton 
3279676Slinton /*
3289676Slinton  * Print the fully specified variable that is described by the given identifer.
3299676Slinton  */
3309676Slinton 
3319676Slinton public printwhich(f, s)
3329676Slinton File f;
3339676Slinton Symbol s;
3349676Slinton {
3359676Slinton     printouter(f, container(s));
3369676Slinton     fprintf(f, "%s", symname(s));
3379676Slinton }
3389676Slinton 
3399676Slinton /*
3409676Slinton  * Print the fully qualified name of each symbol that has the same name
3419676Slinton  * as the given symbol.
3429676Slinton  */
3439676Slinton 
3449676Slinton public printwhereis(f, s)
3459676Slinton File f;
3469676Slinton Symbol s;
3479676Slinton {
3489676Slinton     register Name n;
3499676Slinton     register Symbol t;
3509676Slinton 
3519676Slinton     checkref(s);
3529676Slinton     n = s->name;
3539676Slinton     t = lookup(n);
3549676Slinton     printwhich(f, t);
3559676Slinton     t = t->next_sym;
3569676Slinton     while (t != nil) {
3579676Slinton 	if (t->name == n) {
3589676Slinton 	    putc(' ', f);
3599676Slinton 	    printwhich(f, t);
3609676Slinton 	}
3619676Slinton 	t = t->next_sym;
3629676Slinton     }
3639676Slinton     putc('\n', f);
3649676Slinton }
3659676Slinton 
3669676Slinton private printouter(f, s)
3679676Slinton File f;
3689676Slinton Symbol s;
3699676Slinton {
3709676Slinton     Symbol outer;
3719676Slinton 
3729676Slinton     if (s != nil) {
3739676Slinton 	outer = container(s);
3749676Slinton 	if (outer != nil and outer != program) {
3759676Slinton 	    printouter(f, outer);
3769676Slinton 	}
3779676Slinton 	fprintf(f, "%s.", symname(s));
3789676Slinton     }
3799676Slinton }
3809676Slinton 
3819676Slinton public printdecl(s)
3829676Slinton Symbol s;
3839676Slinton {
38418229Slinton     Language lang;
38518229Slinton 
3869676Slinton     checkref(s);
38718229Slinton     if (s->language == nil or s->language == primlang) {
38818229Slinton 	lang = findlanguage(".s");
38918229Slinton     } else {
39018229Slinton 	lang = s->language;
39118229Slinton     }
39218229Slinton     (*language_op(lang, L_PRINTDECL))(s);
3939676Slinton }
3949676Slinton 
3959676Slinton /*
3969676Slinton  * Straight dump of symbol information.
3979676Slinton  */
3989676Slinton 
3999676Slinton public psym(s)
4009676Slinton Symbol s;
4019676Slinton {
4029676Slinton     printf("name\t%s\n", symname(s));
4039676Slinton     printf("lang\t%s\n", language_name(s->language));
4049676Slinton     printf("level\t%d\n", s->level);
4059676Slinton     printf("class\t%s\n", classname(s));
4069676Slinton     printf("type\t0x%x", s->type);
4079676Slinton     if (s->type != nil and s->type->name != nil) {
4089676Slinton 	printf(" (%s)", symname(s->type));
4099676Slinton     }
4109676Slinton     printf("\nchain\t0x%x", s->chain);
4119676Slinton     if (s->chain != nil and s->chain->name != nil) {
4129676Slinton 	printf(" (%s)", symname(s->chain));
4139676Slinton     }
4149676Slinton     printf("\nblock\t0x%x", s->block);
4159676Slinton     if (s->block->name != nil) {
4169676Slinton 	printf(" (");
4179676Slinton 	printname(stdout, s->block);
4189676Slinton 	putchar(')');
4199676Slinton     }
4209676Slinton     putchar('\n');
4219676Slinton     switch (s->class) {
42218229Slinton 	case TYPE:
42318229Slinton 	    printf("size\t%d\n", size(s));
42418229Slinton 	    break;
42518229Slinton 
4269676Slinton 	case VAR:
4279676Slinton 	case REF:
4289676Slinton 	    if (s->level >= 3) {
4299676Slinton 		printf("address\t0x%x\n", s->symvalue.offset);
4309676Slinton 	    } else {
4319676Slinton 		printf("offset\t%d\n", s->symvalue.offset);
4329676Slinton 	    }
43312545Scsvaf 	    printf("size\t%d\n", size(s));
4349676Slinton 	    break;
4359676Slinton 
4369676Slinton 	case RECORD:
4379676Slinton 	case VARNT:
4389676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
4399676Slinton 	    break;
4409676Slinton 
4419676Slinton 	case FIELD:
4429676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
4439676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
4449676Slinton 	    break;
4459676Slinton 
44614381Slinton 	case PROG:
4479676Slinton 	case PROC:
4489676Slinton 	case FUNC:
4499676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
45014438Slinton 	    if (isinline(s)) {
45114440Slinton 		printf("inline procedure\n");
45214438Slinton 	    }
45311863Slinton 	    if (nosource(s)) {
45411863Slinton 		printf("does not have source information\n");
45511863Slinton 	    } else {
45611863Slinton 		printf("has source information\n");
45711863Slinton 	    }
4589676Slinton 	    break;
4599676Slinton 
4609676Slinton 	case RANGE:
46114381Slinton 	    prangetype(s->symvalue.rangev.lowertype);
4629676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
46314381Slinton 	    prangetype(s->symvalue.rangev.uppertype);
4649676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
4659676Slinton 	    break;
4669676Slinton 
4679676Slinton 	default:
4689676Slinton 	    /* do nothing */
4699676Slinton 	    break;
4709676Slinton     }
4719676Slinton }
4729676Slinton 
47314381Slinton private prangetype(r)
47414381Slinton Rangetype r;
47514381Slinton {
47614381Slinton     switch (r) {
47714381Slinton 	case R_CONST:
47814381Slinton 	    printf("CONST");
47914381Slinton 	    break;
48014381Slinton 
48114381Slinton 	case R_ARG:
48214381Slinton 	    printf("ARG");
48314381Slinton 	    break;
48414381Slinton 
48514381Slinton 	case R_TEMP:
48614381Slinton 	    printf("TEMP");
48714381Slinton 	    break;
48814381Slinton 
48914381Slinton 	case R_ADJUST:
49014381Slinton 	    printf("ADJUST");
49114381Slinton 	    break;
49214381Slinton     }
49314381Slinton }
49414381Slinton 
4959676Slinton /*
4969676Slinton  * Print out the value on top of the stack according to the given type.
4979676Slinton  */
4989676Slinton 
4999676Slinton public printval(t)
5009676Slinton Symbol t;
5019676Slinton {
5029676Slinton     Symbol s;
5039676Slinton 
5049676Slinton     checkref(t);
50516616Ssam     if (t->class == TYPEREF) {
50616616Ssam 	resolveRef(t);
50716616Ssam     }
5089676Slinton     switch (t->class) {
5099676Slinton 	case PROC:
5109676Slinton 	case FUNC:
5119676Slinton 	    s = pop(Symbol);
5129676Slinton 	    printf("%s", symname(s));
5139676Slinton 	    break;
5149676Slinton 
5159676Slinton 	default:
51618229Slinton 	    if (t->language == nil or t->language == primlang) {
51716616Ssam 		(*language_op(findlanguage(".c"), L_PRINTVAL))(t);
5189676Slinton 	    } else {
5199676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
5209676Slinton 	    }
5219676Slinton 	    break;
5229676Slinton     }
5239676Slinton }
5249676Slinton 
5259676Slinton /*
5269676Slinton  * Print out the value of a record, field by field.
5279676Slinton  */
5289676Slinton 
5299676Slinton public printrecord(s)
5309676Slinton Symbol s;
5319676Slinton {
53216616Ssam     Symbol f;
53316616Ssam 
5349676Slinton     if (s->chain == nil) {
5359676Slinton 	error("record has no fields");
5369676Slinton     }
5379676Slinton     printf("(");
5389676Slinton     sp -= size(s);
53916616Ssam     f = s->chain;
54016616Ssam     if (f != nil) {
54116616Ssam 	for (;;) {
54216616Ssam 	    printfield(f);
54316616Ssam 	    f = f->chain;
54416616Ssam 	if (f == nil) break;
54516616Ssam 	    printf(", ");
54616616Ssam 	}
54716616Ssam     }
5489676Slinton     printf(")");
5499676Slinton }
5509676Slinton 
5519676Slinton /*
55216616Ssam  * Print out a field.
5539676Slinton  */
5549676Slinton 
55516616Ssam private printfield(f)
55616616Ssam Symbol f;
5579676Slinton {
5589676Slinton     Stack *savesp;
55916616Ssam     register int off, len;
5609676Slinton 
56116616Ssam     printf("%s = ", symname(f));
5629676Slinton     savesp = sp;
56316616Ssam     off = f->symvalue.field.offset;
56416616Ssam     len = f->symvalue.field.length;
56516616Ssam     sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE);
56616616Ssam     printval(f);
5679676Slinton     sp = savesp;
5689676Slinton }
5699676Slinton 
5709676Slinton /*
5719676Slinton  * Print out the contents of an array.
5729676Slinton  * Haven't quite figured out what the best format is.
5739676Slinton  *
5749676Slinton  * This is rather inefficient.
5759676Slinton  *
5769676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
5779676Slinton  */
5789676Slinton 
5799676Slinton public printarray(a)
5809676Slinton Symbol a;
5819676Slinton {
5829676Slinton     Stack *savesp, *newsp;
5839676Slinton     Symbol eltype;
5849676Slinton     long elsize;
5859676Slinton     String sep;
5869676Slinton 
5879676Slinton     savesp = sp;
58812544Scsvaf     sp -= (size(a));
5899676Slinton     newsp = sp;
5909676Slinton     eltype = rtype(a->type);
5919676Slinton     elsize = size(eltype);
5929676Slinton     printf("(");
5939676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
5949676Slinton       eltype->class == VARNT) {
5959676Slinton 	sep = "\n";
5969676Slinton 	putchar('\n');
5979676Slinton     } else {
5989676Slinton 	sep = ", ";
5999676Slinton     }
6009676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
6019676Slinton 	if (sp - elsize != newsp) {
6029676Slinton 	    fputs(sep, stdout);
6039676Slinton 	}
6049676Slinton 	printval(eltype);
6059676Slinton     }
6069676Slinton     sp = newsp;
6079676Slinton     if (streq(sep, "\n")) {
6089676Slinton 	putchar('\n');
6099676Slinton     }
6109676Slinton     printf(")");
6119676Slinton }
6129676Slinton 
6139676Slinton /*
6149676Slinton  * Print out the value of a real number in Pascal notation.
6159676Slinton  * This is, unfortunately, different than what one gets
6169676Slinton  * from "%g" in printf.
6179676Slinton  */
6189676Slinton 
6199676Slinton public prtreal(r)
6209676Slinton double r;
6219676Slinton {
6229676Slinton     extern char *index();
6239676Slinton     char buf[256];
6249676Slinton 
6259676Slinton     sprintf(buf, "%g", r);
6269676Slinton     if (buf[0] == '.') {
6279676Slinton 	printf("0%s", buf);
6289676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
6299676Slinton 	printf("-0%s", &buf[1]);
6309676Slinton     } else {
6319676Slinton 	printf("%s", buf);
6329676Slinton     }
6339676Slinton     if (index(buf, '.') == nil) {
6349676Slinton 	printf(".0");
6359676Slinton     }
6369676Slinton }
6379676Slinton 
6389676Slinton /*
6399676Slinton  * Print out a character using ^? notation for unprintables.
6409676Slinton  */
6419676Slinton 
6429676Slinton public printchar(c)
6439676Slinton char c;
6449676Slinton {
6459676Slinton     if (c == 0) {
6469676Slinton 	putchar('\\');
6479676Slinton 	putchar('0');
6489676Slinton     } else if (c == '\n') {
6499676Slinton 	putchar('\\');
6509676Slinton 	putchar('n');
6519676Slinton     } else if (c > 0 and c < ' ') {
6529676Slinton 	putchar('^');
6539676Slinton 	putchar(c - 1 + 'A');
65416616Ssam     } else if (c >= ' ' && c <= '~') {
65516616Ssam 	putchar(c);
6569676Slinton     } else {
65716616Ssam 	printf("\\0%o",c);
6589676Slinton     }
6599676Slinton }
66018229Slinton 
66118229Slinton /*
66218229Slinton  * Print out a value for a range type (integer, char, or boolean).
66318229Slinton  */
66418229Slinton 
66518229Slinton public printRangeVal (val, t)
66618229Slinton long val;
66718229Slinton Symbol t;
66818229Slinton {
66918229Slinton     if (t == t_boolean->type or istypename(t->type, "boolean")) {
67018229Slinton 	if ((boolean) val) {
67118229Slinton 	    printf("true");
67218229Slinton 	} else {
67318229Slinton 	    printf("false");
67418229Slinton 	}
67518229Slinton     } else if (t == t_char->type or istypename(t->type, "char")) {
67618229Slinton 	if (varIsSet("$hexchars")) {
67718229Slinton 	    printf("0x%lx", val);
67818229Slinton 	} else {
67918229Slinton 	    putchar('\'');
68018229Slinton 	    printchar(val);
68118229Slinton 	    putchar('\'');
68218229Slinton 	}
68318229Slinton     } else if (varIsSet("$hexints")) {
68418229Slinton 	printf("0x%lx", val);
68518229Slinton     } else if (t->symvalue.rangev.lower >= 0) {
68618229Slinton 	printf("%lu", val);
68718229Slinton     } else {
68818229Slinton 	printf("%ld", val);
68918229Slinton     }
69018229Slinton }
69118229Slinton 
69218229Slinton /*
69318229Slinton  * Print out an enumerated value by finding the corresponding
69418229Slinton  * name in the enumeration list.
69518229Slinton  */
69618229Slinton 
69718229Slinton public printEnum (i, t)
69818229Slinton integer i;
69918229Slinton Symbol t;
70018229Slinton {
70118229Slinton     register Symbol e;
70218229Slinton 
70318229Slinton     e = t->chain;
70418229Slinton     while (e != nil and e->symvalue.constval->value.lcon != i) {
70518229Slinton 	e = e->chain;
70618229Slinton     }
70718229Slinton     if (e != nil) {
70818229Slinton 	printf("%s", symname(e));
70918229Slinton     } else {
71018229Slinton 	printf("%d", i);
71118229Slinton     }
71218229Slinton }
71318229Slinton 
71418229Slinton /*
71518229Slinton  * Print out a null-terminated string (pointer to char)
71618229Slinton  * starting at the given address.
71718229Slinton  */
71818229Slinton 
71918229Slinton public printString (addr, quotes)
72018229Slinton Address addr;
72118229Slinton boolean quotes;
72218229Slinton {
72318229Slinton     register Address a;
72418229Slinton     register integer i, len;
72518229Slinton     register boolean endofstring;
72618229Slinton     union {
72718229Slinton 	char ch[sizeof(Word)];
72818229Slinton 	int word;
72918229Slinton     } u;
73018229Slinton 
73118229Slinton     if (varIsSet("$hexstrings")) {
73218229Slinton 	printf("0x%x", addr);
73318229Slinton     } else {
73418229Slinton 	if (quotes) {
73518229Slinton 	    putchar('"');
73618229Slinton 	}
73718229Slinton 	a = addr;
73818229Slinton 	endofstring = false;
73918229Slinton 	while (not endofstring) {
74018229Slinton 	    dread(&u, a, sizeof(u));
74118229Slinton 	    i = 0;
74218229Slinton 	    do {
74318229Slinton 		if (u.ch[i] == '\0') {
74418229Slinton 		    endofstring = true;
74518229Slinton 		} else {
74618229Slinton 		    printchar(u.ch[i]);
74718229Slinton 		}
74818229Slinton 		++i;
74918229Slinton 	    } while (i < sizeof(Word) and not endofstring);
75018229Slinton 	    a += sizeof(Word);
75118229Slinton 	}
75218229Slinton 	if (quotes) {
75318229Slinton 	    putchar('"');
75418229Slinton 	}
75518229Slinton     }
75618229Slinton }
757