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

1.1       root        1: # include "lmanifest"
                      2: # include "manifest"
                      3: 
                      4: # define USED 01
                      5: # define VUSED 02
                      6: # define EUSED 04
                      7: # define RVAL 010
                      8: # define VARARGS 0100
                      9: 
                     10: typedef struct { TWORD aty; int extra; } atype;
                     11: 
                     12: struct line {
                     13:        char name[8];
                     14:        int decflag;
                     15:        atype type;
                     16:        int nargs;
                     17:        atype atyp[50];
                     18:        int fline;
                     19:        char file[100];
                     20:        }
                     21: 
                     22:        l1,
                     23:        l2,
                     24:        *pd,    /* pointer to line having definition */
                     25:        *pc,    /* pointer to current line read */
                     26:        *p3;    /* used for swapping pc and pd */
                     27: 
                     28: int uses = USED;
                     29: int hflag = 0;
                     30: int pflag = 0;
                     31: int xflag = 0;
                     32: int uflag = 1;
                     33: 
                     34: 
                     35: main( argc, argv ) char *argv[]; {
                     36: 
                     37:        register char *p;
                     38: 
                     39:        /* first argument is - options */
                     40: 
                     41:        if( argc>=2 && argv[1][0] == '-' ){
                     42:                for( p=argv[1]; *p; ++p ){
                     43:                        switch( *p ){
                     44: 
                     45:                        case 'h':
                     46:                                hflag = 1;
                     47:                                break;
                     48: 
                     49:                        case 'p':
                     50:                                pflag = 1;
                     51:                                break;
                     52: 
                     53:                        case 'x':
                     54:                                xflag = 1;
                     55:                                break;
                     56: 
                     57:                        case 'u':
                     58:                                uflag = 0;
                     59:                                break;
                     60: 
                     61:                                }
                     62:                        }
                     63:                }
                     64: 
                     65: 
                     66: 
                     67:        pd = &l1;
                     68:        pc = &l2;
                     69:        pd->name[0] = '\0' ;
                     70:        pd->fline = 0;
                     71:        pd->file[0] = '\0';
                     72:        pd->decflag = LDI;
                     73: 
                     74:        /* main loop: read a line;
                     75:                if same as last line, check compatibility
                     76:                if not same as last line, becomes df.
                     77:                */
                     78: 
                     79:        for(;;){
                     80:                lread();
                     81:                if( steq(pc->name, pd->name) ) chkcompat();
                     82:                else {
                     83:                        lastone();
                     84:                        setuse();
                     85:                        p3=pc;
                     86:                        pc = pd;
                     87:                        pd = p3;
                     88:                        }
                     89:                }
                     90: 
                     91:        }
                     92: 
                     93: lread(){ /* read a line into pc */
                     94: 
                     95:        register i, n;
                     96: 
                     97:        getnam( pc->name );
                     98: 
                     99:        pc->decflag = rdin10();
                    100:        rdinty( &pc->type );
                    101:        n = pc->nargs = rdin10();
                    102:        if( n<0 ) n = -n;
                    103: 
                    104:        for( i=0; i<n; ++i ){
                    105:                rdinty( &pc->atyp[i] );
                    106:                }
                    107: 
                    108:        getnam( pc->file );
                    109:        pc->fline = rdin10();
                    110: 
                    111:        while( getchar() != '\n' ) ; /* VOID */
                    112:        }
                    113: 
                    114: rdin10(){
                    115:        register val, c, s;
                    116: 
                    117:        val = 0;
                    118:        s = 1;
                    119: 
                    120:        while( (c=getchar()) != '\t' ){
                    121:                if( c <= 0 ) error( "unexpected EOF" );
                    122:                else if( c == '-' ) {
                    123:                        s = -1;
                    124:                        continue;
                    125:                        }
                    126:                else if( c<'0' || c>'9' ) {
                    127:                        error("rotten digit: %o\n", c );
                    128:                        }
                    129:                val = val*10 + c - '0';
                    130:                }
                    131:        return( val*s );
                    132:        }
                    133: 
                    134: rdinty( p ) atype *p; {
                    135:        register val, c, s;
                    136: 
                    137:        val = 0;
                    138:        s = 1;
                    139: 
                    140:        while( (c=getchar()) != '\t' && c!= '<' ){
                    141:                if( c <= 0 ) error( "unexpected EOF" );
                    142:                else if( c == '-' ) {
                    143:                        s = -1;
                    144:                        continue;
                    145:                        }
                    146:                else if( c<'0' || c>'7' ) {
                    147:                        error("rotten digit: %o\n", c );
                    148:                        }
                    149:                val = (val<<3) + c - '0';
                    150:                }
                    151:        p->aty = val*s;
                    152:        if( c == '<' ) p->extra = rdin10();
                    153:        else p->extra = 0;
                    154:        }
                    155: 
                    156: getnam(p) char *p; {
                    157:        register c;
                    158:        while( (c=getchar()) != '\t' ){
                    159:                if( c == '\n' ) error( "rotten name\n" );
                    160:                if( c <= 0 ) cleanup();
                    161:                *p++ = c;
                    162:                }
                    163:        *p = '\0';
                    164:        }
                    165: 
                    166: /* VARARGS */
                    167: error( s, a ) char *s; {
                    168: 
                    169:        fprintf( stderr, "pass 2 error: " );
                    170:        fprintf( stderr, s, a );
                    171:        fprintf( stderr, "\n" );
                    172:        exit(1);
                    173:        }
                    174: 
                    175: steq(p,q) char *p,*q; { /* check that the p and q names are the same */
                    176: 
                    177: 
                    178:        while( *p == *q ){
                    179:                if( *p == 0 ) return(1);
                    180:                ++p;
                    181:                ++q;
                    182:                }
                    183: 
                    184:        return(0);
                    185:        }
                    186: 
                    187: chkcompat(){
                    188:        /* are the types, etc. in pc and pd compatible */
                    189:        register int i;
                    190: 
                    191:        setuse();
                    192: 
                    193:        /* argument check */
                    194: 
                    195:        if( pd->decflag & (LDI|LIB|LUV|LUE) ){
                    196:                if( pc->decflag & (LUV|LIB|LUE) ){
                    197:                        if( pd->nargs != pc->nargs ){
                    198:                                if( !(uses&VARARGS) ){
                    199:                                        printf( "%.7s: variable # of args.", pd->name );
                    200:                                        viceversa();
                    201:                                        }
                    202:                                if( pc->nargs > pd->nargs ) pc->nargs = pd->nargs;
                    203:                                if( !(pd->decflag & (LDI|LIB) ) ) {
                    204:                                        pd->nargs = pc->nargs;
                    205:                                        uses |= VARARGS;
                    206:                                        }
                    207:                                }
                    208:                        for( i=0; i<pc->nargs; ++i ){
                    209:                                if( chktype(&pd->atyp[i], &pc->atyp[i]) ){
                    210:                                        printf( "%.7s, arg. %d used inconsistently",
                    211:                                                pd->name, i+1 );
                    212:                                        viceversa();
                    213:                                        }
                    214:                                }
                    215:                        }
                    216:                }
                    217: 
                    218:        if( (pd->decflag&(LDI|LIB|LUV)) && pc->decflag==LUV ){
                    219:                if( chktype( &pc->type, &pd->type ) ){
                    220:                        printf( "%.7s value used inconsistently", pd->name );
                    221:                        viceversa();
                    222:                        }
                    223:                }
                    224: 
                    225:        /* check for multiple declaration */
                    226: 
                    227:        if( (pd->decflag&LDI) && (pc->decflag&(LDI|LIB)) ){
                    228:                printf( "%.7s multiply declared", pd->name );
                    229:                viceversa();
                    230:                }
                    231: 
                    232:        /* do a bit of checking of definitions and uses... */
                    233: 
                    234:        if( (pd->decflag & (LDI|LIB|LDX|LDC)) && (pc->decflag & (LDX|LDC)) && pd->type.aty != pc->type.aty ){
                    235:                printf( "%.7s value declared inconsistently", pd->name );
                    236:                viceversa();
                    237:                }
                    238: 
                    239:        /* better not call functions which are declared to be structure or union returning */
                    240: 
                    241:        if( (pd->decflag & (LDI|LIB|LDX|LDC)) && (pc->decflag & LUE) && pd->type.aty != pc->type.aty ){
                    242:                /* only matters if the function returns union or structure */
                    243:                TWORD ty;
                    244:                ty = pd->type.aty;
                    245:                if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){
                    246:                        printf( "%.7s function value type must be declared before use", pd->name );
                    247:                        viceversa();
                    248:                        }
                    249:                }
                    250: 
                    251:        if( pflag && pd->decflag==LDX && pc->decflag == LUM && !ISFTN(pd->type.aty) ){
                    252:                /* make the external declaration go away */
                    253:                /* in effect, it was used without being defined */
                    254: 
                    255:                /* swap pc and pd */
                    256:                p3 = pc;
                    257:                pc = pd;
                    258:                pd = p3;
                    259:                }
                    260: 
                    261:        }
                    262: 
                    263: viceversa(){
                    264:        /* print out file comparison */
                    265:        printf( "       %s(%d)  ::  %s(%d)\n", pd->file, pd->fline, pc->file, pc->fline );
                    266:        }
                    267: 
                    268:        /* messages for defintion/use */
                    269: char *
                    270: mess[2][2] = {
                    271:        "",
                    272:        "%.7s used( %s(%d) ), but not defined\n",
                    273:        "%.7s defined( %s(%d) ), but never used\n",
                    274:        "%.7s declared( %s(%d) ), but never used or defined\n"
                    275:        };
                    276: 
                    277: lastone(){
                    278: 
                    279:        /* called when pc and pd are at last different */
                    280:        register nu, nd;
                    281: 
                    282:        nu = nd = 0;
                    283: 
                    284:        if( !(uses&USED) && pd->decflag != LIB ) {
                    285:                if( !steq(pd->name,"main") )
                    286:                        nu = 1;
                    287:                }
                    288: 
                    289:        if( !ISFTN(pd->type.aty) ){
                    290:                switch( pd->decflag ){
                    291: 
                    292:                case LIB:
                    293:                        nu = nd = 0;  /* don't complain about uses on libraries */
                    294:                        break;
                    295:                case LDX:
                    296:                        if( !xflag ) break;
                    297:                case LUV:
                    298:                case LUE:
                    299:                case LUM:
                    300:                        nd = 1;
                    301:                        }
                    302:                }
                    303: 
                    304:        if( uflag && ( nu || nd ) ) printf( mess[nu][nd], pd->name, pd->file, pd->fline );
                    305: 
                    306:        if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
                    307:                printf( "%.7s returns value which is %s ignored\n", pd->name,
                    308:                        uses&VUSED ? "sometimes" : "always" );
                    309:                }
                    310: 
                    311:        if( (uses&(RVAL+VUSED)) == (VUSED) && (pd->decflag&(LDI|LIB)) ){
                    312:                printf( "%.7s value is used, but none returned\n", pd->name );
                    313:                }
                    314: 
                    315:        /* clean up pc, in preparation for the next thing */
                    316: 
                    317:        uses = 0;
                    318:        if( pc->nargs < 0 ){
                    319:                pc->nargs = -pc->nargs;
                    320:                uses = VARARGS;
                    321:                }
                    322: 
                    323:        }
                    324: 
                    325: cleanup(){ /* call lastone and die gracefully */
                    326:        lastone();
                    327:        exit(0);
                    328:        }
                    329: 
                    330: setuse(){ /* check new type to ensure that it is used */
                    331: 
                    332:        switch( pc->decflag ){
                    333: 
                    334:        case LRV:
                    335:                uses |= RVAL;
                    336:                return;
                    337:        case LUV:
                    338:                uses |= VUSED+USED;
                    339:                return;
                    340:        case LUE:
                    341:                uses |= EUSED+USED;
                    342:                return;
                    343:        case LUM:
                    344:                uses |= USED;
                    345:                return;
                    346: 
                    347:                }
                    348:        }
                    349: 
                    350: chktype( pt1, pt2 ) register atype *pt1, *pt2; {
                    351: 
                    352:        /* check the two type words to see if they are compatible */
                    353:        /* for the moment, enums are turned into ints, and should be checked as such */
                    354:        if( pt1->aty == ENUMTY ) pt1->aty =  INT;
                    355:        if( pt2->aty == ENUMTY ) pt2->aty = INT;
                    356: 
                    357:        if( pt2->extra ){ /* constant passed in */
                    358:                if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
                    359:                else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
                    360:                }
                    361:        else if( pt1->extra ){ /* for symmetry */
                    362:                if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
                    363:                else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
                    364:                }
                    365: 
                    366:        return( pt1->aty != pt2->aty );
                    367:        }

unix.superglobalmegacorp.com

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