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*29820Ssam static char sccsid[] = "@(#)printsym.c 5.4 (Berkeley) 09/01/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" 30*29820Ssam #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[] = { 5018229Slinton "bad use", "constant", "type", "variable", "array", "@dynarray", 5118229Slinton "@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: 25618229Slinton case DYNARRAY: 25718229Slinton case SUBARRAY: 25818229Slinton t = rtype(t->type); 25918229Slinton if (compatible(t, t_char)) { 26018229Slinton printv(p, frame); 26118229Slinton } else { 26218229Slinton printf("%s = (...)", symname(p)); 26318229Slinton } 26418229Slinton break; 26518229Slinton 26618229Slinton case RECORD: 26718229Slinton printf("%s = (...)", symname(p)); 26818229Slinton break; 26918229Slinton 27018229Slinton default: 27118229Slinton printv(p, frame); 27218229Slinton break; 27318229Slinton } 27418229Slinton } 27518229Slinton 27618229Slinton /* 2779676Slinton * Print the name and value of a variable. 2789676Slinton */ 2799676Slinton 2809676Slinton public printv(s, frame) 2819676Slinton Symbol s; 2829676Slinton Frame frame; 2839676Slinton { 2849676Slinton Address addr; 2859676Slinton int len; 2869676Slinton 2879676Slinton if (isambiguous(s) and ismodule(container(s))) { 2889676Slinton printname(stdout, s); 2899676Slinton printf(" = "); 2909676Slinton } else { 2919676Slinton printf("%s = ", symname(s)); 2929676Slinton } 29318229Slinton if (isvarparam(s) and not isopenarray(s)) { 29418229Slinton rpush(address(s, frame), sizeof(Address)); 29518229Slinton addr = pop(Address); 2969676Slinton } else { 29718229Slinton addr = address(s, frame); 29818229Slinton } 29918229Slinton len = size(s); 30024554Smckusick if (not canpush(len)) { 30124554Smckusick printf("*** expression too large ***"); 30224554Smckusick } else if (isreg(s)) { 30324554Smckusick push(Address, addr); 30424554Smckusick printval(s->type); 30524554Smckusick } else { 30618229Slinton rpush(addr, len); 30718229Slinton printval(s->type); 30818229Slinton } 3099676Slinton } 3109676Slinton 3119676Slinton /* 3129676Slinton * Print out the name of a symbol. 3139676Slinton */ 3149676Slinton 3159676Slinton public printname(f, s) 3169676Slinton File f; 3179676Slinton Symbol s; 3189676Slinton { 3199676Slinton if (s == nil) { 3209676Slinton fprintf(f, "(noname)"); 32116616Ssam } else if (s == program) { 32216616Ssam fprintf(f, "."); 3239676Slinton } else if (isredirected() or isambiguous(s)) { 3249676Slinton printwhich(f, s); 3259676Slinton } else { 3269676Slinton fprintf(f, "%s", symname(s)); 3279676Slinton } 3289676Slinton } 3299676Slinton 3309676Slinton /* 3319676Slinton * Print the fully specified variable that is described by the given identifer. 3329676Slinton */ 3339676Slinton 3349676Slinton public printwhich(f, s) 3359676Slinton File f; 3369676Slinton Symbol s; 3379676Slinton { 3389676Slinton printouter(f, container(s)); 3399676Slinton fprintf(f, "%s", symname(s)); 3409676Slinton } 3419676Slinton 3429676Slinton /* 3439676Slinton * Print the fully qualified name of each symbol that has the same name 3449676Slinton * as the given symbol. 3459676Slinton */ 3469676Slinton 3479676Slinton public printwhereis(f, s) 3489676Slinton File f; 3499676Slinton Symbol s; 3509676Slinton { 3519676Slinton register Name n; 3529676Slinton register Symbol t; 3539676Slinton 3549676Slinton checkref(s); 3559676Slinton n = s->name; 3569676Slinton t = lookup(n); 3579676Slinton printwhich(f, t); 3589676Slinton t = t->next_sym; 3599676Slinton while (t != nil) { 3609676Slinton if (t->name == n) { 3619676Slinton putc(' ', f); 3629676Slinton printwhich(f, t); 3639676Slinton } 3649676Slinton t = t->next_sym; 3659676Slinton } 3669676Slinton putc('\n', f); 3679676Slinton } 3689676Slinton 3699676Slinton private printouter(f, s) 3709676Slinton File f; 3719676Slinton Symbol s; 3729676Slinton { 3739676Slinton Symbol outer; 3749676Slinton 3759676Slinton if (s != nil) { 3769676Slinton outer = container(s); 3779676Slinton if (outer != nil and outer != program) { 3789676Slinton printouter(f, outer); 3799676Slinton } 3809676Slinton fprintf(f, "%s.", symname(s)); 3819676Slinton } 3829676Slinton } 3839676Slinton 3849676Slinton public printdecl(s) 3859676Slinton Symbol s; 3869676Slinton { 38718229Slinton Language lang; 38818229Slinton 3899676Slinton checkref(s); 39018229Slinton if (s->language == nil or s->language == primlang) { 39118229Slinton lang = findlanguage(".s"); 39218229Slinton } else { 39318229Slinton lang = s->language; 39418229Slinton } 39518229Slinton (*language_op(lang, L_PRINTDECL))(s); 3969676Slinton } 3979676Slinton 3989676Slinton /* 3999676Slinton * Straight dump of symbol information. 4009676Slinton */ 4019676Slinton 4029676Slinton public psym(s) 4039676Slinton Symbol s; 4049676Slinton { 4059676Slinton printf("name\t%s\n", symname(s)); 4069676Slinton printf("lang\t%s\n", language_name(s->language)); 4079676Slinton printf("level\t%d\n", s->level); 4089676Slinton printf("class\t%s\n", classname(s)); 4099676Slinton printf("type\t0x%x", s->type); 4109676Slinton if (s->type != nil and s->type->name != nil) { 4119676Slinton printf(" (%s)", symname(s->type)); 4129676Slinton } 4139676Slinton printf("\nchain\t0x%x", s->chain); 4149676Slinton if (s->chain != nil and s->chain->name != nil) { 4159676Slinton printf(" (%s)", symname(s->chain)); 4169676Slinton } 4179676Slinton printf("\nblock\t0x%x", s->block); 4189676Slinton if (s->block->name != nil) { 4199676Slinton printf(" ("); 4209676Slinton printname(stdout, s->block); 4219676Slinton putchar(')'); 4229676Slinton } 4239676Slinton putchar('\n'); 4249676Slinton switch (s->class) { 42518229Slinton case TYPE: 42618229Slinton printf("size\t%d\n", size(s)); 42718229Slinton break; 42818229Slinton 4299676Slinton case VAR: 4309676Slinton case REF: 4319676Slinton if (s->level >= 3) { 4329676Slinton printf("address\t0x%x\n", s->symvalue.offset); 4339676Slinton } else { 4349676Slinton printf("offset\t%d\n", s->symvalue.offset); 4359676Slinton } 43612545Scsvaf printf("size\t%d\n", size(s)); 4379676Slinton break; 4389676Slinton 4399676Slinton case RECORD: 4409676Slinton case VARNT: 4419676Slinton printf("size\t%d\n", s->symvalue.offset); 4429676Slinton break; 4439676Slinton 4449676Slinton case FIELD: 4459676Slinton printf("offset\t%d\n", s->symvalue.field.offset); 4469676Slinton printf("size\t%d\n", s->symvalue.field.length); 4479676Slinton break; 4489676Slinton 44914381Slinton case PROG: 4509676Slinton case PROC: 4519676Slinton case FUNC: 4529676Slinton printf("address\t0x%x\n", s->symvalue.funcv.beginaddr); 45314438Slinton if (isinline(s)) { 45414440Slinton printf("inline procedure\n"); 45514438Slinton } 45611863Slinton if (nosource(s)) { 45711863Slinton printf("does not have source information\n"); 45811863Slinton } else { 45911863Slinton printf("has source information\n"); 46011863Slinton } 4619676Slinton break; 4629676Slinton 4639676Slinton case RANGE: 46414381Slinton prangetype(s->symvalue.rangev.lowertype); 4659676Slinton printf("lower\t%d\n", s->symvalue.rangev.lower); 46614381Slinton prangetype(s->symvalue.rangev.uppertype); 4679676Slinton printf("upper\t%d\n", s->symvalue.rangev.upper); 4689676Slinton break; 4699676Slinton 4709676Slinton default: 4719676Slinton /* do nothing */ 4729676Slinton break; 4739676Slinton } 4749676Slinton } 4759676Slinton 47614381Slinton private prangetype(r) 47714381Slinton Rangetype r; 47814381Slinton { 47914381Slinton switch (r) { 48014381Slinton case R_CONST: 48114381Slinton printf("CONST"); 48214381Slinton break; 48314381Slinton 48414381Slinton case R_ARG: 48514381Slinton printf("ARG"); 48614381Slinton break; 48714381Slinton 48814381Slinton case R_TEMP: 48914381Slinton printf("TEMP"); 49014381Slinton break; 49114381Slinton 49214381Slinton case R_ADJUST: 49314381Slinton printf("ADJUST"); 49414381Slinton break; 49514381Slinton } 49614381Slinton } 49714381Slinton 4989676Slinton /* 4999676Slinton * Print out the value on top of the stack according to the given type. 5009676Slinton */ 5019676Slinton 5029676Slinton public printval(t) 5039676Slinton Symbol t; 5049676Slinton { 5059676Slinton Symbol s; 5069676Slinton 5079676Slinton checkref(t); 50816616Ssam if (t->class == TYPEREF) { 50916616Ssam resolveRef(t); 51016616Ssam } 5119676Slinton switch (t->class) { 5129676Slinton case PROC: 5139676Slinton case FUNC: 5149676Slinton s = pop(Symbol); 5159676Slinton printf("%s", symname(s)); 5169676Slinton break; 5179676Slinton 5189676Slinton default: 51918229Slinton if (t->language == nil or t->language == primlang) { 52026478Ssam (*language_op(findlanguage(".c"), L_PRINTVAL))(t); 5219676Slinton } else { 5229676Slinton (*language_op(t->language, L_PRINTVAL))(t); 5239676Slinton } 5249676Slinton break; 5259676Slinton } 5269676Slinton } 5279676Slinton 5289676Slinton /* 5299676Slinton * Print out the value of a record, field by field. 5309676Slinton */ 5319676Slinton 5329676Slinton public printrecord(s) 5339676Slinton Symbol s; 5349676Slinton { 53516616Ssam Symbol f; 53616616Ssam 5379676Slinton if (s->chain == nil) { 5389676Slinton error("record has no fields"); 5399676Slinton } 5409676Slinton printf("("); 5419676Slinton sp -= size(s); 54216616Ssam f = s->chain; 54316616Ssam if (f != nil) { 54416616Ssam for (;;) { 54516616Ssam printfield(f); 54616616Ssam f = f->chain; 54716616Ssam if (f == nil) break; 54816616Ssam printf(", "); 54916616Ssam } 55016616Ssam } 5519676Slinton printf(")"); 5529676Slinton } 5539676Slinton 5549676Slinton /* 55516616Ssam * Print out a field. 5569676Slinton */ 5579676Slinton 55816616Ssam private printfield(f) 55916616Ssam Symbol f; 5609676Slinton { 5619676Slinton Stack *savesp; 56216616Ssam register int off, len; 5639676Slinton 56416616Ssam printf("%s = ", symname(f)); 5659676Slinton savesp = sp; 56616616Ssam off = f->symvalue.field.offset; 56716616Ssam len = f->symvalue.field.length; 56816616Ssam sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE); 56916616Ssam printval(f); 5709676Slinton sp = savesp; 5719676Slinton } 5729676Slinton 5739676Slinton /* 5749676Slinton * Print out the contents of an array. 5759676Slinton * Haven't quite figured out what the best format is. 5769676Slinton * 5779676Slinton * This is rather inefficient. 5789676Slinton * 5799676Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 5809676Slinton */ 5819676Slinton 5829676Slinton public printarray(a) 5839676Slinton Symbol a; 5849676Slinton { 5859676Slinton Stack *savesp, *newsp; 5869676Slinton Symbol eltype; 5879676Slinton long elsize; 5889676Slinton String sep; 5899676Slinton 5909676Slinton savesp = sp; 59112544Scsvaf sp -= (size(a)); 5929676Slinton newsp = sp; 5939676Slinton eltype = rtype(a->type); 5949676Slinton elsize = size(eltype); 5959676Slinton printf("("); 5969676Slinton if (eltype->class == RECORD or eltype->class == ARRAY or 5979676Slinton eltype->class == VARNT) { 5989676Slinton sep = "\n"; 5999676Slinton putchar('\n'); 6009676Slinton } else { 6019676Slinton sep = ", "; 6029676Slinton } 6039676Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 6049676Slinton if (sp - elsize != newsp) { 6059676Slinton fputs(sep, stdout); 6069676Slinton } 6079676Slinton printval(eltype); 6089676Slinton } 6099676Slinton sp = newsp; 6109676Slinton if (streq(sep, "\n")) { 6119676Slinton putchar('\n'); 6129676Slinton } 6139676Slinton printf(")"); 6149676Slinton } 6159676Slinton 6169676Slinton /* 6179676Slinton * Print out the value of a real number in Pascal notation. 6189676Slinton * This is, unfortunately, different than what one gets 6199676Slinton * from "%g" in printf. 6209676Slinton */ 6219676Slinton 6229676Slinton public prtreal(r) 6239676Slinton double r; 6249676Slinton { 6259676Slinton extern char *index(); 6269676Slinton char buf[256]; 6279676Slinton 6289676Slinton sprintf(buf, "%g", r); 6299676Slinton if (buf[0] == '.') { 6309676Slinton printf("0%s", buf); 6319676Slinton } else if (buf[0] == '-' and buf[1] == '.') { 6329676Slinton printf("-0%s", &buf[1]); 6339676Slinton } else { 6349676Slinton printf("%s", buf); 6359676Slinton } 6369676Slinton if (index(buf, '.') == nil) { 6379676Slinton printf(".0"); 6389676Slinton } 6399676Slinton } 6409676Slinton 6419676Slinton /* 6429676Slinton * Print out a character using ^? notation for unprintables. 6439676Slinton */ 6449676Slinton 6459676Slinton public printchar(c) 6469676Slinton char c; 6479676Slinton { 6489676Slinton if (c == 0) { 6499676Slinton putchar('\\'); 6509676Slinton putchar('0'); 6519676Slinton } else if (c == '\n') { 6529676Slinton putchar('\\'); 6539676Slinton putchar('n'); 6549676Slinton } else if (c > 0 and c < ' ') { 6559676Slinton putchar('^'); 6569676Slinton putchar(c - 1 + 'A'); 65716616Ssam } else if (c >= ' ' && c <= '~') { 65816616Ssam putchar(c); 6599676Slinton } else { 660*29820Ssam printf("\\0%o",c&0xff); 6619676Slinton } 6629676Slinton } 66318229Slinton 66418229Slinton /* 66518229Slinton * Print out a value for a range type (integer, char, or boolean). 66618229Slinton */ 66718229Slinton 66818229Slinton public printRangeVal (val, t) 66918229Slinton long val; 67018229Slinton Symbol t; 67118229Slinton { 67218229Slinton if (t == t_boolean->type or istypename(t->type, "boolean")) { 67318229Slinton if ((boolean) val) { 67418229Slinton printf("true"); 67518229Slinton } else { 67618229Slinton printf("false"); 67718229Slinton } 67818229Slinton } else if (t == t_char->type or istypename(t->type, "char")) { 67918229Slinton if (varIsSet("$hexchars")) { 68018229Slinton printf("0x%lx", val); 68118229Slinton } else { 68218229Slinton putchar('\''); 68318229Slinton printchar(val); 68418229Slinton putchar('\''); 68518229Slinton } 68618229Slinton } else if (varIsSet("$hexints")) { 68718229Slinton printf("0x%lx", val); 68818229Slinton } else if (t->symvalue.rangev.lower >= 0) { 68918229Slinton printf("%lu", val); 69018229Slinton } else { 69118229Slinton printf("%ld", val); 69218229Slinton } 69318229Slinton } 69418229Slinton 69518229Slinton /* 69618229Slinton * Print out an enumerated value by finding the corresponding 69718229Slinton * name in the enumeration list. 69818229Slinton */ 69918229Slinton 70018229Slinton public printEnum (i, t) 70118229Slinton integer i; 70218229Slinton Symbol t; 70318229Slinton { 70418229Slinton register Symbol e; 70518229Slinton 70618229Slinton e = t->chain; 70718229Slinton while (e != nil and e->symvalue.constval->value.lcon != i) { 70818229Slinton e = e->chain; 70918229Slinton } 71018229Slinton if (e != nil) { 71118229Slinton printf("%s", symname(e)); 71218229Slinton } else { 71318229Slinton printf("%d", i); 71418229Slinton } 71518229Slinton } 71618229Slinton 71718229Slinton /* 71818229Slinton * Print out a null-terminated string (pointer to char) 71918229Slinton * starting at the given address. 72018229Slinton */ 72118229Slinton 72218229Slinton public printString (addr, quotes) 72318229Slinton Address addr; 72418229Slinton boolean quotes; 72518229Slinton { 72618229Slinton register Address a; 72718229Slinton register integer i, len; 72818229Slinton register boolean endofstring; 729*29820Ssam register int unprintables; 730*29820Ssam #define MAXGARBAGE 4 73118229Slinton union { 73218229Slinton char ch[sizeof(Word)]; 73318229Slinton int word; 73418229Slinton } u; 73518229Slinton 73618229Slinton if (varIsSet("$hexstrings")) { 73718229Slinton printf("0x%x", addr); 73818229Slinton } else { 73918229Slinton if (quotes) { 74018229Slinton putchar('"'); 74118229Slinton } 74218229Slinton a = addr; 743*29820Ssam unprintables = 0; 74418229Slinton endofstring = false; 74518229Slinton while (not endofstring) { 74618229Slinton dread(&u, a, sizeof(u)); 74718229Slinton i = 0; 74818229Slinton do { 74918229Slinton if (u.ch[i] == '\0') { 75018229Slinton endofstring = true; 75118229Slinton } else { 75218229Slinton printchar(u.ch[i]); 753*29820Ssam if (!isascii(u.ch[i]) and ++unprintables > MAXGARBAGE) { 754*29820Ssam endofstring = true; 755*29820Ssam printf("..."); 756*29820Ssam } 75718229Slinton } 75818229Slinton ++i; 75918229Slinton } while (i < sizeof(Word) and not endofstring); 76018229Slinton a += sizeof(Word); 76118229Slinton } 76218229Slinton if (quotes) { 76318229Slinton putchar('"'); 76418229Slinton } 76518229Slinton } 76618229Slinton } 767