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

Re: Bug with bash emulation regarding ':'



On Sun, 29 Jan 2012 20:01:13 +0100
Vincent Lefevre <vincent@xxxxxxxxxx> wrote:
> On 2012-01-29 19:53:51 +0100, Mikael Magnusson wrote:
> > On 29 January 2012 19:38, Vincent Lefevre <vincent@xxxxxxxxxx> wrote:
> > > On 2012-01-29 15:25:13 +0100, Mikael Magnusson wrote:
> > >> On 29 January 2012 14:44, Felipe Contreras <felipe.contreras@xxxxxxxxx> wrote:
> > >> > emulate bash
> > >>
> > >> There's no such emulation mode.
> > >
> > > I think the problem is that "emulate" doesn't return an error
> > > if the argument is unsupported.
> > 
> > Well, there are no unsupported arguments, anything that isn't
> > recognized is documented (although not accurately) to enter zsh mode
> > :).
> 
> Yes, but this is not intuitive. An error would be better, IMHO.

emulate "bash" is treated as emulate "sh", but isn't so documented.

However, having any random emulation treated as zsh in the emulate
command seems a bit pointless.  I think it only does that because the
code is shared with what happens at shell start-up.

How about the following compromise?

- Behave the same at start-up as always.  There's no point in an
error here if we don't recognise what zsh is supposed to be emulating.

- In the emulate command, keep the behaviour that we only test the
initial letter (and that "b" is like "s"), but document it.

- However, if the initial letter isn't recognised within the emulate
command (i.e. we now require a 'z' for native mode), complain.

This will annoy anyone who deliberately used "emulate native" to enter
zsh mode (for which I have only limited sympathy), but unless I've
missed something it should keep everyone else happy; indeed, the emulate
command only lists the explicit possibilities "zsh", "sh", "ksh", "csh",
but we did document that zsh was used as a default.  Usually Bart spots
something I've missed at this point, however.

I'd argue along with Vincent that even if there is a small amount of
pain it's better than letting people assume "emulate pdksh" or "emulate
dash" did what they presumably thought.

Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.136
diff -p -u -r1.136 builtins.yo
--- Doc/Zsh/builtins.yo	3 Jun 2011 19:54:44 -0000	1.136
+++ Doc/Zsh/builtins.yo	29 Jan 2012 20:21:45 -0000
@@ -354,10 +354,19 @@ Without any argument print current emula
 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
-argument are the same as those used to determine the emulation at startup
-based on the shell name, see
+
+The test is actually based on the initial letter of the emulation mode,
+unless the first letter is `tt(r)', in which case the second letter
+is used.  (The `tt(r)' is assumed to stand for `restricted', however
+no further account of this is taken by `tt(emulate)'.)  In addition
+to the letters `tt(z)', `tt(s)', `tt(k)' and `tt(c)', the letter `tt(b)'
+is treated the same as `tt(s)'.  (The `tt(b)' stands for `tt(bash)', however
+no distinction is made between this and `tt(sh)'.)  Any other initial
+letter is treated as an error.
+
+The tests performed on the argument are the same as those used to
+determine the emulation at startup based on the shell name, with the
+exception that at startup zsh is silently used as a default.  See
 ifzman(\
 the section `Compatibility' in zmanref(zshmisc)
 )\
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.254
diff -p -u -r1.254 builtin.c
--- Src/builtin.c	29 Aug 2011 17:21:40 -0000	1.254
+++ Src/builtin.c	29 Jan 2012 20:21:45 -0000
@@ -4989,7 +4995,8 @@ bin_emulate(UNUSED(char *nam), char **ar
 
     /* with single argument set current emulation */
     if (!argv[1]) {
-	emulate(*argv, OPT_ISSET(ops,'R'));
+	if (emulate(*argv, OPT_ISSET(ops,'R'), 1))
+	    return 1;
 	if (OPT_ISSET(ops,'L'))
 	    opts[LOCALOPTIONS] = opts[LOCALTRAPS] = 1;
 	return 0;
@@ -5016,11 +5023,12 @@ bin_emulate(UNUSED(char *nam), char **ar
     memcpy(saveopts, opts, sizeof(opts));
     saveemulation = emulation;
     savesticky_emulation = sticky_emulation;
-    emulate(*argv, OPT_ISSET(ops,'R'));
-    sticky_emulation = emulation;
-    ret = eval(argv+2);
-    memcpy(opts, saveopts, sizeof(opts));
-    sticky_emulation = savesticky_emulation;
+    if (!emulate(*argv, OPT_ISSET(ops,'R'), 1)) {
+	sticky_emulation = emulation;
+	ret = eval(argv+2);
+	memcpy(opts, saveopts, sizeof(opts));
+	sticky_emulation = savesticky_emulation;
+    }
     emulation = saveemulation;
     return ret;
 }
Index: Src/init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.122
diff -p -u -r1.122 init.c
--- Src/init.c	5 Jan 2012 20:01:25 -0000	1.122
+++ Src/init.c	29 Jan 2012 20:21:45 -0000
@@ -1510,7 +1510,7 @@ zsh_main(UNUSED(int argc), char **argv)
     fdtable = zshcalloc(fdtable_size*sizeof(*fdtable));
 
     createoptiontable();
-    emulate(zsh_name, 1);   /* initialises most options */
+    emulate(zsh_name, 1, 0);   /* initialises most options */
     opts[LOGINSHELL] = (**argv == '-');
     opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid());
     opts[USEZLE] = 1;   /* may be unset in init_io() */
Index: Src/options.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/options.c,v
retrieving revision 1.59
diff -p -u -r1.59 options.c
--- Src/options.c	8 Jan 2012 16:02:55 -0000	1.59
+++ Src/options.c	29 Jan 2012 20:21:45 -0000
@@ -502,8 +502,8 @@ installemulation(void)
 }
 
 /**/
-void
-emulate(const char *zsh_name, int fully)
+int
+emulate(const char *zsh_name, int fully, int error_if_not_matched)
 {
     char ch = *zsh_name;
 
@@ -517,12 +517,18 @@ emulate(const char *zsh_name, int fully)
 	emulation = EMULATE_KSH;
     else if (ch == 's' || ch == 'b')
 	emulation = EMULATE_SH;
-    else
+    else if (ch == 'z' || !error_if_not_matched)
 	emulation = EMULATE_ZSH;
+    else {
+	zwarnnam("emulate", "emulation not recognised: %s", zsh_name);
+	return 1;
+    }
 
     if (fully)
 	emulation |= EMULATE_FULLY;
     installemulation();
+
+    return 0;
 }
 
 /* setopt, unsetopt */

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



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