⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpass2.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
# include "lmanifest"# include "manifest"# define USED 01# define VUSED 02# define EUSED 04# define RVAL 010# define VARARGS 0100typedef struct { TWORD aty; int extra; } atype;struct line {	char name[8];	int decflag;	atype type;	int nargs;	atype atyp[50];	int fline;	char file[100];	}	l1,	l2,	*pd,	/* pointer to line having definition */	*pc,	/* pointer to current line read */	*p3;	/* used for swapping pc and pd */int uses = USED;int hflag = 0;int pflag = 0;int xflag = 0;int uflag = 1;main( argc, argv ) char *argv[]; {	register char *p;	/* first argument is - options */	if( argc>=2 && argv[1][0] == '-' ){		for( p=argv[1]; *p; ++p ){			switch( *p ){			case 'h':				hflag = 1;				break;			case 'p':				pflag = 1;				break;			case 'x':				xflag = 1;				break;			case 'u':				uflag = 0;				break;				}			}		}	pd = &l1;	pc = &l2;	pd->name[0] = '\0' ;	pd->fline = 0;	pd->file[0] = '\0';	pd->decflag = LDI;	/* main loop: read a line;		if same as last line, check compatibility		if not same as last line, becomes df.		*/	for(;;){		lread();		if( steq(pc->name, pd->name) ) chkcompat();		else {			lastone();			setuse();			p3=pc;			pc = pd;			pd = p3;			}		}	}lread(){ /* read a line into pc */	register i, n;	getnam( pc->name );	pc->decflag = rdin10();	rdinty( &pc->type );	n = pc->nargs = rdin10();	if( n<0 ) n = -n;	for( i=0; i<n; ++i ){		rdinty( &pc->atyp[i] );		}	getnam( pc->file );	pc->fline = rdin10();	while( getchar() != '\n' ) ; /* VOID */	}rdin10(){	register val, c, s;	val = 0;	s = 1;	while( (c=getchar()) != '\t' ){		if( c <= 0 ) error( "unexpected EOF" );		else if( c == '-' ) {			s = -1;			continue;			}		else if( c<'0' || c>'9' ) {			error("rotten digit: %o\n", c );			}		val = val*10 + c - '0';		}	return( val*s );	}rdinty( p ) atype *p; {	register val, c, s;	val = 0;	s = 1;	while( (c=getchar()) != '\t' && c!= '<' ){		if( c <= 0 ) error( "unexpected EOF" );		else if( c == '-' ) {			s = -1;			continue;			}		else if( c<'0' || c>'7' ) {			error("rotten digit: %o\n", c );			}		val = (val<<3) + c - '0';		}	p->aty = val*s;	if( c == '<' ) p->extra = rdin10();	else p->extra = 0;	}getnam(p) char *p; {	register c;	while( (c=getchar()) != '\t' ){		if( c == '\n' ) error( "rotten name\n" );		if( c <= 0 ) cleanup();		*p++ = c;		}	*p = '\0';	}/* VARARGS */error( s, a ) char *s; {	fprintf( stderr, "pass 2 error: " );	fprintf( stderr, s, a );	fprintf( stderr, "\n" );	exit(1);	}steq(p,q) char *p,*q; { /* check that the p and q names are the same */	while( *p == *q ){		if( *p == 0 ) return(1);		++p;		++q;		}	return(0);	}chkcompat(){	/* are the types, etc. in pc and pd compatible */	register int i;	setuse();	/* argument check */	if( pd->decflag & (LDI|LIB|LUV|LUE) ){		if( pc->decflag & (LUV|LIB|LUE) ){			if( pd->nargs != pc->nargs ){				if( !(uses&VARARGS) ){					printf( "%.7s: variable # of args.", pd->name );					viceversa();					}				if( pc->nargs > pd->nargs ) pc->nargs = pd->nargs;				if( !(pd->decflag & (LDI|LIB) ) ) {					pd->nargs = pc->nargs;					uses |= VARARGS;					}				}			for( i=0; i<pc->nargs; ++i ){				if( chktype(&pd->atyp[i], &pc->atyp[i]) ){					printf( "%.7s, arg. %d used inconsistently",						pd->name, i+1 );					viceversa();					}				}			}		}	if( (pd->decflag&(LDI|LIB|LUV)) && pc->decflag==LUV ){		if( chktype( &pc->type, &pd->type ) ){			printf( "%.7s value used inconsistently", pd->name );			viceversa();			}		}	/* check for multiple declaration */	if( (pd->decflag&LDI) && (pc->decflag&(LDI|LIB)) ){		printf( "%.7s multiply declared", pd->name );		viceversa();		}	/* 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 );		viceversa();		}	/* 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 */		TWORD ty;		ty = pd->type.aty;		if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){			printf( "%.7s function value type must be declared before use", pd->name );			viceversa();			}		}	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 */		/* swap pc and pd */		p3 = pc;		pc = pd;		pd = p3;		}	}viceversa(){	/* print out file comparison */	printf( "	%s(%d)  ::  %s(%d)\n", pd->file, pd->fline, pc->file, pc->fline );	}	/* messages for defintion/use */char *mess[2][2] = {	"",	"%.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"	};lastone(){	/* called when pc and pd are at last different */	register nu, nd;	nu = nd = 0;	if( !(uses&USED) && pd->decflag != LIB ) {		if( !steq(pd->name,"main") )			nu = 1;		}	if( !ISFTN(pd->type.aty) ){		switch( pd->decflag ){		case LIB:			nu = nd = 0;  /* don't complain about uses on libraries */			break;		case LDX:			if( !xflag ) break;		case LUV:		case LUE:		case LUM:			nd = 1;			}		}	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 */	uses = 0;	if( pc->nargs < 0 ){		pc->nargs = -pc->nargs;		uses = VARARGS;		}	}cleanup(){ /* call lastone and die gracefully */	lastone();	exit(0);	}setuse(){ /* check new type to ensure that it is used */	switch( pc->decflag ){	case LRV:		uses |= RVAL;		return;	case LUV:		uses |= VUSED+USED;		return;	case LUE:		uses |= EUSED+USED;		return;	case LUM:		uses |= USED;		return;		}	}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 );	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -