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*26478Ssam static char sccsid[] = "@(#)printsym.c 5.3 (Berkeley) 03/05/86"; 921619Sdist #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; 2859676Slinton 2869676Slinton if (isambiguous(s) and ismodule(container(s))) { 2879676Slinton printname(stdout, s); 2889676Slinton printf(" = "); 2899676Slinton } else { 2909676Slinton printf("%s = ", symname(s)); 2919676Slinton } 29218229Slinton if (isvarparam(s) and not isopenarray(s)) { 29318229Slinton rpush(address(s, frame), sizeof(Address)); 29418229Slinton addr = pop(Address); 2959676Slinton } else { 29618229Slinton addr = address(s, frame); 29718229Slinton } 29818229Slinton len = size(s); 29924554Smckusick if (not canpush(len)) { 30024554Smckusick printf("*** expression too large ***"); 30124554Smckusick } else if (isreg(s)) { 30224554Smckusick push(Address, addr); 30324554Smckusick printval(s->type); 30424554Smckusick } else { 30518229Slinton rpush(addr, len); 30618229Slinton printval(s->type); 30718229Slinton } 3089676Slinton } 3099676Slinton 3109676Slinton /* 3119676Slinton * Print out the name of a symbol. 3129676Slinton */ 3139676Slinton 3149676Slinton public printname(f, s) 3159676Slinton File f; 3169676Slinton Symbol s; 3179676Slinton { 3189676Slinton if (s == nil) { 3199676Slinton fprintf(f, "(noname)"); 32016616Ssam } else if (s == program) { 32116616Ssam fprintf(f, "."); 3229676Slinton } else if (isredirected() or isambiguous(s)) { 3239676Slinton printwhich(f, s); 3249676Slinton } else { 3259676Slinton fprintf(f, "%s", symname(s)); 3269676Slinton } 3279676Slinton } 3289676Slinton 3299676Slinton /* 3309676Slinton * Print the fully specified variable that is described by the given identifer. 3319676Slinton */ 3329676Slinton 3339676Slinton public printwhich(f, s) 3349676Slinton File f; 3359676Slinton Symbol s; 3369676Slinton { 3379676Slinton printouter(f, container(s)); 3389676Slinton fprintf(f, "%s", symname(s)); 3399676Slinton } 3409676Slinton 3419676Slinton /* 3429676Slinton * Print the fully qualified name of each symbol that has the same name 3439676Slinton * as the given symbol. 3449676Slinton */ 3459676Slinton 3469676Slinton public printwhereis(f, s) 3479676Slinton File f; 3489676Slinton Symbol s; 3499676Slinton { 3509676Slinton register Name n; 3519676Slinton register Symbol t; 3529676Slinton 3539676Slinton checkref(s); 3549676Slinton n = s->name; 3559676Slinton t = lookup(n); 3569676Slinton printwhich(f, t); 3579676Slinton t = t->next_sym; 3589676Slinton while (t != nil) { 3599676Slinton if (t->name == n) { 3609676Slinton putc(' ', f); 3619676Slinton printwhich(f, t); 3629676Slinton } 3639676Slinton t = t->next_sym; 3649676Slinton } 3659676Slinton putc('\n', f); 3669676Slinton } 3679676Slinton 3689676Slinton private printouter(f, s) 3699676Slinton File f; 3709676Slinton Symbol s; 3719676Slinton { 3729676Slinton Symbol outer; 3739676Slinton 3749676Slinton if (s != nil) { 3759676Slinton outer = container(s); 3769676Slinton if (outer != nil and outer != program) { 3779676Slinton printouter(f, outer); 3789676Slinton } 3799676Slinton fprintf(f, "%s.", symname(s)); 3809676Slinton } 3819676Slinton } 3829676Slinton 3839676Slinton public printdecl(s) 3849676Slinton Symbol s; 3859676Slinton { 38618229Slinton Language lang; 38718229Slinton 3889676Slinton checkref(s); 38918229Slinton if (s->language == nil or s->language == primlang) { 39018229Slinton lang = findlanguage(".s"); 39118229Slinton } else { 39218229Slinton lang = s->language; 39318229Slinton } 39418229Slinton (*language_op(lang, L_PRINTDECL))(s); 3959676Slinton } 3969676Slinton 3979676Slinton /* 3989676Slinton * Straight dump of symbol information. 3999676Slinton */ 4009676Slinton 4019676Slinton public psym(s) 4029676Slinton Symbol s; 4039676Slinton { 4049676Slinton printf("name\t%s\n", symname(s)); 4059676Slinton printf("lang\t%s\n", language_name(s->language)); 4069676Slinton printf("level\t%d\n", s->level); 4079676Slinton printf("class\t%s\n", classname(s)); 4089676Slinton printf("type\t0x%x", s->type); 4099676Slinton if (s->type != nil and s->type->name != nil) { 4109676Slinton printf(" (%s)", symname(s->type)); 4119676Slinton } 4129676Slinton printf("\nchain\t0x%x", s->chain); 4139676Slinton if (s->chain != nil and s->chain->name != nil) { 4149676Slinton printf(" (%s)", symname(s->chain)); 4159676Slinton } 4169676Slinton printf("\nblock\t0x%x", s->block); 4179676Slinton if (s->block->name != nil) { 4189676Slinton printf(" ("); 4199676Slinton printname(stdout, s->block); 4209676Slinton putchar(')'); 4219676Slinton } 4229676Slinton putchar('\n'); 4239676Slinton switch (s->class) { 42418229Slinton case TYPE: 42518229Slinton printf("size\t%d\n", size(s)); 42618229Slinton break; 42718229Slinton 4289676Slinton case VAR: 4299676Slinton case REF: 4309676Slinton if (s->level >= 3) { 4319676Slinton printf("address\t0x%x\n", s->symvalue.offset); 4329676Slinton } else { 4339676Slinton printf("offset\t%d\n", s->symvalue.offset); 4349676Slinton } 43512545Scsvaf printf("size\t%d\n", size(s)); 4369676Slinton break; 4379676Slinton 4389676Slinton case RECORD: 4399676Slinton case VARNT: 4409676Slinton printf("size\t%d\n", s->symvalue.offset); 4419676Slinton break; 4429676Slinton 4439676Slinton case FIELD: 4449676Slinton printf("offset\t%d\n", s->symvalue.field.offset); 4459676Slinton printf("size\t%d\n", s->symvalue.field.length); 4469676Slinton break; 4479676Slinton 44814381Slinton case PROG: 4499676Slinton case PROC: 4509676Slinton case FUNC: 4519676Slinton printf("address\t0x%x\n", s->symvalue.funcv.beginaddr); 45214438Slinton if (isinline(s)) { 45314440Slinton printf("inline procedure\n"); 45414438Slinton } 45511863Slinton if (nosource(s)) { 45611863Slinton printf("does not have source information\n"); 45711863Slinton } else { 45811863Slinton printf("has source information\n"); 45911863Slinton } 4609676Slinton break; 4619676Slinton 4629676Slinton case RANGE: 46314381Slinton prangetype(s->symvalue.rangev.lowertype); 4649676Slinton printf("lower\t%d\n", s->symvalue.rangev.lower); 46514381Slinton prangetype(s->symvalue.rangev.uppertype); 4669676Slinton printf("upper\t%d\n", s->symvalue.rangev.upper); 4679676Slinton break; 4689676Slinton 4699676Slinton default: 4709676Slinton /* do nothing */ 4719676Slinton break; 4729676Slinton } 4739676Slinton } 4749676Slinton 47514381Slinton private prangetype(r) 47614381Slinton Rangetype r; 47714381Slinton { 47814381Slinton switch (r) { 47914381Slinton case R_CONST: 48014381Slinton printf("CONST"); 48114381Slinton break; 48214381Slinton 48314381Slinton case R_ARG: 48414381Slinton printf("ARG"); 48514381Slinton break; 48614381Slinton 48714381Slinton case R_TEMP: 48814381Slinton printf("TEMP"); 48914381Slinton break; 49014381Slinton 49114381Slinton case R_ADJUST: 49214381Slinton printf("ADJUST"); 49314381Slinton break; 49414381Slinton } 49514381Slinton } 49614381Slinton 4979676Slinton /* 4989676Slinton * Print out the value on top of the stack according to the given type. 4999676Slinton */ 5009676Slinton 5019676Slinton public printval(t) 5029676Slinton Symbol t; 5039676Slinton { 5049676Slinton Symbol s; 5059676Slinton 5069676Slinton checkref(t); 50716616Ssam if (t->class == TYPEREF) { 50816616Ssam resolveRef(t); 50916616Ssam } 5109676Slinton switch (t->class) { 5119676Slinton case PROC: 5129676Slinton case FUNC: 5139676Slinton s = pop(Symbol); 5149676Slinton printf("%s", symname(s)); 5159676Slinton break; 5169676Slinton 5179676Slinton default: 51818229Slinton if (t->language == nil or t->language == primlang) { 519*26478Ssam (*language_op(findlanguage(".c"), L_PRINTVAL))(t); 5209676Slinton } else { 5219676Slinton (*language_op(t->language, L_PRINTVAL))(t); 5229676Slinton } 5239676Slinton break; 5249676Slinton } 5259676Slinton } 5269676Slinton 5279676Slinton /* 5289676Slinton * Print out the value of a record, field by field. 5299676Slinton */ 5309676Slinton 5319676Slinton public printrecord(s) 5329676Slinton Symbol s; 5339676Slinton { 53416616Ssam Symbol f; 53516616Ssam 5369676Slinton if (s->chain == nil) { 5379676Slinton error("record has no fields"); 5389676Slinton } 5399676Slinton printf("("); 5409676Slinton sp -= size(s); 54116616Ssam f = s->chain; 54216616Ssam if (f != nil) { 54316616Ssam for (;;) { 54416616Ssam printfield(f); 54516616Ssam f = f->chain; 54616616Ssam if (f == nil) break; 54716616Ssam printf(", "); 54816616Ssam } 54916616Ssam } 5509676Slinton printf(")"); 5519676Slinton } 5529676Slinton 5539676Slinton /* 55416616Ssam * Print out a field. 5559676Slinton */ 5569676Slinton 55716616Ssam private printfield(f) 55816616Ssam Symbol f; 5599676Slinton { 5609676Slinton Stack *savesp; 56116616Ssam register int off, len; 5629676Slinton 56316616Ssam printf("%s = ", symname(f)); 5649676Slinton savesp = sp; 56516616Ssam off = f->symvalue.field.offset; 56616616Ssam len = f->symvalue.field.length; 56716616Ssam sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE); 56816616Ssam printval(f); 5699676Slinton sp = savesp; 5709676Slinton } 5719676Slinton 5729676Slinton /* 5739676Slinton * Print out the contents of an array. 5749676Slinton * Haven't quite figured out what the best format is. 5759676Slinton * 5769676Slinton * This is rather inefficient. 5779676Slinton * 5789676Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 5799676Slinton */ 5809676Slinton 5819676Slinton public printarray(a) 5829676Slinton Symbol a; 5839676Slinton { 5849676Slinton Stack *savesp, *newsp; 5859676Slinton Symbol eltype; 5869676Slinton long elsize; 5879676Slinton String sep; 5889676Slinton 5899676Slinton savesp = sp; 59012544Scsvaf sp -= (size(a)); 5919676Slinton newsp = sp; 5929676Slinton eltype = rtype(a->type); 5939676Slinton elsize = size(eltype); 5949676Slinton printf("("); 5959676Slinton if (eltype->class == RECORD or eltype->class == ARRAY or 5969676Slinton eltype->class == VARNT) { 5979676Slinton sep = "\n"; 5989676Slinton putchar('\n'); 5999676Slinton } else { 6009676Slinton sep = ", "; 6019676Slinton } 6029676Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 6039676Slinton if (sp - elsize != newsp) { 6049676Slinton fputs(sep, stdout); 6059676Slinton } 6069676Slinton printval(eltype); 6079676Slinton } 6089676Slinton sp = newsp; 6099676Slinton if (streq(sep, "\n")) { 6109676Slinton putchar('\n'); 6119676Slinton } 6129676Slinton printf(")"); 6139676Slinton } 6149676Slinton 6159676Slinton /* 6169676Slinton * Print out the value of a real number in Pascal notation. 6179676Slinton * This is, unfortunately, different than what one gets 6189676Slinton * from "%g" in printf. 6199676Slinton */ 6209676Slinton 6219676Slinton public prtreal(r) 6229676Slinton double r; 6239676Slinton { 6249676Slinton extern char *index(); 6259676Slinton char buf[256]; 6269676Slinton 6279676Slinton sprintf(buf, "%g", r); 6289676Slinton if (buf[0] == '.') { 6299676Slinton printf("0%s", buf); 6309676Slinton } else if (buf[0] == '-' and buf[1] == '.') { 6319676Slinton printf("-0%s", &buf[1]); 6329676Slinton } else { 6339676Slinton printf("%s", buf); 6349676Slinton } 6359676Slinton if (index(buf, '.') == nil) { 6369676Slinton printf(".0"); 6379676Slinton } 6389676Slinton } 6399676Slinton 6409676Slinton /* 6419676Slinton * Print out a character using ^? notation for unprintables. 6429676Slinton */ 6439676Slinton 6449676Slinton public printchar(c) 6459676Slinton char c; 6469676Slinton { 6479676Slinton if (c == 0) { 6489676Slinton putchar('\\'); 6499676Slinton putchar('0'); 6509676Slinton } else if (c == '\n') { 6519676Slinton putchar('\\'); 6529676Slinton putchar('n'); 6539676Slinton } else if (c > 0 and c < ' ') { 6549676Slinton putchar('^'); 6559676Slinton putchar(c - 1 + 'A'); 65616616Ssam } else if (c >= ' ' && c <= '~') { 65716616Ssam putchar(c); 6589676Slinton } else { 65916616Ssam printf("\\0%o",c); 6609676Slinton } 6619676Slinton } 66218229Slinton 66318229Slinton /* 66418229Slinton * Print out a value for a range type (integer, char, or boolean). 66518229Slinton */ 66618229Slinton 66718229Slinton public printRangeVal (val, t) 66818229Slinton long val; 66918229Slinton Symbol t; 67018229Slinton { 67118229Slinton if (t == t_boolean->type or istypename(t->type, "boolean")) { 67218229Slinton if ((boolean) val) { 67318229Slinton printf("true"); 67418229Slinton } else { 67518229Slinton printf("false"); 67618229Slinton } 67718229Slinton } else if (t == t_char->type or istypename(t->type, "char")) { 67818229Slinton if (varIsSet("$hexchars")) { 67918229Slinton printf("0x%lx", val); 68018229Slinton } else { 68118229Slinton putchar('\''); 68218229Slinton printchar(val); 68318229Slinton putchar('\''); 68418229Slinton } 68518229Slinton } else if (varIsSet("$hexints")) { 68618229Slinton printf("0x%lx", val); 68718229Slinton } else if (t->symvalue.rangev.lower >= 0) { 68818229Slinton printf("%lu", val); 68918229Slinton } else { 69018229Slinton printf("%ld", val); 69118229Slinton } 69218229Slinton } 69318229Slinton 69418229Slinton /* 69518229Slinton * Print out an enumerated value by finding the corresponding 69618229Slinton * name in the enumeration list. 69718229Slinton */ 69818229Slinton 69918229Slinton public printEnum (i, t) 70018229Slinton integer i; 70118229Slinton Symbol t; 70218229Slinton { 70318229Slinton register Symbol e; 70418229Slinton 70518229Slinton e = t->chain; 70618229Slinton while (e != nil and e->symvalue.constval->value.lcon != i) { 70718229Slinton e = e->chain; 70818229Slinton } 70918229Slinton if (e != nil) { 71018229Slinton printf("%s", symname(e)); 71118229Slinton } else { 71218229Slinton printf("%d", i); 71318229Slinton } 71418229Slinton } 71518229Slinton 71618229Slinton /* 71718229Slinton * Print out a null-terminated string (pointer to char) 71818229Slinton * starting at the given address. 71918229Slinton */ 72018229Slinton 72118229Slinton public printString (addr, quotes) 72218229Slinton Address addr; 72318229Slinton boolean quotes; 72418229Slinton { 72518229Slinton register Address a; 72618229Slinton register integer i, len; 72718229Slinton register boolean endofstring; 72818229Slinton union { 72918229Slinton char ch[sizeof(Word)]; 73018229Slinton int word; 73118229Slinton } u; 73218229Slinton 73318229Slinton if (varIsSet("$hexstrings")) { 73418229Slinton printf("0x%x", addr); 73518229Slinton } else { 73618229Slinton if (quotes) { 73718229Slinton putchar('"'); 73818229Slinton } 73918229Slinton a = addr; 74018229Slinton endofstring = false; 74118229Slinton while (not endofstring) { 74218229Slinton dread(&u, a, sizeof(u)); 74318229Slinton i = 0; 74418229Slinton do { 74518229Slinton if (u.ch[i] == '\0') { 74618229Slinton endofstring = true; 74718229Slinton } else { 74818229Slinton printchar(u.ch[i]); 74918229Slinton } 75018229Slinton ++i; 75118229Slinton } while (i < sizeof(Word) and not endofstring); 75218229Slinton a += sizeof(Word); 75318229Slinton } 75418229Slinton if (quotes) { 75518229Slinton putchar('"'); 75618229Slinton } 75718229Slinton } 75818229Slinton } 759