typedef struct { TWORD aty
; int extra
; } atype
;
*pd
, /* pointer to line having definition */
*pc
, /* pointer to current line read */
*p3
; /* used for swapping pc and pd */
main( argc
, argv
) char *argv
[]; {
/* first argument is - options */
if( argc
>=2 && argv
[1][0] == '-' ){
for( p
=argv
[1]; *p
; ++p
){
/* main loop: read a line;
if same as last line, check compatibility
if not same as last line, becomes df.
if( steq(pc
->name
, pd
->name
) ) chkcompat();
lread(){ /* read a line into pc */
n
= pc
->nargs
= rdin10();
while( getchar() != '\n' ) ; /* VOID */
while( (c
=getchar()) != '\t' ){
if( c
<= 0 ) error( "unexpected EOF" );
else if( c
<'0' || c
>'9' ) {
error("rotten digit: %o\n", c
);
while( (c
=getchar()) != '\t' && c
!= '<' ){
if( c
<= 0 ) error( "unexpected EOF" );
else if( c
<'0' || c
>'7' ) {
error("rotten digit: %o\n", c
);
val
= (val
<<3) + c
- '0';
if( c
== '<' ) p
->extra
= rdin10();
while( (c
=getchar()) != '\t' ){
if( c
== '\n' ) error( "rotten name\n" );
fprintf( stderr
, "pass 2 error: " );
steq(p
,q
) char *p
,*q
; { /* check that the p and q names are the same */
/* are the types, etc. in pc and pd compatible */
if( pd
->decflag
& (LDI
|LIB
|LUV
|LUE
) ){
if( pc
->decflag
& (LUV
|LIB
|LUE
) ){
if( pd
->nargs
!= pc
->nargs
){
printf( "%.7s: variable # of args.", pd
->name
);
if( pc
->nargs
> pd
->nargs
) pc
->nargs
= pd
->nargs
;
if( !(pd
->decflag
& (LDI
|LIB
) ) ) {
for( i
=0; i
<pc
->nargs
; ++i
){
if( chktype(&pd
->atyp
[i
], &pc
->atyp
[i
]) ){
printf( "%.7s, arg. %d used inconsistently",
if( (pd
->decflag
&(LDI
|LIB
|LUV
)) && pc
->decflag
==LUV
){
if( chktype( &pc
->type
, &pd
->type
) ){
printf( "%.7s value used inconsistently", pd
->name
);
/* check for multiple declaration */
if( (pd
->decflag
&LDI
) && (pc
->decflag
&(LDI
|LIB
)) ){
printf( "%.7s multiply declared", pd
->name
);
/* do a bit of checking of definitions and uses... */
if( (pd
->decflag
& (LDI
|LIB
|LDX
|LDC
)) && (pc
->decflag
& (LDX
|LDC
)) && pd
->type
.aty
!= pc
->type
.aty
){
printf( "%.7s value declared inconsistently", pd
->name
);
/* better not call functions which are declared to be structure or union returning */
if( (pd
->decflag
& (LDI
|LIB
|LDX
|LDC
)) && (pc
->decflag
& LUE
) && pd
->type
.aty
!= pc
->type
.aty
){
/* only matters if the function returns union or structure */
if( ISFTN(ty
) && ((ty
= DECREF(ty
))==STRTY
|| ty
==UNIONTY
) ){
printf( "%.7s function value type must be declared before use", pd
->name
);
if( pflag
&& pd
->decflag
==LDX
&& pc
->decflag
== LUM
&& !ISFTN(pd
->type
.aty
) ){
/* make the external declaration go away */
/* in effect, it was used without being defined */
/* print out file comparison */
printf( " %s(%d) :: %s(%d)\n", pd
->file
, pd
->fline
, pc
->file
, pc
->fline
);
/* messages for defintion/use */
"%.7s used( %s(%d) ), but not defined\n",
"%.7s defined( %s(%d) ), but never used\n",
"%.7s declared( %s(%d) ), but never used or defined\n"
/* called when pc and pd are at last different */
if( !(uses
&USED
) && pd
->decflag
!= LIB
) {
if( !steq(pd
->name
,"main") )
if( !ISFTN(pd
->type
.aty
) ){
nu
= nd
= 0; /* don't complain about uses on libraries */
if( uflag
&& ( nu
|| nd
) ) printf( mess
[nu
][nd
], pd
->name
, pd
->file
, pd
->fline
);
if( (uses
&(RVAL
+EUSED
)) == (RVAL
+EUSED
) ){
printf( "%.7s returns value which is %s ignored\n", pd
->name
,
uses
&VUSED
? "sometimes" : "always" );
if( (uses
&(RVAL
+VUSED
)) == (VUSED
) && (pd
->decflag
&(LDI
|LIB
)) ){
printf( "%.7s value is used, but none returned\n", pd
->name
);
/* clean up pc, in preparation for the next thing */
cleanup(){ /* call lastone and die gracefully */
setuse(){ /* check new type to ensure that it is used */
chktype( pt1
, pt2
) register atype
*pt1
, *pt2
; {
/* check the two type words to see if they are compatible */
/* for the moment, enums are turned into ints, and should be checked as such */
if( pt1
->aty
== ENUMTY
) pt1
->aty
= INT
;
if( pt2
->aty
== ENUMTY
) pt2
->aty
= INT
;
if( pt2
->extra
){ /* constant passed in */
if( pt1
->aty
== UNSIGNED
&& pt2
->aty
== INT
) return( 0 );
else if( pt1
->aty
== ULONG
&& pt2
->aty
== LONG
) return( 0 );
else if( pt1
->extra
){ /* for symmetry */
if( pt2
->aty
== UNSIGNED
&& pt1
->aty
== INT
) return( 0 );
else if( pt2
->aty
== ULONG
&& pt1
->aty
== LONG
) return( 0 );
return( pt1
->aty
!= pt2
->aty
);