Commit | Line | Data |
---|---|---|
7d3e20bd | 1 | #ifndef lint |
c2383573 | 2 | static char sccsid[] = "@(#)lpass2.c 1.9 (Berkeley) %G%"; |
7d3e20bd RH |
3 | #endif lint |
4 | ||
7184b3eb RC |
5 | # include "macdefs.h" |
6 | # include "manifest.h" | |
7 | # include "lmanifest.h" | |
7d3e20bd RH |
8 | |
9 | # define USED 01 | |
10 | # define VUSED 02 | |
11 | # define EUSED 04 | |
12 | # define RVAL 010 | |
13 | # define VARARGS 0100 | |
14 | ||
66bfb087 | 15 | # define NSZ 4096 |
7d3e20bd | 16 | # define TYSZ 3500 |
6e7568ce | 17 | # define FSZ 500 |
7d3e20bd RH |
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; | |
bbc65794 EW |
65 | int zflag = 0; |
66 | int Pflag = 0; | |
7d3e20bd RH |
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 | ||
bbc65794 EW |
100 | case 'z': |
101 | zflag = 1; | |
102 | break; | |
103 | ||
104 | case 'P': | |
105 | Pflag = 1; | |
106 | break; | |
107 | ||
7d3e20bd RH |
108 | } |
109 | } | |
110 | } | |
111 | ||
112 | if( argc < 2 || !freopen( argv[1], "r", stdin ) ){ | |
113 | error( "cannot open intermediate file" ); | |
114 | exit( 1 ); | |
115 | } | |
bbc65794 EW |
116 | if( Pflag ){ |
117 | pfile(); | |
118 | return( 0 ); | |
119 | } | |
120 | mloop( LDI|LIB|LST ); | |
7d3e20bd RH |
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 | |
8b350387 | 149 | r.f.fn = getstr(0); |
7d3e20bd | 150 | #endif |
bbc65794 | 151 | if( Pflag ) return( 1 ); |
7d3e20bd RH |
152 | setfno( r.f.fn ); |
153 | continue; | |
154 | } | |
155 | #ifdef FLEXNAMES | |
8b350387 KB |
156 | r.l.name = getstr(1); |
157 | #else /* !FLEXNAMES */ | |
158 | portify(r.l.name); | |
159 | #endif /* !FLEXNAMES */ | |
7d3e20bd | 160 | n = r.l.nargs; |
c2383573 | 161 | if( n<0 ) n = ~n; |
bbc65794 EW |
162 | if( n>=NTY ) error( "more than %d args?", n ); |
163 | fread( (char *)atyp, sizeof(ATYPE), n, stdin ); | |
7d3e20bd RH |
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 | |
bbc65794 | 176 | if( !strncmp( s, fnm[i], LFNM ) ) |
7d3e20bd | 177 | #else |
bbc65794 | 178 | if (fnm[i] == s) |
7d3e20bd | 179 | #endif |
bbc65794 | 180 | { |
7d3e20bd RH |
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(){ | |
7d3e20bd RH |
210 | register h=0; |
211 | #ifndef FLEXNAMES | |
bbc65794 | 212 | h = hashstr(r.l.name, LCHNM) % NSZ; |
7d3e20bd | 213 | #else |
bbc65794 | 214 | h = (int)r.l.name % NSZ; |
7d3e20bd RH |
215 | #endif |
216 | { register STAB *p, *q; | |
217 | for( p=q= &stab[h]; q->decflag; ){ | |
7d3e20bd | 218 | #ifndef FLEXNAMES |
bbc65794 | 219 | if( !strncmp( r.l.name, q->name, LCHNM)) |
7d3e20bd | 220 | #else |
bbc65794 | 221 | if (r.l.name == q->name) |
7d3e20bd | 222 | #endif |
bbc65794 EW |
223 | if( ((q->decflag|r.l.decflag)&LST)==0 || q->fno==cfno ) |
224 | return(q); | |
7d3e20bd RH |
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 | ||
bbc65794 | 254 | if( q->decflag & (LDI|LIB|LUV|LUE|LST) ){ |
7d3e20bd RH |
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; | |
bbc65794 | 266 | if( !(q->decflag & (LDI|LIB|LST) ) ) { |
7d3e20bd RH |
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){ | |
db74889b | 272 | if( chktype( &qq->t, &atyp[i], q->fno ) ){ |
7d3e20bd RH |
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 | ||
bbc65794 | 285 | if( (q->decflag&(LDI|LIB|LUV|LST)) && r.l.decflag==LUV ){ |
db74889b | 286 | if( chktype( &r.l.type, &q->symty.t, q->fno ) ){ |
7d3e20bd RH |
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 | ||
bbc65794 | 298 | if( (q->decflag&(LDI|LST)) && (r.l.decflag&(LDI|LIB|LST)) ){ |
7d3e20bd RH |
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 | ||
bbc65794 | 309 | if( (q->decflag & (LDI|LIB|LDX|LDC|LUM|LST)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){ |
7d3e20bd RH |
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 | ||
bbc65794 | 320 | if( (q->decflag & (LDI|LIB|LDX|LDC|LST)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){ |
7d3e20bd RH |
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 | } | |
bbc65794 | 401 | if( uflag && ( nu || nd ) ) |
7d3e20bd | 402 | #ifndef FLEXNAMES |
bbc65794 | 403 | printf( mess[nu][nd], q->name, LFNM, fnm[q->fno], q->fline ); |
7d3e20bd | 404 | #else |
bbc65794 | 405 | printf( mess[nu][nd], q->name, fnm[q->fno], q->fline ); |
7d3e20bd RH |
406 | #endif |
407 | ||
408 | if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){ | |
bbc65794 EW |
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 | |
7d3e20bd | 416 | #ifndef FLEXNAMES |
bbc65794 EW |
417 | printf( "%.*s returns value which is %s ignored\n", |
418 | LCHNM, q->name, uses&VUSED ? "sometimes" : "always" ); | |
7d3e20bd | 419 | #else |
bbc65794 EW |
420 | printf( "%s returns value which is %s ignored\n", |
421 | q->name, uses&VUSED ? "sometimes" : "always" ); | |
7d3e20bd | 422 | #endif |
7d3e20bd RH |
423 | } |
424 | ||
bbc65794 EW |
425 | if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LIB|LST)) ){ |
426 | if( q->decflag & LST ) | |
7d3e20bd | 427 | #ifndef FLEXNAMES |
bbc65794 | 428 | printf( "%.*s(%d):", LFNM, fnm[q->fno], q->fline ); |
7d3e20bd | 429 | #else |
bbc65794 EW |
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); | |
7d3e20bd RH |
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 ){ | |
c2383573 | 455 | q->nargs = ~r.l.nargs; |
7d3e20bd RH |
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 | ||
db74889b | 493 | chktype( pt1, pt2, fno ) register ATYPE *pt1, *pt2; { |
7d3e20bd RH |
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 ){ | |
bbc65794 EW |
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; | |
db74889b KB |
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; | |
bbc65794 | 513 | return pt1->extra != pt2->extra; |
7d3e20bd RH |
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 }; | |
bbc65794 EW |
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 | ||
7d3e20bd RH |
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 */ | |
7d3e20bd RH |
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 | ||
bbc65794 EW |
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; | |
c2383573 | 612 | if( k < 0 ) k = ~k; |
bbc65794 EW |
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 | ||
7d3e20bd RH |
677 | #ifdef FLEXNAMES |
678 | char * | |
8b350387 | 679 | getstr(doport) |
7d3e20bd RH |
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) { | |
bbc65794 | 690 | error("intermediate file format error (getstr)"); |
7d3e20bd RH |
691 | exit(1); |
692 | } | |
693 | *cp++ = 0; | |
8b350387 KB |
694 | if (doport) |
695 | portify(buf); | |
7d3e20bd RH |
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) { | |
bbc65794 | 716 | error("ran out of memory (savestr)"); |
7d3e20bd RH |
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 | ||
bbc65794 | 748 | sh = hashstr(s) % HASHINC; |
7d3e20bd RH |
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) { | |
bbc65794 | 762 | error("ran out of memory (hash)"); |
7d3e20bd RH |
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 | } | |
bbc65794 | 791 | error("ran out of hash tables"); |
7d3e20bd RH |
792 | exit(1); |
793 | } | |
794 | char *tstrbuf[1]; | |
795 | #endif | |
8b350387 KB |
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 | } |