BSD 4_3_Net_2 release
[unix-history] / usr / src / bin / csh / parse.c
index acf107c..4290301 100644 (file)
  * Copyright (c) 1980, 1991 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1980, 1991 The Regents of the University of California.
  * All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)parse.c    5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)parse.c    5.11 (Berkeley) 6/8/91";
 #endif /* not lint */
 
 #endif /* not lint */
 
-#include "sh.h"
-
-/*
- * C shell
- */
-
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#if __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include "csh.h"
+#include "extern.h"
+
+static void     asyntax __P((struct wordent *, struct wordent *));
+static void     asyn0 __P((struct wordent *, struct wordent *));
+static void     asyn3 __P((struct wordent *, struct wordent *));
+static struct wordent 
+               *freenod __P((struct wordent *, struct wordent *));
+static struct command 
+               *syn0 __P((struct wordent *, struct wordent *, int));
+static struct command 
+               *syn1 __P((struct wordent *, struct wordent *, int));
+static struct command 
+               *syn1a __P((struct wordent *, struct wordent *, int));
+static struct command 
+               *syn1b __P((struct wordent *, struct wordent *, int));
+static struct command 
+               *syn2 __P((struct wordent *, struct wordent *, int));
+static struct command 
+               *syn3 __P((struct wordent *, struct wordent *, int));
+
+#define ALEFT  21              /* max of 20 alias expansions    */
+#define HLEFT  11              /* max of 10 history expansions  */
 /*
  * Perform aliasing on the word list lex
  * Do a (very rudimentary) parse to separate into commands.
  * If word 0 of a command has an alias, do it.
  * Repeat a maximum of 20 times.
  */
 /*
  * Perform aliasing on the word list lex
  * Do a (very rudimentary) parse to separate into commands.
  * If word 0 of a command has an alias, do it.
  * Repeat a maximum of 20 times.
  */
+static int aleft;
+extern int hleft;
+void
 alias(lex)
 alias(lex)
-       register struct wordent *lex;
+    register struct wordent *lex;
 {
 {
-       int aleft = 21;
-       jmp_buf osetexit;
-
-       getexit(osetexit);
-       (void)setjmp(reslab);
-       if (haderr) {
-               resexit(osetexit);
-               longjmp(reslab, 0);
-       }
-       if (--aleft == 0)
-               error("Alias loop");
-       asyntax(lex->next, lex);
+    jmp_buf osetexit;
+
+    aleft = ALEFT;
+    hleft = HLEFT;
+    getexit(osetexit);
+    (void) setexit();
+    if (haderr) {
        resexit(osetexit);
        resexit(osetexit);
+       reset();
+    }
+    if (--aleft == 0)
+       stderror(ERR_ALIASLOOP);
+    asyntax(lex->next, lex);
+    resexit(osetexit);
 }
 
 }
 
+static void
 asyntax(p1, p2)
 asyntax(p1, p2)
-       register struct wordent *p1, *p2;
+    register struct wordent *p1, *p2;
 {
 {
-
-       while (p1 != p2)
-               if (index(";&\n", p1->word[0]))
-                       p1 = p1->next;
-               else {
-                       asyn0(p1, p2);
-                       return;
-               }
+    while (p1 != p2)
+       if (any(";&\n", p1->word[0]))
+           p1 = p1->next;
+       else {
+           asyn0(p1, p2);
+           return;
+       }
 }
 
 }
 
+static void
 asyn0(p1, p2)
 asyn0(p1, p2)
