about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2014-06-01 15:01:37 -0700
committerBarton E. Schaefer <schaefer@zsh.org>2014-06-01 15:01:37 -0700
commit19f3161e51dc880093cb71584f75b77a6084d52e (patch)
tree4a33e447de32eb47ff640ffd4dea9f711d8e8539
parent10ae77c0cfee1e15fe062ee5a6d8a4b31304d58a (diff)
downloadzsh-19f3161e51dc880093cb71584f75b77a6084d52e.tar.gz
zsh-19f3161e51dc880093cb71584f75b77a6084d52e.tar.xz
zsh-19f3161e51dc880093cb71584f75b77a6084d52e.zip
32634: add POSIX_ARGZERO option
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/options.yo25
-rw-r--r--Doc/Zsh/params.yo8
-rw-r--r--Src/init.c5
-rw-r--r--Src/options.c1
-rw-r--r--Src/params.c16
-rw-r--r--Src/zsh.h1
7 files changed, 54 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c2aeab2d..5a4f79080 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2014-06-01  Barton E. Schaefer  <schaefer@zsh.org>
 
+	* 32634 (plus doc): Doc/Zsh/options.yo, Doc/Zsh/params.yo,
+	Src/init.c, Src/options.c, Src/params.c, Src/zsh.h: add the
+	POSIX_ARGZERO option to allow toggling between the original
+	value of $0 and the value set by FUNCTION_ARGZERO
+
 	* Daniel Shahaf: users/18857: Doc/Zsh/expn.yo, Src/glob.c,
 	Test/D02glob.ztst: add (Y) glob qualifier
 
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index f7e11d20f..349946d82 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1608,7 +1608,10 @@ pindex(NOFUNCTIONARGZERO)
 cindex($0, setting)
 item(tt(FUNCTION_ARGZERO) <C> <Z>)(
 When executing a shell function or sourcing a script, set tt($0)
-temporarily to the name of the function/script.
+temporarily to the name of the function/script.  Note that toggling
+tt(FUNCTION_ARGZERO) from on to off (or off to on) does not change the
+current value of tt($0).  Only the state upon entry to the function or
+script has an effect.  Compare tt(POSIX_ARGZERO).
 )
 pindex(LOCAL_OPTIONS)
 pindex(NO_LOCAL_OPTIONS)
@@ -1945,6 +1948,26 @@ as one unit, so aliases defined within the argument are not available even
 in later lines.  If in doubt, avoid use of aliases in non-interactive
 code.
 )
+pindex(POSIX_ARGZERO)
+pindex(NO_POSIX_ARGZERO)
+pindex(POSIXARGZERO)
+pindex(NOPOSIXARGZERO)
+cindex($0, using)
+item(tt(POSIX_ARGZERO))(
+This option may be used to temporarily disable tt(FUNCTION_ARGZERO) and
+thereby restore the value of tt($0) to the name used to invoke the shell
+(or as set by the tt(-c) command line option).  For compatibility with
+previous versions of the shell, emulations use tt(NO_FUNCTION_ARGZERO)
+instead of tt(POSIX_ARGZERO), which may result in unexpected scoping of
+tt($0) if the emulation mode is changed inside a function or script.
+To avoid this, explicitly enable tt(POSIX_ARGZERO) in the tt(emulate)
+command:
+
+example(emulate sh -o POSIX_ARGZERO)
+
+Note that tt(NO_POSIX_ARGZERO) has no effect unless tt(FUNCTION_ARGZERO)
+was already enabled upon entry to the function or script.
+)
 pindex(POSIX_BUILTINS)
 pindex(NO_POSIX_BUILTINS)
 pindex(POSIXBUILTINS)
diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index c1cb9739d..5bccdc2d0 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -541,9 +541,11 @@ The exit status returned by the last command.
 )
 vindex(0)
 item(tt(0) <S>)(
-The name used to invoke the current shell.  If the tt(FUNCTION_ARGZERO) option
-is set, this is set temporarily within a shell function to the name of the
-function, and within a sourced script to the name of the script.
+The name used to invoke the current shell, or as set by the tt(-c) command
+line option upon invocation.  If the tt(FUNCTION_ARGZERO) option is set,
+tt($0) is set upon entry to a shell function to the name of the function,
+and upon entry to a sourced script to the name of the script, and reset to
+its previous value when the function or script returns.
 )
 vindex(status)
 item(tt(status) <S> <Z>)(
diff --git a/Src/init.c b/Src/init.c
index fd12412c7..5e92f59df 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -226,7 +226,7 @@ parseargs(char **argv, char **runscript)
     char **x;
     LinkList paramlist;
 
-    argzero = *argv++;
+    argzero = posixzero = *argv++;
     SHIN = 0;
 
     /* There's a bit of trickery with opts[INTERACTIVE] here.  It starts *
@@ -253,7 +253,7 @@ parseargs(char **argv, char **runscript)
     if (*argv) {
 	if (unset(SHINSTDIN)) {
 	    if (cmd)
-		argzero = *argv;
+		argzero = posixzero = *argv;
 	    else
 		*runscript = *argv;
 	    opts[INTERACTIVE] &= 1;
@@ -275,6 +275,7 @@ parseargs(char **argv, char **runscript)
     while ((*x++ = (char *)getlinknode(paramlist)));
     free(paramlist);
     argzero = ztrdup(argzero);
+    posixzero = ztrdup(posixzero);
 }
 
 /* Insert into list in order of pointer value */
diff --git a/Src/options.c b/Src/options.c
index ce73d9901..e83dc5839 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -207,6 +207,7 @@ static struct optname optns[] = {
 {{NULL, "pathscript",	      OPT_EMULATE|OPT_BOURNE},	 PATHSCRIPT},
 {{NULL, "pipefail",           OPT_EMULATE},              PIPEFAIL},
 {{NULL, "posixaliases",       OPT_EMULATE|OPT_BOURNE},	 POSIXALIASES},
+{{NULL, "posixargzero",       OPT_EMULATE},              POSIXARGZERO},
 {{NULL, "posixbuiltins",      OPT_EMULATE|OPT_BOURNE},	 POSIXBUILTINS},
 {{NULL, "posixcd",            OPT_EMULATE|OPT_BOURNE},	 POSIXCD},
 {{NULL, "posixidentifiers",   OPT_EMULATE|OPT_BOURNE},	 POSIXIDENTIFIERS},
diff --git a/Src/params.c b/Src/params.c
index 790102923..0699ead85 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -67,6 +67,7 @@ char **path,		/* $path        */
 /**/
 mod_export
 char *argzero,		/* $0           */
+     *posixzero,	/* $0           */
      *home,		/* $HOME        */
      *nullcmd,		/* $NULLCMD     */
      *oldpwd,		/* $OLDPWD      */
@@ -194,6 +195,8 @@ static const struct gsu_integer euid_gsu =
 static const struct gsu_integer ttyidle_gsu =
 { ttyidlegetfn, nullintsetfn, stdunsetfn };
 
+static const struct gsu_scalar argzero_gsu =
+{ argzerogetfn, nullstrsetfn, nullunsetfn };
 static const struct gsu_scalar username_gsu =
 { usernamegetfn, usernamesetfn, stdunsetfn };
 static const struct gsu_scalar dash_gsu =
@@ -285,6 +288,7 @@ IPDEF2("WORDCHARS", wordchars_gsu, 0),
 IPDEF2("IFS", ifs_gsu, PM_DONTIMPORT),
 IPDEF2("_", underscore_gsu, PM_DONTIMPORT),
 IPDEF2("KEYBOARD_HACK", keyboard_hack_gsu, PM_DONTIMPORT),
+IPDEF2("0", argzero_gsu, 0),
 
 #ifdef USE_LOCALE
 # define LCIPDEF(name) IPDEF2(name, lc_blah_gsu, PM_UNSET)
@@ -340,7 +344,6 @@ IPDEF7U("RPROMPT2", &rprompt2),
 IPDEF7("PS3", &prompt3),
 IPDEF7("PS4", &prompt4),
 IPDEF7("SPROMPT", &sprompt),
-IPDEF7("0", &argzero),
 
 #define IPDEF8(A,B,C,D) {{NULL,A,D|PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(colonarr_gsu),0,0,NULL,C,NULL,0}
 IPDEF8("CDPATH", &cdpath, "cdpath", 0),
@@ -3981,6 +3984,17 @@ lcsetfn(Param pm, char *x)
 }
 #endif /* USE_LOCALE */
 
+/* Function to get value for special parameter `0' */
+
+/**/
+static char *
+argzerogetfn(UNUSED(Param pm))
+{
+    if (isset(POSIXARGZERO))
+	return posixzero;
+    return argzero;
+}
+
 /* Function to get value for special parameter `HISTSIZE' */
 
 /**/
diff --git a/Src/zsh.h b/Src/zsh.h
index 5fbff5767..620883b81 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2151,6 +2151,7 @@ enum {
     PATHSCRIPT,
     PIPEFAIL,
     POSIXALIASES,
+    POSIXARGZERO,
     POSIXBUILTINS,
     POSIXCD,
     POSIXIDENTIFIERS,