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