summaryrefslogtreecommitdiff
path: root/Src/params.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/params.c')
-rw-r--r--Src/params.c110
1 files changed, 94 insertions, 16 deletions
diff --git a/Src/params.c b/Src/params.c
index de151a4cd..b121bd6ad 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -447,7 +447,7 @@ newparamtable(int size, char const *name)
ht->cmpnodes = strcmp;
ht->addnode = addhashnode;
ht->getnode = getparamnode;
- ht->getnode2 = getparamnode;
+ ht->getnode2 = gethashnode2;
ht->removenode = removehashnode;
ht->disablenode = NULL;
ht->enablenode = NULL;
@@ -775,17 +775,18 @@ createparamtable(void)
#endif
opts[ALLEXPORT] = oae;
+ /*
+ * For native emulation we always set the variable home
+ * (see setupvals()).
+ */
+ pm = (Param) paramtab->getnode(paramtab, "HOME");
if (EMULATION(EMULATE_ZSH))
{
- /*
- * For native emulation we always set the variable home
- * (see setupvals()).
- */
- pm = (Param) paramtab->getnode(paramtab, "HOME");
pm->node.flags &= ~PM_UNSET;
if (!(pm->node.flags & PM_EXPORTED))
addenv(pm, home);
- }
+ } else if (!home)
+ pm->node.flags |= PM_UNSET;
pm = (Param) paramtab->getnode(paramtab, "LOGNAME");
if (!(pm->node.flags & PM_EXPORTED))
addenv(pm, pm->u.str);
@@ -868,6 +869,7 @@ createparam(char *name, int flags)
if (name != nulstring) {
oldpm = (Param) (paramtab == realparamtab ?
+ /* gethashnode2() for direct table read */
gethashnode2(paramtab, name) :
paramtab->getnode(paramtab, name));
@@ -2694,6 +2696,37 @@ gethkparam(char *s)
}
/**/
+static void
+check_warn_create(Param pm, const char *pmtype)
+{
+ Funcstack i;
+ const char *name;
+
+ if (pm->level != 0 || (pm->node.flags & PM_SPECIAL))
+ return;
+
+ name = NULL;
+ for (i = funcstack; i; i = i->prev) {
+ if (i->tp == FS_FUNC) {
+ DPUTS(!i->name, "funcstack entry with no name");
+ name = i->name;
+ break;
+ }
+ }
+
+ if (name)
+ {
+ zwarn("%s parameter %s created globally in function %s",
+ pmtype, pm->node.nam, name);
+ }
+ else
+ {
+ zwarn("%s parameter %s created globally in function",
+ pmtype, pm->node.nam);
+ }
+}
+
+/**/
mod_export Param
assignsparam(char *s, char *val, int flags)
{
@@ -2746,9 +2779,8 @@ assignsparam(char *s, char *val, int flags)
zsfree(val);
return NULL;
}
- if ((flags & ASSPM_WARN_CREATE) && v->pm->level == 0)
- zwarn("scalar parameter %s created globally in function",
- v->pm->node.nam);
+ if (flags & ASSPM_WARN_CREATE)
+ check_warn_create(v->pm, "scalar");
if (flags & ASSPM_AUGMENT) {
if (v->start == 0 && v->end == -1) {
switch (PM_TYPE(v->pm->node.flags)) {
@@ -2827,6 +2859,15 @@ assignsparam(char *s, char *val, int flags)
/**/
mod_export Param
+setsparam(char *s, char *val)
+{
+ return assignsparam(
+ s, val, isset(WARNCREATEGLOBAL) && locallevel > 0 ?
+ ASSPM_WARN_CREATE : 0);
+}
+
+/**/
+mod_export Param
assignaparam(char *s, char **val, int flags)
{
struct value vbuf;
@@ -2888,9 +2929,8 @@ assignaparam(char *s, char **val, int flags)
return NULL;
}
- if ((flags & ASSPM_WARN_CREATE) && v->pm->level == 0)
- zwarn("array parameter %s created globally in function",
- v->pm->node.nam);
+ if (flags & ASSPM_WARN_CREATE)
+ check_warn_create(v->pm, "array");
if (flags & ASSPM_AUGMENT) {
if (v->start == 0 && v->end == -1) {
if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) {
@@ -2913,6 +2953,16 @@ assignaparam(char *s, char **val, int flags)
return v->pm;
}
+
+/**/
+mod_export Param
+setaparam(char *s, char **aval)
+{
+ return assignaparam(
+ s, aval, isset(WARNCREATEGLOBAL) && locallevel >0 ?
+ ASSPM_WARN_CREATE : 0);
+}
+
/**/
mod_export Param
sethparam(char *s, char **val)
@@ -2936,11 +2986,14 @@ sethparam(char *s, char **val)
if (unset(EXECOPT))
return NULL;
queue_signals();
- if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING)))
+ if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING))) {
createparam(t, PM_HASHED);
- else if (!(PM_TYPE(v->pm->node.flags) & PM_HASHED) &&
+ if (isset(WARNCREATEGLOBAL) && locallevel > 0)
+ check_warn_create(v->pm, "associative array");
+ } else if (!(PM_TYPE(v->pm->node.flags) & PM_HASHED) &&
!(v->pm->node.flags & PM_SPECIAL)) {
unsetparam(t);
+ /* no WARNCREATEGLOBAL check here as parameter already existed */
createparam(t, PM_HASHED);
v = NULL;
}
@@ -2967,6 +3020,7 @@ setnparam(char *s, mnumber val)
Value v;
char *t = s, *ss;
Param pm;
+ int was_unset = 0;
if (!isident(s)) {
zerr("not an identifier: %s", s);
@@ -2986,6 +3040,7 @@ setnparam(char *s, mnumber val)
*/
unset(KSHARRAYS) && !ss) {
unsetparam_pm(v->pm, 0, 1);
+ was_unset = 1;
s = t;
v = NULL;
}
@@ -3006,6 +3061,8 @@ setnparam(char *s, mnumber val)
}
v = getvalue(&vbuf, &t, 1);
DPUTS(!v, "BUG: value not found for new parameter");
+ if (!was_unset && isset(WARNCREATEGLOBAL) && locallevel > 0)
+ check_warn_create(v->pm, "numeric");
}
setnumvalue(v, val);
unqueue_signals();
@@ -3024,6 +3081,26 @@ setiparam(char *s, zlong val)
return setnparam(s, mnval);
}
+/*
+ * Set an integer parameter without forcing creation of an integer type.
+ * This is useful if the integer is going to be set to a parmaeter which
+ * would usually be scalar but may not exist.
+ */
+
+/**/
+mod_export Param
+setiparam_no_convert(char *s, zlong val)
+{
+ /*
+ * If the target is already an integer, thisgets converted
+ * back. Low technology rules.
+ */
+ char buf[BDIGBUFSIZE];
+ convbase(buf, val, 10);
+ return assignsparam(
+ s, ztrdup(buf),
+ isset(WARNCREATEGLOBAL) && locallevel > 0 ? ASSPM_WARN_CREATE : 0);
+}
/* Unset a parameter */
@@ -3035,7 +3112,8 @@ unsetparam(char *s)
queue_signals();
if ((pm = (Param) (paramtab == realparamtab ?
- gethashnode2(paramtab, s) :
+ /* getnode2() to avoid autoloading */
+ paramtab->getnode2(paramtab, s) :
paramtab->getnode(paramtab, s))))
unsetparam_pm(pm, 0, 1);
unqueue_signals();