msh.c

来自「手机嵌入式Linux下可用的busybox源码」· C语言 代码 · 共 3,606 行 · 第 1/5 页

C
3,606
字号
	if (t != NULL) {		while ((c = yylex(0)) == '|') {			if ((p = command(CONTIN)) == NULL)				SYNTAXERR;			if (t->type != TPAREN && t->type != TCOM) {				/* shell statement */				t = block(TPAREN, t, NOBLOCK, NOWORDS);			}			t = block(TPIPE, t, p, NOWORDS);		}		peeksym = c;	}	return (t);}static struct op *andor(){	register struct op *t, *p;	register int c;	t = pipeline(0);	if (t != NULL) {		while ((c = yylex(0)) == LOGAND || c == LOGOR) {			if ((p = pipeline(CONTIN)) == NULL)				SYNTAXERR;			t = block(c == LOGAND ? TAND : TOR, t, p, NOWORDS);		}		peeksym = c;	}	return (t);}static struct op *c_list(){	register struct op *t, *p;	register int c;	t = andor();	if (t != NULL) {		if ((peeksym = yylex(0)) == '&')			t = block(TASYNC, t, NOBLOCK, NOWORDS);		while ((c = yylex(0)) == ';' || c == '&'			   || (multiline && c == '\n')) {			if ((p = andor()) == NULL)				return (t);			if ((peeksym = yylex(0)) == '&')				p = block(TASYNC, p, NOBLOCK, NOWORDS);			t = list(t, p);		}		peeksym = c;	}	return (t);}static int synio(cf)int cf;{	register struct ioword *iop;	register int i;	register int c;	if ((c = yylex(cf)) != '<' && c != '>') {		peeksym = c;		return (0);	}	i = yylval.i;	musthave(WORD, 0);	iop = io(iounit, i, yylval.cp);	iounit = IODEFAULT;	if (i & IOHERE)		markhere(yylval.cp, iop);	return (1);}static void musthave(c, cf)int c, cf;{	if ((peeksym = yylex(cf)) != c)		SYNTAXERR;	peeksym = 0;}static struct op *simple(){	register struct op *t;	t = NULL;	for (;;) {		switch (peeksym = yylex(0)) {		case '<':		case '>':			(void) synio(0);			break;		case WORD:			if (t == NULL) {				t = newtp();				t->type = TCOM;			}			peeksym = 0;			word(yylval.cp);			break;		default:			return (t);		}	}}static struct op *nested(type, mark)int type, mark;{	register struct op *t;	multiline++;	t = c_list();	musthave(mark, 0);	multiline--;	return (block(type, t, NOBLOCK, NOWORDS));}static struct op *command(cf)int cf;{	register struct op *t;	struct wdblock *iosave;	register int c;	iosave = iolist;	iolist = NULL;	if (multiline)		cf |= CONTIN;	while (synio(cf))		cf = 0;	switch (c = yylex(cf)) {	default:		peeksym = c;		if ((t = simple()) == NULL) {			if (iolist == NULL)				return ((struct op *) NULL);			t = newtp();			t->type = TCOM;		}		break;	case '(':		t = nested(TPAREN, ')');		break;	case '{':		t = nested(TBRACE, '}');		break;	case FOR:		t = newtp();		t->type = TFOR;		musthave(WORD, 0);		startl = 1;		t->str = yylval.cp;		multiline++;		t->words = wordlist();		if ((c = yylex(0)) != '\n' && c != ';')			peeksym = c;		t->left = dogroup(0);		multiline--;		break;	case WHILE:	case UNTIL:		multiline++;		t = newtp();		t->type = c == WHILE ? TWHILE : TUNTIL;		t->left = c_list();		t->right = dogroup(1);		t->words = NULL;		multiline--;		break;	case CASE:		t = newtp();		t->type = TCASE;		musthave(WORD, 0);		t->str = yylval.cp;		startl++;		multiline++;		musthave(IN, CONTIN);		startl++;		t->left = caselist();		musthave(ESAC, 0);		multiline--;		break;	case IF:		multiline++;		t = newtp();		t->type = TIF;		t->left = c_list();		t->right = thenpart();		musthave(FI, 0);		multiline--;		break;	}	while (synio(0));	t = namelist(t);	iolist = iosave;	return (t);}static struct op *dogroup(onlydone)int onlydone;{	register int c;	register struct op *oplist;	c = yylex(CONTIN);	if (c == DONE && onlydone)		return ((struct op *) NULL);	if (c != DO)		SYNTAXERR;	oplist = c_list();	musthave(DONE, 0);	return (oplist);}static struct op *thenpart(){	register int c;	register struct op *t;	if ((c = yylex(0)) != THEN) {		peeksym = c;		return ((struct op *) NULL);	}	t = newtp();	t->type = 0;	t->left = c_list();	if (t->left == NULL)		SYNTAXERR;	t->right = elsepart();	return (t);}static struct op *elsepart(){	register int c;	register struct op *t;	switch (c = yylex(0)) {	case ELSE:		if ((t = c_list()) == NULL)			SYNTAXERR;		return (t);	case ELIF:		t = newtp();		t->type = TELIF;		t->left = c_list();		t->right = thenpart();		return (t);	default:		peeksym = c;		return ((struct op *) NULL);	}}static struct op *caselist(){	register struct op *t;	t = NULL;	while ((peeksym = yylex(CONTIN)) != ESAC)		t = list(t, casepart());	return (t);}static struct op *casepart(){	register struct op *t;	t = newtp();	t->type = TPAT;	t->words = pattern();	musthave(')', 0);	t->left = c_list();	if ((peeksym = yylex(CONTIN)) != ESAC)		musthave(BREAK, CONTIN);	return (t);}static char **pattern(){	register int c, cf;	cf = CONTIN;	do {		musthave(WORD, cf);		word(yylval.cp);		cf = 0;	} while ((c = yylex(0)) == '|');	peeksym = c;	word(NOWORD);	return (copyw());}static char **wordlist(){	register int c;	if ((c = yylex(0)) != IN) {		peeksym = c;		return ((char **) NULL);	}	startl = 0;	while ((c = yylex(0)) == WORD)		word(yylval.cp);	word(NOWORD);	peeksym = c;	return (copyw());}/* * supporting functions */static struct op *list(t1, t2)register struct op *t1, *t2;{	if (t1 == NULL)		return (t2);	if (t2 == NULL)		return (t1);	return (block(TLIST, t1, t2, NOWORDS));}static struct op *block(type, t1, t2, wp)int type;struct op *t1, *t2;char **wp;{	register struct op *t;	t = newtp();	t->type = type;	t->left = t1;	t->right = t2;	t->words = wp;	return (t);}static struct res {	char *r_name;	int r_val;} restab[] = {	{	"for", FOR}, {	"case", CASE}, {	"esac", ESAC}, {	"while", WHILE}, {	"do", DO}, {	"done", DONE}, {	"if", IF}, {	"in", IN}, {	"then", THEN}, {	"else", ELSE}, {	"elif", ELIF}, {	"until", UNTIL}, {	"fi", FI}, {	";;", BREAK}, {	"||", LOGOR}, {	"&&", LOGAND}, {	"{", '{'}, {	"}", '}'}, {	0, 0}};int rlookup(n)register char *n;{	register struct res *rp;	for (rp = restab; rp->r_name; rp++)		if (strcmp(rp->r_name, n) == 0)			return (rp->r_val);	return (0);}static struct op *newtp(){	register struct op *t;	t = (struct op *) tree(sizeof(*t));	t->type = 0;	t->words = NULL;	t->ioact = NULL;	t->left = NULL;	t->right = NULL;	t->str = NULL;	return (t);}static struct op *namelist(t)register struct op *t;{	if (iolist) {		iolist = addword((char *) NULL, iolist);		t->ioact = copyio();	} else		t->ioact = NULL;	if (t->type != TCOM) {		if (t->type != TPAREN && t->ioact != NULL) {			t = block(TPAREN, t, NOBLOCK, NOWORDS);			t->ioact = t->left->ioact;			t->left->ioact = NULL;		}		return (t);	}	word(NOWORD);	t->words = copyw();	return (t);}static char **copyw(){	register char **wd;	wd = getwords(wdlist);	wdlist = 0;	return (wd);}static void word(cp)char *cp;{	wdlist = addword(cp, wdlist);}static struct ioword **copyio(){	register struct ioword **iop;	iop = (struct ioword **) getwords(iolist);	iolist = 0;	return (iop);}static struct ioword *io(u, f, cp)int u;int f;char *cp;{	register struct ioword *iop;	iop = (struct ioword *) tree(sizeof(*iop));	iop->io_unit = u;	iop->io_flag = f;	iop->io_name = cp;	iolist = addword((char *) iop, iolist);	return (iop);}static void zzerr(){	yyerror("syntax error");}void yyerror(s)char *s;{	yynerrs++;	if (interactive && e.iop <= iostack) {		multiline = 0;		while (eofc() == 0 && yylex(0) != '\n');	}	err(s);	fail();}static int yylex(cf)int cf;{	register int c, c1;	int atstart;	if ((c = peeksym) > 0) {		peeksym = 0;		if (c == '\n')			startl = 1;		return (c);	}	nlseen = 0;	e.linep = line;	atstart = startl;	startl = 0;	yylval.i = 0;  loop:	while ((c = getqc(0)) == ' ' || c == '\t');	switch (c) {	default:		if (any(c, "0123456789")) {			unget(c1 = getqc(0));			if (c1 == '<' || c1 == '>') {				iounit = c - '0';				goto loop;			}			*e.linep++ = c;			c = c1;		}		break;	case '#':		while ((c = getqc(0)) != 0 && c != '\n');		unget(c);		goto loop;	case 0:		return (c);	case '$':		*e.linep++ = c;		if ((c = getqc(0)) == '{') {			if ((c = collect(c, '}')) != '\0')				return (c);			goto pack;		}		break;	case '`':	case '\'':	case '"':		if ((c = collect(c, c)) != '\0')			return (c);		goto pack;	case '|':	case '&':	case ';':		if ((c1 = dual(c)) != '\0') {			startl = 1;			return (c1);		}		startl = 1;		return (c);	case '^':		startl = 1;		return ('|');	case '>':	case '<':		diag(c);		return (c);	case '\n':		nlseen++;		gethere();		startl = 1;		if (multiline || cf & CONTIN) {			if (interactive && e.iop <= iostack)#ifdef BB_FEATURE_COMMAND_EDITING				current_prompt = cprompt->value;#else				prs(cprompt->value);#endif			if (cf & CONTIN)				goto loop;		}		return (c);	case '(':	case ')':		startl = 1;		return (c);	}	unget(c);  pack:	while ((c = getqc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n"))		if (e.linep >= elinep)			err("word too long");		else			*e.linep++ = c;	unget(c);	if (any(c, "\"'`$"))		goto loop;	*e.linep++ = '\0';	if (atstart && (c = rlookup(line)) != 0) {		startl = 1;		return (c);	}	yylval.cp = strsave(line, areanum);	return (WORD);}int collect(c, c1)int c, c1;{	char s[2];	*e.linep++ = c;	while ((c = getqc(c1)) != c1) {		if (c == 0) {			unget(c);			s[0] = c1;			s[1] = 0;			prs("no closing ");			yyerror(s);			return (YYERRCODE);		}		if (interactive && c == '\n' && e.iop <= iostack)#ifdef BB_FEATURE_COMMAND_EDITING			current_prompt = cprompt->value;#else			prs(cprompt->value);#endif		*e.linep++ = c;	}	*e.linep++ = c;	return (0);}int dual(c)int c;{	char s[3];	register char *cp = s;	*cp++ = c;	*cp++ = getqc(0);	*cp = 0;	if ((c = rlookup(s)) == 0)		unget(*--cp);	return (c);}static void diag(ec)register int ec;{	register int c;	c = getqc(0);	if (c == '>' || c == '<') {		if (c != ec)			zzerr();		yylval.i = ec == '>' ? IOWRITE | IOCAT : IOHERE;		c = getqc(0);	} else		yylval.i = ec == '>' ? IOWRITE : IOREAD;	if (c != '&' || yylval.i == IOHERE)		unget(c);	else		yylval.i |= IODUP;}static char *tree(size)unsigned size;{	register char *t;	if ((t = getcell(size)) == NULL) {		prs("command line too complicated\n");		fail();		/* NOTREACHED */	}	return (t);}/* -------- exec.c -------- *//* * execute tree */static char *signame[] = {	"Signal 0",	"Hangup",	(char *) NULL,				/* interrupt */	"Quit",	"Illegal instruction",	"Trace/BPT trap",	"Abort",	"EMT trap",	"Floating exception",	"Killed",	"Bus error",	"Memory fault",	"Bad system call",	(char *) NULL,				/* broken pipe */	"Alarm clock",	"Terminated",};#define NSIGNAL (sizeof(signame)/sizeof(signame[0]))/* * common actions when creating a new child */#ifdef USE_FORK#define XFORK forkstatic int parent(){	register int i;	i = fork();	if (i != 0) {		if (i == -1)			warn("try again");	}	return (i);}#else#  define parent vfork#  define XFORK  vfork#endifstatic int forkexec(struct op *t, int *pin, int *pout, int act, char **wp,					int *pforked);static int iosetup(struct ioword *iop, int pipein, int pipeout);static void echo(char **wp);static struct op **find1case(struct op *t, char *w);static struct op *findcase(struct op *t, char *w);static void brkset(struct brkcon *bc);

⌨️ 快捷键说明

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