/* * syntax * empty * syn0 */ struct command * syntax(struct wordent *p1, struct wordent *p2, int flags) { while (p1 != p2) if (any(";&\n", p1->word[0])) p1 = p1->next; else return (syn0(p1, p2, flags)); return (0); }
/* * syn3 * ( syn0 ) [ < in ] [ > out ] * word word* [ < in ] [ > out ] * KEYWORD ( word* ) word* [ < in ] [ > out ] * * KEYWORD = (@ exit foreach if set switch test while) */ static struct command * syn3(struct wordent *p1, struct wordent *p2, int flags) { struct wordent *p; struct wordent *lp, *rp; struct command *t; int l; Char **av; int n, c; bool specp = 0; if (p1 != p2) { p = p1; again: switch (srchx(p->word)) { case T_ELSE: p = p->next; if (p != p2) goto again; break; case T_EXIT: case T_FOREACH: case T_IF: case T_LET: case T_SET: case T_SWITCH: case T_WHILE: specp = 1; break; } } n = 0; l = 0; for (p = p1; p != p2; p = p->next) switch (p->word[0]) { case '(': if (specp) n++; l++; continue; case ')': if (specp) n++; l--; continue; case '>': case '<': if (l != 0) { if (specp) n++; continue; } if (p->next == p2) continue; if (any(RELPAR, p->next->word[0])) continue; n--; continue; default: if (!specp && l != 0) continue; n++; continue; } if (n < 0) n = 0; t = (struct command *) xcalloc(1, sizeof(*t)); av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **)); t->t_dcom = av; n = 0; if (p2->word[0] == ')') t->t_dflg = F_NOFORK; lp = 0; rp = 0; l = 0; for (p = p1; p != p2; p = p->next) { c = p->word[0]; switch (c) { case '(': if (l == 0) { if (lp != 0 && !specp) seterror(ERR_BADPLP); lp = p->next; } l++; goto savep; case ')': l--; if (l == 0) rp = p; goto savep; case '>': if (l != 0) goto savep; if (p->word[1] == '>') t->t_dflg |= F_APPEND; if (p->next != p2 && eq(p->next->word, STRand)) { t->t_dflg |= F_STDERR, p = p->next; if (flags & (POUT | PERR)) { seterror(ERR_OUTRED); continue; } } if (p->next != p2 && eq(p->next->word, STRbang)) t->t_dflg |= F_OVERWRITE, p = p->next; if (p->next == p2) { seterror(ERR_MISRED); continue; } p = p->next; if (any(RELPAR, p->word[0])) { seterror(ERR_MISRED); continue; } if ((flags & POUT) && ((flags & PERR) == 0 || t->t_drit)) seterror(ERR_OUTRED); else t->t_drit = Strsave(p->word); continue; case '<': if (l != 0) goto savep; if (p->word[1] == '<') t->t_dflg |= F_READ; if (p->next == p2) { seterror(ERR_MISRED); continue; } p = p->next; if (any(RELPAR, p->word[0])) { seterror(ERR_MISRED); continue; } if ((flags & PHERE) && (t->t_dflg & F_READ)) seterror(ERR_REDPAR); else if ((flags & PIN) || t->t_dlef) seterror(ERR_INRED); else t->t_dlef = Strsave(p->word); continue; savep: if (!specp) continue; default: if (l != 0 && !specp) continue; if (seterr == 0) av[n] = Strsave(p->word); n++; continue; } } if (lp != 0 && !specp) { if (n != 0) seterror(ERR_BADPLPS); t->t_dtyp = NODE_PAREN; t->t_dspr = syn0(lp, rp, PHERE); } else { if (n == 0) seterror(ERR_NULLCOM); t->t_dtyp = NODE_COMMAND; } return (t); }