Annotation of 43BSDTahoe/usr.bin/lint/lint.c, revision 1.1.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.