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

📄 sh4.c

📁 minix软件源代码
💻 C
字号:
#define Extern extern#include <sys/types.h>#include <sys/stat.h>#include <sys/dir.h>#include <limits.h>#include <signal.h>#include <errno.h>#include <setjmp.h>#include "sh.h"/* -------- eval.c -------- *//* #include "sh.h" *//* #include "word.h" *//* * ${} * `command` * blank interpretation * quoting * glob */_PROTOTYPE(static int expand, (char *cp, struct wdblock **wbp, int f ));_PROTOTYPE(static char *blank, (int f ));_PROTOTYPE(static int dollar, (int quoted ));_PROTOTYPE(static int grave, (int quoted ));_PROTOTYPE(void globname, (char *we, char *pp ));_PROTOTYPE(static char *generate, (char *start1, char *end1, char *middle, char *end ));_PROTOTYPE(static int anyspcl, (struct wdblock *wb ));_PROTOTYPE(static int xstrcmp, (char *p1, char *p2 ));_PROTOTYPE(void glob0, (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *)));_PROTOTYPE(void glob1, (char *base, char *lim ));_PROTOTYPE(void glob2, (char *i, char *j ));_PROTOTYPE(void glob3, (char *i, char *j, char *k ));_PROTOTYPE(char *memcopy, (char *ato, char *from, int nb ));char **eval(ap, f)register char **ap;int f;{	struct wdblock *wb;	char **wp;	char **wf;	jmp_buf ev;	wp = NULL;	wb = NULL;	wf = NULL;	if (newenv(setjmp(errpt = ev)) == 0) {		while (*ap && isassign(*ap))			expand(*ap++, &wb, f & ~DOGLOB);		if (flag['k']) {			for (wf = ap; *wf; wf++) {				if (isassign(*wf))					expand(*wf, &wb, f & ~DOGLOB);			}		}		for (wb = addword((char *)0, wb); *ap; ap++) {			if (!flag['k'] || !isassign(*ap))				expand(*ap, &wb, f & ~DOKEY);		}		wb = addword((char *)0, wb);		wp = getwords(wb);		quitenv();	} else		gflg = 1;	return(gflg? (char **)NULL: wp);}/* * Make the exported environment from the exported * names in the dictionary. Keyword assignments * will already have been done. */char **makenv(){	register struct wdblock *wb;	register struct var *vp;	wb = NULL;	for (vp = vlist; vp; vp = vp->next)		if (vp->status & EXPORT)			wb = addword(vp->name, wb);	wb = addword((char *)0, wb);	return(getwords(wb));}char *evalstr(cp, f)register char *cp;int f;{	struct wdblock *wb;	wb = NULL;	if (expand(cp, &wb, f)) {		if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL)			cp = "";		DELETE(wb);	} else		cp = NULL;	return(cp);}static intexpand(cp, wbp, f)register char *cp;register struct wdblock **wbp;int f;{	jmp_buf ev;	gflg = 0;	if (cp == NULL)		return(0);	if (!anys("$`'\"", cp) &&	    !anys(ifs->value, cp) &&	    ((f&DOGLOB)==0 || !anys("[*?", cp))) {		cp = strsave(cp, areanum);		if (f & DOTRIM)			unquote(cp);		*wbp = addword(cp, *wbp);		return(1);	}	if (newenv(setjmp(errpt = ev)) == 0) {		PUSHIO(aword, cp, strchar);		e.iobase = e.iop;		while ((cp = blank(f)) && gflg == 0) {			e.linep = cp;			cp = strsave(cp, areanum);			if ((f&DOGLOB) == 0) {				if (f & DOTRIM)					unquote(cp);				*wbp = addword(cp, *wbp);			} else				*wbp = glob(cp, *wbp);		}		quitenv();	} else		gflg = 1;	return(gflg == 0);}/* * Blank interpretation and quoting */static char *blank(f)int f;{	register c, c1;	register char *sp;	int scanequals, foundequals;	sp = e.linep;	scanequals = f & DOKEY;	foundequals = 0;loop:	switch (c = subgetc('"', foundequals)) {	case 0:		if (sp == e.linep)			return(0);		*e.linep++ = 0;		return(sp);	default:		if (f & DOBLANK && any(c, ifs->value))			goto loop;		break;	case '"':	case '\'':		scanequals = 0;		if (INSUB())			break;		for (c1 = c; (c = subgetc(c1, 1)) != c1;) {			if (c == 0)				break;			if (c == '\'' || !any(c, "$`\""))				c |= QUOTE;			*e.linep++ = c;		}		c = 0;	}	unget(c);	if (!letter(c))		scanequals = 0;	for (;;) {		c = subgetc('"', foundequals);		if (c == 0 ||		    f & (DOBLANK && any(c, ifs->value)) ||		    (!INSUB() && any(c, "\"'"))) {		        scanequals = 0;			unget(c);			if (any(c, "\"'"))				goto loop;			break;		}		if (scanequals)			if (c == '=') {				foundequals = 1;				scanequals  = 0;			}			else if (!letnum(c))				scanequals = 0;		*e.linep++ = c;	}	*e.linep++ = 0;	return(sp);}/* * Get characters, substituting for ` and $ */intsubgetc(ec, quoted)register char ec;int quoted;{	register char c;again:	c = getc(ec);	if (!INSUB() && ec != '\'') {		if (c == '`') {			if (grave(quoted) == 0)				return(0);			e.iop->task = XGRAVE;			goto again;		}		if (c == '$' && (c = dollar(quoted)) == 0) {			e.iop->task = XDOLL;			goto again;		}	}	return(c);}/* * Prepare to generate the string returned by ${} substitution. */static intdollar(quoted)int quoted;{	int otask;	struct io *oiop;	char *dolp;	register char *s, c, *cp;	struct var *vp;	c = readc();	s = e.linep;	if (c != '{') {		*e.linep++ = c;		if (letter(c)) {			while ((c = readc())!=0 && letnum(c))				if (e.linep < elinep)					*e.linep++ = c;			unget(c);		}		c = 0;	} else {		oiop = e.iop;		otask = e.iop->task;		e.iop->task = XOTHER;		while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n')			if (e.linep < elinep)				*e.linep++ = c;		if (oiop == e.iop)			e.iop->task = otask;		if (c != '}') {			err("unclosed ${");			gflg++;			return(c);		}	}	if (e.linep >= elinep) {		err("string in ${} too long");		gflg++;		e.linep -= 10;	}	*e.linep = 0;	if (*s)		for (cp = s+1; *cp; cp++)			if (any(*cp, "=-+?")) {				c = *cp;				*cp++ = 0;				break;			}	if (s[1] == 0 && (*s == '*' || *s == '@')) {		if (dolc > 1) {			/* currently this does not distinguish $* and $@ */			/* should check dollar */			e.linep = s;			PUSHIO(awordlist, dolv+1, dolchar);			return(0);		} else {	/* trap the nasty ${=} */			s[0] = '1';			s[1] = 0;		}	}	vp = lookup(s);	if ((dolp = vp->value) == null) {		switch (c) {		case '=':			if (digit(*s)) {				err("cannot use ${...=...} with $n");				gflg++;				break;			}			setval(vp, cp);			dolp = vp->value;			break;		case '-':			dolp = strsave(cp, areanum);			break;		case '?':			if (*cp == 0) {				prs("missing value for ");				err(s);			} else				err(cp);			gflg++;			break;		}	} else if (c == '+')		dolp = strsave(cp, areanum);	if (flag['u'] && dolp == null) {		prs("unset variable: ");		err(s);		gflg++;	}	e.linep = s;	PUSHIO(aword, dolp, quoted ? qstrchar : strchar);	return(0);}/* * Run the command in `...` and read its output. */static intgrave(quoted)int quoted;{	register char *cp;	register int i;	int pf[2];	for (cp = e.iop->argp->aword; *cp != '`'; cp++)		if (*cp == 0) {			err("no closing `");			return(0);		}	if (openpipe(pf) < 0)		return(0);	if ((i = fork()) == -1) {		closepipe(pf);		err("try again");		return(0);	}	if (i != 0) {		e.iop->argp->aword = ++cp;		close(pf[1]);		PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar);		return(1);	}	*cp = 0;	/* allow trapped signals */	for (i=0; i<=_NSIG; i++)		if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN)			signal(i, SIG_DFL);	dup2(pf[1], 1);	closepipe(pf);	flag['e'] = 0;	flag['v'] = 0;	flag['n'] = 0;	cp = strsave(e.iop->argp->aword, 0);	areanum = 1;	freehere(areanum);	freearea(areanum);	/* free old space */	e.oenv = NULL;	e.iop = (e.iobase = iostack) - 1;	unquote(cp);	talking = 0;	PUSHIO(aword, cp, nlchar);	onecommand();	exit(1);}char *unquote(as)register char *as;{	register char *s;	if ((s = as) != NULL)		while (*s)			*s++ &= ~QUOTE;	return(as);}/* -------- glob.c -------- *//* #include "sh.h" *//* * glob */#define	scopy(x) strsave((x), areanum)#define	BLKSIZ	512#define	NDENT	((BLKSIZ+sizeof(struct direct)-1)/sizeof(struct direct))static	struct wdblock	*cl, *nl;static	char	spcl[] = "[?*";struct wdblock *glob(cp, wb)char *cp;struct wdblock *wb;{	register i;	register char *pp;	if (cp == 0)		return(wb);	i = 0;	for (pp = cp; *pp; pp++)		if (any(*pp, spcl))			i++;		else if (!any(*pp & ~QUOTE, spcl))			*pp &= ~QUOTE;	if (i != 0) {		for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) {			nl = newword(cl->w_nword*2);			for(i=0; i<cl->w_nword; i++) { /* for each argument */				for (pp = cl->w_words[i]; *pp; pp++)					if (any(*pp, spcl)) {						globname(cl->w_words[i], pp);						break;					}				if (*pp == '\0')					nl = addword(scopy(cl->w_words[i]), nl);			}			for(i=0; i<cl->w_nword; i++)				DELETE(cl->w_words[i]);			DELETE(cl);		}		for(i=0; i<cl->w_nword; i++)			unquote(cl->w_words[i]);		glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp);		if (cl->w_nword) {			for (i=0; i<cl->w_nword; i++)				wb = addword(cl->w_words[i], wb);			DELETE(cl);			return(wb);		}	}	wb = addword(unquote(cp), wb);	return(wb);}voidglobname(we, pp)char *we;register char *pp;{	register char *np, *cp;	char *name, *gp, *dp;	int dn, j, n, k;	struct direct ent[NDENT];	char dname[NAME_MAX+1];	struct stat dbuf;	for (np = we; np != pp; pp--)		if (pp[-1] == '/')			break;	for (dp = cp = space((int)(pp-np)+3); np < pp;)		*cp++ = *np++;	*cp++ = '.';	*cp = '\0';	for (gp = cp = space(strlen(pp)+1); *np && *np != '/';)		*cp++ = *np++;	*cp = '\0';	dn = open(dp, 0);	if (dn < 0) {		DELETE(dp);		DELETE(gp);		return;	}	dname[NAME_MAX] = '\0';	while ((n = read(dn, (char *)ent, sizeof(ent))) >= sizeof(*ent)) {		n /= sizeof(*ent);		for (j=0; j<n; j++) {			if (ent[j].d_ino == 0)				continue;			strncpy(dname, ent[j].d_name, NAME_MAX);			if (dname[0] == '.')				if (*gp != '.')					continue;			for(k=0; k<NAME_MAX; k++)				if (any(dname[k], spcl))					dname[k] |= QUOTE;			if (gmatch(dname, gp)) {				name = generate(we, pp, dname, np);				if (*np && !anys(np, spcl)) {					if (stat(name,&dbuf)) {						DELETE(name);						continue;					}				}				nl = addword(name, nl);			}		}	}	close(dn);	DELETE(dp);	DELETE(gp);}/* * generate a pathname as below. * start..end1 / middle end * the slashes come for free */static char *generate(start1, end1, middle, end)char *start1;register char *end1;char *middle, *end;{	char *p;	register char *op, *xp;	p = op = space((int)(end1-start1)+strlen(middle)+strlen(end)+2);	for (xp = start1; xp != end1;)		*op++ = *xp++;	for (xp = middle; (*op++ = *xp++) != '\0';)		;	op--;	for (xp = end; (*op++ = *xp++) != '\0';)		;	return(p);}static intanyspcl(wb)register struct wdblock *wb;{	register i;	register char **wd;	wd = wb->w_words;	for (i=0; i<wb->w_nword; i++)		if (anys(spcl, *wd++))			return(1);	return(0);}static intxstrcmp(p1, p2)char *p1, *p2;{	return(strcmp(*(char **)p1, *(char **)p2));}/* -------- word.c -------- *//* #include "sh.h" *//* #include "word.h" */#define	NSTART	16	/* default number of words to allow for initially */struct wdblock *newword(nw)register int nw;{	register struct wdblock *wb;	wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *));	wb->w_bsize = nw;	wb->w_nword = 0;	return(wb);}struct wdblock *addword(wd, wb)char *wd;register struct wdblock *wb;{	register struct wdblock *wb2;	register nw;	if (wb == NULL)		wb = newword(NSTART);	if ((nw = wb->w_nword) >= wb->w_bsize) {		wb2 = newword(nw * 2);		memcopy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *));		wb2->w_nword = nw;		DELETE(wb);		wb = wb2;	}	wb->w_words[wb->w_nword++] = wd;	return(wb);}char **getwords(wb)register struct wdblock *wb;{	register char **wd;	register nb;	if (wb == NULL)		return((char **)NULL);	if (wb->w_nword == 0) {		DELETE(wb);		return((char **)NULL);	}	wd = (char **) space(nb = sizeof(*wd) * wb->w_nword);	memcopy((char *)wd, (char *)wb->w_words, nb);	DELETE(wb);	/* perhaps should done by caller */	return(wd);}_PROTOTYPE(int (*func), (char *, char *));int	globv;voidglob0(a0, a1, a2, a3)char *a0;unsigned a1;int a2;_PROTOTYPE(int (*a3), (char *, char *));{	func = a3;	globv = a2;	glob1(a0, a0 + a1 * a2);}voidglob1(base, lim)char *base, *lim;{	register char *i, *j;	int v2;	char *lptr, *hptr;	int c;	unsigned n;	v2 = globv;top:	if ((n=(int)(lim-base)) <= v2)		return;	n = v2 * (n / (2*v2));	hptr = lptr = base+n;	i = base;	j = lim-v2;	for(;;) {		if (i < lptr) {			if ((c = (*func)(i, lptr)) == 0) {				glob2(i, lptr -= v2);				continue;			}			if (c < 0) {				i += v2;				continue;			}		}begin:		if (j > hptr) {			if ((c = (*func)(hptr, j)) == 0) {				glob2(hptr += v2, j);				goto begin;			}			if (c > 0) {				if (i == lptr) {					glob3(i, hptr += v2, j);					i = lptr += v2;					goto begin;				}				glob2(i, j);				j -= v2;				i += v2;				continue;			}			j -= v2;			goto begin;		}		if (i == lptr) {			if (lptr-base >= lim-hptr) {				glob1(hptr+v2, lim);				lim = lptr;			} else {				glob1(base, lptr);				base = hptr+v2;			}			goto top;		}		glob3(j, lptr -= v2, i);		j = hptr -= v2;	}}voidglob2(i, j)char *i, *j;{	register char *index1, *index2, c;	int m;	m = globv;	index1 = i;	index2 = j;	do {		c = *index1;		*index1++ = *index2;		*index2++ = c;	} while(--m);}voidglob3(i, j, k)char *i, *j, *k;{	register char *index1, *index2, *index3;	int c;	int m;	m = globv;	index1 = i;	index2 = j;	index3 = k;	do {		c = *index1;		*index1++ = *index3;		*index3++ = *index2;		*index2++ = c;	} while(--m);}char *memcopy(ato, from, nb)register char *ato, *from;register int nb;{	register char *to;	to = ato;	while (--nb >= 0)		*to++ = *from++;	return(ato);}

⌨️ 快捷键说明

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