Annotation of researchv8dc/cmd/lint/lint2.c, revision 1.1.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: #ifdef FLEXNAMES
                    627: char *
                    628: getstr()
                    629: {
                    630:        char buf[BUFSIZ];
                    631:        register char *cp = buf;
                    632:        register int c;
                    633: 
                    634:        if (feof(stdin) || ferror(stdin))
                    635:                return("");
                    636:        while ((c = getchar()) > 0)
                    637:                *cp++ = c;
                    638:        if (c < 0) {
                    639:                fprintf(stderr, "pass 2 error: intermediate file format error (getstr)");
                    640:                exit(1);
                    641:        }
                    642:        *cp++ = 0;
                    643:        return (hash(buf));
                    644: }
                    645: 
                    646: #define        NSAVETAB        4096
                    647: char   *savetab;
                    648: int    saveleft;
                    649: 
                    650: char *
                    651: savestr(cp)
                    652:        register char *cp;
                    653: {
                    654:        register int len;
                    655: 
                    656:        len = strlen(cp) + 1;
                    657:        if (len > saveleft) {
                    658:                saveleft = NSAVETAB;
                    659:                if (len > saveleft)
                    660:                        saveleft = len;
                    661:                savetab = (char *)malloc(saveleft);
                    662:                if (savetab == 0) {
                    663:                        fprintf(stderr, "pass 2 error: ran out of memory (savestr)");
                    664:                        exit(1);
                    665:                }
                    666:        }
                    667:        strncpy(savetab, cp, len);
                    668:        cp = savetab;
                    669:        savetab += len;
                    670:        saveleft -= len;
                    671:        return (cp);
                    672: }
                    673: 
                    674: /*
                    675:  * The definition for the segmented hash tables.
                    676:  */
                    677: #define        MAXHASH 20
                    678: #define        HASHINC 1013
                    679: struct ht {
                    680:        char    **ht_low;
                    681:        char    **ht_high;
                    682:        int     ht_used;
                    683: } htab[MAXHASH];
                    684: 
                    685: char *
                    686: hash(s)
                    687:        char *s;
                    688: {
                    689:        register char **h;
                    690:        register i;
                    691:        register char *cp;
                    692:        struct ht *htp;
                    693:        int sh;
                    694: 
                    695:        /*
                    696:         * The hash function is a modular hash of
                    697:         * the sum of the characters with the sum
                    698:         * doubled before each successive character
                    699:         * is added.
                    700:         */
                    701:        cp = s;
                    702:        i = 0;
                    703:        while (*cp)
                    704:                i = i*2 + *cp++;
                    705:        sh = (i&077777) % HASHINC;
                    706:        cp = s;
                    707:        /*
                    708:         * There are as many as MAXHASH active
                    709:         * hash tables at any given point in time.
                    710:         * The search starts with the first table
                    711:         * and continues through the active tables
                    712:         * as necessary.
                    713:         */
                    714:        for (htp = htab; htp < &htab[MAXHASH]; htp++) {
                    715:                if (htp->ht_low == 0) {
                    716:                        register char **hp =
                    717:                            (char **) calloc(sizeof (char **), HASHINC);
                    718:                        if (hp == 0) {
                    719:                                fprintf(stderr, "pass 2 error: ran out of memory (hash)");
                    720:                                exit(1);
                    721:                        }
                    722:                        htp->ht_low = hp;
                    723:                        htp->ht_high = htp->ht_low + HASHINC;
                    724:                }
                    725:                h = htp->ht_low + sh;
                    726:                /*
                    727:                 * quadratic rehash increment
                    728:                 * starts at 1 and incremented
                    729:                 * by two each rehash.
                    730:                 */
                    731:                i = 1;
                    732:                do {
                    733:                        if (*h == 0) {
                    734:                                if (htp->ht_used > (HASHINC * 3)/4)
                    735:                                        break;
                    736:                                htp->ht_used++;
                    737:                                *h = savestr(cp);
                    738:                                return (*h);
                    739:                        }
                    740:                        if (**h == *cp && strcmp(*h, cp) == 0)
                    741:                                return (*h);
                    742:                        h += i;
                    743:                        i += 2;
                    744:                        if (h >= htp->ht_high)
                    745:                                h -= HASHINC;
                    746:                } while (i < HASHINC);
                    747:        }
                    748:        fprintf(stderr, "pass 2 error: ran out of hash tables");
                    749:        exit(1);
                    750: }
                    751: char   *tstrbuf[1];
                    752: #endif
                    753: 
                    754: 
                    755: # ifdef FMTARGS
                    756: 
                    757: #define FMTSIZE        256
                    758: 
                    759: char   *getfmt();
                    760: 
                    761: static char    pftab[256],     /* printf */
                    762:                pfltab[128],    /* printf %l? */
                    763:                sftab[256],     /* scanf */
                    764:                sfhtab[128],    /* scanf %h? */
                    765:                sfltab[128];    /* scanf %l? */
                    766: 
                    767: typedef struct {
                    768:        char    *fm_s;          /* format characters of interest */
                    769:        char    fm_ty;          /* expected arg type for fm_c */
                    770:        char    fm_lty;         /* expected type if preceded by `l' */
                    771:        char    fm_hty;         /* expected type if preceded by `h' */
                    772: } Fmtinit;
                    773: 
                    774: 
                    775: static Fmtinit pinit[] = {
                    776:                        { "dox",        INT, LONG },
                    777:                        { "efgEG",      DOUBLE },
                    778:                        { "c",          INT },
                    779:                        { "s",          CHAR+PTR },
                    780: #ifdef USGFMT
                    781:                        { "uX",         INT, LONG },
                    782: #else
                    783:                        { "DOX",        LONG },
                    784:                        { "u",          UNSIGNED, ULONG },
                    785: #endif
                    786:                        { 0 }
                    787:                        };
                    788: 
                    789: static Fmtinit sinit[] = {
                    790:                        { "dox",        INT+PTR, LONG+PTR, SHORT+PTR },
                    791:                        { "efg",        FLOAT+PTR, DOUBLE+PTR },
                    792:                        { "cs[",        CHAR+PTR },
                    793: #ifdef USGFMT
                    794:                        { "u",          UNSIGNED+PTR, ULONG+PTR, USHORT+PTR },
                    795: #else
                    796:                        { "DOX",        LONG+PTR },
                    797:                        { "EFG",        DOUBLE+PTR },
                    798: #endif
                    799:                        { 0 }
                    800:                        };
                    801: 
                    802: 
                    803: chkprintf (q, arg, fmt)
                    804:        STAB            *q;
                    805:        register int    arg;
                    806:        register char   *fmt;
                    807: {
                    808:        register int    c, d;
                    809:        register TWORD  ty;
                    810: 
                    811:        while (c = *fmt++) {
                    812:                if (c != '%' || (c = *fmt++) == '%')
                    813:                        continue;
                    814:                for (; c=='-' || c=='+' || c=='#' || c==' '; c = *fmt++);
                    815:                if (c == '*') {
                    816:                        fmtarg (q, arg++, INT, '*', 0);
                    817:                        c = *fmt++;
                    818:                }
                    819:                else    for (; c >= '0' && c <= '9'; c = *fmt++);
                    820:                if (c == '.')
                    821:                        if ((c = *fmt++) == '*') {
                    822:                                fmtarg (q, arg++, INT, '*', 0);
                    823:                                c = *fmt++;
                    824:                        }
                    825:                        else    for (; c >= '0' && c <= '9'; c = *fmt++);
                    826:                ty = pftab[c];
                    827:                if (c == 'l' && pftab[c = *fmt++]) {
                    828:                        d = 'l';
                    829:                        ty = pfltab[c];
                    830:                }
                    831:                else    d = 0;
                    832:                if (ty)
                    833:                        fmtarg (q, arg++, ty, c, d);
                    834:                else    goto bad;
                    835:        }
                    836: 
                    837:        if (arg < r.l.nargs)
                    838:                fmterror (q, "too many args for format");
                    839:        return;
                    840: 
                    841: bad:
                    842:        fmterror (q, "malformed format string");
                    843:        return;
                    844: }
                    845: 
                    846: 
                    847: chkscanf (q, arg, fmt)
                    848:        STAB            *q;
                    849:        register int    arg;
                    850:        register char   *fmt;
                    851: {
                    852:        register int    c, d = 0, suppress;
                    853:        TWORD           ty;
                    854: 
                    855:        while (c = *fmt++) {
                    856:                if (c != '%' || (c = *fmt++) == '%')
                    857:                        continue;
                    858:                if (suppress = (c == '*'))
                    859:                        c = *fmt++;
                    860:                for (; c >= '0' && c <= '9'; c = *fmt++);
                    861:                ty = sftab[c];
                    862:                if (c == '[') {
                    863:                        if ((c = *fmt++) == '^')
                    864:                                c = *fmt++;
                    865:                        if (c == ']')
                    866:                                c = *fmt++;
                    867:                        for (; c && c != ']'; c = *fmt++);
                    868:                        if (c != ']')
                    869:                                goto bad;
                    870:                        c = '[';
                    871:                }
                    872:                d = 0;
                    873:                if (c == 'l' || c == 'h') {
                    874:                        d = c;
                    875:                        if (sftab[c = *fmt++])
                    876:                                ty = fmt[-2] == 'l' ? sfltab[c] : sfhtab[c];
                    877:                }
                    878:                if (!ty)
                    879:                        goto bad;
                    880:                else    if (!suppress)
                    881:                                fmtarg (q, arg++, ty, c, d);
                    882:        }
                    883: 
                    884:        if (arg < r.l.nargs)
                    885:                fmterror (q, "too many args for format");
                    886:        return;
                    887: 
                    888: bad:
                    889:        fmterror (q, "malformed format string");
                    890:        return;
                    891: }
                    892: 
                    893: 
                    894: fmtarg (q, arg, ty, c, d)
                    895:        STAB    *q;
                    896:        char    c, d;
                    897:        int     arg;
                    898:        TWORD   ty;
                    899: {
                    900:        char    buf[16];
                    901:        TWORD   ty2;
                    902: 
                    903:        if (arg >= r.l.nargs) {
                    904:                if (arg == r.l.nargs)
                    905:                        fmterror (q, "too few args for format");
                    906:                return;
                    907:        }
                    908: 
                    909: #define deunsign(x) (ISUNSIGNED(BTYPE(x))?((x)&~BTMASK|DEUNSIGN(BTYPE(x))):(x))
                    910: 
                    911:        ty = deunsign (ty);
                    912:        ty2 = deunsign (atyp[arg].aty);
                    913: 
                    914:        if (ty == ty2)                          /* fat chance ... */
                    915:                return;
                    916: 
                    917:        if (sizeof (int) == sizeof (long))
                    918:                if ((ty & TMASK) == (ty2 & TMASK))
                    919:                        if (BTYPE (ty) == INT && BTYPE (ty2) == LONG ||
                    920:                            BTYPE (ty) == LONG && BTYPE (ty2) == INT)
                    921:                                return;
                    922: 
                    923:        prflex (q->name);
                    924:        printf (": %%%.1s%c for ", &d, c);
                    925:        sprintf (buf, "arg %d", arg+1);
                    926:        pty (atyp[arg].aty, buf);
                    927:        viceversa (q);
                    928:        return;
                    929: }
                    930: 
                    931: 
                    932: fmtcheck (q)
                    933:        STAB    *q;
                    934: {
                    935:        char    *fmt;
                    936:        int     arg = q->nargs;
                    937: 
                    938:        if (r.l.nargs < arg)    /* somebody else will complain */
                    939:                return;
                    940:        if (arg < 1)            /* should've been caught in pass 1 */
                    941:                return;
                    942:        if (!(fmt = getfmt (atyp+arg-1)))
                    943:                return;
                    944: 
                    945:        if (q->decflag & LPF)
                    946:                chkprintf (q, arg, fmt);
                    947:        else if (q->decflag & LSF)
                    948:                chkscanf (q, arg, fmt);
                    949:        return;
                    950: }
                    951: 
                    952: 
                    953: fmterror (q, msg)
                    954:        STAB    *q;
                    955:        char    *msg;
                    956: {
                    957:        prflex (q->name);
                    958:        printf (": %s", msg);
                    959:        viceversa (q);
                    960: }
                    961: 
                    962: 
                    963: int
                    964: fmtinit()
                    965: {
                    966:        char    *s;
                    967:        int     i;
                    968: 
                    969:        for (i = 0; s = pinit[i].fm_s; i++)
                    970:                for (; *s; s++) {
                    971:                        pftab[*s] = pinit[i].fm_ty;
                    972:                        pfltab[*s] = pinit[i].fm_lty;
                    973:                }
                    974:        for (i = 0; s = sinit[i].fm_s; i++)
                    975:                for (; *s; s++) {
                    976:                        sftab[*s] = sinit[i].fm_ty;
                    977:                        sfhtab[*s] = sinit[i].fm_hty;
                    978:                        sfltab[*s] = sinit[i].fm_lty;
                    979:                }
                    980:        return;
                    981: }
                    982: 
                    983: 
                    984: char *
                    985: getfmt (a)
                    986:        register ATYPE  *a;
                    987: {
                    988:        static char     fmt[FMTSIZE];
                    989:        register char   *s = fmt;
                    990:        register int    c;
                    991: 
                    992:        if (a->straddr <= 0)
                    993:                return (0);     /* not a string constant */
                    994:        if (fseek (stmpfile, a->straddr, 0))
                    995:                error ("cannot fseek string file");
                    996: 
                    997:        while ((c = fgetc (stmpfile)) != EOF && c && s < fmt+FMTSIZE-1)
                    998:                *s++ = c;
                    999: 
                   1000:        *s = '\0';
                   1001:        return (fmt);
                   1002: }
                   1003: 
                   1004: 
                   1005: prflex (name)
                   1006:        char    *name;
                   1007: {
                   1008: #ifdef FLEXNAMES
                   1009:        printf ("%s", name);
                   1010: #else
                   1011:        printf ("%.8s", name);
                   1012: #endif
                   1013: }
                   1014: 
                   1015: 
                   1016: # endif

unix.superglobalmegacorp.com

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