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