From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27726 invoked by alias); 7 Oct 2012 19:26:20 -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: 30722 Received: (qmail 18008 invoked from network); 7 Oct 2012 19:26:16 -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.82.171 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=wqJ3jKTjftguOvoaaLeXvatxDLrzk3nQDsShzF22DEU=; b=j8qxRxua/1VGbRWpVPnDa68uv6P2VjxQ270TdeNCVZ1pyi+i/KPMUrg5uA0n51NU6I 0q/+lfFYRjLQ4W7BNlXiuLuovktnv8D3B4Pko+fYaGTWttFeYSvGUN5Lf0+LPmYBaHhC IZuJCkOD2g0/I7FvYxK6M9eAL3tr/gg/uWh/rhaozUxTNogcg/2pm0fx2FZiUhyaS07x TqeelAQY7gWeeFI7DIndkZXKn5Bqdtn3F28cLRQc0tENEq3qOw97pa1Iog9rDm6yBFOj cwd6/UVBOXNOWz2IsCklifeBirbHprSw8mNVHVqLnWyd3jIA+5qTYYiZkwwv8X4wMpdK 3uLw== X-ProxyUser-IP: 82.8.55.192 Date: Sun, 7 Oct 2012 20:26:06 +0100 From: Peter Stephenson To: Zsh Hackers' List Subject: Re: emulate with options other than -c is broken Message-ID: <20121007202606.5bdd17bb@pws-pc.ntlworld.com> In-Reply-To: <20121006000125.354e8448@pws-pc.ntlworld.com> References: <20121006000125.354e8448@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: ALoCoQkH19A2GId31LIgjbTkZQ52TJRDUYddL6izHrQ8kSY4bc9XxQj4zGWlvwgDQ30tnGCAoZq7 On Sat, 6 Oct 2012 00:01:25 +0100 Peter Stephenson wrote: > Regardless of the autoload thing, > > emulate zsh -o extendedglob -c '[[ -o extendedglob ]] || > print "extendedglob is NOT set"' > > prints > > extendedglob is NOT set > > (though zsh emulation did take effect) while > > setopt ignorebraces > emulate zsh -o extendedglob > [[ -o ignorebraces ]] && print "ignorebraces IS still set" > > prints > > ignorebraces IS still set > > (though extendedglob did get set). > > Also, I'm not happy that parse errors in the option parsing are > handled properly. This should fix and test all three. 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.) This will mean storing the full set of options with the function definition. I'd propose to do that compactly, i.e. as a bit array rather than a char array (consuming 22 characters, it would seem, which doesn't strike me as excessive --- I can restrict it to when sticky emulation is in effect). Open question: where else would it be sensible to use a bit array rather than a char array for options? In doshfunc we save "char saveopts[OPT_SIZE]" (OPT_SIZE appears to be 170) for every function on the stack, which seems pretty wasteful, but I'm not 100% sure, given the size of memory on modern systems, whether compacting this is worth the extra time taken. (I thought of always maintaining both the non-compact and compact forms, since the compact form is 8 times smaller; then we only need to loop over all options when we restore from a compact copy, not when we save which can just copy the current compact form. I think this is workable but it might be more than we really need.) Index: Src/builtin.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v retrieving revision 1.264 diff -p -u -r1.264 builtin.c --- Src/builtin.c 7 Oct 2012 17:50:19 -0000 1.264 +++ Src/builtin.c 7 Oct 2012 19:04:12 -0000 @@ -548,8 +548,8 @@ bin_set(char *nam, char **args, UNUSED(O /* Obsolescent sh compatibility: set - is the same as set +xv * * and set - args is the same as set +xv -- args */ if (!EMULATION(EMULATE_ZSH) && *args && **args == '-' && !args[0][1]) { - dosetopt(VERBOSE, 0, 0); - dosetopt(XTRACE, 0, 0); + dosetopt(VERBOSE, 0, 0, opts); + dosetopt(XTRACE, 0, 0, opts); if (!args[1]) return 0; } @@ -580,7 +580,7 @@ bin_set(char *nam, char **args, UNUSED(O } if(!(optno = optlookup(*args))) zerrnam(nam, "no such option: %s", *args); - else if(dosetopt(optno, action, 0)) + else if(dosetopt(optno, action, 0, opts)) zerrnam(nam, "can't change option: %s", *args); break; } else if(**args == 'A') { @@ -601,7 +601,7 @@ bin_set(char *nam, char **args, UNUSED(O else { if (!(optno = optlookupc(**args))) zerrnam(nam, "bad option: -%c", **args); - else if(dosetopt(optno, action, 0)) + else if(dosetopt(optno, action, 0, opts)) zerrnam(nam, "can't change option: -%c", **args); } } @@ -5008,8 +5008,8 @@ 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 ret = 1; - char saveopts[OPT_SIZE]; + int ret = 1, new_emulation; + char saveopts[OPT_SIZE], new_opts[OPT_SIZE], savesticky_opts[OPT_SIZE]; char *cmd = 0; const char *shname = *argv; @@ -5044,7 +5044,7 @@ bin_emulate(UNUSED(char *nam), char **ar /* with single argument set current emulation */ if (!argv[1]) { - emulate(shname, OPT_ISSET(ops,'R')); + emulate(shname, OPT_ISSET(ops,'R'), &emulation, opts); if (OPT_ISSET(ops,'L')) opts[LOCALOPTIONS] = opts[LOCALTRAPS] = 1; return 0; @@ -5052,8 +5052,13 @@ bin_emulate(UNUSED(char *nam), char **ar argv++; memcpy(saveopts, opts, sizeof(opts)); + memcpy(new_opts, opts, sizeof(opts)); savehackchar = keyboardhackchar; - cmd = parseopts("emulate", &argv); + emulate(shname, OPT_ISSET(ops,'R'), &new_emulation, new_opts); + if (parseopts("emulate", &argv, new_opts, &cmd)) { + ret = 1; + goto restore; + } /* parseopts() has consumed anything that looks like an option */ if (*argv) { @@ -5061,6 +5066,9 @@ bin_emulate(UNUSED(char *nam), char **ar goto restore; } + saveemulation = emulation; + emulation = new_emulation; + memcpy(opts, new_opts, sizeof(opts)); /* If "-c command" is given, evaluate command using specified * emulation mode. */ @@ -5073,15 +5081,16 @@ bin_emulate(UNUSED(char *nam), char **ar } else return 0; - saveemulation = emulation; savesticky_emulation = sticky_emulation; - emulate(shname, OPT_ISSET(ops,'R')); sticky_emulation = emulation; + memcpy(savesticky_opts, sticky_opts, sizeof(opts)); + memcpy(sticky_opts, opts, sizeof(opts)); ret = eval(argv); sticky_emulation = savesticky_emulation; emulation = saveemulation; - restore: memcpy(opts, saveopts, sizeof(opts)); + memcpy(sticky_opts, savesticky_opts, sizeof(opts)); +restore: keyboardhackchar = savehackchar; inittyptab(); /* restore banghist */ return ret; Index: Src/exec.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/exec.c,v retrieving revision 1.211 diff -p -u -r1.211 exec.c --- Src/exec.c 21 Aug 2012 18:03:03 -0000 1.211 +++ Src/exec.c 7 Oct 2012 19:04:12 -0000 @@ -4544,7 +4544,7 @@ doshfunc(Shfunc shfunc, LinkList dosharg */ emulation = sticky_emulation = shfunc->emulation; restore_sticky = 1; - installemulation(); + installemulation(emulation, opts); } else restore_sticky = 0; Index: Src/init.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/init.c,v retrieving revision 1.125 diff -p -u -r1.125 init.c --- Src/init.c 5 Oct 2012 21:35:06 -0000 1.125 +++ Src/init.c 7 Oct 2012 19:04:12 -0000 @@ -246,7 +246,8 @@ parseargs(char **argv, char **runscript) opts[SHINSTDIN] = 0; opts[SINGLECOMMAND] = 0; - cmd = parseopts(NULL, &argv); + if (parseopts(NULL, &argv, opts, &cmd)) + exit(1); paramlist = znewlinklist(); if (*argv) { @@ -276,18 +277,36 @@ parseargs(char **argv, char **runscript) argzero = ztrdup(argzero); } +/* + * Parse shell options. + * If nam is not NULL, this is called from a command; don't + * exit on failure. + */ + /**/ -mod_export char * -parseopts(char *nam, char ***argvp) +mod_export int +parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp) { int optionbreak = 0; int action, optno; - char *cmd = 0; /* deliberately hides static */ char **argv = *argvp; -#define WARN_OPTION(F, S) if (nam) zwarnnam(nam, F, S); else zerr(F, S) -#define LAST_OPTION(N) \ - if (nam) { if (*argv) argv++; goto doneargv; } else exit(N) + *cmdp = 0; +#define WARN_OPTION(F, S) \ + do { \ + if (nam) \ + zwarnnam(nam, F, S); \ + else \ + zerr(F, S); \ + } while (0) +#define LAST_OPTION(N) \ + do { \ + if (nam) { \ + if (*argv) \ + argv++; \ + goto doneargv; \ + } else exit(N); \ + } while(0) /* loop through command line options (begins with "-" or "+") */ while (!optionbreak && *argv && (**argv == '-' || **argv == '+')) { @@ -327,25 +346,25 @@ parseopts(char *nam, char ***argvp) optionbreak = 1; } else if (**argv == 'c') { /* -c command */ - cmd = *argv; - opts[INTERACTIVE] &= 1; + *cmdp = *argv; + new_opts[INTERACTIVE] &= 1; scriptname = scriptfilename = ztrdup("zsh"); } else if (**argv == 'o') { if (!*++*argv) argv++; if (!*argv) { WARN_OPTION("string expected after -o", NULL); - LAST_OPTION(1); + return 1; } longoptions: if (!(optno = optlookup(*argv))) { WARN_OPTION("no such option: %s", *argv); - LAST_OPTION(1); + return 1; } else if (optno == RESTRICTED && !nam) { restricted = action; } else if ((optno == EMACSMODE || optno == VIMODE) && nam) { WARN_OPTION("can't change option: %s", *argv); - } else if (dosetopt(optno, action, !nam) && nam) { + } else if (dosetopt(optno, action, !nam, new_opts) && nam) { WARN_OPTION("can't change option: %s", *argv); } break; @@ -355,18 +374,18 @@ parseopts(char *nam, char ***argvp) if (!isspace(STOUC(**argv))) { badoptionstring: WARN_OPTION("bad option string: '%s'", args); - LAST_OPTION(1); + return 1; } break; } else { if (!(optno = optlookupc(**argv))) { WARN_OPTION("bad option: -%c", **argv); - LAST_OPTION(1); + return 1; } else if (optno == RESTRICTED && !nam) { restricted = action; } else if ((optno == EMACSMODE || optno == VIMODE) && nam) { WARN_OPTION("can't change option: %s", *argv); - } else if (dosetopt(optno, action, !nam) && nam) { + } else if (dosetopt(optno, action, !nam, new_opts) && nam) { WARN_OPTION("can't change option: -%c", **argv); } } @@ -374,18 +393,18 @@ parseopts(char *nam, char ***argvp) argv++; } doneoptions: - if (cmd) { + if (*cmdp) { if (!*argv) { - WARN_OPTION("string expected after -%s", cmd); - LAST_OPTION(1); + WARN_OPTION("string expected after -%s", *cmdp); + exit(1); } - cmd = *argv++; + *cmdp = *argv++; } doneargv: *argvp = argv; - return cmd; + return 0; } - + /**/ static void printhelp(void) @@ -1162,7 +1181,7 @@ init_misc(void) #else if (*zsh_name == 'r' || restricted) #endif - dosetopt(RESTRICTED, 1, 0); + dosetopt(RESTRICTED, 1, 0, opts); if (cmd) { if (SHIN >= 10) fclose(bshin); @@ -1225,7 +1244,7 @@ source(char *s) subsh = 0; lineno = 1; loops = 0; - dosetopt(SHINSTDIN, 0, 1); + dosetopt(SHINSTDIN, 0, 1, opts); scriptname = s; scriptfilename = s; @@ -1297,7 +1316,7 @@ source(char *s) thisjob = cj; /* current job number */ lineno = oldlineno; /* our current lineno */ loops = oloops; /* the # of nested loops we are in */ - dosetopt(SHINSTDIN, oldshst, 1); /* SHINSTDIN option */ + dosetopt(SHINSTDIN, oldshst, 1, opts); /* SHINSTDIN option */ errflag = 0; if (!exit_pending) retflag = 0; @@ -1535,7 +1554,7 @@ zsh_main(UNUSED(int argc), char **argv) fdtable = zshcalloc(fdtable_size*sizeof(*fdtable)); createoptiontable(); - emulate(zsh_name, 1); /* initialises most options */ + emulate(zsh_name, 1, &emulation, opts); /* initialises most options */ opts[LOGINSHELL] = (**argv == '-'); opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid()); opts[USEZLE] = 1; /* may be unset in init_io() */ Index: Src/options.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/options.c,v retrieving revision 1.63 diff -p -u -r1.63 options.c --- Src/options.c 5 Oct 2012 21:43:00 -0000 1.63 +++ Src/options.c 7 Oct 2012 19:04:12 -0000 @@ -44,6 +44,14 @@ mod_export int sticky_emulation; /**/ 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 */ @@ -70,7 +78,7 @@ mod_export HashTable optiontab; /* option is an alias to an other option */ #define OPT_ALIAS (EMULATE_UNUSED<<2) -#define defset(X) (!!((X)->node.flags & emulation)) +#define defset(X, my_emulation) (!!((X)->node.flags & my_emulation)) /* * Note that option names should usually be fewer than 20 characters long @@ -439,11 +447,11 @@ printoptionnode(HashNode hn, int set) if (optno < 0) optno = -optno; if (isset(KSHOPTIONPRINT)) { - if (defset(on)) + if (defset(on, emulation)) printf("no%-19s %s\n", on->node.nam, isset(optno) ? "off" : "on"); else printf("%-21s %s\n", on->node.nam, isset(optno) ? "on" : "off"); - } else if (set == (isset(optno) ^ defset(on))) { + } else if (set == (isset(optno) ^ defset(on, emulation))) { if (set ^ isset(optno)) fputs("no", stdout); puts(on->node.nam); @@ -475,6 +483,15 @@ createoptiontable(void) optiontab->addnode(optiontab, on->node.nam, on); } +/* Emulation appropriate to the setemulate function */ + +static int setemulate_emulation; + +/* Option array manipulated within the setemulate function */ + +/**/ +static char *setemulate_opts; + /* Setting of default options */ /**/ @@ -490,20 +507,22 @@ setemulate(HashNode hn, int fully) if (!(on->node.flags & OPT_ALIAS) && ((fully && !(on->node.flags & OPT_SPECIAL)) || (on->node.flags & OPT_EMULATE))) - opts[on->optno] = defset(on); + setemulate_opts[on->optno] = defset(on, setemulate_emulation); } /**/ void -installemulation(void) +installemulation(int new_emulation, char *new_opts) { + setemulate_emulation = new_emulation; + setemulate_opts = new_opts; scanhashtable(optiontab, 0, 0, 0, setemulate, - !!(emulation & EMULATE_FULLY)); + !!(new_emulation & EMULATE_FULLY)); } /**/ void -emulate(const char *zsh_name, int fully) +emulate(const char *zsh_name, int fully, int *new_emulation, char *new_opts) { char ch = *zsh_name; @@ -512,17 +531,17 @@ emulate(const char *zsh_name, int fully) /* Work out the new emulation mode */ if (ch == 'c') - emulation = EMULATE_CSH; + *new_emulation = EMULATE_CSH; else if (ch == 'k') - emulation = EMULATE_KSH; + *new_emulation = EMULATE_KSH; else if (ch == 's' || ch == 'b') - emulation = EMULATE_SH; + *new_emulation = EMULATE_SH; else - emulation = EMULATE_ZSH; + *new_emulation = EMULATE_ZSH; if (fully) - emulation |= EMULATE_FULLY; - installemulation(); + *new_emulation |= EMULATE_FULLY; + installemulation(*new_emulation, new_opts); if (funcstack && funcstack->tp == FS_FUNC) { /* @@ -534,7 +553,7 @@ emulate(const char *zsh_name, int fully) Shfunc shf = (Shfunc)shfunctab->getnode(shfunctab, funcstack->name); if (shf && (shf->node.flags & (PM_TAGGED|PM_TAGGED_LOCAL))) { /* Tracing is on, so set xtrace */ - opts[XTRACE] = 1; + new_opts[XTRACE] = 1; } } } @@ -545,7 +564,7 @@ emulate(const char *zsh_name, int fully) static void setoption(HashNode hn, int value) { - dosetopt(((Optname) hn)->optno, value, 0); + dosetopt(((Optname) hn)->optno, value, 0, opts); } /**/ @@ -582,7 +601,7 @@ bin_setopt(char *nam, char **args, UNUSE } if(!(optno = optlookup(*args))) zwarnnam(nam, "no such option: %s", *args); - else if(dosetopt(optno, action, 0)) + else if(dosetopt(optno, action, 0, opts)) zwarnnam(nam, "can't change option: %s", *args); break; } else if(**args == 'm') { @@ -590,7 +609,7 @@ bin_setopt(char *nam, char **args, UNUSE } else { if (!(optno = optlookupc(**args))) zwarnnam(nam, "bad option: -%c", **args); - else if(dosetopt(optno, action, 0)) + else if(dosetopt(optno, action, 0, opts)) zwarnnam(nam, "can't change option: -%c", **args); } } @@ -603,7 +622,7 @@ bin_setopt(char *nam, char **args, UNUSE while (*args) { if(!(optno = optlookup(*args++))) zwarnnam(nam, "no such option: %s", args[-1]); - else if(dosetopt(optno, !isun, 0)) + else if(dosetopt(optno, !isun, 0, opts)) zwarnnam(nam, "can't change option: %s", args[-1]); } } else { @@ -713,7 +732,7 @@ static char *rparams[] = { /**/ mod_export int -dosetopt(int optno, int value, int force) +dosetopt(int optno, int value, int force, char *new_opts) { if(!optno) return -1; @@ -735,7 +754,7 @@ dosetopt(int optno, int value, int force return -1; } else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN || optno == SINGLECOMMAND)) { - if (opts[optno] == value) + if (new_opts[optno] == value) return 0; /* it is not permitted to change the value of these options */ return -1; @@ -751,7 +770,7 @@ dosetopt(int optno, int value, int force #endif /* HAVE_SETUID */ #ifdef JOB_CONTROL } else if (!force && optno == MONITOR && value) { - if (opts[optno] == value) + if (new_opts[optno] == value) return 0; if (SHTTY != -1) { origpgrp = GETPGRP(); @@ -770,12 +789,12 @@ dosetopt(int optno, int value, int force if (sticky_emulation) return -1; zleentry(ZLE_CMD_SET_KEYMAP, optno); - opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0; + new_opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0; } else if (optno == SUNKEYBOARDHACK) { /* for backward compatibility */ keyboardhackchar = (value ? '`' : '\0'); } - opts[optno] = value; + new_opts[optno] = value; if (optno == BANGHIST || optno == SHINSTDIN) inittyptab(); return 0; @@ -817,10 +836,11 @@ printoptionnodestate(HashNode hn, int ha int optno = on->optno; if (hadplus) { - if (defset(on) != isset(optno)) - printf("set -o %s%s\n", defset(on) ? "no" : "", on->node.nam); + if (defset(on, emulation) != isset(optno)) + printf("set -o %s%s\n", defset(on, emulation) ? + "no" : "", on->node.nam); } else { - if (defset(on)) + if (defset(on, emulation)) printf("no%-19s %s\n", on->node.nam, isset(optno) ? "off" : "on"); else printf("%-21s %s\n", on->node.nam, isset(optno) ? "on" : "off"); Index: Src/Modules/parameter.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Modules/parameter.c,v retrieving revision 1.54 diff -p -u -r1.54 parameter.c --- Src/Modules/parameter.c 5 Mar 2012 10:06:29 -0000 1.54 +++ Src/Modules/parameter.c 7 Oct 2012 19:04:12 -0000 @@ -771,7 +771,7 @@ setpmoption(Param pm, char *value) zwarn("invalid value: %s", value); else if (!(n = optlookup(pm->node.nam))) zwarn("no such option: %s", pm->node.nam); - else if (dosetopt(n, (value && strcmp(value, "off")), 0)) + else if (dosetopt(n, (value && strcmp(value, "off")), 0, opts)) zwarn("can't change option: %s", pm->node.nam); zsfree(value); } @@ -784,7 +784,7 @@ unsetpmoption(Param pm, UNUSED(int exp)) if (!(n = optlookup(pm->node.nam))) zwarn("no such option: %s", pm->node.nam); - else if (dosetopt(n, 0, 0)) + else if (dosetopt(n, 0, 0, opts)) zwarn("can't change option: %s", pm->node.nam); } @@ -812,7 +812,7 @@ setpmoptions(UNUSED(Param pm), HashTable if (!val || (strcmp(val, "on") && strcmp(val, "off"))) zwarn("invalid value: %s", val); else if (dosetopt(optlookup(hn->nam), - (val && strcmp(val, "off")), 0)) + (val && strcmp(val, "off")), 0, opts)) zwarn("can't change option: %s", hn->nam); } deleteparamtable(ht); Index: Test/B07emulate.ztst =================================================================== RCS file: /cvsroot/zsh/zsh/Test/B07emulate.ztst,v retrieving revision 1.2 diff -p -u -r1.2 B07emulate.ztst --- Test/B07emulate.ztst 11 Feb 2009 20:42:17 -0000 1.2 +++ Test/B07emulate.ztst 7 Oct 2012 19:04:12 -0000 @@ -176,3 +176,28 @@ 0:Sticky emulation not triggered if sticky emulation unchanged >on >off + + ( + setopt ignorebraces + emulate zsh -o extendedglob -c ' + [[ -o ignorebraces ]] || print "Yay, ignorebraces was reset" + [[ -o extendedglob ]] && print "Yay, extendedglob is set" + ' + ) +0:emulate -c with options +>Yay, ignorebraces was reset +>Yay, extendedglob is set + + ( + setopt ignorebraces + emulate zsh -o extendedglob + [[ -o ignorebraces ]] || print "Yay, ignorebraces is no longer set" + [[ -o extendedglob ]] && print "Yay, extendedglob is set" + ) +0:emulate with options but no -c +>Yay, ignorebraces is no longer set +>Yay, extendedglob is set + + emulate zsh -o fixallmybugs 'print This was executed, bad' +1:emulate -c with incorrect options +?(eval):emulate:1: no such option: fixallmybugs