Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: sourcing a sh file in zsh



On 16 ÑÐÐÐÑÑ 2009 21:29:34 Bart Schaefer wrote:
> Another possibility would be to extend the "emulate" command into a
> precommand modifier sort of thing, where arguments following the name
> of the emulation are treated as a command to execute.  Perhaps
> require another option to make this active, to avoid any compatibily
> issue.
>
>   emulate -LRE sh source file.sh
>

What about the following patch. It simply eval's any code after setting 
requested emulation. As a bonus it prints current emulation if no argument 
is specified. Neither should be of compatibility issues as emulate always 
allowed exactly one argument.

Comments?

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	24 Jan 2009 15:40:16 -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(-ELR) ] [ {tt(zsh)|tt(sh)|tt(ksh)|tt(csh)} [ 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,12 +354,19 @@ the section `Compatibility' in zmanref(z
 ifnzman(\
 noderef(Compatibility)
 )\
-.  If the tt(-R) option is given, all options
+.
+
+If the tt(-E) option is given, arguments that follow
+emulation mode are evaluated using tt(eval) after setting requested
+emulation. 
+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.  The tt(-L) option together
+with tt(-E) causes emulation mode to be restored after evaluating the rest
+of arguments; without tt(-E), 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
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	24 Jan 2009 15:40:17 -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, -1, 0, "ELR", 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,83 @@ 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_E = OPT_ISSET(ops, 'E');
+    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_E || 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)) {
+	if (opt_E) {
+	    zwarnnam("emulate", "not enough arguments");
+	    return 1;
+	}
+
+	emulate(*argv, OPT_ISSET(ops,'R'));
+	if (OPT_ISSET(ops,'L'))
+	    opts[LOCALOPTIONS] = opts[LOCALTRAPS] = 1;
+	return 0;
+    }
+
+    /* If more than one argument is given, first one is emulation
+     * and subsequent are eval'ed using specified emulation mode.
+     * If option -L is given, emulation restored after evaluation.
+     */
+    if (!opt_E) {
+	zwarnnam("emulate", "too many arguments");
+	return 1;
+    }
+
+    if (opt_L) {
+	memcpy(saveopts, opts, sizeof(opts));
+	saveemulation = emulation;
+    }
+    emulate(*argv, OPT_ISSET(ops,'R'));
+    ret = eval(argv+1);
+    if (opt_L) {
+	/* restore all shell options except PRIVILEGED and RESTRICTED */
+	saveopts[PRIVILEGED] = opts[PRIVILEGED];
+	saveopts[RESTRICTED] = opts[RESTRICTED];
+	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.



Messages sorted by: Reverse Date, Date, Thread, Author