From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9075 invoked by alias); 31 May 2014 05:13:25 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 32634 Received: (qmail 16222 invoked from network); 31 May 2014 05:13:21 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 From: Bart Schaefer Message-id: <140530221301.ZM31798@torch.brasslantern.com> Date: Fri, 30 May 2014 22:13:01 -0700 In-reply-to: <5388F4C3.6070801@bbn.com> Comments: In reply to Richard Hansen "Re: 'emulate sh -c' and $0" (May 30, 5:14pm) References: <5387BD0D.8090202@bbn.com> <140529204533.ZM5362@torch.brasslantern.com> <5388461D.8060203@bbn.com> <140530100050.ZM18382@torch.brasslantern.com> <5388F4C3.6070801@bbn.com> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: Richard Hansen Subject: Re: 'emulate sh -c' and $0 Cc: zsh-workers@zsh.org MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On May 30, 5:14pm, Richard Hansen wrote: } } Would it add too much complexity to the code or documentation if the } emulate builtin did more than just toggle options (specifically: } temporarily change the binding of $0 to the original value)? No, probably not. We could certainly get away with making the change to $0 be an additional effect of the (relatively new) -c option, i.e., emulate sh changes only the options, but emulate sh -c 'some command' changes both options and $0 in the scope of 'some command'. In fact I like that idea a lot, now that I've written it down ... but it'd be a bit complicated to add that to "sticky emulation" so a simpler plan is probably better. } > The use cases in both directions seem pretty unusual to me. Losing the } > ability to "localize" $0 for scripts feels almost as likely to create } > questions as does your situation. } } I'm not sure what you mean by losing the ability to localize $0. You gave two examples in your original message on this thread: the current behavior and the behavior you expected. Someone else might be expecting the current behavior, and I don't see any clear criteria for deciding which one is "best." If we make any of the suggested changes here, the current behavior is lost. } I see a few OK options: } } * Option #1: } 3. When 'emulate sh' starts, temporarily set argzero to } orig_argzero. Restore argzero when 'emulate sh' returns. } } * Option #2: } 3. Add a new option; let's call it LOCALIZE_ARGZERO for now. If } LOCALIZE_ARGZERO is enabled, use argzero to expand $0. If } LOCALIZE_ARGZERO is disabled, use orig_argzero to expand $0. } 4. Enable LOCALIZE_ARGZERO by default, but disable it in sh } emulation mode. } 5. Stop disabling FUNCTION_ARGZERO by default in sh emulation mode. } } * Option #3: } 3. Modify the expansion rules for $0 as follows: If } FUNCTION_ARGZERO is enabled, use argzero to expand $0. If } FUNCTION_ARGZERO is disabled, use orig_argzero to expand $0. I was initially leaning toward #3, because #1 takes away the current behavior and because I'd rather not add yet another option as in #2 ... but then I had a different idea ... It seems to me that the ideal situation would be that emulate sh works exactly as it does now ("With SINGLE ARGUMENT set up zsh options" says the doc, emphasis mine) but that emulate sh -c 'some command' alters the behavior of $0 as well. The advantage of this is that the -c option to emulate is relatively new; any scripts relying on the current $0 behavior are likely old and won't use -c. The drawback to this is "sticky emulation" for functions, which is based entirely on option settings; but that can be made to work if we add an option. Hence: If we leave FUNCTION_ARGZERO as it is (that is, off by default for sh emulation) and add an option POSIX_ARGZERO which exposes the global argzero when set (inverting your Option #2) but which is never on by default, then bin_emulate can set POSIX_ARGZERO in the -c scope when emulating sh/ksh, and it will be sticky for functions defined there. We wouldn't even have to build those smarts into bin_emulate; a user who wanted the POSIX semantics could explicitly do emulate sh -o POSIX_ARGZERO -c '...' The only "magic" necessary is that POSIX_ARGZERO exposes the original value of $0 in spite of the current FUNCTION_ARGZERO setting. Here are the bits outside bin_emulate, and not yet with doc. I suppose there may be some places where posixzero needs to be saved / changed / restored, which this hasn't covered. diff --git a/Src/init.c b/Src/init.c index fd12412..5e92f59 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 ce73d99..e83dc58 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 7901029..0699ead 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 5fbff57..620883b 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2151,6 +2151,7 @@ enum { PATHSCRIPT, PIPEFAIL, POSIXALIASES, + POSIXARGZERO, POSIXBUILTINS, POSIXCD, POSIXIDENTIFIERS,