|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.