BSD 4_4_Lite2 release
[unix-history] / usr / src / bin / csh / set.c
index 272956e..1192163 100644 (file)
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+/*-
+ * Copyright (c) 1980, 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * 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[] = "@(#)set.c      5.1 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)set.c      8.2 (Berkeley) 3/22/95";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#ifndef SHORT_STRINGS
+#include <string.h>
+#endif /* SHORT_STRINGS */
+#if __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include "csh.h"
+#include "extern.h"
+
+static Char    *getinx __P((Char *, int *));
+static void     asx __P((Char *, int, Char *));
+static struct varent
+               *getvx __P((Char *, int));
+static Char    *xset __P((Char *, Char ***));
+static Char    *operate __P((int, Char *, Char *));
+static void     putn1 __P((int));
+static struct varent
+               *madrof __P((Char *, struct varent *));
+static void     unsetv1 __P((struct varent *));
+static void     exportpath __P((Char **));
+static void     balance __P((struct varent *, int, int));
 
 
-#include "sh.h"
 
 /*
  * C Shell
  */
 
 
 /*
  * C Shell
  */
 
-doset(v)
-       register char **v;
+void
+/*ARGSUSED*/
+doset(v, t)
+    Char **v;
+    struct command *t;
 {
 {
-       register char *p;
-       char *vp, op;
-       char **vecp;
-       bool hadsub;
-       int subscr;
-
-       v++;
-       p = *v++;
-       if (p == 0) {
-               prvars();
-               return;
+    register Char *p;
+    Char   *vp, op;
+    Char  **vecp;
+    bool    hadsub;
+    int     subscr;
+
+    v++;
+    p = *v++;
+    if (p == 0) {
+       prvars();
+       return;
+    }
+    do {
+       hadsub = 0;
+       vp = p;
+       if (letter(*p))
+           for (; alnum(*p); p++)
+               continue;
+       if (vp == p || !letter(*vp))
+           stderror(ERR_NAME | ERR_VARBEGIN);
+       if ((p - vp) > MAXVARLEN) {
+           stderror(ERR_NAME | ERR_VARTOOLONG);
+           return;
+       }
+       if (*p == '[') {
+           hadsub++;
+           p = getinx(p, &subscr);
+       }
+       if ((op = *p) != '\0') {
+           *p++ = 0;
+           if (*p == 0 && *v && **v == '(')
+               p = *v++;
+       }
+       else if (*v && eq(*v, STRequal)) {
+           op = '=', v++;
+           if (*v)
+               p = *v++;
+       }
+       if (op && op != '=')
+           stderror(ERR_NAME | ERR_SYNTAX);
+       if (eq(p, STRLparen)) {
+           register Char **e = v;
+
+           if (hadsub)
+               stderror(ERR_NAME | ERR_SYNTAX);
+           for (;;) {
+               if (!*e)
+                   stderror(ERR_NAME | ERR_MISSING, ')');
+               if (**e == ')')
+                   break;
+               e++;
+           }
+           p = *e;
+           *e = 0;
+           vecp = saveblk(v);
+           set1(vp, vecp, &shvhed);
+           *e = p;
+           v = e + 1;
+       }
+       else if (hadsub)
+           asx(vp, subscr, Strsave(p));
+       else
+           set(vp, Strsave(p));
+       if (eq(vp, STRpath)) {
+           exportpath(adrof(STRpath)->vec);
+           dohash(NULL, NULL);
+       }
+       else if (eq(vp, STRhistchars)) {
+           register Char *pn = value(STRhistchars);
+
+           HIST = *pn++;
+           HISTSUB = *pn;
+       }
+       else if (eq(vp, STRuser)) {
+           Setenv(STRUSER, value(vp));
+           Setenv(STRLOGNAME, value(vp));
+       }
+       else if (eq(vp, STRwordchars)) {
+           word_chars = value(vp);
+       }
+       else if (eq(vp, STRterm))
+           Setenv(STRTERM, value(vp));
+       else if (eq(vp, STRhome)) {
+           register Char *cp;
+
+           cp = Strsave(value(vp));    /* get the old value back */
+
+           /*
+            * convert to cononical pathname (possibly resolving symlinks)
+            */
+           cp = dcanon(cp, cp);
+
+           set(vp, Strsave(cp));       /* have to save the new val */
+
+           /* and now mirror home with HOME */
+           Setenv(STRHOME, cp);
+           /* fix directory stack for new tilde home */
+           dtilde();
+           xfree((ptr_t) cp);
        }
        }
-       do {
-               hadsub = 0;
-               for (vp = p; alnum(*p); p++)
-                       continue;
-               if (vp == p || !letter(*vp))
-                       goto setsyn;
-               if (*p == '[') {
-                       hadsub++;
-                       p = getinx(p, &subscr);
-               }
-               if (op = *p) {
-                       *p++ = 0;
-                       if (*p == 0 && *v && **v == '(')
-                               p = *v++;
-               } else if (*v && eq(*v, "=")) {
-                       op = '=', v++;
-                       if (*v)
-                               p = *v++;
-               }
-               if (op && op != '=')
-setsyn:
-                       bferr("Syntax error");
-               if (eq(p, "(")) {
-                       register char **e = v;
-
-                       if (hadsub)
-                               goto setsyn;
-                       for (;;) {
-                               if (!*e)
-                                       bferr("Missing )");
-                               if (**e == ')')
-                                       break;
-                               e++;
-                       }
-                       p = *e;
-                       *e = 0;
-                       vecp = saveblk(v);
-                       set1(vp, vecp, &shvhed);
-                       *e = p;
-                       v = e + 1;
-               } else if (hadsub)
-                       asx(vp, subscr, savestr(p));
-               else
-                       set(vp, savestr(p));
-               if (eq(vp, "path")) {
-                       exportpath(adrof("path")->vec);
-                       dohash();
-               } else if (eq(vp, "histchars")) {
-                       register char *p = value("histchars");
-
-                       HIST = *p++;
-                       HISTSUB = *p;
-               } else if (eq(vp, "user"))
-                       setenv("USER", value(vp));
-               else if (eq(vp, "term"))
-                       setenv("TERM", value(vp));
-               else if (eq(vp, "home"))
-                       setenv("HOME", value(vp));
 #ifdef FILEC
 #ifdef FILEC
-               else if (eq(vp, "filec"))
-                       filec = 1;
+       else if (eq(vp, STRfilec))
+           filec = 1;
 #endif
 #endif
-       } while (p = *v++);
+    } while ((p = *v++) != NULL);
 }
 
 }
 
-char *
+static Char *
 getinx(cp, ip)
 getinx(cp, ip)
-       register char *cp;
-       register int *ip;
+    register Char *cp;
+    register int *ip;
 {
 
 {
 
-       *ip = 0;
-       *cp++ = 0;
-       while (*cp && digit(*cp))
-               *ip = *ip * 10 + *cp++ - '0';
-       if (*cp++ != ']')
-               bferr("Subscript error");
-       return (cp);
+    *ip = 0;
+    *cp++ = 0;
+    while (*cp && Isdigit(*cp))
+       *ip = *ip * 10 + *cp++ - '0';
+    if (*cp++ != ']')
+       stderror(ERR_NAME | ERR_SUBSCRIPT);
+    return (cp);
 }
 
 }
 
+static void
 asx(vp, subscr, p)
 asx(vp, subscr, p)
-       char *vp;
-       int subscr;
-       char *p;
+    Char   *vp;
+    int     subscr;
+    Char   *p;
 {
 {
-       register struct varent *v = getvx(vp, subscr);
+    register struct varent *v = getvx(vp, subscr);
 
 
-       xfree(v->vec[subscr - 1]);
-       v->vec[subscr - 1] = globone(p);
+    xfree((ptr_t) v->vec[subscr - 1]);
+    v->vec[subscr - 1] = globone(p, G_APPEND);
 }
 
 }
 
-struct varent *
+static struct varent *
 getvx(vp, subscr)
 getvx(vp, subscr)
-       char *vp;
+    Char   *vp;
+    int     subscr;
 {
 {
-       register struct varent *v = adrof(vp);
+    register struct varent *v = adrof(vp);
 
 
-       if (v == 0)
-               udvar(vp);
-       if (subscr < 1 || subscr > blklen(v->vec))
-               bferr("Subscript out of range");
-       return (v);
+    if (v == 0)
+       udvar(vp);
+    if (subscr < 1 || subscr > blklen(v->vec))
+       stderror(ERR_NAME | ERR_RANGE);
+    return (v);
 }
 
 }
 
