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

📄 lint.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
# include "mfile1"# include "lmanifest"# include <ctype.h># define VAL 0# define EFF 1/* these are appropriate for the -p flag */int  SZCHAR = 8;int  SZINT = 16;int  SZFLOAT = 32;int  SZDOUBLE = 64;int  SZLONG = 32;int  SZSHORT = 16;int SZPOINT = 16;int ALCHAR = 8;int ALINT = 16;int ALFLOAT = 32;int ALDOUBLE = 64;int ALLONG = 32;int ALSHORT = 16;int ALPOINT = 16;int ALSTRUCT = 16;int vflag = 1;  /* tell about unused argments */int xflag = 0;  /* tell about unused externals */int argflag = 0;  /* used to turn off complaints about arguments */int libflag = 0;  /* used to generate library descriptions */int vaflag = -1;  /* used to signal functions with a variable number of args */int aflag = 0;  /* used th check precision of assignments */char *flabel = "xxx";# define LNAMES 100struct lnm {	short lid, flgs;	}  lnames[LNAMES], *lnp;contx( p, down, pl, pr ) register NODE *p; register *pl, *pr; {	*pl = *pr = VAL;	switch( p->op ){	case ANDAND:	case OROR:	case QUEST:		*pr = down;		break;	case SCONV:	case PCONV:	case COLON:		*pr = *pl = down;		break;	case COMOP:		*pl = EFF;		*pr = down;	case FORCE:	case INIT:	case UNARY CALL:	case STCALL:	case UNARY STCALL:	case CALL:	case UNARY FORTCALL:	case FORTCALL:	case CBRANCH:		break;	default:		if( asgop(p->op) ) break;		if( p->op == UNARY MUL && ( p->type == STRTY || p->type == UNIONTY) ) {			break;  /* the compiler does this... */			}		if( down == EFF && hflag ) werror( "null effect" );		}	}ecode( p ) NODE *p; {	/* compile code for p */	fwalk( p, contx, EFF );	lnp = lnames;	lprt( p, EFF, 0 );	}ejobcode( flag ){	/* called after processing each job */	/* flag is nonzero if errors were detected */	register k;	register struct symtab *p;	for( p=stab; p< &stab[SYMTSZ]; ++p ){		if( p->stype != TNULL ) {			if( p->stype == STRTY || p->stype == UNIONTY ){				if( dimtab[p->sizoff+1] < 0 ){ /* never defined */					if( hflag ) werror( "struct/union %.7s never defined", p->sname );					}				}			switch( p->sclass ){						case STATIC:				if( p->suse > 0 ){					k = lineno;					lineno = p->suse;					uerror( "static variable %s unused",						p->sname );					lineno = k;					break;					}			case EXTERN:			case USTATIC:				/* with the xflag, worry about externs not used */				/* the filename may be wrong here... */				if( xflag && p->suse >= 0 && !libflag ){					printf( "%.7s\t%03d\t%o\t%d\t", p->sname, LDX, p->stype, 0 );					/* we don't really know the file number; we know only the line 						number, so we put only that out */					printf( "\"???\"\t%d\t%s\n", p->suse, flabel );					}						case EXTDEF:				if( p->suse < 0 ){  /* used */					printf( "%.7s\t%03d\t%o\t%d\t", exname(p->sname), LUM, p->stype, 0 );					fident( -p->suse );					}				break;				}						}		}	exit( 0 );	}fident( line ){ /* like ident, but lineno = line */	register temp;	temp = lineno;	lineno = line;	ident();	lineno = temp;	}ident(){ /* write out file and line identification  */	printf( "%s\t%d\t%s\n", ftitle, lineno, flabel );	}bfcode( a, n ) int a[]; {	/* code for the beginning of a function; a is an array of		indices in stab for the arguments; n is the number */	/* this must also set retlab */	register i;	register struct symtab *cfp;	register unsigned t;	retlab = 1;	cfp = &stab[curftn];	/* if variable number of arguments, only print the ones which will be checked */	if( vaflag > 0 ){		if( n < vaflag ) werror( "declare the VARARGS arguments you want checked!" );		else n = vaflag;		}	printf( "%.7s\t%03d\t%o\t%d\t", exname(cfp->sname), libflag?LIB:LDI,		cfp->stype, vaflag>=0?-n:n );	vaflag = -1;	for( i=0; i<n; ++i ) {		switch( t = stab[a[i]].stype ){		case ULONG:			break;		case CHAR:		case SHORT:			t = INT;			break;		case UCHAR:		case USHORT:		case UNSIGNED:			t = UNSIGNED;			break;			}		printf( "%o\t", t );		}	ident();	}ctargs( p ) NODE *p; {	/* count arguments; p points to at least one */	/* the arguemnts are a tower of commasto the left */	register c;	c = 1; /* count the rhs */	while( p->op == CM ){		++c;		p = p->left;		}	return( c );	}lpta( p ) NODE *p; {	TWORD t;	if( p->op == CM ){		lpta( p->left );		p = p->right;		}	switch( t = p->type ){		case CHAR:		case SHORT:			t = INT;		case LONG:		case ULONG:		case INT:		case UNSIGNED:			break;		case UCHAR:		case USHORT:			t = UNSIGNED;			break;		case FLOAT:			printf( "%o\t", DOUBLE );			return;		default:			printf( "%o\t", p->type );			return;		}	if( p->op == ICON ) printf( "%o<1\t", t );	else printf( "%o\t", t );	}# define VALSET 1# define VALUSED 2# define VALASGOP 4# define VALADDR 8lprt( p, down, uses ) register NODE *p; {	register struct symtab *q;	register id;	register acount;	register down1, down2;	register use1, use2;	register struct lnm *np1, *np2;	/* first, set variables which are set... */	use1 = use2 = VALUSED;	if( p->op == ASSIGN ) use1 = VALSET;	else if( p->op == UNARY AND ) use1 = VALADDR;	else if( asgop( p->op ) ){ /* =ops */		use1 = VALUSED|VALSET;		if( down == EFF ) use1 |= VALASGOP;		}	/* print the lines for lint */	down2 = down1 = VAL;	acount = 0;	switch( p->op ){	case EQ:	case NE:	case GT:	case GE:	case LT:	case LE:		if( p->left->type == CHAR && p->right->op==ICON && p->right->lval < 0 ){			werror( "nonportable character comparison" );			}		if( (p->op==EQ || p->op==NE ) && ISUNSIGNED(p->left->type) && p->right->op == ICON ){			if( p->right->lval < 0 && p->right->rval == NONAME && !ISUNSIGNED(p->right->type) ){				werror( "comparison of unsigned with negative constant" );				}			}		break;	case UGE:	case ULT:		if( p->right->op == ICON && p->right->lval == 0 && p->right->rval == NONAME ){			werror( "unsigned comparison with 0?" );			break;			}	case UGT:	case ULE:		if( p->right->op == ICON && p->right->lval <= 0 && !ISUNSIGNED(p->right->type) && p->right->rval == NONAME ){			werror( "degenerate unsigned comparison" );			}		break;	case COMOP:		down1 = EFF;	case ANDAND:	case OROR:	case QUEST:		down2 = down;		/* go recursively left, then right  */		np1 = lnp;		lprt( p->left, down1, use1 );		np2 = lnp;		lprt( p->right, down2, use2 );		lmerge( np1, np2, 0 );		return;	case SCONV:	case PCONV:	case COLON:		down1 = down2 = down;		break;	case CALL:	case STCALL:	case FORTCALL:		acount = ctargs( p->right );	case UNARY CALL:	case UNARY STCALL:	case UNARY FORTCALL:		if( p->left->op == ICON && (id=p->left->rval) != NONAME ){ /* used to be &name */			printf( "%.7s\t%03d\t%o\t%d\t",				exname(stab[id].sname),				down==EFF ? LUE : LUV,				DECREF(p->left->type), acount );			if( acount ) lpta( p->right );			ident();			}		break;	case ICON:		/* look for &name case */		if( (id = p->rval) >= 0 && id != NONAME ){			q = &stab[id];			q->sflags |= (SREF|SSET);			}		return;	case NAME:		if( (id = p->rval) >= 0 && id != NONAME ){			q = &stab[id];			if( (uses&VALUSED) && !(q->sflags&SSET) ){				if( q->sclass == AUTO || q->sclass == REGISTER ){					if( !ISARY(q->stype ) && !ISFTN(q->stype) && q->stype!=STRTY ){						werror( "%.7s may be used before set", q->sname );						q->sflags |= SSET;						}					}				}			if( uses & VALASGOP ) break;  /* not a real use */			if( uses & VALSET ) q->sflags |= SSET;			if( uses & VALUSED ) q->sflags |= SREF;			if( uses & VALADDR ) q->sflags |= (SREF|SSET);			if( p->lval == 0 ){				lnp->lid = id;				lnp->flgs = (uses&VALADDR)?0:((uses&VALSET)?VALSET:VALUSED);				if( ++lnp >= &lnames[LNAMES] ) --lnp;				}			}		return;		}	/* recurse, going down the right side first if we can */	switch( optype(p->op) ){	case BITYPE:		np1 = lnp;		lprt( p->right, down2, use2 );	case UTYPE:		np2 = lnp;		lprt( p->left, down1, use1 );		}	if( optype(p->op) == BITYPE ){		if( p->op == ASSIGN && p->left->op == NAME ){ /* special case for a =  .. a .. */			lmerge( np1, np2, 0 );			}		else lmerge( np1, np2, p->op != COLON );		/* look for assignments to fields, and complain */

⌨️ 快捷键说明

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