From 0f1ffe0925ef6aff9c56a3a4ca7b84b7411fc2b4 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 24 May 2010 15:31:27 +0800 Subject: [VAR] Add localvars nesting This patch adds localvars nesting infrastructure so we can reuse the localvars mechanism for command evaluation. Signed-off-by: Herbert Xu --- src/var.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'src/var.c') diff --git a/src/var.c b/src/var.c index 2737fb1..de1a5f5 100644 --- a/src/var.c +++ b/src/var.c @@ -64,7 +64,12 @@ #define VTABSIZE 39 -struct localvar *localvars; +struct localvar_list { + struct localvar_list *next; + struct localvar *lv; +}; + +MKINIT struct localvar_list *localvar_stack; const char defpathvar[] = "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; @@ -139,6 +144,11 @@ INIT { p = 0; setpwd(p, 0); } + +RESET { + while (localvar_stack) + poplocalvars(); +} #endif @@ -446,6 +456,9 @@ localcmd(int argc, char **argv) { char *name; + if (!localvar_stack) + sh_error("not in a function"); + argv = argptr; while ((name = *argv++) != NULL) { mklocal(name); @@ -497,8 +510,8 @@ mklocal(char *name) } } lvp->vp = vp; - lvp->next = localvars; - localvars = lvp; + lvp->next = localvar_stack->lv; + localvar_stack->lv = lvp; INTON; } @@ -511,11 +524,19 @@ mklocal(char *name) void poplocalvars(void) { - struct localvar *lvp; + struct localvar_list *ll; + struct localvar *lvp, *next; struct var *vp; - while ((lvp = localvars) != NULL) { - localvars = lvp->next; + INTOFF; + ll = localvar_stack; + localvar_stack = ll->next; + + next = ll->lv; + ckfree(ll); + + while ((lvp = next) != NULL) { + next = lvp->next; vp = lvp->vp; TRACE(("poplocalvar %s", vp ? vp->text : "-")); if (vp == NULL) { /* $- saved */ @@ -534,6 +555,23 @@ poplocalvars(void) } ckfree(lvp); } + INTON; +} + + +/* + * Create a new localvar environment. + */ +void pushlocalvars(void) +{ + struct localvar_list *ll; + + INTOFF; + ll = ckmalloc(sizeof(*ll)); + ll->lv = NULL; + ll->next = localvar_stack; + localvar_stack = ll; + INTON; } -- cgit 1.4.1