147823Sbostic /*- 247823Sbostic * Copyright (c) 1980, 1991 The Regents of the University of California. 347823Sbostic * All rights reserved. 447823Sbostic * 547823Sbostic * %sccs.include.redist.c% 621939Sdist */ 721939Sdist 817511Sedward #ifndef lint 9*50024Schristos static char sccsid[] = "@(#)parse.c 5.9 (Berkeley) 06/07/91"; 1047823Sbostic #endif /* not lint */ 111301Sbill 1250023Sbostic #include "csh.h" 1350023Sbostic #include "extern.h" 141301Sbill 15*50024Schristos static void asyntax __P((struct wordent *, struct wordent *)); 16*50024Schristos static void asyn0 __P((struct wordent *, struct wordent *)); 17*50024Schristos static void asyn3 __P((struct wordent *, struct wordent *)); 18*50024Schristos static struct wordent 19*50024Schristos *freenod __P((struct wordent *, struct wordent *)); 20*50024Schristos static struct command 21*50024Schristos *syn0 __P((struct wordent *, struct wordent *, int)); 22*50024Schristos static struct command 23*50024Schristos *syn1 __P((struct wordent *, struct wordent *, int)); 24*50024Schristos static struct command 25*50024Schristos *syn1a __P((struct wordent *, struct wordent *, int)); 26*50024Schristos static struct command 27*50024Schristos *syn1b __P((struct wordent *, struct wordent *, int)); 28*50024Schristos static struct command 29*50024Schristos *syn2 __P((struct wordent *, struct wordent *, int)); 30*50024Schristos static struct command 31*50024Schristos *syn3 __P((struct wordent *, struct wordent *, int)); 321301Sbill 3349992Sbostic #define ALEFT 21 /* max of 20 alias expansions */ 3449992Sbostic #define HLEFT 11 /* max of 10 history expansions */ 351301Sbill /* 361301Sbill * Perform aliasing on the word list lex 371301Sbill * Do a (very rudimentary) parse to separate into commands. 381301Sbill * If word 0 of a command has an alias, do it. 391301Sbill * Repeat a maximum of 20 times. 401301Sbill */ 4149992Sbostic static int aleft; 4249992Sbostic extern int hleft; 4349992Sbostic void 441301Sbill alias(lex) 4549992Sbostic register struct wordent *lex; 461301Sbill { 4749992Sbostic jmp_buf osetexit; 481301Sbill 4949992Sbostic aleft = ALEFT; 5049992Sbostic hleft = HLEFT; 5149992Sbostic getexit(osetexit); 5249992Sbostic (void) setexit(); 5349992Sbostic if (haderr) { 541301Sbill resexit(osetexit); 5549992Sbostic reset(); 5649992Sbostic } 5749992Sbostic if (--aleft == 0) 5849992Sbostic stderror(ERR_ALIASLOOP); 5949992Sbostic asyntax(lex->next, lex); 6049992Sbostic resexit(osetexit); 611301Sbill } 621301Sbill 6349992Sbostic static void 641301Sbill asyntax(p1, p2) 6549992Sbostic register struct wordent *p1, *p2; 661301Sbill { 6749992Sbostic while (p1 != p2) 6849992Sbostic if (any(";&\n", p1->word[0])) 6949992Sbostic p1 = p1->next; 7049992Sbostic else { 7149992Sbostic asyn0(p1, p2); 7249992Sbostic return; 7349992Sbostic } 741301Sbill } 751301Sbill 7649992Sbostic static void 771301Sbill asyn0(p1, p2) 7849992Sbostic struct wordent *p1; 7949992Sbostic register struct wordent *p2; 801301Sbill { 8149992Sbostic register struct wordent *p; 8249992Sbostic register int l = 0; 831301Sbill 8449992Sbostic for (p = p1; p != p2; p = p->next) 8549992Sbostic switch (p->word[0]) { 861301Sbill 8749992Sbostic case '(': 8849992Sbostic l++; 8949992Sbostic continue; 901301Sbill 9149992Sbostic case ')': 9249992Sbostic l--; 9349992Sbostic if (l < 0) 9449992Sbostic stderror(ERR_TOOMANYRP); 9549992Sbostic continue; 961301Sbill 9749992Sbostic case '>': 9849992Sbostic if (p->next != p2 && eq(p->next->word, STRand)) 9949992Sbostic p = p->next; 10049992Sbostic continue; 1011301Sbill 10249992Sbostic case '&': 10349992Sbostic case '|': 10449992Sbostic case ';': 10549992Sbostic case '\n': 10649992Sbostic if (l != 0) 10749992Sbostic continue; 10849992Sbostic asyn3(p1, p); 10949992Sbostic asyntax(p->next, p2); 11049992Sbostic return; 11149992Sbostic } 11249992Sbostic if (l == 0) 11349992Sbostic asyn3(p1, p2); 1141301Sbill } 1151301Sbill 11649992Sbostic static void 1171301Sbill asyn3(p1, p2) 11849992Sbostic struct wordent *p1; 11949992Sbostic register struct wordent *p2; 1201301Sbill { 12149992Sbostic register struct varent *ap; 12249992Sbostic struct wordent alout; 12349992Sbostic register bool redid; 1241301Sbill 12549992Sbostic if (p1 == p2) 12649992Sbostic return; 12749992Sbostic if (p1->word[0] == '(') { 12849992Sbostic for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev) 12949992Sbostic if (p2 == p1) 1301301Sbill return; 13149992Sbostic if (p2 == p1->next) 13249992Sbostic return; 13349992Sbostic asyn0(p1->next, p2); 13449992Sbostic return; 13549992Sbostic } 13649992Sbostic ap = adrof1(p1->word, &aliases); 13749992Sbostic if (ap == 0) 13849992Sbostic return; 13949992Sbostic alhistp = p1->prev; 14049992Sbostic alhistt = p2; 14149992Sbostic alvec = ap->vec; 14249992Sbostic redid = lex(&alout); 14349992Sbostic alhistp = alhistt = 0; 14449992Sbostic alvec = 0; 14549992Sbostic if (seterr) { 14649992Sbostic freelex(&alout); 14749992Sbostic stderror(ERR_OLD); 14849992Sbostic } 14949992Sbostic if (p1->word[0] && eq(p1->word, alout.next->word)) { 15049992Sbostic Char *cp = alout.next->word; 1511301Sbill 15249992Sbostic alout.next->word = Strspl(STRQNULL, cp); 15349992Sbostic xfree((ptr_t) cp); 15449992Sbostic } 15549992Sbostic p1 = freenod(p1, redid ? p2 : p1->next); 15649992Sbostic if (alout.next != &alout) { 15749992Sbostic p1->next->prev = alout.prev->prev; 15849992Sbostic alout.prev->prev->next = p1->next; 15949992Sbostic alout.next->prev = p1; 16049992Sbostic p1->next = alout.next; 16149992Sbostic xfree((ptr_t) alout.prev->word); 16249992Sbostic xfree((ptr_t) (alout.prev)); 16349992Sbostic } 16449992Sbostic reset(); /* throw! */ 1651301Sbill } 1661301Sbill 16749992Sbostic static struct wordent * 1681301Sbill freenod(p1, p2) 16949992Sbostic register struct wordent *p1, *p2; 1701301Sbill { 17149992Sbostic register struct wordent *retp = p1->prev; 1721301Sbill 17349992Sbostic while (p1 != p2) { 17449992Sbostic xfree((ptr_t) p1->word); 17549992Sbostic p1 = p1->next; 17649992Sbostic xfree((ptr_t) (p1->prev)); 17749992Sbostic } 17849992Sbostic retp->next = p2; 17949992Sbostic p2->prev = retp; 18049992Sbostic return (retp); 1811301Sbill } 1821301Sbill 1831301Sbill #define PHERE 1 1841301Sbill #define PIN 2 1851301Sbill #define POUT 4 1861301Sbill #define PDIAG 8 1871301Sbill 1881301Sbill /* 1891301Sbill * syntax 1901301Sbill * empty 1911301Sbill * syn0 1921301Sbill */ 1931301Sbill struct command * 1941301Sbill syntax(p1, p2, flags) 19549992Sbostic register struct wordent *p1, *p2; 19649992Sbostic int flags; 1971301Sbill { 1981301Sbill 19949992Sbostic while (p1 != p2) 20049992Sbostic if (any(";&\n", p1->word[0])) 20149992Sbostic p1 = p1->next; 20249992Sbostic else 20349992Sbostic return (syn0(p1, p2, flags)); 20449992Sbostic return (0); 2051301Sbill } 2061301Sbill 2071301Sbill /* 2081301Sbill * syn0 2091301Sbill * syn1 2101301Sbill * syn1 & syntax 2111301Sbill */ 21249992Sbostic static struct command * 2131301Sbill syn0(p1, p2, flags) 21449992Sbostic struct wordent *p1, *p2; 21549992Sbostic int flags; 2161301Sbill { 21749992Sbostic register struct wordent *p; 21849992Sbostic register struct command *t, *t1; 21949992Sbostic int l; 2201301Sbill 22149992Sbostic l = 0; 22249992Sbostic for (p = p1; p != p2; p = p->next) 22349992Sbostic switch (p->word[0]) { 2241301Sbill 22549992Sbostic case '(': 22649992Sbostic l++; 22749992Sbostic continue; 2281301Sbill 22949992Sbostic case ')': 23049992Sbostic l--; 23149992Sbostic if (l < 0) 23249992Sbostic seterror(ERR_TOOMANYRP); 23349992Sbostic continue; 2341301Sbill 23549992Sbostic case '|': 23649992Sbostic if (p->word[1] == '|') 23749992Sbostic continue; 23849992Sbostic /* fall into ... */ 2391301Sbill 24049992Sbostic case '>': 24149992Sbostic if (p->next != p2 && eq(p->next->word, STRand)) 24249992Sbostic p = p->next; 24349992Sbostic continue; 2441301Sbill 24549992Sbostic case '&': 24649992Sbostic if (l != 0) 24749992Sbostic break; 24849992Sbostic if (p->word[1] == '&') 24949992Sbostic continue; 25049992Sbostic t1 = syn1(p1, p, flags); 25149992Sbostic if (t1->t_dtyp == NODE_LIST || 25249992Sbostic t1->t_dtyp == NODE_AND || 25349992Sbostic t1->t_dtyp == NODE_OR) { 25449992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 25549992Sbostic t->t_dtyp = NODE_PAREN; 25649992Sbostic t->t_dflg = F_AMPERSAND | F_NOINTERRUPT; 25749992Sbostic t->t_dspr = t1; 25849992Sbostic t1 = t; 25949992Sbostic } 26049992Sbostic else 26149992Sbostic t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT; 26249992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 26349992Sbostic t->t_dtyp = NODE_LIST; 26449992Sbostic t->t_dflg = 0; 26549992Sbostic t->t_dcar = t1; 26649992Sbostic t->t_dcdr = syntax(p, p2, flags); 26749992Sbostic return (t); 26849992Sbostic } 26949992Sbostic if (l == 0) 27049992Sbostic return (syn1(p1, p2, flags)); 27149992Sbostic seterror(ERR_TOOMANYLP); 27249992Sbostic return (0); 2731301Sbill } 2741301Sbill 2751301Sbill /* 2761301Sbill * syn1 2771301Sbill * syn1a 2781301Sbill * syn1a ; syntax 2791301Sbill */ 28049992Sbostic static struct command * 2811301Sbill syn1(p1, p2, flags) 28249992Sbostic struct wordent *p1, *p2; 28349992Sbostic int flags; 2841301Sbill { 28549992Sbostic register struct wordent *p; 28649992Sbostic register struct command *t; 28749992Sbostic int l; 2881301Sbill 28949992Sbostic l = 0; 29049992Sbostic for (p = p1; p != p2; p = p->next) 29149992Sbostic switch (p->word[0]) { 2921301Sbill 29349992Sbostic case '(': 29449992Sbostic l++; 29549992Sbostic continue; 2961301Sbill 29749992Sbostic case ')': 29849992Sbostic l--; 29949992Sbostic continue; 3001301Sbill 30149992Sbostic case ';': 30249992Sbostic case '\n': 30349992Sbostic if (l != 0) 30449992Sbostic break; 30549992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 30649992Sbostic t->t_dtyp = NODE_LIST; 30749992Sbostic t->t_dcar = syn1a(p1, p, flags); 30849992Sbostic t->t_dcdr = syntax(p->next, p2, flags); 30949992Sbostic if (t->t_dcdr == 0) 31049992Sbostic t->t_dcdr = t->t_dcar, t->t_dcar = 0; 31149992Sbostic return (t); 31249992Sbostic } 31349992Sbostic return (syn1a(p1, p2, flags)); 3141301Sbill } 3151301Sbill 3161301Sbill /* 3171301Sbill * syn1a 3181301Sbill * syn1b 3191301Sbill * syn1b || syn1a 3201301Sbill */ 32149992Sbostic static struct command * 3221301Sbill syn1a(p1, p2, flags) 32349992Sbostic struct wordent *p1, *p2; 32449992Sbostic int flags; 3251301Sbill { 32649992Sbostic register struct wordent *p; 32749992Sbostic register struct command *t; 32849992Sbostic register int l = 0; 3291301Sbill 33049992Sbostic for (p = p1; p != p2; p = p->next) 33149992Sbostic switch (p->word[0]) { 3321301Sbill 33349992Sbostic case '(': 33449992Sbostic l++; 33549992Sbostic continue; 3361301Sbill 33749992Sbostic case ')': 33849992Sbostic l--; 33949992Sbostic continue; 3401301Sbill 34149992Sbostic case '|': 34249992Sbostic if (p->word[1] != '|') 34349992Sbostic continue; 34449992Sbostic if (l == 0) { 34549992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 34649992Sbostic t->t_dtyp = NODE_OR; 34749992Sbostic t->t_dcar = syn1b(p1, p, flags); 34849992Sbostic t->t_dcdr = syn1a(p->next, p2, flags); 34949992Sbostic t->t_dflg = 0; 35049992Sbostic return (t); 35149992Sbostic } 35249992Sbostic continue; 35349992Sbostic } 35449992Sbostic return (syn1b(p1, p2, flags)); 3551301Sbill } 3561301Sbill 3571301Sbill /* 3581301Sbill * syn1b 3591301Sbill * syn2 3601301Sbill * syn2 && syn1b 3611301Sbill */ 36249992Sbostic static struct command * 3631301Sbill syn1b(p1, p2, flags) 36449992Sbostic struct wordent *p1, *p2; 36549992Sbostic int flags; 3661301Sbill { 36749992Sbostic register struct wordent *p; 36849992Sbostic register struct command *t; 36949992Sbostic register int l = 0; 3701301Sbill 37149992Sbostic for (p = p1; p != p2; p = p->next) 37249992Sbostic switch (p->word[0]) { 3731301Sbill 37449992Sbostic case '(': 37549992Sbostic l++; 37649992Sbostic continue; 3771301Sbill 37849992Sbostic case ')': 37949992Sbostic l--; 38049992Sbostic continue; 3811301Sbill 38249992Sbostic case '&': 38349992Sbostic if (p->word[1] == '&' && l == 0) { 38449992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 38549992Sbostic t->t_dtyp = NODE_AND; 38649992Sbostic t->t_dcar = syn2(p1, p, flags); 38749992Sbostic t->t_dcdr = syn1b(p->next, p2, flags); 38849992Sbostic t->t_dflg = 0; 38949992Sbostic return (t); 39049992Sbostic } 39149992Sbostic continue; 39249992Sbostic } 39349992Sbostic return (syn2(p1, p2, flags)); 3941301Sbill } 3951301Sbill 3961301Sbill /* 3971301Sbill * syn2 3981301Sbill * syn3 3991301Sbill * syn3 | syn2 4001301Sbill * syn3 |& syn2 4011301Sbill */ 40249992Sbostic static struct command * 4031301Sbill syn2(p1, p2, flags) 40449992Sbostic struct wordent *p1, *p2; 40549992Sbostic int flags; 4061301Sbill { 40749992Sbostic register struct wordent *p, *pn; 40849992Sbostic register struct command *t; 40949992Sbostic register int l = 0; 41049992Sbostic int f; 4111301Sbill 41249992Sbostic for (p = p1; p != p2; p = p->next) 41349992Sbostic switch (p->word[0]) { 4141301Sbill 41549992Sbostic case '(': 41649992Sbostic l++; 41749992Sbostic continue; 4181301Sbill 41949992Sbostic case ')': 42049992Sbostic l--; 42149992Sbostic continue; 4221301Sbill 42349992Sbostic case '|': 42449992Sbostic if (l != 0) 42549992Sbostic continue; 42649992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 42749992Sbostic f = flags | POUT; 42849992Sbostic pn = p->next; 42949992Sbostic if (pn != p2 && pn->word[0] == '&') { 43049992Sbostic f |= PDIAG; 43149992Sbostic t->t_dflg |= F_STDERR; 43249992Sbostic } 43349992Sbostic t->t_dtyp = NODE_PIPE; 43449992Sbostic t->t_dcar = syn3(p1, p, f); 43549992Sbostic if (pn != p2 && pn->word[0] == '&') 43649992Sbostic p = pn; 43749992Sbostic t->t_dcdr = syn2(p->next, p2, flags | PIN); 43849992Sbostic return (t); 43949992Sbostic } 44049992Sbostic return (syn3(p1, p2, flags)); 4411301Sbill } 4421301Sbill 44349992Sbostic static char RELPAR[] = {'<', '>', '(', ')', '\0'}; 4441301Sbill 4451301Sbill /* 4461301Sbill * syn3 4471301Sbill * ( syn0 ) [ < in ] [ > out ] 4481301Sbill * word word* [ < in ] [ > out ] 4491301Sbill * KEYWORD ( word* ) word* [ < in ] [ > out ] 4501301Sbill * 4511301Sbill * KEYWORD = (@ exit foreach if set switch test while) 4521301Sbill */ 45349992Sbostic static struct command * 4541301Sbill syn3(p1, p2, flags) 45549992Sbostic struct wordent *p1, *p2; 45649992Sbostic int flags; 4571301Sbill { 45849992Sbostic register struct wordent *p; 45949992Sbostic struct wordent *lp, *rp; 46049992Sbostic register struct command *t; 46149992Sbostic register int l; 46249992Sbostic Char **av; 46349992Sbostic int n, c; 46449992Sbostic bool specp = 0; 4651301Sbill 46649992Sbostic if (p1 != p2) { 46749992Sbostic p = p1; 4681301Sbill again: 46949992Sbostic switch (srchx(p->word)) { 4701301Sbill 47149992Sbostic case T_ELSE: 47249992Sbostic p = p->next; 47349992Sbostic if (p != p2) 47449992Sbostic goto again; 47549992Sbostic break; 4761301Sbill 47749992Sbostic case T_EXIT: 47849992Sbostic case T_FOREACH: 47949992Sbostic case T_IF: 48049992Sbostic case T_LET: 48149992Sbostic case T_SET: 48249992Sbostic case T_SWITCH: 48349992Sbostic case T_WHILE: 48449992Sbostic specp = 1; 48549992Sbostic break; 4861301Sbill } 48749992Sbostic } 48849992Sbostic n = 0; 48949992Sbostic l = 0; 49049992Sbostic for (p = p1; p != p2; p = p->next) 49149992Sbostic switch (p->word[0]) { 4921301Sbill 49349992Sbostic case '(': 49449992Sbostic if (specp) 49549992Sbostic n++; 49649992Sbostic l++; 49749992Sbostic continue; 4981301Sbill 49949992Sbostic case ')': 50049992Sbostic if (specp) 50149992Sbostic n++; 50249992Sbostic l--; 50349992Sbostic continue; 5041301Sbill 50549992Sbostic case '>': 50649992Sbostic case '<': 50749992Sbostic if (l != 0) { 50849992Sbostic if (specp) 50949992Sbostic n++; 51049992Sbostic continue; 51149992Sbostic } 51249992Sbostic if (p->next == p2) 51349992Sbostic continue; 51449992Sbostic if (any(RELPAR, p->next->word[0])) 51549992Sbostic continue; 51649992Sbostic n--; 51749992Sbostic continue; 5181301Sbill 51949992Sbostic default: 52049992Sbostic if (!specp && l != 0) 52149992Sbostic continue; 52249992Sbostic n++; 52349992Sbostic continue; 52449992Sbostic } 52549992Sbostic if (n < 0) 5261301Sbill n = 0; 52749992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 52849992Sbostic av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **)); 52949992Sbostic t->t_dcom = av; 53049992Sbostic n = 0; 53149992Sbostic if (p2->word[0] == ')') 53249992Sbostic t->t_dflg = F_NOFORK; 53349992Sbostic lp = 0; 53449992Sbostic rp = 0; 53549992Sbostic l = 0; 53649992Sbostic for (p = p1; p != p2; p = p->next) { 53749992Sbostic c = p->word[0]; 53849992Sbostic switch (c) { 5391301Sbill 54049992Sbostic case '(': 54149992Sbostic if (l == 0) { 54249992Sbostic if (lp != 0 && !specp) 54349992Sbostic seterror(ERR_BADPLP); 54449992Sbostic lp = p->next; 54549992Sbostic } 54649992Sbostic l++; 54749992Sbostic goto savep; 5481301Sbill 54949992Sbostic case ')': 55049992Sbostic l--; 55149992Sbostic if (l == 0) 55249992Sbostic rp = p; 55349992Sbostic goto savep; 5541301Sbill 55549992Sbostic case '>': 55649992Sbostic if (l != 0) 55749992Sbostic goto savep; 55849992Sbostic if (p->word[1] == '>') 55949992Sbostic t->t_dflg |= F_APPEND; 56049992Sbostic if (p->next != p2 && eq(p->next->word, STRand)) { 56149992Sbostic t->t_dflg |= F_STDERR, p = p->next; 56249992Sbostic if (flags & (POUT | PDIAG)) { 56349992Sbostic seterror(ERR_OUTRED); 56449992Sbostic continue; 56549992Sbostic } 56649992Sbostic } 56749992Sbostic if (p->next != p2 && eq(p->next->word, STRbang)) 56849992Sbostic t->t_dflg |= F_OVERWRITE, p = p->next; 56949992Sbostic if (p->next == p2) { 57049992Sbostic seterror(ERR_MISRED); 57149992Sbostic continue; 57249992Sbostic } 57349992Sbostic p = p->next; 57449992Sbostic if (any(RELPAR, p->word[0])) { 57549992Sbostic seterror(ERR_MISRED); 57649992Sbostic continue; 57749992Sbostic } 57849992Sbostic if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit) 57949992Sbostic seterror(ERR_OUTRED); 58049992Sbostic else 58149992Sbostic t->t_drit = Strsave(p->word); 58249992Sbostic continue; 5831301Sbill 58449992Sbostic case '<': 58549992Sbostic if (l != 0) 58649992Sbostic goto savep; 58749992Sbostic if (p->word[1] == '<') 58849992Sbostic t->t_dflg |= F_READ; 58949992Sbostic if (p->next == p2) { 59049992Sbostic seterror(ERR_MISRED); 59149992Sbostic continue; 59249992Sbostic } 59349992Sbostic p = p->next; 59449992Sbostic if (any(RELPAR, p->word[0])) { 59549992Sbostic seterror(ERR_MISRED); 59649992Sbostic continue; 59749992Sbostic } 59849992Sbostic if ((flags & PHERE) && (t->t_dflg & F_READ)) 59949992Sbostic seterror(ERR_REDPAR); 60049992Sbostic else if ((flags & PIN) || t->t_dlef) 60149992Sbostic seterror(ERR_INRED); 60249992Sbostic else 60349992Sbostic t->t_dlef = Strsave(p->word); 60449992Sbostic continue; 6051301Sbill 60649992Sbostic savep: 60749992Sbostic if (!specp) 60849992Sbostic continue; 60949992Sbostic default: 61049992Sbostic if (l != 0 && !specp) 61149992Sbostic continue; 61249992Sbostic if (seterr == 0) 61349992Sbostic av[n] = Strsave(p->word); 61449992Sbostic n++; 61549992Sbostic continue; 6161301Sbill } 61749992Sbostic } 61849992Sbostic if (lp != 0 && !specp) { 61949992Sbostic if (n != 0) 62049992Sbostic seterror(ERR_BADPLPS); 62149992Sbostic t->t_dtyp = NODE_PAREN; 62249992Sbostic t->t_dspr = syn0(lp, rp, PHERE); 62349992Sbostic } 62449992Sbostic else { 62549992Sbostic if (n == 0) 62649992Sbostic seterror(ERR_NULLCOM); 62749992Sbostic t->t_dtyp = NODE_COMMAND; 62849992Sbostic } 62949992Sbostic return (t); 6301301Sbill } 6311301Sbill 63249992Sbostic void 6331301Sbill freesyn(t) 63449992Sbostic register struct command *t; 6351301Sbill { 63649992Sbostic register Char **v; 6371301Sbill 63849992Sbostic if (t == 0) 63949992Sbostic return; 64049992Sbostic switch (t->t_dtyp) { 6411301Sbill 64249992Sbostic case NODE_COMMAND: 64349992Sbostic for (v = t->t_dcom; *v; v++) 64449992Sbostic xfree((ptr_t) * v); 64549992Sbostic xfree((ptr_t) (t->t_dcom)); 64649992Sbostic xfree((ptr_t) t->t_dlef); 64749992Sbostic xfree((ptr_t) t->t_drit); 64849992Sbostic break; 64949992Sbostic case NODE_PAREN: 65049992Sbostic freesyn(t->t_dspr); 65149992Sbostic xfree((ptr_t) t->t_dlef); 65249992Sbostic xfree((ptr_t) t->t_drit); 65349992Sbostic break; 6541301Sbill 65549992Sbostic case NODE_AND: 65649992Sbostic case NODE_OR: 65749992Sbostic case NODE_PIPE: 65849992Sbostic case NODE_LIST: 65949992Sbostic freesyn(t->t_dcar), freesyn(t->t_dcdr); 66049992Sbostic break; 66149992Sbostic } 66249992Sbostic xfree((ptr_t) t); 6631301Sbill } 664