Annotation of 3BSD/cmd/lint/lpass2.c, revision 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.