Annotation of 43BSDTahoe/usr.bin/lint/lint.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)lint.c     1.14    (Berkeley)      12/11/87";
        !             3: #endif lint
        !             4: 
        !             5: # include "pass1.h"
        !             6: 
        !             7: # include "lmanifest.h"
        !             8: 
        !             9: # include <ctype.h>
        !            10: 
        !            11: # define VAL 0
        !            12: # define EFF 1
        !            13: 
        !            14: /* these are appropriate for the -p flag */
        !            15: int  SZCHAR = 8;
        !            16: int  SZINT = 16;
        !            17: int  SZFLOAT = 32;
        !            18: int  SZDOUBLE = 64;
        !            19: int  SZLONG = 32;
        !            20: int  SZSHORT = 16;
        !            21: int SZPOINT = 16;
        !            22: int ALCHAR = 8;
        !            23: int ALINT = 16;
        !            24: int ALFLOAT = 32;
        !            25: int ALDOUBLE = 64;
        !            26: int ALLONG = 32;
        !            27: int ALSHORT = 16;
        !            28: int ALPOINT = 16;
        !            29: int ALSTRUCT = 16;
        !            30: 
        !            31: int nflag = 0;         /* avoid gripes about printf et al. */
        !            32: int vflag = 1;         /* tell about unused argments */
        !            33: int xflag = 0;         /* tell about unused externals */
        !            34: int argflag = 0;       /* used to turn off complaints about arguments */
        !            35: int libflag = 0;       /* used to generate library descriptions */
        !            36: int vaflag = -1;       /* signal functions with a variable number of args */
        !            37: int aflag = 0;         /* used to check precision of assignments */
        !            38: int zflag = 0;         /* no 'structure never defined' error */
        !            39: int Cflag = 0; /* filter out certain output, for generating libraries */
        !            40: char *libname = 0;     /* name of the library we're generating */
        !            41: 
        !            42:                        /* flags for the "outdef" function */
        !            43: # define USUAL (-101)
        !            44: # define DECTY (-102)
        !            45: # define NOFILE (-103)
        !            46: # define SVLINE (-104)
        !            47: 
        !            48: # define LNAMES 250
        !            49: 
        !            50: struct lnm {
        !            51:        short lid, flgs;
        !            52:        }  lnames[LNAMES], *lnp;
        !            53: 
        !            54: contx( p, down, pl, pr ) register NODE *p; register *pl, *pr; {
        !            55: 
        !            56:        *pl = *pr = VAL;
        !            57:        switch( p->in.op ){
        !            58: 
        !            59:        case ANDAND:
        !            60:        case OROR:
        !            61:        case QUEST:
        !            62:                *pr = down;
        !            63:                break;
        !            64: 
        !            65:        case SCONV:
        !            66:        case PCONV:
        !            67:        case COLON:
        !            68:                *pr = *pl = down;
        !            69:                break;
        !            70: 
        !            71:        case COMOP:
        !            72:                *pl = EFF;
        !            73:                *pr = down;
        !            74: 
        !            75:        case FORCE:
        !            76:        case INIT:
        !            77:        case UNARY CALL:
        !            78:        case STCALL:
        !            79:        case UNARY STCALL:
        !            80:        case CALL:
        !            81:        case UNARY FORTCALL:
        !            82:        case FORTCALL:
        !            83:        case CBRANCH:
        !            84:                break;
        !            85: 
        !            86:        default:
        !            87:                if( asgop(p->in.op) ) break;
        !            88:                if( p->in.op == UNARY MUL && ( p->in.type == STRTY || p->in.type == UNIONTY || p->in.type == UNDEF) ) {
        !            89:                /* struct x f( );  main( ) {  (void) f( ); }
        !            90:                 * the the cast call appears as U* UNDEF
        !            91:                 */
        !            92:                        break;  /* the compiler does this... */
        !            93:                        }
        !            94:                if( down == EFF && hflag ) werror( "null effect" );
        !            95: 
        !            96:                }
        !            97:        }
        !            98: 
        !            99: ecode( p ) NODE *p; {
        !           100:        /* compile code for p */
        !           101: 
        !           102:        fwalk( p, contx, EFF );
        !           103:        lnp = lnames;
        !           104:        lprt( p, EFF, 0 );
        !           105:        strforget();
        !           106:        }
        !           107: 
        !           108: ejobcode( flag ){
        !           109:        /* called after processing each job */
        !           110:        /* flag is nonzero if errors were detected */
        !           111:        register k;
        !           112:        register struct symtab *p;
        !           113: 
        !           114:        for( p=stab; p< &stab[SYMTSZ]; ++p ){
        !           115: 
        !           116:                if( p->stype != TNULL ) {
        !           117: 
        !           118:                        if( p->stype == STRTY || p->stype == UNIONTY ){
        !           119:                                if( !zflag && dimtab[p->sizoff+1] < 0 ){
        !           120:                                        /* never defined */
        !           121: #ifndef FLEXNAMES
        !           122:                                        if( hflag ) werror( "struct/union %.8s never defined", p->sname );
        !           123: #else
        !           124:                                        if( hflag ) werror( "struct/union %s never defined", p->sname );
        !           125: #endif
        !           126:                                        }
        !           127:                                }
        !           128: 
        !           129:                        switch( p->sclass ){
        !           130:                        
        !           131:                        case STATIC:
        !           132:                                if( p->suse > 0 ){
        !           133:                                        k = lineno;
        !           134:                                        lineno = p->suse;
        !           135: #ifndef FLEXNAMES
        !           136:                                        uerror( "static variable %.8s unused",
        !           137: #else
        !           138:                                        uerror( "static variable %s unused",
        !           139: #endif
        !           140:                                                p->sname );
        !           141:                                        lineno = k;
        !           142:                                        break;
        !           143:                                        }
        !           144:                                /* no statics in libraries */
        !           145:                                if( Cflag ) break;
        !           146: 
        !           147:                        case EXTERN:
        !           148:                        case USTATIC:
        !           149:                                /* with the xflag, worry about externs not used */
        !           150:                                /* the filename may be wrong here... */
        !           151:                                if( xflag && p->suse >= 0 && !libflag ){
        !           152:                                        outdef( p, LDX, NOFILE );
        !           153:                                        }
        !           154:                        
        !           155:                        case EXTDEF:
        !           156:                                if( p->suse < 0 ){  /* used */
        !           157:                                        outdef( p, LUM, SVLINE );
        !           158:                                        }
        !           159:                                break;
        !           160:                                }
        !           161:                        
        !           162:                        }
        !           163: 
        !           164:                }
        !           165:        exit( 0 );
        !           166:        }
        !           167: 
        !           168: astype( t, i ) ATYPE *t; {
        !           169:        TWORD tt;
        !           170:        int j, k=0, l=0;
        !           171: 
        !           172:        if( (tt=BTYPE(t->aty))==STRTY || tt==UNIONTY ){
        !           173:                if( i<0 || i>= DIMTABSZ-3 ){
        !           174:                        werror( "lint's little mind is blown" );
        !           175:                        }
        !           176:                else {
        !           177:                        j = dimtab[i+3];
        !           178:                        if( j<0 || j>SYMTSZ ){
        !           179:                                k = dimtab[i];
        !           180:                                l = X_NONAME | stab[j].suse;
        !           181:                                }
        !           182:                        else {
        !           183:                                if( stab[j].suse <= 0 ) {
        !           184: #ifndef FLEXNAMES
        !           185:                                        werror( "no line number for %.8s",
        !           186: #else
        !           187:                                        werror( "no line number for %s",
        !           188: #endif
        !           189:                                                stab[j].sname );
        !           190:                                        }
        !           191:                                else {
        !           192:                                        k = dimtab[i];
        !           193: #ifdef FLEXNAMES
        !           194:                                        l = hashstr(stab[j].sname);
        !           195: #else
        !           196:                                        l = hashstr(stab[j].sname, LCHNM);
        !           197: #endif
        !           198:                                        }
        !           199:                                }
        !           200:                        }
        !           201:                
        !           202:                t->extra = k;
        !           203:                t->extra1 = l;
        !           204:                return( 1 );
        !           205:                }
        !           206:        else return( 0 );
        !           207:        }
        !           208: 
        !           209: bfcode( a, n ) int a[]; {
        !           210:        /* code for the beginning of a function; a is an array of
        !           211:                indices in stab for the arguments; n is the number */
        !           212:        /* this must also set retlab */
        !           213:        register i;
        !           214:        register struct symtab *cfp;
        !           215:        static ATYPE t;
        !           216: 
        !           217:        strforget();
        !           218:        retlab = 1;
        !           219: 
        !           220:        cfp = &stab[curftn];
        !           221: 
        !           222:        /* if creating library, don't do static functions */
        !           223:        if( Cflag && cfp->sclass == STATIC ) return;
        !           224: 
        !           225:        /* if variable number of arguments, only print the ones which will be checked */
        !           226:        if( vaflag >= 0 ){
        !           227:                if( n < vaflag ) werror( "declare the VARARGS arguments you want checked!" );
        !           228:                else n = vaflag;
        !           229:                }
        !           230:        fsave( ftitle );
        !           231:        if( cfp->sclass == STATIC ) outdef( cfp, LST, vaflag>=0?~n:n );
        !           232:        else outdef( cfp, libflag?LIB:LDI, vaflag>=0?~n:n );
        !           233:        vaflag = -1;
        !           234: 
        !           235:        /* output the arguments */
        !           236:        if( n ){
        !           237:                for( i=0; i<n; ++i ) {
        !           238:                        t.aty = stab[a[i]].stype;
        !           239:                        t.extra = 0;
        !           240:                        t.extra1 = 0;
        !           241:                        if( !astype( &t, stab[a[i]].sizoff ) ) {
        !           242:                                switch( t.aty ){
        !           243: 
        !           244:                                case ULONG:
        !           245:                                        break;
        !           246: 
        !           247:                                case CHAR:
        !           248:                                case SHORT:
        !           249:                                        t.aty = INT;
        !           250:                                        break;
        !           251: 
        !           252:                                case UCHAR:
        !           253:                                case USHORT:
        !           254:                                case UNSIGNED:
        !           255:                                        t.aty = UNSIGNED;
        !           256:                                        break;
        !           257: 
        !           258:                                        }
        !           259:                                }
        !           260:                        fwrite( (char *)&t, sizeof(ATYPE), 1, stdout );
        !           261:                        }
        !           262:                }
        !           263:        }
        !           264: 
        !           265: ctargs( p ) NODE *p; {
        !           266:        /* count arguments; p points to at least one */
        !           267:        /* the arguemnts are a tower of commas to the left */
        !           268:        register c;
        !           269:        c = 1; /* count the rhs */
        !           270:        while( p->in.op == CM ){
        !           271:                ++c;
        !           272:                p = p->in.left;
        !           273:                }
        !           274:        return( c );
        !           275:        }
        !           276: 
        !           277: lpta( p ) NODE *p; {
        !           278:        static ATYPE t;
        !           279: 
        !           280:        if( p->in.op == CM ){
        !           281:                lpta( p->in.left );
        !           282:                p = p->in.right;
        !           283:                }
        !           284: 
        !           285:        t.aty = p->in.type;
        !           286:        t.extra = (p->in.op==ICON);
        !           287:        t.extra1 = 0;
        !           288: 
        !           289:        if( !astype( &t, p->fn.csiz ) ) {
        !           290:                switch( t.aty ){
        !           291: 
        !           292:                        case CHAR:
        !           293:                        case SHORT:
        !           294:                                t.aty = INT;
        !           295:                        case LONG:
        !           296:                        case ULONG:
        !           297:                        case INT:
        !           298:                        case UNSIGNED:
        !           299:                                break;
        !           300: 
        !           301:                        case UCHAR:
        !           302:                        case USHORT:
        !           303:                                t.aty = UNSIGNED;
        !           304:                                break;
        !           305: 
        !           306:                        case FLOAT:
        !           307:                                t.aty = DOUBLE;
        !           308:                                t.extra = 0;
        !           309:                                break;
        !           310: 
        !           311:                        default:
        !           312:                                t.extra = 0;
        !           313:                                break;
        !           314:                        }
        !           315:                }
        !           316:        fwrite( (char *)&t, sizeof(ATYPE), 1, stdout );
        !           317:        }
        !           318: 
        !           319: # define VALSET 1
        !           320: # define VALUSED 2
        !           321: # define VALASGOP 4
        !           322: # define VALADDR 8
        !           323: 
        !           324: lprt( p, down, uses ) register NODE *p; {
        !           325:        register struct symtab *q;
        !           326:        register id;
        !           327:        register acount;
        !           328:        register down1, down2;
        !           329:        register use1, use2;
        !           330:        register struct lnm *np1, *np2;
        !           331: 
        !           332:        /* first, set variables which are set... */
        !           333: 
        !           334:        use1 = use2 = VALUSED;
        !           335:        if( p->in.op == ASSIGN ) use1 = VALSET;
        !           336:        else if( p->in.op == UNARY AND ) use1 = VALADDR;
        !           337:        else if( asgop( p->in.op ) ){ /* =ops */
        !           338:                use1 = VALUSED|VALSET;
        !           339:                if( down == EFF ) use1 |= VALASGOP;
        !           340:                }
        !           341: 
        !           342: 
        !           343:        /* print the lines for lint */
        !           344: 
        !           345:        down2 = down1 = VAL;
        !           346:        acount = 0;
        !           347: 
        !           348:        switch( p->in.op ){
        !           349: 
        !           350:        case EQ:
        !           351:        case NE:
        !           352:        case GT:
        !           353:        case GE:
        !           354:        case LT:
        !           355:        case LE:
        !           356:                if( p->in.left->in.type == CHAR && p->in.right->in.op==ICON && p->in.right->tn.lval < 0 ){
        !           357:                        werror( "nonportable character comparison" );
        !           358:                        }
        !           359:                if( (p->in.op==EQ || p->in.op==NE ) && ISUNSIGNED(p->in.left->in.type) && p->in.right->in.op == ICON ){
        !           360:                        if( p->in.right->tn.lval < 0 && p->in.right->tn.rval == NONAME && !ISUNSIGNED(p->in.right->in.type) ){
        !           361:                                werror( "comparison of unsigned with negative constant" );
        !           362:                                }
        !           363:                        }
        !           364:                break;
        !           365: 
        !           366:        case UGE:
        !           367:        case ULT:
        !           368:                if( p->in.right->in.op == ICON && p->in.right->tn.lval == 0 && p->in.right->tn.rval == NONAME ){
        !           369:                        werror( "unsigned comparison with 0?" );
        !           370:                        break;
        !           371:                        }
        !           372:        case UGT:
        !           373:        case ULE:
        !           374:                if( p->in.right->in.op == ICON && p->in.right->tn.lval <= 0 && !ISUNSIGNED(p->in.right->in.type) && p->in.right->tn.rval == NONAME ){
        !           375:                        werror( "degenerate unsigned comparison" );
        !           376:                        }
        !           377:                break;
        !           378: 
        !           379:        case COMOP:
        !           380:                down1 = EFF;
        !           381: 
        !           382:        case ANDAND:
        !           383:        case OROR:
        !           384:        case QUEST:
        !           385:                down2 = down;
        !           386:                /* go recursively left, then right  */
        !           387:                np1 = lnp;
        !           388:                lprt( p->in.left, down1, use1 );
        !           389:                np2 = lnp;
        !           390:                lprt( p->in.right, down2, use2 );
        !           391:                lmerge( np1, np2, 0 );
        !           392:                return;
        !           393: 
        !           394:        case SCONV:
        !           395:        case PCONV:
        !           396:        case COLON:
        !           397:                down1 = down2 = down;
        !           398:                break;
        !           399: 
        !           400:        case CALL:
        !           401:        case STCALL:
        !           402:        case FORTCALL:
        !           403:                acount = ctargs( p->in.right );
        !           404:        case UNARY CALL:
        !           405:        case UNARY STCALL:
        !           406:        case UNARY FORTCALL:
        !           407:                if( p->in.left->in.op == ICON && (id=p->in.left->tn.rval) != NONAME ){ /* used to be &name */
        !           408:                        struct symtab *sp = &stab[id];
        !           409:                        int lty;
        !           410: 
        !           411:                        fsave( ftitle );
        !           412:                        if (!nflag)
        !           413:                                doform(p, sp, acount);
        !           414:                        /*
        !           415:                         * if we're generating a library -C then
        !           416:                         * we don't want to output references to functions
        !           417:                         */
        !           418:                        if( Cflag ) break;
        !           419:                        /*  if a function used in an effects context is
        !           420:                         *  cast to type  void  then consider its value
        !           421:                         *  to have been disposed of properly
        !           422:                         *  thus a call of type  undef  in an effects
        !           423:                         *  context is construed to be used in a value
        !           424:                         *  context
        !           425:                         */
        !           426:                        if ((down == EFF) && (p->in.type != UNDEF)) {
        !           427:                                lty = LUE;
        !           428:                        } else if (down == EFF) {
        !           429:                                lty = LUV | LUE;
        !           430:                        } else {
        !           431:                                lty = LUV;
        !           432:                        }
        !           433:                        outdef( sp, lty, acount );
        !           434:                        if( acount ) {
        !           435:                                lpta( p->in.right );
        !           436:                                }
        !           437:                        }
        !           438:                break;
        !           439: 
        !           440:        case ICON:
        !           441:                /* look for &name case */
        !           442:                if( (id = p->tn.rval) >= 0 && id != NONAME ){
        !           443:                        q = &stab[id];
        !           444:                        q->sflags |= (SREF|SSET);
        !           445:                        q->suse = -lineno;
        !           446:                        }
        !           447:                return;
        !           448: 
        !           449:        case NAME:
        !           450:                if( (id = p->tn.rval) >= 0 && id != NONAME ){
        !           451:                        q = &stab[id];
        !           452:                        if( (uses&VALUSED) && !(q->sflags&SSET) ){
        !           453:                                if( q->sclass == AUTO || q->sclass == REGISTER ){
        !           454:                                        if( !ISARY(q->stype ) && !ISFTN(q->stype) && q->stype!=STRTY && q->stype!=UNIONTY ){
        !           455: #ifndef FLEXNAMES
        !           456:                                                werror( "%.8s may be used before set", q->sname );
        !           457: #else
        !           458:                                                werror( "%s may be used before set", q->sname );
        !           459: #endif
        !           460:                                                q->sflags |= SSET;
        !           461:                                                }
        !           462:                                        }
        !           463:                                }
        !           464:                        if( uses & VALASGOP ) break;  /* not a real use */
        !           465:                        if( uses & VALSET ) q->sflags |= SSET;
        !           466:                        if( uses & VALUSED ) q->sflags |= SREF;
        !           467:                        if( uses & VALADDR ) q->sflags |= (SREF|SSET);
        !           468:                        if( p->tn.lval == 0 ){
        !           469:                                lnp->lid = id;
        !           470:                                lnp->flgs = (uses&VALADDR)?0:((uses&VALSET)?VALSET:VALUSED);
        !           471:                                if( ++lnp >= &lnames[LNAMES] ) --lnp;
        !           472:                                }
        !           473:                        }
        !           474:                return;
        !           475: 
        !           476:                }
        !           477: 
        !           478:        /* recurse, going down the right side first if we can */
        !           479: 
        !           480:        switch( optype(p->in.op) ){
        !           481: 
        !           482:        case BITYPE:
        !           483:                np1 = lnp;
        !           484:                lprt( p->in.right, down2, use2 );
        !           485:        case UTYPE:
        !           486:                np2 = lnp;
        !           487:                lprt( p->in.left, down1, use1 );
        !           488:                }
        !           489: 
        !           490:        if( optype(p->in.op) == BITYPE ){
        !           491:                if( p->in.op == ASSIGN && p->in.left->in.op == NAME ){ /* special case for a =  .. a .. */
        !           492:                        lmerge( np1, np2, 0 );
        !           493:                        }
        !           494:                else lmerge( np1, np2, p->in.op != COLON );
        !           495:                /* look for assignments to fields, and complain */
        !           496:                if( p->in.op == ASSIGN && p->in.left->in.op == FLD && p->in.right->in.op == ICON ) fldcon( p );
        !           497:                }
        !           498: 
        !           499:        }
        !           500: 
        !           501: lmerge( np1, np2, flag ) struct lnm *np1, *np2; {
        !           502:        /* np1 and np2 point to lists of lnm members, for the two sides
        !           503:         * of a binary operator
        !           504:         * flag is 1 if commutation is possible, 0 otherwise
        !           505:         * lmerge returns a merged list, starting at np1, resetting lnp
        !           506:         * it also complains, if appropriate, about side effects
        !           507:         */
        !           508: 
        !           509:        register struct lnm *npx, *npy;
        !           510: 
        !           511:        for( npx = np2; npx < lnp; ++npx ){
        !           512: 
        !           513:                /* is it already there? */
        !           514:                for( npy = np1; npy < np2; ++npy ){
        !           515:                        if( npx->lid == npy->lid ){ /* yes */
        !           516:                                if( npx->flgs == 0 || npx->flgs == (VALSET|VALUSED) )
        !           517:                                        ;  /* do nothing */
        !           518:                                else if( (npx->flgs|npy->flgs)== (VALSET|VALUSED) ||
        !           519:                                        (npx->flgs&npy->flgs&VALSET) ){
        !           520: #ifndef FLEXNAMES
        !           521:                                        if( flag ) werror( "%.8s evaluation order undefined", stab[npy->lid].sname );
        !           522: #else
        !           523:                                        if( flag ) werror( "%s evaluation order undefined", stab[npy->lid].sname );
        !           524: #endif
        !           525:                                        }
        !           526:                                if( npy->flgs == 0 ) npx->flgs = 0;
        !           527:                                else npy->flgs |= npx->flgs;
        !           528:                                goto foundit;
        !           529:                                }
        !           530:                        }
        !           531: 
        !           532:                /* not there: update entry */
        !           533:                np2->lid = npx->lid;
        !           534:                np2->flgs = npx->flgs;
        !           535:                ++np2;
        !           536: 
        !           537:                foundit: ;
        !           538:                }
        !           539: 
        !           540:        /* all finished: merged list is at np1 */
        !           541:        lnp = np2;
        !           542:        }
        !           543: 
        !           544: efcode(){
        !           545:        /* code for the end of a function */
        !           546:        register struct symtab *cfp;
        !           547: 
        !           548:        cfp = &stab[curftn];
        !           549:        if( retstat & RETVAL && !(Cflag && cfp->sclass==STATIC) )
        !           550:                outdef( cfp, LRV, DECTY );
        !           551:        if( !vflag ){
        !           552:                vflag = argflag;
        !           553:                argflag = 0;
        !           554:                }
        !           555:        if( retstat == RETVAL+NRETVAL )
        !           556: #ifndef FLEXNAMES
        !           557:                werror( "function %.8s has return(e); and return;", cfp->sname);
        !           558: #else
        !           559:                werror( "function %s has return(e); and return;", cfp->sname);
        !           560: #endif
        !           561:        }
        !           562: 
        !           563: aocode(p) struct symtab *p; {
        !           564:        /* called when automatic p removed from stab */
        !           565:        register struct symtab *cfs;
        !           566:        cfs = &stab[curftn];
        !           567:        if(p->suse>0 && !(p->sflags&(SMOS|STAG)) ){
        !           568:                if( p->sclass == PARAM ){
        !           569: #ifndef FLEXNAMES
        !           570:                        if( vflag ) werror( "argument %.8s unused in function %.8s",
        !           571: #else
        !           572:                        if( vflag ) werror( "argument %s unused in function %s",
        !           573: #endif
        !           574:                                p->sname,
        !           575:                                cfs->sname );
        !           576:                        }
        !           577:                else {
        !           578: #ifndef FLEXNAMES
        !           579:                        if( p->sclass != TYPEDEF ) werror( "%.8s unused in function %.8s",
        !           580: #else
        !           581:                        if( p->sclass != TYPEDEF ) werror( "%s unused in function %s",
        !           582: #endif
        !           583:                                p->sname, cfs->sname );
        !           584:                        }
        !           585:                }
        !           586: 
        !           587:        if( p->suse < 0 && (p->sflags & (SSET|SREF|SMOS)) == SSET &&
        !           588:                !ISARY(p->stype) && !ISFTN(p->stype) ){
        !           589: 
        !           590: #ifndef FLEXNAMES
        !           591:                werror( "%.8s set but not used in function %.8s", p->sname, cfs->sname );
        !           592: #else
        !           593:                werror( "%s set but not used in function %s", p->sname, cfs->sname );
        !           594: #endif
        !           595:                }
        !           596: 
        !           597:        if( p->stype == STRTY || p->stype == UNIONTY || p->stype == ENUMTY ){
        !           598:                if( !zflag && dimtab[p->sizoff+1] < 0 )
        !           599: #ifndef FLEXNAMES
        !           600:                        werror( "structure %.8s never defined", p->sname );
        !           601: #else
        !           602:                        werror( "structure %s never defined", p->sname );
        !           603: #endif
        !           604:                }
        !           605: 
        !           606:        }
        !           607: 
        !           608: defnam( p ) register struct symtab *p; {
        !           609:        /* define the current location as the name p->sname */
        !           610: 
        !           611:        if( p->sclass == STATIC && (p->slevel>1 || Cflag) ) return;
        !           612: 
        !           613:        if( !ISFTN( p->stype ) )
        !           614:                if( p->sclass == STATIC ) outdef( p, LST, USUAL );
        !           615:                else outdef( p, libflag?LIB:LDI, USUAL );
        !           616:        }
        !           617: 
        !           618: zecode( n ){
        !           619:        /* n integer words of zeros */
        !           620:        OFFSZ temp;
        !           621:        temp = n;
        !           622:        inoff += temp*SZINT;
        !           623:        ;
        !           624:        }
        !           625: 
        !           626: andable( p ) NODE *p; {  /* p is a NAME node; can it accept & ? */
        !           627:        register r;
        !           628: 
        !           629:        if( p->in.op != NAME ) cerror( "andable error" );
        !           630: 
        !           631:        if( (r = p->tn.rval) < 0 ) return(1);  /* labels are andable */
        !           632: 
        !           633:        if( stab[r].sclass == AUTO || stab[r].sclass == PARAM ) return(0)        !           634: #ifndef FLEXNAMES
        !           635:        if( stab[r].sclass == REGISTER ) uerror( "can't take & of %.8s", stab[r].sname );
        !           636: #else
        !           637:        if( stab[r].sclass == REGISTER ) uerror( "can't take & of %s", stab[r].sname );
        !           638: #endif
        !           639:        return(1);
        !           640:        }
        !           641: 
        !           642: NODE *
        !           643: clocal(p) NODE *p; {
        !           644: 
        !           645:        /* this is called to do local transformations on
        !           646:           an expression tree preparitory to its being
        !           647:           written out in intermediate code.
        !           648:        */
        !           649: 
        !           650:        /* the major essential job is rewriting the
        !           651:           automatic variables and arguments in terms of
        !           652:           REG and OREG nodes */
        !           653:        /* conversion ops which are not necessary are also clobbered here */
        !           654:        /* in addition, any special features (such as rewriting
        !           655:           exclusive or) are easily handled here as well */
        !           656: 
        !           657:        register o;
        !           658:        register unsigned t, tl;
        !           659:        int s;
        !           660: 
        !           661:        switch( o = p->in.op ){
        !           662:        case NAME:
        !           663:                {
        !           664:                        extern int      didstr, subscr;
        !           665:                        extern NODE *   strnodes[];
        !           666: 
        !           667:                        if (didstr) {
        !           668:                                didstr = 0;
        !           669:                                strnodes[subscr] = p;
        !           670:                        }
        !           671:                }
        !           672:                break;
        !           673: 
        !           674:        case SCONV:
        !           675:        case PCONV:
        !           676:                if( p->in.left->in.type==ENUMTY ){
        !           677:                        p->in.left = pconvert( p->in.left );
        !           678:                        }
        !           679:                /* assume conversion takes place; type is inherited */
        !           680:                t = p->in.type;
        !           681:                tl = p->in.left->in.type;
        !           682:                if( aflag && (tl==LONG||tl==ULONG) && (t!=LONG&&t!=ULONG&&t!=UNDEF) ){
        !           683:                        werror( "long assignment may lose accuracy" );
        !           684:                        }
        !           685:                if( aflag>=2 && (tl!=LONG&&tl!=ULONG) && (t==LONG||t==ULONG) && p->in.left->in.op != ICON ){
        !           686:                        werror( "assignment to long may sign-extend incorrectly" );
        !           687:                        }
        !           688:                if( ISPTR(tl) && ISPTR(t) ){
        !           689:                        tl = DECREF(tl);
        !           690:                        t = DECREF(t);
        !           691:                        switch( ISFTN(t) + ISFTN(tl) ){
        !           692: 
        !           693:                        case 0:  /* neither is a function pointer */
        !           694:                                if( talign(t,p->fn.csiz) > talign(tl,p->in.left->fn.csiz) ){
        !           695:                                        if( hflag||pflag ) werror( "possible pointer alignment problem" );
        !           696:                                        }
        !           697:                                break;
        !           698: 
        !           699:                        case 1:
        !           700:                                werror( "questionable conversion of function pointer" );
        !           701: 
        !           702:                        case 2:
        !           703:                                ;
        !           704:                                }
        !           705:                        }
        !           706:                p->in.left->in.type = p->in.type;
        !           707:                p->in.left->fn.cdim = p->fn.cdim;
        !           708:                p->in.left->fn.csiz = p->fn.csiz;
        !           709:                p->in.op = FREE;
        !           710:                return( p->in.left );
        !           711: 
        !           712:        case PVCONV:
        !           713:        case PMCONV:
        !           714:                if( p->in.right->in.op != ICON ) cerror( "bad conversion");
        !           715:                p->in.op = FREE;
        !           716:                return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );
        !           717: 
        !           718:        case RS:
        !           719:        case LS:
        !           720:        case ASG RS:
        !           721:        case ASG LS:
        !           722:                if( p->in.right->in.op != ICON )
        !           723:                        break;
        !           724:                s = p->in.right->tn.lval;
        !           725:                if( s < 0 )
        !           726:                        werror( "negative shift" );
        !           727:                else
        !           728:                if( s >= dimtab[ p->fn.csiz ] )
        !           729:                        werror( "shift greater than size of object" );
        !           730:                break;
        !           731: 
        !           732:                }
        !           733: 
        !           734:        return(p);
        !           735:        }
        !           736: 
        !           737: NODE *
        !           738: offcon( off, t, d, s ) OFFSZ off; TWORD t;{  /* make a structure offset node */
        !           739:        register NODE *p;
        !           740:        p = bcon(0);
        !           741:        p->tn.lval = off/SZCHAR;
        !           742:        return(p);
        !           743:        }
        !           744: 
        !           745: noinit(){
        !           746:        /* storage class for such as "int a;" */
        !           747:        return( pflag ? EXTDEF : EXTERN );
        !           748:        }
        !           749: 
        !           750: 
        !           751: cinit( p, sz ) NODE *p; { /* initialize p into size sz */
        !           752:        register int id;
        !           753: 
        !           754:        inoff += sz;
        !           755:        if( p->in.op == INIT ){
        !           756:                if( p->in.left->in.op == ICON ) return;
        !           757:                if( p->in.left->in.op == NAME && p->in.left->in.type == MOE ) return;
        !           758:                }
        !           759:        uerror( "illegal initialization" );
        !           760:        }
        !           761: 
        !           762: char *
        !           763: exname( p ) char *p; {
        !           764:        /* make a name look like an external name in the local machine */
        !           765:        static char aa[8];
        !           766:        register int i;
        !           767: 
        !           768:        if( !pflag ) return(p);
        !           769:        for( i=0; i<6; ++i ){
        !           770:                if( isupper(*p ) ) aa[i] = tolower( *p );
        !           771:                else aa[i] = *p;
        !           772:                if( *p ) ++p;
        !           773:                }
        !           774:        aa[6] = '\0';
        !           775:        return( aa );
        !           776:        }
        !           777: 
        !           778: char *
        !           779: strip(s) char *s; {
        !           780: #ifndef FLEXNAMES
        !           781:        static char x[LFNM+1];
        !           782: #else
        !           783:        static char x[BUFSIZ];
        !           784: #endif
        !           785:        register char *p;
        !           786:        static  int     stripping = 0;
        !           787: 
        !           788:        if (stripping)
        !           789:                return(s);
        !           790:        stripping++;
        !           791:        for( p=x; *s; ++s ){
        !           792:                if( *s != '"' ){
        !           793: #ifndef FLEXNAMES
        !           794: /* PATCHED by ROBERT HENRY on 8Jul80 to fix 14 character file name bug */
        !           795:                        if( p >= &x[LFNM] )
        !           796: #else
        !           797:                        if( p >= &x[BUFSIZ] )
        !           798: #endif
        !           799:                                cerror( "filename too long" );
        !           800:                        *p++ = *s;
        !           801:                }
        !           802:        }
        !           803:        stripping = 0;
        !           804:        *p = '\0';
        !           805: #ifndef FLEXNAMES
        !           806:        return( x );
        !           807: #else
        !           808:        return( hash(x) );
        !           809: #endif
        !           810:        }
        !           811: 
        !           812: fsave( s ) char *s; {
        !           813:        static union rec fsname;
        !           814:        s = strip( s );
        !           815: #ifndef FLEXNAMES
        !           816:        if( strncmp( s, fsname.f.fn, LFNM ) )
        !           817: #else
        !           818:        if (fsname.f.fn == NULL || strcmp(s, fsname.f.fn))
        !           819: #endif
        !           820:                {
        !           821:                /* new one */
        !           822: #ifndef FLEXNAMES
        !           823:                strncpy( fsname.f.fn, s, LFNM );
        !           824: #else
        !           825:                fsname.f.fn = s;
        !           826: #endif
        !           827:                fsname.f.decflag = LFN;
        !           828:                fwrite( (char *)&fsname, sizeof(fsname), 1, stdout );
        !           829: #ifdef FLEXNAMES
        !           830:                /* if generating a library, prefix with the library name */
        !           831:                /* only do this for flexnames */
        !           832:                if( libname ){
        !           833:                        fwrite( libname, strlen(libname), 1, stdout );
        !           834:                        putchar( ':' );
        !           835:                        }
        !           836:                fwrite( fsname.f.fn, strlen(fsname.f.fn)+1, 1, stdout );
        !           837: #endif
        !           838:                }
        !           839:        }
        !           840: 
        !           841: where(f){ /* print true location of error */
        !           842:        if( f == 'u' && nerrors > 1 )
        !           843:                --nerrors; /* don't get "too many errors" */
        !           844:        fprintf( stderr, "%s(%d): ", strip(ftitle), lineno);
        !           845:        }
        !           846: 
        !           847:        /* a number of dummy routines, unneeded by lint */
        !           848: 
        !           849: branch(n){;}
        !           850: defalign(n){;}
        !           851: deflab(n){;}
        !           852: 
        !           853: extern char *  strchr();
        !           854: 
        !           855: #define SBUFSIZE       16
        !           856: #define SCLICK         80
        !           857: 
        !           858: #ifndef size_t
        !           859: #define size_t unsigned
        !           860: #endif /* !size_t */
        !           861: 
        !           862: static char *  strings[SBUFSIZE];
        !           863: static NODE *  strnodes[SBUFSIZE];
        !           864: static int     didstr;
        !           865: static int     subscr;
        !           866: static int     strapped;
        !           867: 
        !           868: bycode(t, i)
        !           869: {
        !           870:        extern char *   calloc();
        !           871:        extern char *   realloc();
        !           872: 
        !           873:        if (nflag || strapped)
        !           874:                return;
        !           875:        if (i == 0)
        !           876:                if (subscr < (SBUFSIZE - 1))
        !           877:                        ++subscr;
        !           878:        if (subscr >= SBUFSIZE)
        !           879:                return;
        !           880:        didstr = 1;
        !           881:        if ((i % SCLICK) == 0) {
        !           882:                strings[subscr] = (strings[subscr] == NULL) ?
        !           883:                        calloc((size_t) (SCLICK + 1), 1) :
        !           884:                        realloc(strings[subscr], (size_t) (i + SCLICK + 1));
        !           885:                if (strings[subscr] == NULL) {
        !           886:                        strapped = 1;
        !           887:                        return;
        !           888:                }
        !           889:        }
        !           890:        strings[subscr][i] = t;
        !           891: }
        !           892: 
        !           893: strforget()
        !           894: {
        !           895:        didstr = subscr = 0;
        !           896: }
        !           897: 
        !           898: static char *
        !           899: typestr(t)
        !           900: {
        !           901:        switch (t) {
        !           902:                case CHAR:              return "char";
        !           903:                case UCHAR:             return "unsigned char";
        !           904:                case SHORT:             return "short";
        !           905:                case USHORT:            return "unsigned short";
        !           906:                case INT:               return "int";
        !           907:                case UNSIGNED:          return "unsigned";
        !           908:                case ENUMTY:            return "enum";
        !           909:                case LONG:              return "long";
        !           910:                case ULONG:             return "unsigned long";
        !           911:                case FLOAT:             return "float";
        !           912:                case DOUBLE:            return "double";
        !           913:                case STRTY:             return "struct";
        !           914:                case UNIONTY:           return "union";
        !           915:                case PTR|CHAR:          return "char *";
        !           916:                case PTR|UCHAR:         return "unsigned char *";
        !           917:                case PTR|SHORT:         return "short *";
        !           918:                case PTR|USHORT:        return "unsigned short *";
        !           919:                case PTR|INT:           return "int *";
        !           920:                case PTR|UNSIGNED:      return "unsigned *";
        !           921:                case PTR|ENUMTY:        return "enum *";
        !           922:                case PTR|LONG:          return "long *";
        !           923:                case PTR|ULONG:         return "unsigned long *";
        !           924:                case PTR|FLOAT:         return "float *";
        !           925:                case PTR|DOUBLE:        return "double *";
        !           926:                case PTR|STRTY:         return "struct *";
        !           927:                case PTR|UNIONTY:       return "union *";
        !           928:                default:                return ISPTR(t) ?
        !           929:                                                "pointer" : "non-scalar";
        !           930:        }
        !           931: }
        !           932: 
        !           933: NODE *
        !           934: ntharg(p, n, acount)
        !           935: NODE *         p;
        !           936: register int   n;
        !           937: register int   acount;
        !           938: {
        !           939:        if (n > acount)
        !           940:                return NULL;
        !           941:        p = p->in.right;
        !           942:        while (n != acount) {
        !           943:                p = p->in.left;
        !           944:                --acount;
        !           945:        }
        !           946:        return (n == 1) ? p : p->in.right;
        !           947: }
        !           948: 
        !           949: struct entry {
        !           950:        /* If argument to print/scan is of type... */   int     argtype;
        !           951:        /* ...and this length character is used... */   char    lchar;
        !           952:        /* ...and one of these is control char... */    char *  cchars;
        !           953:        /* ...then use this format with werror... */    char *  werror;
        !           954:        /* ...(where NULL means it's hunky dory)... */
        !           955: };
        !           956: 
        !           957: /*
        !           958: ** Portable printf.
        !           959: ** H&S says "%o" takes an unsigned argument;
        !           960: ** X3J11 says "%o" takes an int argument;
        !           961: ** we'll allow either here.
        !           962: */
        !           963: 
        !           964: static struct entry pprintf[] = {
        !           965:        CHAR,           '\0',   "c",            NULL, /* this is deliberate */
        !           966:        INT,            '\0',   "cdoxX",        NULL,
        !           967:        UNSIGNED,       '\0',   "uoxX",         NULL,
        !           968:        CHAR,           '\0',   "cdoxX",        NULL,
        !           969:        UCHAR,          '\0',   "udoxX",        NULL, /* yes, d is okay */
        !           970:        SHORT,          '\0',   "cdoxX",        NULL,
        !           971:        USHORT,         '\0',   "uoxX",         NULL,
        !           972:        ENUMTY,         '\0',   "duoxX",        NULL,
        !           973:        LONG,           'l',    "doxX",         NULL,
        !           974:        ULONG,          'l',    "uoxX",         NULL,
        !           975:        FLOAT,          '\0',   "eEfgG",        NULL,
        !           976:        DOUBLE,         '\0',   "eEfgG",        NULL,
        !           977:        PTR|CHAR,       '\0',   "s",            NULL,
        !           978:        UNDEF,          '\0',   "",             NULL
        !           979: };
        !           980: 
        !           981: /*
        !           982: ** Berkeley printf.
        !           983: ** It allows %D, %O, and %U, which we deprecate.
        !           984: ** Since
        !           985: **     sizeof (char *) == sizeof (int) &&
        !           986: **     sizeof (int) == sizeof (long) &&
        !           987: **     sizeof (char *) == sizeof (int *)
        !           988: ** you can be lax--and we tolerate *some* laxness. 
        !           989: ** g/lax/p to find lax table entries and code.
        !           990: */
        !           991: 
        !           992: static char    uppercase[] = "deprecated upper-case control character (%c)";
        !           993: #define lax    NULL
        !           994: 
        !           995: static struct entry bprintf[] = {
        !           996:        CHAR,           '\0',   "c",            NULL,   /* this is deliberate */
        !           997:        INT,            '\0',   "cdoxX",        NULL,
        !           998:        INT,            '\0',   "DO",           uppercase,
        !           999:        UNSIGNED,       '\0',   "uoxX",         NULL,
        !          1000:        UNSIGNED,       '\0',   "UO",           uppercase,
        !          1001:        CHAR,           '\0',   "cdoxX",        NULL,
        !          1002:        CHAR,           '\0',   "DO",           uppercase,
        !          1003:        UCHAR,          '\0',   "duoxX",        NULL,   /* yes, d is okay */
        !          1004:        UCHAR,          '\0',   "DUO",          uppercase,
        !          1005:        SHORT,          '\0',   "cdoxX",        NULL,
        !          1006:        SHORT,          '\0',   "DO",           uppercase,
        !          1007:        USHORT,         '\0',   "duoxX",        NULL,   /* d okay on BSD */
        !          1008:        USHORT,         '\0',   "DUO",          uppercase,
        !          1009:        ENUMTY,         '\0',   "duoxX",        NULL,
        !          1010:        ENUMTY,         '\0',   "DUO",          uppercase,
        !          1011:        LONG,           '\0',   "doxX",         lax,
        !          1012:        LONG,           '\0',   "DO",           uppercase,
        !          1013:        LONG,           'l',    "doxX",         NULL,
        !          1014:        INT,            'l',    "doxX",         lax,
        !          1015:        ULONG,          '\0',   "uoxX",         lax,
        !          1016:        ULONG,          '\0',   "UO",           uppercase,
        !          1017:        ULONG,          'l',    "uoxX",         NULL,
        !          1018:        UNSIGNED,       'l',    "uoxX",         lax,
        !          1019:        FLOAT,          '\0',   "eEfgG",        NULL,
        !          1020:        DOUBLE,         '\0',   "eEfgG",        NULL,
        !          1021:        PTR|CHAR,       '\0',   "s",            NULL,
        !          1022:        UNDEF,          '\0',   NULL,           NULL,
        !          1023: };
        !          1024: 
        !          1025: /*
        !          1026: ** Portable scanf.  'l' and 'h' are universally ignored preceding 'c' and 's',
        !          1027: ** and 'h' is universally ignored preceding 'e' and 'f',
        !          1028: ** but you won't find such cruft here.
        !          1029: */
        !          1030: 
        !          1031: static struct entry pscanf[] = {
        !          1032:        INT,            '\0',   "dox",  NULL,
        !          1033:        UNSIGNED,       '\0',   "uox",  NULL,
        !          1034:        CHAR,           '\0',   "cs[",  NULL,
        !          1035:        SHORT,          'h',    "dox",  NULL,
        !          1036:        USHORT,         'h',    "uox",  NULL,
        !          1037:        LONG,           'l',    "dox",  NULL,
        !          1038:        ULONG,          'l',    "uox",  NULL,
        !          1039:        FLOAT,          '\0',   "ef",   NULL,   /* BSD doesn't handle g */
        !          1040:        DOUBLE,         'l',    "ef",   NULL,
        !          1041:        UNDEF,          '\0',   NULL,   NULL,
        !          1042: };
        !          1043: 
        !          1044: /*
        !          1045: ** Berkeley scanf.  An upper case letter equals an l plus the lower case char,
        !          1046: ** but this is deprecated.
        !          1047: ** Even though sizeof (int) == sizeof (long), we'll be picky here.
        !          1048: */
        !          1049: 
        !          1050: static struct entry bscanf[] = {
        !          1051:        INT,            '\0',   "dox",  NULL,
        !          1052:        UNSIGNED,       '\0',   "uox",  NULL,
        !          1053:        CHAR,           '\0',   "cs[",  NULL,
        !          1054:        SHORT,          'h',    "dox",  NULL,
        !          1055:        USHORT,         'h',    "uox",  NULL,
        !          1056:        LONG,           '\0',   "dox",  lax,
        !          1057:        LONG,           '\0',   "DOX",  uppercase,
        !          1058:        LONG,           'l',    "dox",  NULL,
        !          1059:        ULONG,          '\0',   "uox",  lax,
        !          1060:        ULONG,          '\0',   "UOX",  uppercase,
        !          1061:        ULONG,          'l',    "uox",  NULL,
        !          1062:        FLOAT,          '\0',   "ef",   NULL,
        !          1063:        DOUBLE,         '\0',   "EF",   uppercase,
        !          1064:        DOUBLE,         'l',    "ef",   NULL,
        !          1065:        UNDEF,          '\0',   NULL,   NULL,
        !          1066: };
        !          1067: 
        !          1068: static struct item {
        !          1069:        char *          name;           /* such as "printf" */
        !          1070:        int             isscan;         /* scanf/printf */
        !          1071:        int             fmtarg;         /* number of format argument */
        !          1072:        struct entry *  ptable;         /* portable checking table */
        !          1073:        struct entry *  btable;         /* berkeley checking table */
        !          1074: } items[] = {
        !          1075:        "printf",       0,      1,      pprintf,        bprintf,        
        !          1076:        "fprintf",      0,      2,      pprintf,        bprintf,
        !          1077:        "sprintf",      0,      2,      pprintf,        bprintf,
        !          1078:        "scanf",        1,      1,      pscanf,         bscanf,
        !          1079:        "fscanf",       1,      2,      pscanf,         bscanf,
        !          1080:        "sscanf",       1,      2,      pscanf,         bscanf,
        !          1081:        NULL,           -1,     -1,     NULL,           NULL
        !          1082: };
        !          1083: 
        !          1084: static char    pwf[]   = "possible wild format";
        !          1085: static char    pfacm[] = "possible format/argument count mismatch";
        !          1086: 
        !          1087: static struct entry *
        !          1088: findlc(ep, lchar, cchar)
        !          1089: register struct entry *        ep;
        !          1090: register int           lchar;
        !          1091: register int           cchar;
        !          1092: {
        !          1093:        for ( ; ep->argtype != UNDEF; ++ep)
        !          1094:                if (ep->lchar == lchar && strchr(ep->cchars, cchar) != 0)
        !          1095:                        return ep;
        !          1096:        return NULL;
        !          1097: }
        !          1098: 
        !          1099: static char *
        !          1100: subform(p, sp, acount)
        !          1101: register NODE *                        p;
        !          1102: register struct symtab *       sp;
        !          1103: {
        !          1104:        register int            i, j, isscan;
        !          1105:        register NODE *         tp;
        !          1106:        register char *         cp;
        !          1107:        register struct entry * basep;
        !          1108:        register struct entry * ep;
        !          1109:        register struct item *  ip;
        !          1110:        register int            lchar;
        !          1111:        register int            cchar;
        !          1112:        register int            t;
        !          1113:        register int            suppressed;
        !          1114:        static char             errbuf[132];
        !          1115: 
        !          1116:        if (nflag || strapped)
        !          1117:                return NULL;
        !          1118:        cp = sp->sname;
        !          1119:        for (ip = items; ; ++ip)
        !          1120:                if (ip->name == NULL)
        !          1121:                        return NULL;    /* not a print/scan function */
        !          1122:                else if (strcmp(ip->name, sp->sname) == 0)
        !          1123:                        break;
        !          1124:        isscan = ip->isscan;
        !          1125:        i = ip->fmtarg;
        !          1126:        if (i > acount)
        !          1127:                return NULL;    /* handled in pass 2 */
        !          1128:        tp = ntharg(p, i, acount);
        !          1129:        if (tp->in.type != (PTR|CHAR))
        !          1130:                return NULL;    /* handled in pass 2 */
        !          1131:        if (tp->in.op != ICON || tp->tn.lval != 0)
        !          1132:                return NULL;    /* can't check it */
        !          1133:        for (j = 1; j <= subscr; ++j)
        !          1134:                if (tp == strnodes[j])
        !          1135:                        break;
        !          1136:        if (j > subscr)
        !          1137:                return NULL;    /* oh well. . . */
        !          1138:        cp = strings[j];
        !          1139:        /*
        !          1140:        ** cp now points to format string.
        !          1141:        */
        !          1142:        /*
        !          1143:        ** For now, ALWAYS use "portable" table, rather than doing this:
        !          1144:        **      basep = pflag ? ip->ptable : ip->btable;
        !          1145:        */
        !          1146:        basep = ip->ptable;
        !          1147:        for ( ; ; ) {
        !          1148:                if (*cp == '\0')
        !          1149:                        return (i == acount) ? NULL : pfacm;
        !          1150:                if (*cp++ != '%')
        !          1151:                        continue;
        !          1152:                if (*cp == '\0')
        !          1153:                        return "wild trailing %% in format";
        !          1154:                if (*cp == '%') {
        !          1155:                        ++cp;
        !          1156:                        continue;
        !          1157:                }
        !          1158:                if (isscan) {
        !          1159:                        suppressed = *cp == '*';
        !          1160:                        if (suppressed)
        !          1161:                                ++cp;
        !          1162:                        while (isdigit(*cp))
        !          1163:                                ++cp;
        !          1164:                        if (!suppressed && ++i <= acount) {
        !          1165:                                t = ntharg(p, i, acount)->in.type;
        !          1166:                                if (!ISPTR(t)) {
        !          1167: (void) sprintf(errbuf,
        !          1168:        "%s argument is type (%s) rather than pointer (arg %d)",
        !          1169:        ip->name, typestr(t), i);
        !          1170:                                        return errbuf;
        !          1171:                                }
        !          1172:                                t = DECREF(t);
        !          1173:                        }
        !          1174:                } else {
        !          1175:                        int     nspace, ndash, nplus, nhash;
        !          1176: 
        !          1177:                        suppressed = 0;
        !          1178:                        nspace = ndash = nplus = nhash = 0;
        !          1179:                        for ( ; ; ) {
        !          1180:                                if (*cp == ' ')
        !          1181:                                        ++nspace;
        !          1182:                                else if (*cp == '+')
        !          1183:                                        ++nplus;
        !          1184:                                else if (*cp == '-')
        !          1185:                                        ++ndash;
        !          1186:                                else if (*cp == '#')
        !          1187:                                        ++nhash;
        !          1188:                                else    break;
        !          1189:                                ++cp;
        !          1190:                        }
        !          1191:                        if (nspace > 1 || ndash > 1 || nplus > 1 || nhash > 1)
        !          1192:                                return "wild repeated flag character in format";
        !          1193:                        if (*cp == '*') {
        !          1194:                                ++cp;
        !          1195:                                if (++i > acount)
        !          1196:                                        break;
        !          1197:                                t = ntharg(p, i, acount)->in.type;
        !          1198:                                /*
        !          1199:                                ** Width other than INT or UNSIGNED is suspect.
        !          1200:                                */
        !          1201:                                if (t != INT && t != UNSIGNED) {
        !          1202: (void) sprintf(errbuf,
        !          1203:        "field width argument is type (%s) rather than (int) (arg %d)",
        !          1204:        typestr(t), i);
        !          1205:                                        return errbuf;
        !          1206:                                }
        !          1207:                        } else while (isdigit(*cp))
        !          1208:                                ++cp;
        !          1209:                        if (*cp == '.') {
        !          1210:                                ++cp;
        !          1211:                                if (*cp == '*') {
        !          1212:                                        ++cp;
        !          1213:                                        if (++i > acount)
        !          1214:                                                return pfacm;
        !          1215:                                        t = ntharg(p, i, acount)->in.type;
        !          1216:                                        if (t != INT && t != UNSIGNED) {
        !          1217: (void) sprintf(errbuf,
        !          1218:        "precision argument is type (%s) rather than (int) (arg %d)",
        !          1219:        typestr(t), i);
        !          1220:                                                return errbuf;
        !          1221:                                        }
        !          1222:                                } else while (isdigit(*cp))
        !          1223:                                        ++cp;
        !          1224:                        }
        !          1225:                        if (++i <= acount)
        !          1226:                                t = ntharg(p, i, acount)->in.type;
        !          1227:                }
        !          1228:                if (*cp == 'h' || *cp == 'l')
        !          1229:                        lchar = *cp++;
        !          1230:                else    lchar = '\0';
        !          1231:                if ((cchar = *cp++) == '\0')
        !          1232:                        return pwf;
        !          1233:                if (i > acount)
        !          1234:                        return (findlc(basep, lchar, cchar) == NULL) ?
        !          1235:                                pwf : pfacm;
        !          1236:                if (!isscan && !pflag && ISPTR(t) &&
        !          1237:                        strchr("douxX", cchar) != 0)
        !          1238:                                continue;       /* lax--printf("%d", (int *)) */
        !          1239:                if (suppressed) {
        !          1240:                        if (findlc(basep, lchar, cchar) == NULL)
        !          1241:                                return pwf;
        !          1242:                } else for (ep = basep; ; ++ep) {
        !          1243:                        if (ep->argtype == UNDEF) {     /* end of table */
        !          1244:                                ep = findlc(basep, lchar, cchar);
        !          1245:                                if (ep == NULL)
        !          1246:                                        return pwf;
        !          1247: (void) sprintf(errbuf, "%s: (%s) format, (%s) arg (arg %d)",
        !          1248:                                        ip->name,
        !          1249:                                        typestr(ep->argtype),
        !          1250:                                        typestr(isscan ? (t | PTR) : t), i);
        !          1251:                                return errbuf;
        !          1252:                        }
        !          1253:                        if (ep->argtype == t && ep->lchar == lchar &&
        !          1254:                                strchr(ep->cchars, cchar) != 0)
        !          1255:                                        if (ep->werror == 0)
        !          1256:                                                break;
        !          1257:                                        else {
        !          1258:                                                werror(ep->werror, cchar);
        !          1259:                                                return NULL;
        !          1260:                                        }
        !          1261:                }
        !          1262:                if (cchar != '[')
        !          1263:                        continue;
        !          1264:                do {
        !          1265:                        if (*cp == '\0')
        !          1266:                                return "possible unmatched '[' in format";
        !          1267:                } while (*cp++ != ']');
        !          1268:        }
        !          1269:        /*NOTREACHED*/
        !          1270: }
        !          1271: 
        !          1272: doform(p, sp, acount)
        !          1273: NODE *         p;
        !          1274: struct symtab *        sp;
        !          1275: {
        !          1276:        char *  cp;
        !          1277: 
        !          1278:        if ((cp = subform(p, sp, acount)) != NULL)
        !          1279:                werror(cp);
        !          1280: }
        !          1281: 
        !          1282: cisreg(t) TWORD t; {return(1);}  /* everyting is a register variable! */
        !          1283: 
        !          1284: fldty(p) struct symtab *p; {
        !          1285:        ; /* all types are OK here... */
        !          1286:        }
        !          1287: 
        !          1288: fldal(t) unsigned t; { /* field alignment... */
        !          1289:        if( t == ENUMTY ) return( ALCHAR );  /* this should be thought through better... */
        !          1290:        if( ISPTR(t) ){ /* really for the benefit of honeywell (and someday IBM) */
        !          1291:                if( pflag ) uerror( "nonportable field type" );
        !          1292:                }
        !          1293:        else uerror( "illegal field type" );
        !          1294:        return(ALINT);
        !          1295:        }
        !          1296: 
        !          1297: main(argc, argv)
        !          1298:        int     argc;
        !          1299:        char    **argv;
        !          1300: {
        !          1301:        extern char     *optarg;
        !          1302:        extern int      optind;
        !          1303:        int     ch;
        !          1304: 
        !          1305:        while ((ch = getopt(argc,argv,"C:D:I:U:LX:Pabchnpuvxz")) != EOF)
        !          1306:                switch((char)ch) {
        !          1307:                        case 'C':
        !          1308:                                Cflag = 1;
        !          1309:                                libname = optarg;
        !          1310:                                continue;
        !          1311:                        case 'D':       /* #define */
        !          1312:                        case 'I':       /* include path */
        !          1313:                        case 'U':       /* #undef */
        !          1314:                        case 'X':       /* debugging, done in first pass */
        !          1315:                        case 'P':       /* debugging, done in second pass */
        !          1316:                                break;
        !          1317:                        case 'L':
        !          1318:                                libflag = 1;
        !          1319:                                /*FALLTHROUGH*/
        !          1320:                        case 'v':       /* unused arguments in functions */
        !          1321:                                vflag = 0;
        !          1322:                                break;
        !          1323:                        case 'a':       /* long to int assignment */
        !          1324:                                ++aflag;
        !          1325:                                break;
        !          1326:                        case 'b':       /* unreached break statements */
        !          1327:                                brkflag = 1;
        !          1328:                                break;
        !          1329:                        case 'c':       /* questionable casts */
        !          1330:                                cflag = 1;
        !          1331:                                break;
        !          1332:                        case 'h':       /* heuristics */
        !          1333:                                hflag = 1;
        !          1334:                                break;
        !          1335:                        case 'n':       /* standard library check */
        !          1336:                                nflag = 1;
        !          1337:                                break;
        !          1338:                        case 'p':       /* IBM & GCOS portability */
        !          1339:                                pflag = 1;
        !          1340:                                break;
        !          1341:                        case 'u':       /* 2nd pass: undefined or unused */
        !          1342:                                break;
        !          1343:                        case 'x':       /* unused externs */
        !          1344:                                xflag = 1;
        !          1345:                                break;
        !          1346:                        case 'z':       /* use of undefined structures */
        !          1347:                                zflag = 1;
        !          1348:                                break;
        !          1349:                        case '?':
        !          1350:                        default:
        !          1351:                                fputs("usage: lint [-C lib] [-D def] [-I include] [-U undef] [-Labchnpuvx] file ...\n",stderr);
        !          1352:                                exit(1);
        !          1353:                }
        !          1354: 
        !          1355:        if (!pflag) {           /* set sizes to sizes of target machine */
        !          1356: # ifdef gcos
        !          1357:                SZCHAR = ALCHAR = 9;
        !          1358: # else
        !          1359:                SZCHAR = ALCHAR = 8;
        !          1360: # endif
        !          1361:                SZINT = ALINT = sizeof(int)*SZCHAR;
        !          1362:                SZFLOAT = ALFLOAT = sizeof(float)*SZCHAR;
        !          1363:                SZDOUBLE = ALDOUBLE = sizeof(double)*SZCHAR;
        !          1364:                SZLONG = ALLONG = sizeof(long)*SZCHAR;
        !          1365:                SZSHORT = ALSHORT = sizeof(short)*SZCHAR;
        !          1366:                SZPOINT = ALPOINT = sizeof(int *)*SZCHAR;
        !          1367:                ALSTRUCT = ALINT;
        !          1368:                /* now, fix some things up for various machines (I wish we had "alignof") */
        !          1369: 
        !          1370: # ifdef pdp11
        !          1371:                ALLONG = ALDOUBLE = ALFLOAT = ALINT;
        !          1372: # endif
        !          1373: # ifdef ibm
        !          1374:                ALSTRUCT = ALCHAR;
        !          1375: # endif
        !          1376:        }
        !          1377:        return(mainp1(argc,argv));
        !          1378: }
        !          1379: 
        !          1380: ctype( type ) unsigned type; { /* are there any funny types? */
        !          1381:        return( type );
        !          1382:        }
        !          1383: 
        !          1384: commdec( i ){
        !          1385:        /* put out a common declaration */
        !          1386:        if( stab[i].sclass == STATIC ) outdef( &stab[i], LST, USUAL );
        !          1387:        else outdef( &stab[i], libflag?LIB:LDC, USUAL );
        !          1388:        }
        !          1389: 
        !          1390: isitfloat ( s ) char *s; {
        !          1391:        /* s is a character string;
        !          1392:           if floating point is implemented, set dcon to the value of s */
        !          1393:        /* lint version
        !          1394:        */
        !          1395:        dcon = atof( s );
        !          1396:        return( DCON );
        !          1397:        }
        !          1398: 
        !          1399: fldcon( p ) register NODE *p; {
        !          1400:        /* p is an assignment of a constant to a field */
        !          1401:        /* check to see if the assignment is going to overflow, or otherwise cause trouble */
        !          1402:        register s;
        !          1403:        CONSZ v;
        !          1404: 
        !          1405:        if( !hflag & !pflag ) return;
        !          1406: 
        !          1407:        s = UPKFSZ(p->in.left->tn.rval);
        !          1408:        v = p->in.right->tn.lval;
        !          1409: 
        !          1410:        switch( p->in.left->in.type ){
        !          1411: 
        !          1412:        case CHAR:
        !          1413:        case INT:
        !          1414:        case SHORT:
        !          1415:        case LONG:
        !          1416:        case ENUMTY:
        !          1417:                if( v>=0 && (v>>(s-1))==0 ) return;
        !          1418:                werror( "precision lost in assignment to (possibly sign-extended) field" );
        !          1419:        default:
        !          1420:                return;
        !          1421: 
        !          1422:        case UNSIGNED:
        !          1423:        case UCHAR:
        !          1424:        case USHORT:
        !          1425:        case ULONG:
        !          1426:                if( v<0 || (v>>s)!=0 ) werror( "precision lost in field assignment" );
        !          1427:                
        !          1428:                return;
        !          1429:                }
        !          1430: 
        !          1431:        }
        !          1432: 
        !          1433: outdef( p, lty, mode ) struct symtab *p; {
        !          1434:        /* output a definition for the second pass */
        !          1435:        /* if mode is > USUAL, it is the number of args */
        !          1436:        char *fname;
        !          1437:        TWORD t;
        !          1438:        int line;
        !          1439:        static union rec rc;
        !          1440: 
        !          1441:        if( mode == NOFILE ){
        !          1442:                fname = "???";
        !          1443:                line = p->suse;
        !          1444:                }
        !          1445:        else if( mode == SVLINE ){
        !          1446:                fname = ftitle;
        !          1447:                line = -p->suse;
        !          1448:                }
        !          1449:        else {
        !          1450:                fname = ftitle;
        !          1451:                line = lineno;
        !          1452:                }
        !          1453:        fsave( fname );
        !          1454: #ifndef FLEXNAMES
        !          1455:        strncpy( rc.l.name, exname(p->sname), LCHNM );
        !          1456: #endif
        !          1457:        rc.l.decflag = lty;
        !          1458:        t = p->stype;
        !          1459:        if( mode == DECTY ) t = DECREF(t);
        !          1460:        rc.l.type.aty = t;
        !          1461:        rc.l.type.extra = 0;
        !          1462:        rc.l.type.extra1 = 0;
        !          1463:        astype( &rc.l.type, p->sizoff );
        !          1464:        rc.l.nargs = (mode>USUAL) ? mode : 0;
        !          1465:        rc.l.fline = line;
        !          1466:        fwrite( (char *)&rc, sizeof(rc), 1, stdout );
        !          1467: #ifdef FLEXNAMES
        !          1468:        rc.l.name = exname(p->sname);
        !          1469:        fwrite( rc.l.name, strlen(rc.l.name)+1, 1, stdout );
        !          1470: #endif
        !          1471:        }
        !          1472: int proflg;
        !          1473: int gdebug;

unix.superglobalmegacorp.com

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