1*21619Sdist /* 2*21619Sdist * Copyright (c) 1983 Regents of the University of California. 3*21619Sdist * All rights reserved. The Berkeley software License Agreement 4*21619Sdist * specifies the terms and conditions for redistribution. 5*21619Sdist */ 69676Slinton 7*21619Sdist #ifndef lint 8*21619Sdist static char sccsid[] = "@(#)printsym.c 5.1 (Berkeley) 05/31/85"; 9*21619Sdist #endif not lint 109676Slinton 1118229Slinton static char rcsid[] = "$Header: printsym.c,v 1.5 84/12/26 10:41:28 linton 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" 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[] = { 4918229Slinton "bad use", "constant", "type", "variable", "array", "@dynarray", 5018229Slinton "@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 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 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 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 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 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 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 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 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: 25518229Slinton case DYNARRAY: 25618229Slinton case SUBARRAY: 25718229Slinton t = rtype(t->type); 25818229Slinton if (compatible(t, t_char)) { 25918229Slinton printv(p, frame); 26018229Slinton } else { 26118229Slinton printf("%s = (...)", symname(p)); 26218229Slinton } 26318229Slinton break; 26418229Slinton 26518229Slinton case RECORD: 26618229Slinton printf("%s = (...)", symname(p)); 26718229Slinton break; 26818229Slinton 26918229Slinton default: 27018229Slinton printv(p, frame); 27118229Slinton break; 27218229Slinton } 27318229Slinton } 27418229Slinton 27518229Slinton /* 2769676Slinton * Print the name and value of a variable. 2779676Slinton */ 2789676Slinton 2799676Slinton public printv(s, frame) 2809676Slinton Symbol s; 2819676Slinton Frame frame; 2829676Slinton { 2839676Slinton Address addr; 2849676Slinton int len; 28516616Ssam Symbol t; 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); 30018229Slinton if (canpush(len)) { 30118229Slinton rpush(addr, len); 30218229Slinton printval(s->type); 30318229Slinton } else { 30418229Slinton printf("*** expression too large ***"); 30518229Slinton } 3069676Slinton } 3079676Slinton 3089676Slinton /* 3099676Slinton * Print out the name of a symbol. 3109676Slinton */ 3119676Slinton 3129676Slinton public printname(f, s) 3139676Slinton File f; 3149676Slinton Symbol s; 3159676Slinton { 3169676Slinton if (s == nil) { 3179676Slinton fprintf(f, "(noname)"); 31816616Ssam } else if (s == program) { 31916616Ssam fprintf(f, "."); 3209676Slinton } else if (isredirected() or isambiguous(s)) { 3219676Slinton printwhich(f, s); 3229676Slinton } else { 3239676Slinton fprintf(f, "%s", symname(s)); 3249676Slinton } 3259676Slinton } 3269676Slinton 3279676Slinton /* 3289676Slinton * Print the fully specified variable that is described by the given identifer. 3299676Slinton */ 3309676Slinton 3319676Slinton public printwhich(f, s) 3329676Slinton File f; 3339676Slinton Symbol s; 3349676Slinton { 3359676Slinton printouter(f, container(s)); 3369676Slinton fprintf(f, "%s", symname(s)); 3379676Slinton } 3389676Slinton 3399676Slinton /* 3409676Slinton * Print the fully qualified name of each symbol that has the same name 3419676Slinton * as the given symbol. 3429676Slinton */ 3439676Slinton 3449676Slinton public printwhereis(f, s) 3459676Slinton File f; 3469676Slinton Symbol s; 3479676Slinton { 3489676Slinton register Name n; 3499676Slinton register Symbol t; 3509676Slinton 3519676Slinton checkref(s); 3529676Slinton n = s->name; 3539676Slinton t = lookup(n); 3549676Slinton printwhich(f, t); 3559676Slinton t = t->next_sym; 3569676Slinton while (t != nil) { 3579676Slinton if (t->name == n) { 3589676Slinton putc(' ', f); 3599676Slinton printwhich(f, t); 3609676Slinton } 3619676Slinton t = t->next_sym; 3629676Slinton } 3639676Slinton putc('\n', f); 3649676Slinton } 3659676Slinton 3669676Slinton private printouter(f, s) 3679676Slinton File f; 3689676Slinton Symbol s; 3699676Slinton { 3709676Slinton Symbol outer; 3719676Slinton 3729676Slinton if (s != nil) { 3739676Slinton outer = container(s); 3749676Slinton if (outer != nil and outer != program) { 3759676Slinton printouter(f, outer); 3769676Slinton } 3779676Slinton fprintf(f, "%s.", symname(s)); 3789676Slinton } 3799676Slinton } 3809676Slinton 3819676Slinton public printdecl(s) 3829676Slinton Symbol s; 3839676Slinton { 38418229Slinton Language lang; 38518229Slinton 3869676Slinton checkref(s); 38718229Slinton if (s->language == nil or s->language == primlang) { 38818229Slinton lang = findlanguage(".s"); 38918229Slinton } else { 39018229Slinton lang = s->language; 39118229Slinton } 39218229Slinton (*language_op(lang, L_PRINTDECL))(s); 3939676Slinton } 3949676Slinton 3959676Slinton /* 3969676Slinton * Straight dump of symbol information. 3979676Slinton */ 3989676Slinton 3999676Slinton public psym(s) 4009676Slinton Symbol s; 4019676Slinton { 4029676Slinton printf("name\t%s\n", symname(s)); 4039676Slinton printf("lang\t%s\n", language_name(s->language)); 4049676Slinton printf("level\t%d\n", s->level); 4059676Slinton printf("class\t%s\n", classname(s)); 4069676Slinton printf("type\t0x%x", s->type); 4079676Slinton if (s->type != nil and s->type->name != nil) { 4089676Slinton printf(" (%s)", symname(s->type)); 4099676Slinton } 4109676Slinton printf("\nchain\t0x%x", s->chain); 4119676Slinton if (s->chain != nil and s->chain->name != nil) { 4129676Slinton printf(" (%s)", symname(s->chain)); 4139676Slinton } 4149676Slinton printf("\nblock\t0x%x", s->block); 4159676Slinton if (s->block->name != nil) { 4169676Slinton printf(" ("); 4179676Slinton printname(stdout, s->block); 4189676Slinton putchar(')'); 4199676Slinton } 4209676Slinton putchar('\n'); 4219676Slinton switch (s->class) { 42218229Slinton case TYPE: 42318229Slinton printf("size\t%d\n", size(s)); 42418229Slinton break; 42518229Slinton 4269676Slinton case VAR: 4279676Slinton case REF: 4289676Slinton if (s->level >= 3) { 4299676Slinton printf("address\t0x%x\n", s->symvalue.offset); 4309676Slinton } else { 4319676Slinton printf("offset\t%d\n", s->symvalue.offset); 4329676Slinton } 43312545Scsvaf printf("size\t%d\n", size(s)); 4349676Slinton break; 4359676Slinton 4369676Slinton case RECORD: 4379676Slinton case VARNT: 4389676Slinton printf("size\t%d\n", s->symvalue.offset); 4399676Slinton break; 4409676Slinton 4419676Slinton case FIELD: 4429676Slinton printf("offset\t%d\n", s->symvalue.field.offset); 4439676Slinton printf("size\t%d\n", s->symvalue.field.length); 4449676Slinton break; 4459676Slinton 44614381Slinton case PROG: 4479676Slinton case PROC: 4489676Slinton case FUNC: 4499676Slinton printf("address\t0x%x\n", s->symvalue.funcv.beginaddr); 45014438Slinton if (isinline(s)) { 45114440Slinton printf("inline procedure\n"); 45214438Slinton } 45311863Slinton if (nosource(s)) { 45411863Slinton printf("does not have source information\n"); 45511863Slinton } else { 45611863Slinton printf("has source information\n"); 45711863Slinton } 4589676Slinton break; 4599676Slinton 4609676Slinton case RANGE: 46114381Slinton prangetype(s->symvalue.rangev.lowertype); 4629676Slinton printf("lower\t%d\n", s->symvalue.rangev.lower); 46314381Slinton prangetype(s->symvalue.rangev.uppertype); 4649676Slinton printf("upper\t%d\n", s->symvalue.rangev.upper); 4659676Slinton break; 4669676Slinton 4679676Slinton default: 4689676Slinton /* do nothing */ 4699676Slinton break; 4709676Slinton } 4719676Slinton } 4729676Slinton 47314381Slinton private prangetype(r) 47414381Slinton Rangetype r; 47514381Slinton { 47614381Slinton switch (r) { 47714381Slinton case R_CONST: 47814381Slinton printf("CONST"); 47914381Slinton break; 48014381Slinton 48114381Slinton case R_ARG: 48214381Slinton printf("ARG"); 48314381Slinton break; 48414381Slinton 48514381Slinton case R_TEMP: 48614381Slinton printf("TEMP"); 48714381Slinton break; 48814381Slinton 48914381Slinton case R_ADJUST: 49014381Slinton printf("ADJUST"); 49114381Slinton break; 49214381Slinton } 49314381Slinton } 49414381Slinton 4959676Slinton /* 4969676Slinton * Print out the value on top of the stack according to the given type. 4979676Slinton */ 4989676Slinton 4999676Slinton public printval(t) 5009676Slinton Symbol t; 5019676Slinton { 5029676Slinton Symbol s; 5039676Slinton 5049676Slinton checkref(t); 50516616Ssam if (t->class == TYPEREF) { 50616616Ssam resolveRef(t); 50716616Ssam } 5089676Slinton switch (t->class) { 5099676Slinton case PROC: 5109676Slinton case FUNC: 5119676Slinton s = pop(Symbol); 5129676Slinton printf("%s", symname(s)); 5139676Slinton break; 5149676Slinton 5159676Slinton default: 51618229Slinton if (t->language == nil or t->language == primlang) { 51716616Ssam (*language_op(findlanguage(".c"), L_PRINTVAL))(t); 5189676Slinton } else { 5199676Slinton (*language_op(t->language, L_PRINTVAL))(t); 5209676Slinton } 5219676Slinton break; 5229676Slinton } 5239676Slinton } 5249676Slinton 5259676Slinton /* 5269676Slinton * Print out the value of a record, field by field. 5279676Slinton */ 5289676Slinton 5299676Slinton public printrecord(s) 5309676Slinton Symbol s; 5319676Slinton { 53216616Ssam Symbol f; 53316616Ssam 5349676Slinton if (s->chain == nil) { 5359676Slinton error("record has no fields"); 5369676Slinton } 5379676Slinton printf("("); 5389676Slinton sp -= size(s); 53916616Ssam f = s->chain; 54016616Ssam if (f != nil) { 54116616Ssam for (;;) { 54216616Ssam printfield(f); 54316616Ssam f = f->chain; 54416616Ssam if (f == nil) break; 54516616Ssam printf(", "); 54616616Ssam } 54716616Ssam } 5489676Slinton printf(")"); 5499676Slinton } 5509676Slinton 5519676Slinton /* 55216616Ssam * Print out a field. 5539676Slinton */ 5549676Slinton 55516616Ssam private printfield(f) 55616616Ssam Symbol f; 5579676Slinton { 5589676Slinton Stack *savesp; 55916616Ssam register int off, len; 5609676Slinton 56116616Ssam printf("%s = ", symname(f)); 5629676Slinton savesp = sp; 56316616Ssam off = f->symvalue.field.offset; 56416616Ssam len = f->symvalue.field.length; 56516616Ssam sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE); 56616616Ssam printval(f); 5679676Slinton sp = savesp; 5689676Slinton } 5699676Slinton 5709676Slinton /* 5719676Slinton * Print out the contents of an array. 5729676Slinton * Haven't quite figured out what the best format is. 5739676Slinton * 5749676Slinton * This is rather inefficient. 5759676Slinton * 5769676Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 5779676Slinton */ 5789676Slinton 5799676Slinton public printarray(a) 5809676Slinton Symbol a; 5819676Slinton { 5829676Slinton Stack *savesp, *newsp; 5839676Slinton Symbol eltype; 5849676Slinton long elsize; 5859676Slinton String sep; 5869676Slinton 5879676Slinton savesp = sp; 58812544Scsvaf sp -= (size(a)); 5899676Slinton newsp = sp; 5909676Slinton eltype = rtype(a->type); 5919676Slinton elsize = size(eltype); 5929676Slinton printf("("); 5939676Slinton if (eltype->class == RECORD or eltype->class == ARRAY or 5949676Slinton eltype->class == VARNT) { 5959676Slinton sep = "\n"; 5969676Slinton putchar('\n'); 5979676Slinton } else { 5989676Slinton sep = ", "; 5999676Slinton } 6009676Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 6019676Slinton if (sp - elsize != newsp) { 6029676Slinton fputs(sep, stdout); 6039676Slinton } 6049676Slinton printval(eltype); 6059676Slinton } 6069676Slinton sp = newsp; 6079676Slinton if (streq(sep, "\n")) { 6089676Slinton putchar('\n'); 6099676Slinton } 6109676Slinton printf(")"); 6119676Slinton } 6129676Slinton 6139676Slinton /* 6149676Slinton * Print out the value of a real number in Pascal notation. 6159676Slinton * This is, unfortunately, different than what one gets 6169676Slinton * from "%g" in printf. 6179676Slinton */ 6189676Slinton 6199676Slinton public prtreal(r) 6209676Slinton double r; 6219676Slinton { 6229676Slinton extern char *index(); 6239676Slinton char buf[256]; 6249676Slinton 6259676Slinton sprintf(buf, "%g", r); 6269676Slinton if (buf[0] == '.') { 6279676Slinton printf("0%s", buf); 6289676Slinton } else if (buf[0] == '-' and buf[1] == '.') { 6299676Slinton printf("-0%s", &buf[1]); 6309676Slinton } else { 6319676Slinton printf("%s", buf); 6329676Slinton } 6339676Slinton if (index(buf, '.') == nil) { 6349676Slinton printf(".0"); 6359676Slinton } 6369676Slinton } 6379676Slinton 6389676Slinton /* 6399676Slinton * Print out a character using ^? notation for unprintables. 6409676Slinton */ 6419676Slinton 6429676Slinton public printchar(c) 6439676Slinton char c; 6449676Slinton { 6459676Slinton if (c == 0) { 6469676Slinton putchar('\\'); 6479676Slinton putchar('0'); 6489676Slinton } else if (c == '\n') { 6499676Slinton putchar('\\'); 6509676Slinton putchar('n'); 6519676Slinton } else if (c > 0 and c < ' ') { 6529676Slinton putchar('^'); 6539676Slinton putchar(c - 1 + 'A'); 65416616Ssam } else if (c >= ' ' && c <= '~') { 65516616Ssam putchar(c); 6569676Slinton } else { 65716616Ssam printf("\\0%o",c); 6589676Slinton } 6599676Slinton } 66018229Slinton 66118229Slinton /* 66218229Slinton * Print out a value for a range type (integer, char, or boolean). 66318229Slinton */ 66418229Slinton 66518229Slinton public printRangeVal (val, t) 66618229Slinton long val; 66718229Slinton Symbol t; 66818229Slinton { 66918229Slinton if (t == t_boolean->type or istypename(t->type, "boolean")) { 67018229Slinton if ((boolean) val) { 67118229Slinton printf("true"); 67218229Slinton } else { 67318229Slinton printf("false"); 67418229Slinton } 67518229Slinton } else if (t == t_char->type or istypename(t->type, "char")) { 67618229Slinton if (varIsSet("$hexchars")) { 67718229Slinton printf("0x%lx", val); 67818229Slinton } else { 67918229Slinton putchar('\''); 68018229Slinton printchar(val); 68118229Slinton putchar('\''); 68218229Slinton } 68318229Slinton } else if (varIsSet("$hexints")) { 68418229Slinton printf("0x%lx", val); 68518229Slinton } else if (t->symvalue.rangev.lower >= 0) { 68618229Slinton printf("%lu", val); 68718229Slinton } else { 68818229Slinton printf("%ld", val); 68918229Slinton } 69018229Slinton } 69118229Slinton 69218229Slinton /* 69318229Slinton * Print out an enumerated value by finding the corresponding 69418229Slinton * name in the enumeration list. 69518229Slinton */ 69618229Slinton 69718229Slinton public printEnum (i, t) 69818229Slinton integer i; 69918229Slinton Symbol t; 70018229Slinton { 70118229Slinton register Symbol e; 70218229Slinton 70318229Slinton e = t->chain; 70418229Slinton while (e != nil and e->symvalue.constval->value.lcon != i) { 70518229Slinton e = e->chain; 70618229Slinton } 70718229Slinton if (e != nil) { 70818229Slinton printf("%s", symname(e)); 70918229Slinton } else { 71018229Slinton printf("%d", i); 71118229Slinton } 71218229Slinton } 71318229Slinton 71418229Slinton /* 71518229Slinton * Print out a null-terminated string (pointer to char) 71618229Slinton * starting at the given address. 71718229Slinton */ 71818229Slinton 71918229Slinton public printString (addr, quotes) 72018229Slinton Address addr; 72118229Slinton boolean quotes; 72218229Slinton { 72318229Slinton register Address a; 72418229Slinton register integer i, len; 72518229Slinton register boolean endofstring; 72618229Slinton union { 72718229Slinton char ch[sizeof(Word)]; 72818229Slinton int word; 72918229Slinton } u; 73018229Slinton 73118229Slinton if (varIsSet("$hexstrings")) { 73218229Slinton printf("0x%x", addr); 73318229Slinton } else { 73418229Slinton if (quotes) { 73518229Slinton putchar('"'); 73618229Slinton } 73718229Slinton a = addr; 73818229Slinton endofstring = false; 73918229Slinton while (not endofstring) { 74018229Slinton dread(&u, a, sizeof(u)); 74118229Slinton i = 0; 74218229Slinton do { 74318229Slinton if (u.ch[i] == '\0') { 74418229Slinton endofstring = true; 74518229Slinton } else { 74618229Slinton printchar(u.ch[i]); 74718229Slinton } 74818229Slinton ++i; 74918229Slinton } while (i < sizeof(Word) and not endofstring); 75018229Slinton a += sizeof(Word); 75118229Slinton } 75218229Slinton if (quotes) { 75318229Slinton putchar('"'); 75418229Slinton } 75518229Slinton } 75618229Slinton } 757