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