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