From 4e2cdd795677e655f89b76b57611a196ce578432 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 7 Oct 2012 19:46:46 +0000 Subject: 30722: fix some cases where emulations or options were not propagated properly from the emulate command --- Src/options.c | 72 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 26 deletions(-) (limited to 'Src/options.c') diff --git a/Src/options.c b/Src/options.c index 6075a7fcb..87e9abe2d 100644 --- a/Src/options.c +++ b/Src/options.c @@ -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, UNUSED(Options ops), int isun) } 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, UNUSED(Options ops), int isun) } 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, UNUSED(Options ops), int isun) 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 hadplus) 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"); -- cgit 1.4.1