xref: /csrg-svn/old/pcc/lint/lpass2/lpass2.c (revision 26319)
17990Srrh #ifndef lint
2*26319Skarels static char sccsid[] = "@(#)lpass2.c	1.6	(Berkeley)	02/21/86";
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 
15*26319Skarels # 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 
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 
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
15111762Sedward 			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;
16011762Sedward 		if( n>=NTY ) error( "more than %d args?", n );
16111762Sedward 		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
17411762Sedward 		if( !strncmp( s, fnm[i], LFNM ) )
1757990Srrh #else
17611762Sedward 		if (fnm[i] == s)
1777990Srrh #endif
17811762Sedward 			{
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
21011762Sedward 	h = hashstr(r.l.name, LCHNM) % NSZ;
2117990Srrh #else
21211762Sedward 	h = (int)r.l.name % NSZ;
2137990Srrh #endif
2147990Srrh 	{	register STAB *p, *q;
2157990Srrh 		for( p=q= &stab[h]; q->decflag; ){
2167990Srrh #ifndef FLEXNAMES
21711762Sedward 			if( !strncmp( r.l.name, q->name, LCHNM))
2187990Srrh #else
21911762Sedward 			if (r.l.name == q->name)
2207990Srrh #endif
22111762Sedward 				if( ((q->decflag|r.l.decflag)&LST)==0 || q->fno==cfno )
22211762Sedward 					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 
25211762Sedward 	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;
26411762Sedward 				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 
28311762Sedward 	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 
29611762Sedward 	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 
30711762Sedward 	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 
31811762Sedward 	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 		}
39911762Sedward 	if( uflag && ( nu || nd ) )
4007990Srrh #ifndef FLEXNAMES
40111762Sedward 		printf( mess[nu][nd], q->name, LFNM, fnm[q->fno], q->fline );
4027990Srrh #else
40311762Sedward 		printf( mess[nu][nd], q->name, fnm[q->fno], q->fline );
4047990Srrh #endif
4057990Srrh 
4067990Srrh 	if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
40711762Sedward 		/* if functions is static, then print the file name too */
40811762Sedward 		if( q->decflag & LST )
4097990Srrh #ifndef FLEXNAMES
41011762Sedward 			printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline );
4117990Srrh #else
41211762Sedward 			printf( "%s(%d):", fnm[q->fno], q->fline );
4137990Srrh #endif
41411762Sedward #ifndef FLEXNAMES
41511762Sedward 		printf( "%.*s returns value which is %s ignored\n",
41611762Sedward 			LCHNM, q->name, uses&VUSED ? "sometimes" : "always" );
41711762Sedward #else
41811762Sedward 		printf( "%s returns value which is %s ignored\n",
41911762Sedward 			q->name, uses&VUSED ? "sometimes" : "always" );
42011762Sedward #endif
4217990Srrh 		}
4227990Srrh 
42311762Sedward 	if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB|LST)) ){
42411762Sedward 		if( q->decflag & LST )
4257990Srrh #ifndef FLEXNAMES
42611762Sedward 			printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline );
4277990Srrh #else
42811762Sedward 			printf( "%s(%d):", fnm[q->fno], q->fline );
4297990Srrh #endif
43011762Sedward #ifndef FLEXNAMES
43111762Sedward 		printf( "%.*s value is used, but none returned\n",
43211762Sedward 			LCHNM, q->name);
43311762Sedward #else
43411762Sedward 		printf( "%s value is used, but none returned\n", q->name);
43511762Sedward #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 ){
50011762Sedward 		if( pt1->aty != pt2->aty || pt1->extra1 != pt2->extra1 )
50111762Sedward 			return 1;
50211762Sedward 		/* if -z then don't worry about undefined structures,
50311762Sedward 		   as long as the names match */
50411762Sedward 		if( zflag && (pt1->extra == 0 || pt2->extra == 0) ) return 0;
50511762Sedward 		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 };
52111762Sedward 
52211762Sedward struct tb dfs[] = {
52311762Sedward 	LDI, "LDI",
52411762Sedward 	LIB, "LIB",
52511762Sedward 	LDC, "LDC",
52611762Sedward 	LDX, "LDX",
52711762Sedward 	LRV, "LRV",
52811762Sedward 	LUV, "LUV",
52911762Sedward 	LUE, "LUE",
53011762Sedward 	LUM, "LUM",
53111762Sedward 	LST, "LST",
53211762Sedward 	LFN, "LFN",
53311762Sedward 	0, "" };
53411762Sedward 
53511762Sedward struct tb us[] = {
53611762Sedward 	USED, "USED",
53711762Sedward 	VUSED, "VUSED",
53811762Sedward 	EUSED, "EUSED",
53911762Sedward 	RVAL, "RVAL",
54011762Sedward 	VARARGS, "VARARGS",
54111762Sedward 	0, "" };
54211762Sedward 
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 
56911762Sedward pfile() {
57011762Sedward 	/* print the input file in readable form */
57111762Sedward 	while( lread( LDI|LIB|LDC|LDX|LRV|LUV|LUE|LUM|LST|LFN ) )
57211762Sedward 		prc();
57311762Sedward 	}
57411762Sedward 
57511762Sedward prc() {
57611762Sedward 	/* print out 'r' for debugging */
57711762Sedward 	register i, j, k;
57811762Sedward 
57911762Sedward 	printf( "decflag\t" );
58011762Sedward 	ptb( r.l.decflag, dfs );
58111762Sedward 	putchar( '\n' );
58211762Sedward 	if( r.l.decflag & LFN ){
5837990Srrh #ifdef FLEXNAMES
58411762Sedward 		printf( "fn\t\t%s\n", r.f.fn );
58511762Sedward #else
58611762Sedward 		printf( "fn\t%\t.*s\n", LFNM, r.f.fn );
58711762Sedward #endif
58811762Sedward 		}
58911762Sedward 	else {
59011762Sedward #ifdef FLEXNAMES
59111762Sedward 		printf( "name\t%s\n", r.l.name );
59211762Sedward #else
59311762Sedward 		printf( "name\t%.*s\n", LCHNM, r.l.name );
59411762Sedward #endif
59511762Sedward 		printf( "nargs\t%d\n", r.l.nargs );
59611762Sedward 		printf( "fline\t%d\n", r.l.fline );
59711762Sedward 		printf( "type.aty\t0%o (", r.l.type.aty );
59811762Sedward 		pty( r.l.type.aty, r.l.name );
59911762Sedward 		printf( ")\ntype.extra\t%d\n", r.l.type.extra );
60011762Sedward 		j = r.l.type.extra1;
60111762Sedward 		printf( "type.extra1\t0x%x (%d,%d)\n",
60211762Sedward 			j, j & X_NONAME ? 1 : 0, j & ~X_NONAME );
60311762Sedward 		k = r.l.nargs;
60411762Sedward 		if( k < 0 ) k = -k;
60511762Sedward 		for( i = 0; i < k; i++ ){
60611762Sedward 			printf( "atyp[%d].aty\t0%o (", i, atyp[i].aty );
60711762Sedward 			pty( atyp[i].aty, "" );
60811762Sedward 			printf( ")\natyp[%d].extra\t%d\n", i, atyp[i].extra);
60911762Sedward 			j = atyp[i].extra1;
61011762Sedward 			printf( "atyp[%d].extra1\t0x%x (%d,%d)\n",
61111762Sedward 				i, j, j & X_NONAME ? 1 : 0, j & ~X_NONAME );
61211762Sedward 			}
61311762Sedward 		}
61411762Sedward 		putchar( '\n' );
61511762Sedward 	}
61611762Sedward 
61711762Sedward pty( t, name )  TWORD t; {
61811762Sedward 	static char * tnames[] = {
61911762Sedward 		"void", "farg", "char", "short",
62011762Sedward 		"int", "long", "float", "double",
62111762Sedward 		"struct xxx", "union %s", "enum", "moety",
62211762Sedward 		"unsigned char", "unsigned short", "unsigned", "unsigned long",
62311762Sedward 		"?", "?"
62411762Sedward 		};
62511762Sedward 
62611762Sedward 	printf( "%s ", tnames[BTYPE(t)] );
62711762Sedward 	pty1( t, name, (8 * sizeof (int) - BTSHIFT) / TSHIFT );
62811762Sedward 	}
62911762Sedward 
63011762Sedward pty1( t, name, level ) TWORD t; {
63111762Sedward 	register TWORD u;
63211762Sedward 
63311762Sedward 	if( level < 0 ){
63411762Sedward 		printf( "%s", name );
63511762Sedward 		return;
63611762Sedward 		}
63711762Sedward 	u = t >> level * TSHIFT;
63811762Sedward 	if( ISPTR(u) ){
63911762Sedward 		printf( "*" );
64011762Sedward 		pty1( t, name, level-1 );
64111762Sedward 		}
64211762Sedward 	else if( ISFTN(u) ){
64311762Sedward 		if( level > 0 && ISPTR(u << TSHIFT) ){
64411762Sedward 			printf( "(" );
64511762Sedward 			pty1( t, name, level-1 );
64611762Sedward 			printf( ")()" );
64711762Sedward 			}
64811762Sedward 		else {
64911762Sedward 			pty1( t, name, level-1 );
65011762Sedward 			printf( "()" );
65111762Sedward 			}
65211762Sedward 		}
65311762Sedward 	else if( ISARY(u) ){
65411762Sedward 		if( level > 0 && ISPTR(u << TSHIFT) ){
65511762Sedward 			printf( "(" );
65611762Sedward 			pty1( t, name, level-1 );
65711762Sedward 			printf( ")[]" );
65811762Sedward 			}
65911762Sedward 		else {
66011762Sedward 			pty1( t, name, level-1 );
66111762Sedward 			printf( "[]" );
66211762Sedward 			}
66311762Sedward 		}
66411762Sedward 	else {
66511762Sedward 		pty1( t, name, level-1 );
66611762Sedward 		}
66711762Sedward 	}
66811762Sedward 
66911762Sedward #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) {
68211762Sedward 		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) {
70611762Sedward 			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 
73811762Sedward 	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) {
75211762Sedward 				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 	}
78111762Sedward 	error("ran out of hash tables");
7827990Srrh 	exit(1);
7837990Srrh }
7847990Srrh char	*tstrbuf[1];
7857990Srrh #endif
786