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

📄 run.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	x->fval = n;	return(x);}Cell *condexpr(Node **a, int n)	/* a[0] ? a[1] : a[2] */{	register Cell *x;	x = execute(a[0]);	if (istrue(x)) {		tempfree(x);		x = execute(a[1]);	} else {		tempfree(x);		x = execute(a[2]);	}	return(x);}Cell *ifstat(Node **a, int n)	/* if (a[0]) a[1]; else a[2] */{	register Cell *x;	x = execute(a[0]);	if (istrue(x)) {		tempfree(x);		x = execute(a[1]);	} else if (a[2] != 0) {		tempfree(x);		x = execute(a[2]);	}	return(x);}Cell *whilestat(Node **a, int n)	/* while (a[0]) a[1] */{	register Cell *x;	for (;;) {		x = execute(a[0]);		if (!istrue(x))			return(x);		tempfree(x);		x = execute(a[1]);		if (isbreak(x)) {			x = true;			return(x);		}		if (isnext(x) || isexit(x) || isret(x))			return(x);		tempfree(x);	}}Cell *dostat(Node **a, int n)	/* do a[0]; while(a[1]) */{	register Cell *x;	for (;;) {		x = execute(a[0]);		if (isbreak(x))			return true;		if (isnext(x) || isexit(x) || isret(x))			return(x);		tempfree(x);		x = execute(a[1]);		if (!istrue(x))			return(x);		tempfree(x);	}}Cell *forstat(Node **a, int n)	/* for (a[0]; a[1]; a[2]) a[3] */{	register Cell *x;	x = execute(a[0]);	tempfree(x);	for (;;) {		if (a[1]!=0) {			x = execute(a[1]);			if (!istrue(x)) return(x);			else tempfree(x);		}		x = execute(a[3]);		if (isbreak(x))		/* turn off break */			return true;		if (isnext(x) || isexit(x) || isret(x))			return(x);		tempfree(x);		x = execute(a[2]);		tempfree(x);	}}Cell *instat(Node **a, int n)	/* for (a[0] in a[1]) a[2] */{	register Cell *x, *vp, *arrayp, *cp, *ncp;	Array *tp;	int i;	vp = execute(a[0]);	arrayp = execute(a[1]);	if (!isarr(arrayp)) {		return true;	}	tp = (Array *) arrayp->sval;	tempfree(arrayp);	for (i = 0; i < tp->size; i++) {	/* this routine knows too much */		for (cp = tp->tab[i]; cp != NULL; cp = ncp) {			setsval(vp, cp->nval);			ncp = cp->cnext;			x = execute(a[2]);			if (isbreak(x)) {				tempfree(vp);				return true;			}			if (isnext(x) || isexit(x) || isret(x)) {				tempfree(vp);				return(x);			}			tempfree(x);		}	}	return true;}/* if someone ever wants to run over the arrays in sorted order, *//* here it is.  but it will likely run slower, not faster. *//* *int qstrcmp(p, q) *	uchar **p, **q; *{ *	return strcmp(*p, *q); *} *//*Cell *instat(Node **a, int n)	/* for (a[0] in a[1]) a[2] *//*{/*	register Cell *x, *vp, *arrayp, *cp, *ncp, *ret;/*	Array *tp;/*	int i, ne;/*#define BIGENOUGH 1000/*	uchar *elems[BIGENOUGH], **ep;/*/*	vp = execute(a[0]);/*	arrayp = execute(a[1]);/*	if (!isarr(arrayp))/*		ERROR "%s is not an array", arrayp->nval FATAL;/*	tp = (Array *) arrayp->sval;/*	tempfree(arrayp);/*	ep = elems;/*	ret = true;/*	if (tp->nelem >= BIGENOUGH)/*		ep = (uchar **) malloc(tp->nelem * sizeof(char *));/*/*	for (i = ne = 0; i < tp->size; i++)/*		for (cp = tp->tab[i]; cp != NULL; cp = cp->cnext)/*			ep[ne++] = cp->nval;/*	if (ne != tp->nelem)/*		ERROR "can't happen: lost elems %d vs. %d", ne, tp->nelem FATAL;/*	qsort(ep, ne, sizeof(char *), qstrcmp);/*	for (i = 0; i < ne; i++) {/*		setsval(vp, ep[i]);/*		x = execute(a[2]);/*		if (isbreak(x)) {/*			tempfree(vp);/*			break;/*		}/*		if (isnext(x) || isexit(x) || isret(x)) {/*			tempfree(vp);/*			ret = x;/*			break;/*		}/*		tempfree(x);/*	}/*	if (ep != elems)/*		free(ep);/*	return ret;/*}*/Cell *bltin(Node **a, int n)	/* builtin functions. a[0] is type, a[1] is arg list */{	register Cell *x, *y;	Awkfloat u;	register int t;	uchar *p, buf[RECSIZE];	Node *nextarg;	FILE *fp;	t = (int) a[0];	x = execute(a[1]);	nextarg = a[1]->nnext;	switch (t) {	case FLENGTH:		u = strlen(getsval(x)); break;	case FLOG:		u = errcheck(log(getfval(x)), "log"); break;	case FINT:		modf(getfval(x), &u); break;	case FEXP:		u = errcheck(exp(getfval(x)), "exp"); break;	case FSQRT:		u = errcheck(sqrt(getfval(x)), "sqrt"); break;	case FSIN:		u = sin(getfval(x)); break;	case FCOS:		u = cos(getfval(x)); break;	case FATAN:		if (nextarg == 0) {			ERROR "atan2 requires two arguments; returning 1.0" WARNING;			u = 1.0;		} else {			y = execute(a[1]->nnext);			u = atan2(getfval(x), getfval(y));			tempfree(y);			nextarg = nextarg->nnext;		}		break;	case FSYSTEM:		fflush(stdout);		/* in case something is buffered already */		u = (Awkfloat) system((char *)getsval(x)) / 256;   /* 256 is unix-dep */		break;	case FRAND:		/* in principle, rand() returns something in 0..RAND_MAX */		u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX;		break;	case FSRAND:		if (x->tval & REC)	/* no argument provided */			u = time((long *)0);		else			u = getfval(x);		srand((int) u); u = (int) u;		break;	case FTOUPPER:	case FTOLOWER:		strcpy(buf, getsval(x));		if (t == FTOUPPER) {			for (p = buf; *p; p++)				if (islower(*p))					*p = toupper(*p);		} else {			for (p = buf; *p; p++)				if (isupper(*p))					*p = tolower(*p);		}		tempfree(x);		x = gettemp();		setsval(x, buf);		return x;	case FFLUSH:		if ((fp = openfile(GT, getsval(x))) == NULL)			u = EOF;		else			u = fflush(fp);		break;	default:	/* can't happen */		ERROR "illegal function type %d", t FATAL;		break;	}	tempfree(x);	x = gettemp();	setfval(x, u);	if (nextarg != 0) {		ERROR "warning: function has too many arguments" WARNING;		for ( ; nextarg; nextarg = nextarg->nnext)			execute(nextarg);	}	return(x);}Cell *printstat(Node **a, int n)	/* print a[0] */{	register Node *x;	register Cell *y;	FILE *fp;	if (a[1] == 0)	/* a[1] is redirection operator, a[2] is file */		fp = stdout;	else		fp = redirect((int)a[1], a[2]);	for (x = a[0]; x != NULL; x = x->nnext) {		y = execute(x);		fputs((char *)getsval(y), fp);		tempfree(y);		if (x->nnext == NULL)			fputs((char *)*ORS, fp);		else			fputs((char *)*OFS, fp);	}	if (a[1] != 0)		fflush(fp);	if (ferror(fp))		ERROR "write error on %s", filename(fp) FATAL;	return(true);}Cell *nullproc(Node **a, int n){	n;	a;	return 0;}FILE *redirect(int a, Node *b)	/* set up all i/o redirections */{	FILE *fp;	Cell *x;	uchar *fname;	x = execute(b);	fname = getsval(x);	fp = openfile(a, fname);	if (fp == NULL)		ERROR "can't open file %s", fname FATAL;	tempfree(x);	return fp;}struct files {	FILE	*fp;	uchar	*fname;	int	mode;	/* '|', 'a', 'w' => LE/LT, GT */} files[FOPEN_MAX] ={	{ stdin,  "/dev/stdin",  LT },	/* watch out: don't free this! */	{ stdout, "/dev/stdout", GT },	{ stderr, "/dev/stderr", GT }};FILE *openfile(int a, uchar *us){	char *s = us;	register int i, m;	register FILE *fp;	if (*s == '\0')		ERROR "null file name in print or getline" FATAL;	for (i=0; i < FOPEN_MAX; i++)		if (files[i].fname && strcmp(s, files[i].fname) == 0)			if (a == files[i].mode || a==APPEND && files[i].mode==GT)				return files[i].fp;	for (i=0; i < FOPEN_MAX; i++)		if (files[i].fp == 0)			break;	if (i >= FOPEN_MAX)		ERROR "%s makes too many open files", s FATAL;	fflush(stdout);	/* force a semblance of order */	m = a;	if (a == GT) {		fp = fopen(s, "w");	} else if (a == APPEND) {		fp = fopen(s, "a");		m = GT;	/* so can mix > and >> */	} else if (a == '|') {	/* output pipe */		fp = popen(s, "w");	} else if (a == LE) {	/* input pipe */		fp = popen(s, "r");	} else if (a == LT) {	/* getline <file */		fp = strcmp(s, "-") == 0 ? stdin : fopen(s, "r");	/* "-" is stdin */	} else	/* can't happen */		ERROR "illegal redirection %d", a FATAL;	if (fp != NULL) {		files[i].fname = tostring(s);		files[i].fp = fp;		files[i].mode = m;	}	return fp;}uchar *filename(FILE *fp){	int i;	for (i = 0; i < FOPEN_MAX; i++)		if (fp == files[i].fp)			return files[i].fname;	return "???";}Cell *closefile(Node **a, int n){	register Cell *x;	int i, stat;	n;	x = execute(a[0]);	getsval(x);	for (i = 0; i < FOPEN_MAX; i++)		if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) {			if (ferror(files[i].fp))				ERROR "i/o error occurred on %s", files[i].fname WARNING;			if (files[i].mode == '|' || files[i].mode == LE)				stat = pclose(files[i].fp);			else				stat = fclose(files[i].fp);			if (stat == EOF)				ERROR "i/o error occurred closing %s", files[i].fname WARNING;			if (i > 2)	/* don't do /dev/std... */				xfree(files[i].fname);			files[i].fname = NULL;	/* watch out for ref thru this */			files[i].fp = NULL;		}	tempfree(x);	return(true);}void closeall(void){	int i, stat;	for (i = 0; i < FOPEN_MAX; i++)		if (files[i].fp) {			if (ferror(files[i].fp))				ERROR "i/o error occurred on %s", files[i].fname WARNING;			if (files[i].mode == '|' || files[i].mode == LE)				stat = pclose(files[i].fp);			else				stat = fclose(files[i].fp);			if (stat == EOF)				ERROR "i/o error occurred while closing %s", files[i].fname WARNING;		}}#define	SUBSIZE	(20 * RECSIZE)Cell *sub(Node **a, int nnn)	/* substitute command */{	register uchar *sptr, *pb, *q;	register Cell *x, *y, *result;	uchar buf[SUBSIZE], *t;	fa *pfa;	x = execute(a[3]);	/* target string */	t = getsval(x);	if (a[0] == 0)		/* 0 => a[1] is already-compiled regexpr */		pfa = (fa *) a[1];	/* regular expression */	else {		y = execute(a[1]);		pfa = makedfa(getsval(y), 1);		tempfree(y);	}	y = execute(a[2]);	/* replacement string */	result = false;	if (pmatch(pfa, t)) {		pb = buf;		sptr = t;		while (sptr < patbeg)			*pb++ = *sptr++;		sptr = getsval(y);		while (*sptr != 0 && pb < buf + SUBSIZE - 1)			if (*sptr == '\\' && *(sptr+1) == '&') {				sptr++;		/* skip \, */				*pb++ = *sptr++; /* add & */			} else if (*sptr == '&') {				sptr++;				for (q = patbeg; q < patbeg+patlen; )					*pb++ = *q++;			} else				*pb++ = *sptr++;		*pb = '\0';		if (pb >= buf + SUBSIZE)			ERROR "sub() result %30s too big", buf FATAL;		sptr = patbeg + patlen;		if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1)))			while (*pb++ = *sptr++)				;		if (pb >= buf + SUBSIZE)			ERROR "sub() result %.30s too big", buf FATAL;		setsval(x, buf);		result = true;;	}	tempfree(x);	tempfree(y);	return result;}Cell *gsub(Node **a, int nnn)	/* global substitute */{	register Cell *x, *y;	register uchar *rptr, *sptr, *t, *pb;	uchar buf[SUBSIZE];	register fa *pfa;	int mflag, tempstat, num;	mflag = 0;	/* if mflag == 0, can replace empty string */	num = 0;	x = execute(a[3]);	/* target string */	t = getsval(x);	if (a[0] == 0)		/* 0 => a[1] is already-compiled regexpr */		pfa = (fa *) a[1];	/* regular expression */	else {		y = execute(a[1]);		pfa = makedfa(getsval(y), 1);		tempfree(y);	}	y = execute(a[2]);	/* replacement string */	if (pmatch(pfa, t)) {		tempstat = pfa->initstat;		pfa->initstat = 2;		pb = buf;		rptr = getsval(y);		do {			/*			uchar *p;			int i;			printf("target string: %s, *patbeg = %o, patlen = %d\n",				t, *patbeg, patlen);			printf("	match found: ");			p=patbeg;			for (i=0; i<patlen; i++)				printf("%c", *p++);			printf("\n");			*/			if (patlen == 0 && *patbeg != 0) {	/* matched empty string */				if (mflag == 0) {	/* can replace empty */					num++;					sptr = rptr;					while (*sptr != 0 && pb < buf + SUBSIZE-1)						if (*sptr == '\\' && *(sptr+1) == '&') {							sptr++;							*pb++ = *sptr++;						} else if (*sptr == '&') {							uchar *q;							sptr++;							for (q = patbeg; q < patbeg+patlen; )								*pb++ = *q++;						} else							*pb++ = *sptr++;				}				if (*t == 0)	/* at end */					goto done;				*pb++ = *t++;				if (pb >= buf + SUBSIZE-1)					ERROR "gsub() result %.30s too big", buf FATAL;				mflag = 0;			}			else {	/* matched nonempty string */				num++;				sptr = t;				while (sptr < patbeg && pb < buf + SUBSIZE-1)					*pb++ = *sptr++;				sptr = rptr;				while (*sptr != 0 && pb < buf + SUBSIZE-1)					if (*sptr == '\\' && *(sptr+1) == '&') {						sptr++;						*pb++ = *sptr++;					} else if (*sptr == '&') {						uchar *q;						sptr++;						for (q = patbeg; q < patbeg+patlen; )							*pb++ = *q++;					} else						*pb++ = *sptr++;				t = patbeg + patlen;				if ((*(t-1) == 0) || (*t == 0))					goto done;				if (pb >= buf + SUBSIZE-1)					ERROR "gsub() result %.30s too big", buf FATAL;				mflag = 1;			}		} while (pmatch(pfa,t));		sptr = t;		while (*pb++ = *sptr++)			;	done:	if (pb >= buf + SUBSIZE-1)			ERROR "gsub() result %.30s too big", buf FATAL;		*pb = '\0';		setsval(x, buf);		pfa->initstat = tempstat;	}	tempfree(x);	tempfree(y);	x = gettemp();	x->tval = NUM;	x->fval = num;	return(x);}

⌨️ 快捷键说明

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