xref: /original-bsd/old/pcc/lint/lpass2/lpass2.c (revision 897d63f2)
1 #ifndef lint
2 static char sccsid[] = "@(#)lpass2.c	1.11	(Berkeley)	02/21/90";
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 (strcmp(r.l.name, q->name) == 0)
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 	switch( q->decflag ){
387 
388 	case LIB:
389 		nu = nd = 0;  /* don't complain about uses on libraries */
390 		break;
391 	case LDX:
392 		if( !xflag ) break;
393 	case LUV:
394 	case LUE:
395 /* 01/04/80 */	case LUV | LUE:
396 	case LUM:
397 		nd = 1;
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, fno ) 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 		/* if -p and pt1 is "too big" and
506 		** pt1 came from a llib-l file, we can't pass judgment on it.
507 		*/
508 		if ( pflag && pt1->extra > pt2->extra &&
509 			strncmp(fnm[fno], "llib-l", 6) == 0)
510 				return 0;
511 		return pt1->extra != pt2->extra;
512 		}
513 
514 	if( pt2->extra ){ /* constant passed in */
515 		if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
516 		else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
517 		}
518 	else if( pt1->extra ){ /* for symmetry */
519 		if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
520 		else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
521 		}
522 
523 	return( pt1->aty != pt2->aty );
524 	}
525 
526 struct tb { int m; char *nm; };
527 
528 struct tb dfs[] = {
529 	LDI, "LDI",
530 	LIB, "LIB",
531 	LDC, "LDC",
532 	LDX, "LDX",
533 	LRV, "LRV",
534 	LUV, "LUV",
535 	LUE, "LUE",
536 	LUM, "LUM",
537 	LST, "LST",
538 	LFN, "LFN",
539 	0, "" };
540 
541 struct tb us[] = {
542 	USED, "USED",
543 	VUSED, "VUSED",
544 	EUSED, "EUSED",
545 	RVAL, "RVAL",
546 	VARARGS, "VARARGS",
547 	0, "" };
548 
549 ptb( v, tp ) struct tb *tp; {
550 	/* print a value from the table */
551 	int flag;
552 	flag = 0;
553 	for( ; tp->m; ++tp ){
554 		if( v&tp->m ){
555 			if( flag++ ) putchar( '|' );
556 			printf( "%s", tp->nm );
557 			}
558 		}
559 	}
560 
561 pst( q ) STAB *q; {
562 	/* give a debugging output for q */
563 
564 #ifndef FLEXNAMES
565 	printf( "%.8s (", q->name );
566 #else
567 	printf( "%s (", q->name );
568 #endif
569 	ptb( q->decflag, dfs );
570 	printf( "), use= " );
571 	ptb( q->use, us );
572 	printf( ", line %d, nargs=%d\n", q->fline, q->nargs );
573 	}
574 
575 pfile() {
576 	/* print the input file in readable form */
577 	while( lread( LDI|LIB|LDC|LDX|LRV|LUV|LUE|LUM|LST|LFN ) )
578 		prc();
579 	}
580 
581 prc() {
582 	/* print out 'r' for debugging */
583 	register i, j, k;
584 
585 	printf( "decflag\t" );
586 	ptb( r.l.decflag, dfs );
587 	putchar( '\n' );
588 	if( r.l.decflag & LFN ){
589 #ifdef FLEXNAMES
590 		printf( "fn\t\t%s\n", r.f.fn );
591 #else
592 		printf( "fn\t%\t.*s\n", LFNM, r.f.fn );
593 #endif
594 		}
595 	else {
596 #ifdef FLEXNAMES
597 		printf( "name\t%s\n", r.l.name );
598 #else
599 		printf( "name\t%.*s\n", LCHNM, r.l.name );
600 #endif
601 		printf( "nargs\t%d\n", r.l.nargs );
602 		printf( "fline\t%d\n", r.l.fline );
603 		printf( "type.aty\t0%o (", r.l.type.aty );
604 		pty( r.l.type.aty, r.l.name );
605 		printf( ")\ntype.extra\t%d\n", r.l.type.extra );
606 		j = r.l.type.extra1;
607 		printf( "type.extra1\t0x%x (%d,%d)\n",
608 			j, j & X_NONAME ? 1 : 0, j & ~X_NONAME );
609 		k = r.l.nargs;
610 		if( k < 0 ) k = ~k;
611 		for( i = 0; i < k; i++ ){
612 			printf( "atyp[%d].aty\t0%o (", i, atyp[i].aty );
613 			pty( atyp[i].aty, "" );
614 			printf( ")\natyp[%d].extra\t%d\n", i, atyp[i].extra);
615 			j = atyp[i].extra1;
616 			printf( "atyp[%d].extra1\t0x%x (%d,%d)\n",
617 				i, j, j & X_NONAME ? 1 : 0, j & ~X_NONAME );
618 			}
619 		}
620 		putchar( '\n' );
621 	}
622 
623 pty( t, name )  TWORD t; {
624 	static char * tnames[] = {
625 		"void", "farg", "char", "short",
626 		"int", "long", "float", "double",
627 		"struct xxx", "union %s", "enum", "moety",
628 		"unsigned char", "unsigned short", "unsigned", "unsigned long",
629 		"?", "?"
630 		};
631 
632 	printf( "%s ", tnames[BTYPE(t)] );
633 	pty1( t, name, (8 * sizeof (int) - BTSHIFT) / TSHIFT );
634 	}
635 
636 pty1( t, name, level ) TWORD t; {
637 	register TWORD u;
638 
639 	if( level < 0 ){
640 		printf( "%s", name );
641 		return;
642 		}
643 	u = t >> level * TSHIFT;
644 	if( ISPTR(u) ){
645 		printf( "*" );
646 		pty1( t, name, level-1 );
647 		}
648 	else if( ISFTN(u) ){
649 		if( level > 0 && ISPTR(u << TSHIFT) ){
650 			printf( "(" );
651 			pty1( t, name, level-1 );
652 			printf( ")()" );
653 			}
654 		else {
655 			pty1( t, name, level-1 );
656 			printf( "()" );
657 			}
658 		}
659 	else if( ISARY(u) ){
660 		if( level > 0 && ISPTR(u << TSHIFT) ){
661 			printf( "(" );
662 			pty1( t, name, level-1 );
663 			printf( ")[]" );
664 			}
665 		else {
666 			pty1( t, name, level-1 );
667 			printf( "[]" );
668 			}
669 		}
670 	else {
671 		pty1( t, name, level-1 );
672 		}
673 	}
674 
675 #ifdef FLEXNAMES
676 char *
677 getstr(doport)
678 {
679 	char buf[BUFSIZ];
680 	register char *cp = buf;
681 	register int c;
682 
683 	if (feof(stdin) || ferror(stdin))
684 		return("");
685 	while ((c = getchar()) > 0)
686 		*cp++ = c;
687 	if (c < 0) {
688 		error("intermediate file format error (getstr)");
689 		exit(1);
690 	}
691 	*cp++ = 0;
692 	if (doport)
693 		portify(buf);
694 	return (hash(buf));
695 }
696 
697 #define	NSAVETAB	4096
698 char	*savetab;
699 int	saveleft;
700 
701 char *
702 savestr(cp)
703 	register char *cp;
704 {
705 	register int len;
706 
707 	len = strlen(cp) + 1;
708 	if (len > saveleft) {
709 		saveleft = NSAVETAB;
710 		if (len > saveleft)
711 			saveleft = len;
712 		savetab = (char *)malloc(saveleft);
713 		if (savetab == 0) {
714 			error("ran out of memory (savestr)");
715 			exit(1);
716 		}
717 	}
718 	strncpy(savetab, cp, len);
719 	cp = savetab;
720 	savetab += len;
721 	saveleft -= len;
722 	return (cp);
723 }
724 
725 /*
726  * The definition for the segmented hash tables.
727  */
728 #define	MAXHASH	20
729 #define	HASHINC	1013
730 struct ht {
731 	char	**ht_low;
732 	char	**ht_high;
733 	int	ht_used;
734 } htab[MAXHASH];
735 
736 char *
737 hash(s)
738 	char *s;
739 {
740 	register char **h;
741 	register i;
742 	register char *cp;
743 	struct ht *htp;
744 	int sh;
745 
746 	sh = hashstr(s) % HASHINC;
747 	cp = s;
748 	/*
749 	 * There are as many as MAXHASH active
750 	 * hash tables at any given point in time.
751 	 * The search starts with the first table
752 	 * and continues through the active tables
753 	 * as necessary.
754 	 */
755 	for (htp = htab; htp < &htab[MAXHASH]; htp++) {
756 		if (htp->ht_low == 0) {
757 			register char **hp =
758 			    (char **) calloc(sizeof (char **), HASHINC);
759 			if (hp == 0) {
760 				error("ran out of memory (hash)");
761 				exit(1);
762 			}
763 			htp->ht_low = hp;
764 			htp->ht_high = htp->ht_low + HASHINC;
765 		}
766 		h = htp->ht_low + sh;
767 		/*
768 		 * quadratic rehash increment
769 		 * starts at 1 and incremented
770 		 * by two each rehash.
771 		 */
772 		i = 1;
773 		do {
774 			if (*h == 0) {
775 				if (htp->ht_used > (HASHINC * 3)/4)
776 					break;
777 				htp->ht_used++;
778 				*h = savestr(cp);
779 				return (*h);
780 			}
781 			if (**h == *cp && strcmp(*h, cp) == 0)
782 				return (*h);
783 			h += i;
784 			i += 2;
785 			if (h >= htp->ht_high)
786 				h -= HASHINC;
787 		} while (i < HASHINC);
788 	}
789 	error("ran out of hash tables");
790 	exit(1);
791 }
792 char	*tstrbuf[1];
793 #endif
794 
795 #include "ctype.h"
796 
797 portify(cp)
798 register char *	cp;
799 {
800 	register int	i;
801 
802 	if (!pflag)
803 		return;
804 	for (i = 0; i < 6; ++i)
805 		if (cp[i] == '\0')
806 			return;
807 		else if (isascii(cp[i]) && isupper(cp[i]))
808 			cp[i] = tolower(cp[i]);
809 	cp[i] = '\0';
810 }
811