-char   plusplus[2] = { '1', 0 };
-
-dolet(v)
-       char **v;
+void
+/*ARGSUSED*/
+dolet(v, t)
+    Char **v;
+    struct command *t;
 {
 {
-       register char *p;
-       char *vp, c, op;
-       bool hadsub;
-       int subscr;
-
-       v++;
-       p = *v++;
-       if (p == 0) {
-               prvars();
-               return;
+    register Char *p;
+    Char   *vp, c, op;
+    bool    hadsub;
+    int     subscr;
+
+    v++;
+    p = *v++;
+    if (p == 0) {
+       prvars();
+       return;
+    }
+    do {
+       hadsub = 0;
+       vp = p;
+       if (letter(*p))
+           for (; alnum(*p); p++)
+               continue;
+       if (vp == p || !letter(*vp))
+           stderror(ERR_NAME | ERR_VARBEGIN);
+       if ((p - vp) > MAXVARLEN)
+           stderror(ERR_NAME | ERR_VARTOOLONG);
+       if (*p == '[') {
+           hadsub++;
+           p = getinx(p, &subscr);
        }
        }
-       do {
-               hadsub = 0;
-               for (vp = p; alnum(*p); p++)
-                       continue;
-               if (vp == p || !letter(*vp))
-                       goto letsyn;
-               if (*p == '[') {
-                       hadsub++;
-                       p = getinx(p, &subscr);
-               }
-               if (*p == 0 && *v)
-                       p = *v++;
-               if (op = *p)
-                       *p++ = 0;
-               else
-                       goto letsyn;
-               vp = savestr(vp);
-               if (op == '=') {
-                       c = '=';
-                       p = xset(p, &v);
-               } else {
-                       c = *p++;
-                       if (any(c, "+-")) {
-                               if (c != op || *p)
-                                       goto letsyn;
-                               p = plusplus;
-                       } else {
-                               if (any(op, "<>")) {
-                                       if (c != op)
-                                               goto letsyn;
-                                       c = *p++;
-letsyn:
-                                       bferr("Syntax error");
-                               }
-                               if (c != '=')
-                                       goto letsyn;
-                               p = xset(p, &v);
-                       }
-               }
-               if (op == '=')
-                       if (hadsub)
-                               asx(vp, subscr, p);
-                       else
-                               set(vp, p);
-               else
-                       if (hadsub)
-#ifndef V6
-                               /* avoid bug in vax CC */
-                               {
-                                       struct varent *gv = getvx(vp, subscr);
-
-                                       asx(vp, subscr, operate(op, gv->vec[subscr - 1], p));
-                               }
-#else
-                               asx(vp, subscr, operate(op, getvx(vp, subscr)->vec[subscr - 1], p));
-#endif
-                       else
-                               set(vp, operate(op, value(vp), p));
-               if (eq(vp, "path")) {
-                       exportpath(adrof("path")->vec);
-                       dohash();
+       if (*p == 0 && *v)
+           p = *v++;
+       if ((op = *p) != '\0')
+           *p++ = 0;
+       else
+           stderror(ERR_NAME | ERR_ASSIGN);
+
+       if (*p == '\0' && *v == NULL)
+           stderror(ERR_NAME | ERR_ASSIGN);
+
+       vp = Strsave(vp);
+       if (op == '=') {
+           c = '=';
+           p = xset(p, &v);
+       }
+       else {
+           c = *p++;
+           if (any("+-", c)) {
+               if (c != op || *p)
+                   stderror(ERR_NAME | ERR_UNKNOWNOP);
+               p = Strsave(STR1);
+           }
+           else {
+               if (any("<>", op)) {
+                   if (c != op)
+                       stderror(ERR_NAME | ERR_UNKNOWNOP);
+                   c = *p++;
+                   stderror(ERR_NAME | ERR_SYNTAX);
                }
                }
-               XFREE(vp)
                if (c != '=')
                if (c != '=')
-                       XFREE(p)
-       } while (p = *v++);
+                   stderror(ERR_NAME | ERR_UNKNOWNOP);
+               p = xset(p, &v);
+           }
+       }
+       if (op == '=')
+           if (hadsub)
+               asx(vp, subscr, p);
+           else
+               set(vp, p);
+       else if (hadsub) {
+           struct varent *gv = getvx(vp, subscr);
+
+           asx(vp, subscr, operate(op, gv->vec[subscr - 1], p));
+       }
+       else
+           set(vp, operate(op, value(vp), p));
+       if (eq(vp, STRpath)) {
+           exportpath(adrof(STRpath)->vec);
+           dohash(NULL, NULL);
+       }
+       xfree((ptr_t) vp);
+       if (c != '=')
+           xfree((ptr_t) p);
+    } while ((p = *v++) != NULL);
 }
 
 }
 
-char *
+static Char *
 xset(cp, vp)
 xset(cp, vp)
-       char *cp, ***vp;
+    Char   *cp, ***vp;
 {
 {
-       register char *dp;
-
-       if (*cp) {
-               dp = savestr(cp);
-               --(*vp);
-               xfree(**vp);
-               **vp = dp;
-       }
-       return (putn(exp(vp)));
+    register Char *dp;
+
+    if (*cp) {
+       dp = Strsave(cp);
+       --(*vp);
+       xfree((ptr_t) ** vp);
+       **vp = dp;
+    }
+    return (putn(expr(vp)));
 }
 
 }
 
-char *
+static Char *
 operate(op, vp, p)
 operate(op, vp, p)
-       char op, *vp, *p;
+    int    op;
+    Char  *vp, *p;
 {
 {
-       char opr[2];
-       char *vec[5];
-       register char **v = vec;
-       char **vecp = v;
-       register int i;
-
-       if (op != '=') {
-               if (*vp)
-                       *v++ = vp;
-               opr[0] = op;
-               opr[1] = 0;
-               *v++ = opr;
-               if (op == '<' || op == '>')
-                       *v++ = opr;
-       }
-       *v++ = p;
-       *v++ = 0;
-       i = exp(&vecp);
-       if (*vecp)
-               bferr("Expression syntax");
-       return (putn(i));
+    Char    opr[2];
+    Char   *vec[5];
+    register Char **v = vec;
+    Char  **vecp = v;
+    register int i;
+
+    if (op != '=') {
+       if (*vp)
+           *v++ = vp;
+       opr[0] = op;
+       opr[1] = 0;
+       *v++ = opr;
+       if (op == '<' || op == '>')
+           *v++ = opr;
+    }
+    *v++ = p;
+    *v++ = 0;
+    i = expr(&vecp);
+    if (*vecp)
+       stderror(ERR_NAME | ERR_EXPRESSION);
+    return (putn(i));
 }
 
 }
 
