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