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

Defined functions

chkcompat defined in line 243; used 1 times
chktype defined in line 491; used 2 times
cleanup defined in line 439; used 1 times
error defined in line 194; used 9 times
find defined in line 206; used 2 times
getstr defined in line 670; used 3 times
hash defined in line 728; used 2 times
lastone defined in line 366; used 1 times
lread defined in line 140; used 2 times
main defined in line 70; never used
mloop defined in line 129; used 3 times
pfile defined in line 569; used 1 times
prc defined in line 575; used 1 times
pst defined in line 555; used 1 times
ptb defined in line 543; used 3 times
pty defined in line 617; used 2 times
pty1 defined in line 630; used 7 times
savestr defined in line 693; used 1 times
setfno defined in line 166; used 1 times
setuse defined in line 447; used 2 times
tget defined in line 235; used 2 times
viceversa defined in line 338; used 6 times

Defined variables

Pflag defined in line 66; used 3 times
atyp defined in line 56; used 7 times
cfno defined in line 68; used 8 times
ddddd defined in line 64; used 2 times
dfs defined in line 522; used 2 times
ffree defined in line 54; used 5 times
fnm defined in line 46; used 16 times
hflag defined in line 60; used 1 times
  • in line 81
htab defined in line 726; used 2 times
  • in line 747(2)
mess defined in line 353; used 2 times
pflag defined in line 61; used 2 times
r defined in line 58; used 52 times
saveleft defined in line 691; used 6 times
savetab defined in line 690; 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 53; used 2 times
tstrbuf defined in line 784; never used
uflag defined in line 63; used 2 times
us defined in line 535; used 1 times
xflag defined in line 62; used 2 times
zflag defined in line 65; used 2 times

Defined struct's

ht defined in line 722; used 2 times
  • in line 735(2)
sty defined in line 21; used 1 times
  • in line 20
sym defined in line 23; never used
tb defined in line 520; 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 4 times
HASHINC defined in line 721; used 6 times
MAXHASH defined in line 720; used 2 times
NSAVETAB defined in line 689; 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: 1986-02-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3005
Valid CSS Valid XHTML 1.0 Strict