From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3977 invoked by alias); 11 Oct 2012 19:54:09 -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: 30726 Received: (qmail 26771 invoked from network); 11 Oct 2012 19:53:54 -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=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 Received-SPF: neutral (ns1.primenet.com.au: 74.125.83.43 is neither permitted nor denied by SPF record at ntlworld.com) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-proxyuser-ip:date:from:to:subject:message-id:in-reply-to :references:x-mailer:mime-version:content-type :content-transfer-encoding:x-gm-message-state; bh=L6KkvxEReKutI/9A3yP3X3RVCp9sHIYMoYZ90cG2N4Q=; b=V65GohQK0kTU/cuY03ib9D3+/xN/8LWtc3NPZKcltMKUAPA7s/7jXfGVl2yxnenc0o PS31vBleJRbXQ98ESuENYI+Szr7+Xn+s2hn6xD/Qdv6+FfYEerwUoxKapfcYEBYQqDLD xdzaude+uiKfRG46D1GBxnbNnXDjvKAbAZkWy1F10DPRo1Jt2BbtRqxWxz4wcEIhHEGy iWdXKW+DUmYEtA5cQQZ+G3N/75zDeiPSJn3Btr/Q4emRVaPih6KF5sOSGhPPNXkizt5y zNSvabSf9lrHDUs++XHnBIQrgMGtsrORuU8cmw816K8HF019q2j6dnUQUumxpV6PVXPw U6uw== X-ProxyUser-IP: 82.8.55.192 Date: Thu, 11 Oct 2012 20:53:38 +0100 From: Peter Stephenson To: Zsh Hackers' List Subject: Re: emulate with options other than -c is broken Message-ID: <20121011205338.02c8d76b@pws-pc.ntlworld.com> In-Reply-To: <20121007202606.5bdd17bb@pws-pc.ntlworld.com> References: <20121006000125.354e8448@pws-pc.ntlworld.com> <20121007202606.5bdd17bb@pws-pc.ntlworld.com> X-Mailer: Claws Mail 3.8.0 (GTK+ 2.24.7; x86_64-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Gm-Message-State: ALoCoQlnBSU+gh7D/pQFU+0eOtOc+AMKaPG+45DCAlCS/VzZf4uSnmWuqi1CcOtFeeL5qGmr7mQf On Sun, 7 Oct 2012 20:26:06 +0100 Peter Stephenson wrote: > There's one thing still only half fixed: > > emulate zsh -o extendedglob -c 'func() { [[ -o extendedglob ]] && > print is on }' > func > > doesn't print "is on" yet. This sure as heck looks like a bug: if you > get to pass options uniformly with the emulation, why would the > emulation but not the options be sticky? (It's half fixed because > I've created and initialised a sticky_opts array but not used it.) I suppose it's not suprising this turned into either a can of worms, or maybe a dog's dinner, or a pig's breakfast. My idea of simply recording all options didn't work: you need to know not just the options that are in effect, but which options need changing. Given that typically you're not going to give that many options in addition to the emulation, it seemed preferable to record only the options that explicitly needed turning off or turning on. The other flea in the dog's wormy breakfast was that in that case, if you want to be able to compare two different emulations with additional options simply, you need to ensure the options are recorded in order. The next question is, do we want to use this for functions autoloaded by the completion system? The argument against is that it changes the behaviour (we'd probably need to enter zsh emulation plus set a few options, rather than just set explicit options --- but note the property that if the emulation is the same we do allow option changes to propagate between functions, as at present), and also we need more memory to store the sticky emulation for every function. The argument in favour is the behaviour is easier to document because it's based on emulations, and the function behaviour is guaranteed wherever it's loaded or called, not just from somewhere under _main_complete (remember what got me into this was the fact that forcing _path_files to autoload outside the completion system gave an error). Index: Doc/Zsh/builtins.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v retrieving revision 1.144 diff -p -u -r1.144 builtins.yo --- Doc/Zsh/builtins.yo 7 Oct 2012 17:50:19 -0000 1.144 +++ Doc/Zsh/builtins.yo 11 Oct 2012 19:43:39 -0000 @@ -462,6 +462,10 @@ sitem(4.)(The presence or absence of the corresponds to different sticky emulation modes, so for example `tt(emulate sh -c)', `tt(emulate -R sh -c)' and `tt(emulate csh -c)' are treated as three distinct sticky emulations.) +sitem(5.)(Difference in shell options supplied in addition to the +basic emulation also mean the sticky emulations are different, so for +example `tt(emulate zsh -c)' and `tt(emulate zsh -o cbases -c)' are +treated as distinct sticky emulations.) endsitem() ) findex(enable) Index: Src/builtin.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v retrieving revision 1.266 diff -p -u -r1.266 builtin.c --- Src/builtin.c 9 Oct 2012 09:24:23 -0000 1.266 +++ Src/builtin.c 11 Oct 2012 19:43:39 -0000 @@ -2944,7 +2944,7 @@ bin_functions(char *name, char **argv, O shf = (Shfunc) zshcalloc(sizeof *shf); shf->node.flags = on; shf->funcdef = mkautofn(shf); - shf->emulation = sticky_emulation; + shfunc_set_sticky(shf); shfunctab->addnode(shfunctab, ztrdup(*argv), shf); if (signum != -1) { @@ -5007,11 +5007,15 @@ bin_emulate(UNUSED(char *nam), char **ar { int opt_L = OPT_ISSET(ops, 'L'); int opt_R = OPT_ISSET(ops, 'R'); - int saveemulation, savesticky_emulation, savehackchar; + int saveemulation, savehackchar; int ret = 1, new_emulation; - char saveopts[OPT_SIZE], new_opts[OPT_SIZE], savesticky_opts[OPT_SIZE]; + char saveopts[OPT_SIZE], new_opts[OPT_SIZE]; char *cmd = 0; const char *shname = *argv; + LinkList optlist; + LinkNode optnode; + Emulation_options save_sticky; + OptIndex *on_ptr, *off_ptr; /* without arguments just print current emulation */ if (!shname) { @@ -5055,7 +5059,8 @@ bin_emulate(UNUSED(char *nam), char **ar memcpy(new_opts, opts, sizeof(opts)); savehackchar = keyboardhackchar; emulate(shname, OPT_ISSET(ops,'R'), &new_emulation, new_opts); - if (parseopts("emulate", &argv, new_opts, &cmd)) { + optlist = newlinklist(); + if (parseopts("emulate", &argv, new_opts, &cmd, optlist)) { ret = 1; goto restore; } @@ -5081,15 +5086,40 @@ bin_emulate(UNUSED(char *nam), char **ar } else return 0; - savesticky_emulation = sticky_emulation; - sticky_emulation = emulation; - memcpy(savesticky_opts, sticky_opts, sizeof(opts)); - memcpy(sticky_opts, opts, sizeof(opts)); + save_sticky = sticky; + sticky = hcalloc(sizeof(*sticky)); + sticky->emulation = emulation; + for (optnode = firstnode(optlist); optnode; incnode(optnode)) { + /* Data is index into new_opts */ + char *optptr = (char *)getdata(optnode); + if (*optptr) + sticky->n_on_opts++; + else + sticky->n_off_opts++; + } + if (sticky->n_on_opts) + on_ptr = sticky->on_opts = + zhalloc(sticky->n_on_opts * sizeof(*sticky->on_opts)); + else + on_ptr = NULL; + if (sticky->n_off_opts) + off_ptr = sticky->off_opts = zhalloc(sticky->n_off_opts * + sizeof(*sticky->off_opts)); + else + off_ptr = NULL; + for (optnode = firstnode(optlist); optnode; incnode(optnode)) { + /* Data is index into new_opts */ + char *optptr = (char *)getdata(optnode); + int optno = optptr - new_opts; + if (*optptr) + *on_ptr++ = optno; + else + *off_ptr++ = optno; + } ret = eval(argv); - sticky_emulation = savesticky_emulation; + sticky = save_sticky; emulation = saveemulation; memcpy(opts, saveopts, sizeof(opts)); - memcpy(sticky_opts, savesticky_opts, sizeof(opts)); restore: keyboardhackchar = savehackchar; inittyptab(); /* restore banghist */ Index: Src/exec.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/exec.c,v retrieving revision 1.213 diff -p -u -r1.213 exec.c --- Src/exec.c 11 Oct 2012 16:36:14 -0000 1.213 +++ Src/exec.c 11 Oct 2012 19:43:39 -0000 @@ -4267,7 +4267,7 @@ execfuncdef(Estate state, UNUSED(int do_ shf->node.flags = 0; shf->filename = ztrdup(scriptfilename); shf->lineno = lineno; - shf->emulation = sticky_emulation; + shfunc_set_sticky(shf); if (!names) { /* @@ -4319,6 +4319,46 @@ execfuncdef(Estate state, UNUSED(int do_ return ret; } +/* Duplicate a sticky emulation */ + +/**/ + +mod_export Emulation_options +sticky_emulation_dup(Emulation_options src, int useheap) +{ + Emulation_options newsticky = useheap ? + hcalloc(sizeof(*src)) : zshcalloc(sizeof(*src)); + newsticky->emulation = src->emulation; + if (src->n_on_opts) { + size_t sz = src->n_on_opts * sizeof(*src->on_opts); + newsticky->n_on_opts = src->n_on_opts; + newsticky->on_opts = useheap ? zhalloc(sz) : zalloc(sz); + memcpy(newsticky->on_opts, src->on_opts, sz); + } + if (src->n_off_opts) { + size_t sz = src->n_off_opts * sizeof(*src->off_opts); + newsticky->n_off_opts = src->n_off_opts; + newsticky->off_opts = useheap ? zhalloc(sz) : zalloc(sz); + memcpy(newsticky->off_opts, src->off_opts, sz); + } + + return newsticky; +} + +/* Set the sticky emulation attributes for a shell function */ + +/**/ + +mod_export void +shfunc_set_sticky(Shfunc shf) +{ + if (sticky) + shf->sticky = sticky_emulation_dup(sticky, 0); + else + shf->sticky = NULL; +} + + /* Main entry point to execute a shell function. */ /**/ @@ -4479,6 +4519,45 @@ loadautofn(Shfunc shf, int fksh, int aut } /* + * Check if a sticky emulation differs from the current one. + */ + +/**/ + +int sticky_emulation_differs(Emulation_options sticky2) +{ + /* If no new sticky emulation, not a different emulation */ + if (!sticky2) + return 0; + /* If no current sticky emulation, different */ + if (!sticky) + return 1; + /* If basic emulation different, different */ + if (sticky->emulation != sticky2->emulation) + return 1; + /* If differing numbers of options, different */ + if (sticky->n_on_opts != sticky2->n_on_opts || + sticky->n_off_opts != sticky2->n_off_opts) + return 1; + /* + * We need to compare option arrays, if non-null. + * We made parseopts() create the list of options in option + * order to make this easy. + */ + /* If different options turned on, different */ + if (sticky->n_on_opts && + memcmp(sticky->on_opts, sticky2->on_opts, + sticky->n_on_opts * sizeof(*sticky->on_opts)) != 0) + return 1; + /* If different options turned on, different */ + if (sticky->n_off_opts && + memcmp(sticky->off_opts, sticky2->off_opts, + sticky->n_off_opts * sizeof(*sticky->off_opts)) != 0) + return 1; + return 0; +} + +/* * execute a shell function * * name is the name of the function @@ -4507,10 +4586,11 @@ doshfunc(Shfunc shfunc, LinkList dosharg char *name = shfunc->node.nam; int flags = shfunc->node.flags, ooflags; char *fname = dupstring(name); - int obreaks, saveemulation, savesticky_emulation, restore_sticky; + int obreaks, saveemulation, restore_sticky; Eprog prog; struct funcstack fstack; static int oflags; + Emulation_options save_sticky = NULL; #ifdef MAX_FUNCTION_DEPTH static int funcdepth; #endif @@ -4548,9 +4628,9 @@ doshfunc(Shfunc shfunc, LinkList dosharg * function we need to restore the original options on exit. */ memcpy(saveopts, opts, sizeof(opts)); saveemulation = emulation; - savesticky_emulation = sticky_emulation; + save_sticky = sticky; - if (shfunc->emulation && sticky_emulation != shfunc->emulation) { + if (sticky_emulation_differs(shfunc->sticky)) { /* * Function is marked for sticky emulation. * Enable it now. @@ -4563,9 +4643,24 @@ doshfunc(Shfunc shfunc, LinkList dosharg * * This propagates the sticky emulation to subfunctions. */ - emulation = sticky_emulation = shfunc->emulation; + sticky = sticky_emulation_dup(shfunc->sticky, 1); + emulation = sticky->emulation; restore_sticky = 1; installemulation(emulation, opts); + if (sticky->n_on_opts) { + OptIndex *onptr; + for (onptr = sticky->on_opts; + onptr < sticky->on_opts + sticky->n_on_opts; + onptr++) + opts[*onptr] = 1; + } + if (sticky->n_off_opts) { + OptIndex *offptr; + for (offptr = sticky->off_opts; + offptr < sticky->off_opts + sticky->n_off_opts; + offptr++) + opts[*offptr] = 0; + } } else restore_sticky = 0; @@ -4674,7 +4769,7 @@ doshfunc(Shfunc shfunc, LinkList dosharg */ memcpy(opts, saveopts, sizeof(opts)); emulation = saveemulation; - sticky_emulation = savesticky_emulation; + sticky = save_sticky; } else if (isset(LOCALOPTIONS)) { /* restore all shell options except PRIVILEGED and RESTRICTED */ saveopts[PRIVILEGED] = opts[PRIVILEGED]; Index: Src/hashtable.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/hashtable.c,v retrieving revision 1.37 diff -p -u -r1.37 hashtable.c --- Src/hashtable.c 21 Aug 2012 18:03:03 -0000 1.37 +++ Src/hashtable.c 11 Oct 2012 19:43:39 -0000 @@ -888,6 +888,15 @@ freeshfuncnode(HashNode hn) if (shf->funcdef) freeeprog(shf->funcdef); zsfree(shf->filename); + if (shf->sticky) { + if (shf->sticky->n_on_opts) + zfree(shf->sticky->on_opts, + shf->sticky->n_on_opts * sizeof(*shf->sticky->on_opts)); + if (shf->sticky->n_off_opts) + zfree(shf->sticky->off_opts, + shf->sticky->n_off_opts * sizeof(*shf->sticky->off_opts)); + zfree(shf->sticky, sizeof(*shf->sticky)); + } zfree(shf, sizeof(struct shfunc)); } Index: Src/init.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/init.c,v retrieving revision 1.126 diff -p -u -r1.126 init.c --- Src/init.c 7 Oct 2012 19:46:46 -0000 1.126 +++ Src/init.c 11 Oct 2012 19:43:39 -0000 @@ -246,7 +246,7 @@ parseargs(char **argv, char **runscript) opts[SHINSTDIN] = 0; opts[SINGLECOMMAND] = 0; - if (parseopts(NULL, &argv, opts, &cmd)) + if (parseopts(NULL, &argv, opts, &cmd, NULL)) exit(1); paramlist = znewlinklist(); @@ -277,15 +277,37 @@ parseargs(char **argv, char **runscript) argzero = ztrdup(argzero); } +/* Insert into list in order of pointer value */ + +/**/ +static void +parseopts_insert(LinkList optlist, void *ptr) +{ + LinkNode node; + + for (node = firstnode(optlist); node; incnode(node)) { + if (ptr < getdata(node)) { + insertlinknode(optlist, prevnode(node), ptr); + return; + } + } + + addlinknode(optlist, ptr); +} + /* * Parse shell options. * If nam is not NULL, this is called from a command; don't * exit on failure. + * + * If optlist is not NULL, it used to form a list of pointers + * into new_opts indicating which options have been changed. */ /**/ mod_export int -parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp) +parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp, + LinkList optlist) { int optionbreak = 0; int action, optno; @@ -364,8 +386,12 @@ parseopts(char *nam, char ***argvp, char restricted = action; } else if ((optno == EMACSMODE || optno == VIMODE) && nam) { WARN_OPTION("can't change option: %s", *argv); - } else if (dosetopt(optno, action, !nam, new_opts) && nam) { - WARN_OPTION("can't change option: %s", *argv); + } else { + if (dosetopt(optno, action, !nam, new_opts) && nam) { + WARN_OPTION("can't change option: %s", *argv); + } else if (optlist) { + parseopts_insert(optlist, new_opts+optno); + } } break; } else if (isspace(STOUC(**argv))) { @@ -385,8 +411,12 @@ parseopts(char *nam, char ***argvp, char restricted = action; } else if ((optno == EMACSMODE || optno == VIMODE) && nam) { WARN_OPTION("can't change option: %s", *argv); - } else if (dosetopt(optno, action, !nam, new_opts) && nam) { - WARN_OPTION("can't change option: -%c", **argv); + } else { + if (dosetopt(optno, action, !nam, new_opts) && nam) { + WARN_OPTION("can't change option: -%c", **argv); + } else if (optlist) { + parseopts_insert(optlist, new_opts+optno); + } } } } @@ -396,7 +426,7 @@ parseopts(char *nam, char ***argvp, char if (*cmdp) { if (!*argv) { WARN_OPTION("string expected after -%s", *cmdp); - exit(1); + return 1; } *cmdp = *argv++; } Index: Src/options.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/options.c,v retrieving revision 1.64 diff -p -u -r1.64 options.c --- Src/options.c 7 Oct 2012 19:46:46 -0000 1.64 +++ Src/options.c 11 Oct 2012 19:43:39 -0000 @@ -35,29 +35,21 @@ /**/ mod_export int emulation; -/* current sticky emulation: 0 means none */ +/* current sticky emulation: sticky = NULL means none */ /**/ -mod_export int sticky_emulation; +mod_export Emulation_options sticky; /* the options; e.g. if opts[SHGLOB] != 0, SH_GLOB is turned on */ - + /**/ mod_export char opts[OPT_SIZE]; -/* - * the options that need setting for current sticky emulation, if any: - * same format as opts. - */ - -/**/ -mod_export char sticky_opts[OPT_SIZE]; - /* Option name hash table */ /**/ mod_export HashTable optiontab; - + /* The canonical option name table */ #define OPT_CSH EMULATE_CSH @@ -786,7 +778,7 @@ dosetopt(int optno, int value, int force return -1; #endif /* GETPWNAM_FAKED */ } else if ((optno == EMACSMODE || optno == VIMODE) && value) { - if (sticky_emulation) + if (sticky && sticky->emulation) return -1; zleentry(ZLE_CMD_SET_KEYMAP, optno); new_opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0; Index: Src/parse.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/parse.c,v retrieving revision 1.91 diff -p -u -r1.91 parse.c --- Src/parse.c 5 Oct 2012 21:35:06 -0000 1.91 +++ Src/parse.c 11 Oct 2012 19:43:40 -0000 @@ -3482,7 +3482,7 @@ dump_autoload(char *nam, char *file, int shf = (Shfunc) zshcalloc(sizeof *shf); shf->node.flags = on; shf->funcdef = mkautofn(shf); - shf->emulation = 0; + shf->sticky = NULL; shfunctab->addnode(shfunctab, ztrdup(fdname(n) + fdhtail(n)), shf); if (OPT_ISSET(ops,'X') && eval_autoload(shf, shf->node.nam, ops, func)) ret = 1; Index: Src/signals.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/signals.c,v retrieving revision 1.65 diff -p -u -r1.65 signals.c --- Src/signals.c 25 Sep 2011 18:09:14 -0000 1.65 +++ Src/signals.c 11 Oct 2012 19:43:40 -0000 @@ -755,7 +755,10 @@ dosavetrap(int sig, int level) newshf->node.flags = shf->node.flags; newshf->funcdef = dupeprog(shf->funcdef, 0); newshf->filename = ztrdup(shf->filename); - newshf->emulation = shf->emulation; + if (shf->sticky) { + newshf->sticky = sticky_emulation_dup(shf->sticky, 0); + } else + newshf->sticky = 0; if (shf->node.flags & PM_UNDEFINED) newshf->funcdef->shf = newshf; } Index: Src/zsh.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v retrieving revision 1.185 diff -p -u -r1.185 zsh.h --- Src/zsh.h 5 Oct 2012 21:35:06 -0000 1.185 +++ Src/zsh.h 11 Oct 2012 19:43:41 -0000 @@ -407,6 +407,7 @@ typedef struct cmdnam *Cmdnam; typedef struct complist *Complist; typedef struct conddef *Conddef; typedef struct dirsav *Dirsav; +typedef struct emulation_options *Emulation_options; typedef struct features *Features; typedef struct feature_enables *Feature_enables; typedef struct funcstack *Funcstack; @@ -1099,7 +1100,7 @@ struct shfunc { char *filename; /* Name of file located in */ zlong lineno; /* line number in above file */ Eprog funcdef; /* function definition */ - int emulation; /* sticky emulation for function */ + Emulation_options sticky; /* sticky emulation definitions, if any */ }; /* Shell function context types. */ @@ -2104,6 +2105,12 @@ enum { OPT_SIZE }; +/* + * Size required to fit an option number. + * If OPT_SIZE goes above 256 this will need to expand. + */ +typedef unsigned char OptIndex; + #undef isset #define isset(X) (opts[X]) #define unset(X) (!opts[X]) @@ -2112,6 +2119,27 @@ enum { #define jobbing (isset(MONITOR)) #define islogin (isset(LOGINSHELL)) +/* + * Record of emulation and options that need to be set + * for a full "emulate". + */ +struct emulation_options { + /* The emulation itself */ + int emulation; + /* The number of options in on_opts. */ + int n_on_opts; + /* The number of options in off_opts. */ + int n_off_opts; + /* + * Array of options to be turned on. + * Only options specified explicitly in the emulate command + * are recorded. Null if n_on_opts is zero. + */ + OptIndex *on_opts; + /* Array of options to be turned off, similar. */ + OptIndex *off_opts; +}; + /***********************************************/ /* Definitions for terminal and display control */ /***********************************************/ Index: Src/Modules/parameter.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/parameter.c,v retrieving revision 1.55 diff -p -u -r1.55 parameter.c --- Src/Modules/parameter.c 7 Oct 2012 19:46:46 -0000 1.55 +++ Src/Modules/parameter.c 11 Oct 2012 19:43:41 -0000 @@ -289,7 +289,7 @@ setfunction(char *name, char *val, int d shf = (Shfunc) zshcalloc(sizeof(*shf)); shf->funcdef = dupeprog(prog, 0); shf->node.flags = dis; - shf->emulation = sticky_emulation; + shfunc_set_sticky(shf); if (!strncmp(name, "TRAP", 4) && (sn = getsignum(name + 4)) != -1) { Index: Test/B07emulate.ztst =================================================================== RCS file: /cvsroot/zsh/zsh/Test/B07emulate.ztst,v retrieving revision 1.3 diff -p -u -r1.3 B07emulate.ztst --- Test/B07emulate.ztst 7 Oct 2012 19:46:46 -0000 1.3 +++ Test/B07emulate.ztst 11 Oct 2012 19:43:41 -0000 @@ -201,3 +201,49 @@ emulate zsh -o fixallmybugs 'print This was executed, bad' 1:emulate -c with incorrect options ?(eval):emulate:1: no such option: fixallmybugs + + emulate zsh -c ' + func() { [[ -o extendedglob ]] || print extendedglob is off } + ' + func + emulate zsh -o extendedglob -c ' + func() { [[ -o extendedglob ]] && print extendedglob is on } + ' + func +0:options specified alongside emulation are also sticky +>extendedglob is off +>extendedglob is on + + emulate zsh -o extendedglob -c ' + func_inner() { setopt nobareglobqual } + ' + emulate zsh -o extendedglob -c ' + func_outer() { + func_inner + [[ -o bareglobqual ]] || print bareglobqual was turned off + [[ -o extendedglob ]] && print extendedglob is on, though + } + ' + [[ -o extendedglob ]] || print extendedglob is initially off + func_outer +0:options propagate between identical emulations +>extendedglob is initially off +>bareglobqual was turned off +>extendedglob is on, though + + emulate zsh -o extendedglob -c ' + func_inner() { setopt nobareglobqual } + ' + emulate zsh -o extendedglob -o cbases -c ' + func_outer() { + func_inner + [[ -o bareglobqual ]] && print bareglobqual is still on + [[ -o extendedglob ]] && print extendedglob is on, too + } + ' + [[ -o extendedglob ]] || print extendedglob is initially off + func_outer +0:options do not propagate between different emulations +>extendedglob is initially off +>bareglobqual is still on +>extendedglob is on, too -- Peter Stephenson Web page now at http://homepage.ntlworld.com/p.w.stephenson/