summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2015-11-01 18:12:40 +0000
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2015-11-01 18:12:40 +0000
commitba36967b575ca57ebde3349e62c190ca69b73832 (patch)
treebb1d3f998cd6a6e4f7d72aabd028fd4435c26772
parentfa59375e36e1718e060048ba7efd7346b3c8e94a (diff)
downloadzsh-ba36967b575ca57ebde3349e62c190ca69b73832.tar.gz
zsh-ba36967b575ca57ebde3349e62c190ca69b73832.tar.xz
zsh-ba36967b575ca57ebde3349e62c190ca69b73832.zip
37038: add -l option to emulate to list options in emulations
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/builtins.yo10
-rw-r--r--Src/builtin.c33
-rw-r--r--Src/options.c30
4 files changed, 69 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 20d848320..13f262bea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-11-01  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 37038: Doc/Zsh/builtins.yo, Src/builtin.c, Src/options.c: add
+	-l option to emulate.
+
 2015-10-31  Oliver Kiddle  <opk@zsh.org>
 
 	* 37029: Completion/Unix/Command/_date,
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 85d1742f0..985e7267f 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -477,7 +477,7 @@ cindex(compatibility, csh)
 cindex(sh, compatibility)
 cindex(ksh, compatibility)
 cindex(csh, compatibility)
-item(tt(emulate) [ tt(-LR) ] [ {tt(zsh)|tt(sh)|tt(ksh)|tt(csh)} [ var(flags) ... ] ])(
+item(tt(emulate) [ tt(-lLR) ] [ {tt(zsh)|tt(sh)|tt(ksh)|tt(csh)} [ var(flags) ... ] ])(
 Without any argument print current emulation mode.
 
 With single argument set up zsh options to emulate the specified shell
@@ -518,6 +518,14 @@ function, if any; normally these options are turned off in all emulation
 modes except tt(ksh). The tt(-L) switch is mutually exclusive with the
 use of tt(-c) in var(flags).
 
+If there is a single argument and the tt(-l) switch is given, the
+options that would be set or unset (the latter indicated with the prefix
+`tt(no)') are listed.  tt(-l) can be combined with tt(-L) or tt(-R) and
+the list will be modified in the appropriate way.  Note the list does
+not depend on the current setting of options, i.e. it includes all
+options that may in principle change, not just those that would actually
+change.
+
 The var(flags) may be any of the invocation-time flags described in
 ifnzman(noderef(Invocation))\
 ifzman(the section INVOCATION in zmanref(zsh)),
diff --git a/Src/builtin.c b/Src/builtin.c
index 8045bc8f7..0be20a5d2 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -58,7 +58,7 @@ static struct builtin builtins[] =
     BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL),
     BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
     BUILTIN("echo", BINF_SKIPINVALID, bin_print, 0, -1, BIN_ECHO, "neE", "-"),
-    BUILTIN("emulate", 0, bin_emulate, 0, -1, 0, "LR", NULL),
+    BUILTIN("emulate", 0, bin_emulate, 0, -1, 0, "lLR", NULL),
     BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmprs", NULL),
     BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL),
     BUILTIN("exit", BINF_PSPECIAL, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
@@ -5425,10 +5425,11 @@ eval(char **argv)
 
 /**/
 int
-bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
+bin_emulate(char *nam, char **argv, Options ops, UNUSED(int func))
 {
     int opt_L = OPT_ISSET(ops, 'L');
     int opt_R = OPT_ISSET(ops, 'R');
+    int opt_l = OPT_ISSET(ops, 'l');
     int saveemulation, savehackchar;
     int ret = 1, new_emulation;
     unsigned int savepatterns;
@@ -5443,7 +5444,7 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
     /* without arguments just print current emulation */
     if (!shname) {
 	if (opt_L || opt_R) {
-	    zwarnnam("emulate", "not enough arguments");
+	    zwarnnam(nam, "not enough arguments");
 	    return 1;
 	}
 
@@ -5471,27 +5472,43 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
 
     /* with single argument set current emulation */
     if (!argv[1]) {
-	emulate(shname, opt_R, &emulation, opts);
+	char *cmdopts;
+	if (opt_l) {
+	    cmdopts = (char *)zhalloc(OPT_SIZE);
+	    memcpy(cmdopts, opts, OPT_SIZE);
+	} else
+	    cmdopts = opts;
+	emulate(shname, opt_R, &emulation, cmdopts);
 	if (opt_L)
-	    opts[LOCALOPTIONS] = opts[LOCALTRAPS] = opts[LOCALPATTERNS] = 1;
+	    cmdopts[LOCALOPTIONS] = cmdopts[LOCALTRAPS] =
+		cmdopts[LOCALPATTERNS] = 1;
+	if (opt_l) {
+	    list_emulate_options(cmdopts, opt_R);
+	    return 0;
+	}
 	clearpatterndisables();
 	return 0;
     }
 
+    if (opt_l) {
+	zwarnnam(nam, "too many arguments for -l");
+	return 1;
+    }
+
     argv++;
     memcpy(saveopts, opts, sizeof(opts));
     memcpy(new_opts, opts, sizeof(opts));
     savehackchar = keyboardhackchar;
     emulate(shname, opt_R, &new_emulation, new_opts);
     optlist = newlinklist();
-    if (parseopts("emulate", &argv, new_opts, &cmd, optlist)) {
+    if (parseopts(nam, &argv, new_opts, &cmd, optlist)) {
 	ret = 1;
 	goto restore;
     }
 
     /* parseopts() has consumed anything that looks like an option */
     if (*argv) {
-	zwarnnam("emulate", "unknown argument %s", *argv);
+	zwarnnam(nam, "unknown argument %s", *argv);
 	goto restore;
     }
 
@@ -5510,7 +5527,7 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
      */
     if (cmd) {
 	if (opt_L) {
-	    zwarnnam("emulate", "option -L incompatible with -c");
+	    zwarnnam(nam, "option -L incompatible with -c");
 	    goto restore2;
 	}
 	*--argv = cmd;	/* on stack, never free()d, see execbuiltin() */
diff --git a/Src/options.c b/Src/options.c
index 3bf9f39a4..2678626c7 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -902,3 +902,33 @@ printoptionlist_printequiv(int optno)
     optno *= (isneg ? -1 : 1);
     printf("  equivalent to --%s%s\n", isneg ? "no-" : "", optns[optno-1].node.nam);
 }
+
+/**/
+static char *print_emulate_opts;
+
+/**/
+static void
+print_emulate_option(HashNode hn, int fully)
+{
+    Optname on = (Optname) hn;
+
+    if (!(on->node.flags & OPT_ALIAS) &&
+	((fully && !(on->node.flags & OPT_SPECIAL)) ||
+	 (on->node.flags & OPT_EMULATE)))
+    {
+	if (!print_emulate_opts[on->optno])
+	    fputs("no", stdout);
+	puts(on->node.nam);
+    }
+}
+
+/*
+ * List the settings of options associated with an emulation
+ */
+
+/**/
+void list_emulate_options(char *cmdopts, int fully)
+{
+    print_emulate_opts = cmdopts;
+    scanhashtable(optiontab, 1, 0, 0, print_emulate_option, fully);
+}