Annotation of 41BSD/cmd/lint/lpass2.c, revision 1.1.1.1

1.1       root        1: # include "manifest"
                      2: # include "lmanifest"
                      3: 
                      4: # define USED 01
                      5: # define VUSED 02
                      6: # define EUSED 04
                      7: # define RVAL 010
                      8: # define VARARGS 0100
                      9: 
                     10: # define NSZ 1024
                     11: # define TYSZ 3500
                     12: # define FSZ 250
                     13: # define NTY 50
                     14: 
                     15: typedef struct sty STYPE;
                     16: struct sty { ATYPE t; STYPE *next; };
                     17: 
                     18: typedef struct sym {
                     19: #ifndef FLEXNAMES
                     20:        char name[LCHNM];
                     21: #else
                     22:        char *name;
                     23: #endif
                     24:        short nargs;
                     25:        int decflag;
                     26:        int fline;
                     27:        STYPE symty;
                     28:        int fno;
                     29:        int use;
                     30:        } STAB;
                     31: 
                     32: STAB stab[NSZ];
                     33: STAB *find();
                     34: 
                     35: STYPE tary[TYSZ];
                     36: STYPE *tget();
                     37: 
                     38: #ifndef FLEXNAMES
                     39: char fnm[FSZ][LFNM];
                     40: #else
                     41: char *fnm[FSZ];
                     42: #endif
                     43: 
                     44: #ifdef FLEXNAMES
                     45: char *getstr();
                     46: #endif
                     47: 
                     48: int tfree;  /* used to allocate types */
                     49: int ffree;  /* used to save filenames */
                     50: 
                     51: struct ty atyp[NTY];
                     52:        /* r is where all the input ends up */
                     53: union rec r;
                     54: 
                     55: int hflag = 0;
                     56: int pflag = 0;
                     57: int xflag = 0;
                     58: int uflag = 1;
                     59: int ddddd = 0;
                     60: 
                     61: int cfno;  /* current file number */
                     62: 
                     63: main( argc, argv ) char *argv[]; {
                     64:        register char *p;
                     65: 
                     66:        /* first argument is intermediate file */
                     67:        /* second argument is - options */
                     68: 
                     69:        for( ; argc>2 && argv[argc-1][0] == '-' ; --argc ){
                     70:                for( p=argv[argc-1]; *p; ++p ){
                     71:                        switch( *p ){
                     72: 
                     73:                        case 'h':
                     74:                                hflag = 1;
                     75:                                break;
                     76: 
                     77:                        case 'p':
                     78:                                pflag = 1;
                     79:                                break;
                     80: 
                     81:                        case 'x':
                     82:                                xflag = 1;
                     83:                                break;
                     84: 
                     85:                        case 'X':
                     86:                                ddddd = 1;
                     87:                                break;
                     88: 
                     89:                        case 'u':
                     90:                                uflag = 0;
                     91:                                break;
                     92: 
                     93:                                }
                     94:                        }
                     95:                }
                     96: 
                     97:        if( argc < 2 || !freopen( argv[1], "r", stdin ) ){
                     98:                error( "cannot open intermediate file" );
                     99:                exit( 1 );
                    100:                }
                    101: 
                    102:        mloop( LDI|LIB );
                    103:        rewind( stdin );
                    104:        mloop( LDC|LDX );
                    105:        rewind( stdin );
                    106:        mloop( LRV|LUV|LUE|LUM );
                    107:        cleanup();
                    108:        return(0);
                    109:        }
                    110: 
                    111: mloop( m ){
                    112:        /* do the main loop */
                    113:        register STAB *q;
                    114: 
                    115:        while( lread(m) ){
                    116:                q = find();
                    117:                if( q->decflag ) chkcompat(q);
                    118:                else setuse(q);
                    119:                }
                    120:        }
                    121: 
                    122: lread(m){ /* read a line into r.l */
                    123: 
                    124:        register n;
                    125: 
                    126:        for(;;) {
                    127:                if( fread( (char *)&r, sizeof(r), 1, stdin ) <= 0 ) return(0);
                    128:                if( r.l.decflag & LFN ){
                    129:                        /* new filename */
                    130: #ifdef FLEXNAMES
                    131:                        r.f.fn = getstr();
                    132: #endif
                    133:                        setfno( r.f.fn );
                    134:                        continue;
                    135:                        }
                    136: #ifdef FLEXNAMES
                    137:                r.l.name = getstr();
                    138: #endif
                    139: 
                    140:                n = r.l.nargs;
                    141:                if( n<0 ) n = -n;
                    142:                if( n ){
                    143:                        if( n>=NTY ) error( "more than %d args?", n );
                    144:                        fread( (char *)atyp, sizeof(ATYPE), n, stdin );
                    145:                        }
                    146:                if( ( r.l.decflag & m ) ) return( 1 );
                    147:                }
                    148:        }
                    149: 
                    150: setfno( s ) char *s; {
                    151:        /* look up current file names */
                    152:        /* first, strip backwards to the beginning or to the first / */
                    153:        int i;
                    154: 
                    155:        /* now look up s */
                    156:        for( i=0; i<ffree; ++i ){
                    157: #ifndef FLEXNAMES
                    158:                if( !strncmp( s, fnm[i], LFNM ) ){
                    159: #else
                    160:                if (fnm[i] == s){
                    161: #endif
                    162:                        cfno = i;
                    163:                        return;
                    164:                        }
                    165:                }
                    166:        /* make a new entry */
                    167:        if( ffree >= FSZ ) error( "more than %d files", FSZ );
                    168: #ifndef FLEXNAMES
                    169:        strncpy( fnm[ffree], s, LFNM );
                    170: #else
                    171:        fnm[ffree] = s;
                    172: #endif
                    173:        cfno = ffree++;
                    174:        }
                    175: 
                    176: /* VARARGS */
                    177: error( s, a ) char *s; {
                    178: 
                    179: #ifndef FLEXNAMES
                    180:        fprintf( stderr, "pass 2 error:(file %.*s) ", LFNM, fnm[cfno] );
                    181: #else
                    182:        fprintf( stderr, "pass 2 error:(file %s) ", fnm[cfno] );
                    183: #endif
                    184:        fprintf( stderr, s, a );
                    185:        fprintf( stderr, "\n" );
                    186:        exit(1);
                    187:        }
                    188: 
                    189: STAB *
                    190: find(){
                    191:        /* for this to work, NSZ should be a power of 2 */
                    192:        register h=0;
                    193: #ifndef FLEXNAMES
                    194:        {       register char *p, *q;
                    195:                for( h=0,p=r.l.name,q=p+LCHNM; *p&&p<q; ++p) {
                    196:                        h = (h<<1)+ *p;
                    197:                        if( h>=NSZ ){
                    198:                                h = (h+1)&(NSZ-1);
                    199:                                }
                    200:                        }
                    201:                }
                    202: #else
                    203:                h = ((int)r.l.name)%NSZ;
                    204: #endif
                    205:        {       register STAB *p, *q;
                    206:                for( p=q= &stab[h]; q->decflag; ){
                    207:                        /* this call to strncmp should be taken out... */
                    208: #ifndef FLEXNAMES
                    209:                        if( !strncmp( r.l.name, q->name, LCHNM)) return(q);
                    210: #else
                    211:                        if (r.l.name == q->name) return (q);
                    212: #endif
                    213:                        if( ++q >= &stab[NSZ] ) q = stab;
                    214:                        if( q == p ) error( "too many names defined" );
                    215:                        }
                    216: #ifndef FLEXNAMES
                    217:                strncpy( q->name, r.l.name, LCHNM );
                    218: #else
                    219:                q->name = r.l.name;
                    220: #endif
                    221:                return( q );
                    222:                }
                    223:        }
                    224: 
                    225: STYPE *
                    226: tget(){
                    227:        if( tfree >= TYSZ ){
                    228:                error( "too many types needed" );
                    229:                }
                    230:        return( &tary[tfree++] );
                    231:        }
                    232: 
                    233: chkcompat(q) STAB *q; {
                    234:        /* are the types, etc. in r.l and q compatible */
                    235:        register int i;
                    236:        STYPE *qq;
                    237: 
                    238:        setuse(q);
                    239: 
                    240:        /* argument check */
                    241: 
                    242:        if( q->decflag & (LDI|LIB|LUV|LUE) ){
                    243:                if( r.l.decflag & (LUV|LIB|LUE) ){
                    244:                        if( q->nargs != r.l.nargs ){
                    245:                                if( !(q->use&VARARGS) ){
                    246: #ifndef FLEXNAMES
                    247:                                        printf( "%.8s: variable # of args.", q->name );
                    248: #else
                    249:                                        printf( "%s: variable # of args.", q->name );
                    250: #endif
                    251:                                        viceversa(q);
                    252:                                        }
                    253:                                if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs;
                    254:                                if( !(q->decflag & (LDI|LIB) ) ) {
                    255:                                        q->nargs = r.l.nargs;
                    256:                                        q->use |= VARARGS;
                    257:                                        }
                    258:                                }
                    259:                        for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next){
                    260:                                if( chktype( &qq->t, &atyp[i] ) ){
                    261: #ifndef FLEXNAMES
                    262:                                        printf( "%.8s, arg. %d used inconsistently",
                    263: #else
                    264:                                        printf( "%s, arg. %d used inconsistently",
                    265: #endif
                    266:                                                q->name, i+1 );
                    267:                                        viceversa(q);
                    268:                                        }
                    269:                                }
                    270:                        }
                    271:                }
                    272: 
                    273:        if( (q->decflag&(LDI|LIB|LUV)) && r.l.decflag==LUV ){
                    274:                if( chktype( &r.l.type, &q->symty.t ) ){
                    275: #ifndef FLEXNAMES
                    276:                        printf( "%.8s value used inconsistently", q->name );
                    277: #else
                    278:                        printf( "%s value used inconsistently", q->name );
                    279: #endif
                    280:                        viceversa(q);
                    281:                        }
                    282:                }
                    283: 
                    284:        /* check for multiple declaration */
                    285: 
                    286:        if( (q->decflag&LDI) && (r.l.decflag&(LDI|LIB)) ){
                    287: #ifndef FLEXNAMES
                    288:                printf( "%.8s multiply declared", q->name );
                    289: #else
                    290:                printf( "%s multiply declared", q->name );
                    291: #endif
                    292:                viceversa(q);
                    293:                }
                    294: 
                    295:        /* do a bit of checking of definitions and uses... */
                    296: 
                    297:        if( (q->decflag & (LDI|LIB|LDX|LDC|LUM)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){
                    298: #ifndef FLEXNAMES
                    299:                printf( "%.8s value declared inconsistently", q->name );
                    300: #else
                    301:                printf( "%s value declared inconsistently", q->name );
                    302: #endif
                    303:                viceversa(q);
                    304:                }
                    305: 
                    306:        /* better not call functions which are declared to be structure or union returning */
                    307: 
                    308:        if( (q->decflag & (LDI|LIB|LDX|LDC)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){
                    309:                /* only matters if the function returns union or structure */
                    310:                TWORD ty;
                    311:                ty = q->symty.t.aty;
                    312:                if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){
                    313: #ifndef FLEXNAMES
                    314:                        printf( "%.8s function value type must be declared before use", q->name );
                    315: #else
                    316:                        printf( "%s function value type must be declared before use", q->name );
                    317: #endif
                    318:                        viceversa(q);
                    319:                        }
                    320:                }
                    321: 
                    322:        if( pflag && q->decflag==LDX && r.l.decflag == LUM && !ISFTN(q->symty.t.aty) ){
                    323:                /* make the external declaration go away */
                    324:                /* in effect, it was used without being defined */
                    325:                }
                    326:        }
                    327: 
                    328: viceversa(q) STAB *q; {
                    329:        /* print out file comparison */
                    330: #ifndef FLEXNAMES
                    331:        printf( "       %.*s(%d)  ::  %.*s(%d)\n",
                    332:                LFNM, fnm[q->fno], q->fline,
                    333:                LFNM, fnm[cfno], r.l.fline );
                    334: #else
                    335:        printf( "       %s(%d)  ::  %s(%d)\n",
                    336:                fnm[q->fno], q->fline,
                    337:                fnm[cfno], r.l.fline );
                    338: #endif
                    339:        }
                    340: 
                    341:        /* messages for defintion/use */
                    342: char *
                    343: mess[2][2] ={
                    344:        "",
                    345: #ifndef FLEXNAMES
                    346:        "%.8s used( %.*s(%d) ), but not defined\n",
                    347:        "%.8s defined( %.*s(%d) ), but never used\n",
                    348:        "%.8s declared( %.*s(%d) ), but never used or defined\n"
                    349: #else
                    350:        "%s used( %s(%d) ), but not defined\n",
                    351:        "%s defined( %s(%d) ), but never used\n",
                    352:        "%s declared( %s(%d) ), but never used or defined\n"
                    353: #endif
                    354:        };
                    355: 
                    356: lastone(q) STAB *q; {
                    357: 
                    358:        register nu, nd, uses;
                    359: 
                    360:        if( ddddd ) pst(q);
                    361: 
                    362:        nu = nd = 0;
                    363:        uses = q->use;
                    364: 
                    365:        if( !(uses&USED) && q->decflag != LIB ) {
                    366: #ifndef FLEXNAMES
                    367:                if( strncmp(q->name,"main",7) )
                    368: #else
                    369:                if (strcmp(q->name, "main"))
                    370: #endif
                    371:                        nu = 1;
                    372:                }
                    373: 
                    374:        if( !ISFTN(q->symty.t.aty) ){
                    375:                switch( q->decflag ){
                    376: 
                    377:                case LIB:
                    378:                        nu = nd = 0;  /* don't complain about uses on libraries */
                    379:                        break;
                    380:                case LDX:
                    381:                        if( !xflag ) break;
                    382:                case LUV:
                    383:                case LUE:
                    384: /* 01/04/80 */ case LUV | LUE:
                    385:                case LUM:
                    386:                        nd = 1;
                    387:                        }
                    388:                }
                    389:        if( uflag && ( nu || nd ) ) printf( mess[nu][nd],
                    390: #ifndef FLEXNAMES
                    391:                 q->name, LFNM, fnm[q->fno], q->fline );
                    392: #else
                    393:                 q->name, fnm[q->fno], q->fline );
                    394: #endif
                    395: 
                    396:        if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
                    397: #ifndef FLEXNAMES
                    398:                printf( "%.8s returns value which is %s ignored\n", q->name,
                    399: #else
                    400:                printf( "%s returns value which is %s ignored\n", q->name,
                    401: #endif
                    402:                        uses&VUSED ? "sometimes" : "always" );
                    403:                }
                    404: 
                    405:        if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB)) ){
                    406: #ifndef FLEXNAMES
                    407:                printf( "%.8s value is used, but none returned\n", q->name );
                    408: #else
                    409:                printf( "%s value is used, but none returned\n", q->name );
                    410: #endif
                    411:                }
                    412:        }
                    413: 
                    414: cleanup(){ /* call lastone and die gracefully */
                    415:        STAB *q;
                    416:        for( q=stab; q< &stab[NSZ]; ++q ){
                    417:                if( q->decflag ) lastone(q);
                    418:                }
                    419:        exit(0);
                    420:        }
                    421: 
                    422: setuse(q) STAB *q; { /* check new type to ensure that it is used */
                    423: 
                    424:        if( !q->decflag ){ /* new one */
                    425:                q->decflag = r.l.decflag;
                    426:                q->symty.t = r.l.type;
                    427:                if( r.l.nargs < 0 ){
                    428:                        q->nargs = -r.l.nargs;
                    429:                        q->use = VARARGS;
                    430:                        }
                    431:                else {
                    432:                        q->nargs = r.l.nargs;
                    433:                        q->use = 0;
                    434:                        }
                    435:                q->fline = r.l.fline;
                    436:                q->fno = cfno;
                    437:                if( q->nargs ){
                    438:                        int i;
                    439:                        STYPE *qq;
                    440:                        for( i=0,qq= &q->symty; i<q->nargs; ++i,qq=qq->next ){
                    441:                                qq->next = tget();
                    442:                                qq->next->t = atyp[i];
                    443:                                }
                    444:                        }
                    445:                }
                    446: 
                    447:        switch( r.l.decflag ){
                    448: 
                    449:        case LRV:
                    450:                q->use |= RVAL;
                    451:                return;
                    452:        case LUV:
                    453:                q->use |= VUSED+USED;
                    454:                return;
                    455:        case LUE:
                    456:                q->use |= EUSED+USED;
                    457:                return;
                    458: /* 01/04/80 */ case LUV | LUE:
                    459:        case LUM:
                    460:                q->use |= USED;
                    461:                return;
                    462: 
                    463:                }
                    464:        }
                    465: 
                    466: chktype( pt1, pt2 ) register ATYPE *pt1, *pt2; {
                    467:        TWORD t;
                    468: 
                    469:        /* check the two type words to see if they are compatible */
                    470:        /* for the moment, enums are turned into ints, and should be checked as such */
                    471:        if( pt1->aty == ENUMTY ) pt1->aty =  INT;
                    472:        if( pt2->aty == ENUMTY ) pt2->aty = INT;
                    473: 
                    474:        if( (t=BTYPE(pt1->aty)==STRTY) || t==UNIONTY ){
                    475:                return( pt1->aty!=pt2->aty || (
                    476:                        pt1->extra!=pt2->extra ) );
                    477:                }
                    478: 
                    479:        if( pt2->extra ){ /* constant passed in */
                    480:                if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
                    481:                else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
                    482:                }
                    483:        else if( pt1->extra ){ /* for symmetry */
                    484:                if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
                    485:                else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
                    486:                }
                    487: 
                    488:        return( pt1->aty != pt2->aty );
                    489:        }
                    490: 
                    491: struct tb { int m; char * nm };
                    492: ptb( v, tp ) struct tb *tp; {
                    493:        /* print a value from the table */
                    494:        int flag;
                    495:        flag = 0;
                    496:        for( ; tp->m; ++tp ){
                    497:                if( v&tp->m ){
                    498:                        if( flag++ ) putchar( '|' );
                    499:                        printf( "%s", tp->nm );
                    500:                        }
                    501:                }
                    502:        }
                    503: 
                    504: pst( q ) STAB *q; {
                    505:        /* give a debugging output for q */
                    506:        static struct tb dfs[] = {
                    507:                LDI, "LDI",
                    508:                LIB, "LIB",
                    509:                LDC, "LDC",
                    510:                LDX, "LDX",
                    511:                LRV, "LRV",
                    512:                LUV, "LUV",
                    513:                LUE, "LUE",
                    514:                LUM, "LUM",
                    515:                0, "" };
                    516: 
                    517:        static struct tb us[] = {
                    518:                USED, "USED",
                    519:                VUSED, "VUSED",
                    520:                EUSED, "EUSED",
                    521:                RVAL, "RVAL",
                    522:                VARARGS, "VARARGS",
                    523:                0,      0,
                    524:                };
                    525: 
                    526: #ifndef FLEXNAMES
                    527:        printf( "%.8s (", q->name );
                    528: #else
                    529:        printf( "%s (", q->name );
                    530: #endif
                    531:        ptb( q->decflag, dfs );
                    532:        printf( "), use= " );
                    533:        ptb( q->use, us );
                    534:        printf( ", line %d, nargs=%d\n", q->fline, q->nargs );
                    535:        }
                    536: 
                    537: #ifdef FLEXNAMES
                    538: char *
                    539: getstr()
                    540: {
                    541:        char buf[BUFSIZ];
                    542:        register char *cp = buf;
                    543:        register int c;
                    544: 
                    545:        if (feof(stdin) || ferror(stdin))
                    546:                return("");
                    547:        while ((c = getchar()) > 0)
                    548:                *cp++ = c;
                    549:        if (c < 0) {
                    550:                fprintf(stderr, "pass 2 error: intermediate file format error (getstr)");
                    551:                exit(1);
                    552:        }
                    553:        *cp++ = 0;
                    554:        return (hash(buf));
                    555: }
                    556: 
                    557: #define        NSAVETAB        4096
                    558: char   *savetab;
                    559: int    saveleft;
                    560: 
                    561: char *
                    562: savestr(cp)
                    563:        register char *cp;
                    564: {
                    565:        register int len;
                    566: 
                    567:        len = strlen(cp) + 1;
                    568:        if (len > saveleft) {
                    569:                saveleft = NSAVETAB;
                    570:                if (len > saveleft)
                    571:                        saveleft = len;
                    572:                savetab = (char *)malloc(saveleft);
                    573:                if (savetab == 0) {
                    574:                        fprintf(stderr, "pass 2 error: ran out of memory (savestr)");
                    575:                        exit(1);
                    576:                }
                    577:        }
                    578:        strncpy(savetab, cp, len);
                    579:        cp = savetab;
                    580:        savetab += len;
                    581:        saveleft -= len;
                    582:        return (cp);
                    583: }
                    584: 
                    585: /*
                    586:  * The definition for the segmented hash tables.
                    587:  */
                    588: #define        MAXHASH 20
                    589: #define        HASHINC 1013
                    590: struct ht {
                    591:        char    **ht_low;
                    592:        char    **ht_high;
                    593:        int     ht_used;
                    594: } htab[MAXHASH];
                    595: 
                    596: char *
                    597: hash(s)
                    598:        char *s;
                    599: {
                    600:        register char **h;
                    601:        register i;
                    602:        register char *cp;
                    603:        struct ht *htp;
                    604:        int sh;
                    605: 
                    606:        /*
                    607:         * The hash function is a modular hash of
                    608:         * the sum of the characters with the sum
                    609:         * doubled before each successive character
                    610:         * is added.
                    611:         */
                    612:        cp = s;
                    613:        i = 0;
                    614:        while (*cp)
                    615:                i = i*2 + *cp++;
                    616:        sh = (i&077777) % HASHINC;
                    617:        cp = s;
                    618:        /*
                    619:         * There are as many as MAXHASH active
                    620:         * hash tables at any given point in time.
                    621:         * The search starts with the first table
                    622:         * and continues through the active tables
                    623:         * as necessary.
                    624:         */
                    625:        for (htp = htab; htp < &htab[MAXHASH]; htp++) {
                    626:                if (htp->ht_low == 0) {
                    627:                        register char **hp =
                    628:                            (char **) calloc(sizeof (char **), HASHINC);
                    629:                        if (hp == 0) {
                    630:                                fprintf(stderr, "pass 2 error: ran out of memory (hash)");
                    631:                                exit(1);
                    632:                        }
                    633:                        htp->ht_low = hp;
                    634:                        htp->ht_high = htp->ht_low + HASHINC;
                    635:                }
                    636:                h = htp->ht_low + sh;
                    637:                /*
                    638:                 * quadratic rehash increment
                    639:                 * starts at 1 and incremented
                    640:                 * by two each rehash.
                    641:                 */
                    642:                i = 1;
                    643:                do {
                    644:                        if (*h == 0) {
                    645:                                if (htp->ht_used > (HASHINC * 3)/4)
                    646:                                        break;
                    647:                                htp->ht_used++;
                    648:                                *h = savestr(cp);
                    649:                                return (*h);
                    650:                        }
                    651:                        if (**h == *cp && strcmp(*h, cp) == 0)
                    652:                                return (*h);
                    653:                        h += i;
                    654:                        i += 2;
                    655:                        if (h >= htp->ht_high)
                    656:                                h -= HASHINC;
                    657:                } while (i < HASHINC);
                    658:        }
                    659:        fprintf(stderr, "pass 2 error: ran out of hash tables");
                    660:        exit(1);
                    661: }
                    662: char   *tstrbuf[1];
                    663: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.