-static char *putp;
-char *
+static Char *putp;
+
+Char   *
 putn(n)
 putn(n)
-       register int n;
+    register int n;
 {
 {
-       static char number[15];
-
-       putp = number;
-       if (n < 0) {
-               n = -n;
-               *putp++ = '-';
-       }
-       if (sizeof (int) == 2 && n == -32768) {
-               *putp++ = '3';
-               n = 2768;
+    int     num;
+    static Char number[15];
+
+    putp = number;
+    if (n < 0) {
+       n = -n;
+       *putp++ = '-';
+    }
+    num = 2;                   /* confuse lint */
+    if (sizeof(int) == num && ((unsigned int) n) == 0x8000) {
+       *putp++ = '3';
+       n = 2768;
 #ifdef pdp11
 #ifdef pdp11
-       }
+    }
 #else
 #else
-       } else if (sizeof (int) == 4 && n == -2147483648) {
-               *putp++ = '2';
-               n = 147483648;
+    }
+    else {
+       num = 4;                /* confuse lint */
+       if (sizeof(int) == num && ((unsigned int) n) == 0x80000000) {
+           *putp++ = '2';
+           n = 147483648;
        }
        }
+    }
 #endif
 #endif
-       putn1(n);
-       *putp = 0;
-       return (savestr(number));
+    putn1(n);
+    *putp = 0;
+    return (Strsave(number));
 }
 
 }
 
+static void
 putn1(n)
 putn1(n)
-       register int n;
+    register int n;
 {
 {
-       if (n > 9)
-               putn1(n / 10);
-       *putp++ = n % 10 + '0';
+    if (n > 9)
+       putn1(n / 10);
+    *putp++ = n % 10 + '0';
 }
 
 }
 
+int
 getn(cp)
 getn(cp)
-       register char *cp;
+    register Char *cp;
 {
 {
-       register int n;
-       int sign;
-
-       sign = 0;
-       if (cp[0] == '+' && cp[1])
-               cp++;
-       if (*cp == '-') {
-               sign++;
-               cp++;
-               if (!digit(*cp))
-                       goto badnum;
-       }
-       n = 0;
-       while (digit(*cp))
-               n = n * 10 + *cp++ - '0';
-       if (*cp)
-               goto badnum;
-       return (sign ? -n : n);
-badnum:
-       bferr("Badly formed number");
-       return (0);
+    register int n;
+    int     sign;
+
+    sign = 0;
+    if (cp[0] == '+' && cp[1])
+       cp++;
+    if (*cp == '-') {
+       sign++;
+       cp++;
+       if (!Isdigit(*cp))
+           stderror(ERR_NAME | ERR_BADNUM);
+    }
+    n = 0;
+    while (Isdigit(*cp))
+       n = n * 10 + *cp++ - '0';
+    if (*cp)
+       stderror(ERR_NAME | ERR_BADNUM);
+    return (sign ? -n : n);
 }
 
 }
 
-char *
+Char   *
 value1(var, head)
 value1(var, head)
-       char *var;
-       struct varent *head;
+    Char   *var;
+    struct varent *head;
 {
 {
-       register struct varent *vp;
+    register struct varent *vp;
 
 
-       vp = adrof1(var, head);
-       return (vp == 0 || vp->vec[0] == 0 ? "" : vp->vec[0]);
+    vp = adrof1(var, head);
+    return (vp == 0 || vp->vec[0] == 0 ? STRNULL : vp->vec[0]);
 }
 
 }
 
-struct varent *
+static struct varent *
 madrof(pat, vp)
 madrof(pat, vp)
-       char *pat;
-       register struct varent *vp;
+    Char   *pat;
+    register struct varent *vp;
 {
 {
-       register struct varent *vp1;
-
-       for (; vp; vp = vp->v_right) {
-               if (vp->v_left && (vp1 = madrof(pat, vp->v_left)))
-                       return vp1;
-               if (Gmatch(vp->v_name, pat))
-                       return vp;
-       }
-       return vp;
+    register struct varent *vp1;
+
+    for (; vp; vp = vp->v_right) {
+       if (vp->v_left && (vp1 = madrof(pat, vp->v_left)))
+           return vp1;
+       if (Gmatch(vp->v_name, pat))
+           return vp;
+    }
+    return vp;
 }
 
 struct varent *
 adrof1(name, v)
 }
 
 struct varent *
 adrof1(name, v)
