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*50023Sbostic static char sccsid[] = "@(#)parse.c 5.8 (Berkeley) 06/07/91"; 1047823Sbostic #endif /* not lint */ 111301Sbill 12*50023Sbostic #include "csh.h" 13*50023Sbostic #include "extern.h" 141301Sbill 1549992Sbostic static void asyntax(); 1649992Sbostic static void asyn0(); 1749992Sbostic static void asyn3(); 1849992Sbostic static struct wordent *freenod(); 1949992Sbostic static struct command *syn0(); 2049992Sbostic static struct command *syn1(); 2149992Sbostic static struct command *syn1a(); 2249992Sbostic static struct command *syn1b(); 2349992Sbostic static struct command *syn2(); 2449992Sbostic static struct command *syn3(); 251301Sbill 2649992Sbostic #define ALEFT 21 /* max of 20 alias expansions */ 2749992Sbostic #define HLEFT 11 /* max of 10 history expansions */ 281301Sbill /* 291301Sbill * Perform aliasing on the word list lex 301301Sbill * Do a (very rudimentary) parse to separate into commands. 311301Sbill * If word 0 of a command has an alias, do it. 321301Sbill * Repeat a maximum of 20 times. 331301Sbill */ 3449992Sbostic static int aleft; 3549992Sbostic extern int hleft; 3649992Sbostic void 371301Sbill alias(lex) 3849992Sbostic register struct wordent *lex; 391301Sbill { 4049992Sbostic jmp_buf osetexit; 411301Sbill 4249992Sbostic aleft = ALEFT; 4349992Sbostic hleft = HLEFT; 4449992Sbostic getexit(osetexit); 4549992Sbostic (void) setexit(); 4649992Sbostic if (haderr) { 471301Sbill resexit(osetexit); 4849992Sbostic reset(); 4949992Sbostic } 5049992Sbostic if (--aleft == 0) 5149992Sbostic stderror(ERR_ALIASLOOP); 5249992Sbostic asyntax(lex->next, lex); 5349992Sbostic resexit(osetexit); 541301Sbill } 551301Sbill 5649992Sbostic static void 571301Sbill asyntax(p1, p2) 5849992Sbostic register struct wordent *p1, *p2; 591301Sbill { 6049992Sbostic while (p1 != p2) 6149992Sbostic if (any(";&\n", p1->word[0])) 6249992Sbostic p1 = p1->next; 6349992Sbostic else { 6449992Sbostic asyn0(p1, p2); 6549992Sbostic return; 6649992Sbostic } 671301Sbill } 681301Sbill 6949992Sbostic static void 701301Sbill asyn0(p1, p2) 7149992Sbostic struct wordent *p1; 7249992Sbostic register struct wordent *p2; 731301Sbill { 7449992Sbostic register struct wordent *p; 7549992Sbostic register int l = 0; 761301Sbill 7749992Sbostic for (p = p1; p != p2; p = p->next) 7849992Sbostic switch (p->word[0]) { 791301Sbill 8049992Sbostic case '(': 8149992Sbostic l++; 8249992Sbostic continue; 831301Sbill 8449992Sbostic case ')': 8549992Sbostic l--; 8649992Sbostic if (l < 0) 8749992Sbostic stderror(ERR_TOOMANYRP); 8849992Sbostic continue; 891301Sbill 9049992Sbostic case '>': 9149992Sbostic if (p->next != p2 && eq(p->next->word, STRand)) 9249992Sbostic p = p->next; 9349992Sbostic continue; 941301Sbill 9549992Sbostic case '&': 9649992Sbostic case '|': 9749992Sbostic case ';': 9849992Sbostic case '\n': 9949992Sbostic if (l != 0) 10049992Sbostic continue; 10149992Sbostic asyn3(p1, p); 10249992Sbostic asyntax(p->next, p2); 10349992Sbostic return; 10449992Sbostic } 10549992Sbostic if (l == 0) 10649992Sbostic asyn3(p1, p2); 1071301Sbill } 1081301Sbill 10949992Sbostic static void 1101301Sbill asyn3(p1, p2) 11149992Sbostic struct wordent *p1; 11249992Sbostic register struct wordent *p2; 1131301Sbill { 11449992Sbostic register struct varent *ap; 11549992Sbostic struct wordent alout; 11649992Sbostic register bool redid; 1171301Sbill 11849992Sbostic if (p1 == p2) 11949992Sbostic return; 12049992Sbostic if (p1->word[0] == '(') { 12149992Sbostic for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev) 12249992Sbostic if (p2 == p1) 1231301Sbill return; 12449992Sbostic if (p2 == p1->next) 12549992Sbostic return; 12649992Sbostic asyn0(p1->next, p2); 12749992Sbostic return; 12849992Sbostic } 12949992Sbostic ap = adrof1(p1->word, &aliases); 13049992Sbostic if (ap == 0) 13149992Sbostic return; 13249992Sbostic alhistp = p1->prev; 13349992Sbostic alhistt = p2; 13449992Sbostic alvec = ap->vec; 13549992Sbostic redid = lex(&alout); 13649992Sbostic alhistp = alhistt = 0; 13749992Sbostic alvec = 0; 13849992Sbostic if (seterr) { 13949992Sbostic freelex(&alout); 14049992Sbostic stderror(ERR_OLD); 14149992Sbostic } 14249992Sbostic if (p1->word[0] && eq(p1->word, alout.next->word)) { 14349992Sbostic Char *cp = alout.next->word; 1441301Sbill 14549992Sbostic alout.next->word = Strspl(STRQNULL, cp); 14649992Sbostic xfree((ptr_t) cp); 14749992Sbostic } 14849992Sbostic p1 = freenod(p1, redid ? p2 : p1->next); 14949992Sbostic if (alout.next != &alout) { 15049992Sbostic p1->next->prev = alout.prev->prev; 15149992Sbostic alout.prev->prev->next = p1->next; 15249992Sbostic alout.next->prev = p1; 15349992Sbostic p1->next = alout.next; 15449992Sbostic xfree((ptr_t) alout.prev->word); 15549992Sbostic xfree((ptr_t) (alout.prev)); 15649992Sbostic } 15749992Sbostic reset(); /* throw! */ 1581301Sbill } 1591301Sbill 16049992Sbostic static struct wordent * 1611301Sbill freenod(p1, p2) 16249992Sbostic register struct wordent *p1, *p2; 1631301Sbill { 16449992Sbostic register struct wordent *retp = p1->prev; 1651301Sbill 16649992Sbostic while (p1 != p2) { 16749992Sbostic xfree((ptr_t) p1->word); 16849992Sbostic p1 = p1->next; 16949992Sbostic xfree((ptr_t) (p1->prev)); 17049992Sbostic } 17149992Sbostic retp->next = p2; 17249992Sbostic p2->prev = retp; 17349992Sbostic return (retp); 1741301Sbill } 1751301Sbill 1761301Sbill #define PHERE 1 1771301Sbill #define PIN 2 1781301Sbill #define POUT 4 1791301Sbill #define PDIAG 8 1801301Sbill 1811301Sbill /* 1821301Sbill * syntax 1831301Sbill * empty 1841301Sbill * syn0 1851301Sbill */ 1861301Sbill struct command * 1871301Sbill syntax(p1, p2, flags) 18849992Sbostic register struct wordent *p1, *p2; 18949992Sbostic int flags; 1901301Sbill { 1911301Sbill 19249992Sbostic while (p1 != p2) 19349992Sbostic if (any(";&\n", p1->word[0])) 19449992Sbostic p1 = p1->next; 19549992Sbostic else 19649992Sbostic return (syn0(p1, p2, flags)); 19749992Sbostic return (0); 1981301Sbill } 1991301Sbill 2001301Sbill /* 2011301Sbill * syn0 2021301Sbill * syn1 2031301Sbill * syn1 & syntax 2041301Sbill */ 20549992Sbostic static struct command * 2061301Sbill syn0(p1, p2, flags) 20749992Sbostic struct wordent *p1, *p2; 20849992Sbostic int flags; 2091301Sbill { 21049992Sbostic register struct wordent *p; 21149992Sbostic register struct command *t, *t1; 21249992Sbostic int l; 2131301Sbill 21449992Sbostic l = 0; 21549992Sbostic for (p = p1; p != p2; p = p->next) 21649992Sbostic switch (p->word[0]) { 2171301Sbill 21849992Sbostic case '(': 21949992Sbostic l++; 22049992Sbostic continue; 2211301Sbill 22249992Sbostic case ')': 22349992Sbostic l--; 22449992Sbostic if (l < 0) 22549992Sbostic seterror(ERR_TOOMANYRP); 22649992Sbostic continue; 2271301Sbill 22849992Sbostic case '|': 22949992Sbostic if (p->word[1] == '|') 23049992Sbostic continue; 23149992Sbostic /* fall into ... */ 2321301Sbill 23349992Sbostic case '>': 23449992Sbostic if (p->next != p2 && eq(p->next->word, STRand)) 23549992Sbostic p = p->next; 23649992Sbostic continue; 2371301Sbill 23849992Sbostic case '&': 23949992Sbostic if (l != 0) 24049992Sbostic break; 24149992Sbostic if (p->word[1] == '&') 24249992Sbostic continue; 24349992Sbostic t1 = syn1(p1, p, flags); 24449992Sbostic if (t1->t_dtyp == NODE_LIST || 24549992Sbostic t1->t_dtyp == NODE_AND || 24649992Sbostic t1->t_dtyp == NODE_OR) { 24749992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 24849992Sbostic t->t_dtyp = NODE_PAREN; 24949992Sbostic t->t_dflg = F_AMPERSAND | F_NOINTERRUPT; 25049992Sbostic t->t_dspr = t1; 25149992Sbostic t1 = t; 25249992Sbostic } 25349992Sbostic else 25449992Sbostic t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT; 25549992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 25649992Sbostic t->t_dtyp = NODE_LIST; 25749992Sbostic t->t_dflg = 0; 25849992Sbostic t->t_dcar = t1; 25949992Sbostic t->t_dcdr = syntax(p, p2, flags); 26049992Sbostic return (t); 26149992Sbostic } 26249992Sbostic if (l == 0) 26349992Sbostic return (syn1(p1, p2, flags)); 26449992Sbostic seterror(ERR_TOOMANYLP); 26549992Sbostic return (0); 2661301Sbill } 2671301Sbill 2681301Sbill /* 2691301Sbill * syn1 2701301Sbill * syn1a 2711301Sbill * syn1a ; syntax 2721301Sbill */ 27349992Sbostic static struct command * 2741301Sbill syn1(p1, p2, flags) 27549992Sbostic struct wordent *p1, *p2; 27649992Sbostic int flags; 2771301Sbill { 27849992Sbostic register struct wordent *p; 27949992Sbostic register struct command *t; 28049992Sbostic int l; 2811301Sbill 28249992Sbostic l = 0; 28349992Sbostic for (p = p1; p != p2; p = p->next) 28449992Sbostic switch (p->word[0]) { 2851301Sbill 28649992Sbostic case '(': 28749992Sbostic l++; 28849992Sbostic continue; 2891301Sbill 29049992Sbostic case ')': 29149992Sbostic l--; 29249992Sbostic continue; 2931301Sbill 29449992Sbostic case ';': 29549992Sbostic case '\n': 29649992Sbostic if (l != 0) 29749992Sbostic break; 29849992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 29949992Sbostic t->t_dtyp = NODE_LIST; 30049992Sbostic t->t_dcar = syn1a(p1, p, flags); 30149992Sbostic t->t_dcdr = syntax(p->next, p2, flags); 30249992Sbostic if (t->t_dcdr == 0) 30349992Sbostic t->t_dcdr = t->t_dcar, t->t_dcar = 0; 30449992Sbostic return (t); 30549992Sbostic } 30649992Sbostic return (syn1a(p1, p2, flags)); 3071301Sbill } 3081301Sbill 3091301Sbill /* 3101301Sbill * syn1a 3111301Sbill * syn1b 3121301Sbill * syn1b || syn1a 3131301Sbill */ 31449992Sbostic static struct command * 3151301Sbill syn1a(p1, p2, flags) 31649992Sbostic struct wordent *p1, *p2; 31749992Sbostic int flags; 3181301Sbill { 31949992Sbostic register struct wordent *p; 32049992Sbostic register struct command *t; 32149992Sbostic register int l = 0; 3221301Sbill 32349992Sbostic for (p = p1; p != p2; p = p->next) 32449992Sbostic switch (p->word[0]) { 3251301Sbill 32649992Sbostic case '(': 32749992Sbostic l++; 32849992Sbostic continue; 3291301Sbill 33049992Sbostic case ')': 33149992Sbostic l--; 33249992Sbostic continue; 3331301Sbill 33449992Sbostic case '|': 33549992Sbostic if (p->word[1] != '|') 33649992Sbostic continue; 33749992Sbostic if (l == 0) { 33849992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 33949992Sbostic t->t_dtyp = NODE_OR; 34049992Sbostic t->t_dcar = syn1b(p1, p, flags); 34149992Sbostic t->t_dcdr = syn1a(p->next, p2, flags); 34249992Sbostic t->t_dflg = 0; 34349992Sbostic return (t); 34449992Sbostic } 34549992Sbostic continue; 34649992Sbostic } 34749992Sbostic return (syn1b(p1, p2, flags)); 3481301Sbill } 3491301Sbill 3501301Sbill /* 3511301Sbill * syn1b 3521301Sbill * syn2 3531301Sbill * syn2 && syn1b 3541301Sbill */ 35549992Sbostic static struct command * 3561301Sbill syn1b(p1, p2, flags) 35749992Sbostic struct wordent *p1, *p2; 35849992Sbostic int flags; 3591301Sbill { 36049992Sbostic register struct wordent *p; 36149992Sbostic register struct command *t; 36249992Sbostic register int l = 0; 3631301Sbill 36449992Sbostic for (p = p1; p != p2; p = p->next) 36549992Sbostic switch (p->word[0]) { 3661301Sbill 36749992Sbostic case '(': 36849992Sbostic l++; 36949992Sbostic continue; 3701301Sbill 37149992Sbostic case ')': 37249992Sbostic l--; 37349992Sbostic continue; 3741301Sbill 37549992Sbostic case '&': 37649992Sbostic if (p->word[1] == '&' && l == 0) { 37749992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 37849992Sbostic t->t_dtyp = NODE_AND; 37949992Sbostic t->t_dcar = syn2(p1, p, flags); 38049992Sbostic t->t_dcdr = syn1b(p->next, p2, flags); 38149992Sbostic t->t_dflg = 0; 38249992Sbostic return (t); 38349992Sbostic } 38449992Sbostic continue; 38549992Sbostic } 38649992Sbostic return (syn2(p1, p2, flags)); 3871301Sbill } 3881301Sbill 3891301Sbill /* 3901301Sbill * syn2 3911301Sbill * syn3 3921301Sbill * syn3 | syn2 3931301Sbill * syn3 |& syn2 3941301Sbill */ 39549992Sbostic static struct command * 3961301Sbill syn2(p1, p2, flags) 39749992Sbostic struct wordent *p1, *p2; 39849992Sbostic int flags; 3991301Sbill { 40049992Sbostic register struct wordent *p, *pn; 40149992Sbostic register struct command *t; 40249992Sbostic register int l = 0; 40349992Sbostic int f; 4041301Sbill 40549992Sbostic for (p = p1; p != p2; p = p->next) 40649992Sbostic switch (p->word[0]) { 4071301Sbill 40849992Sbostic case '(': 40949992Sbostic l++; 41049992Sbostic continue; 4111301Sbill 41249992Sbostic case ')': 41349992Sbostic l--; 41449992Sbostic continue; 4151301Sbill 41649992Sbostic case '|': 41749992Sbostic if (l != 0) 41849992Sbostic continue; 41949992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 42049992Sbostic f = flags | POUT; 42149992Sbostic pn = p->next; 42249992Sbostic if (pn != p2 && pn->word[0] == '&') { 42349992Sbostic f |= PDIAG; 42449992Sbostic t->t_dflg |= F_STDERR; 42549992Sbostic } 42649992Sbostic t->t_dtyp = NODE_PIPE; 42749992Sbostic t->t_dcar = syn3(p1, p, f); 42849992Sbostic if (pn != p2 && pn->word[0] == '&') 42949992Sbostic p = pn; 43049992Sbostic t->t_dcdr = syn2(p->next, p2, flags | PIN); 43149992Sbostic return (t); 43249992Sbostic } 43349992Sbostic return (syn3(p1, p2, flags)); 4341301Sbill } 4351301Sbill 43649992Sbostic static char RELPAR[] = {'<', '>', '(', ')', '\0'}; 4371301Sbill 4381301Sbill /* 4391301Sbill * syn3 4401301Sbill * ( syn0 ) [ < in ] [ > out ] 4411301Sbill * word word* [ < in ] [ > out ] 4421301Sbill * KEYWORD ( word* ) word* [ < in ] [ > out ] 4431301Sbill * 4441301Sbill * KEYWORD = (@ exit foreach if set switch test while) 4451301Sbill */ 44649992Sbostic static struct command * 4471301Sbill syn3(p1, p2, flags) 44849992Sbostic struct wordent *p1, *p2; 44949992Sbostic int flags; 4501301Sbill { 45149992Sbostic register struct wordent *p; 45249992Sbostic struct wordent *lp, *rp; 45349992Sbostic register struct command *t; 45449992Sbostic register int l; 45549992Sbostic Char **av; 45649992Sbostic int n, c; 45749992Sbostic bool specp = 0; 4581301Sbill 45949992Sbostic if (p1 != p2) { 46049992Sbostic p = p1; 4611301Sbill again: 46249992Sbostic switch (srchx(p->word)) { 4631301Sbill 46449992Sbostic case T_ELSE: 46549992Sbostic p = p->next; 46649992Sbostic if (p != p2) 46749992Sbostic goto again; 46849992Sbostic break; 4691301Sbill 47049992Sbostic case T_EXIT: 47149992Sbostic case T_FOREACH: 47249992Sbostic case T_IF: 47349992Sbostic case T_LET: 47449992Sbostic case T_SET: 47549992Sbostic case T_SWITCH: 47649992Sbostic case T_WHILE: 47749992Sbostic specp = 1; 47849992Sbostic break; 4791301Sbill } 48049992Sbostic } 48149992Sbostic n = 0; 48249992Sbostic l = 0; 48349992Sbostic for (p = p1; p != p2; p = p->next) 48449992Sbostic switch (p->word[0]) { 4851301Sbill 48649992Sbostic case '(': 48749992Sbostic if (specp) 48849992Sbostic n++; 48949992Sbostic l++; 49049992Sbostic continue; 4911301Sbill 49249992Sbostic case ')': 49349992Sbostic if (specp) 49449992Sbostic n++; 49549992Sbostic l--; 49649992Sbostic continue; 4971301Sbill 49849992Sbostic case '>': 49949992Sbostic case '<': 50049992Sbostic if (l != 0) { 50149992Sbostic if (specp) 50249992Sbostic n++; 50349992Sbostic continue; 50449992Sbostic } 50549992Sbostic if (p->next == p2) 50649992Sbostic continue; 50749992Sbostic if (any(RELPAR, p->next->word[0])) 50849992Sbostic continue; 50949992Sbostic n--; 51049992Sbostic continue; 5111301Sbill 51249992Sbostic default: 51349992Sbostic if (!specp && l != 0) 51449992Sbostic continue; 51549992Sbostic n++; 51649992Sbostic continue; 51749992Sbostic } 51849992Sbostic if (n < 0) 5191301Sbill n = 0; 52049992Sbostic t = (struct command *) xcalloc(1, sizeof(*t)); 52149992Sbostic av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **)); 52249992Sbostic t->t_dcom = av; 52349992Sbostic n = 0; 52449992Sbostic if (p2->word[0] == ')') 52549992Sbostic t->t_dflg = F_NOFORK; 52649992Sbostic lp = 0; 52749992Sbostic rp = 0; 52849992Sbostic l = 0; 52949992Sbostic for (p = p1; p != p2; p = p->next) { 53049992Sbostic c = p->word[0]; 53149992Sbostic switch (c) { 5321301Sbill 53349992Sbostic case '(': 53449992Sbostic if (l == 0) { 53549992Sbostic if (lp != 0 && !specp) 53649992Sbostic seterror(ERR_BADPLP); 53749992Sbostic lp = p->next; 53849992Sbostic } 53949992Sbostic l++; 54049992Sbostic goto savep; 5411301Sbill 54249992Sbostic case ')': 54349992Sbostic l--; 54449992Sbostic if (l == 0) 54549992Sbostic rp = p; 54649992Sbostic goto savep; 5471301Sbill 54849992Sbostic case '>': 54949992Sbostic if (l != 0) 55049992Sbostic goto savep; 55149992Sbostic if (p->word[1] == '>') 55249992Sbostic t->t_dflg |= F_APPEND; 55349992Sbostic if (p->next != p2 && eq(p->next->word, STRand)) { 55449992Sbostic t->t_dflg |= F_STDERR, p = p->next; 55549992Sbostic if (flags & (POUT | PDIAG)) { 55649992Sbostic seterror(ERR_OUTRED); 55749992Sbostic continue; 55849992Sbostic } 55949992Sbostic } 56049992Sbostic if (p->next != p2 && eq(p->next->word, STRbang)) 56149992Sbostic t->t_dflg |= F_OVERWRITE, p = p->next; 56249992Sbostic if (p->next == p2) { 56349992Sbostic seterror(ERR_MISRED); 56449992Sbostic continue; 56549992Sbostic } 56649992Sbostic p = p->next; 56749992Sbostic if (any(RELPAR, p->word[0])) { 56849992Sbostic seterror(ERR_MISRED); 56949992Sbostic continue; 57049992Sbostic } 57149992Sbostic if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit) 57249992Sbostic seterror(ERR_OUTRED); 57349992Sbostic else 57449992Sbostic t->t_drit = Strsave(p->word); 57549992Sbostic continue; 5761301Sbill 57749992Sbostic case '<': 57849992Sbostic if (l != 0) 57949992Sbostic goto savep; 58049992Sbostic if (p->word[1] == '<') 58149992Sbostic t->t_dflg |= F_READ; 58249992Sbostic if (p->next == p2) { 58349992Sbostic seterror(ERR_MISRED); 58449992Sbostic continue; 58549992Sbostic } 58649992Sbostic p = p->next; 58749992Sbostic if (any(RELPAR, p->word[0])) { 58849992Sbostic seterror(ERR_MISRED); 58949992Sbostic continue; 59049992Sbostic } 59149992Sbostic if ((flags & PHERE) && (t->t_dflg & F_READ)) 59249992Sbostic seterror(ERR_REDPAR); 59349992Sbostic else if ((flags & PIN) || t->t_dlef) 59449992Sbostic seterror(ERR_INRED); 59549992Sbostic else 59649992Sbostic t->t_dlef = Strsave(p->word); 59749992Sbostic continue; 5981301Sbill 59949992Sbostic savep: 60049992Sbostic if (!specp) 60149992Sbostic continue; 60249992Sbostic default: 60349992Sbostic if (l != 0 && !specp) 60449992Sbostic continue; 60549992Sbostic if (seterr == 0) 60649992Sbostic av[n] = Strsave(p->word); 60749992Sbostic n++; 60849992Sbostic continue; 6091301Sbill } 61049992Sbostic } 61149992Sbostic if (lp != 0 && !specp) { 61249992Sbostic if (n != 0) 61349992Sbostic seterror(ERR_BADPLPS); 61449992Sbostic t->t_dtyp = NODE_PAREN; 61549992Sbostic t->t_dspr = syn0(lp, rp, PHERE); 61649992Sbostic } 61749992Sbostic else { 61849992Sbostic if (n == 0) 61949992Sbostic seterror(ERR_NULLCOM); 62049992Sbostic t->t_dtyp = NODE_COMMAND; 62149992Sbostic } 62249992Sbostic return (t); 6231301Sbill } 6241301Sbill 62549992Sbostic void 6261301Sbill freesyn(t) 62749992Sbostic register struct command *t; 6281301Sbill { 62949992Sbostic register Char **v; 6301301Sbill 63149992Sbostic if (t == 0) 63249992Sbostic return; 63349992Sbostic switch (t->t_dtyp) { 6341301Sbill 63549992Sbostic case NODE_COMMAND: 63649992Sbostic for (v = t->t_dcom; *v; v++) 63749992Sbostic xfree((ptr_t) * v); 63849992Sbostic xfree((ptr_t) (t->t_dcom)); 63949992Sbostic xfree((ptr_t) t->t_dlef); 64049992Sbostic xfree((ptr_t) t->t_drit); 64149992Sbostic break; 64249992Sbostic case NODE_PAREN: 64349992Sbostic freesyn(t->t_dspr); 64449992Sbostic xfree((ptr_t) t->t_dlef); 64549992Sbostic xfree((ptr_t) t->t_drit); 64649992Sbostic break; 6471301Sbill 64849992Sbostic case NODE_AND: 64949992Sbostic case NODE_OR: 65049992Sbostic case NODE_PIPE: 65149992Sbostic case NODE_LIST: 65249992Sbostic freesyn(t->t_dcar), freesyn(t->t_dcdr); 65349992Sbostic break; 65449992Sbostic } 65549992Sbostic xfree((ptr_t) t); 6561301Sbill } 657