URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [uclinux/] [userland/] [sh/] [sh2.c] - Rev 1771
Go to most recent revision | Compare with Previous | Blame | View Log
#define Extern extern #include <sys/types.h> #include <signal.h> #include <stdio.h> #include <errno.h> #include <setjmp.h> #include "sh.h" /* -------- csyn.c -------- */ /* * shell: syntax (C version) */ typedef union { char *cp; char **wp; int i; struct op *o; } YYSTYPE; #define WORD 256 #define LOGAND 257 #define LOGOR 258 #define BREAK 259 #define IF 260 #define THEN 261 #define ELSE 262 #define ELIF 263 #define FI 264 #define CASE 265 #define ESAC 266 #define FOR 267 #define WHILE 268 #define UNTIL 269 #define DO 270 #define DONE 271 #define IN 272 #define YYERRCODE 300 /* flags to yylex */ #define CONTIN 01 /* skip new lines to complete command */ /* #include "sh.h" */ #define SYNTAXERR zzerr() static int startl; static int peeksym; static int nlseen; static int iounit = IODEFAULT; static YYSTYPE yylval; static struct op *pipeline(int cf ); static struct op *andor(void); static struct op *c_list(void); static int synio(int cf ); static void musthave (int c, int cf ); static struct op *simple(void); static struct op *nested(int type, int mark ); static struct op *command(int cf ); static struct op *dogroup(int onlydone ); static struct op *thenpart(void); static struct op *elsepart(void); static struct op *caselist(void); static struct op *casepart(void); static char **pattern(void); static char **wordlist(void); static struct op *list(struct op *t1, struct op *t2 ); static struct op *block(int type, struct op *t1, struct op *t2, char **wp ); static struct op *newtp(void); static struct op *namelist(struct op *t ); static char **copyw(void); static void word(char *cp ); static struct ioword **copyio(void); static struct ioword *io (int u, int f, char *cp ); static void zzerr(void); void yyerror(char *s ); static int yylex(int cf ); int collect(int c, int c1 ); int dual(int c ); static void diag(int ec ); static char *tree(unsigned size ); int yyparse() { startl = 1; peeksym = 0; yynerrs = 0; outtree = c_list(); musthave('\n', 0); return(yynerrs!=0); } static struct op * pipeline(cf) int cf; { register struct op *t, *p; register int c; t = command(cf); 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 *list; c = yylex(CONTIN); if (c == DONE && onlydone) return((struct op *)NULL); if (c != DO) SYNTAXERR; list = c_list(); musthave(DONE, 0); return(list); } 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); } 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 (talking && 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 = my_getc(0)) == ' ' || c == '\t') ; switch (c) { default: if (any(c, "0123456789")) { unget(c1 = my_getc(0)); if (c1 == '<' || c1 == '>') { iounit = c - '0'; goto loop; } *e.linep++ = c; c = c1; } break; case '#': while ((c = my_getc(0)) != 0 && c != '\n') ; unget(c); goto loop; case 0: return(c); case '$': *e.linep++ = c; if ((c = my_getc(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 (talking && e.iop <= iostack) prs(cprompt->value); if (cf & CONTIN) goto loop; } return(c); case '(': case ')': startl = 1; return(c); } unget(c); pack: while ((c = my_getc(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) register int c, c1; { char s[2]; *e.linep++ = c; while ((c = my_getc(c1)) != c1) { if (c == 0) { unget(c); s[0] = c1; s[1] = 0; prs("no closing "); yyerror(s); return(YYERRCODE); } if (talking && c == '\n' && e.iop <= iostack) prs(cprompt->value); *e.linep++ = c; } *e.linep++ = c; return(0); } int dual(c) register int c; { char s[3]; register char *cp = s; *cp++ = c; *cp++ = my_getc(0); *cp = 0; if ((c = rlookup(s)) == 0) unget(*--cp); return(c); } static void diag(ec) register int ec; { register int c; c = my_getc(0); if (c == '>' || c == '<') { if (c != ec) zzerr(); yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE; c = my_getc(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); } /* VARARGS1 */ /* ARGSUSED */
Go to most recent revision | Compare with Previous | Blame | View Log