-       register char *name;
-       register struct varent *v;
+    register Char *name;
+    register struct varent *v;
 {
 {
-       register cmp;
-
-       v = v->v_left;
-       while (v && ((cmp = *name - *v->v_name) ||
-                    (cmp = strcmp(name, v->v_name))))
-               if (cmp < 0)
-                       v = v->v_left;
-               else
-                       v = v->v_right;
-       return v;
+    register cmp;
+
+    v = v->v_left;
+    while (v && ((cmp = *name - *v->v_name) ||
+                (cmp = Strcmp(name, v->v_name))))
+       if (cmp < 0)
+           v = v->v_left;
+       else
+           v = v->v_right;
+    return v;
 }
 
 /*
  * The caller is responsible for putting value in a safe place
  */
 }
 
 /*
  * The caller is responsible for putting value in a safe place
  */
+void
 set(var, val)
 set(var, val)
-       char *var, *val;
+    Char   *var, *val;
 {
 {
-       register char **vec = (char **) xalloc(2 * sizeof (char **));
+    register Char **vec = (Char **) xmalloc((size_t) (2 * sizeof(Char **)));
 
 
-       vec[0] = onlyread(val) ? savestr(val) : val;
-       vec[1] = 0;
-       set1(var, vec, &shvhed);
+    vec[0] = val;
+    vec[1] = 0;
+    set1(var, vec, &shvhed);
 }
 
 }
 
+void
 set1(var, vec, head)
 set1(var, vec, head)
-       char *var, **vec;
-       struct varent *head;
+    Char   *var, **vec;
+    struct varent *head;
 {
 {
-       register char **oldv = vec;
-
-       gflag = 0; tglob(oldv);
-       if (gflag) {
-               vec = glob(oldv);
-               if (vec == 0) {
-                       bferr("No match");
-                       blkfree(oldv);
-                       return;
-               }
-               blkfree(oldv);
-               gargv = 0;
+    register Char **oldv = vec;
+
+    gflag = 0;
+    tglob(oldv);
+    if (gflag) {
+       vec = globall(oldv);
+       if (vec == 0) {
+           blkfree(oldv);
+           stderror(ERR_NAME | ERR_NOMATCH);
+           return;
        }
        }
-       setq(var, vec, head);
+       blkfree(oldv);
+       gargv = 0;
+    }
+    setq(var, vec, head);
 }
 
 }
 
+
+void
 setq(name, vec, p)
 setq(name, vec, p)
-       char *name, **vec;
-       register struct varent *p;
+    Char   *name, **vec;
+    register struct varent *p;
 {
 {
-       register struct varent *c;
-       register f;
-
-       f = 0;                  /* tree hangs off the header's left link */
-       while (c = p->v_link[f]) {
-               if ((f = *name - *c->v_name) == 0 &&
-                   (f = strcmp(name, c->v_name)) == 0) {
-                       blkfree(c->vec);
-                       goto found;
-               }
-               p = c;
-               f = f > 0;
+    register struct varent *c;
+    register f;
+
+    f = 0;                     /* tree hangs off the header's left link */
+    while ((c = p->v_link[f]) != NULL) {
+       if ((f = *name - *c->v_name) == 0 &&
+           (f = Strcmp(name, c->v_name)) == 0) {
+           blkfree(c->vec);
+           goto found;
        }
        }
-       p->v_link[f] = c = (struct varent *)xalloc(sizeof (struct varent));
-       c->v_name = savestr(name);
-       c->v_bal = 0;
-       c->v_left = c->v_right = 0;
-       c->v_parent = p;
-       balance(p, f, 0);
+       p = c;
+       f = f > 0;
+    }
+    p->v_link[f] = c = (struct varent *) xmalloc((size_t) sizeof(struct varent));
+    c->v_name = Strsave(name);
+    c->v_bal = 0;
+    c->v_left = c->v_right = 0;
+    c->v_parent = p;
+    balance(p, f, 0);
 found:
 found:
-       trim(c->vec = vec);
+    trim(c->vec = vec);
 }
 
 }
 
-unset(v)
-       char *v[];
+void
+/*ARGSUSED*/
+unset(v, t)
+    Char **v;
+    struct command *t;
 {
 {
-
-       unset1(v, &shvhed);
-       if (adrof("histchars") == 0) {
-               HIST = '!';
-               HISTSUB = '^';
-       }
+    unset1(v, &shvhed);
 #ifdef FILEC
 #ifdef FILEC
-       if (adrof("filec") == 0)
-               filec = 0;
+    if (adrof(STRfilec) == 0)
+       filec = 0;
 #endif
 #endif
+    if (adrof(STRhistchars) == 0) {
+       HIST = '!';
+       HISTSUB = '^';
+    }
+    if (adrof(STRwordchars) == 0)
+       word_chars = STR_WORD_CHARS;
 }
 
 }
 
+void
 unset1(v, head)
 unset1(v, head)
-       register char *v[];
-       struct varent *head;
+    register Char *v[];
+    struct varent *head;
 {
 {
-       register struct varent *vp;
-       register int cnt;
-
-       while (*++v) {
-               cnt = 0;
-               while (vp = madrof(*v, head->v_left))
-                       unsetv1(vp), cnt++;
-               if (cnt == 0)
-                       setname(*v);
-       }
+    register struct varent *vp;
+    register int cnt;
+
+    while (*++v) {
+       cnt = 0;
+       while ((vp = madrof(*v, head->v_left)) != NULL)
+           unsetv1(vp), cnt++;
+       if (cnt == 0)
+           setname(vis_str(*v));
+    }
 }
 
 }
 
