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