* emulate with options other than -c is broken @ 2012-10-05 23:01 Peter Stephenson 2012-10-07 19:26 ` Peter Stephenson 0 siblings, 1 reply; 4+ messages in thread From: Peter Stephenson @ 2012-10-05 23:01 UTC (permalink / raw) To: Zsh Hackers' List 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). This is because of the position where the emulation takes effect within the emulate builtin. Also, I'm not happy that parse errors in the option parsing are handled properly. Work for tomorrow. -- Peter Stephenson <p.w.stephenson@ntlworld.com> Web page now at http://homepage.ntlworld.com/p.w.stephenson/ ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: emulate with options other than -c is broken 2012-10-05 23:01 emulate with options other than -c is broken Peter Stephenson @ 2012-10-07 19:26 ` Peter Stephenson 2012-10-11 19:53 ` Peter Stephenson 0 siblings, 1 reply; 4+ messages in thread From: Peter Stephenson @ 2012-10-07 19:26 UTC (permalink / raw) To: Zsh Hackers' List On Sat, 6 Oct 2012 00:01:25 +0100 Peter Stephenson <p.w.stephenson@ntlworld.com> 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 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: emulate with options other than -c is broken 2012-10-07 19:26 ` Peter Stephenson @ 2012-10-11 19:53 ` Peter Stephenson 2012-10-13 4:01 ` Bart Schaefer 0 siblings, 1 reply; 4+ messages in thread From: Peter Stephenson @ 2012-10-11 19:53 UTC (permalink / raw) To: Zsh Hackers' List On Sun, 7 Oct 2012 20:26:06 +0100 Peter Stephenson <p.w.stephenson@ntlworld.com> 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@ntlworld.com> Web page now at http://homepage.ntlworld.com/p.w.stephenson/ ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: emulate with options other than -c is broken 2012-10-11 19:53 ` Peter Stephenson @ 2012-10-13 4:01 ` Bart Schaefer 0 siblings, 0 replies; 4+ messages in thread From: Bart Schaefer @ 2012-10-13 4:01 UTC (permalink / raw) To: Zsh Hackers' List On Oct 11, 8:53pm, Peter Stephenson wrote: } Subject: Re: emulate with options other than -c is broken } } 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 Hmm. The difficulty I see with this is that compinit is used to load widget functions (#compdef -k / -K) and other helpers (#autoload) for which the set of $_comp_options do not necessarily apply. Futhermore, I know I use #autoload in files that don't necessarily have anything to do with completion, just because I know compinit will pick them up for me. Pulling those setopts out of $_comp_setup into an emulate wrapper around the autoload call in compinit (if that is indeed what you contemplate here) would apply them too broadly. So we'd probably need another #compdef switch to activate emulation mode, and then go through all the completion functions to determine which ones should have it. } (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) I wonder if "the same" is the best comparison to make here. As an example, if I write emulate zsh -c 'doglob() { print * }' it may not be my intention to prevent the extendedglob option from being "passed down" from a calling context. On the other hand emulate zsh -o no_extendedglob -c '...' clearly means extendedglob should be forced off. This would mean that the behavior of non-sticky functions follows naturally -- when the set of options turned on/off is empty, any/all options are "inherited". However, that would mean storing not just the state of the options, but the sense of how they arrived at that state, which is a lot of overhead. And I guess the caller could sneak extendedglob through by doing emulate zsh -c 'setopt extendedglob; doglob' because then the sticky bits are the same but I've changed extendedglob after the fact. } 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 Hmm, maybe. The function behavior would be guaranteed as long as you didn't autoload those functions before compinit had a chance to do so. But I suspect a lot of people autoload everything in $fpath, and that at least some of them do so before calling compinit, particulary the people who zcompile their entire function set. So we'd still need to perform all those setopts in _main_complete et al. } (remember what got me into this was the fact that forcing _path_files } to autoload outside the completion system gave an error). Another potentially interesting question: How should/does this interact with zcompile? For example the -U (noaliases) option is recorded in the ZWC file, why shouldn't other option state be compilable, too? ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-10-13 4:02 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-10-05 23:01 emulate with options other than -c is broken Peter Stephenson 2012-10-07 19:26 ` Peter Stephenson 2012-10-11 19:53 ` Peter Stephenson 2012-10-13 4:01 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).