1: # include "lmanifest"
   2: # include "manifest"
   3: 
   4: # define USED 01
   5: # define VUSED 02
   6: # define EUSED 04
   7: # define RVAL 010
   8: # define VARARGS 0100
   9: 
  10: typedef struct { TWORD aty; int extra; } atype;
  11: 
  12: struct line {
  13:     char name[8];
  14:     int decflag;
  15:     atype type;
  16:     int nargs;
  17:     atype atyp[50];
  18:     int fline;
  19:     char file[100];
  20:     }
  21: 
  22:     l1,
  23:     l2,
  24:     *pd,    /* pointer to line having definition */
  25:     *pc,    /* pointer to current line read */
  26:     *p3;    /* used for swapping pc and pd */
  27: 
  28: int uses = USED;
  29: int hflag = 0;
  30: int pflag = 0;
  31: int xflag = 0;
  32: int uflag = 1;
  33: 
  34: 
  35: main( argc, argv ) char *argv[]; {
  36: 
  37:     register char *p;
  38: 
  39:     /* first argument is - options */
  40: 
  41:     if( argc>=2 && argv[1][0] == '-' ){
  42:         for( p=argv[1]; *p; ++p ){
  43:             switch( *p ){
  44: 
  45:             case 'h':
  46:                 hflag = 1;
  47:                 break;
  48: 
  49:             case 'p':
  50:                 pflag = 1;
  51:                 break;
  52: 
  53:             case 'x':
  54:                 xflag = 1;
  55:                 break;
  56: 
  57:             case 'u':
  58:                 uflag = 0;
  59:                 break;
  60: 
  61:                 }
  62:             }
  63:         }
  64: 
  65: 
  66: 
  67:     pd = &l1;
  68:     pc = &l2;
  69:     pd->name[0] = '\0' ;
  70:     pd->fline = 0;
  71:     pd->file[0] = '\0';
  72:     pd->decflag = LDI;
  73: 
  74:     /* main loop: read a line;
  75: 		if same as last line, check compatibility
  76: 		if not same as last line, becomes df.
  77: 		*/
  78: 
  79:     for(;;){
  80:         lread();
  81:         if( steq(pc->name, pd->name) ) chkcompat();
  82:         else {
  83:             lastone();
  84:             setuse();
  85:             p3=pc;
  86:             pc = pd;
  87:             pd = p3;
  88:             }
  89:         }
  90: 
  91:     }
  92: 
  93: lread(){ /* read a line into pc */
  94: 
  95:     register i, n;
  96: 
  97:     getnam( pc->name );
  98: 
  99:     pc->decflag = rdin10();
 100:     rdinty( &pc->type );
 101:     n = pc->nargs = rdin10();
 102:     if( n<0 ) n = -n;
 103: 
 104:     for( i=0; i<n; ++i ){
 105:         rdinty( &pc->atyp[i] );
 106:         }
 107: 
 108:     getnam( pc->file );
 109:     pc->fline = rdin10();
 110: 
 111:     while( getchar() != '\n' ) ; /* VOID */
 112:     }
 113: 
 114: rdin10(){
 115:     register val, c, s;
 116: 
 117:     val = 0;
 118:     s = 1;
 119: 
 120:     while( (c=getchar()) != '\t' ){
 121:         if( c <= 0 ) error( "unexpected EOF" );
 122:         else if( c == '-' ) {
 123:             s = -1;
 124:             continue;
 125:             }
 126:         else if( c<'0' || c>'9' ) {
 127:             error("rotten digit: %o\n", c );
 128:             }
 129:         val = val*10 + c - '0';
 130:         }
 131:     return( val*s );
 132:     }
 133: 
 134: rdinty( p ) atype *p; {
 135:     register val, c, s;
 136: 
 137:     val = 0;
 138:     s = 1;
 139: 
 140:     while( (c=getchar()) != '\t' && c!= '<' ){
 141:         if( c <= 0 ) error( "unexpected EOF" );
 142:         else if( c == '-' ) {
 143:             s = -1;
 144:             continue;
 145:             }
 146:         else if( c<'0' || c>'7' ) {
 147:             error("rotten digit: %o\n", c );
 148:             }
 149:         val = (val<<3) + c - '0';
 150:         }
 151:     p->aty = val*s;
 152:     if( c == '<' ) p->extra = rdin10();
 153:     else p->extra = 0;
 154:     }
 155: 
 156: getnam(p) char *p; {
 157:     register c;
 158:     while( (c=getchar()) != '\t' ){
 159:         if( c == '\n' ) error( "rotten name\n" );
 160:         if( c <= 0 ) cleanup();
 161:         *p++ = c;
 162:         }
 163:     *p = '\0';
 164:     }
 165: 
 166: /* VARARGS */
 167: error( s, a ) char *s; {
 168: 
 169:     fprintf( stderr, "pass 2 error: " );
 170:     fprintf( stderr, s, a );
 171:     fprintf( stderr, "\n" );
 172:     exit(1);
 173:     }
 174: 
 175: steq(p,q) char *p,*q; { /* check that the p and q names are the same */
 176: 
 177: 
 178:     while( *p == *q ){
 179:         if( *p == 0 ) return(1);
 180:         ++p;
 181:         ++q;
 182:         }
 183: 
 184:     return(0);
 185:     }
 186: 
 187: chkcompat(){
 188:     /* are the types, etc. in pc and pd compatible */
 189:     register int i;
 190: 
 191:     setuse();
 192: 
 193:     /* argument check */
 194: 
 195:     if( pd->decflag & (LDI|LIB|LUV|LUE) ){
 196:         if( pc->decflag & (LUV|LIB|LUE) ){
 197:             if( pd->nargs != pc->nargs ){
 198:                 if( !(uses&VARARGS) ){
 199:                     printf( "%.7s: variable # of args.", pd->name );
 200:                     viceversa();
 201:                     }
 202:                 if( pc->nargs > pd->nargs ) pc->nargs = pd->nargs;
 203:                 if( !(pd->decflag & (LDI|LIB) ) ) {
 204:                     pd->nargs = pc->nargs;
 205:                     uses |= VARARGS;
 206:                     }
 207:                 }
 208:             for( i=0; i<pc->nargs; ++i ){
 209:                 if( chktype(&pd->atyp[i], &pc->atyp[i]) ){
 210:                     printf( "%.7s, arg. %d used inconsistently",
 211:                         pd->name, i+1 );
 212:                     viceversa();
 213:                     }
 214:                 }
 215:             }
 216:         }
 217: 
 218:     if( (pd->decflag&(LDI|LIB|LUV)) && pc->decflag==LUV ){
 219:         if( chktype( &pc->type, &pd->type ) ){
 220:             printf( "%.7s value used inconsistently", pd->name );
 221:             viceversa();
 222:             }
 223:         }
 224: 
 225:     /* check for multiple declaration */
 226: 
 227:     if( (pd->decflag&LDI) && (pc->decflag&(LDI|LIB)) ){
 228:         printf( "%.7s multiply declared", pd->name );
 229:         viceversa();
 230:         }
 231: 
 232:     /* do a bit of checking of definitions and uses... */
 233: 
 234:     if( (pd->decflag & (LDI|LIB|LDX|LDC)) && (pc->decflag & (LDX|LDC)) && pd->type.aty != pc->type.aty ){
 235:         printf( "%.7s value declared inconsistently", pd->name );
 236:         viceversa();
 237:         }
 238: 
 239:     /* better not call functions which are declared to be structure or union returning */
 240: 
 241:     if( (pd->decflag & (LDI|LIB|LDX|LDC)) && (pc->decflag & LUE) && pd->type.aty != pc->type.aty ){
 242:         /* only matters if the function returns union or structure */
 243:         TWORD ty;
 244:         ty = pd->type.aty;
 245:         if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){
 246:             printf( "%.7s function value type must be declared before use", pd->name );
 247:             viceversa();
 248:             }
 249:         }
 250: 
 251:     if( pflag && pd->decflag==LDX && pc->decflag == LUM && !ISFTN(pd->type.aty) ){
 252:         /* make the external declaration go away */
 253:         /* in effect, it was used without being defined */
 254: 
 255:         /* swap pc and pd */
 256:         p3 = pc;
 257:         pc = pd;
 258:         pd = p3;
 259:         }
 260: 
 261:     }
 262: 
 263: viceversa(){
 264:     /* print out file comparison */
 265:     printf( "	%s(%d)  ::  %s(%d)\n", pd->file, pd->fline, pc->file, pc->fline );
 266:     }
 267: 
 268:     /* messages for defintion/use */
 269: char *
 270: mess[2][2] = {
 271:     "",
 272:     "%.7s used( %s(%d) ), but not defined\n",
 273:     "%.7s defined( %s(%d) ), but never used\n",
 274:     "%.7s declared( %s(%d) ), but never used or defined\n"
 275:     };
 276: 
 277: lastone(){
 278: 
 279:     /* called when pc and pd are at last different */
 280:     register nu, nd;
 281: 
 282:     nu = nd = 0;
 283: 
 284:     if( !(uses&USED) && pd->decflag != LIB ) {
 285:         if( !steq(pd->name,"main") )
 286:             nu = 1;
 287:         }
 288: 
 289:     if( !ISFTN(pd->type.aty) ){
 290:         switch( pd->decflag ){
 291: 
 292:         case LIB:
 293:             nu = nd = 0;  /* don't complain about uses on libraries */
 294:             break;
 295:         case LDX:
 296:             if( !xflag ) break;
 297:         case LUV:
 298:         case LUE:
 299:         case LUM:
 300:             nd = 1;
 301:             }
 302:         }
 303: 
 304:     if( uflag && ( nu || nd ) ) printf( mess[nu][nd], pd->name, pd->file, pd->fline );
 305: 
 306:     if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
 307:         printf( "%.7s returns value which is %s ignored\n", pd->name,
 308:             uses&VUSED ? "sometimes" : "always" );
 309:         }
 310: 
 311:     if( (uses&(RVAL+VUSED)) == (VUSED) && (pd->decflag&(LDI|LIB)) ){
 312:         printf( "%.7s value is used, but none returned\n", pd->name );
 313:         }
 314: 
 315:     /* clean up pc, in preparation for the next thing */
 316: 
 317:     uses = 0;
 318:     if( pc->nargs < 0 ){
 319:         pc->nargs = -pc->nargs;
 320:         uses = VARARGS;
 321:         }
 322: 
 323:     }
 324: 
 325: cleanup(){ /* call lastone and die gracefully */
 326:     lastone();
 327:     exit(0);
 328:     }
 329: 
 330: setuse(){ /* check new type to ensure that it is used */
 331: 
 332:     switch( pc->decflag ){
 333: 
 334:     case LRV:
 335:         uses |= RVAL;
 336:         return;
 337:     case LUV:
 338:         uses |= VUSED+USED;
 339:         return;
 340:     case LUE:
 341:         uses |= EUSED+USED;
 342:         return;
 343:     case LUM:
 344:         uses |= USED;
 345:         return;
 346: 
 347:         }
 348:     }
 349: 
 350: chktype( pt1, pt2 ) register atype *pt1, *pt2; {
 351: 
 352:     /* check the two type words to see if they are compatible */
 353:     /* for the moment, enums are turned into ints, and should be checked as such */
 354:     if( pt1->aty == ENUMTY ) pt1->aty =  INT;
 355:     if( pt2->aty == ENUMTY ) pt2->aty = INT;
 356: 
 357:     if( pt2->extra ){ /* constant passed in */
 358:         if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
 359:         else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
 360:         }
 361:     else if( pt1->extra ){ /* for symmetry */
 362:         if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
 363:         else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
 364:         }
 365: 
 366:     return( pt1->aty != pt2->aty );
 367:     }

