xref: /csrg-svn/old/dbx/printsym.c (revision 38105)
121619Sdist /*
2*38105Sbostic  * Copyright (c) 1983 The Regents of the University of California.
3*38105Sbostic  * All rights reserved.
4*38105Sbostic  *
5*38105Sbostic  * Redistribution and use in source and binary forms are permitted
6*38105Sbostic  * provided that the above copyright notice and this paragraph are
7*38105Sbostic  * duplicated in all such forms and that any documentation,
8*38105Sbostic  * advertising materials, and other materials related to such
9*38105Sbostic  * distribution and use acknowledge that the software was developed
10*38105Sbostic  * by the University of California, Berkeley.  The name of the
11*38105Sbostic  * University may not be used to endorse or promote products derived
12*38105Sbostic  * from this software without specific prior written permission.
13*38105Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*38105Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*38105Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621619Sdist  */
179676Slinton 
1821619Sdist #ifndef lint
19*38105Sbostic static char sccsid[] = "@(#)printsym.c	5.6 (Berkeley) 05/23/89";
20*38105Sbostic #endif /* not lint */
219676Slinton 
229676Slinton /*
239676Slinton  * Printing of symbolic information.
249676Slinton  */
259676Slinton 
269676Slinton #include "defs.h"
279676Slinton #include "symbols.h"
289676Slinton #include "languages.h"
299676Slinton #include "printsym.h"
309676Slinton #include "tree.h"
319676Slinton #include "eval.h"
329676Slinton #include "mappings.h"
339676Slinton #include "process.h"
349676Slinton #include "runtime.h"
359676Slinton #include "machine.h"
369676Slinton #include "names.h"
3718229Slinton #include "keywords.h"
389676Slinton #include "main.h"
3929820Ssam #include <ctype.h>
409676Slinton 
419676Slinton #ifndef public
429676Slinton #endif
439676Slinton 
449676Slinton /*
4511863Slinton  * Maximum number of arguments to a function.
4611863Slinton  * This is used as a check for the possibility that the stack has been
4711863Slinton  * overwritten and therefore a saved argument pointer might indicate
4811863Slinton  * to an absurdly large number of arguments.
4911863Slinton  */
5011863Slinton 
5111863Slinton #define MAXARGSPASSED 20
5211863Slinton 
5311863Slinton /*
549676Slinton  * Return a pointer to the string for the name of the class that
559676Slinton  * the given symbol belongs to.
569676Slinton  */
579676Slinton 
589676Slinton private String clname[] = {
5933330Sdonn     "bad use", "constant", "type", "variable", "array", "array",
6033330Sdonn     "dynarray", "subarray", "fileptr", "record", "field",
6118229Slinton     "procedure", "function", "funcvar",
629676Slinton     "ref", "pointer", "file", "set", "range", "label", "withptr",
639676Slinton     "scalar", "string", "program", "improper", "variant",
6416616Ssam     "procparam", "funcparam", "module", "tag", "common", "extref", "typeref"
659676Slinton };
669676Slinton 
679676Slinton public String classname(s)
689676Slinton Symbol s;
699676Slinton {
709676Slinton     return clname[ord(s->class)];
719676Slinton }
729676Slinton 
739676Slinton /*
749676Slinton  * Note the entry of the given block, unless it's the main program.
759676Slinton  */
769676Slinton 
779676Slinton public printentry(s)
789676Slinton Symbol s;
799676Slinton {
809676Slinton     if (s != program) {
8118229Slinton 	printf("\nentering %s ", classname(s));
8218229Slinton 	printname(stdout, s);
8318229Slinton 	printf("\n");
849676Slinton     }
859676Slinton }
869676Slinton 
879676Slinton /*
889676Slinton  * Note the exit of the given block
899676Slinton  */
909676Slinton 
919676Slinton public printexit(s)
929676Slinton Symbol s;
939676Slinton {
949676Slinton     if (s != program) {
9518229Slinton 	printf("leaving %s ", classname(s));
9618229Slinton 	printname(stdout, s);
9718229Slinton 	printf("\n\n");
989676Slinton     }
999676Slinton }
1009676Slinton 
1019676Slinton /*
1029676Slinton  * Note the call of s from t.
1039676Slinton  */
1049676Slinton 
1059676Slinton public printcall(s, t)
1069676Slinton Symbol s, t;
1079676Slinton {
10818229Slinton     printf("calling ");
10918229Slinton     printname(stdout, s);
1109676Slinton     printparams(s, nil);
11118229Slinton     printf(" from %s ", classname(t));
11218229Slinton     printname(stdout, t);
11318229Slinton     printf("\n");
1149676Slinton }
1159676Slinton 
1169676Slinton /*
1179676Slinton  * Note the return from s.  If s is a function, print the value
1189676Slinton  * it is returning.  This is somewhat painful, since the function
1199676Slinton  * has actually just returned.
1209676Slinton  */
1219676Slinton 
1229676Slinton public printrtn(s)
1239676Slinton Symbol s;
1249676Slinton {
1259676Slinton     register Symbol t;
1269676Slinton     register int len;
1279676Slinton     Boolean isindirect;
1289676Slinton 
1299676Slinton     printf("returning ");
13012628Scsvaf     if (s->class == FUNC && (!istypename(s->type,"void"))) {
1319676Slinton 	len = size(s->type);
1329676Slinton 	if (canpush(len)) {
1339676Slinton 	    t = rtype(s->type);
1349676Slinton 	    isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
1359676Slinton 	    pushretval(len, isindirect);
1369676Slinton 	    printval(s->type);
1379676Slinton 	    putchar(' ');
1389676Slinton 	} else {
1399676Slinton 	    printf("(value too large) ");
1409676Slinton 	}
1419676Slinton     }
14218229Slinton     printf("from ");
14318229Slinton     printname(stdout, s);
14418229Slinton     printf("\n");
1459676Slinton }
1469676Slinton 
1479676Slinton /*
1489676Slinton  * Print the values of the parameters of the given procedure or function.
1499676Slinton  * The frame distinguishes recursive instances of a procedure.
15016616Ssam  *
15116616Ssam  * If the procedure or function is internal, the argument count is
15216616Ssam  * not valid so we ignore it.
1539676Slinton  */
1549676Slinton 
1559676Slinton public printparams(f, frame)
1569676Slinton Symbol f;
1579676Slinton Frame frame;
1589676Slinton {
1599676Slinton     Symbol param;
1609676Slinton     int n, m, s;
1619676Slinton 
1629676Slinton     n = nargspassed(frame);
16316616Ssam     if (isinternal(f)) {
16416616Ssam 	n = 0;
16516616Ssam     }
16618229Slinton     printf("(");
1679676Slinton     param = f->chain;
1689676Slinton     if (param != nil or n > 0) {
1699676Slinton 	m = n;
1709676Slinton 	if (param != nil) {
1719676Slinton 	    for (;;) {
17218229Slinton 		s = psize(param) div sizeof(Word);
1739676Slinton 		if (s == 0) {
1749676Slinton 		    s = 1;
1759676Slinton 		}
1769676Slinton 		m -= s;
17718229Slinton 		if (showaggrs) {
17818229Slinton 		    printv(param, frame);
17918229Slinton 		} else {
18018229Slinton 		    printparamv(param, frame);
18118229Slinton 		}
1829676Slinton 		param = param->chain;
1839676Slinton 	    if (param == nil) break;
1849676Slinton 		printf(", ");
1859676Slinton 	    }
1869676Slinton 	}
1879676Slinton 	if (m > 0) {
18811863Slinton 	    if (m > MAXARGSPASSED) {
18911863Slinton 		m = MAXARGSPASSED;
19011863Slinton 	    }
1919676Slinton 	    if (f->chain != nil) {
1929676Slinton 		printf(", ");
1939676Slinton 	    }
1949676Slinton 	    for (;;) {
1959676Slinton 		--m;
1969676Slinton 		printf("0x%x", argn(n - m, frame));
1979676Slinton 	    if (m <= 0) break;
1989676Slinton 		printf(", ");
1999676Slinton 	    }
2009676Slinton 	}
2019676Slinton     }
20218229Slinton     printf(")");
2039676Slinton }
2049676Slinton 
2059676Slinton /*
2069676Slinton  * Test if a symbol should be printed.  We don't print files,
2079676Slinton  * for example, simply because there's no good way to do it.
2089676Slinton  * The symbol must be within the given function.
2099676Slinton  */
2109676Slinton 
2119676Slinton public Boolean should_print(s)
2129676Slinton Symbol s;
2139676Slinton {
2149676Slinton     Boolean b;
2159676Slinton     register Symbol t;
2169676Slinton 
2179676Slinton     switch (s->class) {
2189676Slinton 	case VAR:
2199676Slinton 	case FVAR:
22014339Slinton 	    if (isparam(s)) {
22114339Slinton 		b = false;
22214339Slinton 	    } else {
22314339Slinton 		t = rtype(s->type);
22414339Slinton 		if (t == nil) {
22514339Slinton 		    b = false;
22614339Slinton 		} else {
22714339Slinton 		    switch (t->class) {
22814339Slinton 			case FILET:
22914339Slinton 			case SET:
23014339Slinton 			case BADUSE:
23114339Slinton 			    b = false;
23214339Slinton 			    break;
23314339Slinton 
23414339Slinton 			default:
23514339Slinton 			    b = true;
23614339Slinton 			    break;
23714339Slinton 		    }
23814339Slinton 		}
23914339Slinton 	    }
2409676Slinton 	    break;
2419676Slinton 
2429676Slinton 	default:
2439676Slinton 	    b = false;
2449676Slinton 	    break;
2459676Slinton     }
2469676Slinton     return b;
2479676Slinton }
2489676Slinton 
2499676Slinton /*
25018229Slinton  * Print out a parameter value.
25118229Slinton  *
25218229Slinton  * Since this is intended to be printed on a single line with other information
25318229Slinton  * aggregate values are not printed.
25418229Slinton  */
25518229Slinton 
25618229Slinton public printparamv (p, frame)
25718229Slinton Symbol p;
25818229Slinton Frame frame;
25918229Slinton {
26018229Slinton     Symbol t;
26118229Slinton 
26218229Slinton     t = rtype(p->type);
26318229Slinton     switch (t->class) {
26418229Slinton 	case ARRAY:
26533330Sdonn 	case OPENARRAY:
26618229Slinton 	case DYNARRAY:
26718229Slinton 	case SUBARRAY:
26818229Slinton 	    t = rtype(t->type);
26918229Slinton 	    if (compatible(t, t_char)) {
27018229Slinton 		printv(p, frame);
27118229Slinton 	    } else {
27218229Slinton 		printf("%s = (...)", symname(p));
27318229Slinton 	    }
27418229Slinton 	    break;
27518229Slinton 
27618229Slinton 	case RECORD:
27718229Slinton 	    printf("%s = (...)", symname(p));
27818229Slinton 	    break;
27918229Slinton 
28018229Slinton 	default:
28118229Slinton 	    printv(p, frame);
28218229Slinton 	    break;
28318229Slinton     }
28418229Slinton }
28518229Slinton 
28618229Slinton /*
2879676Slinton  * Print the name and value of a variable.
2889676Slinton  */
2899676Slinton 
2909676Slinton public printv(s, frame)
2919676Slinton Symbol s;
2929676Slinton Frame frame;
2939676Slinton {
2949676Slinton     Address addr;
2959676Slinton     int len;
2969676Slinton 
2979676Slinton     if (isambiguous(s) and ismodule(container(s))) {
2989676Slinton 	printname(stdout, s);
2999676Slinton 	printf(" = ");
3009676Slinton     } else {
3019676Slinton 	printf("%s = ", symname(s));
3029676Slinton     }
30318229Slinton     if (isvarparam(s) and not isopenarray(s)) {
30418229Slinton 	rpush(address(s, frame), sizeof(Address));
30518229Slinton 	addr = pop(Address);
3069676Slinton     } else {
30718229Slinton 	addr = address(s, frame);
30818229Slinton     }
30918229Slinton     len = size(s);
31024554Smckusick     if (not canpush(len)) {
31124554Smckusick 	printf("*** expression too large ***");
31224554Smckusick     } else if (isreg(s)) {
31324554Smckusick 	push(Address, addr);
31424554Smckusick 	printval(s->type);
31524554Smckusick     } else {
31618229Slinton 	rpush(addr, len);
31718229Slinton 	printval(s->type);
31818229Slinton     }
3199676Slinton }
3209676Slinton 
3219676Slinton /*
3229676Slinton  * Print out the name of a symbol.
3239676Slinton  */
3249676Slinton 
3259676Slinton public printname(f, s)
3269676Slinton File f;
3279676Slinton Symbol s;
3289676Slinton {
3299676Slinton     if (s == nil) {
3309676Slinton 	fprintf(f, "(noname)");
33116616Ssam     } else if (s == program) {
33216616Ssam 	fprintf(f, ".");
3339676Slinton     } else if (isredirected() or isambiguous(s)) {
3349676Slinton 	printwhich(f, s);
3359676Slinton     } else {
3369676Slinton 	fprintf(f, "%s", symname(s));
3379676Slinton     }
3389676Slinton }
3399676Slinton 
3409676Slinton /*
3419676Slinton  * Print the fully specified variable that is described by the given identifer.
3429676Slinton  */
3439676Slinton 
3449676Slinton public printwhich(f, s)
3459676Slinton File f;
3469676Slinton Symbol s;
3479676Slinton {
3489676Slinton     printouter(f, container(s));
3499676Slinton     fprintf(f, "%s", symname(s));
3509676Slinton }
3519676Slinton 
3529676Slinton /*
3539676Slinton  * Print the fully qualified name of each symbol that has the same name
3549676Slinton  * as the given symbol.
3559676Slinton  */
3569676Slinton 
3579676Slinton public printwhereis(f, s)
3589676Slinton File f;
3599676Slinton Symbol s;
3609676Slinton {
3619676Slinton     register Name n;
3629676Slinton     register Symbol t;
3639676Slinton 
3649676Slinton     checkref(s);
3659676Slinton     n = s->name;
3669676Slinton     t = lookup(n);
3679676Slinton     printwhich(f, t);
3689676Slinton     t = t->next_sym;
3699676Slinton     while (t != nil) {
3709676Slinton 	if (t->name == n) {
3719676Slinton 	    putc(' ', f);
3729676Slinton 	    printwhich(f, t);
3739676Slinton 	}
3749676Slinton 	t = t->next_sym;
3759676Slinton     }
3769676Slinton     putc('\n', f);
3779676Slinton }
3789676Slinton 
3799676Slinton private printouter(f, s)
3809676Slinton File f;
3819676Slinton Symbol s;
3829676Slinton {
3839676Slinton     Symbol outer;
3849676Slinton 
3859676Slinton     if (s != nil) {
3869676Slinton 	outer = container(s);
3879676Slinton 	if (outer != nil and outer != program) {
3889676Slinton 	    printouter(f, outer);
3899676Slinton 	}
3909676Slinton 	fprintf(f, "%s.", symname(s));
3919676Slinton     }
3929676Slinton }
3939676Slinton 
3949676Slinton public printdecl(s)
3959676Slinton Symbol s;
3969676Slinton {
39718229Slinton     Language lang;
39818229Slinton 
3999676Slinton     checkref(s);
40018229Slinton     if (s->language == nil or s->language == primlang) {
40118229Slinton 	lang = findlanguage(".s");
40218229Slinton     } else {
40318229Slinton 	lang = s->language;
40418229Slinton     }
40518229Slinton     (*language_op(lang, L_PRINTDECL))(s);
4069676Slinton }
4079676Slinton 
4089676Slinton /*
4099676Slinton  * Straight dump of symbol information.
4109676Slinton  */
4119676Slinton 
4129676Slinton public psym(s)
4139676Slinton Symbol s;
4149676Slinton {
4159676Slinton     printf("name\t%s\n", symname(s));
4169676Slinton     printf("lang\t%s\n", language_name(s->language));
4179676Slinton     printf("level\t%d\n", s->level);
4189676Slinton     printf("class\t%s\n", classname(s));
4199676Slinton     printf("type\t0x%x", s->type);
4209676Slinton     if (s->type != nil and s->type->name != nil) {
4219676Slinton 	printf(" (%s)", symname(s->type));
4229676Slinton     }
4239676Slinton     printf("\nchain\t0x%x", s->chain);
4249676Slinton     if (s->chain != nil and s->chain->name != nil) {
4259676Slinton 	printf(" (%s)", symname(s->chain));
4269676Slinton     }
4279676Slinton     printf("\nblock\t0x%x", s->block);
42833330Sdonn     if (s->block != nil and s->block->name != nil) {
4299676Slinton 	printf(" (");
4309676Slinton 	printname(stdout, s->block);
4319676Slinton 	putchar(')');
4329676Slinton     }
4339676Slinton     putchar('\n');
4349676Slinton     switch (s->class) {
43518229Slinton 	case TYPE:
43618229Slinton 	    printf("size\t%d\n", size(s));
43718229Slinton 	    break;
43818229Slinton 
4399676Slinton 	case VAR:
4409676Slinton 	case REF:
44133330Sdonn 	    switch (s->storage) {
44233330Sdonn 		case INREG:
44333330Sdonn 		    printf("reg\t%d\n", s->symvalue.offset);
44433330Sdonn 		    break;
44533330Sdonn 
44633330Sdonn 		case STK:
44733330Sdonn 		    printf("offset\t%d\n", s->symvalue.offset);
44833330Sdonn 		    break;
44933330Sdonn 
45033330Sdonn 		case EXT:
45133330Sdonn 		    printf("address\t0x%x\n", s->symvalue.offset);
45233330Sdonn 		    break;
4539676Slinton 	    }
45412545Scsvaf 	    printf("size\t%d\n", size(s));
4559676Slinton 	    break;
4569676Slinton 
4579676Slinton 	case RECORD:
4589676Slinton 	case VARNT:
4599676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
4609676Slinton 	    break;
4619676Slinton 
4629676Slinton 	case FIELD:
4639676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
4649676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
4659676Slinton 	    break;
4669676Slinton 
46714381Slinton 	case PROG:
4689676Slinton 	case PROC:
4699676Slinton 	case FUNC:
4709676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
47114438Slinton 	    if (isinline(s)) {
47214440Slinton 		printf("inline procedure\n");
47314438Slinton 	    }
47411863Slinton 	    if (nosource(s)) {
47511863Slinton 		printf("does not have source information\n");
47611863Slinton 	    } else {
47711863Slinton 		printf("has source information\n");
47811863Slinton 	    }
4799676Slinton 	    break;
4809676Slinton 
4819676Slinton 	case RANGE:
48214381Slinton 	    prangetype(s->symvalue.rangev.lowertype);
4839676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
48414381Slinton 	    prangetype(s->symvalue.rangev.uppertype);
4859676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
4869676Slinton 	    break;
4879676Slinton 
4889676Slinton 	default:
4899676Slinton 	    /* do nothing */
4909676Slinton 	    break;
4919676Slinton     }
4929676Slinton }
4939676Slinton 
49414381Slinton private prangetype(r)
49514381Slinton Rangetype r;
49614381Slinton {
49714381Slinton     switch (r) {
49814381Slinton 	case R_CONST:
49914381Slinton 	    printf("CONST");
50014381Slinton 	    break;
50114381Slinton 
50214381Slinton 	case R_ARG:
50314381Slinton 	    printf("ARG");
50414381Slinton 	    break;
50514381Slinton 
50614381Slinton 	case R_TEMP:
50714381Slinton 	    printf("TEMP");
50814381Slinton 	    break;
50914381Slinton 
51014381Slinton 	case R_ADJUST:
51114381Slinton 	    printf("ADJUST");
51214381Slinton 	    break;
51314381Slinton     }
51414381Slinton }
51514381Slinton 
5169676Slinton /*
5179676Slinton  * Print out the value on top of the stack according to the given type.
5189676Slinton  */
5199676Slinton 
5209676Slinton public printval(t)
5219676Slinton Symbol t;
5229676Slinton {
5239676Slinton     Symbol s;
5249676Slinton 
5259676Slinton     checkref(t);
52616616Ssam     if (t->class == TYPEREF) {
52716616Ssam 	resolveRef(t);
52816616Ssam     }
5299676Slinton     switch (t->class) {
5309676Slinton 	case PROC:
5319676Slinton 	case FUNC:
5329676Slinton 	    s = pop(Symbol);
5339676Slinton 	    printf("%s", symname(s));
5349676Slinton 	    break;
5359676Slinton 
5369676Slinton 	default:
53718229Slinton 	    if (t->language == nil or t->language == primlang) {
53826478Ssam 		(*language_op(findlanguage(".c"), L_PRINTVAL))(t);
5399676Slinton 	    } else {
5409676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
5419676Slinton 	    }
5429676Slinton 	    break;
5439676Slinton     }
5449676Slinton }
5459676Slinton 
5469676Slinton /*
5479676Slinton  * Print out the value of a record, field by field.
5489676Slinton  */
5499676Slinton 
5509676Slinton public printrecord(s)
5519676Slinton Symbol s;
5529676Slinton {
55316616Ssam     Symbol f;
55416616Ssam 
5559676Slinton     if (s->chain == nil) {
5569676Slinton 	error("record has no fields");
5579676Slinton     }
5589676Slinton     printf("(");
5599676Slinton     sp -= size(s);
56016616Ssam     f = s->chain;
56116616Ssam     if (f != nil) {
56216616Ssam 	for (;;) {
56316616Ssam 	    printfield(f);
56416616Ssam 	    f = f->chain;
56516616Ssam 	if (f == nil) break;
56616616Ssam 	    printf(", ");
56716616Ssam 	}
56816616Ssam     }
5699676Slinton     printf(")");
5709676Slinton }
5719676Slinton 
5729676Slinton /*
57316616Ssam  * Print out a field.
5749676Slinton  */
5759676Slinton 
57616616Ssam private printfield(f)
57716616Ssam Symbol f;
5789676Slinton {
5799676Slinton     Stack *savesp;
58016616Ssam     register int off, len;
5819676Slinton 
58216616Ssam     printf("%s = ", symname(f));
5839676Slinton     savesp = sp;
58416616Ssam     off = f->symvalue.field.offset;
58516616Ssam     len = f->symvalue.field.length;
58616616Ssam     sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE);
58716616Ssam     printval(f);
5889676Slinton     sp = savesp;
5899676Slinton }
5909676Slinton 
5919676Slinton /*
5929676Slinton  * Print out the contents of an array.
5939676Slinton  * Haven't quite figured out what the best format is.
5949676Slinton  *
5959676Slinton  * This is rather inefficient.
5969676Slinton  *
5979676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
5989676Slinton  */
5999676Slinton 
6009676Slinton public printarray(a)
6019676Slinton Symbol a;
6029676Slinton {
6039676Slinton     Stack *savesp, *newsp;
6049676Slinton     Symbol eltype;
6059676Slinton     long elsize;
6069676Slinton     String sep;
6079676Slinton 
6089676Slinton     savesp = sp;
60912544Scsvaf     sp -= (size(a));
6109676Slinton     newsp = sp;
6119676Slinton     eltype = rtype(a->type);
6129676Slinton     elsize = size(eltype);
6139676Slinton     printf("(");
6149676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
6159676Slinton       eltype->class == VARNT) {
6169676Slinton 	sep = "\n";
6179676Slinton 	putchar('\n');
6189676Slinton     } else {
6199676Slinton 	sep = ", ";
6209676Slinton     }
6219676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
6229676Slinton 	if (sp - elsize != newsp) {
6239676Slinton 	    fputs(sep, stdout);
6249676Slinton 	}
6259676Slinton 	printval(eltype);
6269676Slinton     }
6279676Slinton     sp = newsp;
6289676Slinton     if (streq(sep, "\n")) {
6299676Slinton 	putchar('\n');
6309676Slinton     }
6319676Slinton     printf(")");
6329676Slinton }
6339676Slinton 
6349676Slinton /*
6359676Slinton  * Print out the value of a real number in Pascal notation.
6369676Slinton  * This is, unfortunately, different than what one gets
6379676Slinton  * from "%g" in printf.
6389676Slinton  */
6399676Slinton 
6409676Slinton public prtreal(r)
6419676Slinton double r;
6429676Slinton {
6439676Slinton     extern char *index();
6449676Slinton     char buf[256];
6459676Slinton 
64633330Sdonn #   ifdef IRIS
64733330Sdonn 	sprintf(buf, "%lg", r);
64833330Sdonn #   else
64933330Sdonn 	sprintf(buf, "%g", r);
65033330Sdonn #   endif
6519676Slinton     if (buf[0] == '.') {
6529676Slinton 	printf("0%s", buf);
6539676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
6549676Slinton 	printf("-0%s", &buf[1]);
6559676Slinton     } else {
6569676Slinton 	printf("%s", buf);
6579676Slinton     }
6589676Slinton     if (index(buf, '.') == nil) {
6599676Slinton 	printf(".0");
6609676Slinton     }
6619676Slinton }
6629676Slinton 
6639676Slinton /*
6649676Slinton  * Print out a character using ^? notation for unprintables.
6659676Slinton  */
6669676Slinton 
6679676Slinton public printchar(c)
6689676Slinton char c;
6699676Slinton {
6709676Slinton     if (c == 0) {
6719676Slinton 	putchar('\\');
6729676Slinton 	putchar('0');
6739676Slinton     } else if (c == '\n') {
6749676Slinton 	putchar('\\');
6759676Slinton 	putchar('n');
6769676Slinton     } else if (c > 0 and c < ' ') {
6779676Slinton 	putchar('^');
6789676Slinton 	putchar(c - 1 + 'A');
67916616Ssam     } else if (c >= ' ' && c <= '~') {
68016616Ssam 	putchar(c);
6819676Slinton     } else {
68229820Ssam 	printf("\\0%o",c&0xff);
6839676Slinton     }
6849676Slinton }
68518229Slinton 
68618229Slinton /*
68718229Slinton  * Print out a value for a range type (integer, char, or boolean).
68818229Slinton  */
68918229Slinton 
69018229Slinton public printRangeVal (val, t)
69118229Slinton long val;
69218229Slinton Symbol t;
69318229Slinton {
69418229Slinton     if (t == t_boolean->type or istypename(t->type, "boolean")) {
69518229Slinton 	if ((boolean) val) {
69618229Slinton 	    printf("true");
69718229Slinton 	} else {
69818229Slinton 	    printf("false");
69918229Slinton 	}
70018229Slinton     } else if (t == t_char->type or istypename(t->type, "char")) {
70118229Slinton 	if (varIsSet("$hexchars")) {
70218229Slinton 	    printf("0x%lx", val);
70318229Slinton 	} else {
70418229Slinton 	    putchar('\'');
70518229Slinton 	    printchar(val);
70618229Slinton 	    putchar('\'');
70718229Slinton 	}
70818229Slinton     } else if (varIsSet("$hexints")) {
70918229Slinton 	printf("0x%lx", val);
71018229Slinton     } else if (t->symvalue.rangev.lower >= 0) {
71118229Slinton 	printf("%lu", val);
71218229Slinton     } else {
71318229Slinton 	printf("%ld", val);
71418229Slinton     }
71518229Slinton }
71618229Slinton 
71718229Slinton /*
71818229Slinton  * Print out an enumerated value by finding the corresponding
71918229Slinton  * name in the enumeration list.
72018229Slinton  */
72118229Slinton 
72218229Slinton public printEnum (i, t)
72318229Slinton integer i;
72418229Slinton Symbol t;
72518229Slinton {
72618229Slinton     register Symbol e;
72718229Slinton 
72818229Slinton     e = t->chain;
72918229Slinton     while (e != nil and e->symvalue.constval->value.lcon != i) {
73018229Slinton 	e = e->chain;
73118229Slinton     }
73218229Slinton     if (e != nil) {
73318229Slinton 	printf("%s", symname(e));
73418229Slinton     } else {
73518229Slinton 	printf("%d", i);
73618229Slinton     }
73718229Slinton }
73818229Slinton 
73918229Slinton /*
74018229Slinton  * Print out a null-terminated string (pointer to char)
74118229Slinton  * starting at the given address.
74218229Slinton  */
74318229Slinton 
74418229Slinton public printString (addr, quotes)
74518229Slinton Address addr;
74618229Slinton boolean quotes;
74718229Slinton {
74818229Slinton     register Address a;
74918229Slinton     register integer i, len;
75018229Slinton     register boolean endofstring;
75129820Ssam     register int unprintables;
75229820Ssam #define	MAXGARBAGE	4
75318229Slinton     union {
75418229Slinton 	char ch[sizeof(Word)];
75518229Slinton 	int word;
75618229Slinton     } u;
75718229Slinton 
75818229Slinton     if (varIsSet("$hexstrings")) {
75918229Slinton 	printf("0x%x", addr);
76018229Slinton     } else {
76118229Slinton 	if (quotes) {
76218229Slinton 	    putchar('"');
76318229Slinton 	}
76418229Slinton 	a = addr;
76529820Ssam 	unprintables = 0;
76618229Slinton 	endofstring = false;
76718229Slinton 	while (not endofstring) {
76818229Slinton 	    dread(&u, a, sizeof(u));
76918229Slinton 	    i = 0;
77018229Slinton 	    do {
77118229Slinton 		if (u.ch[i] == '\0') {
77218229Slinton 		    endofstring = true;
77318229Slinton 		} else {
77418229Slinton 		    printchar(u.ch[i]);
77529820Ssam 		    if (!isascii(u.ch[i]) and ++unprintables > MAXGARBAGE) {
77629820Ssam 			endofstring = true;
77729820Ssam 			printf("...");
77829820Ssam 		    }
77918229Slinton 		}
78018229Slinton 		++i;
78118229Slinton 	    } while (i < sizeof(Word) and not endofstring);
78218229Slinton 	    a += sizeof(Word);
78318229Slinton 	}
78418229Slinton 	if (quotes) {
78518229Slinton 	    putchar('"');
78618229Slinton 	}
78718229Slinton     }
78818229Slinton }
789