+void
 unsetv(var)
 unsetv(var)
-       char *var;
+    Char   *var;
 {
 {
-       register struct varent *vp;
+    register struct varent *vp;
 
 
-       if ((vp = adrof1(var, &shvhed)) == 0)
-               udvar(var);
-       unsetv1(vp);
+    if ((vp = adrof1(var, &shvhed)) == 0)
+       udvar(var);
+    unsetv1(vp);
 }
 
 }
 
+static void
 unsetv1(p)
 unsetv1(p)
-       register struct varent *p;
+    register struct varent *p;
 {
 {
-       register struct varent *c, *pp;
-       register f;
-
-       /*
-        * Free associated memory first to avoid complications.
-        */
-       blkfree(p->vec);
-       XFREE(p->v_name);
-       /*
-        * If p is missing one child, then we can move the other
-        * into where p is.  Otherwise, we find the predecessor
-        * of p, which is guaranteed to have no right child, copy
-        * it into p, and move it's left child into it.
-        */
-       if (p->v_right == 0)
-               c = p->v_left;
-       else if (p->v_left == 0)
-               c = p->v_right;
-       else {
-               for (c = p->v_left; c->v_right; c = c->v_right)
-                       ;
-               p->v_name = c->v_name;
-               p->vec = c->vec;
-               p = c;
-               c = p->v_left;
-       }
-       /*
-        * Move c into where p is.
-        */
-       pp = p->v_parent;
-       f = pp->v_right == p;
-       if (pp->v_link[f] = c)
-               c->v_parent = pp;
-       /*
-        * Free the deleted node, and rebalance.
-        */
-       XFREE((char *)p);
-       balance(pp, f, 1);
+    register struct varent *c, *pp;
+    register f;
+
+    /*
+     * Free associated memory first to avoid complications.
+     */
+    blkfree(p->vec);
+    xfree((ptr_t) p->v_name);
+    /*
+     * If p is missing one child, then we can move the other into where p is.
+     * Otherwise, we find the predecessor of p, which is guaranteed to have no
+     * right child, copy it into p, and move it's left child into it.
+     */
+    if (p->v_right == 0)
+       c = p->v_left;
+    else if (p->v_left == 0)
+       c = p->v_right;
+    else {
+       for (c = p->v_left; c->v_right; c = c->v_right)
+           continue;
+       p->v_name = c->v_name;
+       p->vec = c->vec;
+       p = c;
+       c = p->v_left;
+    }
+    /*
+     * Move c into where p is.
+     */
+    pp = p->v_parent;
+    f = pp->v_right == p;
+    if ((pp->v_link[f] = c) != NULL)
+       c->v_parent = pp;
+    /*
+     * Free the deleted node, and rebalance.
+     */
+    xfree((ptr_t) p);
+    balance(pp, f, 1);
 }
 
 }
 
+void
 setNS(cp)
 setNS(cp)
-       char *cp;
+    Char   *cp;
 {
 {
-
-       set(cp, "");
+    set(cp, Strsave(STRNULL));
 }
 
 }
 
-shift(v)
-       register char **v;
+void
+/*ARGSUSED*/
+shift(v, t)
+    Char **v;
+    struct command *t;
 {
 {
-       register struct varent *argv;
-       register char *name;
-
-       v++;
-       name = *v;
-       if (name == 0)
-               name = "argv";
-       else
-               (void) strip(name);
-       argv = adrof(name);
-       if (argv == 0)
-               udvar(name);
-       if (argv->vec[0] == 0)
-               bferr("No more words");
-       lshift(argv->vec, 1);
+    register struct varent *argv;
+    register Char *name;
+
+    v++;
+    name = *v;
+    if (name == 0)
+       name = STRargv;
+    else
+       (void) strip(name);
+    argv = adrof(name);
+    if (argv == 0)
+       udvar(name);
+    if (argv->vec[0] == 0)
+       stderror(ERR_NAME | ERR_NOMORE);
+    lshift(argv->vec, 1);
 }
 
 }
 
+static void
 exportpath(val)
 exportpath(val)
