misc.c

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

C
1,261
字号
	if((vp = srchvar(v)) != 0)		return(vp);	vp = ALLOC(varblock);	vp->nextvar = firstvar;	firstvar = vp;	vp->varname = copys(v);	vp->varval = Nullstr;	return(vp);}VARBLOCKsrchvar(vname)register CHARSTAR vname;{	register VARBLOCK vp;	for(vp=firstvar; vp != 0 ; vp = vp->nextvar)		if(equal(vname, vp->varname))			return(vp);	return(NO);}/*VARARGS*/fatal1(s,t1,t2,t3)CHARSTAR s;{	char buf[100];	sprintf(buf, s, t1,t2,t3);	fatal(buf);}fatal(s)CHARSTAR s;{	if(s)		fprintf(stderr, "Make: %s.  Stop.\n", s);	else		fprintf(stderr, "\nStop.\n");#ifdef unix	mexit(1);#endif#ifdef gcos	mexit(0);#endif}yyerror(s)CHARSTAR s;{	char buf[50];	extern int yylineno;	sprintf(buf, "line %d: %s", yylineno, s);	fatal(buf);}CHAINappendq(head,tail)register CHAIN head;register CHARSTAR tail;{	register CHAIN p;	p = ALLOC(chain);	p->datap = tail;	while(head->nextchain)		head = head->nextchain;	head->nextchain = p;}CHARSTARmkqlist(p)register CHAIN p;{	register CHARSTAR qbufp, s;	static char qbuf[OUTMAX];	qbufp = qbuf;	for( ; p ; p = p->nextchain)	{		s = p->datap;		if(qbufp != qbuf)			*qbufp++ = BLANK;		if(qbufp+strlen(s) > &qbuf[OUTMAX-3])		{			fprintf(stderr, "$? list too long\n");			break;		}		while (*s)			*qbufp++ = *s++;	}	*qbufp = CNULL;	return(qbuf);}sindex(s1,s2)register CHARSTAR s1;register CHARSTAR s2;{	register CHARSTAR p1;	register CHARSTAR p2;	register int flag;	register int ii;	p1 = s1;	p2 = s2;	flag = -1;	for(ii = 0; ; ii++)	{		while(*p1 == *p2)		{			if(flag < 0)				flag = ii;			if(*p1++ == CNULL)				return(flag);			p2++;		}		if(*p2 == CNULL)			return(flag);		if(flag >= 0)		{			flag = -1;			p2 = s2;		}		if(*s1++ == CNULL)			return(flag);		p1 = s1;	}}#include "sys/types.h"#include "sys/stat.h"/* *	findfl(name)	(like execvp, but does path search and finds files) */static char fname[128];CHARSTAR execat();CHARSTARfindfl(name)register CHARSTAR name;{	register CHARSTAR p;	register VARBLOCK cp;	if(name[0] == SLASH)		return(name);	cp = varptr("VPATH");	if(*cp->varval == 0)		p = ":";	else		p = cp->varval;	do	    {		p = execat(p, name, fname);		if(access(fname, 4) == 0)			return(fname);	} 	while (p);	return((CHARSTAR )-1);}CHARSTARexecat(s1, s2, si)register CHARSTAR s1, s2;register CHARSTAR si;{	register CHARSTAR s;	s = si;	while (*s1 && *s1 != KOLON && *s1 != MINUS)		*s++ = *s1++;	if (si != s)		*s++ = SLASH;	while (*s2)		*s++ = *s2++;	*s = CNULL;	return(*s1? ++s1: 0);}/* *	change xx to s.xx or /x/y/z to /x/y/s.z */CHARSTARtrysccs(str)register CHARSTAR str;{	register CHARSTAR sstr;	register int i = 2;	sstr = str;	for(; *str; str++);	str[2] = CNULL;	str--;	for(;str >= sstr; str--)	{		if(*str == SLASH)			if(i == 2)			{				i = 0;				*(str+2) = DOT;				*(str+1) = 's';			}		*(str+i) = *str;	}	if(i == 2)	{		*(str+2) = DOT;		*(str+1) = 's';	}	return(sstr);}is_sccs(p)register CHARSTAR p;{#define ESS 's'	if (*p == ESS && *(p+1) == DOT) return(YES);	for(p++;*p;p++)		if(*p == SLASH && *(p+1) == ESS && *(p+2) == DOT) return(YES);	return(NO);}CHARSTARsdot(p)register char *p;{	if (*p == ESS && *(p+1) == DOT) return(p);	for(p++;*p;p++)		if(*p == SLASH && *(p+1) == ESS && *(p+2) == DOT) return(p);	return(NULL);}/* *	change pfx to /xxx/yy/*zz.* or *zz.* */CHARSTARaddstars(pfx)register CHARSTAR pfx;{	register CHARSTAR p1, p2;	for(p1 = pfx; *p1; p1++);	p2 = p1 + 3;			/* 3 characters, '*', '.', and '*'. */	p1--;	*p2-- = CNULL;	*p2-- = STAR;	*p2-- = DOT;	while(p1 >= pfx)	{		if(*p1 == SLASH)		{			*p2 = STAR;			return(pfx);		}		*p2-- = *p1--;	}	*p2 = STAR;	return(p2);}#define NENV	300extern CHARSTAR *environ;/* *	This routine is called just before an exec. */setenv(){	register CHARSTAR *ea;	register int nenv = 0;	register CHARSTAR p;	register CHARSTAR *es;	register VARBLOCK vp;	register int length;	if(firstvar == 0)		return;	es=ea=(CHARSTAR *)calloc(NENV, sizeof *ea);	if(es == NULL)		fatal("Cannot alloc mem for envp.");	for(vp=firstvar; vp != 0; vp=vp->nextvar)		if(vp->envflg)		{			if(++nenv >= NENV)				fatal("Too many env parameters.");			length = strlen(vp->varname) + strlen(vp->varval) + 2;			if((*ea = calloc(length, sizeof **ea)) == NULL)				fatal("Cannot alloc mem for env.");			p = *ea++;			catstr(p,vp->varname);			*p++ = '=';			catstr(p,vp->varval);		}	*ea = 0;	if(nenv > 0)		environ=es;	if(IS_ON(DBUG))		printf("nenv = %d\n", nenv);}/* *	Called in main *	If a string like "CC=" occurs then CC is not put in environment. *	This is because there is no good way to remove a variable *	from the environment within the shell. *	When in posix mode always ignore value of SHELL envir var. */readenv(){	register CHARSTAR *ea;	register CHARSTAR p;	ea=environ;	for(;*ea; ea++)	{		for(p = *ea; *p && *p != EQUALS; p++);		if(*p == EQUALS)			if(*(p+1)) {				if(sysvmode == POSIX_ON){				    if(strncmp(*ea,"SHELL=",6))					eqsign(*ea);				}				else				    eqsign(*ea);			}	}}sccstrip(pstr)register CHARSTAR pstr;{	register CHARSTAR p2;	register CHARSTAR sstr;	sstr = pstr;	for(; *pstr ; pstr++)		if(*pstr == RCURLY)		{			if(isdigit(pstr[1]) && pstr!=sstr && pstr[-1] != DOLLAR)			{				for(p2 = pstr; *p2 && (*p2 != LCURLY); p2++);				if(*p2 == CNULL) break;				strshift(pstr, -(int)(p2-pstr+1) );			}		}}/* *	Shift a string `pstr' count places. negative is left, pos is right *	Negative shifts cause char's at front to be lost. *	Positive shifts assume enough space! */CHARSTARstrshift(pstr, count)register CHARSTAR pstr;register int count;{	register CHARSTAR sstr;	sstr = pstr;	if(count < 0)	{		for(count = -count; *pstr=pstr[count]; pstr++);		*pstr = 0;		return(sstr);	}	for(; *pstr; pstr++);	do	    {		pstr[count] = *pstr;	} 	while (pstr--, count--);	return(sstr);}/* *	execlp(name, arg,...,0)	(like execl, but does path search) *	execvp(name, argv)	(like execv, but does path search) */#include <errno.h>#define	NULL	0CHARSTAR execat();extern	errno;execlp(name, argv)CHARSTAR name, argv;{	return(execvp(name, &argv));}execvp(name, argv)CHARSTAR name, *argv;{	register etxtbsy = 1;	register eacces = 0;	register CHARSTAR cp;	register CHARSTAR pathstr;	register CHARSTAR shell;#if 0	char fname[128];#endif 0	pathstr = varptr("PATH")->varval;	if(pathstr == 0 || *pathstr == CNULL)		pathstr = ":/bin:/usr/bin";	shell = varptr("SHELL")->varval;	if(shell == 0 || *shell == CNULL || sysvmode==0)		shell = SHELLCOM;	cp = any(name, SLASH)? "": pathstr;	do	    {		cp = execat(cp, name, fname);retry:		execv(fname, argv);		switch(errno)		{		case ENOEXEC:			*argv = fname;			*--argv = "sh";			execv(shell, argv);			return(-1);		case ETXTBSY:			if (++etxtbsy > 5)				return(-1);			sleep(etxtbsy);			goto retry;		case EACCES:			eacces++;			break;		case ENOMEM:		case E2BIG:			return(-1);		}	} 	while (cp);	if (eacces)		errno = EACCES;	return(-1);}/* *	get() does an SCCS get on the file ssfile. *	For the get command, get() uses the value of the variable "GET". *	If ssfile has a slash in it, get() does a "chdir" to the appropriate *	directory if the cdflag is set to CD. This assures *	the program finds the ssfile where it belongs when necessary. *	If the rlse string variable is set, get() uses it in the *	get command sequence. *	Thus a possible sequence is: *		set -x; *		cd ../sys/head; *		get -r2.3.4.5 s.stdio.h * *//* *	The gothead and gotf structures are used to remember *	the names of the files `make' automatically gets so *	`make' can remove them upon exit. */GOTHEAD gotfiles;get(ssfile, cdflag, rlse)register CHARSTAR ssfile;register int cdflag;register CHARSTAR rlse;{	register CHARSTAR pr;	register CHARSTAR pr1;	char gbuf[128];	char sfile[128];	register int retval;	GOTF gf;	pr = sfile;	strcpy(pr, ssfile);	if(!sdot(sfile))		trysccs(sfile);	if(access(sfile, 4) != 0 && IS_OFF(GET))		return(NO);	pr = gbuf;	if(IS_OFF(SIL))		catstr(pr, "set -x;\n");	if(cdflag == CD)		if(any(sfile, SLASH))		{			catstr(pr, "cd ");			for(pr1 = sfile; *pr1; pr1++);			while(*pr1 != SLASH)				pr1--;			*pr1 = CNULL;			catstr(pr, sfile);			catstr(pr, ";\n");			*pr1 = SLASH;		}	catstr(pr, varptr("GET")->varval);	*pr++ = ' ';	catstr(pr, varptr("GFLAGS")->varval);	*pr++ = ' ';	pr1 = rlse;	if(pr1 != NULL && pr1[0] != CNULL)	{		if(pr1[0] != MINUS)	/* RELEASE doesn't have '-r' */			catstr(pr, "-r");		catstr(pr, pr1);		*pr++ = ' ';	}	strcpy(pr, sfile);	/*	 *	exit codes are opposite of error codes so do the following:	 */	retval = (system(gbuf) == 0) ? YES : NO ;	if(retval == YES)	{		if(gotfiles == 0)		{			gotfiles = ALLOC(gothead);			gf = (GOTF)gotfiles;			gotfiles->gnextp = 0;			gotfiles->endp = (GOTF)gotfiles;		}		else		{			gf = gotfiles->endp;			gf->gnextp = ALLOC(gotf);			gf = gf->gnextp;			gf->gnextp = 0;		}		gf->gnamep = copys(sfile+2);	/* `+2' skips `s.' */		gotfiles->endp = gf;	}	return(retval);}/* *	subroutine to actually remove to gotten files. */rm_gots(){	register GOTF gf;	if(IS_ON(GF_KEEP))		return;	for(gf = (GOTF)gotfiles; gf ; gf=gf->gnextp)		if(gf->gnamep)		{			if(IS_ON(DBUG))printf("rm_got: %s\n", gf->gnamep);			unlink(gf->gnamep);		}}callyacc(str)register CHARSTAR str;{	CHARSTAR lines[2];	FILE *finsave;	CHARSTAR *lpsave;	finsave = fin;	lpsave = linesptr;	fin = 0;	lines[0] = str;	lines[1] = 0;	linesptr = lines;	yyparse();	fin = finsave;	linesptr = lpsave;}/* *	exit routine for removing the files `make' automatically *	got. */mexit(arg){	rm_gots();	if(IS_ON(MEMMAP))	{		prtmem();	}	if(IS_ON(DBUG)) {		char pathname[MAXPATHLEN];		if(getwd(pathname) == 0) {			fprintf(stderr,				"error trying to get current working directory, %s\n",																  pathname);		} else {			printf("Current working directory on exit from make is %s\n", pathname);		}	}	exit(arg);}

⌨️ 快捷键说明

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