Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: emulate with options other than -c is broken



On Sun, 7 Oct 2012 20:26:06 +0100
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx> 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 <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author