summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2000-04-13 14:22:47 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2000-04-13 14:22:47 +0000
commitcf92384eac7c961d96a9bf3bde3df8f8427b45bc (patch)
tree9c8f88188a053a6979e40e1661df1e8069403de6 /Src
parentb692ed1b9d19d10646d3870bb3b9b301216bddf7 (diff)
downloadzsh-cf92384eac7c961d96a9bf3bde3df8f8427b45bc.tar.gz
zsh-cf92384eac7c961d96a9bf3bde3df8f8427b45bc.zip
10738: pws: local parameters can be exported
Diffstat (limited to 'Src')
-rw-r--r--Src/builtin.c26
-rw-r--r--Src/params.c71
2 files changed, 61 insertions, 36 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index 6cb03b3f5..f18e956e8 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -79,7 +79,7 @@ static struct builtin builtins[] =
BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
BUILTIN("kill", 0, bin_kill, 0, -1, 0, NULL, NULL),
BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL),
- BUILTIN("local", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFLRTUZahilrtu", NULL),
+ BUILTIN("local", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFLRTUZahilrtux", NULL),
BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL),
BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL),
@@ -644,14 +644,12 @@ set_pwd_env(void)
setsparam("OLDPWD", ztrdup(oldpwd));
pm = (Param) paramtab->getnode(paramtab, "PWD");
- if (!(pm->flags & PM_EXPORTED) &&
- (!pm->level || (isset(ALLEXPORT) && !pm->old))) {
+ if (!(pm->flags & PM_EXPORTED)) {
pm->flags |= PM_EXPORTED;
pm->env = addenv("PWD", pwd, pm->flags);
}
pm = (Param) paramtab->getnode(paramtab, "OLDPWD");
- if (!(pm->flags & PM_EXPORTED) &&
- (!pm->level || (isset(ALLEXPORT) && !pm->old))) {
+ if (!(pm->flags & PM_EXPORTED)) {
pm->flags |= PM_EXPORTED;
pm->env = addenv("OLDPWD", oldpwd, pm->flags);
}
@@ -1589,7 +1587,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
}
/*
- * According to the manual, local parameters don't get exported.
* A parameter will be local if
* 1. we are re-using an existing local parameter
* or
@@ -1598,10 +1595,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
* or
* ii. we are creating a new local parameter
*/
- if ((usepm && pm->level) ||
- (!usepm && (pm || (locallevel && (on & PM_LOCAL)))))
- on &= ~PM_EXPORTED;
-
if (usepm) {
on &= ~PM_LOCAL;
if (!on && !roff && !value) {
@@ -1630,9 +1623,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
if (pm->flags & PM_EXPORTED) {
if (!(pm->flags & PM_UNSET) && !pm->env && !value)
pm->env = addenv(pname, getsparam(pname), pm->flags);
- } else if (pm->env &&
- (!pm->level || (isset(ALLEXPORT) && !pm->old &&
- !(pm->flags & PM_HASHELEM)))) {
+ } else if (pm->env && !(pm->flags & PM_HASHELEM)) {
delenv(pm->env);
zsfree(pm->env);
pm->env = NULL;
@@ -1708,7 +1699,11 @@ typeset_single(char *cname, char *pname, Param pm, int func,
tpm->old = pm->old;
tpm->level = pm->level;
tpm->ct = pm->ct;
- tpm->env = pm->env;
+ if (pm->env) {
+ delenv(pm->env);
+ zsfree(pm->env);
+ }
+ tpm->env = pm->env = NULL;
pm->old = tpm;
/*
@@ -1725,7 +1720,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
pm->ct = auxlen;
else
pm->ct = 0;
- pm->env = NULL;
} else {
/*
* Create a new node for a parameter with the flags in `on' minus the
@@ -1856,7 +1850,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
return 0;
}
- if (!ops['g'] && !ops['x'])
+ if ((!ops['g'] && !ops['x']) || ops['g'] == 2 || *name == 'l')
on |= PM_LOCAL;
if (on & PM_TIED) {
diff --git a/Src/params.c b/Src/params.c
index 3179fc6a7..6a9dfe588 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -643,13 +643,21 @@ createparam(char *name, int flags)
} else {
pm = (Param) zcalloc(sizeof *pm);
if ((pm->old = oldpm)) {
- /* needed to avoid freeing oldpm */
+ /*
+ * needed to avoid freeing oldpm, but we do take it
+ * out of the environment when it's hidden.
+ */
+ if (oldpm->env) {
+ delenv(oldpm->env);
+ zsfree(oldpm->env);
+ oldpm->env = NULL;
+ }
paramtab->removenode(paramtab, name);
}
paramtab->addnode(paramtab, ztrdup(name), pm);
}
- if (isset(ALLEXPORT) && !oldpm && !(flags & PM_HASHELEM))
+ if (isset(ALLEXPORT) && !(flags & PM_HASHELEM))
flags |= PM_EXPORTED;
} else {
pm = (Param) zhalloc(sizeof *pm);
@@ -1446,11 +1454,30 @@ getnumvalue(Value v)
}
/**/
+void
+export_param(Param pm)
+{
+ char buf[(sizeof(zlong) * 8) + 4], *val;
+
+ if (PM_TYPE(pm->flags) == PM_INTEGER)
+ convbase(val = buf, pm->gets.ifn(pm), pm->ct);
+ else if (pm->flags & (PM_EFLOAT|PM_FFLOAT))
+ val = convfloat(pm->gets.ffn(pm), pm->ct,
+ pm->flags, NULL);
+ else
+ val = pm->gets.cfn(pm);
+ if (pm->env)
+ pm->env = replenv(pm->env, val, pm->flags);
+ else {
+ pm->flags |= PM_EXPORTED;
+ pm->env = addenv(pm->nam, val, pm->flags);
+ }
+}
+
+/**/
mod_export void
setstrvalue(Value v, char *val)
{
- char buf[(sizeof(zlong) * 8) + 4];
-
if (v->pm->flags & PM_READONLY) {
zerr("read-only variable: %s", v->pm->nam, 0);
zsfree(val);
@@ -1523,22 +1550,10 @@ setstrvalue(Value v, char *val)
break;
}
if ((!v->pm->env && !(v->pm->flags & PM_EXPORTED) &&
- !(isset(ALLEXPORT) && !v->pm->old && !(v->pm->flags & PM_HASHELEM))) ||
+ !(isset(ALLEXPORT) && !(v->pm->flags & PM_HASHELEM))) ||
(v->pm->flags & PM_ARRAY) || v->pm->ename)
return;
- if (PM_TYPE(v->pm->flags) == PM_INTEGER)
- convbase(val = buf, v->pm->gets.ifn(v->pm), v->pm->ct);
- else if (v->pm->flags & (PM_EFLOAT|PM_FFLOAT))
- val = convfloat(v->pm->gets.ffn(v->pm), v->pm->ct,
- v->pm->flags, NULL);
- else
- val = v->pm->gets.cfn(v->pm);
- if (v->pm->env)
- v->pm->env = replenv(v->pm->env, val, v->pm->flags);
- else {
- v->pm->flags |= PM_EXPORTED;
- v->pm->env = addenv(v->pm->nam, val, v->pm->flags);
- }
+ export_param(v->pm);
}
/**/
@@ -1969,6 +1984,15 @@ unsetparam_pm(Param pm, int altflag, int exp)
if ((PM_TYPE(oldpm->flags) == PM_SCALAR) &&
oldpm->sets.cfn == strsetfn)
adduserdir(oldpm->nam, oldpm->u.str, 0, 0);
+ if (oldpm->flags & PM_EXPORTED) {
+ /*
+ * Re-export the old value which we removed in typeset_single().
+ * I don't think we need to test for ALL_EXPORT here, since if
+ * it was used to export the parameter originally the parmeter
+ * should still have the PM_EXPORTED flag.
+ */
+ export_param(oldpm);
+ }
}
paramtab->freenode((HashNode) pm); /* free parameter node */
@@ -2745,7 +2769,7 @@ arrfixenv(char *s, char **t)
*/
if (t == path)
cmdnamtab->emptytable(cmdnamtab);
- if ((pm->flags & PM_HASHELEM) || (isset(ALLEXPORT) ? !!pm->old : pm->level))
+ if (pm->flags & PM_HASHELEM)
return;
u = t ? zjoin(t, ':', 1) : "";
len_s = strlen(s);
@@ -3013,7 +3037,11 @@ scanendscope(HashNode hn, int flags)
pm->flags = (tpm->flags & ~PM_NORESTORE);
pm->level = tpm->level;
pm->ct = tpm->ct;
- pm->env = tpm->env;
+ if (pm->env) {
+ delenv(pm->env);
+ zsfree(pm->env);
+ }
+ pm->env = NULL;
if (!(tpm->flags & PM_NORESTORE))
switch (PM_TYPE(pm->flags)) {
@@ -3035,6 +3063,9 @@ scanendscope(HashNode hn, int flags)
break;
}
zfree(tpm, sizeof(*tpm));
+
+ if (pm->flags & PM_EXPORTED)
+ export_param(pm);
} else
unsetparam_pm(pm, 0, 0);
}