|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)lpass2.c 1.9 (Berkeley) 12/11/87"; ! 3: #endif lint ! 4: ! 5: # include "macdefs.h" ! 6: # include "manifest.h" ! 7: # include "lmanifest.h" ! 8: ! 9: # define USED 01 ! 10: # define VUSED 02 ! 11: # define EUSED 04 ! 12: # define RVAL 010 ! 13: # define VARARGS 0100 ! 14: ! 15: # define NSZ 4096 ! 16: # define TYSZ 3500 ! 17: # define FSZ 500 ! 18: # define NTY 50 ! 19: ! 20: typedef struct sty STYPE; ! 21: struct sty { ATYPE t; STYPE *next; }; ! 22: ! 23: typedef struct sym { ! 24: #ifndef FLEXNAMES ! 25: char name[LCHNM]; ! 26: #else ! 27: char *name; ! 28: #endif ! 29: short nargs; ! 30: int decflag; ! 31: int fline; ! 32: STYPE symty; ! 33: int fno; ! 34: int use; ! 35: } STAB; ! 36: ! 37: STAB stab[NSZ]; ! 38: STAB *find(); ! 39: ! 40: STYPE tary[TYSZ]; ! 41: STYPE *tget(); ! 42: ! 43: #ifndef FLEXNAMES ! 44: char fnm[FSZ][LFNM]; ! 45: #else ! 46: char *fnm[FSZ]; ! 47: #endif ! 48: ! 49: #ifdef FLEXNAMES ! 50: char *getstr(); ! 51: #endif ! 52: ! 53: int tfree; /* used to allocate types */ ! 54: int ffree; /* used to save filenames */ ! 55: ! 56: struct ty atyp[NTY]; ! 57: /* r is where all the input ends up */ ! 58: union rec r; ! 59: ! 60: int hflag = 0; ! 61: int pflag = 0; ! 62: int xflag = 0; ! 63: int uflag = 1; ! 64: int ddddd = 0; ! 65: int zflag = 0; ! 66: int Pflag = 0; ! 67: ! 68: int cfno; /* current file number */ ! 69: ! 70: main( argc, argv ) char *argv[]; { ! 71: register char *p; ! 72: ! 73: /* first argument is intermediate file */ ! 74: /* second argument is - options */ ! 75: ! 76: for( ; argc>2 && argv[argc-1][0] == '-' ; --argc ){ ! 77: for( p=argv[argc-1]; *p; ++p ){ ! 78: switch( *p ){ ! 79: ! 80: case 'h': ! 81: hflag = 1; ! 82: break; ! 83: ! 84: case 'p': ! 85: pflag = 1; ! 86: break; ! 87: ! 88: case 'x': ! 89: xflag = 1; ! 90: break; ! 91: ! 92: case 'X': ! 93: ddddd = 1; ! 94: break; ! 95: ! 96: case 'u': ! 97: uflag = 0; ! 98: break; ! 99: ! 100: case 'z': ! 101: zflag = 1; ! 102: break; ! 103: ! 104: case 'P': ! 105: Pflag = 1; ! 106: break; ! 107: ! 108: } ! 109: } ! 110: } ! 111: ! 112: if( argc < 2 || !freopen( argv[1], "r", stdin ) ){ ! 113: error( "cannot open intermediate file" ); ! 114: exit( 1 ); ! 115: } ! 116: if( Pflag ){ ! 117: pfile(); ! 118: return( 0 ); ! 119: } ! 120: mloop( LDI|LIB|LST ); ! 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(0); ! 150: #endif ! 151: if( Pflag ) return( 1 ); ! 152: setfno( r.f.fn ); ! 153: continue; ! 154: } ! 155: #ifdef FLEXNAMES ! 156: r.l.name = getstr(1); ! 157: #else /* !FLEXNAMES */ ! 158: portify(r.l.name); ! 159: #endif /* !FLEXNAMES */ ! 160: n = r.l.nargs; ! 161: if( n<0 ) n = ~n; ! 162: if( n>=NTY ) error( "more than %d args?", n ); ! 163: fread( (char *)atyp, sizeof(ATYPE), n, stdin ); ! 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: { ! 181: cfno = i; ! 182: return; ! 183: } ! 184: } ! 185: /* make a new entry */ ! 186: if( ffree >= FSZ ) error( "more than %d files", FSZ ); ! 187: #ifndef FLEXNAMES ! 188: strncpy( fnm[ffree], s, LFNM ); ! 189: #else ! 190: fnm[ffree] = s; ! 191: #endif ! 192: cfno = ffree++; ! 193: } ! 194: ! 195: /* VARARGS */ ! 196: error( s, a ) char *s; { ! 197: ! 198: #ifndef FLEXNAMES ! 199: fprintf( stderr, "pass 2 error:(file %.*s) ", LFNM, fnm[cfno] ); ! 200: #else ! 201: fprintf( stderr, "pass 2 error:(file %s) ", fnm[cfno] ); ! 202: #endif ! 203: fprintf( stderr, s, a ); ! 204: fprintf( stderr, "\n" ); ! 205: exit(1); ! 206: } ! 207: ! 208: STAB * ! 209: find(){ ! 210: register h=0; ! 211: #ifndef FLEXNAMES ! 212: h = hashstr(r.l.name, LCHNM) % NSZ; ! 213: #else ! 214: h = (int)r.l.name % NSZ; ! 215: #endif ! 216: { register STAB *p, *q; ! 217: for( p=q= &stab[h]; q->decflag; ){ ! 218: #ifndef FLEXNAMES ! 219: if( !strncmp( r.l.name, q->name, LCHNM)) ! 220: #else ! 221: if (r.l.name == q->name) ! 222: #endif ! 223: if( ((q->decflag|r.l.decflag)&LST)==0 || q->fno==cfno ) ! 224: return(q); ! 225: if( ++q >= &stab[NSZ] ) q = stab; ! 226: if( q == p ) error( "too many names defined" ); ! 227: } ! 228: #ifndef FLEXNAMES ! 229: strncpy( q->name, r.l.name, LCHNM ); ! 230: #else ! 231: q->name = r.l.name; ! 232: #endif ! 233: return( q ); ! 234: } ! 235: } ! 236: ! 237: STYPE * ! 238: tget(){ ! 239: if( tfree >= TYSZ ){ ! 240: error( "too many types needed" ); ! 241: } ! 242: return( &tary[tfree++] ); ! 243: } ! 244: ! 245: chkcompat(q) STAB *q; { ! 246: /* are the types, etc. in r.l and q compatible */ ! 247: register int i; ! 248: STYPE *qq; ! 249: ! 250: setuse(q); ! 251: ! 252: /* argument check */ ! 253: ! 254: if( q->decflag & (LDI|LIB|LUV|LUE|LST) ){ ! 255: if( r.l.decflag & (LUV|LIB|LUE) ){ ! 256: if( q->nargs != r.l.nargs ){ ! 257: if( !(q->use&VARARGS) ){ ! 258: #ifndef FLEXNAMES ! 259: printf( "%.8s: variable # of args.", q->name ); ! 260: #else ! 261: printf( "%s: variable # of args.", q->name ); ! 262: #endif ! 263: viceversa(q); ! 264: } ! 265: if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs; ! 266: if( !(q->decflag & (LDI|LIB|LST) ) ) { ! 267: q->nargs = r.l.nargs; ! 268: q->use |= VARARGS; ! 269: } ! 270: } ! 271: for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next){ ! 272: if( chktype( &qq->t, &atyp[i], q->fno ) ){ ! 273: #ifndef FLEXNAMES ! 274: printf( "%.8s, arg. %d used inconsistently", ! 275: #else ! 276: printf( "%s, arg. %d used inconsistently", ! 277: #endif ! 278: q->name, i+1 ); ! 279: viceversa(q); ! 280: } ! 281: } ! 282: } ! 283: } ! 284: ! 285: if( (q->decflag&(LDI|LIB|LUV|LST)) && r.l.decflag==LUV ){ ! 286: if( chktype( &r.l.type, &q->symty.t, q->fno ) ){ ! 287: #ifndef FLEXNAMES ! 288: printf( "%.8s value used inconsistently", q->name ); ! 289: #else ! 290: printf( "%s value used inconsistently", q->name ); ! 291: #endif ! 292: viceversa(q); ! 293: } ! 294: } ! 295: ! 296: /* check for multiple declaration */ ! 297: ! 298: if( (q->decflag&(LDI|LST)) && (r.l.decflag&(LDI|LIB|LST)) ){ ! 299: #ifndef FLEXNAMES ! 300: printf( "%.8s multiply declared", q->name ); ! 301: #else ! 302: printf( "%s multiply declared", q->name ); ! 303: #endif ! 304: viceversa(q); ! 305: } ! 306: ! 307: /* do a bit of checking of definitions and uses... */ ! 308: ! 309: if( (q->decflag & (LDI|LIB|LDX|LDC|LUM|LST)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){ ! 310: #ifndef FLEXNAMES ! 311: printf( "%.8s value declared inconsistently", q->name ); ! 312: #else ! 313: printf( "%s value declared inconsistently", q->name ); ! 314: #endif ! 315: viceversa(q); ! 316: } ! 317: ! 318: /* better not call functions which are declared to be structure or union returning */ ! 319: ! 320: if( (q->decflag & (LDI|LIB|LDX|LDC|LST)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){ ! 321: /* only matters if the function returns union or structure */ ! 322: TWORD ty; ! 323: ty = q->symty.t.aty; ! 324: if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){ ! 325: #ifndef FLEXNAMES ! 326: printf( "%.8s function value type must be declared before use", q->name ); ! 327: #else ! 328: printf( "%s function value type must be declared before use", q->name ); ! 329: #endif ! 330: viceversa(q); ! 331: } ! 332: } ! 333: ! 334: if( pflag && q->decflag==LDX && r.l.decflag == LUM && !ISFTN(q->symty.t.aty) ){ ! 335: /* make the external declaration go away */ ! 336: /* in effect, it was used without being defined */ ! 337: } ! 338: } ! 339: ! 340: viceversa(q) STAB *q; { ! 341: /* print out file comparison */ ! 342: #ifndef FLEXNAMES ! 343: printf( " %.*s(%d) :: %.*s(%d)\n", ! 344: LFNM, fnm[q->fno], q->fline, ! 345: LFNM, fnm[cfno], r.l.fline ); ! 346: #else ! 347: printf( " %s(%d) :: %s(%d)\n", ! 348: fnm[q->fno], q->fline, ! 349: fnm[cfno], r.l.fline ); ! 350: #endif ! 351: } ! 352: ! 353: /* messages for defintion/use */ ! 354: char * ! 355: mess[2][2] ={ ! 356: "", ! 357: #ifndef FLEXNAMES ! 358: "%.8s used( %.*s(%d) ), but not defined\n", ! 359: "%.8s defined( %.*s(%d) ), but never used\n", ! 360: "%.8s declared( %.*s(%d) ), but never used or defined\n" ! 361: #else ! 362: "%s used( %s(%d) ), but not defined\n", ! 363: "%s defined( %s(%d) ), but never used\n", ! 364: "%s declared( %s(%d) ), but never used or defined\n" ! 365: #endif ! 366: }; ! 367: ! 368: lastone(q) STAB *q; { ! 369: ! 370: register nu, nd, uses; ! 371: ! 372: if( ddddd ) pst(q); ! 373: ! 374: nu = nd = 0; ! 375: uses = q->use; ! 376: ! 377: if( !(uses&USED) && q->decflag != LIB ) { ! 378: #ifndef FLEXNAMES ! 379: if( strncmp(q->name,"main",7) ) ! 380: #else ! 381: if (strcmp(q->name, "main")) ! 382: #endif ! 383: nu = 1; ! 384: } ! 385: ! 386: if( !ISFTN(q->symty.t.aty) ){ ! 387: switch( q->decflag ){ ! 388: ! 389: case LIB: ! 390: nu = nd = 0; /* don't complain about uses on libraries */ ! 391: break; ! 392: case LDX: ! 393: if( !xflag ) break; ! 394: case LUV: ! 395: case LUE: ! 396: /* 01/04/80 */ case LUV | LUE: ! 397: case LUM: ! 398: nd = 1; ! 399: } ! 400: } ! 401: if( uflag && ( nu || nd ) ) ! 402: #ifndef FLEXNAMES ! 403: printf( mess[nu][nd], q->name, LFNM, fnm[q->fno], q->fline ); ! 404: #else ! 405: printf( mess[nu][nd], q->name, fnm[q->fno], q->fline ); ! 406: #endif ! 407: ! 408: if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){ ! 409: /* if functions is static, then print the file name too */ ! 410: if( q->decflag & LST ) ! 411: #ifndef FLEXNAMES ! 412: printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline ); ! 413: #else ! 414: printf( "%s(%d):", fnm[q->fno], q->fline ); ! 415: #endif ! 416: #ifndef FLEXNAMES ! 417: printf( "%.*s returns value which is %s ignored\n", ! 418: LCHNM, q->name, uses&VUSED ? "sometimes" : "always" ); ! 419: #else ! 420: printf( "%s returns value which is %s ignored\n", ! 421: q->name, uses&VUSED ? "sometimes" : "always" ); ! 422: #endif ! 423: } ! 424: ! 425: if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB|LST)) ){ ! 426: if( q->decflag & LST ) ! 427: #ifndef FLEXNAMES ! 428: printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline ); ! 429: #else ! 430: printf( "%s(%d):", fnm[q->fno], q->fline ); ! 431: #endif ! 432: #ifndef FLEXNAMES ! 433: printf( "%.*s value is used, but none returned\n", ! 434: LCHNM, q->name); ! 435: #else ! 436: printf( "%s value is used, but none returned\n", q->name); ! 437: #endif ! 438: } ! 439: } ! 440: ! 441: cleanup(){ /* call lastone and die gracefully */ ! 442: STAB *q; ! 443: for( q=stab; q< &stab[NSZ]; ++q ){ ! 444: if( q->decflag ) lastone(q); ! 445: } ! 446: exit(0); ! 447: } ! 448: ! 449: setuse(q) STAB *q; { /* check new type to ensure that it is used */ ! 450: ! 451: if( !q->decflag ){ /* new one */ ! 452: q->decflag = r.l.decflag; ! 453: q->symty.t = r.l.type; ! 454: if( r.l.nargs < 0 ){ ! 455: q->nargs = ~r.l.nargs; ! 456: q->use = VARARGS; ! 457: } ! 458: else { ! 459: q->nargs = r.l.nargs; ! 460: q->use = 0; ! 461: } ! 462: q->fline = r.l.fline; ! 463: q->fno = cfno; ! 464: if( q->nargs ){ ! 465: int i; ! 466: STYPE *qq; ! 467: for( i=0,qq= &q->symty; i<q->nargs; ++i,qq=qq->next ){ ! 468: qq->next = tget(); ! 469: qq->next->t = atyp[i]; ! 470: } ! 471: } ! 472: } ! 473: ! 474: switch( r.l.decflag ){ ! 475: ! 476: case LRV: ! 477: q->use |= RVAL; ! 478: return; ! 479: case LUV: ! 480: q->use |= VUSED+USED; ! 481: return; ! 482: case LUE: ! 483: q->use |= EUSED+USED; ! 484: return; ! 485: /* 01/04/80 */ case LUV | LUE: ! 486: case LUM: ! 487: q->use |= USED; ! 488: return; ! 489: ! 490: } ! 491: } ! 492: ! 493: chktype( pt1, pt2, fno ) register ATYPE *pt1, *pt2; { ! 494: TWORD t; ! 495: ! 496: /* check the two type words to see if they are compatible */ ! 497: /* for the moment, enums are turned into ints, and should be checked as such */ ! 498: if( pt1->aty == ENUMTY ) pt1->aty = INT; ! 499: if( pt2->aty == ENUMTY ) pt2->aty = INT; ! 500: ! 501: if( (t=BTYPE(pt1->aty)==STRTY) || t==UNIONTY ){ ! 502: if( pt1->aty != pt2->aty || pt1->extra1 != pt2->extra1 ) ! 503: return 1; ! 504: /* if -z then don't worry about undefined structures, ! 505: as long as the names match */ ! 506: if( zflag && (pt1->extra == 0 || pt2->extra == 0) ) return 0; ! 507: /* if -p and pt1 is "too big" and ! 508: ** pt1 came from a llib-l file, we can't pass judgment on it. ! 509: */ ! 510: if ( pflag && pt1->extra > pt2->extra && ! 511: strncmp(fnm[fno], "llib-l", 6) == 0) ! 512: return 0; ! 513: return pt1->extra != pt2->extra; ! 514: } ! 515: ! 516: if( pt2->extra ){ /* constant passed in */ ! 517: if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 ); ! 518: else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 ); ! 519: } ! 520: else if( pt1->extra ){ /* for symmetry */ ! 521: if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 ); ! 522: else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 ); ! 523: } ! 524: ! 525: return( pt1->aty != pt2->aty ); ! 526: } ! 527: ! 528: struct tb { int m; char * nm }; ! 529: ! 530: struct tb dfs[] = { ! 531: LDI, "LDI", ! 532: LIB, "LIB", ! 533: LDC, "LDC", ! 534: LDX, "LDX", ! 535: LRV, "LRV", ! 536: LUV, "LUV", ! 537: LUE, "LUE", ! 538: LUM, "LUM", ! 539: LST, "LST", ! 540: LFN, "LFN", ! 541: 0, "" }; ! 542: ! 543: struct tb us[] = { ! 544: USED, "USED", ! 545: VUSED, "VUSED", ! 546: EUSED, "EUSED", ! 547: RVAL, "RVAL", ! 548: VARARGS, "VARARGS", ! 549: 0, "" }; ! 550: ! 551: ptb( v, tp ) struct tb *tp; { ! 552: /* print a value from the table */ ! 553: int flag; ! 554: flag = 0; ! 555: for( ; tp->m; ++tp ){ ! 556: if( v&tp->m ){ ! 557: if( flag++ ) putchar( '|' ); ! 558: printf( "%s", tp->nm ); ! 559: } ! 560: } ! 561: } ! 562: ! 563: pst( q ) STAB *q; { ! 564: /* give a debugging output for q */ ! 565: ! 566: #ifndef FLEXNAMES ! 567: printf( "%.8s (", q->name ); ! 568: #else ! 569: printf( "%s (", q->name ); ! 570: #endif ! 571: ptb( q->decflag, dfs ); ! 572: printf( "), use= " ); ! 573: ptb( q->use, us ); ! 574: printf( ", line %d, nargs=%d\n", q->fline, q->nargs ); ! 575: } ! 576: ! 577: pfile() { ! 578: /* print the input file in readable form */ ! 579: while( lread( LDI|LIB|LDC|LDX|LRV|LUV|LUE|LUM|LST|LFN ) ) ! 580: prc(); ! 581: } ! 582: ! 583: prc() { ! 584: /* print out 'r' for debugging */ ! 585: register i, j, k; ! 586: ! 587: printf( "decflag\t" ); ! 588: ptb( r.l.decflag, dfs ); ! 589: putchar( '\n' ); ! 590: if( r.l.decflag & LFN ){ ! 591: #ifdef FLEXNAMES ! 592: printf( "fn\t\t%s\n", r.f.fn ); ! 593: #else ! 594: printf( "fn\t%\t.*s\n", LFNM, r.f.fn ); ! 595: #endif ! 596: } ! 597: else { ! 598: #ifdef FLEXNAMES ! 599: printf( "name\t%s\n", r.l.name ); ! 600: #else ! 601: printf( "name\t%.*s\n", LCHNM, r.l.name ); ! 602: #endif ! 603: printf( "nargs\t%d\n", r.l.nargs ); ! 604: printf( "fline\t%d\n", r.l.fline ); ! 605: printf( "type.aty\t0%o (", r.l.type.aty ); ! 606: pty( r.l.type.aty, r.l.name ); ! 607: printf( ")\ntype.extra\t%d\n", r.l.type.extra ); ! 608: j = r.l.type.extra1; ! 609: printf( "type.extra1\t0x%x (%d,%d)\n", ! 610: j, j & X_NONAME ? 1 : 0, j & ~X_NONAME ); ! 611: k = r.l.nargs; ! 612: if( k < 0 ) k = ~k; ! 613: for( i = 0; i < k; i++ ){ ! 614: printf( "atyp[%d].aty\t0%o (", i, atyp[i].aty ); ! 615: pty( atyp[i].aty, "" ); ! 616: printf( ")\natyp[%d].extra\t%d\n", i, atyp[i].extra); ! 617: j = atyp[i].extra1; ! 618: printf( "atyp[%d].extra1\t0x%x (%d,%d)\n", ! 619: i, j, j & X_NONAME ? 1 : 0, j & ~X_NONAME ); ! 620: } ! 621: } ! 622: putchar( '\n' ); ! 623: } ! 624: ! 625: pty( t, name ) TWORD t; { ! 626: static char * tnames[] = { ! 627: "void", "farg", "char", "short", ! 628: "int", "long", "float", "double", ! 629: "struct xxx", "union %s", "enum", "moety", ! 630: "unsigned char", "unsigned short", "unsigned", "unsigned long", ! 631: "?", "?" ! 632: }; ! 633: ! 634: printf( "%s ", tnames[BTYPE(t)] ); ! 635: pty1( t, name, (8 * sizeof (int) - BTSHIFT) / TSHIFT ); ! 636: } ! 637: ! 638: pty1( t, name, level ) TWORD t; { ! 639: register TWORD u; ! 640: ! 641: if( level < 0 ){ ! 642: printf( "%s", name ); ! 643: return; ! 644: } ! 645: u = t >> level * TSHIFT; ! 646: if( ISPTR(u) ){ ! 647: printf( "*" ); ! 648: pty1( t, name, level-1 ); ! 649: } ! 650: else if( ISFTN(u) ){ ! 651: if( level > 0 && ISPTR(u << TSHIFT) ){ ! 652: printf( "(" ); ! 653: pty1( t, name, level-1 ); ! 654: printf( ")()" ); ! 655: } ! 656: else { ! 657: pty1( t, name, level-1 ); ! 658: printf( "()" ); ! 659: } ! 660: } ! 661: else if( ISARY(u) ){ ! 662: if( level > 0 && ISPTR(u << TSHIFT) ){ ! 663: printf( "(" ); ! 664: pty1( t, name, level-1 ); ! 665: printf( ")[]" ); ! 666: } ! 667: else { ! 668: pty1( t, name, level-1 ); ! 669: printf( "[]" ); ! 670: } ! 671: } ! 672: else { ! 673: pty1( t, name, level-1 ); ! 674: } ! 675: } ! 676: ! 677: #ifdef FLEXNAMES ! 678: char * ! 679: getstr(doport) ! 680: { ! 681: char buf[BUFSIZ]; ! 682: register char *cp = buf; ! 683: register int c; ! 684: ! 685: if (feof(stdin) || ferror(stdin)) ! 686: return(""); ! 687: while ((c = getchar()) > 0) ! 688: *cp++ = c; ! 689: if (c < 0) { ! 690: error("intermediate file format error (getstr)"); ! 691: exit(1); ! 692: } ! 693: *cp++ = 0; ! 694: if (doport) ! 695: portify(buf); ! 696: return (hash(buf)); ! 697: } ! 698: ! 699: #define NSAVETAB 4096 ! 700: char *savetab; ! 701: int saveleft; ! 702: ! 703: char * ! 704: savestr(cp) ! 705: register char *cp; ! 706: { ! 707: register int len; ! 708: ! 709: len = strlen(cp) + 1; ! 710: if (len > saveleft) { ! 711: saveleft = NSAVETAB; ! 712: if (len > saveleft) ! 713: saveleft = len; ! 714: savetab = (char *)malloc(saveleft); ! 715: if (savetab == 0) { ! 716: error("ran out of memory (savestr)"); ! 717: exit(1); ! 718: } ! 719: } ! 720: strncpy(savetab, cp, len); ! 721: cp = savetab; ! 722: savetab += len; ! 723: saveleft -= len; ! 724: return (cp); ! 725: } ! 726: ! 727: /* ! 728: * The definition for the segmented hash tables. ! 729: */ ! 730: #define MAXHASH 20 ! 731: #define HASHINC 1013 ! 732: struct ht { ! 733: char **ht_low; ! 734: char **ht_high; ! 735: int ht_used; ! 736: } htab[MAXHASH]; ! 737: ! 738: char * ! 739: hash(s) ! 740: char *s; ! 741: { ! 742: register char **h; ! 743: register i; ! 744: register char *cp; ! 745: struct ht *htp; ! 746: int sh; ! 747: ! 748: sh = hashstr(s) % HASHINC; ! 749: cp = s; ! 750: /* ! 751: * There are as many as MAXHASH active ! 752: * hash tables at any given point in time. ! 753: * The search starts with the first table ! 754: * and continues through the active tables ! 755: * as necessary. ! 756: */ ! 757: for (htp = htab; htp < &htab[MAXHASH]; htp++) { ! 758: if (htp->ht_low == 0) { ! 759: register char **hp = ! 760: (char **) calloc(sizeof (char **), HASHINC); ! 761: if (hp == 0) { ! 762: error("ran out of memory (hash)"); ! 763: exit(1); ! 764: } ! 765: htp->ht_low = hp; ! 766: htp->ht_high = htp->ht_low + HASHINC; ! 767: } ! 768: h = htp->ht_low + sh; ! 769: /* ! 770: * quadratic rehash increment ! 771: * starts at 1 and incremented ! 772: * by two each rehash. ! 773: */ ! 774: i = 1; ! 775: do { ! 776: if (*h == 0) { ! 777: if (htp->ht_used > (HASHINC * 3)/4) ! 778: break; ! 779: htp->ht_used++; ! 780: *h = savestr(cp); ! 781: return (*h); ! 782: } ! 783: if (**h == *cp && strcmp(*h, cp) == 0) ! 784: return (*h); ! 785: h += i; ! 786: i += 2; ! 787: if (h >= htp->ht_high) ! 788: h -= HASHINC; ! 789: } while (i < HASHINC); ! 790: } ! 791: error("ran out of hash tables"); ! 792: exit(1); ! 793: } ! 794: char *tstrbuf[1]; ! 795: #endif ! 796: ! 797: #include "ctype.h" ! 798: ! 799: portify(cp) ! 800: register char * cp; ! 801: { ! 802: register int i; ! 803: ! 804: if (!pflag) ! 805: return; ! 806: for (i = 0; i < 6; ++i) ! 807: if (cp[i] == '\0') ! 808: return; ! 809: else if (isascii(cp[i]) && isupper(cp[i])) ! 810: cp[i] = tolower(cp[i]); ! 811: cp[i] = '\0'; ! 812: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.