|
|
1.1 root 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.