Annotation of 42BSD/ucb/dbx/printsym.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1982 Regents of the University of California */
                      2: 
                      3: static char sccsid[] = "@(#)printsym.c 1.12 8/10/83";
                      4: 
                      5: /*
                      6:  * Printing of symbolic information.
                      7:  */
                      8: 
                      9: #include "defs.h"
                     10: #include "symbols.h"
                     11: #include "languages.h"
                     12: #include "printsym.h"
                     13: #include "tree.h"
                     14: #include "eval.h"
                     15: #include "mappings.h"
                     16: #include "process.h"
                     17: #include "runtime.h"
                     18: #include "machine.h"
                     19: #include "names.h"
                     20: #include "main.h"
                     21: 
                     22: #ifndef public
                     23: #endif
                     24: 
                     25: /*
                     26:  * Maximum number of arguments to a function.
                     27:  * This is used as a check for the possibility that the stack has been
                     28:  * overwritten and therefore a saved argument pointer might indicate
                     29:  * to an absurdly large number of arguments.
                     30:  */
                     31: 
                     32: #define MAXARGSPASSED 20
                     33: 
                     34: /*
                     35:  * Return a pointer to the string for the name of the class that
                     36:  * the given symbol belongs to.
                     37:  */
                     38: 
                     39: private String clname[] = {
                     40:     "bad use", "constant", "type", "variable", "array", "fileptr",
                     41:     "record", "field", "procedure", "function", "funcvar",
                     42:     "ref", "pointer", "file", "set", "range", "label", "withptr",
                     43:     "scalar", "string", "program", "improper", "variant",
                     44:     "procparam", "funcparam", "module", "tag", "common", "typeref"
                     45: };
                     46: 
                     47: public String classname(s)
                     48: Symbol s;
                     49: {
                     50:     return clname[ord(s->class)];
                     51: }
                     52: 
                     53: /*
                     54:  * Note the entry of the given block, unless it's the main program.
                     55:  */
                     56: 
                     57: public printentry(s)
                     58: Symbol s;
                     59: {
                     60:     if (s != program) {
                     61:        printf("\nentering %s %s\n", classname(s), symname(s));
                     62:     }
                     63: }
                     64: 
                     65: /*
                     66:  * Note the exit of the given block
                     67:  */
                     68: 
                     69: public printexit(s)
                     70: Symbol s;
                     71: {
                     72:     if (s != program) {
                     73:        printf("leaving %s %s\n\n", classname(s), symname(s));
                     74:     }
                     75: }
                     76: 
                     77: /*
                     78:  * Note the call of s from t.
                     79:  */
                     80: 
                     81: public printcall(s, t)
                     82: Symbol s, t;
                     83: {
                     84:     printf("calling %s", symname(s));
                     85:     printparams(s, nil);
                     86:     printf(" from %s %s\n", classname(t), symname(t));
                     87: }
                     88: 
                     89: /*
                     90:  * Note the return from s.  If s is a function, print the value
                     91:  * it is returning.  This is somewhat painful, since the function
                     92:  * has actually just returned.
                     93:  */
                     94: 
                     95: public printrtn(s)
                     96: Symbol s;
                     97: {
                     98:     register Symbol t;
                     99:     register int len;
                    100:     Boolean isindirect;
                    101: 
                    102:     printf("returning ");
                    103:     if (s->class == FUNC && (!istypename(s->type,"void"))) {
                    104:        len = size(s->type);
                    105:        if (canpush(len)) {
                    106:            t = rtype(s->type);
                    107:            isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
                    108:            pushretval(len, isindirect);
                    109:            printval(s->type);
                    110:            putchar(' ');
                    111:        } else {
                    112:            printf("(value too large) ");
                    113:        }
                    114:     }
                    115:     printf("from %s\n", symname(s));
                    116: }
                    117: 
                    118: /*
                    119:  * Print the values of the parameters of the given procedure or function.
                    120:  * The frame distinguishes recursive instances of a procedure.
                    121:  */
                    122: 
                    123: public printparams(f, frame)
                    124: Symbol f;
                    125: Frame frame;
                    126: {
                    127:     Symbol param;
                    128:     int n, m, s;
                    129: 
                    130:     n = nargspassed(frame);
                    131:     param = f->chain;
                    132:     if (param != nil or n > 0) {
                    133:        printf("(");
                    134:        m = n;
                    135:        if (param != nil) {
                    136:            for (;;) {
                    137:                s = size(param) div sizeof(Word);
                    138:                if (s == 0) {
                    139:                    s = 1;
                    140:                }
                    141:                m -= s;
                    142:                printv(param, frame);
                    143:                param = param->chain;
                    144:            if (param == nil) break;
                    145:                printf(", ");
                    146:            }
                    147:        }
                    148:        if (m > 0) {
                    149:            if (m > MAXARGSPASSED) {
                    150:                m = MAXARGSPASSED;
                    151:            }
                    152:            if (f->chain != nil) {
                    153:                printf(", ");
                    154:            }
                    155:            for (;;) {
                    156:                --m;
                    157:                printf("0x%x", argn(n - m, frame));
                    158:            if (m <= 0) break;
                    159:                printf(", ");
                    160:            }
                    161:        }
                    162:        printf(")");
                    163:     }
                    164: }
                    165: 
                    166: /*
                    167:  * Test if a symbol should be printed.  We don't print files,
                    168:  * for example, simply because there's no good way to do it.
                    169:  * The symbol must be within the given function.
                    170:  */
                    171: 
                    172: public Boolean should_print(s)
                    173: Symbol s;
                    174: {
                    175:     Boolean b;
                    176:     register Symbol t;
                    177: 
                    178:     switch (s->class) {
                    179:        case VAR:
                    180:        case FVAR:
                    181:            if (isparam(s)) {
                    182:                b = false;
                    183:            } else {
                    184:                t = rtype(s->type);
                    185:                if (t == nil) {
                    186:                    b = false;
                    187:                } else {
                    188:                    switch (t->class) {
                    189:                        case FILET:
                    190:                        case SET:
                    191:                        case BADUSE:
                    192:                            b = false;
                    193:                            break;
                    194: 
                    195:                        default:
                    196:                            b = true;
                    197:                            break;
                    198:                    }
                    199:                }
                    200:            }
                    201:            break;
                    202: 
                    203:        default:
                    204:            b = false;
                    205:            break;
                    206:     }
                    207:     return b;
                    208: }
                    209: 
                    210: /*
                    211:  * Print the name and value of a variable.
                    212:  */
                    213: 
                    214: public printv(s, frame)
                    215: Symbol s;
                    216: Frame frame;
                    217: {
                    218:     Address addr;
                    219:     int len;
                    220: 
                    221:     if (isambiguous(s) and ismodule(container(s))) {
                    222:        printname(stdout, s);
                    223:        printf(" = ");
                    224:     } else {
                    225:        printf("%s = ", symname(s));
                    226:     }
                    227:     if(s->type->class == ARRAY && (! istypename(s->type->type,"char")) ) {
                    228:        printf(" ARRAY ");
                    229:     } else {
                    230:        if (isvarparam(s)) {
                    231:           rpush(address(s, frame), sizeof(Address));
                    232:           addr = pop(Address);
                    233:           len = size(s->type);
                    234:        } else {
                    235:           addr = address(s, frame);
                    236:           len = size(s);
                    237:        }
                    238:        if (canpush(len)) {
                    239:           rpush(addr, len);
                    240:           printval(s->type);
                    241:        } else {
                    242:           printf("*** expression too large ***");
                    243:        }
                    244:    }
                    245: }
                    246: 
                    247: /*
                    248:  * Print out the name of a symbol.
                    249:  */
                    250: 
                    251: public printname(f, s)
                    252: File f;
                    253: Symbol s;
                    254: {
                    255:     if (s == nil) {
                    256:        fprintf(f, "(noname)");
                    257:     } else if (isredirected() or isambiguous(s)) {
                    258:        printwhich(f, s);
                    259:     } else {
                    260:        fprintf(f, "%s", symname(s));
                    261:     }
                    262: }
                    263: 
                    264: /*
                    265:  * Print the fully specified variable that is described by the given identifer.
                    266:  */
                    267: 
                    268: public printwhich(f, s)
                    269: File f;
                    270: Symbol s;
                    271: {
                    272:     printouter(f, container(s));
                    273:     fprintf(f, "%s", symname(s));
                    274: }
                    275: 
                    276: /*
                    277:  * Print the fully qualified name of each symbol that has the same name
                    278:  * as the given symbol.
                    279:  */
                    280: 
                    281: public printwhereis(f, s)
                    282: File f;
                    283: Symbol s;
                    284: {
                    285:     register Name n;
                    286:     register Symbol t;
                    287: 
                    288:     checkref(s);
                    289:     n = s->name;
                    290:     t = lookup(n);
                    291:     printwhich(f, t);
                    292:     t = t->next_sym;
                    293:     while (t != nil) {
                    294:        if (t->name == n) {
                    295:            putc(' ', f);
                    296:            printwhich(f, t);
                    297:        }
                    298:        t = t->next_sym;
                    299:     }
                    300:     putc('\n', f);
                    301: }
                    302: 
                    303: private printouter(f, s)
                    304: File f;
                    305: Symbol s;
                    306: {
                    307:     Symbol outer;
                    308: 
                    309:     if (s != nil) {
                    310:        outer = container(s);
                    311:        if (outer != nil and outer != program) {
                    312:            printouter(f, outer);
                    313:        }
                    314:        fprintf(f, "%s.", symname(s));
                    315:     }
                    316: }
                    317: 
                    318: public printdecl(s)
                    319: Symbol s;
                    320: {
                    321:     checkref(s);
                    322:     (*language_op(s->language, L_PRINTDECL))(s);
                    323: }
                    324: 
                    325: /*
                    326:  * Straight dump of symbol information.
                    327:  */
                    328: 
                    329: public psym(s)
                    330: Symbol s;
                    331: {
                    332:     printf("name\t%s\n", symname(s));
                    333:     printf("lang\t%s\n", language_name(s->language));
                    334:     printf("level\t%d\n", s->level);
                    335:     printf("class\t%s\n", classname(s));
                    336:     printf("type\t0x%x", s->type);
                    337:     if (s->type != nil and s->type->name != nil) {
                    338:        printf(" (%s)", symname(s->type));
                    339:     }
                    340:     printf("\nchain\t0x%x", s->chain);
                    341:     if (s->chain != nil and s->chain->name != nil) {
                    342:        printf(" (%s)", symname(s->chain));
                    343:     }
                    344:     printf("\nblock\t0x%x", s->block);
                    345:     if (s->block->name != nil) {
                    346:        printf(" (");
                    347:        printname(stdout, s->block);
                    348:        putchar(')');
                    349:     }
                    350:     putchar('\n');
                    351:     switch (s->class) {
                    352:        case VAR:
                    353:        case REF:
                    354:            if (s->level >= 3) {
                    355:                printf("address\t0x%x\n", s->symvalue.offset);
                    356:            } else {
                    357:                printf("offset\t%d\n", s->symvalue.offset);
                    358:            }
                    359:            printf("size\t%d\n", size(s));
                    360:            break;
                    361: 
                    362:        case RECORD:
                    363:        case VARNT:
                    364:            printf("size\t%d\n", s->symvalue.offset);
                    365:            break;
                    366: 
                    367:        case FIELD:
                    368:            printf("offset\t%d\n", s->symvalue.field.offset);
                    369:            printf("size\t%d\n", s->symvalue.field.length);
                    370:            break;
                    371: 
                    372:        case PROG:
                    373:        case PROC:
                    374:        case FUNC:
                    375:            printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
                    376:            if (isinline(s)) {
                    377:                printf("inline procedure\n");
                    378:            }
                    379:            if (nosource(s)) {
                    380:                printf("does not have source information\n");
                    381:            } else {
                    382:                printf("has source information\n");
                    383:            }
                    384:            break;
                    385: 
                    386:        case RANGE:
                    387: 
                    388:            prangetype(s->symvalue.rangev.lowertype);
                    389:            printf("lower\t%d\n", s->symvalue.rangev.lower);
                    390:            prangetype(s->symvalue.rangev.uppertype);
                    391:            printf("upper\t%d\n", s->symvalue.rangev.upper);
                    392:            break;
                    393: 
                    394:        default:
                    395:            /* do nothing */
                    396:            break;
                    397:     }
                    398: }
                    399: 
                    400: private prangetype(r)
                    401: Rangetype r;
                    402: {
                    403:     switch (r) {
                    404:        case R_CONST:
                    405:            printf("CONST");
                    406:            break;
                    407: 
                    408:        case R_ARG:
                    409:            printf("ARG");
                    410:            break;
                    411: 
                    412:        case R_TEMP:
                    413:            printf("TEMP");
                    414:            break;
                    415: 
                    416:        case R_ADJUST:
                    417:            printf("ADJUST");
                    418:            break;
                    419:     }
                    420: }
                    421: 
                    422: /*
                    423:  * Print out the value on top of the stack according to the given type.
                    424:  */
                    425: 
                    426: public printval(t)
                    427: Symbol t;
                    428: {
                    429:     Symbol s;
                    430: 
                    431:     checkref(t);
                    432:     switch (t->class) {
                    433:        case PROC:
                    434:        case FUNC:
                    435:            s = pop(Symbol);
                    436:            printf("%s", symname(s));
                    437:            break;
                    438: 
                    439:        default:
                    440:            if (t->language == nil) {
                    441:                error("unknown language");
                    442:            } else {
                    443:                (*language_op(t->language, L_PRINTVAL))(t);
                    444:            }
                    445:            break;
                    446:     }
                    447: }
                    448: 
                    449: /*
                    450:  * Print out the value of a record, field by field.
                    451:  */
                    452: 
                    453: public printrecord(s)
                    454: Symbol s;
                    455: {
                    456:     if (s->chain == nil) {
                    457:        error("record has no fields");
                    458:     }
                    459:     printf("(");
                    460:     sp -= size(s);
                    461:     printfield(s->chain);
                    462:     printf(")");
                    463: }
                    464: 
                    465: /*
                    466:  * Print out a field, first printing out other fields.
                    467:  * This is done because the fields are chained together backwards.
                    468:  */
                    469: 
                    470: private printfield(s)
                    471: Symbol s;
                    472: {
                    473:     Stack *savesp;
                    474: 
                    475:     if (s->chain != nil) {
                    476:        printfield(s->chain);
                    477:        printf(", ");
                    478:     }
                    479:     printf("%s = ", symname(s));
                    480:     savesp = sp;
                    481:     sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type));
                    482:     printval(s);
                    483:     sp = savesp;
                    484: }
                    485: 
                    486: /*
                    487:  * Print out the contents of an array.
                    488:  * Haven't quite figured out what the best format is.
                    489:  *
                    490:  * This is rather inefficient.
                    491:  *
                    492:  * The "2*elsize" is there since "printval" drops the stack by elsize.
                    493:  */
                    494: 
                    495: public printarray(a)
                    496: Symbol a;
                    497: {
                    498:     Stack *savesp, *newsp;
                    499:     Symbol eltype;
                    500:     long elsize;
                    501:     String sep;
                    502: 
                    503:     savesp = sp;
                    504:     sp -= (size(a));
                    505:     newsp = sp;
                    506:     eltype = rtype(a->type);
                    507:     elsize = size(eltype);
                    508:     printf("(");
                    509:     if (eltype->class == RECORD or eltype->class == ARRAY or
                    510:       eltype->class == VARNT) {
                    511:        sep = "\n";
                    512:        putchar('\n');
                    513:     } else {
                    514:        sep = ", ";
                    515:     }
                    516:     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
                    517:        if (sp - elsize != newsp) {
                    518:            fputs(sep, stdout);
                    519:        }
                    520:        printval(eltype);
                    521:     }
                    522:     sp = newsp;
                    523:     if (streq(sep, "\n")) {
                    524:        putchar('\n');
                    525:     }
                    526:     printf(")");
                    527: }
                    528: 
                    529: /*
                    530:  * Print out the value of a real number in Pascal notation.
                    531:  * This is, unfortunately, different than what one gets
                    532:  * from "%g" in printf.
                    533:  */
                    534: 
                    535: public prtreal(r)
                    536: double r;
                    537: {
                    538:     extern char *index();
                    539:     char buf[256];
                    540: 
                    541:     sprintf(buf, "%g", r);
                    542:     if (buf[0] == '.') {
                    543:        printf("0%s", buf);
                    544:     } else if (buf[0] == '-' and buf[1] == '.') {
                    545:        printf("-0%s", &buf[1]);
                    546:     } else {
                    547:        printf("%s", buf);
                    548:     }
                    549:     if (index(buf, '.') == nil) {
                    550:        printf(".0");
                    551:     }
                    552: }
                    553: 
                    554: /*
                    555:  * Print out a character using ^? notation for unprintables.
                    556:  */
                    557: 
                    558: public printchar(c)
                    559: char c;
                    560: {
                    561:     if (c == 0) {
                    562:        putchar('\\');
                    563:        putchar('0');
                    564:     } else if (c == '\n') {
                    565:        putchar('\\');
                    566:        putchar('n');
                    567:     } else if (c > 0 and c < ' ') {
                    568:        putchar('^');
                    569:        putchar(c - 1 + 'A');
                    570:     } else {
                    571:        putchar(c);
                    572:     }
                    573: }

unix.superglobalmegacorp.com

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