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 + -
显示快捷键?