xref: /csrg-svn/old/pcc/lint/lpass2/lpass2.c (revision 7990)
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