-       struct wordent *p1;
-       register struct wordent *p2;
+    struct wordent *p1;
+    register struct wordent *p2;
 {
 {
-       register struct wordent *p;
-       register int l = 0;
-
-       for (p = p1; p != p2; p = p->next)
-               switch (p->word[0]) {
-
-               case '(':
-                       l++;
-                       continue;
-
-               case ')':
-                       l--;
-                       if (l < 0)
-                               error("Too many )'s");
-                       continue;
-
-               case '>':
-                       if (p->next != p2 && eq(p->next->word, "&"))
-                               p = p->next;
-                       continue;
-
-               case '&':
-               case '|':
-               case ';':
-               case '\n':
-                       if (l != 0)
-                               continue;
-                       asyn3(p1, p);
-                       asyntax(p->next, p2);
-                       return;
-               }
-       if (l == 0)
-               asyn3(p1, p2);
+    register struct wordent *p;
+    register int l = 0;
+
+    for (p = p1; p != p2; p = p->next)
+       switch (p->word[0]) {
+
+       case '(':
+           l++;
+           continue;
+
+       case ')':
+           l--;
+           if (l < 0)
+               stderror(ERR_TOOMANYRP);
+           continue;
+
+       case '>':
+           if (p->next != p2 && eq(p->next->word, STRand))
+               p = p->next;
+           continue;
+
+       case '&':
+       case '|':
+       case ';':
+       case '\n':
+           if (l != 0)
+               continue;
+           asyn3(p1, p);
+           asyntax(p->next, p2);
+           return;
+       }
+    if (l == 0)
+       asyn3(p1, p2);
 }
 
 }
 
+static void
 asyn3(p1, p2)
 asyn3(p1, p2)
-       struct wordent *p1;
-       register struct wordent *p2;
+    struct wordent *p1;
+    register struct wordent *p2;
 {
 {
-       register struct varent *ap;
-       struct wordent alout;
-       register bool redid;
-
-       if (p1 == p2)
-               return;
-       if (p1->word[0] == '(') {
-               for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
-                       if (p2 == p1)
-                               return;
-               if (p2 == p1->next)
-                       return;
-               asyn0(p1->next, p2);
-               return;
-       }
-       ap = adrof1(p1->word, &aliases);
-       if (ap == 0)
+    register struct varent *ap;
+    struct wordent alout;
+    register bool redid;
+
+    if (p1 == p2)
+       return;
+    if (p1->word[0] == '(') {
+       for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
+           if (p2 == p1)
                return;
                return;
-       alhistp = p1->prev;
-       alhistt = p2;
-       alvec = ap->vec;
-       redid = lex(&alout);
-       alhistp = alhistt = 0;
-       alvec = 0;
-       if (err) {
-               freelex(&alout);
-               error(err);
-       }
-       if (p1->word[0] && eq(p1->word, alout.next->word)) {
-               char *cp = alout.next->word;
-
-               alout.next->word = strspl("\200", cp);
-               XFREE(cp)
-       }
-       p1 = freenod(p1, redid ? p2 : p1->next);
-       if (alout.next != &alout) {
-               p1->next->prev = alout.prev->prev;
-               alout.prev->prev->next = p1->next;
-               alout.next->prev = p1;
-               p1->next = alout.next;
-               XFREE(alout.prev->word)
-               XFREE((char *)alout.prev)
-       }
-       longjmp(reslab, 0);             /* throw! */
+       if (p2 == p1->next)
+           return;
+       asyn0(p1->next, p2);
+       return;
+    }
+    ap = adrof1(p1->word, &aliases);
+    if (ap == 0)
+       return;
+    alhistp = p1->prev;
+    alhistt = p2;
+    alvec = ap->vec;
+    redid = lex(&alout);
+    alhistp = alhistt = 0;
+    alvec = 0;
+    if (seterr) {
+       freelex(&alout);
+       stderror(ERR_OLD);
+    }
+    if (p1->word[0] && eq(p1->word, alout.next->word)) {
+       Char   *cp = alout.next->word;
+
+       alout.next->word = Strspl(STRQNULL, cp);
+       xfree((ptr_t) cp);
+    }
+    p1 = freenod(p1, redid ? p2 : p1->next);
+    if (alout.next != &alout) {
+       p1->next->prev = alout.prev->prev;
+       alout.prev->prev->next = p1->next;
+       alout.next->prev = p1;
+       p1->next = alout.next;
+       xfree((ptr_t) alout.prev->word);
+       xfree((ptr_t) (alout.prev));
+    }
+    reset();                   /* throw! */
 }
 
 }
 
