|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)lpass2.c 1.9 (Berkeley) 12/11/87";
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.