Annotation of researchv10no/cmd/lint/lint2.c, revision 1.1

1.1     ! root        1: # include "manifest"
        !             2: # include "lint.h"
        !             3: 
        !             4: # define USED 01
        !             5: # define VUSED 02
        !             6: # define EUSED 04
        !             7: # define RVAL 010
        !             8: # define VARARGS 0100
        !             9: 
        !            10: # define NSZ 2048
        !            11: # define TYSZ 3500
        !            12: # define FSZ 250
        !            13: # define NTY 50
        !            14: 
        !            15: typedef struct sty STYPE;
        !            16: struct sty { ATYPE t; STYPE *next; };
        !            17: 
        !            18: typedef struct sym {
        !            19: #ifndef FLEXNAMES
        !            20:        char name[LCHNM];
        !            21: #else
        !            22:        char *name;
        !            23: #endif
        !            24:        short nargs;
        !            25:        int decflag;
        !            26:        int fline;
        !            27:        STYPE symty;
        !            28:        int fno;
        !            29:        int use;
        !            30:        } STAB;
        !            31: 
        !            32: STAB stab[NSZ];
        !            33: STAB *find();
        !            34: 
        !            35: STYPE tary[TYSZ];
        !            36: STYPE *tget();
        !            37: 
        !            38: #ifndef FLEXNAMES
        !            39: char fnm[FSZ][LFNM];
        !            40: #else
        !            41: char *fnm[FSZ];
        !            42: #endif
        !            43: 
        !            44: #ifdef FLEXNAMES
        !            45: char *getstr();
        !            46: #endif
        !            47: 
        !            48: int tfree;  /* used to allocate types */
        !            49: int ffree;  /* used to save filenames */
        !            50: 
        !            51: struct ty atyp[NTY];
        !            52:        /* r is where all the input ends up */
        !            53: union rec r;
        !            54: 
        !            55: int hflag = 0;
        !            56: int pflag = 0;
        !            57: int xflag = 0;
        !            58: int uflag = 1;
        !            59: int ddddd = 0;
        !            60: 
        !            61: int cfno;  /* current file number */
        !            62: 
        !            63: #ifdef FMTARGS
        !            64: FILE   *stmpfile;      /* string tmp file pointer */
        !            65: char   *stmpname;      /* string tmp file name */
        !            66: #endif
        !            67: 
        !            68: 
        !            69: main( argc, argv ) char *argv[]; {
        !            70:        register char *p;
        !            71: 
        !            72:        /* first argument is intermediate file */
        !            73:        /* second argument is - options */
        !            74: 
        !            75: #ifdef FMTARGS
        !            76:        fmtinit();
        !            77: #endif
        !            78:        for( ; argc>2 && argv[argc-1][0] == '-' ; --argc ){
        !            79:                for( p=argv[argc-1]; *p; ++p ){
        !            80:                        switch( *p ){
        !            81: 
        !            82:                        case 'h':
        !            83:                                hflag = 1;
        !            84:                                break;
        !            85: 
        !            86:                        case 'p':
        !            87:                                pflag = 1;
        !            88:                                break;
        !            89: 
        !            90:                        case 'x':
        !            91:                                xflag = 1;
        !            92:                                break;
        !            93: 
        !            94:                        case 'X':
        !            95:                                ddddd = 1;
        !            96:                                break;
        !            97: 
        !            98:                        case 'u':
        !            99:                                uflag = 0;
        !           100:                                break;
        !           101: 
        !           102: #ifdef FMTARGS
        !           103:                        case 'S':
        !           104:                                for (stmpname = p + 1; p[1]; p++);
        !           105:                                if (!(stmpfile = fopen (stmpname, "r"))) {
        !           106:                                        error ("%s: can't open", stmpname);
        !           107:                                        exit (1);
        !           108:                                }
        !           109:                                break;
        !           110: #endif
        !           111:                                }
        !           112:                        }
        !           113:                }
        !           114: 
        !           115:        if( argc < 2 || !freopen( argv[1], "r", stdin ) ){
        !           116:                error( "cannot open intermediate file" );
        !           117:                exit( 1 );
        !           118:                }
        !           119: 
        !           120:        mloop( LDI|LIB );
        !           121:        rewind( stdin );
        !           122:        mloop( LDC|LDX );
        !           123:        rewind( stdin );
        !           124:        mloop( LRV|LUV|LUE|LUM );
        !           125:        cleanup();
        !           126:        return(0);
        !           127:        }
        !           128: 
        !           129: mloop( m ){
        !           130:        /* do the main loop */
        !           131:        register STAB *q;
        !           132: 
        !           133:        while( lread(m) ){
        !           134:                q = find();
        !           135:                if( q->decflag ) chkcompat(q);
        !           136:                else setuse(q);
        !           137:                }
        !           138:        }
        !           139: 
        !           140: lread(m){ /* read a line into r.l */
        !           141: 
        !           142:        register n;
        !           143: 
        !           144:        for(;;) {
        !           145:                if( fread( (char *)&r, sizeof(r), 1, stdin ) <= 0 ) return(0);
        !           146:                if( r.l.decflag & LFN ){
        !           147:                        /* new filename */
        !           148: #ifdef FLEXNAMES
        !           149:                        r.f.fn = getstr();
        !           150: #endif
        !           151:                        setfno( r.f.fn );
        !           152:                        continue;
        !           153:                        }
        !           154: #ifdef FLEXNAMES
        !           155:                r.l.name = getstr();
        !           156: #endif
        !           157: 
        !           158:                n = r.l.nargs;
        !           159:                if( n<0 ) n = -n;
        !           160:                if( n ){
        !           161:                        if( n>=NTY ) error( "more than %d args?", n );
        !           162:                        fread( (char *)atyp, sizeof(ATYPE), n, stdin );
        !           163:                        }
        !           164:                if( ( r.l.decflag & m ) ) return( 1 );
        !           165:                }
        !           166:        }
        !           167: 
        !           168: setfno( s ) char *s; {
        !           169:        /* look up current file names */
        !           170:        /* first, strip backwards to the beginning or to the first / */
        !           171:        int i;
        !           172: 
        !           173:        /* now look up s */
        !           174:        for( i=0; i<ffree; ++i ){
        !           175: #ifndef FLEXNAMES
        !           176:                if( !strncmp( s, fnm[i], LFNM ) ){
        !           177: #else
        !           178:                if (fnm[i] == s){
        !           179: #endif
        !           180:                        cfno = i;
        !           181:                        return;
        !           182:                        }
        !           183:                }
        !           184:        /* make a new entry */
        !           185:        if( ffree >= FSZ ) error( "more than %d files", FSZ );
        !           186: #ifndef FLEXNAMES
        !           187:        strncpy( fnm[ffree], s, LFNM );
        !           188: #else
        !           189:        fnm[ffree] = s;
        !           190: #endif
        !           191:        cfno = ffree++;
        !           192:        }
        !           193: 
        !           194: /* VARARGS */
        !           195: error( s, a ) char *s; {
        !           196: 
        !           197: #ifndef FLEXNAMES
        !           198:        fprintf( stderr, "pass 2 error:(file %.*s) ", LFNM, fnm[cfno] );
        !           199: #else
        !           200:        fprintf( stderr, "pass 2 error:(file %s) ", fnm[cfno] );
        !           201: #endif
        !           202:        fprintf( stderr, s, a );
        !           203:        fprintf( stderr, "\n" );
        !           204:        exit(1);
        !           205:        }
        !           206: 
        !           207: STAB *
        !           208: find(){
        !           209:        /* for this to work, NSZ should be a power of 2 */
        !           210:        register h=0;
        !           211: #ifndef FLEXNAMES
        !           212:        {       register char *p, *q;
        !           213:                for( h=0,p=r.l.name,q=p+LCHNM; *p&&p<q; ++p) {
        !           214:                        h = (h<<1)+ *p;
        !           215:                        if( h>=NSZ ){
        !           216:                                h = (h+1)&(NSZ-1);
        !           217:                                }
        !           218:                        }
        !           219:                }
        !           220: #else
        !           221:                h = ((int)r.l.name)%NSZ;
        !           222: #endif
        !           223:        {       register STAB *p, *q;
        !           224:                for( p=q= &stab[h]; q->decflag; ){
        !           225:                        /* this call to strncmp should be taken out... */
        !           226: #ifndef FLEXNAMES
        !           227:                        if( !strncmp( r.l.name, q->name, LCHNM)) return(q);
        !           228: #else
        !           229:                        if (r.l.name == q->name) return (q);
        !           230: #endif
        !           231:                        if( ++q >= &stab[NSZ] ) q = stab;
        !           232:                        if( q == p ) error( "too many names defined" );
        !           233:                        }
        !           234: #ifndef FLEXNAMES
        !           235:                strncpy( q->name, r.l.name, LCHNM );
        !           236: #else
        !           237:                q->name = r.l.name;
        !           238: #endif
        !           239:                return( q );
        !           240:                }
        !           241:        }
        !           242: 
        !           243: STYPE *
        !           244: tget(){
        !           245:        if( tfree >= TYSZ ){
        !           246:                error( "too many types needed" );
        !           247:                }
        !           248:        return( &tary[tfree++] );
        !           249:        }
        !           250: 
        !           251: chkcompat(q) STAB *q; {
        !           252:        /* are the types, etc. in r.l and q compatible */
        !           253:        register int i;
        !           254:        STYPE *qq;
        !           255: 
        !           256:        setuse(q);
        !           257: 
        !           258:        /* argument check */
        !           259: 
        !           260:        if( q->decflag & (LDI|LIB|LUV|LUE) ){
        !           261:                if( r.l.decflag & (LUV|LIB|LUE) ){
        !           262: #ifdef FMTARGS
        !           263:                        if (q->decflag & (LPF|LSF)) {
        !           264:                                fmtcheck (q);
        !           265:                                if(r.l.nargs > q->nargs)
        !           266:                                        r.l.nargs = q->nargs;
        !           267:                                q->use |= VARARGS;
        !           268:                        }
        !           269: #endif
        !           270:                        if( q->nargs != r.l.nargs ){
        !           271:                                if( !(q->use&VARARGS) ){
        !           272: #ifndef FLEXNAMES
        !           273:                                        printf( "%.8s: variable # of args.", q->name );
        !           274: #else
        !           275:                                        printf( "%s: variable # of args.", q->name );
        !           276: #endif
        !           277:                                        viceversa(q);
        !           278:                                        }
        !           279:                                if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs;
        !           280:                                if( !(q->decflag & (LDI|LIB) ) ) {
        !           281:                                        q->nargs = r.l.nargs;
        !           282:                                        q->use |= VARARGS;
        !           283:                                        }
        !           284:                                }
        !           285:                        for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next){
        !           286:                                if( chktype( &qq->t, &atyp[i] ) ){
        !           287: #ifndef FLEXNAMES
        !           288:                                        printf( "%.8s, arg. %d used inconsistently",
        !           289: #else
        !           290:                                        printf( "%s, arg. %d used inconsistently",
        !           291: #endif
        !           292:                                                q->name, i+1 );
        !           293:                                        viceversa(q);
        !           294:                                        }
        !           295:                                }
        !           296:                        }
        !           297:                }
        !           298: 
        !           299:        if( (q->decflag&(LDI|LIB|LUV)) && r.l.decflag==LUV ){
        !           300:                if( chktype( &r.l.type, &q->symty.t ) ){
        !           301: #ifndef FLEXNAMES
        !           302:                        printf( "%.8s value used inconsistently", q->name );
        !           303: #else
        !           304:                        printf( "%s value used inconsistently", q->name );
        !           305: #endif
        !           306:                        viceversa(q);
        !           307:                        }
        !           308:                }
        !           309: 
        !           310:        /* check for multiple declaration */
        !           311: 
        !           312:        if( (q->decflag&LDI) && (r.l.decflag&(LDI|LIB)) ){
        !           313: #ifndef FLEXNAMES
        !           314:                printf( "%.8s multiply declared", q->name );
        !           315: #else
        !           316:                printf( "%s multiply declared", q->name );
        !           317: #endif
        !           318:                viceversa(q);
        !           319:                }
        !           320: 
        !           321:        /* do a bit of checking of definitions and uses... */
        !           322: 
        !           323:        if( (q->decflag & (LDI|LIB|LDX|LDC|LUM)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){
        !           324: #ifndef FLEXNAMES
        !           325:                printf( "%.8s value declared inconsistently", q->name );
        !           326: #else
        !           327:                printf( "%s value declared inconsistently", q->name );
        !           328: #endif
        !           329:                viceversa(q);
        !           330:                }
        !           331: 
        !           332:        /* better not call functions which are declared to be structure or union returning */
        !           333: 
        !           334:        if( (q->decflag & (LDI|LIB|LDX|LDC)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){
        !           335:                /* only matters if the function returns union or structure */
        !           336:                TWORD ty;
        !           337:                ty = q->symty.t.aty;
        !           338:                if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){
        !           339: #ifndef FLEXNAMES
        !           340:                        printf( "%.8s function value type must be declared before use", q->name );
        !           341: #else
        !           342:                        printf( "%s function value type must be declared before use", q->name );
        !           343: #endif
        !           344:                        viceversa(q);
        !           345:                        }
        !           346:                }
        !           347: 
        !           348:        if( pflag && q->decflag==LDX && r.l.decflag == LUM && !ISFTN(q->symty.t.aty) ){
        !           349:                /* make the external declaration go away */
        !           350:                /* in effect, it was used without being defined */
        !           351:                }
        !           352:        }
        !           353: 
        !           354: viceversa(q) STAB *q; {
        !           355:        /* print out file comparison */
        !           356: #ifndef FLEXNAMES
        !           357:        printf( "       %.*s(%d)  ::  %.*s(%d)\n",
        !           358:                LFNM, fnm[q->fno], q->fline,
        !           359:                LFNM, fnm[cfno], r.l.fline );
        !           360: #else
        !           361:        printf( "       %s(%d)  ::  %s(%d)\n",
        !           362:                fnm[q->fno], q->fline,
        !           363:                fnm[cfno], r.l.fline );
        !           364: #endif
        !           365:        }
        !           366: 
        !           367:        /* messages for defintion/use */
        !           368: char *
        !           369: mess[2][2] ={
        !           370:        "",
        !           371: #ifndef FLEXNAMES
        !           372:        "%.8s used( %.*s(%d) ), but not defined\n",
        !           373:        "%.8s defined( %.*s(%d) ), but never used\n",
        !           374:        "%.8s declared( %.*s(%d) ), but never used or defined\n"
        !           375: #else
        !           376:        "%s used( %s(%d) ), but not defined\n",
        !           377:        "%s defined( %s(%d) ), but never used\n",
        !           378:        "%s declared( %s(%d) ), but never used or defined\n"
        !           379: #endif
        !           380:        };
        !           381: 
        !           382: lastone(q) STAB *q; {
        !           383: 
        !           384:        register nu, nd, uses;
        !           385: 
        !           386:        if( ddddd ) pst(q);
        !           387: 
        !           388:        nu = nd = 0;
        !           389:        uses = q->use;
        !           390: 
        !           391: #ifdef FMTARGS
        !           392:        /* not needed anymore, right? */
        !           393:        q->decflag &= ~(LPF|LSF);
        !           394: #endif
        !           395: 
        !           396:        if( !(uses&USED) && q->decflag != LIB ) {
        !           397: #ifndef FLEXNAMES
        !           398:                if( strncmp(q->name,"main",7) )
        !           399: #else
        !           400:                if (strcmp(q->name, "main"))
        !           401: #endif
        !           402:                        nu = 1;
        !           403:                }
        !           404: 
        !           405:        if( !ISFTN(q->symty.t.aty) ){
        !           406:                switch( q->decflag ){
        !           407: 
        !           408:                case LIB:
        !           409:                        nu = nd = 0;  /* don't complain about uses on libraries */
        !           410:                        break;
        !           411:                case LDX:
        !           412:                        if( !xflag ) break;
        !           413:                case LUV:
        !           414:                case LUE:
        !           415: /* 01/04/80 */ case LUV | LUE:
        !           416:                case LUM:
        !           417:                        nd = 1;
        !           418:                        }
        !           419:                }
        !           420:        if( uflag && ( nu || nd ) ) printf( mess[nu][nd],
        !           421: #ifndef FLEXNAMES
        !           422:                 q->name, LFNM, fnm[q->fno], q->fline );
        !           423: #else
        !           424:                 q->name, fnm[q->fno], q->fline );
        !           425: #endif
        !           426: 
        !           427:        if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
        !           428: #ifndef FLEXNAMES
        !           429:                printf( "%.8s returns value which is %s ignored\n", q->name,
        !           430: #else
        !           431:                printf( "%s returns value which is %s ignored\n", q->name,
        !           432: #endif
        !           433:                        uses&VUSED ? "sometimes" : "always" );
        !           434:                }
        !           435: 
        !           436:        if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB)) ){
        !           437: #ifndef FLEXNAMES
        !           438:                printf( "%.8s value is used, but none returned\n", q->name );
        !           439: #else
        !           440:                printf( "%s value is used, but none returned\n", q->name );
        !           441: #endif
        !           442:                }
        !           443:        }
        !           444: 
        !           445: cleanup(){ /* call lastone and die gracefully */
        !           446:        STAB *q;
        !           447:        for( q=stab; q< &stab[NSZ]; ++q ){
        !           448:                if( q->decflag ) lastone(q);
        !           449:                }
        !           450:        exit(0);
        !           451:        }
        !           452: 
        !           453: setuse(q) STAB *q; { /* check new type to ensure that it is used */
        !           454: 
        !           455:        if( !q->decflag ){ /* new one */
        !           456:                q->decflag = r.l.decflag;
        !           457:                q->symty.t = r.l.type;
        !           458:                if( r.l.nargs < 0 ){
        !           459:                        q->nargs = -r.l.nargs;
        !           460:                        q->use = VARARGS;
        !           461:                        }
        !           462:                else {
        !           463:                        q->nargs = r.l.nargs;
        !           464:                        q->use = 0;
        !           465:                        }
        !           466:                q->fline = r.l.fline;
        !           467:                q->fno = cfno;
        !           468:                if( q->nargs ){
        !           469:                        int i;
        !           470:                        STYPE *qq;
        !           471:                        for( i=0,qq= &q->symty; i<q->nargs; ++i,qq=qq->next ){
        !           472:                                qq->next = tget();
        !           473:                                qq->next->t = atyp[i];
        !           474:                                }
        !           475:                        }
        !           476:                }
        !           477: 
        !           478:        switch( r.l.decflag ){
        !           479: 
        !           480:        case LRV:
        !           481:                q->use |= RVAL;
        !           482:                return;
        !           483:        case LUV:
        !           484:                q->use |= VUSED+USED;
        !           485:                return;
        !           486:        case LUE:
        !           487:                q->use |= EUSED+USED;
        !           488:                return;
        !           489: /* 01/04/80 */ case LUV | LUE:
        !           490:        case LUM:
        !           491:                q->use |= USED;
        !           492:                return;
        !           493: 
        !           494:                }
        !           495:        }
        !           496: 
        !           497: chktype( pt1, pt2 ) register ATYPE *pt1, *pt2; {
        !           498:        TWORD t;
        !           499: 
        !           500:        /* check the two type words to see if they are compatible */
        !           501:        /* for the moment, enums are turned into ints, and should be checked as such */
        !           502:        if( pt1->aty == ENUMTY ) pt1->aty =  INT;
        !           503:        if( pt2->aty == ENUMTY ) pt2->aty = INT;
        !           504: 
        !           505:        if( (t=BTYPE(pt1->aty)==STRTY) || t==UNIONTY ){
        !           506:                return( pt1->aty!=pt2->aty || (
        !           507:                        pt1->extra!=pt2->extra ) );
        !           508:                }
        !           509: 
        !           510:        if( pt2->extra ){ /* constant passed in */
        !           511:                if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
        !           512:                else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
        !           513:                }
        !           514:        else if( pt1->extra ){ /* for symmetry */
        !           515:                if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
        !           516:                else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
        !           517:                }
        !           518: 
        !           519:        return( pt1->aty != pt2->aty );
        !           520:        }
        !           521: 
        !           522: struct tb { int m; char * nm };
        !           523: ptb( v, tp ) struct tb *tp; {
        !           524:        /* print a value from the table */
        !           525:        int flag;
        !           526:        flag = 0;
        !           527:        for( ; tp->m; ++tp ){
        !           528:                if( v&tp->m ){
        !           529:                        if( flag++ ) putchar( '|' );
        !           530:                        printf( "%s", tp->nm );
        !           531:                        }
        !           532:                }
        !           533:        }
        !           534: 
        !           535: pst( q ) STAB *q; {
        !           536:        /* give a debugging output for q */
        !           537:        static struct tb dfs[] = {
        !           538:                LDI, "LDI",
        !           539:                LIB, "LIB",
        !           540:                LDC, "LDC",
        !           541:                LDX, "LDX",
        !           542:                LRV, "LRV",
        !           543:                LUV, "LUV",
        !           544:                LUE, "LUE",
        !           545:                LUM, "LUM",
        !           546: #ifdef FMTARGS
        !           547:                LPF, "printf-like",
        !           548:                LSF, "scanf-like",
        !           549: #endif
        !           550:                0, "" };
        !           551: 
        !           552:        static struct tb us[] = {
        !           553:                USED, "USED",
        !           554:                VUSED, "VUSED",
        !           555:                EUSED, "EUSED",
        !           556:                RVAL, "RVAL",
        !           557:                VARARGS, "VARARGS",
        !           558:                0,      0,
        !           559:                };
        !           560: 
        !           561: #ifndef FLEXNAMES
        !           562:        printf( "%.8s (", q->name );
        !           563: #else
        !           564:        printf( "%s (", q->name );
        !           565: #endif
        !           566:        ptb( q->decflag, dfs );
        !           567:        printf( "), use= " );
        !           568:        ptb( q->use, us );
        !           569:        printf( ", line %d, nargs=%d\n", q->fline, q->nargs );
        !           570:        }
        !           571: 
        !           572: #ifdef FLEXNAMES
        !           573: 
        !           574: pty( t, name )  TWORD t; {
        !           575:        static char * tnames[] = {
        !           576:                "void", "farg", "char", "short",
        !           577:                "int", "long", "float", "double",
        !           578:                "struct xxx", "union %s", "enum", "moety",
        !           579:                "unsigned char", "unsigned short", "unsigned", "unsigned long",
        !           580:                "?", "?"
        !           581:                };
        !           582: 
        !           583:        printf( "%s ", tnames[BTYPE(t)] );
        !           584:        pty1( t, name, (8 * sizeof (int) - BTSHIFT) / TSHIFT );
        !           585:        }
        !           586: 
        !           587: pty1( t, name, level ) TWORD t; {
        !           588:        register TWORD u;
        !           589: 
        !           590:        if( level < 0 ){
        !           591:                printf( "%s", name );
        !           592:                return;
        !           593:                }
        !           594:        u = t >> level * TSHIFT;
        !           595:        if( ISPTR(u) ){
        !           596:                printf( "*" );
        !           597:                pty1( t, name, level-1 );
        !           598:                }
        !           599:        else if( ISFTN(u) ){
        !           600:                if( level > 0 && ISPTR(u << TSHIFT) ){
        !           601:                        printf( "(" );
        !           602:                        pty1( t, name, level-1 );
        !           603:                        printf( ")()" );
        !           604:                        }
        !           605:                else {
        !           606:                        pty1( t, name, level-1 );
        !           607:                        printf( "()" );
        !           608:                        }
        !           609:                }
        !           610:        else if( ISARY(u) ){
        !           611:                if( level > 0 && ISPTR(u << TSHIFT) ){
        !           612:                        printf( "(" );
        !           613:                        pty1( t, name, level-1 );
        !           614:                        printf( ")[]" );
        !           615:                        }
        !           616:                else {
        !           617:                        pty1( t, name, level-1 );
        !           618:                        printf( "[]" );
        !           619:                        }
        !           620:                }
        !           621:        else {
        !           622:                pty1( t, name, level-1 );
        !           623:                }
        !           624:        }
        !           625: 
        !           626: char *
        !           627: getstr()
        !           628: {
        !           629:        char buf[BUFSIZ];
        !           630:        register char *cp = buf;
        !           631:        register int c;
        !           632: 
        !           633:        if (feof(stdin) || ferror(stdin))
        !           634:                return("");
        !           635:        while ((c = getchar()) > 0)
        !           636:                *cp++ = c;
        !           637:        if (c < 0) {
        !           638:                fprintf(stderr, "pass 2 error: intermediate file format error (getstr)");
        !           639:                exit(1);
        !           640:        }
        !           641:        *cp++ = 0;
        !           642:        return (hash(buf));
        !           643: }
        !           644: 
        !           645: #define        NSAVETAB        4096
        !           646: char   *savetab;
        !           647: int    saveleft;
        !           648: 
        !           649: char *
        !           650: savestr(cp)
        !           651:        register char *cp;
        !           652: {
        !           653:        register int len;
        !           654: 
        !           655:        len = strlen(cp) + 1;
        !           656:        if (len > saveleft) {
        !           657:                saveleft = NSAVETAB;
        !           658:                if (len > saveleft)
        !           659:                        saveleft = len;
        !           660:                savetab = (char *)malloc(saveleft);
        !           661:                if (savetab == 0) {
        !           662:                        fprintf(stderr, "pass 2 error: ran out of memory (savestr)");
        !           663:                        exit(1);
        !           664:                }
        !           665:        }
        !           666:        strncpy(savetab, cp, len);
        !           667:        cp = savetab;
        !           668:        savetab += len;
        !           669:        saveleft -= len;
        !           670:        return (cp);
        !           671: }
        !           672: 
        !           673: /*
        !           674:  * The definition for the segmented hash tables.
        !           675:  */
        !           676: #define        MAXHASH 20
        !           677: #define        HASHINC 1013
        !           678: struct ht {
        !           679:        char    **ht_low;
        !           680:        char    **ht_high;
        !           681:        int     ht_used;
        !           682: } htab[MAXHASH];
        !           683: 
        !           684: char *
        !           685: hash(s)
        !           686:        char *s;
        !           687: {
        !           688:        register char **h;
        !           689:        register i;
        !           690:        register char *cp;
        !           691:        struct ht *htp;
        !           692:        int sh;
        !           693: 
        !           694:        /*
        !           695:         * The hash function is a modular hash of
        !           696:         * the sum of the characters with the sum
        !           697:         * doubled before each successive character
        !           698:         * is added.
        !           699:         */
        !           700:        cp = s;
        !           701:        i = 0;
        !           702:        while (*cp)
        !           703:                i = i*2 + *cp++;
        !           704:        sh = (i&077777) % HASHINC;
        !           705:        cp = s;
        !           706:        /*
        !           707:         * There are as many as MAXHASH active
        !           708:         * hash tables at any given point in time.
        !           709:         * The search starts with the first table
        !           710:         * and continues through the active tables
        !           711:         * as necessary.
        !           712:         */
        !           713:        for (htp = htab; htp < &htab[MAXHASH]; htp++) {
        !           714:                if (htp->ht_low == 0) {
        !           715:                        register char **hp =
        !           716:                            (char **) calloc(sizeof (char **), HASHINC);
        !           717:                        if (hp == 0) {
        !           718:                                fprintf(stderr, "pass 2 error: ran out of memory (hash)");
        !           719:                                exit(1);
        !           720:                        }
        !           721:                        htp->ht_low = hp;
        !           722:                        htp->ht_high = htp->ht_low + HASHINC;
        !           723:                }
        !           724:                h = htp->ht_low + sh;
        !           725:                /*
        !           726:                 * quadratic rehash increment
        !           727:                 * starts at 1 and incremented
        !           728:                 * by two each rehash.
        !           729:                 */
        !           730:                i = 1;
        !           731:                do {
        !           732:                        if (*h == 0) {
        !           733:                                if (htp->ht_used > (HASHINC * 3)/4)
        !           734:                                        break;
        !           735:                                htp->ht_used++;
        !           736:                                *h = savestr(cp);
        !           737:                                return (*h);
        !           738:                        }
        !           739:                        if (**h == *cp && strcmp(*h, cp) == 0)
        !           740:                                return (*h);
        !           741:                        h += i;
        !           742:                        i += 2;
        !           743:                        if (h >= htp->ht_high)
        !           744:                                h -= HASHINC;
        !           745:                } while (i < HASHINC);
        !           746:        }
        !           747:        fprintf(stderr, "pass 2 error: ran out of hash tables");
        !           748:        exit(1);
        !           749: }
        !           750: char   *tstrbuf[1];
        !           751: #endif
        !           752: 
        !           753: 
        !           754: # ifdef FMTARGS
        !           755: 
        !           756: #define FMTSIZE        256
        !           757: 
        !           758: char   *getfmt();
        !           759: 
        !           760: static char    pftab[256],     /* printf */
        !           761:                pfltab[128],    /* printf %l? */
        !           762:                sftab[256],     /* scanf */
        !           763:                sfhtab[128],    /* scanf %h? */
        !           764:                sfltab[128];    /* scanf %l? */
        !           765: 
        !           766: typedef struct {
        !           767:        char    *fm_s;          /* format characters of interest */
        !           768:        char    fm_ty;          /* expected arg type for fm_c */
        !           769:        char    fm_lty;         /* expected type if preceded by `l' */
        !           770:        char    fm_hty;         /* expected type if preceded by `h' */
        !           771: } Fmtinit;
        !           772: 
        !           773: 
        !           774: static Fmtinit pinit[] = {
        !           775:                        { "dox",        INT, LONG },
        !           776:                        { "efgEG",      DOUBLE },
        !           777:                        { "c",          INT },
        !           778:                        { "s",          CHAR+PTR },
        !           779: #ifdef USGFMT
        !           780:                        { "uX",         INT, LONG },
        !           781: #else
        !           782:                        { "DOX",        LONG },
        !           783:                        { "u",          UNSIGNED, ULONG },
        !           784: #endif
        !           785:                        { 0 }
        !           786:                        };
        !           787: 
        !           788: static Fmtinit sinit[] = {
        !           789:                        { "dox",        INT+PTR, LONG+PTR, SHORT+PTR },
        !           790:                        { "efg",        FLOAT+PTR, DOUBLE+PTR },
        !           791:                        { "cs[",        CHAR+PTR },
        !           792: #ifdef USGFMT
        !           793:                        { "u",          UNSIGNED+PTR, ULONG+PTR, USHORT+PTR },
        !           794: #else
        !           795:                        { "DOX",        LONG+PTR },
        !           796:                        { "EFG",        DOUBLE+PTR },
        !           797: #endif
        !           798:                        { 0 }
        !           799:                        };
        !           800: 
        !           801: 
        !           802: chkprintf (q, arg, fmt)
        !           803:        STAB            *q;
        !           804:        register int    arg;
        !           805:        register char   *fmt;
        !           806: {
        !           807:        register int    c, d;
        !           808:        register TWORD  ty;
        !           809: 
        !           810:        while (c = *fmt++) {
        !           811:                if (c != '%' || (c = *fmt++) == '%')
        !           812:                        continue;
        !           813:                for (; c=='-' || c=='+' || c=='#' || c==' '; c = *fmt++);
        !           814:                if (c == '*') {
        !           815:                        fmtarg (q, arg++, INT, '*', 0);
        !           816:                        c = *fmt++;
        !           817:                }
        !           818:                else    for (; c >= '0' && c <= '9'; c = *fmt++);
        !           819:                if (c == '.')
        !           820:                        if ((c = *fmt++) == '*') {
        !           821:                                fmtarg (q, arg++, INT, '*', 0);
        !           822:                                c = *fmt++;
        !           823:                        }
        !           824:                        else    for (; c >= '0' && c <= '9'; c = *fmt++);
        !           825:                ty = pftab[c];
        !           826:                if (c == 'l' && pftab[c = *fmt++]) {
        !           827:                        d = 'l';
        !           828:                        ty = pfltab[c];
        !           829:                }
        !           830:                else    d = 0;
        !           831:                if (ty)
        !           832:                        fmtarg (q, arg++, ty, c, d);
        !           833:                else    goto bad;
        !           834:        }
        !           835: 
        !           836:        if (arg < r.l.nargs)
        !           837:                fmterror (q, "too many args for format");
        !           838:        return;
        !           839: 
        !           840: bad:
        !           841:        fmterror (q, "malformed format string");
        !           842:        return;
        !           843: }
        !           844: 
        !           845: 
        !           846: chkscanf (q, arg, fmt)
        !           847:        STAB            *q;
        !           848:        register int    arg;
        !           849:        register char   *fmt;
        !           850: {
        !           851:        register int    c, d = 0, suppress;
        !           852:        TWORD           ty;
        !           853: 
        !           854:        while (c = *fmt++) {
        !           855:                if (c != '%' || (c = *fmt++) == '%')
        !           856:                        continue;
        !           857:                if (suppress = (c == '*'))
        !           858:                        c = *fmt++;
        !           859:                for (; c >= '0' && c <= '9'; c = *fmt++);
        !           860:                ty = sftab[c];
        !           861:                if (c == '[') {
        !           862:                        if ((c = *fmt++) == '^')
        !           863:                                c = *fmt++;
        !           864:                        if (c == ']')
        !           865:                                c = *fmt++;
        !           866:                        for (; c && c != ']'; c = *fmt++);
        !           867:                        if (c != ']')
        !           868:                                goto bad;
        !           869:                        c = '[';
        !           870:                }
        !           871:                d = 0;
        !           872:                if (c == 'l' || c == 'h') {
        !           873:                        d = c;
        !           874:                        if (sftab[c = *fmt++])
        !           875:                                ty = fmt[-2] == 'l' ? sfltab[c] : sfhtab[c];
        !           876:                }
        !           877:                if (!ty)
        !           878:                        goto bad;
        !           879:                else    if (!suppress)
        !           880:                                fmtarg (q, arg++, ty, c, d);
        !           881:        }
        !           882: 
        !           883:        if (arg < r.l.nargs)
        !           884:                fmterror (q, "too many args for format");
        !           885:        return;
        !           886: 
        !           887: bad:
        !           888:        fmterror (q, "malformed format string");
        !           889:        return;
        !           890: }
        !           891: 
        !           892: 
        !           893: fmtarg (q, arg, ty, c, d)
        !           894:        STAB    *q;
        !           895:        char    c, d;
        !           896:        int     arg;
        !           897:        TWORD   ty;
        !           898: {
        !           899:        char    buf[16];
        !           900:        TWORD   ty2;
        !           901: 
        !           902:        if (arg >= r.l.nargs) {
        !           903:                if (arg == r.l.nargs)
        !           904:                        fmterror (q, "too few args for format");
        !           905:                return;
        !           906:        }
        !           907: 
        !           908: #define deunsign(x) (ISUNSIGNED(BTYPE(x))?((x)&~BTMASK|DEUNSIGN(BTYPE(x))):(x))
        !           909: 
        !           910:        ty = deunsign (ty);
        !           911:        ty2 = deunsign (atyp[arg].aty);
        !           912: 
        !           913:        if (ty == ty2)                          /* fat chance ... */
        !           914:                return;
        !           915: 
        !           916:        if (sizeof (int) == sizeof (long))
        !           917:                if ((ty & TMASK) == (ty2 & TMASK))
        !           918:                        if (BTYPE (ty) == INT && BTYPE (ty2) == LONG ||
        !           919:                            BTYPE (ty) == LONG && BTYPE (ty2) == INT)
        !           920:                                return;
        !           921: 
        !           922:        prflex (q->name);
        !           923:        printf (": %%%.1s%c for ", &d, c);
        !           924:        sprintf (buf, "arg %d", arg+1);
        !           925:        pty (atyp[arg].aty, buf);
        !           926:        viceversa (q);
        !           927:        return;
        !           928: }
        !           929: 
        !           930: 
        !           931: fmtcheck (q)
        !           932:        STAB    *q;
        !           933: {
        !           934:        char    *fmt;
        !           935:        int     arg = q->nargs;
        !           936: 
        !           937:        if (r.l.nargs < arg)    /* somebody else will complain */
        !           938:                return;
        !           939:        if (arg < 1)            /* should've been caught in pass 1 */
        !           940:                return;
        !           941:        if (!(fmt = getfmt (atyp+arg-1)))
        !           942:                return;
        !           943: 
        !           944:        if (q->decflag & LPF)
        !           945:                chkprintf (q, arg, fmt);
        !           946:        else if (q->decflag & LSF)
        !           947:                chkscanf (q, arg, fmt);
        !           948:        return;
        !           949: }
        !           950: 
        !           951: 
        !           952: fmterror (q, msg)
        !           953:        STAB    *q;
        !           954:        char    *msg;
        !           955: {
        !           956:        prflex (q->name);
        !           957:        printf (": %s", msg);
        !           958:        viceversa (q);
        !           959: }
        !           960: 
        !           961: 
        !           962: int
        !           963: fmtinit()
        !           964: {
        !           965:        char    *s;
        !           966:        int     i;
        !           967: 
        !           968:        for (i = 0; s = pinit[i].fm_s; i++)
        !           969:                for (; *s; s++) {
        !           970:                        pftab[*s] = pinit[i].fm_ty;
        !           971:                        pfltab[*s] = pinit[i].fm_lty;
        !           972:                }
        !           973:        for (i = 0; s = sinit[i].fm_s; i++)
        !           974:                for (; *s; s++) {
        !           975:                        sftab[*s] = sinit[i].fm_ty;
        !           976:                        sfhtab[*s] = sinit[i].fm_hty;
        !           977:                        sfltab[*s] = sinit[i].fm_lty;
        !           978:                }
        !           979:        return;
        !           980: }
        !           981: 
        !           982: 
        !           983: char *
        !           984: getfmt (a)
        !           985:        register ATYPE  *a;
        !           986: {
        !           987:        static char     fmt[FMTSIZE];
        !           988:        register char   *s = fmt;
        !           989:        register int    c;
        !           990: 
        !           991:        if (a->straddr <= 0)
        !           992:                return (0);     /* not a string constant */
        !           993:        if (fseek (stmpfile, a->straddr, 0))
        !           994:                error ("cannot fseek string file");
        !           995: 
        !           996:        while ((c = fgetc (stmpfile)) != EOF && c && s < fmt+FMTSIZE-1)
        !           997:                *s++ = c;
        !           998: 
        !           999:        *s = '\0';
        !          1000:        return (fmt);
        !          1001: }
        !          1002: 
        !          1003: 
        !          1004: prflex (name)
        !          1005:        char    *name;
        !          1006: {
        !          1007: #ifdef FLEXNAMES
        !          1008:        printf ("%s", name);
        !          1009: #else
        !          1010:        printf ("%.8s", name);
        !          1011: #endif
        !          1012: }
        !          1013: 
        !          1014: 
        !          1015: # endif

unix.superglobalmegacorp.com

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