19676Slinton /* Copyright (c) 1982 Regents of the University of California */ 29676Slinton 3*18229Slinton static char sccsid[] = "@(#)printsym.c 1.14 (Berkeley) 03/01/85"; 49676Slinton 5*18229Slinton static char rcsid[] = "$Header: printsym.c,v 1.5 84/12/26 10:41:28 linton Exp $"; 6*18229Slinton 79676Slinton /* 89676Slinton * Printing of symbolic information. 99676Slinton */ 109676Slinton 119676Slinton #include "defs.h" 129676Slinton #include "symbols.h" 139676Slinton #include "languages.h" 149676Slinton #include "printsym.h" 159676Slinton #include "tree.h" 169676Slinton #include "eval.h" 179676Slinton #include "mappings.h" 189676Slinton #include "process.h" 199676Slinton #include "runtime.h" 209676Slinton #include "machine.h" 219676Slinton #include "names.h" 22*18229Slinton #include "keywords.h" 239676Slinton #include "main.h" 249676Slinton 259676Slinton #ifndef public 269676Slinton #endif 279676Slinton 289676Slinton /* 2911863Slinton * Maximum number of arguments to a function. 3011863Slinton * This is used as a check for the possibility that the stack has been 3111863Slinton * overwritten and therefore a saved argument pointer might indicate 3211863Slinton * to an absurdly large number of arguments. 3311863Slinton */ 3411863Slinton 3511863Slinton #define MAXARGSPASSED 20 3611863Slinton 3711863Slinton /* 389676Slinton * Return a pointer to the string for the name of the class that 399676Slinton * the given symbol belongs to. 409676Slinton */ 419676Slinton 429676Slinton private String clname[] = { 43*18229Slinton "bad use", "constant", "type", "variable", "array", "@dynarray", 44*18229Slinton "@subarray", "fileptr", "record", "field", 45*18229Slinton "procedure", "function", "funcvar", 469676Slinton "ref", "pointer", "file", "set", "range", "label", "withptr", 479676Slinton "scalar", "string", "program", "improper", "variant", 4816616Ssam "procparam", "funcparam", "module", "tag", "common", "extref", "typeref" 499676Slinton }; 509676Slinton 519676Slinton public String classname(s) 529676Slinton Symbol s; 539676Slinton { 549676Slinton return clname[ord(s->class)]; 559676Slinton } 569676Slinton 579676Slinton /* 589676Slinton * Note the entry of the given block, unless it's the main program. 599676Slinton */ 609676Slinton 619676Slinton public printentry(s) 629676Slinton Symbol s; 639676Slinton { 649676Slinton if (s != program) { 65*18229Slinton printf("\nentering %s ", classname(s)); 66*18229Slinton printname(stdout, s); 67*18229Slinton printf("\n"); 689676Slinton } 699676Slinton } 709676Slinton 719676Slinton /* 729676Slinton * Note the exit of the given block 739676Slinton */ 749676Slinton 759676Slinton public printexit(s) 769676Slinton Symbol s; 779676Slinton { 789676Slinton if (s != program) { 79*18229Slinton printf("leaving %s ", classname(s)); 80*18229Slinton printname(stdout, s); 81*18229Slinton printf("\n\n"); 829676Slinton } 839676Slinton } 849676Slinton 859676Slinton /* 869676Slinton * Note the call of s from t. 879676Slinton */ 889676Slinton 899676Slinton public printcall(s, t) 909676Slinton Symbol s, t; 919676Slinton { 92*18229Slinton printf("calling "); 93*18229Slinton printname(stdout, s); 949676Slinton printparams(s, nil); 95*18229Slinton printf(" from %s ", classname(t)); 96*18229Slinton printname(stdout, t); 97*18229Slinton printf("\n"); 989676Slinton } 999676Slinton 1009676Slinton /* 1019676Slinton * Note the return from s. If s is a function, print the value 1029676Slinton * it is returning. This is somewhat painful, since the function 1039676Slinton * has actually just returned. 1049676Slinton */ 1059676Slinton 1069676Slinton public printrtn(s) 1079676Slinton Symbol s; 1089676Slinton { 1099676Slinton register Symbol t; 1109676Slinton register int len; 1119676Slinton Boolean isindirect; 1129676Slinton 1139676Slinton printf("returning "); 11412628Scsvaf if (s->class == FUNC && (!istypename(s->type,"void"))) { 1159676Slinton len = size(s->type); 1169676Slinton if (canpush(len)) { 1179676Slinton t = rtype(s->type); 1189676Slinton isindirect = (Boolean) (t->class == RECORD or t->class == VARNT); 1199676Slinton pushretval(len, isindirect); 1209676Slinton printval(s->type); 1219676Slinton putchar(' '); 1229676Slinton } else { 1239676Slinton printf("(value too large) "); 1249676Slinton } 1259676Slinton } 126*18229Slinton printf("from "); 127*18229Slinton printname(stdout, s); 128*18229Slinton printf("\n"); 1299676Slinton } 1309676Slinton 1319676Slinton /* 1329676Slinton * Print the values of the parameters of the given procedure or function. 1339676Slinton * The frame distinguishes recursive instances of a procedure. 13416616Ssam * 13516616Ssam * If the procedure or function is internal, the argument count is 13616616Ssam * not valid so we ignore it. 1379676Slinton */ 1389676Slinton 1399676Slinton public printparams(f, frame) 1409676Slinton Symbol f; 1419676Slinton Frame frame; 1429676Slinton { 1439676Slinton Symbol param; 1449676Slinton int n, m, s; 1459676Slinton 1469676Slinton n = nargspassed(frame); 14716616Ssam if (isinternal(f)) { 14816616Ssam n = 0; 14916616Ssam } 150*18229Slinton printf("("); 1519676Slinton param = f->chain; 1529676Slinton if (param != nil or n > 0) { 1539676Slinton m = n; 1549676Slinton if (param != nil) { 1559676Slinton for (;;) { 156*18229Slinton s = psize(param) div sizeof(Word); 1579676Slinton if (s == 0) { 1589676Slinton s = 1; 1599676Slinton } 1609676Slinton m -= s; 161*18229Slinton if (showaggrs) { 162*18229Slinton printv(param, frame); 163*18229Slinton } else { 164*18229Slinton printparamv(param, frame); 165*18229Slinton } 1669676Slinton param = param->chain; 1679676Slinton if (param == nil) break; 1689676Slinton printf(", "); 1699676Slinton } 1709676Slinton } 1719676Slinton if (m > 0) { 17211863Slinton if (m > MAXARGSPASSED) { 17311863Slinton m = MAXARGSPASSED; 17411863Slinton } 1759676Slinton if (f->chain != nil) { 1769676Slinton printf(", "); 1779676Slinton } 1789676Slinton for (;;) { 1799676Slinton --m; 1809676Slinton printf("0x%x", argn(n - m, frame)); 1819676Slinton if (m <= 0) break; 1829676Slinton printf(", "); 1839676Slinton } 1849676Slinton } 1859676Slinton } 186*18229Slinton printf(")"); 1879676Slinton } 1889676Slinton 1899676Slinton /* 1909676Slinton * Test if a symbol should be printed. We don't print files, 1919676Slinton * for example, simply because there's no good way to do it. 1929676Slinton * The symbol must be within the given function. 1939676Slinton */ 1949676Slinton 1959676Slinton public Boolean should_print(s) 1969676Slinton Symbol s; 1979676Slinton { 1989676Slinton Boolean b; 1999676Slinton register Symbol t; 2009676Slinton 2019676Slinton switch (s->class) { 2029676Slinton case VAR: 2039676Slinton case FVAR: 20414339Slinton if (isparam(s)) { 20514339Slinton b = false; 20614339Slinton } else { 20714339Slinton t = rtype(s->type); 20814339Slinton if (t == nil) { 20914339Slinton b = false; 21014339Slinton } else { 21114339Slinton switch (t->class) { 21214339Slinton case FILET: 21314339Slinton case SET: 21414339Slinton case BADUSE: 21514339Slinton b = false; 21614339Slinton break; 21714339Slinton 21814339Slinton default: 21914339Slinton b = true; 22014339Slinton break; 22114339Slinton } 22214339Slinton } 22314339Slinton } 2249676Slinton break; 2259676Slinton 2269676Slinton default: 2279676Slinton b = false; 2289676Slinton break; 2299676Slinton } 2309676Slinton return b; 2319676Slinton } 2329676Slinton 2339676Slinton /* 234*18229Slinton * Print out a parameter value. 235*18229Slinton * 236*18229Slinton * Since this is intended to be printed on a single line with other information 237*18229Slinton * aggregate values are not printed. 238*18229Slinton */ 239*18229Slinton 240*18229Slinton public printparamv (p, frame) 241*18229Slinton Symbol p; 242*18229Slinton Frame frame; 243*18229Slinton { 244*18229Slinton Symbol t; 245*18229Slinton 246*18229Slinton t = rtype(p->type); 247*18229Slinton switch (t->class) { 248*18229Slinton case ARRAY: 249*18229Slinton case DYNARRAY: 250*18229Slinton case SUBARRAY: 251*18229Slinton t = rtype(t->type); 252*18229Slinton if (compatible(t, t_char)) { 253*18229Slinton printv(p, frame); 254*18229Slinton } else { 255*18229Slinton printf("%s = (...)", symname(p)); 256*18229Slinton } 257*18229Slinton break; 258*18229Slinton 259*18229Slinton case RECORD: 260*18229Slinton printf("%s = (...)", symname(p)); 261*18229Slinton break; 262*18229Slinton 263*18229Slinton default: 264*18229Slinton printv(p, frame); 265*18229Slinton break; 266*18229Slinton } 267*18229Slinton } 268*18229Slinton 269*18229Slinton /* 2709676Slinton * Print the name and value of a variable. 2719676Slinton */ 2729676Slinton 2739676Slinton public printv(s, frame) 2749676Slinton Symbol s; 2759676Slinton Frame frame; 2769676Slinton { 2779676Slinton Address addr; 2789676Slinton int len; 27916616Ssam Symbol t; 2809676Slinton 2819676Slinton if (isambiguous(s) and ismodule(container(s))) { 2829676Slinton printname(stdout, s); 2839676Slinton printf(" = "); 2849676Slinton } else { 2859676Slinton printf("%s = ", symname(s)); 2869676Slinton } 287*18229Slinton if (isvarparam(s) and not isopenarray(s)) { 288*18229Slinton rpush(address(s, frame), sizeof(Address)); 289*18229Slinton addr = pop(Address); 2909676Slinton } else { 291*18229Slinton addr = address(s, frame); 292*18229Slinton } 293*18229Slinton len = size(s); 294*18229Slinton if (canpush(len)) { 295*18229Slinton rpush(addr, len); 296*18229Slinton printval(s->type); 297*18229Slinton } else { 298*18229Slinton printf("*** expression too large ***"); 299*18229Slinton } 3009676Slinton } 3019676Slinton 3029676Slinton /* 3039676Slinton * Print out the name of a symbol. 3049676Slinton */ 3059676Slinton 3069676Slinton public printname(f, s) 3079676Slinton File f; 3089676Slinton Symbol s; 3099676Slinton { 3109676Slinton if (s == nil) { 3119676Slinton fprintf(f, "(noname)"); 31216616Ssam } else if (s == program) { 31316616Ssam fprintf(f, "."); 3149676Slinton } else if (isredirected() or isambiguous(s)) { 3159676Slinton printwhich(f, s); 3169676Slinton } else { 3179676Slinton fprintf(f, "%s", symname(s)); 3189676Slinton } 3199676Slinton } 3209676Slinton 3219676Slinton /* 3229676Slinton * Print the fully specified variable that is described by the given identifer. 3239676Slinton */ 3249676Slinton 3259676Slinton public printwhich(f, s) 3269676Slinton File f; 3279676Slinton Symbol s; 3289676Slinton { 3299676Slinton printouter(f, container(s)); 3309676Slinton fprintf(f, "%s", symname(s)); 3319676Slinton } 3329676Slinton 3339676Slinton /* 3349676Slinton * Print the fully qualified name of each symbol that has the same name 3359676Slinton * as the given symbol. 3369676Slinton */ 3379676Slinton 3389676Slinton public printwhereis(f, s) 3399676Slinton File f; 3409676Slinton Symbol s; 3419676Slinton { 3429676Slinton register Name n; 3439676Slinton register Symbol t; 3449676Slinton 3459676Slinton checkref(s); 3469676Slinton n = s->name; 3479676Slinton t = lookup(n); 3489676Slinton printwhich(f, t); 3499676Slinton t = t->next_sym; 3509676Slinton while (t != nil) { 3519676Slinton if (t->name == n) { 3529676Slinton putc(' ', f); 3539676Slinton printwhich(f, t); 3549676Slinton } 3559676Slinton t = t->next_sym; 3569676Slinton } 3579676Slinton putc('\n', f); 3589676Slinton } 3599676Slinton 3609676Slinton private printouter(f, s) 3619676Slinton File f; 3629676Slinton Symbol s; 3639676Slinton { 3649676Slinton Symbol outer; 3659676Slinton 3669676Slinton if (s != nil) { 3679676Slinton outer = container(s); 3689676Slinton if (outer != nil and outer != program) { 3699676Slinton printouter(f, outer); 3709676Slinton } 3719676Slinton fprintf(f, "%s.", symname(s)); 3729676Slinton } 3739676Slinton } 3749676Slinton 3759676Slinton public printdecl(s) 3769676Slinton Symbol s; 3779676Slinton { 378*18229Slinton Language lang; 379*18229Slinton 3809676Slinton checkref(s); 381*18229Slinton if (s->language == nil or s->language == primlang) { 382*18229Slinton lang = findlanguage(".s"); 383*18229Slinton } else { 384*18229Slinton lang = s->language; 385*18229Slinton } 386*18229Slinton (*language_op(lang, L_PRINTDECL))(s); 3879676Slinton } 3889676Slinton 3899676Slinton /* 3909676Slinton * Straight dump of symbol information. 3919676Slinton */ 3929676Slinton 3939676Slinton public psym(s) 3949676Slinton Symbol s; 3959676Slinton { 3969676Slinton printf("name\t%s\n", symname(s)); 3979676Slinton printf("lang\t%s\n", language_name(s->language)); 3989676Slinton printf("level\t%d\n", s->level); 3999676Slinton printf("class\t%s\n", classname(s)); 4009676Slinton printf("type\t0x%x", s->type); 4019676Slinton if (s->type != nil and s->type->name != nil) { 4029676Slinton printf(" (%s)", symname(s->type)); 4039676Slinton } 4049676Slinton printf("\nchain\t0x%x", s->chain); 4059676Slinton if (s->chain != nil and s->chain->name != nil) { 4069676Slinton printf(" (%s)", symname(s->chain)); 4079676Slinton } 4089676Slinton printf("\nblock\t0x%x", s->block); 4099676Slinton if (s->block->name != nil) { 4109676Slinton printf(" ("); 4119676Slinton printname(stdout, s->block); 4129676Slinton putchar(')'); 4139676Slinton } 4149676Slinton putchar('\n'); 4159676Slinton switch (s->class) { 416*18229Slinton case TYPE: 417*18229Slinton printf("size\t%d\n", size(s)); 418*18229Slinton break; 419*18229Slinton 4209676Slinton case VAR: 4219676Slinton case REF: 4229676Slinton if (s->level >= 3) { 4239676Slinton printf("address\t0x%x\n", s->symvalue.offset); 4249676Slinton } else { 4259676Slinton printf("offset\t%d\n", s->symvalue.offset); 4269676Slinton } 42712545Scsvaf printf("size\t%d\n", size(s)); 4289676Slinton break; 4299676Slinton 4309676Slinton case RECORD: 4319676Slinton case VARNT: 4329676Slinton printf("size\t%d\n", s->symvalue.offset); 4339676Slinton break; 4349676Slinton 4359676Slinton case FIELD: 4369676Slinton printf("offset\t%d\n", s->symvalue.field.offset); 4379676Slinton printf("size\t%d\n", s->symvalue.field.length); 4389676Slinton break; 4399676Slinton 44014381Slinton case PROG: 4419676Slinton case PROC: 4429676Slinton case FUNC: 4439676Slinton printf("address\t0x%x\n", s->symvalue.funcv.beginaddr); 44414438Slinton if (isinline(s)) { 44514440Slinton printf("inline procedure\n"); 44614438Slinton } 44711863Slinton if (nosource(s)) { 44811863Slinton printf("does not have source information\n"); 44911863Slinton } else { 45011863Slinton printf("has source information\n"); 45111863Slinton } 4529676Slinton break; 4539676Slinton 4549676Slinton case RANGE: 45514381Slinton prangetype(s->symvalue.rangev.lowertype); 4569676Slinton printf("lower\t%d\n", s->symvalue.rangev.lower); 45714381Slinton prangetype(s->symvalue.rangev.uppertype); 4589676Slinton printf("upper\t%d\n", s->symvalue.rangev.upper); 4599676Slinton break; 4609676Slinton 4619676Slinton default: 4629676Slinton /* do nothing */ 4639676Slinton break; 4649676Slinton } 4659676Slinton } 4669676Slinton 46714381Slinton private prangetype(r) 46814381Slinton Rangetype r; 46914381Slinton { 47014381Slinton switch (r) { 47114381Slinton case R_CONST: 47214381Slinton printf("CONST"); 47314381Slinton break; 47414381Slinton 47514381Slinton case R_ARG: 47614381Slinton printf("ARG"); 47714381Slinton break; 47814381Slinton 47914381Slinton case R_TEMP: 48014381Slinton printf("TEMP"); 48114381Slinton break; 48214381Slinton 48314381Slinton case R_ADJUST: 48414381Slinton printf("ADJUST"); 48514381Slinton break; 48614381Slinton } 48714381Slinton } 48814381Slinton 4899676Slinton /* 4909676Slinton * Print out the value on top of the stack according to the given type. 4919676Slinton */ 4929676Slinton 4939676Slinton public printval(t) 4949676Slinton Symbol t; 4959676Slinton { 4969676Slinton Symbol s; 4979676Slinton 4989676Slinton checkref(t); 49916616Ssam if (t->class == TYPEREF) { 50016616Ssam resolveRef(t); 50116616Ssam } 5029676Slinton switch (t->class) { 5039676Slinton case PROC: 5049676Slinton case FUNC: 5059676Slinton s = pop(Symbol); 5069676Slinton printf("%s", symname(s)); 5079676Slinton break; 5089676Slinton 5099676Slinton default: 510*18229Slinton if (t->language == nil or t->language == primlang) { 51116616Ssam (*language_op(findlanguage(".c"), L_PRINTVAL))(t); 5129676Slinton } else { 5139676Slinton (*language_op(t->language, L_PRINTVAL))(t); 5149676Slinton } 5159676Slinton break; 5169676Slinton } 5179676Slinton } 5189676Slinton 5199676Slinton /* 5209676Slinton * Print out the value of a record, field by field. 5219676Slinton */ 5229676Slinton 5239676Slinton public printrecord(s) 5249676Slinton Symbol s; 5259676Slinton { 52616616Ssam Symbol f; 52716616Ssam 5289676Slinton if (s->chain == nil) { 5299676Slinton error("record has no fields"); 5309676Slinton } 5319676Slinton printf("("); 5329676Slinton sp -= size(s); 53316616Ssam f = s->chain; 53416616Ssam if (f != nil) { 53516616Ssam for (;;) { 53616616Ssam printfield(f); 53716616Ssam f = f->chain; 53816616Ssam if (f == nil) break; 53916616Ssam printf(", "); 54016616Ssam } 54116616Ssam } 5429676Slinton printf(")"); 5439676Slinton } 5449676Slinton 5459676Slinton /* 54616616Ssam * Print out a field. 5479676Slinton */ 5489676Slinton 54916616Ssam private printfield(f) 55016616Ssam Symbol f; 5519676Slinton { 5529676Slinton Stack *savesp; 55316616Ssam register int off, len; 5549676Slinton 55516616Ssam printf("%s = ", symname(f)); 5569676Slinton savesp = sp; 55716616Ssam off = f->symvalue.field.offset; 55816616Ssam len = f->symvalue.field.length; 55916616Ssam sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE); 56016616Ssam printval(f); 5619676Slinton sp = savesp; 5629676Slinton } 5639676Slinton 5649676Slinton /* 5659676Slinton * Print out the contents of an array. 5669676Slinton * Haven't quite figured out what the best format is. 5679676Slinton * 5689676Slinton * This is rather inefficient. 5699676Slinton * 5709676Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 5719676Slinton */ 5729676Slinton 5739676Slinton public printarray(a) 5749676Slinton Symbol a; 5759676Slinton { 5769676Slinton Stack *savesp, *newsp; 5779676Slinton Symbol eltype; 5789676Slinton long elsize; 5799676Slinton String sep; 5809676Slinton 5819676Slinton savesp = sp; 58212544Scsvaf sp -= (size(a)); 5839676Slinton newsp = sp; 5849676Slinton eltype = rtype(a->type); 5859676Slinton elsize = size(eltype); 5869676Slinton printf("("); 5879676Slinton if (eltype->class == RECORD or eltype->class == ARRAY or 5889676Slinton eltype->class == VARNT) { 5899676Slinton sep = "\n"; 5909676Slinton putchar('\n'); 5919676Slinton } else { 5929676Slinton sep = ", "; 5939676Slinton } 5949676Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 5959676Slinton if (sp - elsize != newsp) { 5969676Slinton fputs(sep, stdout); 5979676Slinton } 5989676Slinton printval(eltype); 5999676Slinton } 6009676Slinton sp = newsp; 6019676Slinton if (streq(sep, "\n")) { 6029676Slinton putchar('\n'); 6039676Slinton } 6049676Slinton printf(")"); 6059676Slinton } 6069676Slinton 6079676Slinton /* 6089676Slinton * Print out the value of a real number in Pascal notation. 6099676Slinton * This is, unfortunately, different than what one gets 6109676Slinton * from "%g" in printf. 6119676Slinton */ 6129676Slinton 6139676Slinton public prtreal(r) 6149676Slinton double r; 6159676Slinton { 6169676Slinton extern char *index(); 6179676Slinton char buf[256]; 6189676Slinton 6199676Slinton sprintf(buf, "%g", r); 6209676Slinton if (buf[0] == '.') { 6219676Slinton printf("0%s", buf); 6229676Slinton } else if (buf[0] == '-' and buf[1] == '.') { 6239676Slinton printf("-0%s", &buf[1]); 6249676Slinton } else { 6259676Slinton printf("%s", buf); 6269676Slinton } 6279676Slinton if (index(buf, '.') == nil) { 6289676Slinton printf(".0"); 6299676Slinton } 6309676Slinton } 6319676Slinton 6329676Slinton /* 6339676Slinton * Print out a character using ^? notation for unprintables. 6349676Slinton */ 6359676Slinton 6369676Slinton public printchar(c) 6379676Slinton char c; 6389676Slinton { 6399676Slinton if (c == 0) { 6409676Slinton putchar('\\'); 6419676Slinton putchar('0'); 6429676Slinton } else if (c == '\n') { 6439676Slinton putchar('\\'); 6449676Slinton putchar('n'); 6459676Slinton } else if (c > 0 and c < ' ') { 6469676Slinton putchar('^'); 6479676Slinton putchar(c - 1 + 'A'); 64816616Ssam } else if (c >= ' ' && c <= '~') { 64916616Ssam putchar(c); 6509676Slinton } else { 65116616Ssam printf("\\0%o",c); 6529676Slinton } 6539676Slinton } 654*18229Slinton 655*18229Slinton /* 656*18229Slinton * Print out a value for a range type (integer, char, or boolean). 657*18229Slinton */ 658*18229Slinton 659*18229Slinton public printRangeVal (val, t) 660*18229Slinton long val; 661*18229Slinton Symbol t; 662*18229Slinton { 663*18229Slinton if (t == t_boolean->type or istypename(t->type, "boolean")) { 664*18229Slinton if ((boolean) val) { 665*18229Slinton printf("true"); 666*18229Slinton } else { 667*18229Slinton printf("false"); 668*18229Slinton } 669*18229Slinton } else if (t == t_char->type or istypename(t->type, "char")) { 670*18229Slinton if (varIsSet("$hexchars")) { 671*18229Slinton printf("0x%lx", val); 672*18229Slinton } else { 673*18229Slinton putchar('\''); 674*18229Slinton printchar(val); 675*18229Slinton putchar('\''); 676*18229Slinton } 677*18229Slinton } else if (varIsSet("$hexints")) { 678*18229Slinton printf("0x%lx", val); 679*18229Slinton } else if (t->symvalue.rangev.lower >= 0) { 680*18229Slinton printf("%lu", val); 681*18229Slinton } else { 682*18229Slinton printf("%ld", val); 683*18229Slinton } 684*18229Slinton } 685*18229Slinton 686*18229Slinton /* 687*18229Slinton * Print out an enumerated value by finding the corresponding 688*18229Slinton * name in the enumeration list. 689*18229Slinton */ 690*18229Slinton 691*18229Slinton public printEnum (i, t) 692*18229Slinton integer i; 693*18229Slinton Symbol t; 694*18229Slinton { 695*18229Slinton register Symbol e; 696*18229Slinton 697*18229Slinton e = t->chain; 698*18229Slinton while (e != nil and e->symvalue.constval->value.lcon != i) { 699*18229Slinton e = e->chain; 700*18229Slinton } 701*18229Slinton if (e != nil) { 702*18229Slinton printf("%s", symname(e)); 703*18229Slinton } else { 704*18229Slinton printf("%d", i); 705*18229Slinton } 706*18229Slinton } 707*18229Slinton 708*18229Slinton /* 709*18229Slinton * Print out a null-terminated string (pointer to char) 710*18229Slinton * starting at the given address. 711*18229Slinton */ 712*18229Slinton 713*18229Slinton public printString (addr, quotes) 714*18229Slinton Address addr; 715*18229Slinton boolean quotes; 716*18229Slinton { 717*18229Slinton register Address a; 718*18229Slinton register integer i, len; 719*18229Slinton register boolean endofstring; 720*18229Slinton union { 721*18229Slinton char ch[sizeof(Word)]; 722*18229Slinton int word; 723*18229Slinton } u; 724*18229Slinton 725*18229Slinton if (varIsSet("$hexstrings")) { 726*18229Slinton printf("0x%x", addr); 727*18229Slinton } else { 728*18229Slinton if (quotes) { 729*18229Slinton putchar('"'); 730*18229Slinton } 731*18229Slinton a = addr; 732*18229Slinton endofstring = false; 733*18229Slinton while (not endofstring) { 734*18229Slinton dread(&u, a, sizeof(u)); 735*18229Slinton i = 0; 736*18229Slinton do { 737*18229Slinton if (u.ch[i] == '\0') { 738*18229Slinton endofstring = true; 739*18229Slinton } else { 740*18229Slinton printchar(u.ch[i]); 741*18229Slinton } 742*18229Slinton ++i; 743*18229Slinton } while (i < sizeof(Word) and not endofstring); 744*18229Slinton a += sizeof(Word); 745*18229Slinton } 746*18229Slinton if (quotes) { 747*18229Slinton putchar('"'); 748*18229Slinton } 749*18229Slinton } 750*18229Slinton } 751