-static char *space(int n)
-{
- char *cp;
-
- if ((cp = getcell(n)) == 0)
- err("out of string space");
- return (cp);
-}
-
-static char *strsave(char *s, int a)
-{
- char *cp, *xp;
-
- if ((cp = space(strlen(s) + 1)) != NULL) {
- setarea((char *) cp, a);
- for (xp = cp; (*xp++ = *s++) != '\0';);
- return (cp);
- }
- return ("");
-}
-
-/*
- * trap handling
- */
-static void sig(int i)
-{
- trapset = i;
- signal(i, sig);
-}
-
-static void runtrap(int i)
-{
- char *trapstr;
-
- if ((trapstr = trap[i]) == NULL)
- return;
-
- if (i == 0)
- trap[i] = 0;
-
- RUN(aword, trapstr, nlchar);
-}
-
-/* -------- var.c -------- */
-
-/*
- * Find the given name in the dictionary
- * and return its value. If the name was
- * not previously there, enter it now and
- * return a null value.
- */
-static struct var *lookup(char *n)
-{
- struct var *vp;
- char *cp;
- int c;
- static struct var dummy;
-
- if (isdigit(*n)) {
- dummy.name = n;
- for (c = 0; isdigit(*n) && c < 1000; n++)
- c = c * 10 + *n - '0';
- dummy.status = RONLY;
- dummy.value = c <= dolc ? dolv[c] : null;
- return (&dummy);
- }
- for (vp = vlist; vp; vp = vp->next)
- if (eqname(vp->name, n))
- return (vp);
- cp = findeq(n);
- vp = (struct var *) space(sizeof(*vp));
- if (vp == 0 || (vp->name = space((int) (cp - n) + 2)) == 0) {
- dummy.name = dummy.value = "";
- return (&dummy);
- }
- for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++);
- if (*cp == 0)
- *cp = '=';
- *++cp = 0;
- setarea((char *) vp, 0);
- setarea((char *) vp->name, 0);
- vp->value = null;
- vp->next = vlist;
- vp->status = GETCELL;
- vlist = vp;
- return (vp);
-}
-
-/*
- * give variable at `vp' the value `val'.
- */
-static void setval(struct var *vp, char *val)
-{
- nameval(vp, val, (char *) NULL);
-}
-
-/*
- * if name is not NULL, it must be
- * a prefix of the space `val',
- * and end with `='.
- * this is all so that exporting
- * values is reasonably painless.
- */
-static void nameval(struct var *vp, char *val, char *name)
-{
- char *cp, *xp;
- char *nv;
- int fl;
-
- if (vp->status & RONLY) {
- for (xp = vp->name; *xp && *xp != '=';)
- putc(*xp++, stderr);
- err(" is read-only");
- return;
- }
- fl = 0;
- if (name == NULL) {
- xp = space(strlen(vp->name) + strlen(val) + 2);
- if (xp == 0)
- return;
- /* make string: name=value */
- setarea((char *) xp, 0);
- name = xp;
- for (cp = vp->name; (*xp = *cp++) && *xp != '='; xp++);
- if (*xp++ == 0)
- xp[-1] = '=';
- nv = xp;
- for (cp = val; (*xp++ = *cp++) != '\0';);
- val = nv;
- fl = GETCELL;
- }
- if (vp->status & GETCELL)
- freecell(vp->name); /* form new string `name=value' */
- vp->name = name;
- vp->value = val;
- vp->status |= fl;
-}
-
-static void export(struct var *vp)
-{
- vp->status |= EXPORT;
-}
-
-static void ronly(struct var *vp)
-{
- if (isalpha(vp->name[0]) || vp->name[0] == '_') /* not an internal symbol */
- vp->status |= RONLY;
-}
-
-static int isassign(char *s)
-{
- DBGPRINTF7(("ISASSIGN: enter, s=%s\n", s));
-
- if (!isalpha((int) *s) && *s != '_')
- return (0);
- for (; *s != '='; s++)
- if (*s == 0 || (!isalnum(*s) && *s != '_'))
- return (0);
-
- return (1);
-}
-
-static int assign(char *s, int cf)
-{
- char *cp;
- struct var *vp;
-
- DBGPRINTF7(("ASSIGN: enter, s=%s, cf=%d\n", s, cf));
-
- if (!isalpha(*s) && *s != '_')
- return (0);
- for (cp = s; *cp != '='; cp++)
- if (*cp == 0 || (!isalnum(*cp) && *cp != '_'))
- return (0);
- vp = lookup(s);
- nameval(vp, ++cp, cf == COPYV ? (char *) NULL : s);
- if (cf != COPYV)
- vp->status &= ~GETCELL;
- return (1);
-}
-
-static int checkname(char *cp)
-{
- DBGPRINTF7(("CHECKNAME: enter, cp=%s\n", cp));
-
- if (!isalpha(*cp++) && *(cp - 1) != '_')
- return (0);
- while (*cp)
- if (!isalnum(*cp++) && *(cp - 1) != '_')
- return (0);
- return (1);
-}
-
-static void putvlist(int f, int out)
-{
- struct var *vp;
-
- for (vp = vlist; vp; vp = vp->next)
- if (vp->status & f && (isalpha(*vp->name) || *vp->name == '_')) {
- if (vp->status & EXPORT)
- write(out, "export ", 7);
- if (vp->status & RONLY)
- write(out, "readonly ", 9);
- write(out, vp->name, (int) (findeq(vp->name) - vp->name));
- write(out, "\n", 1);
- }
-}
-
-static int eqname(char *n1, char *n2)
-{
- for (; *n1 != '=' && *n1 != 0; n1++)
- if (*n2++ != *n1)
- return (0);
- return (*n2 == 0 || *n2 == '=');
-}
-
-static char *findeq(char *cp)
-{
- while (*cp != '\0' && *cp != '=')
- cp++;
- return (cp);
-}