121619Sdist /* 221619Sdist * Copyright (c) 1983 Regents of the University of California. 321619Sdist * All rights reserved. The Berkeley software License Agreement 421619Sdist * specifies the terms and conditions for redistribution. 521619Sdist */ 69676Slinton 721619Sdist #ifndef lint 8*33330Sdonn static char sccsid[] = "@(#)printsym.c 5.5 (Berkeley) 01/12/88"; 921619Sdist #endif not lint 109676Slinton 11*33330Sdonn static char rcsid[] = "$Header: printsym.c,v 1.4 87/04/15 00:23:35 donn 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" 3029820Ssam #include <ctype.h> 319676Slinton 329676Slinton #ifndef public 339676Slinton #endif 349676Slinton 359676Slinton /* 3611863Slinton * Maximum number of arguments to a function. 3711863Slinton * This is used as a check for the possibility that the stack has been 3811863Slinton * overwritten and therefore a saved argument pointer might indicate 3911863Slinton * to an absurdly large number of arguments. 4011863Slinton */ 4111863Slinton 4211863Slinton #define MAXARGSPASSED 20 4311863Slinton 4411863Slinton /* 459676Slinton * Return a pointer to the string for the name of the class that 469676Slinton * the given symbol belongs to. 479676Slinton */ 489676Slinton 499676Slinton private String clname[] = { 50*33330Sdonn "bad use", "constant", "type", "variable", "array", "array", 51*33330Sdonn "dynarray", "subarray", "fileptr", "record", "field", 5218229Slinton "procedure", "function", "funcvar", 539676Slinton "ref", "pointer", "file", "set", "range", "label", "withptr", 549676Slinton "scalar", "string", "program", "improper", "variant", 5516616Ssam "procparam", "funcparam", "module", "tag", "common", "extref", "typeref" 569676Slinton }; 579676Slinton 589676Slinton public String classname(s) 599676Slinton Symbol s; 609676Slinton { 619676Slinton return clname[ord(s->class)]; 629676Slinton } 639676Slinton 649676Slinton /* 659676Slinton * Note the entry of the given block, unless it's the main program. 669676Slinton */ 679676Slinton 689676Slinton public printentry(s) 699676Slinton Symbol s; 709676Slinton { 719676Slinton if (s != program) { 7218229Slinton printf("\nentering %s ", classname(s)); 7318229Slinton printname(stdout, s); 7418229Slinton printf("\n"); 759676Slinton } 769676Slinton } 779676Slinton 789676Slinton /* 799676Slinton * Note the exit of the given block 809676Slinton */ 819676Slinton 829676Slinton public printexit(s) 839676Slinton Symbol s; 849676Slinton { 859676Slinton if (s != program) { 8618229Slinton printf("leaving %s ", classname(s)); 8718229Slinton printname(stdout, s); 8818229Slinton printf("\n\n"); 899676Slinton } 909676Slinton } 919676Slinton 929676Slinton /* 939676Slinton * Note the call of s from t. 949676Slinton */ 959676Slinton 969676Slinton public printcall(s, t) 979676Slinton Symbol s, t; 989676Slinton { 9918229Slinton printf("calling "); 10018229Slinton printname(stdout, s); 1019676Slinton printparams(s, nil); 10218229Slinton printf(" from %s ", classname(t)); 10318229Slinton printname(stdout, t); 10418229Slinton printf("\n"); 1059676Slinton } 1069676Slinton 1079676Slinton /* 1089676Slinton * Note the return from s. If s is a function, print the value 1099676Slinton * it is returning. This is somewhat painful, since the function 1109676Slinton * has actually just returned. 1119676Slinton */ 1129676Slinton 1139676Slinton public printrtn(s) 1149676Slinton Symbol s; 1159676Slinton { 1169676Slinton register Symbol t; 1179676Slinton register int len; 1189676Slinton Boolean isindirect; 1199676Slinton 1209676Slinton printf("returning "); 12112628Scsvaf if (s->class == FUNC && (!istypename(s->type,"void"))) { 1229676Slinton len = size(s->type); 1239676Slinton if (canpush(len)) { 1249676Slinton t = rtype(s->type); 1259676Slinton isindirect = (Boolean) (t->class == RECORD or t->class == VARNT); 1269676Slinton pushretval(len, isindirect); 1279676Slinton printval(s->type); 1289676Slinton putchar(' '); 1299676Slinton } else { 1309676Slinton printf("(value too large) "); 1319676Slinton } 1329676Slinton } 13318229Slinton printf("from "); 13418229Slinton printname(stdout, s); 13518229Slinton printf("\n"); 1369676Slinton } 1379676Slinton 1389676Slinton /* 1399676Slinton * Print the values of the parameters of the given procedure or function. 1409676Slinton * The frame distinguishes recursive instances of a procedure. 14116616Ssam * 14216616Ssam * If the procedure or function is internal, the argument count is 14316616Ssam * not valid so we ignore it. 1449676Slinton */ 1459676Slinton 1469676Slinton public printparams(f, frame) 1479676Slinton Symbol f; 1489676Slinton Frame frame; 1499676Slinton { 1509676Slinton Symbol param; 1519676Slinton int n, m, s; 1529676Slinton 1539676Slinton n = nargspassed(frame); 15416616Ssam if (isinternal(f)) { 15516616Ssam n = 0; 15616616Ssam } 15718229Slinton printf("("); 1589676Slinton param = f->chain; 1599676Slinton if (param != nil or n > 0) { 1609676Slinton m = n; 1619676Slinton if (param != nil) { 1629676Slinton for (;;) { 16318229Slinton s = psize(param) div sizeof(Word); 1649676Slinton if (s == 0) { 1659676Slinton s = 1; 1669676Slinton } 1679676Slinton m -= s; 16818229Slinton if (showaggrs) { 16918229Slinton printv(param, frame); 17018229Slinton } else { 17118229Slinton printparamv(param, frame); 17218229Slinton } 1739676Slinton param = param->chain; 1749676Slinton if (param == nil) break; 1759676Slinton printf(", "); 1769676Slinton } 1779676Slinton } 1789676Slinton if (m > 0) { 17911863Slinton if (m > MAXARGSPASSED) { 18011863Slinton m = MAXARGSPASSED; 18111863Slinton } 1829676Slinton if (f->chain != nil) { 1839676Slinton printf(", "); 1849676Slinton } 1859676Slinton for (;;) { 1869676Slinton --m; 1879676Slinton printf("0x%x", argn(n - m, frame)); 1889676Slinton if (m <= 0) break; 1899676Slinton printf(", "); 1909676Slinton } 1919676Slinton } 1929676Slinton } 19318229Slinton printf(")"); 1949676Slinton } 1959676Slinton 1969676Slinton /* 1979676Slinton * Test if a symbol should be printed. We don't print files, 1989676Slinton * for example, simply because there's no good way to do it. 1999676Slinton * The symbol must be within the given function. 2009676Slinton */ 2019676Slinton 2029676Slinton public Boolean should_print(s) 2039676Slinton Symbol s; 2049676Slinton { 2059676Slinton Boolean b; 2069676Slinton register Symbol t; 2079676Slinton 2089676Slinton switch (s->class) { 2099676Slinton case VAR: 2109676Slinton case FVAR: 21114339Slinton if (isparam(s)) { 21214339Slinton b = false; 21314339Slinton } else { 21414339Slinton t = rtype(s->type); 21514339Slinton if (t == nil) { 21614339Slinton b = false; 21714339Slinton } else { 21814339Slinton switch (t->class) { 21914339Slinton case FILET: 22014339Slinton case SET: 22114339Slinton case BADUSE: 22214339Slinton b = false; 22314339Slinton break; 22414339Slinton 22514339Slinton default: 22614339Slinton b = true; 22714339Slinton break; 22814339Slinton } 22914339Slinton } 23014339Slinton } 2319676Slinton break; 2329676Slinton 2339676Slinton default: 2349676Slinton b = false; 2359676Slinton break; 2369676Slinton } 2379676Slinton return b; 2389676Slinton } 2399676Slinton 2409676Slinton /* 24118229Slinton * Print out a parameter value. 24218229Slinton * 24318229Slinton * Since this is intended to be printed on a single line with other information 24418229Slinton * aggregate values are not printed. 24518229Slinton */ 24618229Slinton 24718229Slinton public printparamv (p, frame) 24818229Slinton Symbol p; 24918229Slinton Frame frame; 25018229Slinton { 25118229Slinton Symbol t; 25218229Slinton 25318229Slinton t = rtype(p->type); 25418229Slinton switch (t->class) { 25518229Slinton case ARRAY: 256*33330Sdonn case OPENARRAY: 25718229Slinton case DYNARRAY: 25818229Slinton case SUBARRAY: 25918229Slinton t = rtype(t->type); 26018229Slinton if (compatible(t, t_char)) { 26118229Slinton printv(p, frame); 26218229Slinton } else { 26318229Slinton printf("%s = (...)", symname(p)); 26418229Slinton } 26518229Slinton break; 26618229Slinton 26718229Slinton case RECORD: 26818229Slinton printf("%s = (...)", symname(p)); 26918229Slinton break; 27018229Slinton 27118229Slinton default: 27218229Slinton printv(p, frame); 27318229Slinton break; 27418229Slinton } 27518229Slinton } 27618229Slinton 27718229Slinton /* 2789676Slinton * Print the name and value of a variable. 2799676Slinton */ 2809676Slinton 2819676Slinton public printv(s, frame) 2829676Slinton Symbol s; 2839676Slinton Frame frame; 2849676Slinton { 2859676Slinton Address addr; 2869676Slinton int len; 2879676Slinton 2889676Slinton if (isambiguous(s) and ismodule(container(s))) { 2899676Slinton printname(stdout, s); 2909676Slinton printf(" = "); 2919676Slinton } else { 2929676Slinton printf("%s = ", symname(s)); 2939676Slinton } 29418229Slinton if (isvarparam(s) and not isopenarray(s)) { 29518229Slinton rpush(address(s, frame), sizeof(Address)); 29618229Slinton addr = pop(Address); 2979676Slinton } else { 29818229Slinton addr = address(s, frame); 29918229Slinton } 30018229Slinton len = size(s); 30124554Smckusick if (not canpush(len)) { 30224554Smckusick printf("*** expression too large ***"); 30324554Smckusick } else if (isreg(s)) { 30424554Smckusick push(Address, addr); 30524554Smckusick printval(s->type); 30624554Smckusick } else { 30718229Slinton rpush(addr, len); 30818229Slinton printval(s->type); 30918229Slinton } 3109676Slinton } 3119676Slinton 3129676Slinton /* 3139676Slinton * Print out the name of a symbol. 3149676Slinton */ 3159676Slinton 3169676Slinton public printname(f, s) 3179676Slinton File f; 3189676Slinton Symbol s; 3199676Slinton { 3209676Slinton if (s == nil) { 3219676Slinton fprintf(f, "(noname)"); 32216616Ssam } else if (s == program) { 32316616Ssam fprintf(f, "."); 3249676Slinton } else if (isredirected() or isambiguous(s)) { 3259676Slinton printwhich(f, s); 3269676Slinton } else { 3279676Slinton fprintf(f, "%s", symname(s)); 3289676Slinton } 3299676Slinton } 3309676Slinton 3319676Slinton /* 3329676Slinton * Print the fully specified variable that is described by the given identifer. 3339676Slinton */ 3349676Slinton 3359676Slinton public printwhich(f, s) 3369676Slinton File f; 3379676Slinton Symbol s; 3389676Slinton { 3399676Slinton printouter(f, container(s)); 3409676Slinton fprintf(f, "%s", symname(s)); 3419676Slinton } 3429676Slinton 3439676Slinton /* 3449676Slinton * Print the fully qualified name of each symbol that has the same name 3459676Slinton * as the given symbol. 3469676Slinton */ 3479676Slinton 3489676Slinton public printwhereis(f, s) 3499676Slinton File f; 3509676Slinton Symbol s; 3519676Slinton { 3529676Slinton register Name n; 3539676Slinton register Symbol t; 3549676Slinton 3559676Slinton checkref(s); 3569676Slinton n = s->name; 3579676Slinton t = lookup(n); 3589676Slinton printwhich(f, t); 3599676Slinton t = t->next_sym; 3609676Slinton while (t != nil) { 3619676Slinton if (t->name == n) { 3629676Slinton putc(' ', f); 3639676Slinton printwhich(f, t); 3649676Slinton } 3659676Slinton t = t->next_sym; 3669676Slinton } 3679676Slinton putc('\n', f); 3689676Slinton } 3699676Slinton 3709676Slinton private printouter(f, s) 3719676Slinton File f; 3729676Slinton Symbol s; 3739676Slinton { 3749676Slinton Symbol outer; 3759676Slinton 3769676Slinton if (s != nil) { 3779676Slinton outer = container(s); 3789676Slinton if (outer != nil and outer != program) { 3799676Slinton printouter(f, outer); 3809676Slinton } 3819676Slinton fprintf(f, "%s.", symname(s)); 3829676Slinton } 3839676Slinton } 3849676Slinton 3859676Slinton public printdecl(s) 3869676Slinton Symbol s; 3879676Slinton { 38818229Slinton Language lang; 38918229Slinton 3909676Slinton checkref(s); 39118229Slinton if (s->language == nil or s->language == primlang) { 39218229Slinton lang = findlanguage(".s"); 39318229Slinton } else { 39418229Slinton lang = s->language; 39518229Slinton } 39618229Slinton (*language_op(lang, L_PRINTDECL))(s); 3979676Slinton } 3989676Slinton 3999676Slinton /* 4009676Slinton * Straight dump of symbol information. 4019676Slinton */ 4029676Slinton 4039676Slinton public psym(s) 4049676Slinton Symbol s; 4059676Slinton { 4069676Slinton printf("name\t%s\n", symname(s)); 4079676Slinton printf("lang\t%s\n", language_name(s->language)); 4089676Slinton printf("level\t%d\n", s->level); 4099676Slinton printf("class\t%s\n", classname(s)); 4109676Slinton printf("type\t0x%x", s->type); 4119676Slinton if (s->type != nil and s->type->name != nil) { 4129676Slinton printf(" (%s)", symname(s->type)); 4139676Slinton } 4149676Slinton printf("\nchain\t0x%x", s->chain); 4159676Slinton if (s->chain != nil and s->chain->name != nil) { 4169676Slinton printf(" (%s)", symname(s->chain)); 4179676Slinton } 4189676Slinton printf("\nblock\t0x%x", s->block); 419*33330Sdonn if (s->block != nil and s->block->name != nil) { 4209676Slinton printf(" ("); 4219676Slinton printname(stdout, s->block); 4229676Slinton putchar(')'); 4239676Slinton } 4249676Slinton putchar('\n'); 4259676Slinton switch (s->class) { 42618229Slinton case TYPE: 42718229Slinton printf("size\t%d\n", size(s)); 42818229Slinton break; 42918229Slinton 4309676Slinton case VAR: 4319676Slinton case REF: 432*33330Sdonn switch (s->storage) { 433*33330Sdonn case INREG: 434*33330Sdonn printf("reg\t%d\n", s->symvalue.offset); 435*33330Sdonn break; 436*33330Sdonn 437*33330Sdonn case STK: 438*33330Sdonn printf("offset\t%d\n", s->symvalue.offset); 439*33330Sdonn break; 440*33330Sdonn 441*33330Sdonn case EXT: 442*33330Sdonn printf("address\t0x%x\n", s->symvalue.offset); 443*33330Sdonn break; 4449676Slinton } 44512545Scsvaf printf("size\t%d\n", size(s)); 4469676Slinton break; 4479676Slinton 4489676Slinton case RECORD: 4499676Slinton case VARNT: 4509676Slinton printf("size\t%d\n", s->symvalue.offset); 4519676Slinton break; 4529676Slinton 4539676Slinton case FIELD: 4549676Slinton printf("offset\t%d\n", s->symvalue.field.offset); 4559676Slinton printf("size\t%d\n", s->symvalue.field.length); 4569676Slinton break; 4579676Slinton 45814381Slinton case PROG: 4599676Slinton case PROC: 4609676Slinton case FUNC: 4619676Slinton printf("address\t0x%x\n", s->symvalue.funcv.beginaddr); 46214438Slinton if (isinline(s)) { 46314440Slinton printf("inline procedure\n"); 46414438Slinton } 46511863Slinton if (nosource(s)) { 46611863Slinton printf("does not have source information\n"); 46711863Slinton } else { 46811863Slinton printf("has source information\n"); 46911863Slinton } 4709676Slinton break; 4719676Slinton 4729676Slinton case RANGE: 47314381Slinton prangetype(s->symvalue.rangev.lowertype); 4749676Slinton printf("lower\t%d\n", s->symvalue.rangev.lower); 47514381Slinton prangetype(s->symvalue.rangev.uppertype); 4769676Slinton printf("upper\t%d\n", s->symvalue.rangev.upper); 4779676Slinton break; 4789676Slinton 4799676Slinton default: 4809676Slinton /* do nothing */ 4819676Slinton break; 4829676Slinton } 4839676Slinton } 4849676Slinton 48514381Slinton private prangetype(r) 48614381Slinton Rangetype r; 48714381Slinton { 48814381Slinton switch (r) { 48914381Slinton case R_CONST: 49014381Slinton printf("CONST"); 49114381Slinton break; 49214381Slinton 49314381Slinton case R_ARG: 49414381Slinton printf("ARG"); 49514381Slinton break; 49614381Slinton 49714381Slinton case R_TEMP: 49814381Slinton printf("TEMP"); 49914381Slinton break; 50014381Slinton 50114381Slinton case R_ADJUST: 50214381Slinton printf("ADJUST"); 50314381Slinton break; 50414381Slinton } 50514381Slinton } 50614381Slinton 5079676Slinton /* 5089676Slinton * Print out the value on top of the stack according to the given type. 5099676Slinton */ 5109676Slinton 5119676Slinton public printval(t) 5129676Slinton Symbol t; 5139676Slinton { 5149676Slinton Symbol s; 5159676Slinton 5169676Slinton checkref(t); 51716616Ssam if (t->class == TYPEREF) { 51816616Ssam resolveRef(t); 51916616Ssam } 5209676Slinton switch (t->class) { 5219676Slinton case PROC: 5229676Slinton case FUNC: 5239676Slinton s = pop(Symbol); 5249676Slinton printf("%s", symname(s)); 5259676Slinton break; 5269676Slinton 5279676Slinton default: 52818229Slinton if (t->language == nil or t->language == primlang) { 52926478Ssam (*language_op(findlanguage(".c"), L_PRINTVAL))(t); 5309676Slinton } else { 5319676Slinton (*language_op(t->language, L_PRINTVAL))(t); 5329676Slinton } 5339676Slinton break; 5349676Slinton } 5359676Slinton } 5369676Slinton 5379676Slinton /* 5389676Slinton * Print out the value of a record, field by field. 5399676Slinton */ 5409676Slinton 5419676Slinton public printrecord(s) 5429676Slinton Symbol s; 5439676Slinton { 54416616Ssam Symbol f; 54516616Ssam 5469676Slinton if (s->chain == nil) { 5479676Slinton error("record has no fields"); 5489676Slinton } 5499676Slinton printf("("); 5509676Slinton sp -= size(s); 55116616Ssam f = s->chain; 55216616Ssam if (f != nil) { 55316616Ssam for (;;) { 55416616Ssam printfield(f); 55516616Ssam f = f->chain; 55616616Ssam if (f == nil) break; 55716616Ssam printf(", "); 55816616Ssam } 55916616Ssam } 5609676Slinton printf(")"); 5619676Slinton } 5629676Slinton 5639676Slinton /* 56416616Ssam * Print out a field. 5659676Slinton */ 5669676Slinton 56716616Ssam private printfield(f) 56816616Ssam Symbol f; 5699676Slinton { 5709676Slinton Stack *savesp; 57116616Ssam register int off, len; 5729676Slinton 57316616Ssam printf("%s = ", symname(f)); 5749676Slinton savesp = sp; 57516616Ssam off = f->symvalue.field.offset; 57616616Ssam len = f->symvalue.field.length; 57716616Ssam sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE); 57816616Ssam printval(f); 5799676Slinton sp = savesp; 5809676Slinton } 5819676Slinton 5829676Slinton /* 5839676Slinton * Print out the contents of an array. 5849676Slinton * Haven't quite figured out what the best format is. 5859676Slinton * 5869676Slinton * This is rather inefficient. 5879676Slinton * 5889676Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 5899676Slinton */ 5909676Slinton 5919676Slinton public printarray(a) 5929676Slinton Symbol a; 5939676Slinton { 5949676Slinton Stack *savesp, *newsp; 5959676Slinton Symbol eltype; 5969676Slinton long elsize; 5979676Slinton String sep; 5989676Slinton 5999676Slinton savesp = sp; 60012544Scsvaf sp -= (size(a)); 6019676Slinton newsp = sp; 6029676Slinton eltype = rtype(a->type); 6039676Slinton elsize = size(eltype); 6049676Slinton printf("("); 6059676Slinton if (eltype->class == RECORD or eltype->class == ARRAY or 6069676Slinton eltype->class == VARNT) { 6079676Slinton sep = "\n"; 6089676Slinton putchar('\n'); 6099676Slinton } else { 6109676Slinton sep = ", "; 6119676Slinton } 6129676Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 6139676Slinton if (sp - elsize != newsp) { 6149676Slinton fputs(sep, stdout); 6159676Slinton } 6169676Slinton printval(eltype); 6179676Slinton } 6189676Slinton sp = newsp; 6199676Slinton if (streq(sep, "\n")) { 6209676Slinton putchar('\n'); 6219676Slinton } 6229676Slinton printf(")"); 6239676Slinton } 6249676Slinton 6259676Slinton /* 6269676Slinton * Print out the value of a real number in Pascal notation. 6279676Slinton * This is, unfortunately, different than what one gets 6289676Slinton * from "%g" in printf. 6299676Slinton */ 6309676Slinton 6319676Slinton public prtreal(r) 6329676Slinton double r; 6339676Slinton { 6349676Slinton extern char *index(); 6359676Slinton char buf[256]; 6369676Slinton 637*33330Sdonn # ifdef IRIS 638*33330Sdonn sprintf(buf, "%lg", r); 639*33330Sdonn # else 640*33330Sdonn sprintf(buf, "%g", r); 641*33330Sdonn # endif 6429676Slinton if (buf[0] == '.') { 6439676Slinton printf("0%s", buf); 6449676Slinton } else if (buf[0] == '-' and buf[1] == '.') { 6459676Slinton printf("-0%s", &buf[1]); 6469676Slinton } else { 6479676Slinton printf("%s", buf); 6489676Slinton } 6499676Slinton if (index(buf, '.') == nil) { 6509676Slinton printf(".0"); 6519676Slinton } 6529676Slinton } 6539676Slinton 6549676Slinton /* 6559676Slinton * Print out a character using ^? notation for unprintables. 6569676Slinton */ 6579676Slinton 6589676Slinton public printchar(c) 6599676Slinton char c; 6609676Slinton { 6619676Slinton if (c == 0) { 6629676Slinton putchar('\\'); 6639676Slinton putchar('0'); 6649676Slinton } else if (c == '\n') { 6659676Slinton putchar('\\'); 6669676Slinton putchar('n'); 6679676Slinton } else if (c > 0 and c < ' ') { 6689676Slinton putchar('^'); 6699676Slinton putchar(c - 1 + 'A'); 67016616Ssam } else if (c >= ' ' && c <= '~') { 67116616Ssam putchar(c); 6729676Slinton } else { 67329820Ssam printf("\\0%o",c&0xff); 6749676Slinton } 6759676Slinton } 67618229Slinton 67718229Slinton /* 67818229Slinton * Print out a value for a range type (integer, char, or boolean). 67918229Slinton */ 68018229Slinton 68118229Slinton public printRangeVal (val, t) 68218229Slinton long val; 68318229Slinton Symbol t; 68418229Slinton { 68518229Slinton if (t == t_boolean->type or istypename(t->type, "boolean")) { 68618229Slinton if ((boolean) val) { 68718229Slinton printf("true"); 68818229Slinton } else { 68918229Slinton printf("false"); 69018229Slinton } 69118229Slinton } else if (t == t_char->type or istypename(t->type, "char")) { 69218229Slinton if (varIsSet("$hexchars")) { 69318229Slinton printf("0x%lx", val); 69418229Slinton } else { 69518229Slinton putchar('\''); 69618229Slinton printchar(val); 69718229Slinton putchar('\''); 69818229Slinton } 69918229Slinton } else if (varIsSet("$hexints")) { 70018229Slinton printf("0x%lx", val); 70118229Slinton } else if (t->symvalue.rangev.lower >= 0) { 70218229Slinton printf("%lu", val); 70318229Slinton } else { 70418229Slinton printf("%ld", val); 70518229Slinton } 70618229Slinton } 70718229Slinton 70818229Slinton /* 70918229Slinton * Print out an enumerated value by finding the corresponding 71018229Slinton * name in the enumeration list. 71118229Slinton */ 71218229Slinton 71318229Slinton public printEnum (i, t) 71418229Slinton integer i; 71518229Slinton Symbol t; 71618229Slinton { 71718229Slinton register Symbol e; 71818229Slinton 71918229Slinton e = t->chain; 72018229Slinton while (e != nil and e->symvalue.constval->value.lcon != i) { 72118229Slinton e = e->chain; 72218229Slinton } 72318229Slinton if (e != nil) { 72418229Slinton printf("%s", symname(e)); 72518229Slinton } else { 72618229Slinton printf("%d", i); 72718229Slinton } 72818229Slinton } 72918229Slinton 73018229Slinton /* 73118229Slinton * Print out a null-terminated string (pointer to char) 73218229Slinton * starting at the given address. 73318229Slinton */ 73418229Slinton 73518229Slinton public printString (addr, quotes) 73618229Slinton Address addr; 73718229Slinton boolean quotes; 73818229Slinton { 73918229Slinton register Address a; 74018229Slinton register integer i, len; 74118229Slinton register boolean endofstring; 74229820Ssam register int unprintables; 74329820Ssam #define MAXGARBAGE 4 74418229Slinton union { 74518229Slinton char ch[sizeof(Word)]; 74618229Slinton int word; 74718229Slinton } u; 74818229Slinton 74918229Slinton if (varIsSet("$hexstrings")) { 75018229Slinton printf("0x%x", addr); 75118229Slinton } else { 75218229Slinton if (quotes) { 75318229Slinton putchar('"'); 75418229Slinton } 75518229Slinton a = addr; 75629820Ssam unprintables = 0; 75718229Slinton endofstring = false; 75818229Slinton while (not endofstring) { 75918229Slinton dread(&u, a, sizeof(u)); 76018229Slinton i = 0; 76118229Slinton do { 76218229Slinton if (u.ch[i] == '\0') { 76318229Slinton endofstring = true; 76418229Slinton } else { 76518229Slinton printchar(u.ch[i]); 76629820Ssam if (!isascii(u.ch[i]) and ++unprintables > MAXGARBAGE) { 76729820Ssam endofstring = true; 76829820Ssam printf("..."); 76929820Ssam } 77018229Slinton } 77118229Slinton ++i; 77218229Slinton } while (i < sizeof(Word) and not endofstring); 77318229Slinton a += sizeof(Word); 77418229Slinton } 77518229Slinton if (quotes) { 77618229Slinton putchar('"'); 77718229Slinton } 77818229Slinton } 77918229Slinton } 780