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

📄 run.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
			do				s++;			while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0');			temp = *s;			*s = '\0';			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);			*s = temp;			if (*s != 0)				s++;		}	} else if (sep == 0) {	/* new: split(s, a, "") => 1 char/elem */		for (n = 0; *s != 0; s++) {			char buf[2];			n++;			sprintf(num, "%d", n);			buf[0] = *s;			buf[1] = 0;			if (isdigit(buf[0]))				setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval);			else				setsymtab(num, buf, 0.0, STR, (Array *) ap->sval);		}	} else if (*s != 0) {		for (;;) {			n++;			t = s;			while (*s != sep && *s != '\n' && *s != '\0')				s++;			temp = *s;			*s = '\0';			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);			*s = temp;			if (*s++ == 0)				break;		}	}	tempfree(ap);	tempfree(y);	if (a[2] != 0 && arg3type == STRING)		tempfree(x);	x = gettemp();	x->tval = NUM;	x->fval = n;	return(x);}Cell *condexpr(Node **a, int n)	/* a[0] ? a[1] : a[2] */{	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] */{	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] */{	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]) */{	Cell *x;	for (;;) {		x = execute(a[0]);		if (isbreak(x))			return True;		if (isnext(x) || isnextfile(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] */{	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] */{	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;}Cell *bltin(Node **a, int n)	/* builtin functions. a[0] is type, a[1] is arg list */{	Cell *x, *y;	Awkfloat u;	int t;	wchar_t wc;	char *p, *buf;	char mbc[50];	Node *nextarg;	FILE *fp;	t = ptoi(a[0]);	x = execute(a[1]);	nextarg = a[1]->nnext;	switch (t) {	case FLENGTH:		p = getsval(x);		u = (Awkfloat) countposn(p, strlen(p)); 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) {			WARNING("atan2 requires two arguments; returning 1.0");			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(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 (isrec(x))	/* no argument provided */			u = time((time_t *)0);		else			u = getfval(x);		srand((unsigned int) u);		break;	case FTOUPPER:	case FTOLOWER:		buf = tostring(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);		free(buf);		return x;	case FFLUSH:		if ((fp = openfile(FFLUSH, getsval(x))) == NULL)			u = EOF;		else			u = fflush(fp);		break;	case FUTF:		wc = (int)getfval(x);		mbc[wctomb(mbc, wc)] = 0;		tempfree(x);		x = gettemp();		setsval(x, mbc);		return x;	default:	/* can't happen */		FATAL("illegal function type %d", t);		break;	}	tempfree(x);	x = gettemp();	setfval(x, u);	if (nextarg != 0) {		WARNING("warning: function has too many arguments");		for ( ; nextarg; nextarg = nextarg->nnext)			execute(nextarg);	}	return(x);}Cell *printstat(Node **a, int n)	/* print a[0] */{	int r;	Node *x;	Cell *y;	FILE *fp;	if (a[1] == 0)	/* a[1] is redirection operator, a[2] is file */		fp = stdout;	else		fp = redirect(ptoi(a[1]), a[2]);	for (x = a[0]; x != NULL; x = x->nnext) {		y = execute(x);		fputs(getsval(y), fp);		tempfree(y);		if (x->nnext == NULL)			r = fputs(*ORS, fp);		else			r = fputs(*OFS, fp);		if (r == EOF)			FATAL("write error on %s", filename(fp));	}	if (a[1] != 0)		if (fflush(fp) == EOF)			FATAL("write error on %s", filename(fp));	return(True);}Cell *nullproc(Node **a, int n){	n = n;	a = a;	return 0;}FILE *redirect(int a, Node *b)	/* set up all i/o redirections */{	FILE *fp;	Cell *x;	char *fname;	x = execute(b);	fname = getsval(x);	fp = openfile(a, fname);	if (fp == NULL)		FATAL("can't open file %s", fname);	tempfree(x);	return fp;}struct files {	FILE	*fp;	char	*fname;	int	mode;	/* '|', 'a', 'w' => LE/LT, GT */} files[FOPEN_MAX] ={	{ NULL,  "/dev/stdin",  LT },	/* watch out: don't free this! */	{ NULL, "/dev/stdout", GT },	{ NULL, "/dev/stderr", GT }};void stdinit(void)	/* in case stdin, etc., are not constants */{	files[0].fp = stdin;	files[1].fp = stdout;	files[2].fp = stderr;}FILE *openfile(int a, char *us){	char *s = us;	int i, m;	FILE *fp = 0;	if (*s == '\0')		FATAL("null file name in print or getline");	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;			if (a == FFLUSH)				return files[i].fp;		}	if (a == FFLUSH)	/* didn't find it, so don't create it! */		return NULL;	for (i=0; i < FOPEN_MAX; i++)		if (files[i].fp == 0)			break;	if (i >= FOPEN_MAX)		FATAL("%s makes too many open files", s);	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 */		FATAL("illegal redirection %d", a);	if (fp != NULL) {		files[i].fname = tostring(s);		files[i].fp = fp;		files[i].mode = m;	}	return fp;}char *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){	Cell *x;	int i, stat;	n = 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))				WARNING( "i/o error occurred on %s", files[i].fname );			if (files[i].mode == '|' || files[i].mode == LE)				stat = pclose(files[i].fp);			else				stat = fclose(files[i].fp);			if (stat == EOF)				WARNING( "i/o error occurred closing %s", files[i].fname );			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))				WARNING( "i/o error occurred on %s", files[i].fname );			if (files[i].mode == '|' || files[i].mode == LE)				stat = pclose(files[i].fp);			else				stat = fclose(files[i].fp);			if (stat == EOF)				WARNING( "i/o error occurred while closing %s", files[i].fname );		}}void backsub(char **pb_ptr, char **sptr_ptr);Cell *sub(Node **a, int nnn)	/* substitute command */{	char *sptr, *pb, *q;	Cell *x, *y, *result;	char *t, *buf;	void *p;	int bufsz = recsize;	if ((buf = (char *) malloc(bufsz)) == NULL)		FATAL("out of memory in sub");	x = execute(a[3]);	/* target string */	t = getsval(x);	if (a[0] == 0)		/* 0 => a[1] is already-compiled regexpr */		p = (void *) a[1];	/* regular expression */	else {		y = execute(a[1]);		p = compre(getsval(y));		tempfree(y);	}	y = execute(a[2]);	/* replacement string */	result = False;	if (pmatch(p, t, t)) {		sptr = t;		adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub");		pb = buf;		while (sptr < patbeg)			*pb++ = *sptr++;		sptr = getsval(y);		while (*sptr != 0) {			adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "sub");			if (*sptr == '\\') {				backsub(&pb, &sptr);			} else if (*sptr == '&') {				sptr++;				adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "sub");				for (q = patbeg; q < patbeg+patlen; )					*pb++ = *q++;			} else				*pb++ = *sptr++;		}		*pb = '\0';		if (pb > buf + bufsz)			FATAL("sub result1 %.30s too big; can't happen", buf);		sptr = patbeg + patlen;		if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) {			adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "sub");			while ((*pb++ = *sptr++) != 0)				;		}		if (pb > buf + bufsz)			FATAL("sub result2 %.30s too big; can't happen", buf);		setsval(x, buf);	/* BUG: should be able to avoid copy */		result = True;;	}	tempfree(x);	tempfree(y);	free(buf);	return result;}Cell *gsub(Node **a, int nnn)	/* global substitute */{	Cell *x, *y;	char *rptr, *sptr, *t, *pb, *c;	char *buf;	void *p;	int mflag, num;	int bufsz = recsize;	if ((buf = (char *)malloc(bufsz)) == NULL)		FATAL("out of memory in gsub");	mflag = 0;	/* if mflag == 0, can replace empty string */	num = 0;	x = execute(a[3]);	/* target string */	c = t = getsval(x);	if (a[0] == 0)		/* 0 => a[1] is already-compiled regexpr */		p = (void *) a[1];	/* regular expression */	else {		y = execute(a[1]);		p = compre(getsval(y));		tempfree(y);	}	y = execute(a[2]);	/* replacement string */	if (pmatch(p, t, c)) {		pb = buf;		rptr = getsval(y);		do {			if (patlen == 0 && *patbeg != 0) {	/* matched empty string */				if (mflag == 0) {	/* can replace empty */					num++;					sptr = rptr;					while (*sptr != 0) {						adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub");						if (*sptr == '\\') {							backsub(&pb, &sptr);						} else if (*sptr == '&') {							char *q;							sptr++;							adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub");							for (q = patbeg; q < patbeg+patlen; )								*pb++ = *q++;						} else							*pb++ = *sptr++;					}				}				if (*c == 0)	/* at end */					goto done;				adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gsub");				*pb++ = *c++;				if (pb > buf + bufsz)	/* BUG: not sure of this test */					FATAL("gsub result0 %.30s too big; can't happen", buf);				mflag = 0;			}			else {	/* matched nonempty string */				num++;				sptr = c;				adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gsub");				while (sptr < patbeg)					*pb++ = *sptr++;				sptr = rptr;				while (*sptr != 0) {					adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub");					if (*sptr == '\\') {						backsub(&pb, &sptr);					} else if (*sptr == '&') {						char *q;						sptr++;						adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub");						for (q = patbeg; q < patbeg+patlen; )							*pb++ = *q++;					} else						*pb++ = *sptr++;				}				c = patbeg + patlen;				if ((c[-1] == 0) || (*c == 0))					goto done;				if (pb > buf + bufsz)					FATAL("gsub result1 %.30s too big; can't happen", buf);				mflag = 1;			}		} while (pmatch(p, t, c));		sptr = c;		adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub");		while ((*pb++ = *sptr++) != 0)			;	done:	if (pb > buf + bufsz)			FATAL("gsub result2 %.30s too big; can't happen", buf);		*pb = '\0';		setsval(x, buf);	/* BUG: should be able to avoid copy + free */	}	tempfree(x);	tempfree(y);	x = gettemp();	x->tval = NUM;	x->fval = num;	free(buf);	return(x);}void backsub(char **pb_ptr, char **sptr_ptr)	/* handle \\& variations */{						/* sptr[0] == '\\' */	char *pb = *pb_ptr, *sptr = *sptr_ptr;	if (sptr[1] == '\\') {		if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */			*pb++ = '\\';			*pb++ = '&';			sptr += 4;		} else if (sptr[2] == '&') {	/* \\& -> \ + matched */			*pb++ = '\\';			sptr += 2;		} else {			/* \\x -> \\x */			*pb++ = *sptr++;			*pb++ = *sptr++;		}	} else if (sptr[1] == '&') {	/* literal & */		sptr++;		*pb++ = *sptr++;	} else				/* literal \ */		*pb++ = *sptr++;	*pb_ptr = pb;	*sptr_ptr = sptr;}

⌨️ 快捷键说明

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