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

📄 lpass2.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char sccsid[] = "@(#)lpass2.c 1.1 92/07/30 SMI"; /* from S5R2 1.8 */#endif#ident "@(#)RELEASE lint2 4.1"/* lpass2.c *	This file includes the main functions for the second lint pass. * *	Functions: *	========== *		chkcompat	check for various sorts of compatibility *		chktype		check two types to see if they are compatible *		cleanup		do wrapup checking *		find		find name in symbol table *		lastone		check set/use in a last pass over the symbol table *		lread		read in a line from the intermediate file *		main		the driver for the second pass (lint2) *		mloop		the main loop of the second pass *		setfno		set file number (keep track of source file names) *		setuse		fix set/use and other information for objects *		tget */# include <stdio.h># include "types.h"extern char *strncpy();/* * local aliases */# define TWORD PCC_TWORD# include "lerror.h"# include "lmanifest.h"# include "lpass2.h"# define USED 01# define VUSED 02# define EUSED 04# define RVAL 010# define VARARGS 0100# define NSZ 8192# if pdp11#	define TYSZ 2500# else#	define TYSZ 3500	/* should be 2500 temp fix for mjs */# endif# define NTY 50SYMTAB stab[NSZ];			/* second pass symbol table */SYMTAB *find();STYPE *tptr = NULL;STYPE *tget();typedef char *filename;filename *fnm = NULL;	/* varying-length array of filenames */int fnmlimit = 0;	/* current upper bound of fnm table */static void init_fnm();static void new_fnm();extern char *realloc();char *getstr();char *hash();int tfree;  /* used to allocate types */int ffree;  /* used to save filenames */struct ty atyp[NTY];union rec r;			/* where all the input ends up */TWORD ctype();int hflag = 1;			/* 28 feb 80  reverse sense of hflag */int pflag = 0;int qflag = 0;int xflag = 1;			/* 28 feb 80  reverse sense of xflag */int uflag = 1;int zflag = 0;int sys5flag = 1;static int idebug = 0;static int odebug = 0;int cfno;				/* current file number */int cmno;				/* current module number */char		*ifilename = NULL;/* main program for second pass */main( argc, argv ) char *argv[]; {	int c;	extern char	*htmpname;	extern char *optarg;	int Hflag = 0, Tflag = 0;	/*	 * If our first argument isn't an option, we're being invoked	 * as the pre-S3 "lint".  Use that argument as "ifilename",	 * delete it from the middle of the argument list, and turn	 * off the S5 flag.	 */	if( argc > 1 && argv[1][0] != '-' )	{		ifilename = argv[1];		Tflag = 1;		argv[1] = argv[0];		argv++;		argc--;		sys5flag = 0;	}	while((c=getopt(argc,argv,"abchnpquvxzH:LT:X:")) != EOF)		switch(c) {		case 'h':			hflag = 0;			break;		case 'p':			pflag = 1;			break;		case 'q':			qflag = 1;			break;		case 'x':			xflag = 0;			break;		case 'u':			uflag = 0;			break;		case 'z':			zflag = 1;			break;		case 'H':			htmpname = optarg;			Hflag = 1;			break;		case 'T':			ifilename = optarg;			Tflag = 1;			break;			/* debugging options */		case 'X':			for(; *optarg; optarg++)				switch(*optarg) {				case 'i':					idebug = 1;					break;				case 'o':					odebug = 1;					break;				} /*end switch(*optarg), for*/			break;		case 'a':		/* first pass option */		case 'b':		/* first pass option */		case 'c':		/* first pass option */		case 'n':		/* done in shell script */		case 'v':		/* first pass option */		case 'L':		/* first pass option */			break;		} /*end switch for processing args*/	/*	 * Decide whether you're S5 or pre-S3, and patch up if pre-S3.	 * "Patching up" involves the following:	 * - toggling the values of hflag and xflag	 * - forcing msgs to come out one per line, instead of	 *	being nicely formatted as is the S5 default	 */	if( !sys5flag )	{		hflag = !hflag;		xflag = !xflag;	}	tmpopen( );	if ( Hflag )		unbuffer( );	if ( !Tflag )	{		lerror( "", CCLOSE | HCLOSE );	/* all done */		return (0);	}	if ( !freopen( ifilename, "r", stdin ) )		lerror( "cannot open intermediate file", FATAL | CCLOSE | ERRMSG );	if ( idebug ) pif();	init_fnm();	mloop( LDI|LDS|LIB );	rewind( stdin );	mloop( LDC|LDX );	rewind( stdin );	mloop( LRV|LUV|LUE|LUM );	if ( odebug ) pst();	cleanup();	un2buffer( );	return(0);} /*end main*//* mloop - main loop *	each pass of the main loop reads in names from the intermediate  *	file that have characteristics which overlap with the *	characteristics specified as the parameter */mloop( m ){	register SYMTAB *q;	while( lread(m) ){		q = find();		if( q->decflag ) chkcompat(q);		else setuse(q);	}}/* lread - read a line from intermediate file into r.l */lread(m){	register n;	for(;;) {		/* read in line from intermediate file; exit if at end */		if( fread( (char *)&r, sizeof(r), 1, stdin ) <= 0 ) return(0);		if( r.l.decflag & LFN ){			/* new filename and module number */			r.f.fn = getstr();			setfno( r.f.fn );			/* the purpose of the module number is to handle static scoping			 *	correctly.  A module is a file with all its include files.			 *	From a scoping point of view, there is no difference between			 *	a variable in a file and a variable in an included file.			 *	The module number itself is not meaningful; it must only			 *	be unique to ensure that modules are distinguishable			 */			cmno = r.f.mno;			continue;		}		/* number of arguments is negative for VARARGS (plus one) */		r.l.name = getstr();		n = r.l.nargs;		if( n<0 ) n = -n - 1;		/* collect type info for all args */		if( n ) {			if ( n > sizeof atyp / sizeof (ATYPE) ) {				lerror( "invalid number of arguments", 				    CCLOSE | FATAL | ERRMSG );			}			fread( (char *)atyp, sizeof(ATYPE), n, stdin );		}		/* return with entry only if it has correct characteristics */		if( ( r.l.decflag & m ) ) return( 1 );	}}/* setfno - set file number */setfno( s ) char *s;{  int i;	/* look up filename */	for( i=0; i<ffree; ++i )		if( fnm[i] == s ){			cfno = i;			return;		}	/* make a new entry */	new_fnm();	fnm[ffree] = s;	cfno = ffree++;}static voidinit_fnm(){	fnm = (filename*)malloc((unsigned)FSZ*sizeof(filename));	if (fnm == NULL) {		lerror("cannot allocate storage for file name table");	}	fnmlimit = FSZ;}static voidnew_fnm(){	if (ffree >= fnmlimit) {		fnmlimit += FSZ;		fnm = (filename*)realloc(fnm, fnmlimit*sizeof(filename));		if (fnm == NULL) {			lerror("cannot allocate storage for file name table");		}	}}/* find - find object in the symbol table */SYMTAB *find(){  register h=0;	/* hashing scheme */	/* for this to work, NSZ should be a power of 2 */	h = ( (int) r.l.name ) % NSZ;	/* symbol table search */	/* 21 July 1980 - scoping added to symbol table search */	{  register SYMTAB *p, *q, *maybe = 0;		for( p=q= &stab[h]; q->decflag; ){			/* find a name that matches */			if ( r.l.name == q->name )  {				/* match if module id-s are the same */				if (q->mno == cmno) return(q);				/* otherwise, possible match if neither is static */				if( !( q->decflag&LDS || r.l.decflag&LDS ) ) maybe = q;				/* else there must be another stab entry with same name				 * (if there is NOT, then we will add an entry) */				else if (!maybe) q->more = 1;				/* at end of chain - so use global name */				if( !(q->more) && maybe ) return(maybe);			}			/* no match, so continue looking */			if( ++q >= &stab[NSZ] ) q = stab;			if( q == p )				lerror( "too many names defined", CCLOSE | FATAL | ERRMSG );		}		q->name = r.l.name;		/* if we are inserting, the new entry is the last in the "chain" */		q->more = 0;		return( q );	}}/* tget */STYPE *tget(){	if( tfree == 0 )	{		/*		 * Allocate a fresh batch of TYSZ type entries.		 */		if (( tptr = (STYPE *)malloc(TYSZ*sizeof (STYPE))) == NULL )			lerror( "can't allocate memory for type table", CCLOSE | FATAL | ERRMSG );		tfree = TYSZ;	}	tfree--;	return( tptr++ );}/* chkcompat - check for compatibility *	compare item in symbol table (stab) with item just read in *	The work of this routine is not well defined; there are many *	checks that might be added or changes */chkcompat(q) SYMTAB *q; {	register int i;	STYPE *qq;	setuse(q);	/* do an argument check only if item is a function; if it is	*  both a function and a variable, it will get caught later on	*/	if( ISFTN(r.l.type.aty) && ISFTN(q->symty.t.aty) )		/* argument check */		if( q->decflag & (LDI|LDS|LIB|LUV|LUE) )			if( r.l.decflag & (LUV|LIB|LUE) ){				if( q->nargs != r.l.nargs ){					if( !(q->use&VARARGS) )						/* "%.8s: variable # of args." */						/* "%s: variable # of args." */						buffer( 7, q );					if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs;					if( !(q->decflag & (LDI|LDS|LIB) ) ) {						q->nargs = r.l.nargs;						q->use |= VARARGS;					}				}				for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next)					if( chktype( &qq->t, &atyp[i] ) )						/* "%.8s, arg. %d used inconsistently" */						/* "%s, arg. %d used inconsistently" */						buffer( 6, q, i+1 );			}	if( (q->decflag&(LDI|LDS|LIB|LUV)) && r.l.decflag==LUV )		if( chktype( &r.l.type, &q->symty.t ) )			/* "%.8s value used inconsistently" */			/* "%s value used inconsistently" */			buffer( 4, q );	/* check for multiple declaration */	if( (q->decflag & (LDI|LDS) ) && (r.l.decflag&(LDI|LDS|LIB)) )		/* "%.8s multiply declared" */		/* "%s multiply declared" */		buffer( 3, q );	/* do a bit of checking of definitions and uses... */	if( (q->decflag & (LDI|LDS|LIB|LDX|LDC|LUM))	    && (r.l.decflag & (LDX|LDC|LUM))	    && ctype(q->symty.t.aty) != ctype(r.l.type.aty) )		/* "%.8s value type declared inconsistently" */		/* "%s value type declared inconsistently" */		buffer( 5, q );	/* better not call functions which are declared to be		structure or union returning */	if( (q->decflag & (LDI|LDS|LIB|LDX|LDC))	    && (r.l.decflag & LUE)	    && q->symty.t.aty != r.l.type.aty ){		/* only matters if the function returns union or structure */		TWORD ty;		ty = q->symty.t.aty;		if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) )			/* "%.8s function value type must be declared before use" */			/* "%s function value type must be declared before use" */			buffer( 8, q );	}} /*end chkcompat*//* messages for defintion/use */int	mess[2][2] = {	NUM2MSGS,	0,	1,	2};lastone(q) SYMTAB *q; {	register nu, nd, uses;	nu = nd = 0;	uses = q->use;	if( !(uses&USED) && q->decflag != LIB )		if( strcmp(q->name,"main") ) nu = 1;	/* treat functions and variables the same */	switch( q->decflag ){	case LIB:		nu = nd = 0;  /* don't complain about uses on libraries */		break;	case LDX:		if( !xflag ) break;	case LUV:	case LUE:/* 01/04/80 */	case LUV | LUE:/* or'ed together for void */	case LUM:		nd = 1;	}	if( uflag && ( nu || nd ) ) buffer( mess[nu][nd], q );	if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){		if ( uses & VUSED ) 

⌨️ 快捷键说明

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