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

unix.superglobalmegacorp.com

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