This patch adds support for listsetvar to be used for setting local
variables in bulk through the VLOCAL flag.

It also removes the use of mklocal in evalcommand, and replaces it
with listsetvar.

Signed-off-by: Herbert Xu <herb...@gondor.apana.org.au>

diff --git a/src/eval.c b/src/eval.c
index 39c4e41..23be7ba 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -714,6 +714,7 @@ evalcommand(union node *cmd, int flags)
        int execcmd;
        int status;
        char **nargv;
+       int vflags;
 
        errlinno = lineno = cmd->ncmd.linno;
        if (funcline)
@@ -769,8 +770,6 @@ evalcommand(union node *cmd, int flags)
                spp = varlist.lastp;
                expandarg(argp, &varlist, EXP_VARTILDE);
 
-               mklocal((*spp)->text);
-
                /*
                 * Modify the command lookup path, if a PATH= assignment
                 * is present
@@ -852,6 +851,13 @@ bail:
 
        jp = NULL;
 
+       if (cmdentry.cmdtype == CMDBUILTIN && (spclbltin > 0 || argc == 0))
+               vflags = execcmd && argc > 1 ? VEXPORT : 0;
+       else
+               vflags = VLOCAL | (cmdentry.cmdtype == CMDNORMAL ?
+                                  VEXPORT | VNOFUNC : 0);
+       listsetvar(varlist.list, vflags);
+
        /* Execute the command. */
        switch (cmdentry.cmdtype) {
        default:
@@ -863,16 +869,10 @@ bail:
                                break;
                        FORCEINTON;
                }
-               listsetvar(varlist.list, VEXPORT|VSTACK);
                shellexec(argv, path, cmdentry.u.index);
                /* NOTREACHED */
 
        case CMDBUILTIN:
-               if (spclbltin > 0 || argc == 0) {
-                       poplocalvars(1);
-                       if (execcmd && argc > 1)
-                               listsetvar(varlist.list, VEXPORT);
-               }
                if (evalbltin(cmdentry.u.cmd, argc, argv, flags) &&
                    !(exception == EXERROR && spclbltin <= 0)) {
 raise:
diff --git a/src/var.c b/src/var.c
index cc6f7f2..c877f68 100644
--- a/src/var.c
+++ b/src/var.c
@@ -116,6 +116,7 @@ STATIC struct var *vartab[VTABSIZE];
 STATIC struct var **hashvar(const char *);
 STATIC int vpcmp(const void *, const void *);
 STATIC struct var **findvar(struct var **, const char *);
+static void mklocal(char *name, int flags);
 
 /*
  * Initialize the varable symbol tables and import the environment
@@ -325,7 +326,10 @@ listsetvar(struct strlist *list, int flags)
                return;
        INTOFF;
        do {
-               setvareq(lp->text, flags);
+               if (flags & VLOCAL)
+                       mklocal(lp->text, flags & ~VLOCAL);
+               else
+                       setvareq(lp->text, flags);
        } while ((lp = lp->next));
        INTON;
 }
@@ -475,7 +479,7 @@ localcmd(int argc, char **argv)
 
        argv = argptr;
        while ((name = *argv++) != NULL) {
-               mklocal(name);
+               mklocal(name, 0);
        }
        return 0;
 }
@@ -488,7 +492,7 @@ localcmd(int argc, char **argv)
  * "-" as a special case.
  */
 
-void mklocal(char *name)
+static void mklocal(char *name, int flags)
 {
        struct localvar *lvp;
        struct var **vpp;
@@ -509,16 +513,16 @@ void mklocal(char *name)
                eq = strchr(name, '=');
                if (vp == NULL) {
                        if (eq)
-                               vp = setvareq(name, VSTRFIXED);
+                               vp = setvareq(name, VSTRFIXED | flags);
                        else
-                               vp = setvar(name, NULL, VSTRFIXED);
+                               vp = setvar(name, NULL, VSTRFIXED | flags);
                        lvp->flags = VUNSET;
                } else {
                        lvp->text = vp->text;
                        lvp->flags = vp->flags;
                        vp->flags |= VSTRFIXED|VTEXTFIXED;
                        if (eq)
-                               setvareq(name, 0);
+                               setvareq(name, flags);
                }
        }
        lvp->vp = vp;
diff --git a/src/var.h b/src/var.h
index 872e2db..60eac4b 100644
--- a/src/var.h
+++ b/src/var.h
@@ -50,6 +50,7 @@
 #define VNOFUNC                0x40    /* don't call the callback function */
 #define VNOSET         0x80    /* do not set variable - just readonly test */
 #define VNOSAVE                0x100   /* when text is on the heap before 
setvareq */
+#define VLOCAL         0x200   /* Tell listsetvar to call mklocal */
 
 
 struct var {
@@ -151,7 +152,6 @@ char **listvars(int, int, char ***);
 int showvars(const char *, int, int);
 int exportcmd(int, char **);
 int localcmd(int, char **);
-void mklocal(char *);
 struct localvar_list *pushlocalvars(void);
 void poplocalvars(int);
 void unwindlocalvars(struct localvar_list *stop);
-- 
Email: Herbert Xu <herb...@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to