On 25 ÑÐÐÐÑÑ 2009 02:11:13 Bart Schaefer wrote:
>
> I'm still undecided on (1) whether "-E" should either require or
> always imply -L, and (2) whether I like "-c" better, as in
>
> emulate sh -c 'source file.sh'
>
> As to (1), in what circumstances would you want to eval a command
> under emulation and then leave the emulation in place? If you were
> going to leave emulation turned on anyway, why wouldn't you write
> it as
>
> emulate sh
> source file.sh
>
> ??
>
I did not want to shut the door. But you are right, implying -L makes both
code and documentation simpler. I do not think requiring it makes sense - -
LE implies that -E is possible, which is not.
I personally would flag -LE as error then for the same reason as well as
do not confuse user who reads manuals. Let -L just always set
LOCAL_OPTIONS.
> (2) is a nit. Mainly it affects whether emulate accepts only one
> argument to be eval'd.
Note that
a) -c cannot be an option. It would be yet another argument. Not a
problem (actually, it even simplifies parsing).
b) this makes impression that
emulate sh -c "some command" arg1 arg2 ...
is valid (it is with shell, is not it?) This could be added later if
someone finds usage case.
Yes, I am more and more inclined to make it "-c ..." ... OK to commit?
Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.114
diff -u -p -r1.114 builtins.yo
--- Doc/Zsh/builtins.yo 18 Dec 2008 09:49:04 -0000 1.114
+++ Doc/Zsh/builtins.yo 25 Jan 2009 08:37:08 -0000
@@ -338,8 +338,11 @@ 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)})(
-Set up zsh options to emulate the specified shell as much as possible.
+item(tt(emulate) [ tt(-LR) ] [ {tt(zsh)|tt(sh)|tt(ksh)|tt(csh)} [ tt(-c)
tt(arg) ] ])(
+Without any argument print current emulation mode.
+
+With single argument set up zsh options to emulate the specified shell
+as much as possible.
bf(csh) will never be fully emulated.
If the argument is not one of the shells listed above, tt(zsh)
will be used as a default; more precisely, the tests performed on the
@@ -351,16 +354,21 @@ the section `Compatibility' in zmanref(z
ifnzman(\
noderef(Compatibility)
)\
-. If the tt(-R) option is given, all options
+.
+
+If tt(-c) tt(arg) is given, evaluate tt(arg) after temporary setting
+requested emulation. Emulation will be restored before tt(emulate) returns.
+
+If the tt(-R) option is given, all options
are reset to their default value corresponding to the specified emulation
mode, except for certain options describing the interactive
environment; otherwise, only those options likely to cause portability
-problems in scripts and functions are altered. If the tt(-L) option
-is given, the options tt(LOCAL_OPTIONS) and tt(LOCAL_TRAPS) will be set as
+problems in scripts and functions are altered. If the tt(-L) option is
given,
+the options tt(LOCAL_OPTIONS) and tt(LOCAL_TRAPS) will be set as
well, causing the effects of the tt(emulate) command and any tt(setopt) and
tt(trap) commands to be local to the immediately surrounding shell
function, if any; normally these options are turned off in all emulation
-modes except tt(ksh).
+modes except tt(ksh). The tt(-L) and tt(-c) are mutually exclusive.
)
findex(enable)
cindex(enabling commands)
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.218
diff -u -p -r1.218 builtin.c
--- Src/builtin.c 12 Nov 2008 12:57:26 -0000 1.218
+++ Src/builtin.c 25 Jan 2009 08:37:08 -0000
@@ -58,7 +58,7 @@ static struct builtin builtins[] =
BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmrs", 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, 1, 1, 0, "LR", NULL),
+ BUILTIN("emulate", 0, bin_emulate, 0, 3, 0, "LR", NULL),
BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmrs", 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),
@@ -4744,24 +4744,12 @@ bin_dot(char *name, char **argv, UNUSED(
return ret ? ret : lastval;
}
-/**/
-int
-bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
-{
- emulate(*argv, OPT_ISSET(ops,'R'));
- if (OPT_ISSET(ops,'L'))
- opts[LOCALOPTIONS] = opts[LOCALTRAPS] = 1;
- return 0;
-}
-
-/* eval: simple evaluation */
-
-/**/
-mod_export int ineval;
+/*
+ * common for bin_emulate and bin_eval
+ */
-/**/
-int
-bin_eval(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int
func))
+static int
+eval(char **argv)
{
Eprog prog;
char *oscriptname = scriptname;
@@ -4838,6 +4826,79 @@ bin_eval(UNUSED(char *nam), char **argv,
return lastval;
}
+/* emulate: set emulation mode and optionally evaluate shell code */
+
+/**/
+int
+bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
+{
+ int opt_L = OPT_ISSET(ops, 'L');
+ int opt_R = OPT_ISSET(ops, 'R');
+ int saveemulation ;
+ int ret;
+ char saveopts[OPT_SIZE];
+
+ /* without arguments just print current emulation */
+ if (!*argv) {
+ if (opt_L || opt_R) {
+ zwarnnam("emulate", "not enough arguments");
+ return 1;
+ }
+
+ printf("%s\n", emulation == EMULATE_CSH ? "csh" :
+ emulation == EMULATE_KSH ? "ksh" :
+ emulation == EMULATE_SH ? "sh" :
+ "zsh");
+ return 0;
+ }
+
+ /* with single argument set current emulation */
+ if (!argv[1]) {
+ emulate(*argv, OPT_ISSET(ops,'R'));
+ if (OPT_ISSET(ops,'L'))
+ opts[LOCALOPTIONS] = opts[LOCALTRAPS] = 1;
+ return 0;
+ }
+
+ /* If "-c command" is given, evaluate command using specified
+ * emulation mode.
+ */
+ if (strcmp(argv[1], "-c")) {
+ zwarnnam("emulate", "unknown argument %s", argv[1]);
+ return 1;
+ }
+
+ if (!argv[2]) {
+ zwarnnam("emulate", "not enough arguments");
+ return 1;
+ }
+
+ if (opt_L) {
+ zwarnnam("emulate", "option -L incompatible with -c");
+ return 1;
+ }
+
+ memcpy(saveopts, opts, sizeof(opts));
+ saveemulation = emulation;
+ emulate(*argv, OPT_ISSET(ops,'R'));
+ ret = eval(argv+2);
+ memcpy(opts, saveopts, sizeof(opts));
+ emulation = saveemulation;
+ return ret;
+}
+
+/* eval: simple evaluation */
+
+/**/
+mod_export int ineval;
+
+/**/
+int
+bin_eval(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int
func))
+{
+ return eval(argv);
+}
+
static char *zbuf;
static int readfd;
Attachment:
signature.asc
Description: This is a digitally signed message part.