summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--Functions/MIME/zsh-mime-setup2
-rw-r--r--Functions/Misc/add-zsh-hook2
-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
9 files changed, 94 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 0c38b2697..9454013cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2015-10-29  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* 37014: Functions/MIME/zsh-mime-setup,
+	Functions/Misc/add-zsh-hook, Src/Modules/socket.c,
+	Src/Modules/tcp.c, Src/Modules/zpty.c, Src/builtin.c,
+	Src/params.c,Src/zsh.h: 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.
+
 2015-10-29  Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
 
 	* 36983 (with fix from 36990): Completion/Unix/Command/_head,
diff --git a/Functions/MIME/zsh-mime-setup b/Functions/MIME/zsh-mime-setup
index 23e44fdc0..35f6e6b6b 100644
--- a/Functions/MIME/zsh-mime-setup
+++ b/Functions/MIME/zsh-mime-setup
@@ -1,7 +1,7 @@
 emulate -L zsh
 setopt extendedglob cbases
 
-local opt o_verbose o_list
+local opt o_verbose o_list i
 
 autoload -Uz zsh-mime-handler
 
diff --git a/Functions/Misc/add-zsh-hook b/Functions/Misc/add-zsh-hook
index ee37d674d..fc39659ae 100644
--- a/Functions/Misc/add-zsh-hook
+++ b/Functions/Misc/add-zsh-hook
@@ -82,9 +82,11 @@ if (( del )); then
 else
   if (( ${(P)+hook} )); then
     if (( ${${(P)hook}[(I)$fn]} == 0 )); then
+      typeset -ga $hook
       set -A $hook ${(P)hook} $fn
     fi
   else
+    typeset -ga $hook
     set -A $hook $fn
   fi
   autoload $autoopts -- $fn
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.
  */