zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: PATCH: emulate -l to list options that would change
Date: Sat, 31 Oct 2015 20:40:36 +0000	[thread overview]
Message-ID: <20151031204036.77fbfee4@ntlworld.com> (raw)

For a long time I've felt a bit unclean about the fact that the easiest
way to find out what changes in an emulation is to look at the source.
It's there in the documentation, but not in an easily queriable way (and
certainly not an automatable one).

This fixes it so that "emulate -l [-LR] <mode>" tells you what options would
change if you executed "emulate [-LR] <mode>".  This is incompatible with
additional options (including a -c argument).

Arguably "emulate -l" should be an error, but it seems natural enough it does
the same as "emulate".

diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 85d1742..d13c7b4 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 8045bc8..0be20a5 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 3bf9f39..2678626 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);
+}


             reply	other threads:[~2015-10-31 20:46 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-31 20:40 Peter Stephenson [this message]
2015-11-01  0:03 ` Bart Schaefer
2015-11-01 18:15   ` Peter Stephenson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20151031204036.77fbfee4@ntlworld.com \
    --to=p.w.stephenson@ntlworld.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).