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

📄 lint.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)lint.c	4.2	(ULTRIX)	12/9/87";#endif lint/************************************************************************ *									* *			Copyright (c) 1984 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *			Modification History				* *									* *	David Metsky, 2-Jul-87, 2.4(2.2) * 003	Made it OK to do a greater than of an unsigned number against	* *	0.								* *									* *	Lu Anne Van de Pas, 13-Mar-86, 2.0				* * 002  Added functions cvtfloat and cvtdouble to distinguish between   * *	double and float constants.					* *	David L. Ballenger, 14-Nov-1984, 1.2				* * 001	Add definitions of ALSTACK so that code shared with PCC will	* *	work								* *									* ************************************************************************/# 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 ALSTACK = 32;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 to check precision of assignments */int zflag = 0;  /* no 'structure never defined' error */int Cflag = 0;  /* filter out certain output, for generating libraries */char *libname = 0;  /* name of the library we're generating */	/* flags for the "outdef" function */# define USUAL (-101)# define DECTY (-102)# define NOFILE (-103)# define SVLINE (-104)# define LNAMES 250struct lnm {	short lid, flgs;	}  lnames[LNAMES], *lnp;contx( p, down, pl, pr ) register NODE *p; register *pl, *pr; {	*pl = *pr = VAL;	switch( p->in.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->in.op) ) break;		if( p->in.op == UNARY MUL && ( p->in.type == STRTY || p->in.type == UNIONTY || p->in.type == UNDEF) ) {		/* struct x f( );  main( ) {  (void) f( ); }		 * the the cast call appears as U* UNDEF		 */			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( !zflag && dimtab[p->sizoff+1] < 0 ){					/* never defined */#ifndef FLEXNAMES					if( hflag ) werror( "struct/union %.8s never defined", p->sname );#else					if( hflag ) werror( "struct/union %s never defined", p->sname );#endif					}				}			switch( p->sclass ){						case STATIC:				if( p->suse > 0 ){					k = lineno;					lineno = p->suse;#ifndef FLEXNAMES					uerror( "static variable %.8s unused",#else					uerror( "static variable %s unused",#endif						p->sname );					lineno = k;					break;					}				/* no statics in libraries */				if( Cflag ) 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 ){					outdef( p, LDX, NOFILE );					}						case EXTDEF:				if( p->suse < 0 ){  /* used */					outdef( p, LUM, SVLINE );					}				break;				}						}		}	exit( 0 );	}astype( t, i ) ATYPE *t; {	TWORD tt;	int j, k=0, l=0;	if( (tt=BTYPE(t->aty))==STRTY || tt==UNIONTY ){		if( i<0 || i>= DIMTABSZ-3 ){			werror( "lint's little mind is blown" );			}		else {			j = dimtab[i+3];			if( j<0 || j>SYMTSZ ){				k = dimtab[i];				l = X_NONAME | stab[j].suse;				}			else {				if( stab[j].suse <= 0 ) {#ifndef FLEXNAMES					werror( "no line number for %.8s",#else					werror( "no line number for %s",#endif						stab[j].sname );					}				else {					k = dimtab[i];#ifdef FLEXNAMES					l = hashstr(stab[j].sname);#else					l = hashstr(stab[j].sname, LCHNM);#endif					}				}			}				t->extra = k;		t->extra1 = l;		return( 1 );		}	else return( 0 );	}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;	static ATYPE t;	retlab = 1;	cfp = &stab[curftn];	/* if creating library, don't do static functions */	if( Cflag && cfp->sclass == STATIC ) return;	/* 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;		}	fsave( ftitle );	if( cfp->sclass == STATIC ) outdef( cfp, LST, vaflag>=0?-n:n );	else outdef( cfp, libflag?LIB:LDI, vaflag>=0?-n:n );	vaflag = -1;	/* output the arguments */	if( n ){		for( i=0; i<n; ++i ) {			t.aty = stab[a[i]].stype;			t.extra = 0;			t.extra1 = 0;			if( !astype( &t, stab[a[i]].sizoff ) ) {				switch( t.aty ){				case ULONG:					break;				case CHAR:				case SHORT:					t.aty = INT;					break;				case UCHAR:				case USHORT:				case UNSIGNED:					t.aty = UNSIGNED;					break;					}				}			fwrite( (char *)&t, sizeof(ATYPE), 1, stdout );			}		}	}ctargs( p ) NODE *p; {	/* count arguments; p points to at least one */	/* the arguemnts are a tower of commas to the left */	register c;	c = 1; /* count the rhs */	while( p->in.op == CM ){		++c;		p = p->in.left;		}	return( c );	}lpta( p ) NODE *p; {	static ATYPE t;	if( p->in.op == CM ){		lpta( p->in.left );		p = p->in.right;		}	t.aty = p->in.type;	t.extra = (p->in.op==ICON);	t.extra1 = 0;	if( !astype( &t, p->in.csiz ) ) {		switch( t.aty ){			case CHAR:			case SHORT:				t.aty = INT;			case LONG:			case ULONG:			case INT:			case UNSIGNED:				break;			case UCHAR:			case USHORT:				t.aty = UNSIGNED;				break;			case FLOAT:				t.aty = DOUBLE;				t.extra = 0;				break;			default:				t.extra = 0;				break;			}		}	fwrite( (char *)&t, sizeof(ATYPE), 1, stdout );	}# 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->in.op == ASSIGN ) use1 = VALSET;	else if( p->in.op == UNARY AND ) use1 = VALADDR;	else if( asgop( p->in.op ) ){ /* =ops */		use1 = VALUSED|VALSET;		if( down == EFF ) use1 |= VALASGOP;		}	/* print the lines for lint */	down2 = down1 = VAL;	acount = 0;	switch( p->in.op ){	case EQ:	case NE:	case GT:	case GE:	case LT:	case LE:		if( p->in.left->in.type == CHAR && p->in.right->in.op==ICON && p->in.right->tn.lval < 0 ){			werror( "nonportable character comparison" );			}		if( (p->in.op==EQ || p->in.op==NE ) && ISUNSIGNED(p->in.left->in.type) && p->in.right->in.op == ICON ){			if( p->in.right->tn.lval < 0 && p->in.right->tn.rval == NONAME && !ISUNSIGNED(p->in.right->in.type) ){				werror( "comparison of unsigned with negative constant" );				}			}		break;	case UGE:	case ULT:		if( p->in.right->in.op == ICON && p->in.right->tn.lval == 0 && p->in.right->tn.rval == NONAME ){			werror( "unsigned comparison with 0?" );			break;			}	case ULE:		if( p->in.right->in.op == ICON && p->in.right->tn.lval <= 0 && !ISUNSIGNED(p->in.right->in.type) && p->in.right->tn.rval == NONAME ){			werror( "degenerate unsigned comparison" );			}		break;	case UGT:			/* 003 - dnm */		if( p->in.right->in.op == ICON && p->in.right->tn.lval < 0 && !ISUNSIGNED(p->in.right->in.type) && p->in.right->tn.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->in.left, down1, use1 );		np2 = lnp;		lprt( p->in.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->in.right );	case UNARY CALL:	case UNARY STCALL:	case UNARY FORTCALL:		if( p->in.left->in.op == ICON && (id=p->in.left->tn.rval) != NONAME ){ /* used to be &name */			struct symtab *sp = &stab[id];			int lty;			fsave( ftitle );			/*			 * if we're generating a library -C then			 * we don't want to output references to functions			 */			if( Cflag ) break;			/*  if a function used in an effects context is			 *  cast to type  void  then consider its value			 *  to have been disposed of properly			 *  thus a call of type  undef  in an effects			 *  context is construed to be used in a value			 *  context			 */			if ((down == EFF) && (p->in.type != UNDEF)) {				lty = LUE;			} else if (down == EFF) {				lty = LUV | LUE;			} else {				lty = LUV;			}			outdef( sp, lty, acount );			if( acount ) {				lpta( p->in.right );				}			}		break;	case ICON:		/* look for &name case */		if( (id = p->tn.rval) >= 0 && id != NONAME ){			q = &stab[id];			q->sflags |= (SREF|SSET);			q->suse = -lineno;			}		return;	case NAME:		if( (id = p->tn.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 && q->stype!=UNIONTY ){#ifndef FLEXNAMES						werror( "%.8s may be used before set", q->sname );#else						werror( "%s may be used before set", q->sname );#endif						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->tn.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->in.op) ){	case BITYPE:		np1 = lnp;		lprt( p->in.right, down2, use2 );	case UTYPE:		np2 = lnp;		lprt( p->in.left, down1, use1 );		}	if( optype(p->in.op) == BITYPE ){		if( p->in.op == ASSIGN && p->in.left->in.op == NAME ){ /* special case for a =  .. a .. */			lmerge( np1, np2, 0 );			}		else lmerge( np1, np2, p->in.op != COLON );		/* look for assignments to fields, and complain */		if( p->in.op == ASSIGN && p->in.left->in.op == FLD && p->in.right->in.op == ICON ) fldcon( p );		}	}lmerge( np1, np2, flag ) struct lnm *np1, *np2; {	/* np1 and np2 point to lists of lnm members, for the two sides	 * of a binary operator	 * flag is 1 if commutation is possible, 0 otherwise	 * lmerge returns a merged list, starting at np1, resetting lnp	 * it also complains, if appropriate, about side effects	 */

⌨️ 快捷键说明

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