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

📄 run.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
{	int i;	Cell *x, *y;	Awkfloat j;	x = execute(a[0]);	y = execute(a[1]);	if (x->tval&NUM && y->tval&NUM) {		j = x->fval - y->fval;		i = j<0? -1: (j>0? 1: 0);	} else {		i = strcmp(getsval(x), getsval(y));	}	tempfree(x);	tempfree(y);	switch (n) {	case LT:	if (i<0) return(True);			else return(False);	case LE:	if (i<=0) return(True);			else return(False);	case NE:	if (i!=0) return(True);			else return(False);	case EQ:	if (i == 0) return(True);			else return(False);	case GE:	if (i>=0) return(True);			else return(False);	case GT:	if (i>0) return(True);			else return(False);	default:	/* can't happen */		FATAL("unknown relational operator %d", n);	}	return 0;	/*NOTREACHED*/}void tfree(Cell *a)	/* free a tempcell */{	if (freeable(a)) {		   dprintf( ("freeing %s %s %o\n", a->nval, a->sval, a->tval) );		xfree(a->sval);	}	if (a == tmps)		FATAL("tempcell list is curdled");	a->cnext = tmps;	tmps = a;}Cell *gettemp(void)	/* get a tempcell */{	int i;	Cell *x;	if (!tmps) {		tmps = (Cell *) calloc(100, sizeof(Cell));		if (!tmps)			FATAL("out of space for temporaries");		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] ) */{	Cell *x;	int m;	char *s;	x = execute(a[0]);	m = (int) getfval(x);	if (m == 0 && !is_number(s = getsval(x)))	/* suspicion! */		FATAL("illegal field $(%s), name \"%s\"", s, x->nval);		/* BUG: can x->nval ever be null??? */	tempfree(x);	x = fieldadr(m);	x->ctype = OCELL;	/* BUG?  why are these needed? */	x->csub = CFLD;	return(x);}Cell *substr(Node **a, int nnn)		/* substr(a[0], a[1], a[2]) */{	int k, m, n;	char *s, *p;	int temp;	Cell *x, *y, *z = 0;	x = execute(a[0]);	y = execute(a[1]);	if (a[2] != 0)		z = execute(a[2]);	s = getsval(x);	k = countposn(s, strlen(s)) + 1;	if (k <= 1) {		tempfree(x);		tempfree(y);		if (a[2] != 0)			tempfree(z);		x = gettemp();		setsval(x, "");		return(x);	}	m = (int) getfval(y);	if (m <= 0)		m = 1;	else if (m > k)		m = k;	tempfree(y);	if (a[2] != 0) {		n = (int) 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();	while (*s && --m)		 s += mblen(s, k);	for (p = s; *p && n--; p += mblen(p, k))			;	temp = *p;	/* with thanks to John Linderman */	*p = '\0';	setsval(y, s);	*p = temp;	tempfree(x);	return(y);}Cell *sindex(Node **a, int nnn)		/* index(a[0], a[1]) */{	Cell *x, *y, *z;	char *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) countposn(s1, p1-s1) + 1;	/* origin 1 */			break;		}	}	tempfree(x);	tempfree(y);	setfval(z, v);	return(z);}#define	MAXNUMSIZE	50int format(char **pbuf, int *pbufsize, char *s, Node *a)	/* printf-like conversions */{	char *fmt;	char *p, *t, *os;	Cell *x;	int flag = 0, n;	int fmtwd; /* format width */	int fmtsz = recsize;	char *buf = *pbuf;	int bufsize = *pbufsize;	os = s;	p = buf;	if ((fmt = (char *) malloc(fmtsz)) == NULL)		FATAL("out of memory in format()");	while (*s) {		adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format");		if (*s != '%') {			*p++ = *s++;			continue;		}		if (*(s+1) == '%') {			*p++ = '%';			s += 2;			continue;		}		/* have to be real careful in case this is a huge number, eg, %100000d */		fmtwd = atoi(s+1);		if (fmtwd < 0)			fmtwd = -fmtwd;		adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");		for (t = fmt; (*t++ = *s) != '\0'; s++) {			if (!adjbuf(&fmt, &fmtsz, MAXNUMSIZE+1+t-fmt, recsize, &t, 0))				FATAL("format item %.30s... ran format() out of memory", os);			if (isalpha(*s) && *s != 'l' && *s != 'h' && *s != 'L')				break;	/* the ansi panoply */			if (*s == '*') {				x = execute(a);				a = a->nnext;				sprintf(t-1, "%d", fmtwd=(int) getfval(x));				if (fmtwd < 0)					fmtwd = -fmtwd;				adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");				t = fmt + strlen(fmt);				tempfree(x);			}		}		*t = '\0';		if (fmtwd < 0)			fmtwd = -fmtwd;		adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");		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:			WARNING("weird printf conversion %s", fmt);			flag = 0;			break;		}		if (a == NULL)			FATAL("not enough args in printf(%s)", os);		x = execute(a);		a = a->nnext;		n = MAXNUMSIZE;		if (fmtwd > n)			n = fmtwd;		adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format");		switch (flag) {		case 0:	sprintf(p, "%s", fmt);	/* unknown, so dump it too */			t = getsval(x);			n = strlen(t);			if (fmtwd > n)				n = fmtwd;			adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format");			p += strlen(p);			sprintf(p, "%s", t);			break;		case 1:	sprintf(p, fmt, getfval(x)); break;		case 2:	sprintf(p, fmt, (long) getfval(x)); break;		case 3:	sprintf(p, fmt, (int) getfval(x)); break;		case 4:			t = getsval(x);			n = strlen(t);			if (fmtwd > n)				n = fmtwd;			if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, 0))				FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t);			sprintf(p, fmt, t);			break;		case 5:			if (isnum(x)) {				if (getfval(x))					sprintf(p, fmt, (int) getfval(x));				else{					*p++ = '\0';					*p = '\0';				}			} else				sprintf(p, fmt, getsval(x)[0]);			break;		}		tempfree(x);		p += strlen(p);		s++;	}	*p = '\0';	free(fmt);	for ( ; a; a = a->nnext)		/* evaluate any remaining args */		execute(a);	*pbuf = buf;	*pbufsize = bufsize;	return p - buf;}Cell *awksprintf(Node **a, int n)		/* sprintf(a[0]) */{	Cell *x;	Node *y;	char *buf;	int bufsz=3*recsize;	if ((buf = (char *) malloc(bufsz)) == NULL)		FATAL("out of memory in awksprintf");	y = a[0]->nnext;	x = execute(a[0]);	if (format(&buf, &bufsz, getsval(x), y) == -1)		FATAL("sprintf string %.30s... too long.  can't happen.", buf);	tempfree(x);	x = gettemp();	x->sval = buf;	x->tval = STR;	return(x);}Cell *awkprintf(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;	Cell *x;	Node *y;	char *buf;	int len;	int bufsz=3*recsize;	if ((buf = (char *) malloc(bufsz)) == NULL)		FATAL("out of memory in awkprintf");	y = a[0]->nnext;	x = execute(a[0]);	if ((len = format(&buf, &bufsz, getsval(x), y)) == -1)		FATAL("printf string %.30s... too long.  can't happen.", buf);	tempfree(x);	if (a[1] == NULL) {		/* fputs(buf, stdout); */		fwrite(buf, len, 1, stdout);		if (ferror(stdout))			FATAL("write error on stdout");	} else {		fp = redirect(ptoi(a[1]), a[2]);		/* fputs(buf, fp); */		fwrite(buf, len, 1, fp);		fflush(fp);		if (ferror(fp))			FATAL("write error on %s", filename(fp));	}	free(buf);	return(True);}Cell *arith(Node **a, int n)	/* a[0] + a[1], etc.  also -a[0] */{	Awkfloat i, j = 0;	double v;	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)			FATAL("division by zero");		i /= j;		break;	case MOD:		if (j == 0)			FATAL("division by zero in mod");		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 */		FATAL("illegal arithmetic operator %d", n);	}	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. */{	Cell *x, *z;	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. */	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 (isstr(y))			setsval(x, getsval(y));		else if (isnum(y))			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)			FATAL("division by zero in /=");		xf /= yf;		break;	case MODEQ:		if (yf == 0)			FATAL("division by zero in %%=");		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:		FATAL("illegal assignment operator %d", n);		break;	}	tempfree(y);	setfval(x, xf);	return(x);}Cell *cat(Node **a, int q)	/* a[0] cat a[1] */{	Cell *x, *y, *z;	int n1, n2;	char *s;	x = execute(a[0]);	y = execute(a[1]);	getsval(x);	getsval(y);	n1 = strlen(x->sval);	n2 = strlen(y->sval);	s = (char *) malloc(n1 + n2 + 1);	if (s == NULL)		FATAL("out of space concatenating %.15s... and %.15s...",			x->sval, y->sval);	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] } */{	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] } */{	Cell *x;	int pair;	pair = ptoi(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 = 0, *y, *ap;	char *s;	int sep;	char *t, temp, num[50], *fs = 0;	int n, tempstat, arg3type;	y = execute(a[0]);	/* source string */	s = getsval(y);	arg3type = ptoi(a[3]);	if (a[2] == 0)		/* fs string */		fs = *FS;	else if (arg3type == STRING) {	/* split(str,arr,"string") */		x = execute(a[2]);		fs = getsval(x);	} else if (arg3type == REGEXPR)		fs = "(regexpr)";	/* split(str,arr,/regexpr/) */	else		FATAL("illegal type of split");	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 = (char *) makesymtab(NSYMTAB);	n = 0;	if ((*s != '\0' && strlen(fs) > 1) || arg3type == REGEXPR) {	/* reg expr */		void *p;		if (arg3type == REGEXPR) {	/* it's ready already */			p = (void *) a[2];		} else {			p = compre(fs);		}		t = s;		if (nematch(p,s,t)) {			do {				n++;				sprintf(num, "%d", n);				temp = *patbeg;				*patbeg = '\0';				if (is_number(t))					setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);				else					setsymtab(num, t, 0.0, STR, (Array *) ap->sval);				*patbeg = temp;				t = patbeg + patlen;				if (t[-1] == 0 || *t == 0) {					n++;					sprintf(num, "%d", n);					setsymtab(num, "", 0.0, STR, (Array *) ap->sval);					goto spdone;				}			} while (nematch(p,s,t));		}		n++;		sprintf(num, "%d", n);		if (is_number(t))			setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);		else			setsymtab(num, t, 0.0, STR, (Array *) ap->sval);  spdone:		p = NULL;	} else if (sep == ' ') {		for (n = 0; ; ) {			while (*s == ' ' || *s == '\t' || *s == '\n')				s++;			if (*s == 0)				break;			n++;			t = s;

⌨️ 快捷键说明

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