-struct wordent *
+static struct wordent *
 freenod(p1, p2)
 freenod(p1, p2)
-       register struct wordent *p1, *p2;
+    register struct wordent *p1, *p2;
 {
 {
-       register struct wordent *retp = p1->prev;
-
-       while (p1 != p2) {
-               XFREE(p1->word)
-               p1 = p1->next;
-               XFREE((char *)p1->prev)
-       }
-       retp->next = p2;
-       p2->prev = retp;
-       return (retp);
+    register struct wordent *retp = p1->prev;
+
+    while (p1 != p2) {
+       xfree((ptr_t) p1->word);
+       p1 = p1->next;
+       xfree((ptr_t) (p1->prev));
+    }
+    retp->next = p2;
+    p2->prev = retp;
+    return (retp);
 }
 
 #define        PHERE   1
 }
 
 #define        PHERE   1
@@ -169,16 +227,16 @@ freenod(p1, p2)
  */
 struct command *
 syntax(p1, p2, flags)
  */
 struct command *
 syntax(p1, p2, flags)
-       register struct wordent *p1, *p2;
-       int flags;
+    register struct wordent *p1, *p2;
+    int     flags;
 {
 
 {
 
-       while (p1 != p2)
-               if (index(";&\n", p1->word[0]))
-                       p1 = p1->next;
-               else
-                       return (syn0(p1, p2, flags));
-       return (0);
+    while (p1 != p2)
+       if (any(";&\n", p1->word[0]))
+           p1 = p1->next;
+       else
+           return (syn0(p1, p2, flags));
+    return (0);
 }
 
 /*
 }
 
 /*
@@ -186,66 +244,67 @@ syntax(p1, p2, flags)
  *     syn1
  *     syn1 & syntax
  */
  *     syn1
  *     syn1 & syntax
  */
-struct command *
+static struct command *
 syn0(p1, p2, flags)
 syn0(p1, p2, flags)
-       struct wordent *p1, *p2;
-       int flags;
+    struct wordent *p1, *p2;
+    int     flags;
 {
 {
-       register struct wordent *p;
-       register struct command *t, *t1;
-       int l;
-
-       l = 0;
-       for (p = p1; p != p2; p = p->next)
-               switch (p->word[0]) {
-
-               case '(':
-                       l++;
-                       continue;
-
-               case ')':
-                       l--;
-                       if (l < 0)
-                               seterr("Too many )'s");
-                       continue;
-
-               case '|':
-                       if (p->word[1] == '|')
-                               continue;
-                       /* fall into ... */
-
-               case '>':
-                       if (p->next != p2 && eq(p->next->word, "&"))
-                               p = p->next;
-                       continue;
-
-               case '&':
-                       if (l != 0)
-                               break;
-                       if (p->word[1] == '&')
-                               continue;
-                       t1 = syn1(p1, p, flags);
-                       if (t1->t_dtyp == NODE_LIST ||
-                           t1->t_dtyp == NODE_AND ||
-                           t1->t_dtyp == NODE_OR) {
-                               t = (struct command *) calloc(1, sizeof (*t));
-                               t->t_dtyp = NODE_PAREN;
-                               t->t_dflg = F_AMPERSAND|F_NOINTERRUPT;
-                               t->t_dspr = t1;
-                               t1 = t;
-                       } else
-                               t1->t_dflg |= F_AMPERSAND|F_NOINTERRUPT;
-                       t = (struct command *) calloc(1, sizeof (*t));
-                       t->t_dtyp = NODE_LIST;
-                       t->t_dflg = 0;
-                       t->t_dcar = t1;
-                       t->t_dcdr = syntax(p, p2, flags);
-                       return(t);
-               }
-       if (l == 0)
-               return (syn1(p1, p2, flags));
-       seterr("Too many ('s");
-       return (0);
+    register struct wordent *p;
+    register struct command *t, *t1;
+    int     l;
+
+    l = 0;
+    for (p = p1; p != p2; p = p->next)
+       switch (p->word[0]) {
+
+       case '(':
+           l++;
+           continue;
+
+       case ')':
+           l--;
+           if (l < 0)
+               seterror(ERR_TOOMANYRP);
+           continue;
+
+       case '|':
+           if (p->word[1] == '|')
+               continue;
+           /* fall into ... */
+
+       case '>':
+           if (p->next != p2 && eq(p->next->word, STRand))
+               p = p->next;
+           continue;
+
+       case '&':
+           if (l != 0)
+               break;
+           if (p->word[1] == '&')
+               continue;
+           t1 = syn1(p1, p, flags);
+           if (t1->t_dtyp == NODE_LIST ||
+               t1->t_dtyp == NODE_AND ||
+               t1->t_dtyp == NODE_OR) {
+               t = (struct command *) xcalloc(1, sizeof(*t));
+               t->t_dtyp = NODE_PAREN;
+               t->t_dflg = F_AMPERSAND | F_NOINTERRUPT;
+               t->t_dspr = t1;
+               t1 = t;
+           }
+           else
+               t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT;
+           t = (struct command *) xcalloc(1, sizeof(*t));
+           t->t_dtyp = NODE_LIST;
+           t->t_dflg = 0;
+           t->t_dcar = t1;
+           t->t_dcdr = syntax(p, p2, flags);
+           return (t);
+       }
+    if (l == 0)
+       return (syn1(p1, p2, flags));
+    seterror(ERR_TOOMANYLP);
+    return (0);
 }
 
 /*
 }
 
 /*
@@ -253,40 +312,40 @@ syn0(p1, p2, flags)
  *     syn1a
  *     syn1a ; syntax
  */
  *     syn1a
  *     syn1a ; syntax
  */
-struct command *
+static struct command *
 syn1(p1, p2, flags)
 syn1(p1, p2, flags)
-       struct wordent *p1, *p2;
-       int flags;
+    struct wordent *p1, *p2;
+    int     flags;
 {
 {
-       register struct wordent *p;
-       register struct command *t;
-       int l;
-
-       l = 0;
-       for (p = p1; p != p2; p = p->next)
-               switch (p->word[0]) {
-
-               case '(':
-                       l++;
-                       continue;
-
-               case ')':
-                       l--;
-                       continue;
-
-               case ';':
-               case '\n':
-                       if (l != 0)
-                               break;
-                       t = (struct command *) calloc(1, sizeof (*t));
-                       t->t_dtyp = NODE_LIST;
-                       t->t_dcar = syn1a(p1, p, flags);
-                       t->t_dcdr = syntax(p->next, p2, flags);
-                       if (t->t_dcdr == 0)
-                               t->t_dcdr = t->t_dcar, t->t_dcar = 0;
-                       return (t);
-               }
-       return (syn1a(p1, p2, flags));
+    register struct wordent *p;
+    register struct command *t;
+    int     l;
+
+    l = 0;
+    for (p = p1; p != p2; p = p->next)
+       switch (p->word[0]) {
+
+       case '(':
+           l++;
+           continue;
+
+       case ')':
+           l--;
+           continue;
+
+       case ';':
+       case '\n':
+           if (l != 0)
+               break;
+           t = (struct command *) xcalloc(1, sizeof(*t));
+           t->t_dtyp = NODE_LIST;
+           t->t_dcar = syn1a(p1, p, flags);
+           t->t_dcdr = syntax(p->next, p2, flags);
+           if (t->t_dcdr == 0)
+               t->t_dcdr = t->t_dcar, t->t_dcar = 0;
+           return (t);
+       }
+    return (syn1a(p1, p2, flags));
 }
 
 /*
 }
 
 /*
@@ -294,40 +353,40 @@ syn1(p1, p2, flags)
  *     syn1b
  *     syn1b || syn1a
  */
  *     syn1b
  *     syn1b || syn1a
  */
-struct command *
+static struct command *
 syn1a(p1, p2, flags)
 syn1a(p1, p2, flags)
-       struct wordent *p1, *p2;
-       int flags;
+    struct wordent *p1, *p2;
+    int     flags;
 {
 {
-       register struct wordent *p;
-       register struct command *t;
-       register int l = 0;
-
-       for (p = p1; p != p2; p = p->next)
-               switch (p->word[0]) {
-
-               case '(':
-                       l++;
-                       continue;
-
-               case ')':
-                       l--;
-                       continue;
-
-               case '|':
-                       if (p->word[1] != '|')
-                               continue;
-                       if (l == 0) {
-                               t = (struct command *) calloc(1, sizeof (*t));
-                               t->t_dtyp = NODE_OR;
-                               t->t_dcar = syn1b(p1, p, flags);
-                               t->t_dcdr = syn1a(p->next, p2, flags);
-                               t->t_dflg = 0;
-                               return (t);
-                       }
-                       continue;
-               }
-       return (syn1b(p1, p2, flags));
+    register struct wordent *p;
+    register struct command *t;
+    register int l = 0;
+
+    for (p = p1; p != p2; p = p->next)
+       switch (p->word[0]) {
+
+       case '(':
+           l++;
+           continue;
+
+       case ')':
+           l--;
+           continue;
+
+       case '|':
+           if (p->word[1] != '|')
+               continue;
+           if (l == 0) {
+               t = (struct command *) xcalloc(1, sizeof(*t));
+               t->t_dtyp = NODE_OR;
+               t->t_dcar = syn1b(p1, p, flags);
+               t->t_dcdr = syn1a(p->next, p2, flags);
+               t->t_dflg = 0;
+               return (t);
+           }
+           continue;
+       }
+    return (syn1b(p1, p2, flags));
 }
 
 /*
 }
 
 /*
@@ -335,39 +394,38 @@ syn1a(p1, p2, flags)
  *     syn2
  *     syn2 && syn1b
  */
  *     syn2
  *     syn2 && syn1b
  */
-struct command *
+static struct command *
 syn1b(p1, p2, flags)
 syn1b(p1, p2, flags)
-       struct wordent *p1, *p2;
-       int flags;
+    struct wordent *p1, *p2;
+    int     flags;
 {
 {
-       register struct wordent *p;
-       register struct command *t;
-       register int l = 0;
-
-       l = 0;
-       for (p = p1; p != p2; p = p->next)
-               switch (p->word[0]) {
-
-               case '(':
-                       l++;
-                       continue;
-
-               case ')':
-                       l--;
-                       continue;
-
-               case '&':
-                       if (p->word[1] == '&' && l == 0) {
-                               t = (struct command *) calloc(1, sizeof (*t));
-                               t->t_dtyp = NODE_AND;
-                               t->t_dcar = syn2(p1, p, flags);
-                               t->t_dcdr = syn1b(p->next, p2, flags);
-                               t->t_dflg = 0;
-                               return (t);
-                       }
-                       continue;
-               }
-       return (syn2(p1, p2, flags));
+    register struct wordent *p;
+    register struct command *t;
+    register int l = 0;
+
+    for (p = p1; p != p2; p = p->next)
+       switch (p->word[0]) {
+
+       case '(':
+           l++;
+           continue;
+
+       case ')':
+           l--;
+           continue;
+
+       case '&':
+           if (p->word[1] == '&' && l == 0) {
+               t = (struct command *) xcalloc(1, sizeof(*t));
+               t->t_dtyp = NODE_AND;
+               t->t_dcar = syn2(p1, p, flags);
+               t->t_dcdr = syn1b(p->next, p2, flags);
+               t->t_dflg = 0;
+               return (t);
+           }
+           continue;
+       }
+    return (syn2(p1, p2, flags));
 }
 
 /*
 }
 
 /*
@@ -376,48 +434,48 @@ syn1b(p1, p2, flags)
  *     syn3 | syn2
  *     syn3 |& syn2
  */
  *     syn3 | syn2
  *     syn3 |& syn2
  */
-struct command *
+static struct command *
 syn2(p1, p2, flags)
 syn2(p1, p2, flags)
-       struct wordent *p1, *p2;
-       int flags;
+    struct wordent *p1, *p2;
+    int     flags;
 {
 {
-       register struct wordent *p, *pn;
-       register struct command *t;
-       register int l = 0;
-       int f;
-
-       for (p = p1; p != p2; p = p->next)
-               switch (p->word[0]) {
-
-               case '(':
-                       l++;
-                       continue;
-
-               case ')':
-                       l--;
-                       continue;
-
-               case '|':
-                       if (l != 0)
-                               continue;
-                       t = (struct command *) calloc(1, sizeof (*t));
-                       f = flags | POUT;
-                       pn = p->next;
-                       if (pn != p2 && pn->word[0] == '&') {
-                               f |= PDIAG;
-                               t->t_dflg |= F_STDERR;
-                       }
-                       t->t_dtyp = NODE_PIPE;
-                       t->t_dcar = syn3(p1, p, f);
-                       if (pn != p2 && pn->word[0] == '&')
-                               p = pn;
-                       t->t_dcdr = syn2(p->next, p2, flags | PIN);
-                       return (t);
-               }
-       return (syn3(p1, p2, flags));
+    register struct wordent *p, *pn;
+    register struct command *t;
+    register int l = 0;
+    int     f;
+
+    for (p = p1; p != p2; p = p->next)
+       switch (p->word[0]) {
+
+       case '(':
+           l++;
+           continue;
+
+       case ')':
+           l--;
+           continue;
+
+       case '|':
+           if (l != 0)
+               continue;
+           t = (struct command *) xcalloc(1, sizeof(*t));
+           f = flags | POUT;
+           pn = p->next;
+           if (pn != p2 && pn->word[0] == '&') {
+               f |= PDIAG;
+               t->t_dflg |= F_STDERR;
+           }
+           t->t_dtyp = NODE_PIPE;
+           t->t_dcar = syn3(p1, p, f);
+           if (pn != p2 && pn->word[0] == '&')
+               p = pn;
+           t->t_dcdr = syn2(p->next, p2, flags | PIN);
+           return (t);
+       }
+    return (syn3(p1, p2, flags));
 }
 
 }
 
-char   *RELPAR =       "<>()";
+static char RELPAR[] = {'<', '>', '(', ')', '\0'};
 
 /*
  * syn3
 
 /*
  * syn3
@@ -427,212 +485,214 @@ char    *RELPAR =       "<>()";
  *
  *     KEYWORD = (@ exit foreach if set switch test while)
  */
  *
  *     KEYWORD = (@ exit foreach if set switch test while)
  */
-struct command *
+static struct command *
 syn3(p1, p2, flags)
 syn3(p1, p2, flags)
-       struct wordent *p1, *p2;
-       int flags;
+    struct wordent *p1, *p2;
+    int     flags;
 {
 {
-       register struct wordent *p;
-       struct wordent *lp, *rp;
-       register struct command *t;
-       register int l;
-       char **av;
-       int n, c;
-       bool specp = 0;
-
-       if (p1 != p2) {
-               p = p1;
+    register struct wordent *p;
+    struct wordent *lp, *rp;
+    register struct command *t;
+    register int l;
+    Char  **av;
+    int     n, c;
+    bool    specp = 0;
+
+    if (p1 != p2) {
+       p = p1;
 again:
 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;
-               }
+       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;
        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 (index(RELPAR, p->next->word[0]))
-                               continue;
-                       n--;
-                       continue;
-
-               default:
-                       if (!specp && l != 0)
-                               continue;
-                       n++;
-                       continue;
-               }
-       if (n < 0)
-               n = 0;
-       t = (struct command *) calloc(1, sizeof (*t));
-       av = (char **) calloc((unsigned) (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)
-                                       seterr("Badly placed (");
-                               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, "&")) {
-                               t->t_dflg |= F_STDERR;
-                               p = p->next;
-                               if (flags & (POUT|PDIAG))
-                                       goto badout;
-                       }
-                       if (p->next != p2 && eq(p->next->word, "!")) {
-                               t->t_dflg |= F_OVERWRITE;
-                               p = p->next;
-                       }
-                       if (p->next == p2) {
-missfile:
-                               seterr("Missing name for redirect");
-                               continue;
-                       }
-                       p = p->next;
-                       if (index(RELPAR, p->word[0]))
-                               goto missfile;
-                       if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit)
-badout:
-                               seterr("Ambiguous output redirect");
-                       else
-                               t->t_drit = savestr(p->word);
-                       continue;
-
-               case '<':
-                       if (l != 0)
-                               goto savep;
-                       if (p->word[1] == '<')
-                               t->t_dflg |= F_READ;
-                       if (p->next == p2)
-                               goto missfile;
-                       p = p->next;
-                       if (index(RELPAR, p->word[0]))
-                               goto missfile;
-                       if ((flags & PHERE) && (t->t_dflg & F_READ))
-                               seterr("Can't << within ()'s");
-                       else if ((flags & PIN) || t->t_dlef)
-                               seterr("Ambiguous input redirect");
-                       else
-                               t->t_dlef = savestr(p->word);
-                       continue;
-
-savep:
-                       if (!specp)
-                               continue;
-               default:
-                       if (l != 0 && !specp)
-                               continue;
-                       if (err == 0)
-                               av[n] = savestr(p->word);
-                       n++;
-                       continue;
+    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 | PDIAG)) {
+                   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 & PDIAG) == 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)
-                       seterr("Badly placed ()'s");
-               t->t_dtyp = NODE_PAREN;
-               t->t_dspr = syn0(lp, rp, PHERE);
-       } else {
-               if (n == 0)
-                       seterr("Invalid null command");
-               t->t_dtyp = NODE_COMMAND;
-       }
-       return (t);
+    }
+    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);
 }
 
 }
 
