summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2015-10-29 15:01:07 +0000
committerPeter Stephenson <pws@zsh.org>2015-10-29 15:01:07 +0000
commit0628802baf5c9245138db82dd058cad023a7d0ae (patch)
treebdbc600fe01ccbac2fb1b34814626a53f909c806 /Src
parent9640e9f497e8d78bf0bfa9defc4cfdeba1e7bfae (diff)
downloadzsh-0628802baf5c9245138db82dd058cad023a7d0ae.tar.gz
zsh-0628802baf5c9245138db82dd058cad023a7d0ae.tar.xz
zsh-0628802baf5c9245138db82dd058cad023a7d0ae.zip
37014: Improved internal parameter setting.
Enhance WARNCREATEGLOBAL to work in many more cases.

Don't create REPLY as an integer if it didn't previously exist
as one, even if the value to be set is integral, as this is likely to
mess up later uses of REPLY.
Diffstat (limited to 'Src')
-rw-r--r--Src/Modules/socket.c6
-rw-r--r--Src/Modules/tcp.c6
-rw-r--r--Src/Modules/zpty.c2
-rw-r--r--Src/builtin.c38
-rw-r--r--Src/params.c53
-rw-r--r--Src/zsh.h3
6 files changed, 80 insertions, 28 deletions
diff --git a/Src/Modules/socket.c b/Src/Modules/socket.c
index f683496df..7c3fb5ebe 100644
--- a/Src/Modules/socket.c
+++ b/Src/Modules/socket.c
@@ -132,7 +132,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	/* allow to be closed explicitly */
 	fdtable[sfd] = FDT_EXTERNAL;
 
-	setiparam("REPLY", sfd);
+	setiparam_no_convert("REPLY", (zlong)sfd);
 
 	if (verbose)
 	    printf("%s listener is on fd %d\n", soun.sun_path, sfd);
@@ -220,7 +220,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 	    sfd = rfd;
 	}
 
-	setiparam("REPLY", sfd);
+	setiparam_no_convert("REPLY", (zlong)sfd);
 
 	if (verbose)
 	    printf("new connection from %s is on fd %d\n", soun.sun_path, sfd);
@@ -261,7 +261,7 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
 		fdtable[sfd] = FDT_EXTERNAL;
 	    }
 
-	    setiparam("REPLY", sfd);
+	    setiparam_no_convert("REPLY", (zlong)sfd);
 
 	    if (verbose)
 		printf("%s is now on fd %d\n", soun.sun_path, sfd);
diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c
index 7b0dcc74a..9fc1b29a2 100644
--- a/Src/Modules/tcp.c
+++ b/Src/Modules/tcp.c
@@ -461,7 +461,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    return 1;
 	}
 
-	setiparam("REPLY", sess->fd);
+	setiparam_no_convert("REPLY", (zlong)sess->fd);
 
 	if (verbose)
 	    printf("%d listener is on fd %d\n", ntohs(sess->sock.in.sin_port), sess->fd);
@@ -562,7 +562,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    sess->fd = rfd;
 	}
 
-	setiparam("REPLY", sess->fd);
+	setiparam_no_convert("REPLY", (zlong)sess->fd);
 
 	if (verbose)
 	    printf("%d is on fd %d\n", ntohs(sess->peer.in.sin_port), sess->fd);
@@ -681,7 +681,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 		}
 	    }
 
-	    setiparam("REPLY", sess->fd);
+	    setiparam_no_convert("REPLY", (zlong)sess->fd);
 
 	    if (verbose)
 		printf("%s:%d is now on fd %d\n",
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 9741ee287..3b8366076 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -464,7 +464,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 #endif
 	    errno == EINTR));
 
-    setiparam("REPLY", master);
+    setiparam_no_convert("REPLY", (zlong)master);
 
     return 0;
 }
diff --git a/Src/builtin.c b/Src/builtin.c
index 97022addf..8045bc8f7 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2090,7 +2090,9 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 			tc = 0;	/* but don't do a normal conversion */
 		    }
 		} else if (!setsecondstype(pm, on, off)) {
-		    if (asg->value.scalar && !(pm = setsparam(pname, ztrdup(asg->value.scalar))))
+		    if (asg->value.scalar &&
+			!(pm = assignsparam(
+			      pname, ztrdup(asg->value.scalar), 0)))
 			return NULL;
 		    usepm = 1;
 		    err = 0;
@@ -2202,12 +2204,13 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	    } else if (pm->env && !(pm->node.flags & PM_HASHELEM))
 		delenv(pm);
 	    DPUTS(ASG_ARRAYP(asg), "BUG: typeset got array value where scalar expected");
-	    if (asg->value.scalar && !(pm = setsparam(pname, ztrdup(asg->value.scalar))))
+	    if (asg->value.scalar &&
+		!(pm = assignsparam(pname, ztrdup(asg->value.scalar), 0)))
 		return NULL;
 	} else if (asg->is_array) {
-	    if (!(pm = setaparam(pname, asg->value.array ?
+	    if (!(pm = assignaparam(pname, asg->value.array ?
 				 zlinklist2array(asg->value.array) :
-				 mkarray(NULL))))
+				 mkarray(NULL), 0)))
 		return NULL;
 	}
 	pm->node.flags |= (on & PM_READONLY);
