xref: /csrg-svn/old/pcc/lint/lpass2/lpass2.c (revision 41771)
17990Srrh #ifndef lint
2*41771Smckusick static char sccsid[] = "@(#)lpass2.c	1.12	(Berkeley)	05/12/90";
37990Srrh #endif lint
47990Srrh 
518599Sralph # include "macdefs.h"
618599Sralph # include "manifest.h"
718599Sralph # include "lmanifest.h"
87990Srrh 
97990Srrh # define USED 01
107990Srrh # define VUSED 02
117990Srrh # define EUSED 04
127990Srrh # define RVAL 010
137990Srrh # define VARARGS 0100
147990Srrh 
1526319Skarels # define NSZ 4096
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;
6511762Sedward int zflag = 0;
6611762Sedward int Pflag = 0;
677990Srrh 
687990Srrh int cfno;  /* current file number */
697990Srrh 
main(argc,argv)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 
10011762Sedward 			case 'z':
10111762Sedward 				zflag = 1;
10211762Sedward 				break;
10311762Sedward 
10411762Sedward 			case 'P':
10511762Sedward 				Pflag = 1;
10611762Sedward 				break;
10711762Sedward 
1087990Srrh 				}
1097990Srrh 			}
1107990Srrh 		}
1117990Srrh 
1127990Srrh 	if( argc < 2 || !freopen( argv[1], "r", stdin ) ){
1137990Srrh 		error( "cannot open intermediate file" );
1147990Srrh 		exit( 1 );
1157990Srrh 		}
11611762Sedward 	if( Pflag ){
11711762Sedward 		pfile();
11811762Sedward 		return( 0 );
11911762Sedward 		}
12011762Sedward 	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 
mloop(m)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 
lread(m)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
14930938Sbostic 			r.f.fn = getstr(0);
1507990Srrh #endif
15111762Sedward 			if( Pflag ) return( 1 );
1527990Srrh 			setfno( r.f.fn );
1537990Srrh 			continue;
1547990Srrh 			}
1557990Srrh #ifdef FLEXNAMES
15630938Sbostic 		r.l.name = getstr(1);
15730938Sbostic #else /* !FLEXNAMES */
15830938Sbostic 		portify(r.l.name);
15930938Sbostic #endif /* !FLEXNAMES */
1607990Srrh 		n = r.l.nargs;
16132981Sdonn 		if( n<0 ) n = ~n;
16211762Sedward 		if( n>=NTY ) error( "more than %d args?", n );
16311762Sedward 		fread( (char *)atyp, sizeof(ATYPE), n, stdin );
1647990Srrh 		if( ( r.l.decflag & m ) ) return( 1 );
1657990Srrh 		}
1667990Srrh 	}
1677990Srrh 
setfno(s)1687990Srrh setfno( s ) char *s; {
1697990Srrh 	/* look up current file names */
1707990Srrh 	/* first, strip backwards to the beginning or to the first / */
1717990Srrh 	int i;
1727990Srrh 
1737990Srrh 	/* now look up s */
1747990Srrh 	for( i=0; i<ffree; ++i ){
1757990Srrh #ifndef FLEXNAMES
17611762Sedward 		if( !strncmp( s, fnm[i], LFNM ) )
1777990Srrh #else
17811762Sedward 		if (fnm[i] == s)
1797990Srrh #endif
18011762Sedward 			{
1817990Srrh 			cfno = i;
1827990Srrh 			return;
1837990Srrh 			}
1847990Srrh 		}
1857990Srrh 	/* make a new entry */
1867990Srrh 	if( ffree >= FSZ ) error( "more than %d files", FSZ );
1877990Srrh #ifndef FLEXNAMES
1887990Srrh 	strncpy( fnm[ffree], s, LFNM );
1897990Srrh #else
1907990Srrh 	fnm[ffree] = s;
1917990Srrh #endif
1927990Srrh 	cfno = ffree++;
1937990Srrh 	}
1947990Srrh 
1957990Srrh /* VARARGS */
error(s,a)1967990Srrh error( s, a ) char *s; {
1977990Srrh 
1987990Srrh #ifndef FLEXNAMES
1997990Srrh 	fprintf( stderr, "pass 2 error:(file %.*s) ", LFNM, fnm[cfno] );
2007990Srrh #else
2017990Srrh 	fprintf( stderr, "pass 2 error:(file %s) ", fnm[cfno] );
2027990Srrh #endif
2037990Srrh 	fprintf( stderr, s, a );
2047990Srrh 	fprintf( stderr, "\n" );
2057990Srrh 	exit(1);
2067990Srrh 	}
2077990Srrh 
2087990Srrh STAB *
find()2097990Srrh find(){
2107990Srrh 	register h=0;
2117990Srrh #ifndef FLEXNAMES
21211762Sedward 	h = hashstr(r.l.name, LCHNM) % NSZ;
2137990Srrh #else
214*41771Smckusick 	h = (int)r.l.name % NSZ;
2157990Srrh #endif
2167990Srrh 	{	register STAB *p, *q;
2177990Srrh 		for( p=q= &stab[h]; q->decflag; ){
2187990Srrh #ifndef FLEXNAMES
21911762Sedward 			if( !strncmp( r.l.name, q->name, LCHNM))
2207990Srrh #else
221*41771Smckusick 			if (r.l.name == q->name)
2227990Srrh #endif
22311762Sedward 				if( ((q->decflag|r.l.decflag)&LST)==0 || q->fno==cfno )
22411762Sedward 					return(q);
2257990Srrh 			if( ++q >= &stab[NSZ] ) q = stab;
2267990Srrh 			if( q == p ) error( "too many names defined" );
2277990Srrh 			}
2287990Srrh #ifndef FLEXNAMES
2297990Srrh 		strncpy( q->name, r.l.name, LCHNM );
2307990Srrh #else
2317990Srrh 		q->name = r.l.name;
2327990Srrh #endif
2337990Srrh 		return( q );
2347990Srrh 		}
2357990Srrh 	}
2367990Srrh 
2377990Srrh STYPE *
tget()2387990Srrh tget(){
2397990Srrh 	if( tfree >= TYSZ ){
2407990Srrh 		error( "too many types needed" );
2417990Srrh 		}
2427990Srrh 	return( &tary[tfree++] );
2437990Srrh 	}
2447990Srrh 
chkcompat(q)2457990Srrh chkcompat(q) STAB *q; {
2467990Srrh 	/* are the types, etc. in r.l and q compatible */
2477990Srrh 	register int i;
2487990Srrh 	STYPE *qq;
2497990Srrh 
2507990Srrh 	setuse(q);
2517990Srrh 
2527990Srrh 	/* argument check */
2537990Srrh 
25411762Sedward 	if( q->decflag & (LDI|LIB|LUV|LUE|LST) ){
2557990Srrh 		if( r.l.decflag & (LUV|LIB|LUE) ){
2567990Srrh 			if( q->nargs != r.l.nargs ){
2577990Srrh 				if( !(q->use&VARARGS) ){
2587990Srrh #ifndef FLEXNAMES
2597990Srrh 					printf( "%.8s: variable # of args.", q->name );
2607990Srrh #else
2617990Srrh 					printf( "%s: variable # of args.", q->name );
2627990Srrh #endif
2637990Srrh 					viceversa(q);
2647990Srrh 					}
2657990Srrh 				if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs;
26611762Sedward 				if( !(q->decflag & (LDI|LIB|LST) ) ) {
2677990Srrh 					q->nargs = r.l.nargs;
2687990Srrh 					q->use |= VARARGS;
2697990Srrh 					}
2707990Srrh 				}
2717990Srrh 			for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next){
27230939Sbostic 				if( chktype( &qq->t, &atyp[i], q->fno ) ){
2737990Srrh #ifndef FLEXNAMES
2747990Srrh 					printf( "%.8s, arg. %d used inconsistently",
2757990Srrh #else
2767990Srrh 					printf( "%s, arg. %d used inconsistently",
2777990Srrh #endif
2787990Srrh 						q->name, i+1 );
2797990Srrh 					viceversa(q);
2807990Srrh 					}
2817990Srrh 				}
2827990Srrh 			}
2837990Srrh 		}
2847990Srrh 
28511762Sedward 	if( (q->decflag&(LDI|LIB|LUV|LST)) && r.l.decflag==LUV ){
28630939Sbostic 		if( chktype( &r.l.type, &q->symty.t, q->fno ) ){
2877990Srrh #ifndef FLEXNAMES
2887990Srrh 			printf( "%.8s value used inconsistently", q->name );
2897990Srrh #else
2907990Srrh 			printf( "%s value used inconsistently", q->name );
2917990Srrh #endif
2927990Srrh 			viceversa(q);
2937990Srrh 			}
2947990Srrh 		}
2957990Srrh 
2967990Srrh 	/* check for multiple declaration */
2977990Srrh 
29811762Sedward 	if( (q->decflag&(LDI|LST)) && (r.l.decflag&(LDI|LIB|LST)) ){
2997990Srrh #ifndef FLEXNAMES
3007990Srrh 		printf( "%.8s multiply declared", q->name );
3017990Srrh #else
3027990Srrh 		printf( "%s multiply declared", q->name );
3037990Srrh #endif
3047990Srrh 		viceversa(q);
3057990Srrh 		}
3067990Srrh 
3077990Srrh 	/* do a bit of checking of definitions and uses... */
3087990Srrh 
30911762Sedward 	if( (q->decflag & (LDI|LIB|LDX|LDC|LUM|LST)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){
3107990Srrh #ifndef FLEXNAMES
3117990Srrh 		printf( "%.8s value declared inconsistently", q->name );
3127990Srrh #else
3137990Srrh 		printf( "%s value declared inconsistently", q->name );
3147990Srrh #endif
3157990Srrh 		viceversa(q);
3167990Srrh 		}
3177990Srrh 
3187990Srrh 	/* better not call functions which are declared to be structure or union returning */
3197990Srrh 
32011762Sedward 	if( (q->decflag & (LDI|LIB|LDX|LDC|LST)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){
3217990Srrh 		/* only matters if the function returns union or structure */
3227990Srrh 		TWORD ty;
3237990Srrh 		ty = q->symty.t.aty;
3247990Srrh 		if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){
3257990Srrh #ifndef FLEXNAMES
3267990Srrh 			printf( "%.8s function value type must be declared before use", q->name );
3277990Srrh #else
3287990Srrh 			printf( "%s function value type must be declared before use", q->name );
3297990Srrh #endif
3307990Srrh 			viceversa(q);
3317990Srrh 			}
3327990Srrh 		}
3337990Srrh 
3347990Srrh 	if( pflag && q->decflag==LDX && r.l.decflag == LUM && !ISFTN(q->symty.t.aty) ){
3357990Srrh 		/* make the external declaration go away */
3367990Srrh 		/* in effect, it was used without being defined */
3377990Srrh 		}
3387990Srrh 	}
3397990Srrh 
viceversa(q)3407990Srrh viceversa(q) STAB *q; {
3417990Srrh 	/* print out file comparison */
3427990Srrh #ifndef FLEXNAMES
3437990Srrh 	printf( "	%.*s(%d)  ::  %.*s(%d)\n",
3447990Srrh 		LFNM, fnm[q->fno], q->fline,
3457990Srrh 		LFNM, fnm[cfno], r.l.fline );
3467990Srrh #else
3477990Srrh 	printf( "	%s(%d)  ::  %s(%d)\n",
3487990Srrh 		fnm[q->fno], q->fline,
3497990Srrh 		fnm[cfno], r.l.fline );
3507990Srrh #endif
3517990Srrh 	}
3527990Srrh 
3537990Srrh 	/* messages for defintion/use */
3547990Srrh char *
3557990Srrh mess[2][2] ={
3567990Srrh 	"",
3577990Srrh #ifndef FLEXNAMES
3587990Srrh 	"%.8s used( %.*s(%d) ), but not defined\n",
3597990Srrh 	"%.8s defined( %.*s(%d) ), but never used\n",
3607990Srrh 	"%.8s declared( %.*s(%d) ), but never used or defined\n"
3617990Srrh #else
3627990Srrh 	"%s used( %s(%d) ), but not defined\n",
3637990Srrh 	"%s defined( %s(%d) ), but never used\n",
3647990Srrh 	"%s declared( %s(%d) ), but never used or defined\n"
3657990Srrh #endif
3667990Srrh 	};
3677990Srrh 
lastone(q)3687990Srrh lastone(q) STAB *q; {
3697990Srrh 
3707990Srrh 	register nu, nd, uses;
3717990Srrh 
3727990Srrh 	if( ddddd ) pst(q);
3737990Srrh 
3747990Srrh 	nu = nd = 0;
3757990Srrh 	uses = q->use;
3767990Srrh 
3777990Srrh 	if( !(uses&USED) && q->decflag != LIB ) {
3787990Srrh #ifndef FLEXNAMES
3797990Srrh 		if( strncmp(q->name,"main",7) )
3807990Srrh #else
3817990Srrh 		if (strcmp(q->name, "main"))
3827990Srrh #endif
3837990Srrh 			nu = 1;
3847990Srrh 		}
3857990Srrh 
386*41771Smckusick 	if( !ISFTN(q->symty.t.aty) ){
387*41771Smckusick 		switch( q->decflag ){
3887990Srrh 
389*41771Smckusick 		case LIB:
390*41771Smckusick 			nu = nd = 0;  /* don't complain about uses on libraries */
391*41771Smckusick 			break;
392*41771Smckusick 		case LDX:
393*41771Smckusick 			if( !xflag ) break;
394*41771Smckusick 		case LUV:
395*41771Smckusick 		case LUE:
3967990Srrh /* 01/04/80 */	case LUV | LUE:
397*41771Smckusick 		case LUM:
398*41771Smckusick 			nd = 1;
399*41771Smckusick 			}
400*41771Smckusick 		}
40111762Sedward 	if( uflag && ( nu || nd ) )
4027990Srrh #ifndef FLEXNAMES
40311762Sedward 		printf( mess[nu][nd], q->name, LFNM, fnm[q->fno], q->fline );
4047990Srrh #else
40511762Sedward 		printf( mess[nu][nd], q->name, fnm[q->fno], q->fline );
4067990Srrh #endif
4077990Srrh 
4087990Srrh 	if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
40911762Sedward 		/* if functions is static, then print the file name too */
41011762Sedward 		if( q->decflag & LST )
4117990Srrh #ifndef FLEXNAMES
41211762Sedward 			printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline );
4137990Srrh #else
41411762Sedward 			printf( "%s(%d):", fnm[q->fno], q->fline );
4157990Srrh #endif
41611762Sedward #ifndef FLEXNAMES
41711762Sedward 		printf( "%.*s returns value which is %s ignored\n",
41811762Sedward 			LCHNM, q->name, uses&VUSED ? "sometimes" : "always" );
41911762Sedward #else
42011762Sedward 		printf( "%s returns value which is %s ignored\n",
42111762Sedward 			q->name, uses&VUSED ? "sometimes" : "always" );
42211762Sedward #endif
4237990Srrh 		}
4247990Srrh 
42511762Sedward 	if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB|LST)) ){
42611762Sedward 		if( q->decflag & LST )
4277990Srrh #ifndef FLEXNAMES
42811762Sedward 			printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline );
4297990Srrh #else
43011762Sedward 			printf( "%s(%d):", fnm[q->fno], q->fline );
4317990Srrh #endif
43211762Sedward #ifndef FLEXNAMES
43311762Sedward 		printf( "%.*s value is used, but none returned\n",
43411762Sedward 			LCHNM, q->name);
43511762Sedward #else
43611762Sedward 		printf( "%s value is used, but none returned\n", q->name);
43711762Sedward #endif
4387990Srrh 		}
4397990Srrh 	}
4407990Srrh 
cleanup()4417990Srrh cleanup(){ /* call lastone and die gracefully */
4427990Srrh 	STAB *q;
4437990Srrh 	for( q=stab; q< &stab[NSZ]; ++q ){
4447990Srrh 		if( q->decflag ) lastone(q);
4457990Srrh 		}
4467990Srrh 	exit(0);
4477990Srrh 	}
4487990Srrh 
setuse(q)4497990Srrh setuse(q) STAB *q; { /* check new type to ensure that it is used */
4507990Srrh 
4517990Srrh 	if( !q->decflag ){ /* new one */
4527990Srrh 		q->decflag = r.l.decflag;
4537990Srrh 		q->symty.t = r.l.type;
4547990Srrh 		if( r.l.nargs < 0 ){
45532981Sdonn 			q->nargs = ~r.l.nargs;
4567990Srrh 			q->use = VARARGS;
4577990Srrh 			}
4587990Srrh 		else {
4597990Srrh 			q->nargs = r.l.nargs;
4607990Srrh 			q->use = 0;
4617990Srrh 			}
4627990Srrh 		q->fline = r.l.fline;
4637990Srrh 		q->fno = cfno;
4647990Srrh 		if( q->nargs ){
4657990Srrh 			int i;
4667990Srrh 			STYPE *qq;
4677990Srrh 			for( i=0,qq= &q->symty; i<q->nargs; ++i,qq=qq->next ){
4687990Srrh 				qq->next = tget();
4697990Srrh 				qq->next->t = atyp[i];
4707990Srrh 				}
4717990Srrh 			}
4727990Srrh 		}
4737990Srrh 
4747990Srrh 	switch( r.l.decflag ){
4757990Srrh 
4767990Srrh 	case LRV:
4777990Srrh 		q->use |= RVAL;
4787990Srrh 		return;
4797990Srrh 	case LUV:
4807990Srrh 		q->use |= VUSED+USED;
4817990Srrh 		return;
4827990Srrh 	case LUE:
4837990Srrh 		q->use |= EUSED+USED;
4847990Srrh 		return;
4857990Srrh /* 01/04/80 */	case LUV | LUE:
4867990Srrh 	case LUM:
4877990Srrh 		q->use |= USED;
4887990Srrh 		return;
4897990Srrh 
4907990Srrh 		}
4917990Srrh 	}
4927990Srrh 
chktype(pt1,pt2,fno)49330939Sbostic chktype( pt1, pt2, fno ) register ATYPE *pt1, *pt2; {
4947990Srrh 	TWORD t;
4957990Srrh 
4967990Srrh 	/* check the two type words to see if they are compatible */
4977990Srrh 	/* for the moment, enums are turned into ints, and should be checked as such */
4987990Srrh 	if( pt1->aty == ENUMTY ) pt1->aty =  INT;
4997990Srrh 	if( pt2->aty == ENUMTY ) pt2->aty = INT;
5007990Srrh 
5017990Srrh 	if( (t=BTYPE(pt1->aty)==STRTY) || t==UNIONTY ){
50211762Sedward 		if( pt1->aty != pt2->aty || pt1->extra1 != pt2->extra1 )
50311762Sedward 			return 1;
50411762Sedward 		/* if -z then don't worry about undefined structures,
50511762Sedward 		   as long as the names match */
50611762Sedward 		if( zflag && (pt1->extra == 0 || pt2->extra == 0) ) return 0;
50730939Sbostic 		/* if -p and pt1 is "too big" and
50830939Sbostic 		** pt1 came from a llib-l file, we can't pass judgment on it.
50930939Sbostic 		*/
51030939Sbostic 		if ( pflag && pt1->extra > pt2->extra &&
51130939Sbostic 			strncmp(fnm[fno], "llib-l", 6) == 0)
51230939Sbostic 				return 0;
51311762Sedward 		return pt1->extra != pt2->extra;
5147990Srrh 		}
5157990Srrh 
5167990Srrh 	if( pt2->extra ){ /* constant passed in */
5177990Srrh 		if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
5187990Srrh 		else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
5197990Srrh 		}
5207990Srrh 	else if( pt1->extra ){ /* for symmetry */
5217990Srrh 		if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
5227990Srrh 		else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
5237990Srrh 		}
5247990Srrh 
5257990Srrh 	return( pt1->aty != pt2->aty );
5267990Srrh 	}
5277990Srrh 
52835255Sbostic struct tb { int m; char *nm; };
52911762Sedward 
53011762Sedward struct tb dfs[] = {
53111762Sedward 	LDI, "LDI",
53211762Sedward 	LIB, "LIB",
53311762Sedward 	LDC, "LDC",
53411762Sedward 	LDX, "LDX",
53511762Sedward 	LRV, "LRV",
53611762Sedward 	LUV, "LUV",
53711762Sedward 	LUE, "LUE",
53811762Sedward 	LUM, "LUM",
53911762Sedward 	LST, "LST",
54011762Sedward 	LFN, "LFN",
54111762Sedward 	0, "" };
54211762Sedward 
54311762Sedward struct tb us[] = {
54411762Sedward 	USED, "USED",
54511762Sedward 	VUSED, "VUSED",
54611762Sedward 	EUSED, "EUSED",
54711762Sedward 	RVAL, "RVAL",
54811762Sedward 	VARARGS, "VARARGS",
54911762Sedward 	0, "" };
55011762Sedward 
5517990Srrh ptb( v, tp ) struct tb *tp; {
5527990Srrh 	/* print a value from the table */
5537990Srrh 	int flag;
5547990Srrh 	flag = 0;
5557990Srrh 	for( ; tp->m; ++tp ){
5567990Srrh 		if( v&tp->m ){
5577990Srrh 			if( flag++ ) putchar( '|' );
5587990Srrh 			printf( "%s", tp->nm );
5597990Srrh 			}
5607990Srrh 		}
5617990Srrh 	}
5627990Srrh 
pst(q)5637990Srrh pst( q ) STAB *q; {
5647990Srrh 	/* give a debugging output for q */
5657990Srrh 
5667990Srrh #ifndef FLEXNAMES
5677990Srrh 	printf( "%.8s (", q->name );
5687990Srrh #else
5697990Srrh 	printf( "%s (", q->name );
5707990Srrh #endif
5717990Srrh 	ptb( q->decflag, dfs );
5727990Srrh 	printf( "), use= " );
5737990Srrh 	ptb( q->use, us );
5747990Srrh 	printf( ", line %d, nargs=%d\n", q->fline, q->nargs );
5757990Srrh 	}
5767990Srrh 
pfile()57711762Sedward pfile() {
57811762Sedward 	/* print the input file in readable form */
57911762Sedward 	while( lread( LDI|LIB|LDC|LDX|LRV|LUV|LUE|LUM|LST|LFN ) )
58011762Sedward 		prc();
58111762Sedward 	}
58211762Sedward 
prc()58311762Sedward prc() {
58411762Sedward 	/* print out 'r' for debugging */
58511762Sedward 	register i, j, k;
58611762Sedward 
58711762Sedward 	printf( "decflag\t" );
58811762Sedward 	ptb( r.l.decflag, dfs );
58911762Sedward 	putchar( '\n' );
59011762Sedward 	if( r.l.decflag & LFN ){
5917990Srrh #ifdef FLEXNAMES
59211762Sedward 		printf( "fn\t\t%s\n", r.f.fn );
59311762Sedward #else
59411762Sedward 		printf( "fn\t%\t.*s\n", LFNM, r.f.fn );
59511762Sedward #endif
59611762Sedward 		}
59711762Sedward 	else {
59811762Sedward #ifdef FLEXNAMES
59911762Sedward 		printf( "name\t%s\n", r.l.name );
60011762Sedward #else
60111762Sedward 		printf( "name\t%.*s\n", LCHNM, r.l.name );
60211762Sedward #endif
60311762Sedward 		printf( "nargs\t%d\n", r.l.nargs );
60411762Sedward 		printf( "fline\t%d\n", r.l.fline );
60511762Sedward 		printf( "type.aty\t0%o (", r.l.type.aty );
60611762Sedward 		pty( r.l.type.aty, r.l.name );
60711762Sedward 		printf( ")\ntype.extra\t%d\n", r.l.type.extra );
60811762Sedward 		j = r.l.type.extra1;
60911762Sedward 		printf( "type.extra1\t0x%x (%d,%d)\n",
61011762Sedward 			j, j & X_NONAME ? 1 : 0, j & ~X_NONAME );
61111762Sedward 		k = r.l.nargs;
61232981Sdonn 		if( k < 0 ) k = ~k;
61311762Sedward 		for( i = 0; i < k; i++ ){
61411762Sedward 			printf( "atyp[%d].aty\t0%o (", i, atyp[i].aty );
61511762Sedward 			pty( atyp[i].aty, "" );
61611762Sedward 			printf( ")\natyp[%d].extra\t%d\n", i, atyp[i].extra);
61711762Sedward 			j = atyp[i].extra1;
61811762Sedward 			printf( "atyp[%d].extra1\t0x%x (%d,%d)\n",
61911762Sedward 				i, j, j & X_NONAME ? 1 : 0, j & ~X_NONAME );
62011762Sedward 			}
62111762Sedward 		}
62211762Sedward 		putchar( '\n' );
62311762Sedward 	}
62411762Sedward 
pty(t,name)62511762Sedward pty( t, name )  TWORD t; {
62611762Sedward 	static char * tnames[] = {
62711762Sedward 		"void", "farg", "char", "short",
62811762Sedward 		"int", "long", "float", "double",
62911762Sedward 		"struct xxx", "union %s", "enum", "moety",
63011762Sedward 		"unsigned char", "unsigned short", "unsigned", "unsigned long",
63111762Sedward 		"?", "?"
63211762Sedward 		};
63311762Sedward 
63411762Sedward 	printf( "%s ", tnames[BTYPE(t)] );
63511762Sedward 	pty1( t, name, (8 * sizeof (int) - BTSHIFT) / TSHIFT );
63611762Sedward 	}
63711762Sedward 
pty1(t,name,level)63811762Sedward pty1( t, name, level ) TWORD t; {
63911762Sedward 	register TWORD u;
64011762Sedward 
64111762Sedward 	if( level < 0 ){
64211762Sedward 		printf( "%s", name );
64311762Sedward 		return;
64411762Sedward 		}
64511762Sedward 	u = t >> level * TSHIFT;
64611762Sedward 	if( ISPTR(u) ){
64711762Sedward 		printf( "*" );
64811762Sedward 		pty1( t, name, level-1 );
64911762Sedward 		}
65011762Sedward 	else if( ISFTN(u) ){
65111762Sedward 		if( level > 0 && ISPTR(u << TSHIFT) ){
65211762Sedward 			printf( "(" );
65311762Sedward 			pty1( t, name, level-1 );
65411762Sedward 			printf( ")()" );
65511762Sedward 			}
65611762Sedward 		else {
65711762Sedward 			pty1( t, name, level-1 );
65811762Sedward 			printf( "()" );
65911762Sedward 			}
66011762Sedward 		}
66111762Sedward 	else if( ISARY(u) ){
66211762Sedward 		if( level > 0 && ISPTR(u << TSHIFT) ){
66311762Sedward 			printf( "(" );
66411762Sedward 			pty1( t, name, level-1 );
66511762Sedward 			printf( ")[]" );
66611762Sedward 			}
66711762Sedward 		else {
66811762Sedward 			pty1( t, name, level-1 );
66911762Sedward 			printf( "[]" );
67011762Sedward 			}
67111762Sedward 		}
67211762Sedward 	else {
67311762Sedward 		pty1( t, name, level-1 );
67411762Sedward 		}
67511762Sedward 	}
67611762Sedward 
67711762Sedward #ifdef FLEXNAMES
6787990Srrh char *
getstr(doport)67930938Sbostic getstr(doport)
6807990Srrh {
6817990Srrh 	char buf[BUFSIZ];
6827990Srrh 	register char *cp = buf;
6837990Srrh 	register int c;
6847990Srrh 
6857990Srrh 	if (feof(stdin) || ferror(stdin))
6867990Srrh 		return("");
6877990Srrh 	while ((c = getchar()) > 0)
6887990Srrh 		*cp++ = c;
6897990Srrh 	if (c < 0) {
69011762Sedward 		error("intermediate file format error (getstr)");
6917990Srrh 		exit(1);
6927990Srrh 	}
6937990Srrh 	*cp++ = 0;
69430938Sbostic 	if (doport)
69530938Sbostic 		portify(buf);
6967990Srrh 	return (hash(buf));
6977990Srrh }
6987990Srrh 
6997990Srrh #define	NSAVETAB	4096
7007990Srrh char	*savetab;
7017990Srrh int	saveleft;
7027990Srrh 
7037990Srrh char *
savestr(cp)7047990Srrh savestr(cp)
7057990Srrh 	register char *cp;
7067990Srrh {
7077990Srrh 	register int len;
7087990Srrh 
7097990Srrh 	len = strlen(cp) + 1;
7107990Srrh 	if (len > saveleft) {
7117990Srrh 		saveleft = NSAVETAB;
7127990Srrh 		if (len > saveleft)
7137990Srrh 			saveleft = len;
7147990Srrh 		savetab = (char *)malloc(saveleft);
7157990Srrh 		if (savetab == 0) {
71611762Sedward 			error("ran out of memory (savestr)");
7177990Srrh 			exit(1);
7187990Srrh 		}
7197990Srrh 	}
7207990Srrh 	strncpy(savetab, cp, len);
7217990Srrh 	cp = savetab;
7227990Srrh 	savetab += len;
7237990Srrh 	saveleft -= len;
7247990Srrh 	return (cp);
7257990Srrh }
7267990Srrh 
7277990Srrh /*
7287990Srrh  * The definition for the segmented hash tables.
7297990Srrh  */
7307990Srrh #define	MAXHASH	20
7317990Srrh #define	HASHINC	1013
7327990Srrh struct ht {
7337990Srrh 	char	**ht_low;
7347990Srrh 	char	**ht_high;
7357990Srrh 	int	ht_used;
7367990Srrh } htab[MAXHASH];
7377990Srrh 
7387990Srrh char *
hash(s)7397990Srrh hash(s)
7407990Srrh 	char *s;
7417990Srrh {
7427990Srrh 	register char **h;
7437990Srrh 	register i;
7447990Srrh 	register char *cp;
7457990Srrh 	struct ht *htp;
7467990Srrh 	int sh;
7477990Srrh 
74811762Sedward 	sh = hashstr(s) % HASHINC;
7497990Srrh 	cp = s;
7507990Srrh 	/*
7517990Srrh 	 * There are as many as MAXHASH active
7527990Srrh 	 * hash tables at any given point in time.
7537990Srrh 	 * The search starts with the first table
7547990Srrh 	 * and continues through the active tables
7557990Srrh 	 * as necessary.
7567990Srrh 	 */
7577990Srrh 	for (htp = htab; htp < &htab[MAXHASH]; htp++) {
7587990Srrh 		if (htp->ht_low == 0) {
7597990Srrh 			register char **hp =
7607990Srrh 			    (char **) calloc(sizeof (char **), HASHINC);
7617990Srrh 			if (hp == 0) {
76211762Sedward 				error("ran out of memory (hash)");
7637990Srrh 				exit(1);
7647990Srrh 			}
7657990Srrh 			htp->ht_low = hp;
7667990Srrh 			htp->ht_high = htp->ht_low + HASHINC;
7677990Srrh 		}
7687990Srrh 		h = htp->ht_low + sh;
7697990Srrh 		/*
7707990Srrh 		 * quadratic rehash increment
7717990Srrh 		 * starts at 1 and incremented
7727990Srrh 		 * by two each rehash.
7737990Srrh 		 */
7747990Srrh 		i = 1;
7757990Srrh 		do {
7767990Srrh 			if (*h == 0) {
7777990Srrh 				if (htp->ht_used > (HASHINC * 3)/4)
7787990Srrh 					break;
7797990Srrh 				htp->ht_used++;
7807990Srrh 				*h = savestr(cp);
7817990Srrh 				return (*h);
7827990Srrh 			}
7837990Srrh 			if (**h == *cp && strcmp(*h, cp) == 0)
7847990Srrh 				return (*h);
7857990Srrh 			h += i;
7867990Srrh 			i += 2;
7877990Srrh 			if (h >= htp->ht_high)
7887990Srrh 				h -= HASHINC;
7897990Srrh 		} while (i < HASHINC);
7907990Srrh 	}
79111762Sedward 	error("ran out of hash tables");
7927990Srrh 	exit(1);
7937990Srrh }
7947990Srrh char	*tstrbuf[1];
7957990Srrh #endif
79630938Sbostic 
79730938Sbostic #include "ctype.h"
79830938Sbostic 
portify(cp)79930938Sbostic portify(cp)
80030938Sbostic register char *	cp;
80130938Sbostic {
80230938Sbostic 	register int	i;
80330938Sbostic 
80430938Sbostic 	if (!pflag)
80530938Sbostic 		return;
80630938Sbostic 	for (i = 0; i < 6; ++i)
80730938Sbostic 		if (cp[i] == '\0')
80830938Sbostic 			return;
80930938Sbostic 		else if (isascii(cp[i]) && isupper(cp[i]))
81030938Sbostic 			cp[i] = tolower(cp[i]);
81130938Sbostic 	cp[i] = '\0';
81230938Sbostic }
813