1: #if !defined(lint) && defined(DOSCCS) 2: static char sccsid[] = "@(#)lpass2.c 1.6 (Berkeley) 2/21/86"; 3: #endif lint 4: 5: # include "macdefs.h" 6: # include "manifest.h" 7: # include "lmanifest.h" 8: 9: # define USED 01 10: # define VUSED 02 11: # define EUSED 04 12: # define RVAL 010 13: # define VARARGS 0100 14: 15: # define NSZ 1630 /* was 4096 */ 16: # define TYSZ 1150 /* was 3500 */ 17: # define FSZ 200 /* was 500 must be less than 256 */ 18: # define NTY 32 /* was 50 */ 19: 20: typedef struct sty STYPE; 21: struct sty { ATYPE t; STYPE *next; }; 22: 23: typedef struct sym { 24: #ifndef FLEXNAMES 25: char name[LCHNM]; 26: #else 27: char *name; 28: #endif 29: int decflag; 30: int fline; 31: STYPE symty; 32: unsigned char nargs; 33: unsigned char fno; 34: int use; 35: } STAB; 36: 37: STAB stab[NSZ]; 38: STAB *find(); 39: 40: STYPE tary[TYSZ]; 41: STYPE *tget(); 42: 43: char *fnm[FSZ]; 44: char *getstr(), *hash(); 45: 46: int tfree; /* used to allocate types */ 47: int ffree; /* used to save filenames */ 48: 49: struct ty atyp[NTY]; 50: /* r is where all the input ends up */ 51: union rec r; 52: 53: int hflag = 0; 54: int pflag = 0; 55: int xflag = 0; 56: int uflag = 1; 57: int ddddd = 0; 58: int zflag = 0; 59: int Pflag = 0; 60: 61: int cfno; /* current file number */ 62: 63: main( argc, argv ) char *argv[]; { 64: register char *p; 65: char ibuf[BUFSIZ], obuf[BUFSIZ]; 66: 67: /* first argument is intermediate file */ 68: /* second argument is - options */ 69: 70: for( ; argc>2 && argv[argc-1][0] == '-' ; --argc ){ 71: for( p=argv[argc-1]; *p; ++p ){ 72: switch( *p ){ 73: 74: case 'h': 75: hflag = 1; 76: break; 77: 78: case 'p': 79: pflag = 1; 80: break; 81: 82: case 'x': 83: xflag = 1; 84: break; 85: 86: case 'X': 87: ddddd = 1; 88: break; 89: 90: case 'u': 91: uflag = 0; 92: break; 93: 94: case 'z': 95: zflag = 1; 96: break; 97: 98: case 'P': 99: Pflag = 1; 100: break; 101: 102: } 103: } 104: } 105: 106: if( argc < 2 || !freopen( argv[1], "r", stdin ) ){ 107: error( "cannot open intermediate file" ); 108: exit( 1 ); 109: } 110: setbuf(stdin, ibuf); 111: setbuf(stdout, obuf); 112: if( Pflag ){ 113: pfile(); 114: return( 0 ); 115: } 116: mloop( LDI|LIB|LST ); 117: rewind( stdin ); 118: mloop( LDC|LDX ); 119: rewind( stdin ); 120: mloop( LRV|LUV|LUE|LUM ); 121: cleanup(); 122: return(0); 123: } 124: 125: mloop( m ){ 126: /* do the main loop */ 127: register STAB *q; 128: 129: while( lread(m) ){ 130: q = find(); 131: if( q->decflag ) chkcompat(q); 132: else setuse(q); 133: } 134: } 135: 136: lread(m){ /* read a line into r.l */ 137: 138: register n; 139: 140: for(;;) { 141: if( fread( (char *)&r, sizeof(r), 1, stdin ) <= 0 ) return(0); 142: if( r.l.decflag & LFN ){ 143: /* new filename */ 144: r.f.fn = getstr(); 145: if( Pflag ) return( 1 ); 146: setfno( r.f.fn ); 147: continue; 148: } 149: #ifdef FLEXNAMES 150: r.l.name = getstr(); 151: #endif 152: n = r.l.nargs; 153: if( n<0 ) n = -n; 154: if( n>=NTY ) error( "more than %d args?", n ); 155: fread( (char *)atyp, sizeof(ATYPE), n, stdin ); 156: if( ( r.l.decflag & m ) ) return( 1 ); 157: } 158: } 159: 160: setfno( s ) char *s; { 161: /* look up current file names */ 162: /* first, strip backwards to the beginning or to the first / */ 163: int i; 164: 165: /* now look up s */ 166: for( i=0; i<ffree; ++i ){ 167: if (fnm[i] == s) 168: { 169: cfno = i; 170: return; 171: } 172: } 173: /* make a new entry */ 174: if( ffree >= FSZ ) error( "more than %d files", FSZ ); 175: fnm[ffree] = s; 176: cfno = ffree++; 177: } 178: 179: /* VARARGS */ 180: error( s, a ) char *s; { 181: 182: fprintf( stderr, "pass 2 error:(file %s) ", fnm[cfno] ); 183: fprintf( stderr, s, a ); 184: fprintf( stderr, "\n" ); 185: exit(1); 186: } 187: 188: STAB * 189: find(){ 190: register h=0; 191: #ifndef FLEXNAMES 192: h = hashstr(r.l.name, LCHNM) % NSZ; 193: #else 194: h = (unsigned int)r.l.name % NSZ; 195: #endif 196: { register STAB *p, *q; 197: for( p=q= &stab[h]; q->decflag; ){ 198: #ifndef FLEXNAMES 199: if( !strncmp( r.l.name, q->name, LCHNM)) 200: #else 201: if (r.l.name == q->name) 202: #endif 203: if( ((q->decflag|r.l.decflag)&LST)==0 || q->fno==cfno ) 204: return(q); 205: if( ++q >= &stab[NSZ] ) q = stab; 206: if( q == p ) error( "too many names defined" ); 207: } 208: #ifndef FLEXNAMES 209: strncpy( q->name, r.l.name, LCHNM ); 210: #else 211: q->name = r.l.name; 212: #endif 213: return( q ); 214: } 215: } 216: 217: STYPE * 218: tget(){ 219: if( tfree >= TYSZ ){ 220: error( "too many types needed" ); 221: } 222: return( &tary[tfree++] ); 223: } 224: 225: chkcompat(q) STAB *q; { 226: /* are the types, etc. in r.l and q compatible */ 227: register int i; 228: STYPE *qq; 229: 230: setuse(q); 231: 232: /* argument check */ 233: 234: if( q->decflag & (LDI|LIB|LUV|LUE|LST) ){ 235: if( r.l.decflag & (LUV|LIB|LUE) ){ 236: if( q->nargs != r.l.nargs ){ 237: if( !(q->use&VARARGS) ){ 238: #ifndef FLEXNAMES 239: printf( "%.8s: variable # of args.", q->name ); 240: #else 241: printf( "%s: variable # of args.", q->name ); 242: #endif 243: viceversa(q); 244: } 245: if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs; 246: if( !(q->decflag & (LDI|LIB|LST) ) ) { 247: q->nargs = r.l.nargs; 248: q->use |= VARARGS; 249: } 250: } 251: for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next){ 252: if( chktype( &qq->t, &atyp[i] ) ){ 253: #ifndef FLEXNAMES 254: printf( "%.8s, arg. %d used inconsistently", 255: #else 256: printf( "%s, arg. %d used inconsistently", 257: #endif 258: q->name, i+1 ); 259: viceversa(q); 260: } 261: } 262: } 263: } 264: 265: if( (q->decflag&(LDI|LIB|LUV|LST)) && r.l.decflag==LUV ){ 266: if( chktype( &r.l.type, &q->symty.t ) ){ 267: #ifndef FLEXNAMES 268: printf( "%.8s value used inconsistently", q->name ); 269: #else 270: printf( "%s value used inconsistently", q->name ); 271: #endif 272: viceversa(q); 273: } 274: } 275: 276: /* check for multiple declaration */ 277: 278: if( (q->decflag&(LDI|LST)) && (r.l.decflag&(LDI|LIB|LST)) ){ 279: #ifndef FLEXNAMES 280: printf( "%.8s multiply declared", q->name ); 281: #else 282: printf( "%s multiply declared", q->name ); 283: #endif 284: viceversa(q); 285: } 286: 287: /* do a bit of checking of definitions and uses... */ 288: 289: if( (q->decflag & (LDI|LIB|LDX|LDC|LUM|LST)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){ 290: #ifndef FLEXNAMES 291: printf( "%.8s value declared inconsistently", q->name ); 292: #else 293: printf( "%s value declared inconsistently", q->name ); 294: #endif 295: viceversa(q); 296: } 297: 298: /* better not call functions which are declared to be structure or union returning */ 299: 300: if( (q->decflag & (LDI|LIB|LDX|LDC|LST)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){ 301: /* only matters if the function returns union or structure */ 302: TWORD ty; 303: ty = q->symty.t.aty; 304: if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){ 305: #ifndef FLEXNAMES 306: printf( "%.8s function value type must be declared before use", q->name ); 307: #else 308: printf( "%s function value type must be declared before use", q->name ); 309: #endif 310: viceversa(q); 311: } 312: } 313: 314: if( pflag && q->decflag==LDX && r.l.decflag == LUM && !ISFTN(q->symty.t.aty) ){ 315: /* make the external declaration go away */ 316: /* in effect, it was used without being defined */ 317: } 318: } 319: 320: viceversa(q) STAB *q; { 321: /* print out file comparison */ 322: 323: printf( " %s(%d) :: %s(%d)\n", 324: fnm[q->fno], q->fline, 325: fnm[cfno], r.l.fline ); 326: } 327: 328: /* messages for defintion/use */ 329: char * 330: mess[2][2] ={ 331: "", 332: #ifndef FLEXNAMES 333: "%.8s used( %s(%d) ), but not defined\n", 334: "%.8s defined( %s(%d) ), but never used\n", 335: "%.8s declared( %s(%d) ), but never used or defined\n" 336: #else 337: "%s used( %s(%d) ), but not defined\n", 338: "%s defined( %s(%d) ), but never used\n", 339: "%s declared( %s(%d) ), but never used or defined\n" 340: #endif 341: }; 342: 343: lastone(q) STAB *q; { 344: 345: register nu, nd, uses; 346: 347: if( ddddd ) pst(q); 348: 349: nu = nd = 0; 350: uses = q->use; 351: 352: if( !(uses&USED) && q->decflag != LIB ) { 353: #ifndef FLEXNAMES 354: if( strncmp(q->name,"main",7) ) 355: #else 356: if (strcmp(q->name, "main")) 357: #endif 358: nu = 1; 359: } 360: 361: if( !ISFTN(q->symty.t.aty) ){ 362: switch( q->decflag ){ 363: 364: case LIB: 365: nu = nd = 0; /* don't complain about uses on libraries */ 366: break; 367: case LDX: 368: if( !xflag ) break; 369: case LUV: 370: case LUE: 371: /* 01/04/80 */ case LUV | LUE: 372: case LUM: 373: nd = 1; 374: } 375: } 376: if( uflag && ( nu || nd ) ) 377: printf( mess[nu][nd], q->name, fnm[q->fno], q->fline ); 378: 379: if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){ 380: /* if functions is static, then print the file name too */ 381: if( q->decflag & LST ) 382: printf( "%s(%d):", fnm[q->fno], q->fline ); 383: #ifndef FLEXNAMES 384: printf( "%.8s returns value which is %s ignored\n", 385: q->name, uses&VUSED ? "sometimes" : "always" ); 386: #else 387: printf( "%s returns value which is %s ignored\n", 388: q->name, uses&VUSED ? "sometimes" : "always" ); 389: #endif 390: } 391: 392: if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB|LST)) ){ 393: if( q->decflag & LST ) 394: printf( "%s(%d):", fnm[q->fno], q->fline ); 395: #ifndef FLEXNAMES 396: printf( "%.8s value is used, but none returned\n", q->name); 397: #else 398: printf( "%s value is used, but none returned\n", q->name); 399: #endif 400: } 401: } 402: 403: cleanup(){ /* call lastone and die gracefully */ 404: STAB *q; 405: for( q=stab; q< &stab[NSZ]; ++q ){ 406: if( q->decflag ) lastone(q); 407: } 408: exit(0); 409: } 410: 411: setuse(q) register STAB *q; { /* check new type to ensure that it is used */ 412: 413: if( !q->decflag ){ /* new one */ 414: q->decflag = r.l.decflag; 415: q->symty.t = r.l.type; 416: if( r.l.nargs < 0 ){ 417: q->nargs = -r.l.nargs; 418: q->use = VARARGS; 419: } 420: else { 421: q->nargs = r.l.nargs; 422: q->use = 0; 423: } 424: q->fline = r.l.fline; 425: q->fno = cfno; 426: if( q->nargs ){ 427: int i; 428: STYPE *qq; 429: for( i=0,qq= &q->symty; i<q->nargs; ++i,qq=qq->next ){ 430: qq->next = tget(); 431: qq->next->t = atyp[i]; 432: } 433: } 434: } 435: 436: switch( r.l.decflag ){ 437: 438: case LRV: 439: q->use |= RVAL; 440: return; 441: case LUV: 442: q->use |= VUSED+USED; 443: return; 444: case LUE: 445: q->use |= EUSED+USED; 446: return; 447: /* 01/04/80 */ case LUV | LUE: 448: case LUM: 449: q->use |= USED; 450: return; 451: 452: } 453: } 454: 455: chktype( pt1, pt2 ) register ATYPE *pt1, *pt2; { 456: TWORD t; 457: 458: /* check the two type words to see if they are compatible */ 459: /* for the moment, enums are turned into ints, and should be checked as such */ 460: if( pt1->aty == ENUMTY ) pt1->aty = INT; 461: if( pt2->aty == ENUMTY ) pt2->aty = INT; 462: 463: if( (t=BTYPE(pt1->aty)==STRTY) || t==UNIONTY ){ 464: if( pt1->aty != pt2->aty || pt1->extra1 != pt2->extra1 ) 465: return 1; 466: /* if -z then don't worry about undefined structures, 467: as long as the names match */ 468: if( zflag && (pt1->extra == 0 || pt2->extra == 0) ) return 0; 469: return pt1->extra != pt2->extra; 470: } 471: 472: if( pt2->extra ){ /* constant passed in */ 473: if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 ); 474: else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 ); 475: } 476: else if( pt1->extra ){ /* for symmetry */ 477: if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 ); 478: else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 ); 479: } 480: 481: return( pt1->aty != pt2->aty ); 482: } 483: 484: struct tb { int m; char * nm }; 485: 486: struct tb dfs[] = { 487: LDI, "LDI", 488: LIB, "LIB", 489: LDC, "LDC", 490: LDX, "LDX", 491: LRV, "LRV", 492: LUV, "LUV", 493: LUE, "LUE", 494: LUM, "LUM", 495: LST, "LST", 496: LFN, "LFN", 497: 0, "" }; 498: 499: struct tb us[] = { 500: USED, "USED", 501: VUSED, "VUSED", 502: EUSED, "EUSED", 503: RVAL, "RVAL", 504: VARARGS, "VARARGS", 505: 0, "" }; 506: 507: ptb( v, tp ) struct tb *tp; { 508: /* print a value from the table */ 509: int flag; 510: flag = 0; 511: for( ; tp->m; ++tp ){ 512: if( v&tp->m ){ 513: if( flag++ ) putchar( '|' ); 514: printf( "%s", tp->nm ); 515: } 516: } 517: } 518: 519: pst( q ) STAB *q; { 520: /* give a debugging output for q */ 521: 522: #ifndef FLEXNAMES 523: printf( "%.8s (", q->name ); 524: #else 525: printf( "%s (", q->name ); 526: #endif 527: ptb( q->decflag, dfs ); 528: printf( "), use= " ); 529: ptb( q->use, us ); 530: printf( ", line %d, nargs=%d\n", q->fline, q->nargs ); 531: } 532: 533: pfile() { 534: /* print the input file in readable form */ 535: while( lread( LDI|LIB|LDC|LDX|LRV|LUV|LUE|LUM|LST|LFN ) ) 536: prc(); 537: } 538: 539: prc() { 540: /* print out 'r' for debugging */ 541: register i, j, k; 542: 543: printf( "decflag\t" ); 544: ptb( r.l.decflag, dfs ); 545: putchar( '\n' ); 546: if( r.l.decflag & LFN ){ 547: printf( "fn\t\t%s\n", r.f.fn ); 548: } 549: else { 550: #ifdef FLEXNAMES 551: printf( "name\t%s\n", r.l.name ); 552: #else 553: printf( "name\t%.8s\n", r.l.name ); 554: #endif 555: printf( "nargs\t%d\n", r.l.nargs ); 556: printf( "fline\t%d\n", r.l.fline ); 557: printf( "type.aty\t0%o (", r.l.type.aty ); 558: pty( r.l.type.aty, r.l.name ); 559: printf( ")\ntype.extra\t%d\n", r.l.type.extra ); 560: j = r.l.type.extra1; 561: printf( "type.extra1\t0x%x (%d,%d)\n", 562: j, j & X_NONAME ? 1 : 0, j & ~X_NONAME ); 563: k = r.l.nargs; 564: if( k < 0 ) k = -k; 565: for( i = 0; i < k; i++ ){ 566: printf( "atyp[%d].aty\t0%o (", i, atyp[i].aty ); 567: pty( atyp[i].aty, "" ); 568: printf( ")\natyp[%d].extra\t%d\n", i, atyp[i].extra); 569: j = atyp[i].extra1; 570: printf( "atyp[%d].extra1\t0x%x (%d,%d)\n", 571: i, j, j & X_NONAME ? 1 : 0, j & ~X_NONAME ); 572: } 573: } 574: putchar( '\n' ); 575: } 576: 577: pty( t, name ) TWORD t; { 578: static char * tnames[] = { 579: "void", "farg", "char", "short", 580: "int", "long", "float", "double", 581: "struct xxx", "union %s", "enum", "moety", 582: "unsigned char", "unsigned short", "unsigned", "unsigned long", 583: "?", "?" 584: }; 585: 586: printf( "%s ", tnames[BTYPE(t)] ); 587: pty1( t, name, (8 * sizeof (int) - BTSHIFT) / TSHIFT ); 588: } 589: 590: pty1( t, name, level ) TWORD t; { 591: register TWORD u; 592: 593: if( level < 0 ){ 594: printf( "%s", name ); 595: return; 596: } 597: u = t >> level * TSHIFT; 598: if( ISPTR(u) ){ 599: printf( "*" ); 600: pty1( t, name, level-1 ); 601: } 602: else if( ISFTN(u) ){ 603: if( level > 0 && ISPTR(u << TSHIFT) ){ 604: printf( "(" ); 605: pty1( t, name, level-1 ); 606: printf( ")()" ); 607: } 608: else { 609: pty1( t, name, level-1 ); 610: printf( "()" ); 611: } 612: } 613: else if( ISARY(u) ){ 614: if( level > 0 && ISPTR(u << TSHIFT) ){ 615: printf( "(" ); 616: pty1( t, name, level-1 ); 617: printf( ")[]" ); 618: } 619: else { 620: pty1( t, name, level-1 ); 621: printf( "[]" ); 622: } 623: } 624: else { 625: pty1( t, name, level-1 ); 626: } 627: } 628: 629: char * 630: getstr() 631: { 632: char buf[BUFSIZ]; 633: register char *cp = buf; 634: register int c; 635: 636: if (feof(stdin) || ferror(stdin)) 637: return(""); 638: while ((c = getchar()) > 0) 639: *cp++ = c; 640: if (c < 0) { 641: error("intermediate file format error (getstr)"); 642: exit(1); 643: } 644: *cp++ = 0; 645: return (hash(buf)); 646: } 647: 648: #define NSAVETAB 1024 /* was 4096 */ 649: char *savetab; 650: int saveleft; 651: 652: char * 653: savestr(cp) 654: register char *cp; 655: { 656: register int len; 657: 658: len = strlen(cp) + 1; 659: if (len > saveleft) { 660: saveleft = NSAVETAB; 661: if (len > saveleft) 662: saveleft = len; 663: savetab = (char *)malloc(saveleft); 664: if (savetab == 0) { 665: error("ran out of memory (savestr)"); 666: exit(1); 667: } 668: } 669: strncpy(savetab, cp, len); 670: cp = savetab; 671: savetab += len; 672: saveleft -= len; 673: return (cp); 674: } 675: 676: /* 677: * The definition for the segmented hash tables. 678: */ 679: #define MAXHASH 30 680: #define HASHINC 111 /* was 1013 */ 681: struct ht { 682: char **ht_low; 683: char **ht_high; 684: int ht_used; 685: } htab[MAXHASH]; 686: 687: char * 688: hash(s) 689: char *s; 690: { 691: register char **h; 692: register i; 693: register char *cp; 694: struct ht *htp; 695: int sh; 696: 697: sh = hashstr(s) % HASHINC; 698: cp = s; 699: /* 700: * There are as many as MAXHASH active 701: * hash tables at any given point in time. 702: * The search starts with the first table 703: * and continues through the active tables 704: * as necessary. 705: */ 706: for (htp = htab; htp < &htab[MAXHASH]; htp++) { 707: if (htp->ht_low == 0) { 708: register char **hp = 709: (char **) calloc(sizeof (char **), HASHINC); 710: if (hp == 0) { 711: error("ran out of memory (hash)"); 712: exit(1); 713: } 714: htp->ht_low = hp; 715: htp->ht_high = htp->ht_low + HASHINC; 716: } 717: h = htp->ht_low + sh; 718: /* 719: * quadratic rehash increment 720: * starts at 1 and incremented 721: * by two each rehash. 722: */ 723: i = 1; 724: do { 725: if (*h == 0) { 726: if (htp->ht_used > (HASHINC * 3)/4) 727: break; 728: htp->ht_used++; 729: *h = savestr(cp); 730: return (*h); 731: } 732: if (**h == *cp && strcmp(*h, cp) == 0) 733: return (*h); 734: h += i; 735: i += 2; 736: if (h >= htp->ht_high) 737: h -= HASHINC; 738: } while (i < HASHINC); 739: } 740: error("ran out of hash tables"); 741: exit(1); 742: } 743: char *tstrbuf[1];