xref: /csrg-svn/old/pcc/lint/lpass2/lpass2.c (revision 11550)
17990Srrh 
27990Srrh #ifndef lint
3*11550Ssam static char sccsid[] = "@(#)lpass2.c	1.2	(Berkeley)	03/12/83";
47990Srrh #endif lint
57990Srrh 
67990Srrh # include "manifest"
77990Srrh # include "lmanifest"
87990Srrh 
97990Srrh # define USED 01
107990Srrh # define VUSED 02
117990Srrh # define EUSED 04
127990Srrh # define RVAL 010
137990Srrh # define VARARGS 0100
147990Srrh 
157990Srrh # define NSZ 2048
167990Srrh # define TYSZ 3500
17*11550Ssam # define FSZ 500
187990Srrh # define NTY 50
197990Srrh 
207990Srrh typedef struct sty STYPE;
217990Srrh struct sty { ATYPE t; STYPE *next; };
227990Srrh 
237990Srrh typedef struct sym {
247990Srrh #ifndef FLEXNAMES
257990Srrh 	char name[LCHNM];
267990Srrh #else
277990Srrh 	char *name;
287990Srrh #endif
297990Srrh 	short nargs;
307990Srrh 	int decflag;
317990Srrh 	int fline;
327990Srrh 	STYPE symty;
337990Srrh 	int fno;
347990Srrh 	int use;
357990Srrh 	} STAB;
367990Srrh 
377990Srrh STAB stab[NSZ];
387990Srrh STAB *find();
397990Srrh 
407990Srrh STYPE tary[TYSZ];
417990Srrh STYPE *tget();
427990Srrh 
437990Srrh #ifndef FLEXNAMES
447990Srrh char fnm[FSZ][LFNM];
457990Srrh #else
467990Srrh char *fnm[FSZ];
477990Srrh #endif
487990Srrh 
497990Srrh #ifdef FLEXNAMES
507990Srrh char *getstr();
517990Srrh #endif
527990Srrh 
537990Srrh int tfree;  /* used to allocate types */
547990Srrh int ffree;  /* used to save filenames */
557990Srrh 
567990Srrh struct ty atyp[NTY];
577990Srrh 	/* r is where all the input ends up */
587990Srrh union rec r;
597990Srrh 
607990Srrh int hflag = 0;
617990Srrh int pflag = 0;
627990Srrh int xflag = 0;
637990Srrh int uflag = 1;
647990Srrh int ddddd = 0;
657990Srrh 
667990Srrh int cfno;  /* current file number */
677990Srrh 
687990Srrh main( argc, argv ) char *argv[]; {
697990Srrh 	register char *p;
707990Srrh 
717990Srrh 	/* first argument is intermediate file */
727990Srrh 	/* second argument is - options */
737990Srrh 
747990Srrh 	for( ; argc>2 && argv[argc-1][0] == '-' ; --argc ){
757990Srrh 		for( p=argv[argc-1]; *p; ++p ){
767990Srrh 			switch( *p ){
777990Srrh 
787990Srrh 			case 'h':
797990Srrh 				hflag = 1;
807990Srrh 				break;
817990Srrh 
827990Srrh 			case 'p':
837990Srrh 				pflag = 1;
847990Srrh 				break;
857990Srrh 
867990Srrh 			case 'x':
877990Srrh 				xflag = 1;
887990Srrh 				break;
897990Srrh 
907990Srrh 			case 'X':
917990Srrh 				ddddd = 1;
927990Srrh 				break;
937990Srrh 
947990Srrh 			case 'u':
957990Srrh 				uflag = 0;
967990Srrh 				break;
977990Srrh 
987990Srrh 				}
997990Srrh 			}
1007990Srrh 		}
1017990Srrh 
1027990Srrh 	if( argc < 2 || !freopen( argv[1], "r", stdin ) ){
1037990Srrh 		error( "cannot open intermediate file" );
1047990Srrh 		exit( 1 );
1057990Srrh 		}
1067990Srrh 
1077990Srrh 	mloop( LDI|LIB );
1087990Srrh 	rewind( stdin );
1097990Srrh 	mloop( LDC|LDX );
1107990Srrh 	rewind( stdin );
1117990Srrh 	mloop( LRV|LUV|LUE|LUM );
1127990Srrh 	cleanup();
1137990Srrh 	return(0);
1147990Srrh 	}
1157990Srrh 
1167990Srrh mloop( m ){
1177990Srrh 	/* do the main loop */
1187990Srrh 	register STAB *q;
1197990Srrh 
1207990Srrh 	while( lread(m) ){
1217990Srrh 		q = find();
1227990Srrh 		if( q->decflag ) chkcompat(q);
1237990Srrh 		else setuse(q);
1247990Srrh 		}
1257990Srrh 	}
1267990Srrh 
1277990Srrh lread(m){ /* read a line into r.l */
1287990Srrh 
1297990Srrh 	register n;
1307990Srrh 
1317990Srrh 	for(;;) {
1327990Srrh 		if( fread( (char *)&r, sizeof(r), 1, stdin ) <= 0 ) return(0);
1337990Srrh 		if( r.l.decflag & LFN ){
1347990Srrh 			/* new filename */
1357990Srrh #ifdef FLEXNAMES
1367990Srrh 			r.f.fn = getstr();
1377990Srrh #endif
1387990Srrh 			setfno( r.f.fn );
1397990Srrh 			continue;
1407990Srrh 			}
1417990Srrh #ifdef FLEXNAMES
1427990Srrh 		r.l.name = getstr();
1437990Srrh #endif
1447990Srrh 
1457990Srrh 		n = r.l.nargs;
1467990Srrh 		if( n<0 ) n = -n;
1477990Srrh 		if( n ){
1487990Srrh 			if( n>=NTY ) error( "more than %d args?", n );
1497990Srrh 			fread( (char *)atyp, sizeof(ATYPE), n, stdin );
1507990Srrh 			}
1517990Srrh 		if( ( r.l.decflag & m ) ) return( 1 );
1527990Srrh 		}
1537990Srrh 	}
1547990Srrh 
1557990Srrh setfno( s ) char *s; {
1567990Srrh 	/* look up current file names */
1577990Srrh 	/* first, strip backwards to the beginning or to the first / */
1587990Srrh 	int i;
1597990Srrh 
1607990Srrh 	/* now look up s */
1617990Srrh 	for( i=0; i<ffree; ++i ){
1627990Srrh #ifndef FLEXNAMES
1637990Srrh 		if( !strncmp( s, fnm[i], LFNM ) ){
1647990Srrh #else
1657990Srrh 		if (fnm[i] == s){
1667990Srrh #endif
1677990Srrh 			cfno = i;
1687990Srrh 			return;
1697990Srrh 			}
1707990Srrh 		}
1717990Srrh 	/* make a new entry */
1727990Srrh 	if( ffree >= FSZ ) error( "more than %d files", FSZ );
1737990Srrh #ifndef FLEXNAMES
1747990Srrh 	strncpy( fnm[ffree], s, LFNM );
1757990Srrh #else
1767990Srrh 	fnm[ffree] = s;
1777990Srrh #endif
1787990Srrh 	cfno = ffree++;
1797990Srrh 	}
1807990Srrh 
1817990Srrh /* VARARGS */
1827990Srrh error( s, a ) char *s; {
1837990Srrh 
1847990Srrh #ifndef FLEXNAMES
1857990Srrh 	fprintf( stderr, "pass 2 error:(file %.*s) ", LFNM, fnm[cfno] );
1867990Srrh #else
1877990Srrh 	fprintf( stderr, "pass 2 error:(file %s) ", fnm[cfno] );
1887990Srrh #endif
1897990Srrh 	fprintf( stderr, s, a );
1907990Srrh 	fprintf( stderr, "\n" );
1917990Srrh 	exit(1);
1927990Srrh 	}
1937990Srrh 
1947990Srrh STAB *
1957990Srrh find(){
1967990Srrh 	/* for this to work, NSZ should be a power of 2 */
1977990Srrh 	register h=0;
1987990Srrh #ifndef FLEXNAMES
1997990Srrh 	{	register char *p, *q;
2007990Srrh 		for( h=0,p=r.l.name,q=p+LCHNM; *p&&p<q; ++p) {
2017990Srrh 			h = (h<<1)+ *p;
2027990Srrh 			if( h>=NSZ ){
2037990Srrh 				h = (h+1)&(NSZ-1);
2047990Srrh 				}
2057990Srrh 			}
2067990Srrh 		}
2077990Srrh #else
2087990Srrh 		h = ((int)r.l.name)%NSZ;
2097990Srrh #endif
2107990Srrh 	{	register STAB *p, *q;
2117990Srrh 		for( p=q= &stab[h]; q->decflag; ){
2127990Srrh 			/* this call to strncmp should be taken out... */
2137990Srrh #ifndef FLEXNAMES
2147990Srrh 			if( !strncmp( r.l.name, q->name, LCHNM)) return(q);
2157990Srrh #else
2167990Srrh 			if (r.l.name == q->name) return (q);
2177990Srrh #endif
2187990Srrh 			if( ++q >= &stab[NSZ] ) q = stab;
2197990Srrh 			if( q == p ) error( "too many names defined" );
2207990Srrh 			}
2217990Srrh #ifndef FLEXNAMES
2227990Srrh 		strncpy( q->name, r.l.name, LCHNM );
2237990Srrh #else
2247990Srrh 		q->name = r.l.name;
2257990Srrh #endif
2267990Srrh 		return( q );
2277990Srrh 		}
2287990Srrh 	}
2297990Srrh 
2307990Srrh STYPE *
2317990Srrh tget(){
2327990Srrh 	if( tfree >= TYSZ ){
2337990Srrh 		error( "too many types needed" );
2347990Srrh 		}
2357990Srrh 	return( &tary[tfree++] );
2367990Srrh 	}
2377990Srrh 
2387990Srrh chkcompat(q) STAB *q; {
2397990Srrh 	/* are the types, etc. in r.l and q compatible */
2407990Srrh 	register int i;
2417990Srrh 	STYPE *qq;
2427990Srrh 
2437990Srrh 	setuse(q);
2447990Srrh 
2457990Srrh 	/* argument check */
2467990Srrh 
2477990Srrh 	if( q->decflag & (LDI|LIB|LUV|LUE) ){
2487990Srrh 		if( r.l.decflag & (LUV|LIB|LUE) ){
2497990Srrh 			if( q->nargs != r.l.nargs ){
2507990Srrh 				if( !(q->use&VARARGS) ){
2517990Srrh #ifndef FLEXNAMES
2527990Srrh 					printf( "%.8s: variable # of args.", q->name );
2537990Srrh #else
2547990Srrh 					printf( "%s: variable # of args.", q->name );
2557990Srrh #endif
2567990Srrh 					viceversa(q);
2577990Srrh 					}
2587990Srrh 				if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs;
2597990Srrh 				if( !(q->decflag & (LDI|LIB) ) ) {
2607990Srrh 					q->nargs = r.l.nargs;
2617990Srrh 					q->use |= VARARGS;
2627990Srrh 					}
2637990Srrh 				}
2647990Srrh 			for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next){
2657990Srrh 				if( chktype( &qq->t, &atyp[i] ) ){
2667990Srrh #ifndef FLEXNAMES
2677990Srrh 					printf( "%.8s, arg. %d used inconsistently",
2687990Srrh #else
2697990Srrh 					printf( "%s, arg. %d used inconsistently",
2707990Srrh #endif
2717990Srrh 						q->name, i+1 );
2727990Srrh 					viceversa(q);
2737990Srrh 					}
2747990Srrh 				}
2757990Srrh 			}
2767990Srrh 		}
2777990Srrh 
2787990Srrh 	if( (q->decflag&(LDI|LIB|LUV)) && r.l.decflag==LUV ){
2797990Srrh 		if( chktype( &r.l.type, &q->symty.t ) ){
2807990Srrh #ifndef FLEXNAMES
2817990Srrh 			printf( "%.8s value used inconsistently", q->name );
2827990Srrh #else
2837990Srrh 			printf( "%s value used inconsistently", q->name );
2847990Srrh #endif
2857990Srrh 			viceversa(q);
2867990Srrh 			}
2877990Srrh 		}
2887990Srrh 
2897990Srrh 	/* check for multiple declaration */
2907990Srrh 
2917990Srrh 	if( (q->decflag&LDI) && (r.l.decflag&(LDI|LIB)) ){
2927990Srrh #ifndef FLEXNAMES
2937990Srrh 		printf( "%.8s multiply declared", q->name );
2947990Srrh #else
2957990Srrh 		printf( "%s multiply declared", q->name );
2967990Srrh #endif
2977990Srrh 		viceversa(q);
2987990Srrh 		}
2997990Srrh 
3007990Srrh 	/* do a bit of checking of definitions and uses... */
3017990Srrh 
3027990Srrh 	if( (q->decflag & (LDI|LIB|LDX|LDC|LUM)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){
3037990Srrh #ifndef FLEXNAMES
3047990Srrh 		printf( "%.8s value declared inconsistently", q->name );
3057990Srrh #else
3067990Srrh 		printf( "%s value declared inconsistently", q->name );
3077990Srrh #endif
3087990Srrh 		viceversa(q);
3097990Srrh 		}
3107990Srrh 
3117990Srrh 	/* better not call functions which are declared to be structure or union returning */
3127990Srrh 
3137990Srrh 	if( (q->decflag & (LDI|LIB|LDX|LDC)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){
3147990Srrh 		/* only matters if the function returns union or structure */
3157990Srrh 		TWORD ty;
3167990Srrh 		ty = q->symty.t.aty;
3177990Srrh 		if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){
3187990Srrh #ifndef FLEXNAMES
3197990Srrh 			printf( "%.8s function value type must be declared before use", q->name );
3207990Srrh #else
3217990Srrh 			printf( "%s function value type must be declared before use", q->name );
3227990Srrh #endif
3237990Srrh 			viceversa(q);
3247990Srrh 			}
3257990Srrh 		}
3267990Srrh 
3277990Srrh 	if( pflag && q->decflag==LDX && r.l.decflag == LUM && !ISFTN(q->symty.t.aty) ){
3287990Srrh 		/* make the external declaration go away */
3297990Srrh 		/* in effect, it was used without being defined */
3307990Srrh 		}
3317990Srrh 	}
3327990Srrh 
3337990Srrh viceversa(q) STAB *q; {
3347990Srrh 	/* print out file comparison */
3357990Srrh #ifndef FLEXNAMES
3367990Srrh 	printf( "	%.*s(%d)  ::  %.*s(%d)\n",
3377990Srrh 		LFNM, fnm[q->fno], q->fline,
3387990Srrh 		LFNM, fnm[cfno], r.l.fline );
3397990Srrh #else
3407990Srrh 	printf( "	%s(%d)  ::  %s(%d)\n",
3417990Srrh 		fnm[q->fno], q->fline,
3427990Srrh 		fnm[cfno], r.l.fline );
3437990Srrh #endif
3447990Srrh 	}
3457990Srrh 
3467990Srrh 	/* messages for defintion/use */
3477990Srrh char *
3487990Srrh mess[2][2] ={
3497990Srrh 	"",
3507990Srrh #ifndef FLEXNAMES
3517990Srrh 	"%.8s used( %.*s(%d) ), but not defined\n",
3527990Srrh 	"%.8s defined( %.*s(%d) ), but never used\n",
3537990Srrh 	"%.8s declared( %.*s(%d) ), but never used or defined\n"
3547990Srrh #else
3557990Srrh 	"%s used( %s(%d) ), but not defined\n",
3567990Srrh 	"%s defined( %s(%d) ), but never used\n",
3577990Srrh 	"%s declared( %s(%d) ), but never used or defined\n"
3587990Srrh #endif
3597990Srrh 	};
3607990Srrh 
3617990Srrh lastone(q) STAB *q; {
3627990Srrh 
3637990Srrh 	register nu, nd, uses;
3647990Srrh 
3657990Srrh 	if( ddddd ) pst(q);
3667990Srrh 
3677990Srrh 	nu = nd = 0;
3687990Srrh 	uses = q->use;
3697990Srrh 
3707990Srrh 	if( !(uses&USED) && q->decflag != LIB ) {
3717990Srrh #ifndef FLEXNAMES
3727990Srrh 		if( strncmp(q->name,"main",7) )
3737990Srrh #else
3747990Srrh 		if (strcmp(q->name, "main"))
3757990Srrh #endif
3767990Srrh 			nu = 1;
3777990Srrh 		}
3787990Srrh 
3797990Srrh 	if( !ISFTN(q->symty.t.aty) ){
3807990Srrh 		switch( q->decflag ){
3817990Srrh 
3827990Srrh 		case LIB:
3837990Srrh 			nu = nd = 0;  /* don't complain about uses on libraries */
3847990Srrh 			break;
3857990Srrh 		case LDX:
3867990Srrh 			if( !xflag ) break;
3877990Srrh 		case LUV:
3887990Srrh 		case LUE:
3897990Srrh /* 01/04/80 */	case LUV | LUE:
3907990Srrh 		case LUM:
3917990Srrh 			nd = 1;
3927990Srrh 			}
3937990Srrh 		}
3947990Srrh 	if( uflag && ( nu || nd ) ) printf( mess[nu][nd],
3957990Srrh #ifndef FLEXNAMES
3967990Srrh 		 q->name, LFNM, fnm[q->fno], q->fline );
3977990Srrh #else
3987990Srrh 		 q->name, fnm[q->fno], q->fline );
3997990Srrh #endif
4007990Srrh 
4017990Srrh 	if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
4027990Srrh #ifndef FLEXNAMES
4037990Srrh 		printf( "%.8s returns value which is %s ignored\n", q->name,
4047990Srrh #else
4057990Srrh 		printf( "%s returns value which is %s ignored\n", q->name,
4067990Srrh #endif
4077990Srrh 			uses&VUSED ? "sometimes" : "always" );
4087990Srrh 		}
4097990Srrh 
4107990Srrh 	if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB)) ){
4117990Srrh #ifndef FLEXNAMES
4127990Srrh 		printf( "%.8s value is used, but none returned\n", q->name );
4137990Srrh #else
4147990Srrh 		printf( "%s value is used, but none returned\n", q->name );
4157990Srrh #endif
4167990Srrh 		}
4177990Srrh 	}
4187990Srrh 
4197990Srrh cleanup(){ /* call lastone and die gracefully */
4207990Srrh 	STAB *q;
4217990Srrh 	for( q=stab; q< &stab[NSZ]; ++q ){
4227990Srrh 		if( q->decflag ) lastone(q);
4237990Srrh 		}
4247990Srrh 	exit(0);
4257990Srrh 	}
4267990Srrh 
4277990Srrh setuse(q) STAB *q; { /* check new type to ensure that it is used */
4287990Srrh 
4297990Srrh 	if( !q->decflag ){ /* new one */
4307990Srrh 		q->decflag = r.l.decflag;
4317990Srrh 		q->symty.t = r.l.type;
4327990Srrh 		if( r.l.nargs < 0 ){
4337990Srrh 			q->nargs = -r.l.nargs;
4347990Srrh 			q->use = VARARGS;
4357990Srrh 			}
4367990Srrh 		else {
4377990Srrh 			q->nargs = r.l.nargs;
4387990Srrh 			q->use = 0;
4397990Srrh 			}
4407990Srrh 		q->fline = r.l.fline;
4417990Srrh 		q->fno = cfno;
4427990Srrh 		if( q->nargs ){
4437990Srrh 			int i;
4447990Srrh 			STYPE *qq;
4457990Srrh 			for( i=0,qq= &q->symty; i<q->nargs; ++i,qq=qq->next ){
4467990Srrh 				qq->next = tget();
4477990Srrh 				qq->next->t = atyp[i];
4487990Srrh 				}
4497990Srrh 			}
4507990Srrh 		}
4517990Srrh 
4527990Srrh 	switch( r.l.decflag ){
4537990Srrh 
4547990Srrh 	case LRV:
4557990Srrh 		q->use |= RVAL;
4567990Srrh 		return;
4577990Srrh 	case LUV:
4587990Srrh 		q->use |= VUSED+USED;
4597990Srrh 		return;
4607990Srrh 	case LUE:
4617990Srrh 		q->use |= EUSED+USED;
4627990Srrh 		return;
4637990Srrh /* 01/04/80 */	case LUV | LUE:
4647990Srrh 	case LUM:
4657990Srrh 		q->use |= USED;
4667990Srrh 		return;
4677990Srrh 
4687990Srrh 		}
4697990Srrh 	}
4707990Srrh 
4717990Srrh chktype( pt1, pt2 ) register ATYPE *pt1, *pt2; {
4727990Srrh 	TWORD t;
4737990Srrh 
4747990Srrh 	/* check the two type words to see if they are compatible */
4757990Srrh 	/* for the moment, enums are turned into ints, and should be checked as such */
4767990Srrh 	if( pt1->aty == ENUMTY ) pt1->aty =  INT;
4777990Srrh 	if( pt2->aty == ENUMTY ) pt2->aty = INT;
4787990Srrh 
4797990Srrh 	if( (t=BTYPE(pt1->aty)==STRTY) || t==UNIONTY ){
4807990Srrh 		return( pt1->aty!=pt2->aty || (
4817990Srrh 			pt1->extra!=pt2->extra ) );
4827990Srrh 		}
4837990Srrh 
4847990Srrh 	if( pt2->extra ){ /* constant passed in */
4857990Srrh 		if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
4867990Srrh 		else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
4877990Srrh 		}
4887990Srrh 	else if( pt1->extra ){ /* for symmetry */
4897990Srrh 		if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
4907990Srrh 		else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
4917990Srrh 		}
4927990Srrh 
4937990Srrh 	return( pt1->aty != pt2->aty );
4947990Srrh 	}
4957990Srrh 
4967990Srrh struct tb { int m; char * nm };
4977990Srrh ptb( v, tp ) struct tb *tp; {
4987990Srrh 	/* print a value from the table */
4997990Srrh 	int flag;
5007990Srrh 	flag = 0;
5017990Srrh 	for( ; tp->m; ++tp ){
5027990Srrh 		if( v&tp->m ){
5037990Srrh 			if( flag++ ) putchar( '|' );
5047990Srrh 			printf( "%s", tp->nm );
5057990Srrh 			}
5067990Srrh 		}
5077990Srrh 	}
5087990Srrh 
5097990Srrh pst( q ) STAB *q; {
5107990Srrh 	/* give a debugging output for q */
5117990Srrh 	static struct tb dfs[] = {
5127990Srrh 		LDI, "LDI",
5137990Srrh 		LIB, "LIB",
5147990Srrh 		LDC, "LDC",
5157990Srrh 		LDX, "LDX",
5167990Srrh 		LRV, "LRV",
5177990Srrh 		LUV, "LUV",
5187990Srrh 		LUE, "LUE",
5197990Srrh 		LUM, "LUM",
5207990Srrh 		0, "" };
5217990Srrh 
5227990Srrh 	static struct tb us[] = {
5237990Srrh 		USED, "USED",
5247990Srrh 		VUSED, "VUSED",
5257990Srrh 		EUSED, "EUSED",
5267990Srrh 		RVAL, "RVAL",
5277990Srrh 		VARARGS, "VARARGS",
5287990Srrh 		0,	0,
5297990Srrh 		};
5307990Srrh 
5317990Srrh #ifndef FLEXNAMES
5327990Srrh 	printf( "%.8s (", q->name );
5337990Srrh #else
5347990Srrh 	printf( "%s (", q->name );
5357990Srrh #endif
5367990Srrh 	ptb( q->decflag, dfs );
5377990Srrh 	printf( "), use= " );
5387990Srrh 	ptb( q->use, us );
5397990Srrh 	printf( ", line %d, nargs=%d\n", q->fline, q->nargs );
5407990Srrh 	}
5417990Srrh 
5427990Srrh #ifdef FLEXNAMES
5437990Srrh char *
5447990Srrh getstr()
5457990Srrh {
5467990Srrh 	char buf[BUFSIZ];
5477990Srrh 	register char *cp = buf;
5487990Srrh 	register int c;
5497990Srrh 
5507990Srrh 	if (feof(stdin) || ferror(stdin))
5517990Srrh 		return("");
5527990Srrh 	while ((c = getchar()) > 0)
5537990Srrh 		*cp++ = c;
5547990Srrh 	if (c < 0) {
5557990Srrh 		fprintf(stderr, "pass 2 error: intermediate file format error (getstr)");
5567990Srrh 		exit(1);
5577990Srrh 	}
5587990Srrh 	*cp++ = 0;
5597990Srrh 	return (hash(buf));
5607990Srrh }
5617990Srrh 
5627990Srrh #define	NSAVETAB	4096
5637990Srrh char	*savetab;
5647990Srrh int	saveleft;
5657990Srrh 
5667990Srrh char *
5677990Srrh savestr(cp)
5687990Srrh 	register char *cp;
5697990Srrh {
5707990Srrh 	register int len;
5717990Srrh 
5727990Srrh 	len = strlen(cp) + 1;
5737990Srrh 	if (len > saveleft) {
5747990Srrh 		saveleft = NSAVETAB;
5757990Srrh 		if (len > saveleft)
5767990Srrh 			saveleft = len;
5777990Srrh 		savetab = (char *)malloc(saveleft);
5787990Srrh 		if (savetab == 0) {
5797990Srrh 			fprintf(stderr, "pass 2 error: ran out of memory (savestr)");
5807990Srrh 			exit(1);
5817990Srrh 		}
5827990Srrh 	}
5837990Srrh 	strncpy(savetab, cp, len);
5847990Srrh 	cp = savetab;
5857990Srrh 	savetab += len;
5867990Srrh 	saveleft -= len;
5877990Srrh 	return (cp);
5887990Srrh }
5897990Srrh 
5907990Srrh /*
5917990Srrh  * The definition for the segmented hash tables.
5927990Srrh  */
5937990Srrh #define	MAXHASH	20
5947990Srrh #define	HASHINC	1013
5957990Srrh struct ht {
5967990Srrh 	char	**ht_low;
5977990Srrh 	char	**ht_high;
5987990Srrh 	int	ht_used;
5997990Srrh } htab[MAXHASH];
6007990Srrh 
6017990Srrh char *
6027990Srrh hash(s)
6037990Srrh 	char *s;
6047990Srrh {
6057990Srrh 	register char **h;
6067990Srrh 	register i;
6077990Srrh 	register char *cp;
6087990Srrh 	struct ht *htp;
6097990Srrh 	int sh;
6107990Srrh 
6117990Srrh 	/*
6127990Srrh 	 * The hash function is a modular hash of
6137990Srrh 	 * the sum of the characters with the sum
6147990Srrh 	 * doubled before each successive character
6157990Srrh 	 * is added.
6167990Srrh 	 */
6177990Srrh 	cp = s;
6187990Srrh 	i = 0;
6197990Srrh 	while (*cp)
6207990Srrh 		i = i*2 + *cp++;
6217990Srrh 	sh = (i&077777) % HASHINC;
6227990Srrh 	cp = s;
6237990Srrh 	/*
6247990Srrh 	 * There are as many as MAXHASH active
6257990Srrh 	 * hash tables at any given point in time.
6267990Srrh 	 * The search starts with the first table
6277990Srrh 	 * and continues through the active tables
6287990Srrh 	 * as necessary.
6297990Srrh 	 */
6307990Srrh 	for (htp = htab; htp < &htab[MAXHASH]; htp++) {
6317990Srrh 		if (htp->ht_low == 0) {
6327990Srrh 			register char **hp =
6337990Srrh 			    (char **) calloc(sizeof (char **), HASHINC);
6347990Srrh 			if (hp == 0) {
6357990Srrh 				fprintf(stderr, "pass 2 error: ran out of memory (hash)");
6367990Srrh 				exit(1);
6377990Srrh 			}
6387990Srrh 			htp->ht_low = hp;
6397990Srrh 			htp->ht_high = htp->ht_low + HASHINC;
6407990Srrh 		}
6417990Srrh 		h = htp->ht_low + sh;
6427990Srrh 		/*
6437990Srrh 		 * quadratic rehash increment
6447990Srrh 		 * starts at 1 and incremented
6457990Srrh 		 * by two each rehash.
6467990Srrh 		 */
6477990Srrh 		i = 1;
6487990Srrh 		do {
6497990Srrh 			if (*h == 0) {
6507990Srrh 				if (htp->ht_used > (HASHINC * 3)/4)
6517990Srrh 					break;
6527990Srrh 				htp->ht_used++;
6537990Srrh 				*h = savestr(cp);
6547990Srrh 				return (*h);
6557990Srrh 			}
6567990Srrh 			if (**h == *cp && strcmp(*h, cp) == 0)
6577990Srrh 				return (*h);
6587990Srrh 			h += i;
6597990Srrh 			i += 2;
6607990Srrh 			if (h >= htp->ht_high)
6617990Srrh 				h -= HASHINC;
6627990Srrh 		} while (i < HASHINC);
6637990Srrh 	}
6647990Srrh 	fprintf(stderr, "pass 2 error: ran out of hash tables");
6657990Srrh 	exit(1);
6667990Srrh }
6677990Srrh char	*tstrbuf[1];
6687990Srrh #endif
669