xref: /csrg-svn/old/dbx/printsym.c (revision 42683)
121619Sdist /*
238105Sbostic  * Copyright (c) 1983 The Regents of the University of California.
338105Sbostic  * All rights reserved.
438105Sbostic  *
5*42683Sbostic  * %sccs.include.redist.c%
621619Sdist  */
79676Slinton 
821619Sdist #ifndef lint
9*42683Sbostic static char sccsid[] = "@(#)printsym.c	5.7 (Berkeley) 06/01/90";
1038105Sbostic #endif /* not lint */
119676Slinton 
129676Slinton /*
139676Slinton  * Printing of symbolic information.
149676Slinton  */
159676Slinton 
169676Slinton #include "defs.h"
179676Slinton #include "symbols.h"
189676Slinton #include "languages.h"
199676Slinton #include "printsym.h"
209676Slinton #include "tree.h"
219676Slinton #include "eval.h"
229676Slinton #include "mappings.h"
239676Slinton #include "process.h"
249676Slinton #include "runtime.h"
259676Slinton #include "machine.h"
269676Slinton #include "names.h"
2718229Slinton #include "keywords.h"
289676Slinton #include "main.h"
2929820Ssam #include <ctype.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[] = {
4933330Sdonn     "bad use", "constant", "type", "variable", "array", "array",
5033330Sdonn     "dynarray", "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 
classname(s)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 
printentry(s)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 
printexit(s)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 
printcall(s,t)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 
printrtn(s)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 
printparams(f,frame)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 
should_print(s)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 
printparamv(p,frame)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:
25533330Sdonn 	case OPENARRAY:
25618229Slinton 	case DYNARRAY:
25718229Slinton 	case SUBARRAY:
25818229Slinton 	    t = rtype(t->type);
25918229Slinton 	    if (compatible(t, t_char)) {
26018229Slinton 		printv(p, frame);
26118229Slinton 	    } else {
26218229Slinton 		printf("%s = (...)", symname(p));
26318229Slinton 	    }
26418229Slinton 	    break;
26518229Slinton 
26618229Slinton 	case RECORD:
26718229Slinton 	    printf("%s = (...)", symname(p));
26818229Slinton 	    break;
26918229Slinton 
27018229Slinton 	default:
27118229Slinton 	    printv(p, frame);
27218229Slinton 	    break;
27318229Slinton     }
27418229Slinton }
27518229Slinton 
27618229Slinton /*
2779676Slinton  * Print the name and value of a variable.
2789676Slinton  */
2799676Slinton 
printv(s,frame)2809676Slinton public printv(s, frame)
2819676Slinton Symbol s;
2829676Slinton Frame frame;
2839676Slinton {
2849676Slinton     Address addr;
2859676Slinton     int len;
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);
30024554Smckusick     if (not canpush(len)) {
30124554Smckusick 	printf("*** expression too large ***");
30224554Smckusick     } else if (isreg(s)) {
30324554Smckusick 	push(Address, addr);
30424554Smckusick 	printval(s->type);
30524554Smckusick     } else {
30618229Slinton 	rpush(addr, len);
30718229Slinton 	printval(s->type);
30818229Slinton     }
3099676Slinton }
3109676Slinton 
3119676Slinton /*
3129676Slinton  * Print out the name of a symbol.
3139676Slinton  */
3149676Slinton 
printname(f,s)3159676Slinton public printname(f, s)
3169676Slinton File f;
3179676Slinton Symbol s;
3189676Slinton {
3199676Slinton     if (s == nil) {
3209676Slinton 	fprintf(f, "(noname)");
32116616Ssam     } else if (s == program) {
32216616Ssam 	fprintf(f, ".");
3239676Slinton     } else if (isredirected() or isambiguous(s)) {
3249676Slinton 	printwhich(f, s);
3259676Slinton     } else {
3269676Slinton 	fprintf(f, "%s", symname(s));
3279676Slinton     }
3289676Slinton }
3299676Slinton 
3309676Slinton /*
3319676Slinton  * Print the fully specified variable that is described by the given identifer.
3329676Slinton  */
3339676Slinton 
printwhich(f,s)3349676Slinton public printwhich(f, s)
3359676Slinton File f;
3369676Slinton Symbol s;
3379676Slinton {
3389676Slinton     printouter(f, container(s));
3399676Slinton     fprintf(f, "%s", symname(s));
3409676Slinton }
3419676Slinton 
3429676Slinton /*
3439676Slinton  * Print the fully qualified name of each symbol that has the same name
3449676Slinton  * as the given symbol.
3459676Slinton  */
3469676Slinton 
printwhereis(f,s)3479676Slinton public printwhereis(f, s)
3489676Slinton File f;
3499676Slinton Symbol s;
3509676Slinton {
3519676Slinton     register Name n;
3529676Slinton     register Symbol t;
3539676Slinton 
3549676Slinton     checkref(s);
3559676Slinton     n = s->name;
3569676Slinton     t = lookup(n);
3579676Slinton     printwhich(f, t);
3589676Slinton     t = t->next_sym;
3599676Slinton     while (t != nil) {
3609676Slinton 	if (t->name == n) {
3619676Slinton 	    putc(' ', f);
3629676Slinton 	    printwhich(f, t);
3639676Slinton 	}
3649676Slinton 	t = t->next_sym;
3659676Slinton     }
3669676Slinton     putc('\n', f);
3679676Slinton }
3689676Slinton 
printouter(f,s)3699676Slinton private printouter(f, s)
3709676Slinton File f;
3719676Slinton Symbol s;
3729676Slinton {
3739676Slinton     Symbol outer;
3749676Slinton 
3759676Slinton     if (s != nil) {
3769676Slinton 	outer = container(s);
3779676Slinton 	if (outer != nil and outer != program) {
3789676Slinton 	    printouter(f, outer);
3799676Slinton 	}
3809676Slinton 	fprintf(f, "%s.", symname(s));
3819676Slinton     }
3829676Slinton }
3839676Slinton 
printdecl(s)3849676Slinton public printdecl(s)
3859676Slinton Symbol s;
3869676Slinton {
38718229Slinton     Language lang;
38818229Slinton 
3899676Slinton     checkref(s);
39018229Slinton     if (s->language == nil or s->language == primlang) {
39118229Slinton 	lang = findlanguage(".s");
39218229Slinton     } else {
39318229Slinton 	lang = s->language;
39418229Slinton     }
39518229Slinton     (*language_op(lang, L_PRINTDECL))(s);
3969676Slinton }
3979676Slinton 
3989676Slinton /*
3999676Slinton  * Straight dump of symbol information.
4009676Slinton  */
4019676Slinton 
psym(s)4029676Slinton public psym(s)
4039676Slinton Symbol s;
4049676Slinton {
4059676Slinton     printf("name\t%s\n", symname(s));
4069676Slinton     printf("lang\t%s\n", language_name(s->language));
4079676Slinton     printf("level\t%d\n", s->level);
4089676Slinton     printf("class\t%s\n", classname(s));
4099676Slinton     printf("type\t0x%x", s->type);
4109676Slinton     if (s->type != nil and s->type->name != nil) {
4119676Slinton 	printf(" (%s)", symname(s->type));
4129676Slinton     }
4139676Slinton     printf("\nchain\t0x%x", s->chain);
4149676Slinton     if (s->chain != nil and s->chain->name != nil) {
4159676Slinton 	printf(" (%s)", symname(s->chain));
4169676Slinton     }
4179676Slinton     printf("\nblock\t0x%x", s->block);
41833330Sdonn     if (s->block != nil and s->block->name != nil) {
4199676Slinton 	printf(" (");
4209676Slinton 	printname(stdout, s->block);
4219676Slinton 	putchar(')');
4229676Slinton     }
4239676Slinton     putchar('\n');
4249676Slinton     switch (s->class) {
42518229Slinton 	case TYPE:
42618229Slinton 	    printf("size\t%d\n", size(s));
42718229Slinton 	    break;
42818229Slinton 
4299676Slinton 	case VAR:
4309676Slinton 	case REF:
43133330Sdonn 	    switch (s->storage) {
43233330Sdonn 		case INREG:
43333330Sdonn 		    printf("reg\t%d\n", s->symvalue.offset);
43433330Sdonn 		    break;
43533330Sdonn 
43633330Sdonn 		case STK:
43733330Sdonn 		    printf("offset\t%d\n", s->symvalue.offset);
43833330Sdonn 		    break;
43933330Sdonn 
44033330Sdonn 		case EXT:
44133330Sdonn 		    printf("address\t0x%x\n", s->symvalue.offset);
44233330Sdonn 		    break;
4439676Slinton 	    }
44412545Scsvaf 	    printf("size\t%d\n", size(s));
4459676Slinton 	    break;
4469676Slinton 
4479676Slinton 	case RECORD:
4489676Slinton 	case VARNT:
4499676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
4509676Slinton 	    break;
4519676Slinton 
4529676Slinton 	case FIELD:
4539676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
4549676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
4559676Slinton 	    break;
4569676Slinton 
45714381Slinton 	case PROG:
4589676Slinton 	case PROC:
4599676Slinton 	case FUNC:
4609676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
46114438Slinton 	    if (isinline(s)) {
46214440Slinton 		printf("inline procedure\n");
46314438Slinton 	    }
46411863Slinton 	    if (nosource(s)) {
46511863Slinton 		printf("does not have source information\n");
46611863Slinton 	    } else {
46711863Slinton 		printf("has source information\n");
46811863Slinton 	    }
4699676Slinton 	    break;
4709676Slinton 
4719676Slinton 	case RANGE:
47214381Slinton 	    prangetype(s->symvalue.rangev.lowertype);
4739676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
47414381Slinton 	    prangetype(s->symvalue.rangev.uppertype);
4759676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
4769676Slinton 	    break;
4779676Slinton 
4789676Slinton 	default:
4799676Slinton 	    /* do nothing */
4809676Slinton 	    break;
4819676Slinton     }
4829676Slinton }
4839676Slinton 
prangetype(r)48414381Slinton private prangetype(r)
48514381Slinton Rangetype r;
48614381Slinton {
48714381Slinton     switch (r) {
48814381Slinton 	case R_CONST:
48914381Slinton 	    printf("CONST");
49014381Slinton 	    break;
49114381Slinton 
49214381Slinton 	case R_ARG:
49314381Slinton 	    printf("ARG");
49414381Slinton 	    break;
49514381Slinton 
49614381Slinton 	case R_TEMP:
49714381Slinton 	    printf("TEMP");
49814381Slinton 	    break;
49914381Slinton 
50014381Slinton 	case R_ADJUST:
50114381Slinton 	    printf("ADJUST");
50214381Slinton 	    break;
50314381Slinton     }
50414381Slinton }
50514381Slinton 
5069676Slinton /*
5079676Slinton  * Print out the value on top of the stack according to the given type.
5089676Slinton  */
5099676Slinton 
printval(t)5109676Slinton public printval(t)
5119676Slinton Symbol t;
5129676Slinton {
5139676Slinton     Symbol s;
5149676Slinton 
5159676Slinton     checkref(t);
51616616Ssam     if (t->class == TYPEREF) {
51716616Ssam 	resolveRef(t);
51816616Ssam     }
5199676Slinton     switch (t->class) {
5209676Slinton 	case PROC:
5219676Slinton 	case FUNC:
5229676Slinton 	    s = pop(Symbol);
5239676Slinton 	    printf("%s", symname(s));
5249676Slinton 	    break;
5259676Slinton 
5269676Slinton 	default:
52718229Slinton 	    if (t->language == nil or t->language == primlang) {
52826478Ssam 		(*language_op(findlanguage(".c"), L_PRINTVAL))(t);
5299676Slinton 	    } else {
5309676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
5319676Slinton 	    }
5329676Slinton 	    break;
5339676Slinton     }
5349676Slinton }
5359676Slinton 
5369676Slinton /*
5379676Slinton  * Print out the value of a record, field by field.
5389676Slinton  */
5399676Slinton 
printrecord(s)5409676Slinton public printrecord(s)
5419676Slinton Symbol s;
5429676Slinton {
54316616Ssam     Symbol f;
54416616Ssam 
5459676Slinton     if (s->chain == nil) {
5469676Slinton 	error("record has no fields");
5479676Slinton     }
5489676Slinton     printf("(");
5499676Slinton     sp -= size(s);
55016616Ssam     f = s->chain;
55116616Ssam     if (f != nil) {
55216616Ssam 	for (;;) {
55316616Ssam 	    printfield(f);
55416616Ssam 	    f = f->chain;
55516616Ssam 	if (f == nil) break;
55616616Ssam 	    printf(", ");
55716616Ssam 	}
55816616Ssam     }
5599676Slinton     printf(")");
5609676Slinton }
5619676Slinton 
5629676Slinton /*
56316616Ssam  * Print out a field.
5649676Slinton  */
5659676Slinton 
printfield(f)56616616Ssam private printfield(f)
56716616Ssam Symbol f;
5689676Slinton {
5699676Slinton     Stack *savesp;
57016616Ssam     register int off, len;
5719676Slinton 
57216616Ssam     printf("%s = ", symname(f));
5739676Slinton     savesp = sp;
57416616Ssam     off = f->symvalue.field.offset;
57516616Ssam     len = f->symvalue.field.length;
57616616Ssam     sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE);
57716616Ssam     printval(f);
5789676Slinton     sp = savesp;
5799676Slinton }
5809676Slinton 
5819676Slinton /*
5829676Slinton  * Print out the contents of an array.
5839676Slinton  * Haven't quite figured out what the best format is.
5849676Slinton  *
5859676Slinton  * This is rather inefficient.
5869676Slinton  *
5879676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
5889676Slinton  */
5899676Slinton 
printarray(a)5909676Slinton public printarray(a)
5919676Slinton Symbol a;
5929676Slinton {
5939676Slinton     Stack *savesp, *newsp;
5949676Slinton     Symbol eltype;
5959676Slinton     long elsize;
5969676Slinton     String sep;
5979676Slinton 
5989676Slinton     savesp = sp;
59912544Scsvaf     sp -= (size(a));
6009676Slinton     newsp = sp;
6019676Slinton     eltype = rtype(a->type);
6029676Slinton     elsize = size(eltype);
6039676Slinton     printf("(");
6049676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
6059676Slinton       eltype->class == VARNT) {
6069676Slinton 	sep = "\n";
6079676Slinton 	putchar('\n');
6089676Slinton     } else {
6099676Slinton 	sep = ", ";
6109676Slinton     }
6119676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
6129676Slinton 	if (sp - elsize != newsp) {
6139676Slinton 	    fputs(sep, stdout);
6149676Slinton 	}
6159676Slinton 	printval(eltype);
6169676Slinton     }
6179676Slinton     sp = newsp;
6189676Slinton     if (streq(sep, "\n")) {
6199676Slinton 	putchar('\n');
6209676Slinton     }
6219676Slinton     printf(")");
6229676Slinton }
6239676Slinton 
6249676Slinton /*
6259676Slinton  * Print out the value of a real number in Pascal notation.
6269676Slinton  * This is, unfortunately, different than what one gets
6279676Slinton  * from "%g" in printf.
6289676Slinton  */
6299676Slinton 
prtreal(r)6309676Slinton public prtreal(r)
6319676Slinton double r;
6329676Slinton {
6339676Slinton     extern char *index();
6349676Slinton     char buf[256];
6359676Slinton 
63633330Sdonn #   ifdef IRIS
63733330Sdonn 	sprintf(buf, "%lg", r);
63833330Sdonn #   else
63933330Sdonn 	sprintf(buf, "%g", r);
64033330Sdonn #   endif
6419676Slinton     if (buf[0] == '.') {
6429676Slinton 	printf("0%s", buf);
6439676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
6449676Slinton 	printf("-0%s", &buf[1]);
6459676Slinton     } else {
6469676Slinton 	printf("%s", buf);
6479676Slinton     }
6489676Slinton     if (index(buf, '.') == nil) {
6499676Slinton 	printf(".0");
6509676Slinton     }
6519676Slinton }
6529676Slinton 
6539676Slinton /*
6549676Slinton  * Print out a character using ^? notation for unprintables.
6559676Slinton  */
6569676Slinton 
printchar(c)6579676Slinton public printchar(c)
6589676Slinton char c;
6599676Slinton {
6609676Slinton     if (c == 0) {
6619676Slinton 	putchar('\\');
6629676Slinton 	putchar('0');
6639676Slinton     } else if (c == '\n') {
6649676Slinton 	putchar('\\');
6659676Slinton 	putchar('n');
6669676Slinton     } else if (c > 0 and c < ' ') {
6679676Slinton 	putchar('^');
6689676Slinton 	putchar(c - 1 + 'A');
66916616Ssam     } else if (c >= ' ' && c <= '~') {
67016616Ssam 	putchar(c);
6719676Slinton     } else {
67229820Ssam 	printf("\\0%o",c&0xff);
6739676Slinton     }
6749676Slinton }
67518229Slinton 
67618229Slinton /*
67718229Slinton  * Print out a value for a range type (integer, char, or boolean).
67818229Slinton  */
67918229Slinton 
printRangeVal(val,t)68018229Slinton public printRangeVal (val, t)
68118229Slinton long val;
68218229Slinton Symbol t;
68318229Slinton {
68418229Slinton     if (t == t_boolean->type or istypename(t->type, "boolean")) {
68518229Slinton 	if ((boolean) val) {
68618229Slinton 	    printf("true");
68718229Slinton 	} else {
68818229Slinton 	    printf("false");
68918229Slinton 	}
69018229Slinton     } else if (t == t_char->type or istypename(t->type, "char")) {
69118229Slinton 	if (varIsSet("$hexchars")) {
69218229Slinton 	    printf("0x%lx", val);
69318229Slinton 	} else {
69418229Slinton 	    putchar('\'');
69518229Slinton 	    printchar(val);
69618229Slinton 	    putchar('\'');
69718229Slinton 	}
69818229Slinton     } else if (varIsSet("$hexints")) {
69918229Slinton 	printf("0x%lx", val);
70018229Slinton     } else if (t->symvalue.rangev.lower >= 0) {
70118229Slinton 	printf("%lu", val);
70218229Slinton     } else {
70318229Slinton 	printf("%ld", val);
70418229Slinton     }
70518229Slinton }
70618229Slinton 
70718229Slinton /*
70818229Slinton  * Print out an enumerated value by finding the corresponding
70918229Slinton  * name in the enumeration list.
71018229Slinton  */
71118229Slinton 
printEnum(i,t)71218229Slinton public printEnum (i, t)
71318229Slinton integer i;
71418229Slinton Symbol t;
71518229Slinton {
71618229Slinton     register Symbol e;
71718229Slinton 
71818229Slinton     e = t->chain;
71918229Slinton     while (e != nil and e->symvalue.constval->value.lcon != i) {
72018229Slinton 	e = e->chain;
72118229Slinton     }
72218229Slinton     if (e != nil) {
72318229Slinton 	printf("%s", symname(e));
72418229Slinton     } else {
72518229Slinton 	printf("%d", i);
72618229Slinton     }
72718229Slinton }
72818229Slinton 
72918229Slinton /*
73018229Slinton  * Print out a null-terminated string (pointer to char)
73118229Slinton  * starting at the given address.
73218229Slinton  */
73318229Slinton 
printString(addr,quotes)73418229Slinton public printString (addr, quotes)
73518229Slinton Address addr;
73618229Slinton boolean quotes;
73718229Slinton {
73818229Slinton     register Address a;
73918229Slinton     register integer i, len;
74018229Slinton     register boolean endofstring;
74129820Ssam     register int unprintables;
74229820Ssam #define	MAXGARBAGE	4
74318229Slinton     union {
74418229Slinton 	char ch[sizeof(Word)];
74518229Slinton 	int word;
74618229Slinton     } u;
74718229Slinton 
74818229Slinton     if (varIsSet("$hexstrings")) {
74918229Slinton 	printf("0x%x", addr);
75018229Slinton     } else {
75118229Slinton 	if (quotes) {
75218229Slinton 	    putchar('"');
75318229Slinton 	}
75418229Slinton 	a = addr;
75529820Ssam 	unprintables = 0;
75618229Slinton 	endofstring = false;
75718229Slinton 	while (not endofstring) {
75818229Slinton 	    dread(&u, a, sizeof(u));
75918229Slinton 	    i = 0;
76018229Slinton 	    do {
76118229Slinton 		if (u.ch[i] == '\0') {
76218229Slinton 		    endofstring = true;
76318229Slinton 		} else {
76418229Slinton 		    printchar(u.ch[i]);
76529820Ssam 		    if (!isascii(u.ch[i]) and ++unprintables > MAXGARBAGE) {
76629820Ssam 			endofstring = true;
76729820Ssam 			printf("...");
76829820Ssam 		    }
76918229Slinton 		}
77018229Slinton 		++i;
77118229Slinton 	    } while (i < sizeof(Word) and not endofstring);
77218229Slinton 	    a += sizeof(Word);
77318229Slinton 	}
77418229Slinton 	if (quotes) {
77518229Slinton 	    putchar('"');
77618229Slinton 	}
77718229Slinton     }
77818229Slinton }
779