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