-char **val;
+    Char  **val;
 {
 {
-       char exppath[BUFSIZ];
-
-       exppath[0] = 0;
-       if (val)
-               while (*val) {
-                       if (strlen(*val) + strlen(exppath) + 2 > BUFSIZ) {
-                               printf("Warning: ridiculously long PATH truncated\n");
-                               break;
-                       }
-                       (void) strcat(exppath, *val++);
-                       if (*val == 0 || eq(*val, ")"))
-                               break;
-                       (void) strcat(exppath, ":");
-               }
-       setenv("PATH", exppath);
+    Char    exppath[BUFSIZ];
+
+    exppath[0] = 0;
+    if (val)
+       while (*val) {
+           if (Strlen(*val) + Strlen(exppath) + 2 > BUFSIZ) {
+               (void) fprintf(csherr,
+                              "Warning: ridiculously long PATH truncated\n");
+               break;
+           }
+           if ((**val != '/' || **val == '\0') && (euid == 0 || uid == 0)) 
+                   (void) fprintf(csherr,
+                   "Warning: exported path contains relative components.\n");
+           (void) Strcat(exppath, *val++);
+           if (*val == 0 || eq(*val, STRRparen))
+               break;
+           (void) Strcat(exppath, STRcolon);
+       }
+    Setenv(STRPATH, exppath);
 }
 
 }
 
-       /* macros to do single rotations on node p */
+#ifndef lint
+ /*
+  * Lint thinks these have null effect
+  */
+ /* macros to do single rotations on node p */
 #define rright(p) (\
        t = (p)->v_left,\
        (t)->v_parent = (p)->v_parent,\
 #define rright(p) (\
        t = (p)->v_left,\
        (t)->v_parent = (p)->v_parent,\
@@ -570,132 +690,159 @@ char **val;
        ((p)->v_right = t->v_left) ? (t->v_left->v_parent = (p)) : 0,\
        (t->v_left = (p))->v_parent = t,\
        (p) = t)
        ((p)->v_right = t->v_left) ? (t->v_left->v_parent = (p)) : 0,\
        (t->v_left = (p))->v_parent = t,\
        (p) = t)
+#else
+struct varent *
+rleft(p)
+    struct varent *p;
+{
+    return (p);
+}
+struct varent *
+rright(p)
+    struct varent *p;
+{
+    return (p);
+}
+
+#endif                         /* ! lint */
+
 
 /*
  * Rebalance a tree, starting at p and up.
  * F == 0 means we've come from p's left child.
  * D == 1 means we've just done a delete, otherwise an insert.
  */
 
 /*
  * Rebalance a tree, starting at p and up.
  * F == 0 means we've come from p's left child.
  * D == 1 means we've just done a delete, otherwise an insert.
  */
+static void
 balance(p, f, d)
 balance(p, f, d)
