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

Defined functions

chkcompat defined in line 225; used 1 times
chktype defined in line 455; used 2 times
cleanup defined in line 403; used 1 times
error defined in line 180; used 9 times
find defined in line 188; used 2 times
getstr defined in line 629; used 3 times
hash defined in line 687; used 4 times
lastone defined in line 343; used 1 times
lread defined in line 136; used 2 times
main defined in line 63; never used
mloop defined in line 125; used 3 times
pfile defined in line 533; used 1 times
prc defined in line 539; used 1 times
pst defined in line 519; used 1 times
ptb defined in line 507; used 3 times
pty defined in line 577; used 2 times
pty1 defined in line 590; used 7 times
savestr defined in line 652; used 1 times
setfno defined in line 160; used 1 times
setuse defined in line 411; used 2 times
tget defined in line 217; used 2 times
viceversa defined in line 320; used 6 times

Defined variables

Pflag defined in line 59; used 3 times
atyp defined in line 49; used 7 times
cfno defined in line 61; used 6 times
ddddd defined in line 57; used 2 times
dfs defined in line 486; used 2 times
ffree defined in line 47; used 4 times
fnm defined in line 43; used 8 times
hflag defined in line 53; used 1 times
  • in line 75
htab defined in line 685; used 2 times
  • in line 706(2)
mess defined in line 330; used 1 times
pflag defined in line 54; used 2 times
r defined in line 51; used 50 times
saveleft defined in line 650; used 6 times
savetab defined in line 649; used 5 times
sccsid defined in line 2; never used
stab defined in line 37; used 5 times
tary defined in line 40; used 1 times
tfree defined in line 46; used 2 times
tstrbuf defined in line 743; never used
uflag defined in line 56; used 2 times
us defined in line 499; used 1 times
xflag defined in line 55; used 2 times
zflag defined in line 58; used 2 times

Defined struct's

ht defined in line 681; used 2 times
  • in line 694(2)
sty defined in line 21; used 1 times
  • in line 20
sym defined in line 23; never used
tb defined in line 484; used 6 times

Defined typedef's

STAB defined in line 35; used 11 times
STYPE defined in line 20; used 7 times

Defined macros

EUSED defined in line 11; used 4 times
FSZ defined in line 17; used 3 times
HASHINC defined in line 680; used 6 times
MAXHASH defined in line 679; used 2 times
NSAVETAB defined in line 648; used 1 times
NSZ defined in line 15; used 5 times
NTY defined in line 18; used 2 times
RVAL defined in line 12; used 5 times
TYSZ defined in line 16; used 2 times
USED defined in line 9; used 5 times
VARARGS defined in line 13; used 4 times
VUSED defined in line 10; used 6 times
Last modified: 1991-08-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5033
Valid CSS Valid XHTML 1.0 Strict