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

📄 run.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
void tfree(Cell *a)	/* free a tempcell */{	if (freeable(a))		xfree(a->sval);	if (a == tmps)		ERROR "tempcell list is curdled" FATAL;	a->cnext = tmps;	tmps = a;}Cell *gettemp(void)	/* get a tempcell */{	int i;	register Cell *x;	if (!tmps) {		tmps = (Cell *) calloc(100, sizeof(Cell));		if (!tmps)			ERROR "out of space for temporaries" FATAL;		for(i = 1; i < 100; i++)			tmps[i-1].cnext = &tmps[i];		tmps[i-1].cnext = 0;	}	x = tmps;	tmps = x->cnext;	*x = tempcell;	return(x);}Cell *indirect(Node **a, int n)	/* $( a[0] ) */{	register Cell *x;	register int m;	register uchar *s;	x = execute(a[0]);	m = getfval(x);	if (m == 0 && !is_a_number(s = getsval(x)))	/* suspicion! */		ERROR "illegal field $(%s), name \"%s\"", s, x->nval FATAL;  /* can x->nval ever be null??? */		/* ERROR "illegal field $(%s)", s FATAL; */	tempfree(x);	x = fieldadr(m);	x->ctype = OCELL;	x->csub = CFLD;	return(x);}Cell *substr(Node **a, int nnn)		/* substr(a[0], a[1], a[2]) */{	register int k, m, n;	register uchar *s;	int temp;	register Cell *x, *y, *z;	x = execute(a[0]);	y = execute(a[1]);	if (a[2] != 0)		z = execute(a[2]);	s = getsval(x);	k = strlen(s) + 1;	if (k <= 1) {		tempfree(x);		tempfree(y);		if (a[2] != 0)			tempfree(z);		x = gettemp();		setsval(x, "");		return(x);	}	m = getfval(y);	if (m <= 0)		m = 1;	else if (m > k)		m = k;	tempfree(y);	if (a[2] != 0) {		n = getfval(z);		tempfree(z);	} else		n = k - 1;	if (n < 0)		n = 0;	else if (n > k - m)		n = k - m;	dprintf( ("substr: m=%d, n=%d, s=%s\n", m, n, s) );	y = gettemp();	temp = s[n+m-1];	/* with thanks to John Linderman */	s[n+m-1] = '\0';	setsval(y, s + m - 1);	s[n+m-1] = temp;	tempfree(x);	return(y);}Cell *sindex(Node **a, int nnn)		/* index(a[0], a[1]) */{	register Cell *x, *y, *z;	register uchar *s1, *s2, *p1, *p2, *q;	Awkfloat v = 0.0;	x = execute(a[0]);	s1 = getsval(x);	y = execute(a[1]);	s2 = getsval(y);	z = gettemp();	for (p1 = s1; *p1 != '\0'; p1++) {		for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++)			;		if (*p2 == '\0') {			v = (Awkfloat) (p1 - s1 + 1);	/* origin 1 */			break;		}	}	tempfree(x);	tempfree(y);	setfval(z, v);	return(z);}format(uchar *buf, int bufsize, uchar *s, Node *a)	/* printf-like conversions */{	uchar fmt[RECSIZE];	register uchar *p, *t, *os;	register Cell *x;	int flag = 0, n;	os = s;	p = buf;	while (*s) {		if (p - buf >= bufsize)			return -1;		if (*s != '%') {			*p++ = *s++;			continue;		}		if (*(s+1) == '%') {			*p++ = '%';			s += 2;			continue;		}		for (t=fmt; (*t++ = *s) != '\0'; s++) {			if (isalpha(*s) && *s != 'l' && *s != 'h' && *s != 'L')				break;	/* the ansi panoply */			if (*s == '*') {				x = execute(a);				a = a->nnext;				sprintf((char *)t-1, "%d", (int) getfval(x));				t = fmt + strlen(fmt);				tempfree(x);			}		}		*t = '\0';		if (t >= fmt + sizeof(fmt))			ERROR "format item %.30s... too long", os FATAL;		switch (*s) {		case 'f': case 'e': case 'g': case 'E': case 'G':			flag = 1;			break;		case 'd': case 'i':			flag = 2;			if(*(s-1) == 'l') break;			*(t-1) = 'l';			*t = 'd';			*++t = '\0';			break;		case 'o': case 'x': case 'X': case 'u':			flag = *(s-1) == 'l' ? 2 : 3;			break;		case 's':			flag = 4;			break;		case 'c':			flag = 5;			break;		default:			ERROR "weird printf conversion %s", fmt WARNING;			flag = 0;			break;		}		if (a == NULL)			ERROR "not enough args in printf(%s)", os FATAL;		x = execute(a);		a = a->nnext;		switch (flag) {		case 0:	sprintf((char *)p, "%s", fmt);	/* unknown, so dump it too */			p += strlen(p);			sprintf((char *)p, "%s", getsval(x));			break;		case 1:	sprintf((char *)p, (char *)fmt, getfval(x)); break;		case 2:	sprintf((char *)p, (char *)fmt, (long) getfval(x)); break;		case 3:	sprintf((char *)p, (char *)fmt, (int) getfval(x)); break;		case 4:			t = getsval(x);			n = strlen(t);			if (n >= bufsize)				ERROR "huge string (%d chars) in printf %.30s...",					n, t FATAL;			sprintf((char *)p, (char *)fmt, t);			break;		case 5:			isnum(x) ? sprintf((char *)p, (char *)fmt, (int) getfval(x))				 : sprintf((char *)p, (char *)fmt, getsval(x)[0]);			break;		}		tempfree(x);		p += strlen(p);		s++;	}	*p = '\0';	for ( ; a; a = a->nnext)		/* evaluate any remaining args */		execute(a);	return 0;}Cell *asprintf(Node **a, int n)		/* sprintf(a[0]) */{	register Cell *x;	register Node *y;	uchar buf[3*RECSIZE];	y = a[0]->nnext;	x = execute(a[0]);	if (format(buf, sizeof buf, getsval(x), y) == -1)		ERROR "sprintf string %.30s... too long", buf FATAL;	tempfree(x);	x = gettemp();	x->sval = tostring(buf);	x->tval = STR;	return(x);}Cell *aprintf(Node **a, int n)		/* printf */{	/* a[0] is list of args, starting with format string */	/* a[1] is redirection operator, a[2] is redirection file */	FILE *fp;	register Cell *x;	register Node *y;	uchar buf[3*RECSIZE];	y = a[0]->nnext;	x = execute(a[0]);	if (format(buf, sizeof buf, getsval(x), y) == -1)		ERROR "printf string %.30s... too long", buf FATAL;	tempfree(x);	if (a[1] == NULL) {		fputs((char *)buf, stdout);		if (ferror(stdout))			ERROR "write error on stdout" FATAL;	} else {		fp = redirect((int)a[1], a[2]);		fputs((char *)buf, fp);		fflush(fp);		if (ferror(fp))			ERROR "write error on %s", filename(fp) FATAL;	}	return(true);}Cell *arith(Node **a, int n)	/* a[0] + a[1], etc.  also -a[0] */{	Awkfloat i, j;	double v;	register Cell *x, *y, *z;	x = execute(a[0]);	i = getfval(x);	tempfree(x);	if (n != UMINUS) {		y = execute(a[1]);		j = getfval(y);		tempfree(y);	}	z = gettemp();	switch (n) {	case ADD:		i += j;		break;	case MINUS:		i -= j;		break;	case MULT:		i *= j;		break;	case DIVIDE:		if (j == 0)			ERROR "division by zero" FATAL;		i /= j;		break;	case MOD:		if (j == 0)			ERROR "division by zero in mod" FATAL;		modf(i/j, &v);		i = i - j * v;		break;	case UMINUS:		i = -i;		break;	case POWER:		if (j >= 0 && modf(j, &v) == 0.0)	/* pos integer exponent */			i = ipow(i, (int) j);		else			i = errcheck(pow(i, j), "pow");		break;	default:	/* can't happen */		ERROR "illegal arithmetic operator %d", n FATAL;	}	setfval(z, i);	return(z);}double ipow(double x, int n)	/* x**n.  ought to be done by pow, but isn't always */{	double v;	if (n <= 0)		return 1;	v = ipow(x, n/2);	if (n % 2 == 0)		return v * v;	else		return x * v * v;}Cell *incrdecr(Node **a, int n)		/* a[0]++, etc. */{	register Cell *x, *z;	register int k;	Awkfloat xf;	x = execute(a[0]);	xf = getfval(x);	k = (n == PREINCR || n == POSTINCR) ? 1 : -1;	if (n == PREINCR || n == PREDECR) {		setfval(x, xf + k);		return(x);	}	z = gettemp();	setfval(z, xf);	setfval(x, xf + k);	tempfree(x);	return(z);}Cell *assign(Node **a, int n)	/* a[0] = a[1], a[0] += a[1], etc. */{		/* this is subtle; don't muck with it. */	register Cell *x, *y;	Awkfloat xf, yf;	double v;	y = execute(a[1]);	x = execute(a[0]);	if (n == ASSIGN) {	/* ordinary assignment */		if (x == y && !(x->tval & (FLD|REC)))	/* self-assignment: */			;		/* leave alone unless it's a field */		else if ((y->tval & (STR|NUM)) == (STR|NUM)) {			setsval(x, getsval(y));			x->fval = getfval(y);			x->tval |= NUM;		}		else if (y->tval & STR)			setsval(x, getsval(y));		else if (y->tval & NUM)			setfval(x, getfval(y));		else			funnyvar(y, "read value of");		tempfree(y);		return(x);	}	xf = getfval(x);	yf = getfval(y);	switch (n) {	case ADDEQ:		xf += yf;		break;	case SUBEQ:		xf -= yf;		break;	case MULTEQ:		xf *= yf;		break;	case DIVEQ:		if (yf == 0)			ERROR "division by zero in /=" FATAL;		xf /= yf;		break;	case MODEQ:		if (yf == 0)			ERROR "division by zero in %%=" FATAL;		modf(xf/yf, &v);		xf = xf - yf * v;		break;	case POWEQ:		if (yf >= 0 && modf(yf, &v) == 0.0)	/* pos integer exponent */			xf = ipow(xf, (int) yf);		else			xf = errcheck(pow(xf, yf), "pow");		break;	default:		ERROR "illegal assignment operator %d", n FATAL;		break;	}	tempfree(y);	setfval(x, xf);	return(x);}Cell *cat(Node **a, int q)	/* a[0] cat a[1] */{	register Cell *x, *y, *z;	register int n1, n2;	register uchar *s;	x = execute(a[0]);	y = execute(a[1]);	getsval(x);	getsval(y);	n1 = strlen(x->sval);	n2 = strlen(y->sval);	s = (uchar *) malloc(n1 + n2 + 1);	if (s == NULL)		ERROR "out of space concatenating %.15s... and %.15s...",			x->sval, y->sval FATAL;	strcpy(s, x->sval);	strcpy(s+n1, y->sval);	tempfree(y);	z = gettemp();	z->sval = s;	z->tval = STR;	tempfree(x);	return(z);}Cell *pastat(Node **a, int n)	/* a[0] { a[1] } */{	register Cell *x;	if (a[0] == 0)		x = execute(a[1]);	else {		x = execute(a[0]);		if (istrue(x)) {			tempfree(x);			x = execute(a[1]);		}	}	return x;}Cell *dopa2(Node **a, int n)	/* a[0], a[1] { a[2] } */{	register Cell *x;	register int pair;	pair = (int) a[3];	if (pairstack[pair] == 0) {		x = execute(a[0]);		if (istrue(x))			pairstack[pair] = 1;		tempfree(x);	}	if (pairstack[pair] == 1) {		x = execute(a[1]);		if (istrue(x))			pairstack[pair] = 0;		tempfree(x);		x = execute(a[2]);		return(x);	}	return(false);}Cell *split(Node **a, int nnn)	/* split(a[0], a[1], a[2]); a[3] is type */{	Cell *x, *y, *ap;	register uchar *s;	register int sep;	uchar *t, temp, num[10], *fs;	int n, tempstat;	y = execute(a[0]);	/* source string */	s = getsval(y);	if (a[2] == 0)		/* fs string */		fs = *FS;	else if ((int) a[3] == STRING) {	/* split(str,arr,"string") */		x = execute(a[2]);		fs = getsval(x);	} else if ((int) a[3] == REGEXPR)		fs = (uchar*) "(regexpr)";	/* split(str,arr,/regexpr/) */	else		ERROR "illegal type of split()" FATAL;	sep = *fs;	ap = execute(a[1]);	/* array name */	freesymtab(ap);	dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs) );	ap->tval &= ~STR;	ap->tval |= ARR;	ap->sval = (uchar *) makesymtab(NSYMTAB);	n = 0;	if (*s != '\0' && strlen(fs) > 1 || (int) a[3] == REGEXPR) {	/* reg expr */		fa *pfa;		if ((int) a[3] == REGEXPR) {	/* it's ready already */			pfa = (fa *) a[2];		} else {			pfa = makedfa(fs, 1);		}		if (nematch(pfa,s)) {			tempstat = pfa->initstat;			pfa->initstat = 2;			do {				n++;				sprintf((char *)num, "%d", n);				temp = *patbeg;				*patbeg = '\0';				if (is_a_number(s))					setsymtab(num, s, atof((char *)s), STR|NUM, (Array *) ap->sval);				else					setsymtab(num, s, 0.0, STR, (Array *) ap->sval);				*patbeg = temp;				s = patbeg + patlen;				if (*(patbeg+patlen-1) == 0 || *s == 0) {					n++;					sprintf((char *)num, "%d", n);					setsymtab(num, "", 0.0, STR, (Array *) ap->sval);					pfa->initstat = tempstat;					goto spdone;				}			} while (nematch(pfa,s));		}		n++;		sprintf((char *)num, "%d", n);		if (is_a_number(s))			setsymtab(num, s, atof((char *)s), STR|NUM, (Array *) ap->sval);		else			setsymtab(num, s, 0.0, STR, (Array *) ap->sval);  spdone:		pfa = NULL;	} else if (sep == ' ') {		for (n = 0; ; ) {			while (*s == ' ' || *s == '\t' || *s == '\n')				s++;			if (*s == 0)				break;			n++;			t = s;			do				s++;			while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0');			temp = *s;			*s = '\0';			sprintf((char *)num, "%d", n);			if (is_a_number(t))				setsymtab(num, t, atof((char *)t), STR|NUM, (Array *) ap->sval);			else				setsymtab(num, t, 0.0, STR, (Array *) ap->sval);			*s = temp;			if (*s != 0)				s++;		}	} else if (*s != 0) {		for (;;) {			n++;			t = s;			while (*s != sep && *s != '\n' && *s != '\0')				s++;			temp = *s;			*s = '\0';			sprintf((char *)num, "%d", n);			if (is_a_number(t))				setsymtab(num, t, atof((char *)t), STR|NUM, (Array *) ap->sval);			else				setsymtab(num, t, 0.0, STR, (Array *) ap->sval);			*s = temp;			if (*s++ == 0)				break;		}	}	tempfree(ap);	tempfree(y);	if (a[2] != 0 && (int) a[3] == STRING)		tempfree(x);	x = gettemp();	x->tval = NUM;

⌨️ 快捷键说明

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