-       register struct varent *p;
-       register f;
+    register struct varent *p;
+    register int f, d;
 {
 {
-       register struct varent *pp;
-       register struct varent *t;              /* used by the rotate macros */
-       register ff;
+    register struct varent *pp;
 
 
-       /*
-        * Ok, from here on, p is the node we're operating on;
-        * pp is it's parent; f is the branch of p from which we have come;
-        * ff is the branch of pp which is p.
-        */
-       for (; pp = p->v_parent; p = pp, f = ff) {
-               ff = pp->v_right == p;
-               if (f ^ d) {            /* right heavy */
-                       switch (p->v_bal) {
-                       case -1:                /* was left heavy */
-                               p->v_bal = 0;
-                               break;
-                       case 0:                 /* was balanced */
-                               p->v_bal = 1;
-                               break;
-                       case 1:                 /* was already right heavy */
-                               switch (p->v_right->v_bal) {
-                               case 1:                 /* sigle rotate */
-                                       pp->v_link[ff] = rleft(p);
-                                       p->v_left->v_bal = 0;
-                                       p->v_bal = 0;
-                                       break;
-                               case 0:                 /* single rotate */
-                                       pp->v_link[ff] = rleft(p);
-                                       p->v_left->v_bal = 1;
-                                       p->v_bal = -1;
-                                       break;
-                               case -1:                /* double rotate */
-                                       rright(p->v_right);
-                                       pp->v_link[ff] = rleft(p);
-                                       p->v_left->v_bal =
-                                               p->v_bal < 1 ? 0 : -1;
-                                       p->v_right->v_bal =
-                                               p->v_bal > -1 ? 0 : 1;
-                                       p->v_bal = 0;
-                                       break;
-                               }
-                               break;
-                       }
-               } else {                /* left heavy */
-                       switch (p->v_bal) {
-                       case 1:                 /* was right heavy */
-                               p->v_bal = 0;
-                               break;
-                       case 0:                 /* was balanced */
-                               p->v_bal = -1;
-                               break;
-                       case -1:                /* was already left heavy */
-                               switch (p->v_left->v_bal) {
-                               case -1:                /* single rotate */
-                                       pp->v_link[ff] = rright(p);
-                                       p->v_right->v_bal = 0;
-                                       p->v_bal = 0;
-                                       break;
-                               case 0:                 /* signle rotate */
-                                       pp->v_link[ff] = rright(p);
-                                       p->v_right->v_bal = -1;
-                                       p->v_bal = 1;
-                                       break;
-                               case 1:                 /* double rotate */
-                                       rleft(p->v_left);
-                                       pp->v_link[ff] = rright(p);
-                                       p->v_left->v_bal =
-                                               p->v_bal < 1 ? 0 : -1;
-                                       p->v_right->v_bal =
-                                               p->v_bal > -1 ? 0 : 1;
-                                       p->v_bal = 0;
-                                       break;
-                               }
-                               break;
-                       }
+#ifndef lint
+    register struct varent *t; /* used by the rotate macros */
+
+#endif
+    register ff;
+
+    /*
+     * Ok, from here on, p is the node we're operating on; pp is it's parent; f
+     * is the branch of p from which we have come; ff is the branch of pp which
+     * is p.
+     */
+    for (; (pp = p->v_parent) != NULL; p = pp, f = ff) {
+       ff = pp->v_right == p;
+       if (f ^ d) {            /* right heavy */
+           switch (p->v_bal) {
+           case -1:            /* was left heavy */
+               p->v_bal = 0;
+               break;
+           case 0:             /* was balanced */
+               p->v_bal = 1;
+               break;
+           case 1:             /* was already right heavy */
+               switch (p->v_right->v_bal) {
+               case 1: /* sigle rotate */
+                   pp->v_link[ff] = rleft(p);
+                   p->v_left->v_bal = 0;
+                   p->v_bal = 0;
+                   break;
+               case 0: /* single rotate */
+                   pp->v_link[ff] = rleft(p);
+                   p->v_left->v_bal = 1;
+                   p->v_bal = -1;
+                   break;
+               case -1:        /* double rotate */
+                   (void) rright(p->v_right);
+                   pp->v_link[ff] = rleft(p);
+                   p->v_left->v_bal =
+                       p->v_bal < 1 ? 0 : -1;
+                   p->v_right->v_bal =
+                       p->v_bal > -1 ? 0 : 1;
+                   p->v_bal = 0;
+                   break;
                }
                }
-               /*
-                * If from insert, then we terminate when p is balanced.
-                * If from delete, then we terminate when p is unbalanced.
-                */
-               if ((p->v_bal == 0) ^ d)
-                       break;
+               break;
+           }
        }
        }
+       else {                  /* left heavy */
+           switch (p->v_bal) {
+           case 1:             /* was right heavy */
+               p->v_bal = 0;
+               break;
+           case 0:             /* was balanced */
+               p->v_bal = -1;
+               break;
+           case -1:            /* was already left heavy */
+               switch (p->v_left->v_bal) {
+               case -1:        /* single rotate */
+                   pp->v_link[ff] = rright(p);
+                   p->v_right->v_bal = 0;
+                   p->v_bal = 0;
+                   break;
+               case 0: /* signle rotate */
+                   pp->v_link[ff] = rright(p);
+                   p->v_right->v_bal = -1;
+                   p->v_bal = 1;
+                   break;
+               case 1: /* double rotate */
+                   (void) rleft(p->v_left);
+                   pp->v_link[ff] = rright(p);
+                   p->v_left->v_bal =
+                       p->v_bal < 1 ? 0 : -1;
+                   p->v_right->v_bal =
+                       p->v_bal > -1 ? 0 : 1;
+                   p->v_bal = 0;
+                   break;
+               }
+               break;
+           }
+       }
+       /*
+        * If from insert, then we terminate when p is balanced. If from
+        * delete, then we terminate when p is unbalanced.
+        */
+       if ((p->v_bal == 0) ^ d)
+           break;
+    }
 }
 
 }
 
+void
 plist(p)
 plist(p)
-       register struct varent *p;
+    register struct varent *p;
 {
 {
-       register struct varent *c;
-       register len;
-
-       if (setintr)
-               (void) sigsetmask(sigblock(0) & ~ sigmask(SIGINT));
-       for (;;) {
-               while (p->v_left)
-                       p = p->v_left;
-       x:
-               if (p->v_parent == 0)           /* is it the header? */
-                       return;
-               len = blklen(p->vec);
-               printf(p->v_name);
-               putchar('\t');
-               if (len != 1)
-                       putchar('(');
-               blkpr(p->vec);
-               if (len != 1)
-                       putchar(')');
-               putchar('\n');
-               if (p->v_right) {
-                       p = p->v_right;
-                       continue;
-               }
-               do {
-                       c = p;
-                       p = p->v_parent;
-               } while (p->v_right == c);
-               goto x;
+    register struct varent *c;
+    register len;
+    sigset_t sigset;
+
+    if (setintr) {
+       sigemptyset(&sigset);
+       sigaddset(&sigset, SIGINT);
+       sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+    }
+
+    for (;;) {
+       while (p->v_left)
+           p = p->v_left;
+x:
+       if (p->v_parent == 0)   /* is it the header? */
+           return;
+       len = blklen(p->vec);
+       (void) fprintf(cshout, "%s\t", short2str(p->v_name));
+       if (len != 1)
+           (void) fputc('(', cshout);
+       blkpr(cshout, p->vec);
+       if (len != 1)
+           (void) fputc(')', cshout);
+       (void) fputc('\n', cshout);
+       if (p->v_right) {
+           p = p->v_right;
+           continue;
        }
        }
+       do {
+           c = p;
+           p = p->v_parent;
+       } while (p->v_right == c);
+       goto x;
+    }
 }
 }