Annotation of 43BSD/ucb/dbx/printsym.c, revision 1.1

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

unix.superglobalmegacorp.com

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