Defined functions

chkcompat defined in line 187; used 1 times
  • in line 81
chktype defined in line 350; used 2 times
cleanup defined in line 325; used 1 times
error defined in line 167; used 5 times
getnam defined in line 156; used 2 times
lastone defined in line 277; used 2 times
lread defined in line 93; used 1 times
  • in line 80
main defined in line 35; never used
rdin10 defined in line 114; used 4 times
rdinty defined in line 134; used 2 times
setuse defined in line 330; used 2 times
steq defined in line 175; used 2 times
viceversa defined in line 263; used 6 times

Defined variables

hflag defined in line 29; used 1 times
  • in line 46
l1 defined in line 22; used 1 times
  • in line 67
l2 defined in line 23; used 1 times
  • in line 68
mess defined in line 270; used 1 times
p3 defined in line 26; used 4 times
pc defined in line 25; used 34 times
pd defined in line 24; used 45 times
pflag defined in line 30; used 2 times
uflag defined in line 32; used 2 times
uses defined in line 28; used 12 times
xflag defined in line 31; used 2 times

Defined struct's

line defined in line 12; never used

Defined macros

EUSED defined in line 6; used 3 times
RVAL defined in line 7; used 4 times
USED defined in line 4; used 5 times
VARARGS defined in line 8; used 3 times
VUSED defined in line 5; used 4 times
Last modified: 1982-08-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 699
Valid CSS Valid XHTML 1.0 Strict