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: }

Defined functions

prangetype defined in line 475; used 2 times
printEnum defined in line 699; used 5 times
printString defined in line 721; used 3 times
printcall defined in line 95; used 1 times
printchar defined in line 644; used 5 times
printdecl defined in line 383; never used
printentry defined in line 67; used 1 times
printexit defined in line 81; used 1 times
printfield defined in line 557; used 1 times
printouter defined in line 368; used 2 times
printparams defined in line 145; used 1 times
printparamv defined in line 246; used 1 times
printrecord defined in line 531; used 2 times
printrtn defined in line 112; used 1 times
printv defined in line 279; used 4 times
printwhereis defined in line 346; used 2 times
printwhich defined in line 333; used 5 times
psym defined in line 401; used 4 times
should_print defined in line 201; used 1 times

Defined variables

clname defined in line 48; used 1 times
  • in line 60
rcsid defined in line 11; never used
sccsid defined in line 8; never used

Defined macros

MAXARGSPASSED defined in line 41; used 2 times
Last modified: 1986-03-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1806
Valid CSS Valid XHTML 1.0 Strict