@@ -2347,16 +2350,18 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	     * creating a stray parameter along the way via createparam(),
 	     * now called below in the isident() branch.
 	     */
-	    if (!(pm = setsparam(pname, ztrdup(asg->value.scalar ? asg->value.scalar : ""))))
+	    if (!(pm = assignsparam(
+		      pname,
+		      ztrdup(asg->value.scalar ? asg->value.scalar : ""), 0)))
 		return NULL;
 	    dont_set = 1;
 	    asg->is_array = 0;
 	    keeplocal = 0;
 	    on = pm->node.flags;
 	} else if (PM_TYPE(on) == PM_ARRAY && ASG_ARRAYP(asg)) {
-	    if (!(pm = setaparam(pname, asg->value.array ?
-				 zlinklist2array(asg->value.array) :
-				 mkarray(NULL))))
+	    if (!(pm = assignaparam(pname, asg->value.array ?
+				    zlinklist2array(asg->value.array) :
+				    mkarray(NULL), 0)))
 		return NULL;
 	    dont_set = 1;
 	    keeplocal = 0;
@@ -2433,13 +2438,13 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 	Param ipm = pm;
 	if (pm->node.flags & (PM_ARRAY|PM_HASHED)) {
 	    DPUTS(!ASG_ARRAYP(asg), "BUG: inconsistent scalar value for array");
-	    if (!(pm=setaparam(pname, asg->value.array ?
-			       zlinklist2array(asg->value.array) :
-			       mkarray(NULL))))
+	    if (!(pm=assignaparam(pname, asg->value.array ?
+				  zlinklist2array(asg->value.array) :
+				  mkarray(NULL), 0)))
 		return NULL;
 	} else {
 	    DPUTS(ASG_ARRAYP(asg), "BUG: inconsistent array value for scalar");
-	    if (!(pm = setsparam(pname, ztrdup(asg->value.scalar))))
+	    if (!(pm = assignsparam(pname, ztrdup(asg->value.scalar), 0)))
 		return NULL;
 	}
 	if (pm != ipm) {
@@ -2687,9 +2692,10 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 		    /* Update join character */
 		    tdp->joinchar = joinchar;
 		    if (asg0.value.scalar)
-			setsparam(asg0.name, ztrdup(asg0.value.scalar));
+			assignsparam(asg0.name, ztrdup(asg0.value.scalar), 0);
 		    else if (asg->value.array)
-			setaparam(asg->name, zlinklist2array(asg->value.array));
+			assignaparam(
+			    asg->name, zlinklist2array(asg->value.array), 0);
 		    return 0;
 		} else {
 		    zwarnnam(name, "can't tie already tied scalar: %s",
@@ -2750,9 +2756,9 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 	    zsfree(apm->ename);
 	apm->ename = ztrdup(asg0.name);
 	if (asg->value.array)
-	    setaparam(asg->name, zlinklist2array(asg->value.array));
+	    assignaparam(asg->name, zlinklist2array(asg->value.array), 0);
 	else if (oldval)
-	    setsparam(asg0.name, oldval);
+	    assignsparam(asg0.name, oldval, 0);
 	unqueue_signals();
 
 	return 0;
diff --git a/Src/params.c b/Src/params.c
index a8abb289e..4d33660fb 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -2828,6 +2828,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;
@@ -2914,6 +2923,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)
@@ -2937,11 +2956,15 @@ 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 && v->pm->level == 0)
+	    zwarn("associative array parameter %s created globally in function",
+		  v->pm->node.nam);
+    } 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;
     }
@@ -2968,6 +2991,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);
@@ -2987,6 +3011,7 @@ setnparam(char *s, mnumber val)
 	 */
 	unset(KSHARRAYS) && !ss) {
 	unsetparam_pm(v->pm, 0, 1);
+	was_unset = 1;
 	s = t;
 	v = NULL;
     }
@@ -3007,6 +3032,10 @@ 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 &&
+	    v->pm->level == 0)
+	    zwarn("numeric parameter %s created globally in function",
+		  v->pm->node.nam);
     }
     setnumvalue(v, val);
     unqueue_signals();
@@ -3025,6 +3054,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 */
 
diff --git a/Src/zsh.h b/Src/zsh.h
index f819249c3..d03d171e4 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1939,9 +1939,6 @@ struct paramdef {
     { name, flags | PM_SPECIAL | PM_HIDE | PM_HIDEVAL, \
 	    NULL, gsufn, getfn, scanfn, NULL }
 
-#define setsparam(S,V) assignsparam(S,V,0)
-#define setaparam(S,V) assignaparam(S,V,0)
-
 /*
  * Flags for assignsparam and assignaparam.
  */