+void
 freesyn(t)
 freesyn(t)
-       register struct command *t;
+    register struct command *t;
 {
 {
-       register char **v;
-
-       if (t == 0)
-               return;
-       switch (t->t_dtyp) {
-
-       case NODE_COMMAND:
-               for (v = t->t_dcom; *v; v++)
-                       XFREE(*v)
-               XFREE((char *)t->t_dcom)
-               goto lr;
-
-       case NODE_PAREN:
-               freesyn(t->t_dspr);
-               /* fall into ... */
-
-lr:
-               XFREE(t->t_dlef)
-               XFREE(t->t_drit)
-               break;
-
-       case NODE_AND:
-       case NODE_OR:
-       case NODE_PIPE:
-       case NODE_LIST:
-               freesyn(t->t_dcar);
-               freesyn(t->t_dcdr);
-               break;
-       }
-       XFREE((char *)t)
+    register Char **v;
+
+    if (t == 0)
+       return;
+    switch (t->t_dtyp) {
+
+    case NODE_COMMAND:
+       for (v = t->t_dcom; *v; v++)
+           xfree((ptr_t) * v);
+       xfree((ptr_t) (t->t_dcom));
+       xfree((ptr_t) t->t_dlef);
+       xfree((ptr_t) t->t_drit);
+       break;
+    case NODE_PAREN:
+       freesyn(t->t_dspr);
+       xfree((ptr_t) t->t_dlef);
+       xfree((ptr_t) t->t_drit);
+       break;
+
+    case NODE_AND:
+    case NODE_OR:
+    case NODE_PIPE:
+    case NODE_LIST:
+       freesyn(t->t_dcar), freesyn(t->t_dcdr);
+       break;
+    }
+    xfree((ptr_t) t);
 }
 }