misc.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,261 行 · 第 1/2 页

C
1,261
字号
#ifndef lintstatic	char	*sccsid = "@(#)misc.c	4.2	(ULTRIX)	10/16/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1986,1987,1988,1989 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: * *	14-Apr-89	Tim N. *	Removed local vax conditional definition of calloc routine. *	Also put in 3.1 fixes which were: *	Changed the get routine to use null terminated *	string copy to get proper end of string on *      local copies of the file names passed in.  Also added special *	handling of the SHELL and MAKESHELL env vars while in POSIX mode. * */#include "defs"#include "ctype.h"CHARSTAR do_colon();CHARSTAR do_df();#if 0FSTATIC CHARSTAR nextchar=0;FSTATIC CHARSTAR lastchar=0;FSTATIC int *nextint=0;FSTATIC int *lastint=0;#endif 0int nhashed=0;/* simple linear hash.  hash function is sum of   characters mod hash table size.*/hashloc(s)register CHARSTAR s;{	register int i;	register int hashval;	register CHARSTAR t;	hashval = 0;	for(t=s; *t!=CNULL ; ++t) hashval += *t;	hashval &= HASHSIZE;	for(i=hashval;		hashtab[i]!=0 && !equal(s,hashtab[i]->namep);			i = (i+1)&HASHSIZE ) ;	return(i);}/* made this a macro....rrNAMEBLOCKsrchname(s)register CHARSTAR s;{	return( hashtab[hashloc(s)] );}*/NAMEBLOCKmakename(s)register CHARSTAR s;{	/* make a name entry; `s' is presumed to already to have been saved */	register NAMEBLOCK p;	if(nhashed++ > HASHSIZE-3)		fatal("Hash table overflow");	p = ALLOC(nameblock);	p->nextname = firstname;	p->backname = NULL;	p->namep = s;	p->linep = 0;	p->done = 0;	p->septype = 0;	p->rundep  = 0;	p->modtime = 0;	firstname = p;	hashtab[hashloc(s)] = p;	return(p);}#define NOTSHORT sizeof (struct nameblock)#define TABLESIZE 127	/* must be 2**n -1 */#define TRUE 1#define FALSE 0CHARSTARcopys(s)register CHARSTAR s;{#ifdef SYSV	register CHARSTAR t;	static struct entry		/* structure will form linked      */	{				/* list of strings in alpha-order. */		CHARSTAR name;		/* table is hash-table of 100 els. */		struct entry *next;	/* used to make searching faster.  */	} 	*table[TABLESIZE],*laste,*newe,*e;	register int found;	register int i;	register int hashval = 0;	for(t=s; *t != CNULL; ++t)	/* Hash the string - sum of chars */		hashval += *t;	hashval &= TABLESIZE;		/* Mod tablesize */	e = table[hashval];		/* initial element */	laste = table[hashval];	while(TRUE)		if(e == NULL)		/* No - table[hashval] == NULL */		{			/*    or end of linked list    */			if((e = (struct entry *)					calloc(1,sizeof(struct entry))) == NULL)				fatal("Cannot allocate memory");			if((e->name = (char *)					calloc(strlen(s)+1,sizeof(*s))) == NULL)				fatal("Cannot allocate memory");			strcpy(e->name,s);			e->next = NULL;			if(!table[hashval])				table[hashval] = e;			else				laste->next = e;			break;		}#define equstr(a,b) ((a)[0] == (b)[0] ? strcmp((a),(b)) : 1)		else if((i=equstr(e->name,s)) == 0)			break;		/* e points to entry */		else if(i>0)		{			/* create entry  and link */			if((newe=(struct entry *)				calloc(1, sizeof(struct entry))) == NULL)				fatal("Cannot allocate memory");			if((newe->name=calloc(strlen(s)+1,sizeof(*s)))==NULL)				fatal("Cannot allocate memory");			strcpy(newe->name,s);			newe->next = e;			if(laste == table[hashval])				table[hashval] = newe;			else				laste->next = newe;			e = newe;	/* set up e for return value */			break;		}		else {			laste = e;			e = e->next;		}	return(e->name);#else SYSV	register char *t,*t0;	if ( (t = t0 = calloc(strlen(s)+1,sizeof(char))) == NULL)		fatal("out of memory");	while (*t++ = *s++);	return(t0);#endif SYSV}CHARSTARconcat(a,b,c)   /* c = concatenation of a and b */register CHARSTAR a, b;register CHARSTAR c;{	register CHARSTAR t;	t = c;	while(*t = *a++) t++;	while(*t++ = *b++);	return(c);}suffix(a,b,p)  /* is b the suffix of a?  if so, set p = prefix */register CHARSTAR a, b, p;{	register CHARSTAR a0, b0;	a0 = a;	b0 = b;	if(!a || !b)		return(0);	while(*a++);	while(*b++);	if( (a-a0) < (b-b0) )		return(0);	while(b>b0)		if(*--a != *--b)			return(0);	while(a0<a)		*p++ = *a0++;	*p = CNULL;	return(1);}/* this is now a macro calling private calloc -- rr int * intalloc(n)register int n;{	register INTSTAR p;	if( p = (int *) calloc(1,n) )		return(p);	fprintf(stderr,"out of memory");	fatal("out of memory");}*//* copy string a into b, substituting for arguments */extern NAMEBLOCK cur_name;CHARSTARsubst(a,b)register CHARSTAR a, b;{	register CHARSTAR s;	static depth=0;	char vname[100];	char closer;	if(++depth > 100)		fatal("infinitely recursive macro?");	if(a!=0)	{		while(*a)		{			if(*a != DOLLAR)				*b++ = *a++;			else if(*++a==CNULL || *a==DOLLAR)				*b++ = *a++;			else			{				s = vname;				if( *a==LPAREN || *a==LCURLY )				{					closer=(*a==LPAREN ? RPAREN : RCURLY);					++a;					while(*a == BLANK)						++a;					while(	*a!=BLANK  &&					    *a!=closer &&					    *a!=CNULL)						*s++ = *a++;					while(*a!=closer && *a!=CNULL)						++a;					if(*a == closer)						++a;				}				else					*s++ = *a++;				*s = CNULL;				if(amatch(&vname[0], "*:*=*"))					b = colontrans(b, vname);				else if(any("@*<%?", vname[0]) && vname[1])					b = dftrans(b, vname);				else					b = straightrans(b, vname);				s++;			}		}	}	*b = CNULL;	--depth;	return(b);}/* *	Translate the $(name:*=*) type things. */CHARSTARcolontrans(b, vname)register CHARSTAR b, vname;{	register CHARSTAR p;	register CHARSTAR q = 0;	char dftype = 0;	register CHARSTAR pcolon;	register VARBLOCK vbp;	for(p = vname; *p && *p != KOLON; p++);	pcolon = p;	*pcolon = CNULL;	if(any("@*<%?", vname[0]))	{		dftype = vname[1];		vname[1] = CNULL;	}	if((vbp = srchvar(vname)) == NULL)		return(b);	p = vbp->varval;	if(dftype)	{		if((q = calloc(strlen(p)+2,1)) == NULL)			fatal("Cannot alloc mem");		do_df(q, p, vname[1]);		/* D/F trans gets smaller */		p = q;	}	if(p && *p)		b = do_colon(b, p, pcolon+1);	*pcolon = KOLON;	if(dftype)		vname[1] = dftype;	if(q)		cfree(q);	return(b);}/* *	Translate the $(name:*=*) type things. */CHARSTARdo_colon(to, from, trans)register CHARSTAR to, from, trans;{	register int i;	register CHARSTAR  p;	register int leftlen;	int len;	char left[30], right[70];	char buf[128];	CHARSTAR pbuf;	int lwig = 0;	int rwig = 0;	/*	 * Mark off the name (up to colon), the from expression (up to '='),	 * and the to expresion (up to CNULL).	 */	i = 0;	while(*trans != EQUALS)		left[i++] = *trans++;	if(left[i-1] == WIGGLE)	{		lwig++;		--i;	}	left[i] = CNULL;	leftlen = i;	i = 0;	while(*++trans)		right[i++] = *trans;	if(right[i-1] == WIGGLE)	{		rwig++;		--i;	}	right[i] = CNULL;	/*	 *	Now, tanslate.	 */	for(; len=getword(from,buf); from += len)	{		pbuf = buf;		if((i = sindex(pbuf, left)) >= 0 && pbuf[i+leftlen] == CNULL &&		    (lwig?((p=sdot(pbuf))!=(char *)0):1) )		{			pbuf[i] = CNULL;			if(!lwig && rwig)				trysccs(pbuf);			else if(lwig && !rwig)				strshift(p, -2);			catstr(to, pbuf);			catstr(to, right);		}		else		{			catstr(to, pbuf);		}	}	return(to);}getword(from, buf)register CHARSTAR from;register CHARSTAR buf;{	register int i = 0;	if(*from == TAB || *from == BLANK)	{		while(*from == TAB || *from == BLANK)		{			*buf++ = *from++;			++i;		}		goto out;	}	while(*from && *from != TAB && *from != BLANK)	{		*buf++ = *from++;		++i;	}out:	*buf = CNULL;	return(i);}/* *	Do the $(@D) type translations. */CHARSTARdftrans(b, vname)register CHARSTAR b, vname;{	register char c1;	register VARBLOCK vbp;	c1 = vname[1];	vname[1] = CNULL;	vbp = srchvar(vname);	vname[1] = c1;	if(vbp != 0 && *vbp->varval != 0)		b = do_df(b, vbp->varval, c1);	return(b);}#define lastslash(a)		strrchr( (a) , SLASH )CHARSTARdo_df(b, str, type)register CHARSTAR b;register CHARSTAR str;char type;{	register CHARSTAR p;	register int i;	char buf[128];	*b = CNULL;	for(; (i=getword(str, buf)); str += i)	{		if(buf[0] == BLANK || buf[0] == TAB)		{			catstr(b, buf);			continue;		}		p = lastslash(buf);		if(p)		{			*p = CNULL;			catstr(b, type=='D'?(buf[0]==CNULL?"/":buf):			p+1);			*p = SLASH;		}		else			catstr(b, type=='D'?".":buf);	}	return(b);}/* *	Standard trnaslation, nothing fancy. */CHARSTARstraightrans(b, vname)register CHARSTAR b, vname;{	register VARBLOCK vbp;	register CHAIN pchain;	register NAMEBLOCK pn;	vbp = srchvar(vname);	if( vbp != 0)	{		if(vbp->v_aflg == YES && vbp->varval)		{			pchain = (CHAIN)vbp->varval;			for(; pchain; pchain = pchain->nextchain)			{				pn = (NAMEBLOCK)pchain->datap;				if(pn->alias) {					catstr(b,pn->alias);				}				else {					catstr(b,pn->namep);				}				*b++ = BLANK;			}			vbp->used = YES;		}		else if(*vbp->varval)		{			b = subst(vbp->varval, b);			vbp->used = YES;		}	}	return(b);}/* copy s into t, return the location of the next free character in s */CHARSTARcopstr(s, t)register CHARSTAR s, t;{	if(t == 0)		return(s);	while (*t)		*s++ = *t++;	*s = CNULL;	return(s);}setvar(v,s)register CHARSTAR v, s;{	register VARBLOCK p;	p = srchvar(v);	if(p == 0)	{		p = varptr(v);	}	s = s?s:Nullstr;	if (p->noreset == NO)	{		if(IS_ON(EXPORT))			p->envflg = YES;		p->varval = s;		if(IS_ON(INARGS) || IS_ON(ENVOVER))			p->noreset = YES;		else			p->noreset = NO;		if(IS_ON(DBUG)) {			printf(		"setvar: %s = %s noreset = %d envflg = %d Mflags = 0%o\n",			v, p->varval, p->noreset, p->envflg, Mflags);		if(p->used && !amatch(v, "[@*<?!%]") )		    fprintf(stderr, "Warning: %s changed after being used\n",v);		}	}}eqsign(a)register CHARSTAR a;{	register CHARSTAR p;	for(p = ":;=$\n\t"; *p; p++)		if(any(a, *p))		{			callyacc(a);			return(YES);		}	return(NO);}VARBLOCKvarptr(v)register CHARSTAR v;{	register VARBLOCK vp;

⌨️ 快捷键说明

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