xref: /csrg-svn/old/pcc/lint/lpass2/lpass2.c (revision 11762)
17990Srrh 
27990Srrh #ifndef lint
3*11762Sedward static char sccsid[] = "@(#)lpass2.c	1.3	(Berkeley)	03/29/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
1711550Ssam # 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;
65*11762Sedward int zflag = 0;
66*11762Sedward int Pflag = 0;
677990Srrh 
687990Srrh int cfno;  /* current file number */
697990Srrh 
707990Srrh main( argc, argv ) char *argv[]; {
717990Srrh 	register char *p;
727990Srrh 
737990Srrh 	/* first argument is intermediate file */
747990Srrh 	/* second argument is - options */
757990Srrh 
767990Srrh 	for( ; argc>2 && argv[argc-1][0] == '-' ; --argc ){
777990Srrh 		for( p=argv[argc-1]; *p; ++p ){
787990Srrh 			switch( *p ){
797990Srrh 
807990Srrh 			case 'h':
817990Srrh 				hflag = 1;
827990Srrh 				break;
837990Srrh 
847990Srrh 			case 'p':
857990Srrh 				pflag = 1;
867990Srrh 				break;
877990Srrh 
887990Srrh 			case 'x':
897990Srrh 				xflag = 1;
907990Srrh 				break;
917990Srrh 
927990Srrh 			case 'X':
937990Srrh 				ddddd = 1;
947990Srrh 				break;
957990Srrh 
967990Srrh 			case 'u':
977990Srrh 				uflag = 0;
987990Srrh 				break;
997990Srrh 
100*11762Sedward 			case 'z':
101*11762Sedward 				zflag = 1;
102*11762Sedward 				break;
103*11762Sedward 
104*11762Sedward 			case 'P':
105*11762Sedward 				Pflag = 1;
106*11762Sedward 				break;
107*11762Sedward 
1087990Srrh 				}
1097990Srrh 			}
1107990Srrh 		}
1117990Srrh 
1127990Srrh 	if( argc < 2 || !freopen( argv[1], "r", stdin ) ){
1137990Srrh 		error( "cannot open intermediate file" );
1147990Srrh 		exit( 1 );
1157990Srrh 		}
116*11762Sedward 	if( Pflag ){
117*11762Sedward 		pfile();
118*11762Sedward 		return( 0 );
119*11762Sedward 		}
120*11762Sedward 	mloop( LDI|LIB|LST );
1217990Srrh 	rewind( stdin );
1227990Srrh 	mloop( LDC|LDX );
1237990Srrh 	rewind( stdin );
1247990Srrh 	mloop( LRV|LUV|LUE|LUM );
1257990Srrh 	cleanup();
1267990Srrh 	return(0);
1277990Srrh 	}
1287990Srrh 
1297990Srrh mloop( m ){
1307990Srrh 	/* do the main loop */
1317990Srrh 	register STAB *q;
1327990Srrh 
1337990Srrh 	while( lread(m) ){
1347990Srrh 		q = find();
1357990Srrh 		if( q->decflag ) chkcompat(q);
1367990Srrh 		else setuse(q);
1377990Srrh 		}
1387990Srrh 	}
1397990Srrh 
1407990Srrh lread(m){ /* read a line into r.l */
1417990Srrh 
1427990Srrh 	register n;
1437990Srrh 
1447990Srrh 	for(;;) {
1457990Srrh 		if( fread( (char *)&r, sizeof(r), 1, stdin ) <= 0 ) return(0);
1467990Srrh 		if( r.l.decflag & LFN ){
1477990Srrh 			/* new filename */
1487990Srrh #ifdef FLEXNAMES
1497990Srrh 			r.f.fn = getstr();
1507990Srrh #endif
151*11762Sedward 			if( Pflag ) return( 1 );
1527990Srrh 			setfno( r.f.fn );
1537990Srrh 			continue;
1547990Srrh 			}
1557990Srrh #ifdef FLEXNAMES
1567990Srrh 		r.l.name = getstr();
1577990Srrh #endif
1587990Srrh 		n = r.l.nargs;
1597990Srrh 		if( n<0 ) n = -n;
160*11762Sedward 		if( n>=NTY ) error( "more than %d args?", n );
161*11762Sedward 		fread( (char *)atyp, sizeof(ATYPE), n, stdin );
1627990Srrh 		if( ( r.l.decflag & m ) ) return( 1 );
1637990Srrh 		}
1647990Srrh 	}
1657990Srrh 
1667990Srrh setfno( s ) char *s; {
1677990Srrh 	/* look up current file names */
1687990Srrh 	/* first, strip backwards to the beginning or to the first / */
1697990Srrh 	int i;
1707990Srrh 
1717990Srrh 	/* now look up s */
1727990Srrh 	for( i=0; i<ffree; ++i ){
1737990Srrh #ifndef FLEXNAMES
174*11762Sedward 		if( !strncmp( s, fnm[i], LFNM ) )
1757990Srrh #else
176*11762Sedward 		if (fnm[i] == s)
1777990Srrh #endif
178*11762Sedward 			{
1797990Srrh 			cfno = i;
1807990Srrh 			return;
1817990Srrh 			}
1827990Srrh 		}
1837990Srrh 	/* make a new entry */
1847990Srrh 	if( ffree >= FSZ ) error( "more than %d files", FSZ );
1857990Srrh #ifndef FLEXNAMES
1867990Srrh 	strncpy( fnm[ffree], s, LFNM );
1877990Srrh #else
1887990Srrh 	fnm[ffree] = s;
1897990Srrh #endif
1907990Srrh 	cfno = ffree++;
1917990Srrh 	}
1927990Srrh 
1937990Srrh /* VARARGS */
1947990Srrh error( s, a ) char *s; {
1957990Srrh 
1967990Srrh #ifndef FLEXNAMES
1977990Srrh 	fprintf( stderr, "pass 2 error:(file %.*s) ", LFNM, fnm[cfno] );
1987990Srrh #else
1997990Srrh 	fprintf( stderr, "pass 2 error:(file %s) ", fnm[cfno] );
2007990Srrh #endif
2017990Srrh 	fprintf( stderr, s, a );
2027990Srrh 	fprintf( stderr, "\n" );
2037990Srrh 	exit(1);
2047990Srrh 	}
2057990Srrh 
2067990Srrh STAB *
2077990Srrh find(){
2087990Srrh 	register h=0;
2097990Srrh #ifndef FLEXNAMES
210*11762Sedward 	h = hashstr(r.l.name, LCHNM) % NSZ;
2117990Srrh #else
212*11762Sedward 	h = (int)r.l.name % NSZ;
2137990Srrh #endif
2147990Srrh 	{	register STAB *p, *q;
2157990Srrh 		for( p=q= &stab[h]; q->decflag; ){
2167990Srrh #ifndef FLEXNAMES
217*11762Sedward 			if( !strncmp( r.l.name, q->name, LCHNM))
2187990Srrh #else
219*11762Sedward 			if (r.l.name == q->name)
2207990Srrh #endif
221*11762Sedward 				if( ((q->decflag|r.l.decflag)&LST)==0 || q->fno==cfno )
222*11762Sedward 					return(q);
2237990Srrh 			if( ++q >= &stab[NSZ] ) q = stab;
2247990Srrh 			if( q == p ) error( "too many names defined" );
2257990Srrh 			}
2267990Srrh #ifndef FLEXNAMES
2277990Srrh 		strncpy( q->name, r.l.name, LCHNM );
2287990Srrh #else
2297990Srrh 		q->name = r.l.name;
2307990Srrh #endif
2317990Srrh 		return( q );
2327990Srrh 		}
2337990Srrh 	}
2347990Srrh 
2357990Srrh STYPE *
2367990Srrh tget(){
2377990Srrh 	if( tfree >= TYSZ ){
2387990Srrh 		error( "too many types needed" );
2397990Srrh 		}
2407990Srrh 	return( &tary[tfree++] );
2417990Srrh 	}
2427990Srrh 
2437990Srrh chkcompat(q) STAB *q; {
2447990Srrh 	/* are the types, etc. in r.l and q compatible */
2457990Srrh 	register int i;
2467990Srrh 	STYPE *qq;
2477990Srrh 
2487990Srrh 	setuse(q);
2497990Srrh 
2507990Srrh 	/* argument check */
2517990Srrh 
252*11762Sedward 	if( q->decflag & (LDI|LIB|LUV|LUE|LST) ){
2537990Srrh 		if( r.l.decflag & (LUV|LIB|LUE) ){
2547990Srrh 			if( q->nargs != r.l.nargs ){
2557990Srrh 				if( !(q->use&VARARGS) ){
2567990Srrh #ifndef FLEXNAMES
2577990Srrh 					printf( "%.8s: variable # of args.", q->name );
2587990Srrh #else
2597990Srrh 					printf( "%s: variable # of args.", q->name );
2607990Srrh #endif
2617990Srrh 					viceversa(q);
2627990Srrh 					}
2637990Srrh 				if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs;
264*11762Sedward 				if( !(q->decflag & (LDI|LIB|LST) ) ) {
2657990Srrh 					q->nargs = r.l.nargs;
2667990Srrh 					q->use |= VARARGS;
2677990Srrh 					}
2687990Srrh 				}
2697990Srrh 			for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next){
2707990Srrh 				if( chktype( &qq->t, &atyp[i] ) ){
2717990Srrh #ifndef FLEXNAMES
2727990Srrh 					printf( "%.8s, arg. %d used inconsistently",
2737990Srrh #else
2747990Srrh 					printf( "%s, arg. %d used inconsistently",
2757990Srrh #endif
2767990Srrh 						q->name, i+1 );
2777990Srrh 					viceversa(q);
2787990Srrh 					}
2797990Srrh 				}
2807990Srrh 			}
2817990Srrh 		}
2827990Srrh 
283*11762Sedward 	if( (q->decflag&(LDI|LIB|LUV|LST)) && r.l.decflag==LUV ){
2847990Srrh 		if( chktype( &r.l.type, &q->symty.t ) ){
2857990Srrh #ifndef FLEXNAMES
2867990Srrh 			printf( "%.8s value used inconsistently", q->name );
2877990Srrh #else
2887990Srrh 			printf( "%s value used inconsistently", q->name );
2897990Srrh #endif
2907990Srrh 			viceversa(q);
2917990Srrh 			}
2927990Srrh 		}
2937990Srrh 
2947990Srrh 	/* check for multiple declaration */
2957990Srrh 
296*11762Sedward 	if( (q->decflag&(LDI|LST)) && (r.l.decflag&(LDI|LIB|LST)) ){
2977990Srrh #ifndef FLEXNAMES
2987990Srrh 		printf( "%.8s multiply declared", q->name );
2997990Srrh #else
3007990Srrh 		printf( "%s multiply declared", q->name );
3017990Srrh #endif
3027990Srrh 		viceversa(q);
3037990Srrh 		}
3047990Srrh 
3057990Srrh 	/* do a bit of checking of definitions and uses... */
3067990Srrh 
307*11762Sedward 	if( (q->decflag & (LDI|LIB|LDX|LDC|LUM|LST)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){
3087990Srrh #ifndef FLEXNAMES
3097990Srrh 		printf( "%.8s value declared inconsistently", q->name );
3107990Srrh #else
3117990Srrh 		printf( "%s value declared inconsistently", q->name );
3127990Srrh #endif
3137990Srrh 		viceversa(q);
3147990Srrh 		}
3157990Srrh 
3167990Srrh 	/* better not call functions which are declared to be structure or union returning */
3177990Srrh 
318*11762Sedward 	if( (q->decflag & (LDI|LIB|LDX|LDC|LST)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){
3197990Srrh 		/* only matters if the function returns union or structure */
3207990Srrh 		TWORD ty;
3217990Srrh 		ty = q->symty.t.aty;
3227990Srrh 		if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){
3237990Srrh #ifndef FLEXNAMES
3247990Srrh 			printf( "%.8s function value type must be declared before use", q->name );
3257990Srrh #else
3267990Srrh 			printf( "%s function value type must be declared before use", q->name );
3277990Srrh #endif
3287990Srrh 			viceversa(q);
3297990Srrh 			}
3307990Srrh 		}
3317990Srrh 
3327990Srrh 	if( pflag && q->decflag==LDX && r.l.decflag == LUM && !ISFTN(q->symty.t.aty) ){
3337990Srrh 		/* make the external declaration go away */
3347990Srrh 		/* in effect, it was used without being defined */
3357990Srrh 		}
3367990Srrh 	}
3377990Srrh 
3387990Srrh viceversa(q) STAB *q; {
3397990Srrh 	/* print out file comparison */
3407990Srrh #ifndef FLEXNAMES
3417990Srrh 	printf( "	%.*s(%d)  ::  %.*s(%d)\n",
3427990Srrh 		LFNM, fnm[q->fno], q->fline,
3437990Srrh 		LFNM, fnm[cfno], r.l.fline );
3447990Srrh #else
3457990Srrh 	printf( "	%s(%d)  ::  %s(%d)\n",
3467990Srrh 		fnm[q->fno], q->fline,
3477990Srrh 		fnm[cfno], r.l.fline );
3487990Srrh #endif
3497990Srrh 	}
3507990Srrh 
3517990Srrh 	/* messages for defintion/use */
3527990Srrh char *
3537990Srrh mess[2][2] ={
3547990Srrh 	"",
3557990Srrh #ifndef FLEXNAMES
3567990Srrh 	"%.8s used( %.*s(%d) ), but not defined\n",
3577990Srrh 	"%.8s defined( %.*s(%d) ), but never used\n",
3587990Srrh 	"%.8s declared( %.*s(%d) ), but never used or defined\n"
3597990Srrh #else
3607990Srrh 	"%s used( %s(%d) ), but not defined\n",
3617990Srrh 	"%s defined( %s(%d) ), but never used\n",
3627990Srrh 	"%s declared( %s(%d) ), but never used or defined\n"
3637990Srrh #endif
3647990Srrh 	};
3657990Srrh 
3667990Srrh lastone(q) STAB *q; {
3677990Srrh 
3687990Srrh 	register nu, nd, uses;
3697990Srrh 
3707990Srrh 	if( ddddd ) pst(q);
3717990Srrh 
3727990Srrh 	nu = nd = 0;
3737990Srrh 	uses = q->use;
3747990Srrh 
3757990Srrh 	if( !(uses&USED) && q->decflag != LIB ) {
3767990Srrh #ifndef FLEXNAMES
3777990Srrh 		if( strncmp(q->name,"main",7) )
3787990Srrh #else
3797990Srrh 		if (strcmp(q->name, "main"))
3807990Srrh #endif
3817990Srrh 			nu = 1;
3827990Srrh 		}
3837990Srrh 
3847990Srrh 	if( !ISFTN(q->symty.t.aty) ){
3857990Srrh 		switch( q->decflag ){
3867990Srrh 
3877990Srrh 		case LIB:
3887990Srrh 			nu = nd = 0;  /* don't complain about uses on libraries */
3897990Srrh 			break;
3907990Srrh 		case LDX:
3917990Srrh 			if( !xflag ) break;
3927990Srrh 		case LUV:
3937990Srrh 		case LUE:
3947990Srrh /* 01/04/80 */	case LUV | LUE:
3957990Srrh 		case LUM:
3967990Srrh 			nd = 1;
3977990Srrh 			}
3987990Srrh 		}
399*11762Sedward 	if( uflag && ( nu || nd ) )
4007990Srrh #ifndef FLEXNAMES
401*11762Sedward 		printf( mess[nu][nd], q->name, LFNM, fnm[q->fno], q->fline );
4027990Srrh #else
403*11762Sedward 		printf( mess[nu][nd], q->name, fnm[q->fno], q->fline );
4047990Srrh #endif
4057990Srrh 
4067990Srrh 	if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
407*11762Sedward 		/* if functions is static, then print the file name too */
408*11762Sedward 		if( q->decflag & LST )
4097990Srrh #ifndef FLEXNAMES
410*11762Sedward 			printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline );
4117990Srrh #else
412*11762Sedward 			printf( "%s(%d):", fnm[q->fno], q->fline );
4137990Srrh #endif
414*11762Sedward #ifndef FLEXNAMES
415*11762Sedward 		printf( "%.*s returns value which is %s ignored\n",
416*11762Sedward 			LCHNM, q->name, uses&VUSED ? "sometimes" : "always" );
417*11762Sedward #else
418*11762Sedward 		printf( "%s returns value which is %s ignored\n",
419*11762Sedward 			q->name, uses&VUSED ? "sometimes" : "always" );
420*11762Sedward #endif
4217990Srrh 		}
4227990Srrh 
423*11762Sedward 	if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB|LST)) ){
424*11762Sedward 		if( q->decflag & LST )
4257990Srrh #ifndef FLEXNAMES
426*11762Sedward 			printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline );
4277990Srrh #else
428*11762Sedward 			printf( "%s(%d):", fnm[q->fno], q->fline );
4297990Srrh #endif
430*11762Sedward #ifndef FLEXNAMES
431*11762Sedward 		printf( "%.*s value is used, but none returned\n",
432*11762Sedward 			LCHNM, q->name);
433*11762Sedward #else
434*11762Sedward 		printf( "%s value is used, but none returned\n", q->name);
435*11762Sedward #endif
4367990Srrh 		}
4377990Srrh 	}
4387990Srrh 
4397990Srrh cleanup(){ /* call lastone and die gracefully */
4407990Srrh 	STAB *q;
4417990Srrh 	for( q=stab; q< &stab[NSZ]; ++q ){
4427990Srrh 		if( q->decflag ) lastone(q);
4437990Srrh 		}
4447990Srrh 	exit(0);
4457990Srrh 	}
4467990Srrh 
4477990Srrh setuse(q) STAB *q; { /* check new type to ensure that it is used */
4487990Srrh 
4497990Srrh 	if( !q->decflag ){ /* new one */
4507990Srrh 		q->decflag = r.l.decflag;
4517990Srrh 		q->symty.t = r.l.type;
4527990Srrh 		if( r.l.nargs < 0 ){
4537990Srrh 			q->nargs = -r.l.nargs;
4547990Srrh 			q->use = VARARGS;
4557990Srrh 			}
4567990Srrh 		else {
4577990Srrh 			q->nargs = r.l.nargs;
4587990Srrh 			q->use = 0;
4597990Srrh 			}
4607990Srrh 		q->fline = r.l.fline;
4617990Srrh 		q->fno = cfno;
4627990Srrh 		if( q->nargs ){
4637990Srrh 			int i;
4647990Srrh 			STYPE *qq;
4657990Srrh 			for( i=0,qq= &q->symty; i<q->nargs; ++i,qq=qq->next ){
4667990Srrh 				qq->next = tget();
4677990Srrh 				qq->next->t = atyp[i];
4687990Srrh 				}
4697990Srrh 			}
4707990Srrh 		}
4717990Srrh 
4727990Srrh 	switch( r.l.decflag ){
4737990Srrh 
4747990Srrh 	case LRV:
4757990Srrh 		q->use |= RVAL;
4767990Srrh 		return;
4777990Srrh 	case LUV:
4787990Srrh 		q->use |= VUSED+USED;
4797990Srrh 		return;
4807990Srrh 	case LUE:
4817990Srrh 		q->use |= EUSED+USED;
4827990Srrh 		return;
4837990Srrh /* 01/04/80 */	case LUV | LUE:
4847990Srrh 	case LUM:
4857990Srrh 		q->use |= USED;
4867990Srrh 		return;
4877990Srrh 
4887990Srrh 		}
4897990Srrh 	}
4907990Srrh 
4917990Srrh chktype( pt1, pt2 ) register ATYPE *pt1, *pt2; {
4927990Srrh 	TWORD t;
4937990Srrh 
4947990Srrh 	/* check the two type words to see if they are compatible */
4957990Srrh 	/* for the moment, enums are turned into ints, and should be checked as such */
4967990Srrh 	if( pt1->aty == ENUMTY ) pt1->aty =  INT;
4977990Srrh 	if( pt2->aty == ENUMTY ) pt2->aty = INT;
4987990Srrh 
4997990Srrh 	if( (t=BTYPE(pt1->aty)==STRTY) || t==UNIONTY ){
500*11762Sedward 		if( pt1->aty != pt2->aty || pt1->extra1 != pt2->extra1 )
501*11762Sedward 			return 1;
502*11762Sedward 		/* if -z then don't worry about undefined structures,
503*11762Sedward 		   as long as the names match */
504*11762Sedward 		if( zflag && (pt1->extra == 0 || pt2->extra == 0) ) return 0;
505*11762Sedward 		return pt1->extra != pt2->extra;
5067990Srrh 		}
5077990Srrh 
5087990Srrh 	if( pt2->extra ){ /* constant passed in */
5097990Srrh 		if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
5107990Srrh 		else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
5117990Srrh 		}
5127990Srrh 	else if( pt1->extra ){ /* for symmetry */
5137990Srrh 		if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
5147990Srrh 		else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
5157990Srrh 		}
5167990Srrh 
5177990Srrh 	return( pt1->aty != pt2->aty );
5187990Srrh 	}
5197990Srrh 
5207990Srrh struct tb { int m; char * nm };
521*11762Sedward 
522*11762Sedward struct tb dfs[] = {
523*11762Sedward 	LDI, "LDI",
524*11762Sedward 	LIB, "LIB",
525*11762Sedward 	LDC, "LDC",
526*11762Sedward 	LDX, "LDX",
527*11762Sedward 	LRV, "LRV",
528*11762Sedward 	LUV, "LUV",
529*11762Sedward 	LUE, "LUE",
530*11762Sedward 	LUM, "LUM",
531*11762Sedward 	LST, "LST",
532*11762Sedward 	LFN, "LFN",
533*11762Sedward 	0, "" };
534*11762Sedward 
535*11762Sedward struct tb us[] = {
536*11762Sedward 	USED, "USED",
537*11762Sedward 	VUSED, "VUSED",
538*11762Sedward 	EUSED, "EUSED",
539*11762Sedward 	RVAL, "RVAL",
540*11762Sedward 	VARARGS, "VARARGS",
541*11762Sedward 	0, "" };
542*11762Sedward 
5437990Srrh ptb( v, tp ) struct tb *tp; {
5447990Srrh 	/* print a value from the table */
5457990Srrh 	int flag;
5467990Srrh 	flag = 0;
5477990Srrh 	for( ; tp->m; ++tp ){
5487990Srrh 		if( v&tp->m ){
5497990Srrh 			if( flag++ ) putchar( '|' );
5507990Srrh 			printf( "%s", tp->nm );
5517990Srrh 			}
5527990Srrh 		}
5537990Srrh 	}
5547990Srrh 
5557990Srrh pst( q ) STAB *q; {
5567990Srrh 	/* give a debugging output for q */
5577990Srrh 
5587990Srrh #ifndef FLEXNAMES
5597990Srrh 	printf( "%.8s (", q->name );
5607990Srrh #else
5617990Srrh 	printf( "%s (", q->name );
5627990Srrh #endif
5637990Srrh 	ptb( q->decflag, dfs );
5647990Srrh 	printf( "), use= " );
5657990Srrh 	ptb( q->use, us );
5667990Srrh 	printf( ", line %d, nargs=%d\n", q->fline, q->nargs );
5677990Srrh 	}
5687990Srrh 
569*11762Sedward pfile() {
570*11762Sedward 	/* print the input file in readable form */
571*11762Sedward 	while( lread( LDI|LIB|LDC|LDX|LRV|LUV|LUE|LUM|LST|LFN ) )
572*11762Sedward 		prc();
573*11762Sedward 	}
574*11762Sedward 
575*11762Sedward prc() {
576*11762Sedward 	/* print out 'r' for debugging */
577*11762Sedward 	register i, j, k;
578*11762Sedward 
579*11762Sedward 	printf( "decflag\t" );
580*11762Sedward 	ptb( r.l.decflag, dfs );
581*11762Sedward 	putchar( '\n' );
582*11762Sedward 	if( r.l.decflag & LFN ){
5837990Srrh #ifdef FLEXNAMES
584*11762Sedward 		printf( "fn\t\t%s\n", r.f.fn );
585*11762Sedward #else
586*11762Sedward 		printf( "fn\t%\t.*s\n", LFNM, r.f.fn );
587*11762Sedward #endif
588*11762Sedward 		}
589*11762Sedward 	else {
590*11762Sedward #ifdef FLEXNAMES
591*11762Sedward 		printf( "name\t%s\n", r.l.name );
592*11762Sedward #else
593*11762Sedward 		printf( "name\t%.*s\n", LCHNM, r.l.name );
594*11762Sedward #endif
595*11762Sedward 		printf( "nargs\t%d\n", r.l.nargs );
596*11762Sedward 		printf( "fline\t%d\n", r.l.fline );
597*11762Sedward 		printf( "type.aty\t0%o (", r.l.type.aty );
598*11762Sedward 		pty( r.l.type.aty, r.l.name );
599*11762Sedward 		printf( ")\ntype.extra\t%d\n", r.l.type.extra );
600*11762Sedward 		j = r.l.type.extra1;
601*11762Sedward 		printf( "type.extra1\t0x%x (%d,%d)\n",
602*11762Sedward 			j, j & X_NONAME ? 1 : 0, j & ~X_NONAME );
603*11762Sedward 		k = r.l.nargs;
604*11762Sedward 		if( k < 0 ) k = -k;
605*11762Sedward 		for( i = 0; i < k; i++ ){
606*11762Sedward 			printf( "atyp[%d].aty\t0%o (", i, atyp[i].aty );
607*11762Sedward 			pty( atyp[i].aty, "" );
608*11762Sedward 			printf( ")\natyp[%d].extra\t%d\n", i, atyp[i].extra);
609*11762Sedward 			j = atyp[i].extra1;
610*11762Sedward 			printf( "atyp[%d].extra1\t0x%x (%d,%d)\n",
611*11762Sedward 				i, j, j & X_NONAME ? 1 : 0, j & ~X_NONAME );
612*11762Sedward 			}
613*11762Sedward 		}
614*11762Sedward 		putchar( '\n' );
615*11762Sedward 	}
616*11762Sedward 
617*11762Sedward pty( t, name )  TWORD t; {
618*11762Sedward 	static char * tnames[] = {
619*11762Sedward 		"void", "farg", "char", "short",
620*11762Sedward 		"int", "long", "float", "double",
621*11762Sedward 		"struct xxx", "union %s", "enum", "moety",
622*11762Sedward 		"unsigned char", "unsigned short", "unsigned", "unsigned long",
623*11762Sedward 		"?", "?"
624*11762Sedward 		};
625*11762Sedward 
626*11762Sedward 	printf( "%s ", tnames[BTYPE(t)] );
627*11762Sedward 	pty1( t, name, (8 * sizeof (int) - BTSHIFT) / TSHIFT );
628*11762Sedward 	}
629*11762Sedward 
630*11762Sedward pty1( t, name, level ) TWORD t; {
631*11762Sedward 	register TWORD u;
632*11762Sedward 
633*11762Sedward 	if( level < 0 ){
634*11762Sedward 		printf( "%s", name );
635*11762Sedward 		return;
636*11762Sedward 		}
637*11762Sedward 	u = t >> level * TSHIFT;
638*11762Sedward 	if( ISPTR(u) ){
639*11762Sedward 		printf( "*" );
640*11762Sedward 		pty1( t, name, level-1 );
641*11762Sedward 		}
642*11762Sedward 	else if( ISFTN(u) ){
643*11762Sedward 		if( level > 0 && ISPTR(u << TSHIFT) ){
644*11762Sedward 			printf( "(" );
645*11762Sedward 			pty1( t, name, level-1 );
646*11762Sedward 			printf( ")()" );
647*11762Sedward 			}
648*11762Sedward 		else {
649*11762Sedward 			pty1( t, name, level-1 );
650*11762Sedward 			printf( "()" );
651*11762Sedward 			}
652*11762Sedward 		}
653*11762Sedward 	else if( ISARY(u) ){
654*11762Sedward 		if( level > 0 && ISPTR(u << TSHIFT) ){
655*11762Sedward 			printf( "(" );
656*11762Sedward 			pty1( t, name, level-1 );
657*11762Sedward 			printf( ")[]" );
658*11762Sedward 			}
659*11762Sedward 		else {
660*11762Sedward 			pty1( t, name, level-1 );
661*11762Sedward 			printf( "[]" );
662*11762Sedward 			}
663*11762Sedward 		}
664*11762Sedward 	else {
665*11762Sedward 		pty1( t, name, level-1 );
666*11762Sedward 		}
667*11762Sedward 	}
668*11762Sedward 
669*11762Sedward #ifdef FLEXNAMES
6707990Srrh char *
6717990Srrh getstr()
6727990Srrh {
6737990Srrh 	char buf[BUFSIZ];
6747990Srrh 	register char *cp = buf;
6757990Srrh 	register int c;
6767990Srrh 
6777990Srrh 	if (feof(stdin) || ferror(stdin))
6787990Srrh 		return("");
6797990Srrh 	while ((c = getchar()) > 0)
6807990Srrh 		*cp++ = c;
6817990Srrh 	if (c < 0) {
682*11762Sedward 		error("intermediate file format error (getstr)");
6837990Srrh 		exit(1);
6847990Srrh 	}
6857990Srrh 	*cp++ = 0;
6867990Srrh 	return (hash(buf));
6877990Srrh }
6887990Srrh 
6897990Srrh #define	NSAVETAB	4096
6907990Srrh char	*savetab;
6917990Srrh int	saveleft;
6927990Srrh 
6937990Srrh char *
6947990Srrh savestr(cp)
6957990Srrh 	register char *cp;
6967990Srrh {
6977990Srrh 	register int len;
6987990Srrh 
6997990Srrh 	len = strlen(cp) + 1;
7007990Srrh 	if (len > saveleft) {
7017990Srrh 		saveleft = NSAVETAB;
7027990Srrh 		if (len > saveleft)
7037990Srrh 			saveleft = len;
7047990Srrh 		savetab = (char *)malloc(saveleft);
7057990Srrh 		if (savetab == 0) {
706*11762Sedward 			error("ran out of memory (savestr)");
7077990Srrh 			exit(1);
7087990Srrh 		}
7097990Srrh 	}
7107990Srrh 	strncpy(savetab, cp, len);
7117990Srrh 	cp = savetab;
7127990Srrh 	savetab += len;
7137990Srrh 	saveleft -= len;
7147990Srrh 	return (cp);
7157990Srrh }
7167990Srrh 
7177990Srrh /*
7187990Srrh  * The definition for the segmented hash tables.
7197990Srrh  */
7207990Srrh #define	MAXHASH	20
7217990Srrh #define	HASHINC	1013
7227990Srrh struct ht {
7237990Srrh 	char	**ht_low;
7247990Srrh 	char	**ht_high;
7257990Srrh 	int	ht_used;
7267990Srrh } htab[MAXHASH];
7277990Srrh 
7287990Srrh char *
7297990Srrh hash(s)
7307990Srrh 	char *s;
7317990Srrh {
7327990Srrh 	register char **h;
7337990Srrh 	register i;
7347990Srrh 	register char *cp;
7357990Srrh 	struct ht *htp;
7367990Srrh 	int sh;
7377990Srrh 
738*11762Sedward 	sh = hashstr(s) % HASHINC;
7397990Srrh 	cp = s;
7407990Srrh 	/*
7417990Srrh 	 * There are as many as MAXHASH active
7427990Srrh 	 * hash tables at any given point in time.
7437990Srrh 	 * The search starts with the first table
7447990Srrh 	 * and continues through the active tables
7457990Srrh 	 * as necessary.
7467990Srrh 	 */
7477990Srrh 	for (htp = htab; htp < &htab[MAXHASH]; htp++) {
7487990Srrh 		if (htp->ht_low == 0) {
7497990Srrh 			register char **hp =
7507990Srrh 			    (char **) calloc(sizeof (char **), HASHINC);
7517990Srrh 			if (hp == 0) {
752*11762Sedward 				error("ran out of memory (hash)");
7537990Srrh 				exit(1);
7547990Srrh 			}
7557990Srrh 			htp->ht_low = hp;
7567990Srrh 			htp->ht_high = htp->ht_low + HASHINC;
7577990Srrh 		}
7587990Srrh 		h = htp->ht_low + sh;
7597990Srrh 		/*
7607990Srrh 		 * quadratic rehash increment
7617990Srrh 		 * starts at 1 and incremented
7627990Srrh 		 * by two each rehash.
7637990Srrh 		 */
7647990Srrh 		i = 1;
7657990Srrh 		do {
7667990Srrh 			if (*h == 0) {
7677990Srrh 				if (htp->ht_used > (HASHINC * 3)/4)
7687990Srrh 					break;
7697990Srrh 				htp->ht_used++;
7707990Srrh 				*h = savestr(cp);
7717990Srrh 				return (*h);
7727990Srrh 			}
7737990Srrh 			if (**h == *cp && strcmp(*h, cp) == 0)
7747990Srrh 				return (*h);
7757990Srrh 			h += i;
7767990Srrh 			i += 2;
7777990Srrh 			if (h >= htp->ht_high)
7787990Srrh 				h -= HASHINC;
7797990Srrh 		} while (i < HASHINC);
7807990Srrh 	}
781*11762Sedward 	error("ran out of hash tables");
7827990Srrh 	exit(1);
7837990Srrh }
7847990Srrh char	*tstrbuf[1];
7857990Srrh #endif
786