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