xref: /original-bsd/old/pcc/lint/lpass2/lpass2.c (revision 0999a820)
1 #ifndef lint
2 static char sccsid[] = "@(#)lpass2.c	1.12	(Berkeley)	05/12/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 (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 }
813