Annotation of 43BSDReno/pgrm/dbx/printsym.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that: (1) source distributions retain this entire copyright
        !             7:  * notice and comment, and (2) distributions including binaries display
        !             8:  * the following acknowledgement:  ``This product includes software
        !             9:  * developed by the University of California, Berkeley and its contributors''
        !            10:  * in the documentation or other materials provided with the distribution
        !            11:  * and in all advertising materials mentioning features or use of this
        !            12:  * software. Neither the name of the University nor the names of its
        !            13:  * contributors may be used to endorse or promote products derived
        !            14:  * from this software without specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: static char sccsid[] = "@(#)printsym.c 5.7 (Berkeley) 6/1/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: /*
        !            25:  * Printing of symbolic information.
        !            26:  */
        !            27: 
        !            28: #include "defs.h"
        !            29: #include "symbols.h"
        !            30: #include "languages.h"
        !            31: #include "printsym.h"
        !            32: #include "tree.h"
        !            33: #include "eval.h"
        !            34: #include "mappings.h"
        !            35: #include "process.h"
        !            36: #include "runtime.h"
        !            37: #include "machine.h"
        !            38: #include "names.h"
        !            39: #include "keywords.h"
        !            40: #include "main.h"
        !            41: #include <ctype.h>
        !            42: 
        !            43: #ifndef public
        !            44: #endif
        !            45: 
        !            46: /*
        !            47:  * Maximum number of arguments to a function.
        !            48:  * This is used as a check for the possibility that the stack has been
        !            49:  * overwritten and therefore a saved argument pointer might indicate
        !            50:  * to an absurdly large number of arguments.
        !            51:  */
        !            52: 
        !            53: #define MAXARGSPASSED 20
        !            54: 
        !            55: /*
        !            56:  * Return a pointer to the string for the name of the class that
        !            57:  * the given symbol belongs to.
        !            58:  */
        !            59: 
        !            60: private String clname[] = {
        !            61:     "bad use", "constant", "type", "variable", "array", "array",
        !            62:     "dynarray", "subarray", "fileptr", "record", "field",
        !            63:     "procedure", "function", "funcvar",
        !            64:     "ref", "pointer", "file", "set", "range", "label", "withptr",
        !            65:     "scalar", "string", "program", "improper", "variant",
        !            66:     "procparam", "funcparam", "module", "tag", "common", "extref", "typeref"
        !            67: };
        !            68: 
        !            69: public String classname(s)
        !            70: Symbol s;
        !            71: {
        !            72:     return clname[ord(s->class)];
        !            73: }
        !            74: 
        !            75: /*
        !            76:  * Note the entry of the given block, unless it's the main program.
        !            77:  */
        !            78: 
        !            79: public printentry(s)
        !            80: Symbol s;
        !            81: {
        !            82:     if (s != program) {
        !            83:        printf("\nentering %s ", classname(s));
        !            84:        printname(stdout, s);
        !            85:        printf("\n");
        !            86:     }
        !            87: }
        !            88: 
        !            89: /*
        !            90:  * Note the exit of the given block
        !            91:  */
        !            92: 
        !            93: public printexit(s)
        !            94: Symbol s;
        !            95: {
        !            96:     if (s != program) {
        !            97:        printf("leaving %s ", classname(s));
        !            98:        printname(stdout, s);
        !            99:        printf("\n\n");
        !           100:     }
        !           101: }
        !           102: 
        !           103: /*
        !           104:  * Note the call of s from t.
        !           105:  */
        !           106: 
        !           107: public printcall(s, t)
        !           108: Symbol s, t;
        !           109: {
        !           110:     printf("calling ");
        !           111:     printname(stdout, s);
        !           112:     printparams(s, nil);
        !           113:     printf(" from %s ", classname(t));
        !           114:     printname(stdout, t);
        !           115:     printf("\n");
        !           116: }
        !           117: 
        !           118: /*
        !           119:  * Note the return from s.  If s is a function, print the value
        !           120:  * it is returning.  This is somewhat painful, since the function
        !           121:  * has actually just returned.
        !           122:  */
        !           123: 
        !           124: public printrtn(s)
        !           125: Symbol s;
        !           126: {
        !           127:     register Symbol t;
        !           128:     register int len;
        !           129:     Boolean isindirect;
        !           130: 
        !           131:     printf("returning ");
        !           132:     if (s->class == FUNC && (!istypename(s->type,"void"))) {
        !           133:        len = size(s->type);
        !           134:        if (canpush(len)) {
        !           135:            t = rtype(s->type);
        !           136:            isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
        !           137:            pushretval(len, isindirect);
        !           138:            printval(s->type);
        !           139:            putchar(' ');
        !           140:        } else {
        !           141:            printf("(value too large) ");
        !           142:        }
        !           143:     }
        !           144:     printf("from ");
        !           145:     printname(stdout, s);
        !           146:     printf("\n");
        !           147: }
        !           148: 
        !           149: /*
        !           150:  * Print the values of the parameters of the given procedure or function.
        !           151:  * The frame distinguishes recursive instances of a procedure.
        !           152:  *
        !           153:  * If the procedure or function is internal, the argument count is
        !           154:  * not valid so we ignore it.
        !           155:  */
        !           156: 
        !           157: public printparams(f, frame)
        !           158: Symbol f;
        !           159: Frame frame;
        !           160: {
        !           161:     Symbol param;
        !           162:     int n, m, s;
        !           163: 
        !           164:     n = nargspassed(frame);
        !           165:     if (isinternal(f)) {
        !           166:        n = 0;
        !           167:     }
        !           168:     printf("(");
        !           169:     param = f->chain;
        !           170:     if (param != nil or n > 0) {
        !           171:        m = n;
        !           172:        if (param != nil) {
        !           173:            for (;;) {
        !           174:                s = psize(param) div sizeof(Word);
        !           175:                if (s == 0) {
        !           176:                    s = 1;
        !           177:                }
        !           178:                m -= s;
        !           179:                if (showaggrs) {
        !           180:                    printv(param, frame);
        !           181:                } else {
        !           182:                    printparamv(param, frame);
        !           183:                }
        !           184:                param = param->chain;
        !           185:            if (param == nil) break;
        !           186:                printf(", ");
        !           187:            }
        !           188:        }
        !           189:        if (m > 0) {
        !           190:            if (m > MAXARGSPASSED) {
        !           191:                m = MAXARGSPASSED;
        !           192:            }
        !           193:            if (f->chain != nil) {
        !           194:                printf(", ");
        !           195:            }
        !           196:            for (;;) {
        !           197:                --m;
        !           198:                printf("0x%x", argn(n - m, frame));
        !           199:            if (m <= 0) break;
        !           200:                printf(", ");
        !           201:            }
        !           202:        }
        !           203:     }
        !           204:     printf(")");
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * Test if a symbol should be printed.  We don't print files,
        !           209:  * for example, simply because there's no good way to do it.
        !           210:  * The symbol must be within the given function.
        !           211:  */
        !           212: 
        !           213: public Boolean should_print(s)
        !           214: Symbol s;
        !           215: {
        !           216:     Boolean b;
        !           217:     register Symbol t;
        !           218: 
        !           219:     switch (s->class) {
        !           220:        case VAR:
        !           221:        case FVAR:
        !           222:            if (isparam(s)) {
        !           223:                b = false;
        !           224:            } else {
        !           225:                t = rtype(s->type);
        !           226:                if (t == nil) {
        !           227:                    b = false;
        !           228:                } else {
        !           229:                    switch (t->class) {
        !           230:                        case FILET:
        !           231:                        case SET:
        !           232:                        case BADUSE:
        !           233:                            b = false;
        !           234:                            break;
        !           235: 
        !           236:                        default:
        !           237:                            b = true;
        !           238:                            break;
        !           239:                    }
        !           240:                }
        !           241:            }
        !           242:            break;
        !           243: 
        !           244:        default:
        !           245:            b = false;
        !           246:            break;
        !           247:     }
        !           248:     return b;
        !           249: }
        !           250: 
        !           251: /*
        !           252:  * Print out a parameter value.
        !           253:  *
        !           254:  * Since this is intended to be printed on a single line with other information
        !           255:  * aggregate values are not printed.
        !           256:  */
        !           257: 
        !           258: public printparamv (p, frame)
        !           259: Symbol p;
        !           260: Frame frame;
        !           261: {
        !           262:     Symbol t;
        !           263: 
        !           264:     t = rtype(p->type);
        !           265:     switch (t->class) {
        !           266:        case ARRAY:
        !           267:        case OPENARRAY:
        !           268:        case DYNARRAY:
        !           269:        case SUBARRAY:
        !           270:            t = rtype(t->type);
        !           271:            if (compatible(t, t_char)) {
        !           272:                printv(p, frame);
        !           273:            } else {
        !           274:                printf("%s = (...)", symname(p));
        !           275:            }
        !           276:            break;
        !           277: 
        !           278:        case RECORD:
        !           279:            printf("%s = (...)", symname(p));
        !           280:            break;
        !           281: 
        !           282:        default:
        !           283:            printv(p, frame);
        !           284:            break;
        !           285:     }
        !           286: }
        !           287: 
        !           288: /*
        !           289:  * Print the name and value of a variable.
        !           290:  */
        !           291: 
        !           292: public printv(s, frame)
        !           293: Symbol s;
        !           294: Frame frame;
        !           295: {
        !           296:     Address addr;
        !           297:     int len;
        !           298: 
        !           299:     if (isambiguous(s) and ismodule(container(s))) {
        !           300:        printname(stdout, s);
        !           301:        printf(" = ");
        !           302:     } else {
        !           303:        printf("%s = ", symname(s));
        !           304:     }
        !           305:     if (isvarparam(s) and not isopenarray(s)) {
        !           306:        rpush(address(s, frame), sizeof(Address));
        !           307:        addr = pop(Address);
        !           308:     } else {
        !           309:        addr = address(s, frame);
        !           310:     }
        !           311:     len = size(s);
        !           312:     if (not canpush(len)) {
        !           313:        printf("*** expression too large ***");
        !           314:     } else if (isreg(s)) {
        !           315:        push(Address, addr);
        !           316:        printval(s->type);
        !           317:     } else {
        !           318:        rpush(addr, len);
        !           319:        printval(s->type);
        !           320:     }
        !           321: }
        !           322: 
        !           323: /*
        !           324:  * Print out the name of a symbol.
        !           325:  */
        !           326: 
        !           327: public printname(f, s)
        !           328: File f;
        !           329: Symbol s;
        !           330: {
        !           331:     if (s == nil) {
        !           332:        fprintf(f, "(noname)");
        !           333:     } else if (s == program) {
        !           334:        fprintf(f, ".");
        !           335:     } else if (isredirected() or isambiguous(s)) {
        !           336:        printwhich(f, s);
        !           337:     } else {
        !           338:        fprintf(f, "%s", symname(s));
        !           339:     }
        !           340: }
        !           341: 
        !           342: /*
        !           343:  * Print the fully specified variable that is described by the given identifer.
        !           344:  */
        !           345: 
        !           346: public printwhich(f, s)
        !           347: File f;
        !           348: Symbol s;
        !           349: {
        !           350:     printouter(f, container(s));
        !           351:     fprintf(f, "%s", symname(s));
        !           352: }
        !           353: 
        !           354: /*
        !           355:  * Print the fully qualified name of each symbol that has the same name
        !           356:  * as the given symbol.
        !           357:  */
        !           358: 
        !           359: public printwhereis(f, s)
        !           360: File f;
        !           361: Symbol s;
        !           362: {
        !           363:     register Name n;
        !           364:     register Symbol t;
        !           365: 
        !           366:     checkref(s);
        !           367:     n = s->name;
        !           368:     t = lookup(n);
        !           369:     printwhich(f, t);
        !           370:     t = t->next_sym;
        !           371:     while (t != nil) {
        !           372:        if (t->name == n) {
        !           373:            putc(' ', f);
        !           374:            printwhich(f, t);
        !           375:        }
        !           376:        t = t->next_sym;
        !           377:     }
        !           378:     putc('\n', f);
        !           379: }
        !           380: 
        !           381: private printouter(f, s)
        !           382: File f;
        !           383: Symbol s;
        !           384: {
        !           385:     Symbol outer;
        !           386: 
        !           387:     if (s != nil) {
        !           388:        outer = container(s);
        !           389:        if (outer != nil and outer != program) {
        !           390:            printouter(f, outer);
        !           391:        }
        !           392:        fprintf(f, "%s.", symname(s));
        !           393:     }
        !           394: }
        !           395: 
        !           396: public printdecl(s)
        !           397: Symbol s;
        !           398: {
        !           399:     Language lang;
        !           400: 
        !           401:     checkref(s);
        !           402:     if (s->language == nil or s->language == primlang) {
        !           403:        lang = findlanguage(".s");
        !           404:     } else {
        !           405:        lang = s->language;
        !           406:     }
        !           407:     (*language_op(lang, L_PRINTDECL))(s);
        !           408: }
        !           409: 
        !           410: /*
        !           411:  * Straight dump of symbol information.
        !           412:  */
        !           413: 
        !           414: public psym(s)
        !           415: Symbol s;
        !           416: {
        !           417:     printf("name\t%s\n", symname(s));
        !           418:     printf("lang\t%s\n", language_name(s->language));
        !           419:     printf("level\t%d\n", s->level);
        !           420:     printf("class\t%s\n", classname(s));
        !           421:     printf("type\t0x%x", s->type);
        !           422:     if (s->type != nil and s->type->name != nil) {
        !           423:        printf(" (%s)", symname(s->type));
        !           424:     }
        !           425:     printf("\nchain\t0x%x", s->chain);
        !           426:     if (s->chain != nil and s->chain->name != nil) {
        !           427:        printf(" (%s)", symname(s->chain));
        !           428:     }
        !           429:     printf("\nblock\t0x%x", s->block);
        !           430:     if (s->block != nil and s->block->name != nil) {
        !           431:        printf(" (");
        !           432:        printname(stdout, s->block);
        !           433:        putchar(')');
        !           434:     }
        !           435:     putchar('\n');
        !           436:     switch (s->class) {
        !           437:        case TYPE:
        !           438:            printf("size\t%d\n", size(s));
        !           439:            break;
        !           440: 
        !           441:        case VAR:
        !           442:        case REF:
        !           443:            switch (s->storage) {
        !           444:                case INREG:
        !           445:                    printf("reg\t%d\n", s->symvalue.offset);
        !           446:                    break;
        !           447: 
        !           448:                case STK:
        !           449:                    printf("offset\t%d\n", s->symvalue.offset);
        !           450:                    break;
        !           451: 
        !           452:                case EXT:
        !           453:                    printf("address\t0x%x\n", s->symvalue.offset);
        !           454:                    break;
        !           455:            }
        !           456:            printf("size\t%d\n", size(s));
        !           457:            break;
        !           458: 
        !           459:        case RECORD:
        !           460:        case VARNT:
        !           461:            printf("size\t%d\n", s->symvalue.offset);
        !           462:            break;
        !           463: 
        !           464:        case FIELD:
        !           465:            printf("offset\t%d\n", s->symvalue.field.offset);
        !           466:            printf("size\t%d\n", s->symvalue.field.length);
        !           467:            break;
        !           468: 
        !           469:        case PROG:
        !           470:        case PROC:
        !           471:        case FUNC:
        !           472:            printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
        !           473:            if (isinline(s)) {
        !           474:                printf("inline procedure\n");
        !           475:            }
        !           476:            if (nosource(s)) {
        !           477:                printf("does not have source information\n");
        !           478:            } else {
        !           479:                printf("has source information\n");
        !           480:            }
        !           481:            break;
        !           482: 
        !           483:        case RANGE:
        !           484:            prangetype(s->symvalue.rangev.lowertype);
        !           485:            printf("lower\t%d\n", s->symvalue.rangev.lower);
        !           486:            prangetype(s->symvalue.rangev.uppertype);
        !           487:            printf("upper\t%d\n", s->symvalue.rangev.upper);
        !           488:            break;
        !           489: 
        !           490:        default:
        !           491:            /* do nothing */
        !           492:            break;
        !           493:     }
        !           494: }
        !           495: 
        !           496: private prangetype(r)
        !           497: Rangetype r;
        !           498: {
        !           499:     switch (r) {
        !           500:        case R_CONST:
        !           501:            printf("CONST");
        !           502:            break;
        !           503: 
        !           504:        case R_ARG:
        !           505:            printf("ARG");
        !           506:            break;
        !           507: 
        !           508:        case R_TEMP:
        !           509:            printf("TEMP");
        !           510:            break;
        !           511: 
        !           512:        case R_ADJUST:
        !           513:            printf("ADJUST");
        !           514:            break;
        !           515:     }
        !           516: }
        !           517: 
        !           518: /*
        !           519:  * Print out the value on top of the stack according to the given type.
        !           520:  */
        !           521: 
        !           522: public printval(t)
        !           523: Symbol t;
        !           524: {
        !           525:     Symbol s;
        !           526: 
        !           527:     checkref(t);
        !           528:     if (t->class == TYPEREF) {
        !           529:        resolveRef(t);
        !           530:     }
        !           531:     switch (t->class) {
        !           532:        case PROC:
        !           533:        case FUNC:
        !           534:            s = pop(Symbol);
        !           535:            printf("%s", symname(s));
        !           536:            break;
        !           537: 
        !           538:        default:
        !           539:            if (t->language == nil or t->language == primlang) {
        !           540:                (*language_op(findlanguage(".c"), L_PRINTVAL))(t);
        !           541:            } else {
        !           542:                (*language_op(t->language, L_PRINTVAL))(t);
        !           543:            }
        !           544:            break;
        !           545:     }
        !           546: }
        !           547: 
        !           548: /*
        !           549:  * Print out the value of a record, field by field.
        !           550:  */
        !           551: 
        !           552: public printrecord(s)
        !           553: Symbol s;
        !           554: {
        !           555:     Symbol f;
        !           556: 
        !           557:     if (s->chain == nil) {
        !           558:        error("record has no fields");
        !           559:     }
        !           560:     printf("(");
        !           561:     sp -= size(s);
        !           562:     f = s->chain;
        !           563:     if (f != nil) {
        !           564:        for (;;) {
        !           565:            printfield(f);
        !           566:            f = f->chain;
        !           567:        if (f == nil) break;
        !           568:            printf(", ");
        !           569:        }
        !           570:     }
        !           571:     printf(")");
        !           572: }
        !           573: 
        !           574: /*
        !           575:  * Print out a field.
        !           576:  */
        !           577: 
        !           578: private printfield(f)
        !           579: Symbol f;
        !           580: {
        !           581:     Stack *savesp;
        !           582:     register int off, len;
        !           583: 
        !           584:     printf("%s = ", symname(f));
        !           585:     savesp = sp;
        !           586:     off = f->symvalue.field.offset;
        !           587:     len = f->symvalue.field.length;
        !           588:     sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE);
        !           589:     printval(f);
        !           590:     sp = savesp;
        !           591: }
        !           592: 
        !           593: /*
        !           594:  * Print out the contents of an array.
        !           595:  * Haven't quite figured out what the best format is.
        !           596:  *
        !           597:  * This is rather inefficient.
        !           598:  *
        !           599:  * The "2*elsize" is there since "printval" drops the stack by elsize.
        !           600:  */
        !           601: 
        !           602: public printarray(a)
        !           603: Symbol a;
        !           604: {
        !           605:     Stack *savesp, *newsp;
        !           606:     Symbol eltype;
        !           607:     long elsize;
        !           608:     String sep;
        !           609: 
        !           610:     savesp = sp;
        !           611:     sp -= (size(a));
        !           612:     newsp = sp;
        !           613:     eltype = rtype(a->type);
        !           614:     elsize = size(eltype);
        !           615:     printf("(");
        !           616:     if (eltype->class == RECORD or eltype->class == ARRAY or
        !           617:       eltype->class == VARNT) {
        !           618:        sep = "\n";
        !           619:        putchar('\n');
        !           620:     } else {
        !           621:        sep = ", ";
        !           622:     }
        !           623:     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
        !           624:        if (sp - elsize != newsp) {
        !           625:            fputs(sep, stdout);
        !           626:        }
        !           627:        printval(eltype);
        !           628:     }
        !           629:     sp = newsp;
        !           630:     if (streq(sep, "\n")) {
        !           631:        putchar('\n');
        !           632:     }
        !           633:     printf(")");
        !           634: }
        !           635: 
        !           636: /*
        !           637:  * Print out the value of a real number in Pascal notation.
        !           638:  * This is, unfortunately, different than what one gets
        !           639:  * from "%g" in printf.
        !           640:  */
        !           641: 
        !           642: public prtreal(r)
        !           643: double r;
        !           644: {
        !           645:     extern char *index();
        !           646:     char buf[256];
        !           647: 
        !           648: #   ifdef IRIS
        !           649:        sprintf(buf, "%lg", r);
        !           650: #   else
        !           651:        sprintf(buf, "%g", r);
        !           652: #   endif
        !           653:     if (buf[0] == '.') {
        !           654:        printf("0%s", buf);
        !           655:     } else if (buf[0] == '-' and buf[1] == '.') {
        !           656:        printf("-0%s", &buf[1]);
        !           657:     } else {
        !           658:        printf("%s", buf);
        !           659:     }
        !           660:     if (index(buf, '.') == nil) {
        !           661:        printf(".0");
        !           662:     }
        !           663: }
        !           664: 
        !           665: /*
        !           666:  * Print out a character using ^? notation for unprintables.
        !           667:  */
        !           668: 
        !           669: public printchar(c)
        !           670: char c;
        !           671: {
        !           672:     if (c == 0) {
        !           673:        putchar('\\');
        !           674:        putchar('0');
        !           675:     } else if (c == '\n') {
        !           676:        putchar('\\');
        !           677:        putchar('n');
        !           678:     } else if (c > 0 and c < ' ') {
        !           679:        putchar('^');
        !           680:        putchar(c - 1 + 'A');
        !           681:     } else if (c >= ' ' && c <= '~') {
        !           682:        putchar(c);
        !           683:     } else {
        !           684:        printf("\\0%o",c&0xff);
        !           685:     }
        !           686: }
        !           687: 
        !           688: /*
        !           689:  * Print out a value for a range type (integer, char, or boolean).
        !           690:  */
        !           691: 
        !           692: public printRangeVal (val, t)
        !           693: long val;
        !           694: Symbol t;
        !           695: {
        !           696:     if (t == t_boolean->type or istypename(t->type, "boolean")) {
        !           697:        if ((boolean) val) {
        !           698:            printf("true");
        !           699:        } else {
        !           700:            printf("false");
        !           701:        }
        !           702:     } else if (t == t_char->type or istypename(t->type, "char")) {
        !           703:        if (varIsSet("$hexchars")) {
        !           704:            printf("0x%lx", val);
        !           705:        } else {
        !           706:            putchar('\'');
        !           707:            printchar(val);
        !           708:            putchar('\'');
        !           709:        }
        !           710:     } else if (varIsSet("$hexints")) {
        !           711:        printf("0x%lx", val);
        !           712:     } else if (t->symvalue.rangev.lower >= 0) {
        !           713:        printf("%lu", val);
        !           714:     } else {
        !           715:        printf("%ld", val);
        !           716:     }
        !           717: }
        !           718: 
        !           719: /*
        !           720:  * Print out an enumerated value by finding the corresponding
        !           721:  * name in the enumeration list.
        !           722:  */
        !           723: 
        !           724: public printEnum (i, t)
        !           725: integer i;
        !           726: Symbol t;
        !           727: {
        !           728:     register Symbol e;
        !           729: 
        !           730:     e = t->chain;
        !           731:     while (e != nil and e->symvalue.constval->value.lcon != i) {
        !           732:        e = e->chain;
        !           733:     }
        !           734:     if (e != nil) {
        !           735:        printf("%s", symname(e));
        !           736:     } else {
        !           737:        printf("%d", i);
        !           738:     }
        !           739: }
        !           740: 
        !           741: /*
        !           742:  * Print out a null-terminated string (pointer to char)
        !           743:  * starting at the given address.
        !           744:  */
        !           745: 
        !           746: public printString (addr, quotes)
        !           747: Address addr;
        !           748: boolean quotes;
        !           749: {
        !           750:     register Address a;
        !           751:     register integer i, len;
        !           752:     register boolean endofstring;
        !           753:     register int unprintables;
        !           754: #define        MAXGARBAGE      4
        !           755:     union {
        !           756:        char ch[sizeof(Word)];
        !           757:        int word;
        !           758:     } u;
        !           759: 
        !           760:     if (varIsSet("$hexstrings")) {
        !           761:        printf("0x%x", addr);
        !           762:     } else {
        !           763:        if (quotes) {
        !           764:            putchar('"');
        !           765:        }
        !           766:        a = addr;
        !           767:        unprintables = 0;
        !           768:        endofstring = false;
        !           769:        while (not endofstring) {
        !           770:            dread(&u, a, sizeof(u));
        !           771:            i = 0;
        !           772:            do {
        !           773:                if (u.ch[i] == '\0') {
        !           774:                    endofstring = true;
        !           775:                } else {
        !           776:                    printchar(u.ch[i]);
        !           777:                    if (!isascii(u.ch[i]) and ++unprintables > MAXGARBAGE) {
        !           778:                        endofstring = true;
        !           779:                        printf("...");
        !           780:                    }
        !           781:                }
        !           782:                ++i;
        !           783:            } while (i < sizeof(Word) and not endofstring);
        !           784:            a += sizeof(Word);
        !           785:        }
        !           786:        if (quotes) {
        !           787:            putchar('"');
        !           788:        }
        !           789:     }
        !           790: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.