zsh-workers
 help / color / mirror / code / Atom feed
* eval and resetting $? (Was Re: trap DEBUG + set -o DEBUG_BEFORE_CMD not setting $? nonzero in current CVS)
@ 2008-08-05  1:33 Rocky Bernstein
  2008-08-06 19:30 ` Peter Stephenson
  0 siblings, 1 reply; 2+ messages in thread
From: Rocky Bernstein @ 2008-08-05  1:33 UTC (permalink / raw)
  To: zsh-workers

Thanks. This seems to work.

However when I use it I run into something else that looks like either
a bug or at least something whose behavior should be documented. In
the following program it feels like $? gets changed/reset? before eval
is run:

#!/usr/local/bin/zsh -f
cmd='print $?'
fdsafsdsfa # Invalid command
eval $cmd  # print $? works and so does
                  # ./file-containing: print $?

print $? works because $? is expanded before print is run. And
sourcing a file which contains the string I want to eval also works,
so this gives me a workaround for this problem.

But somehow I think that a string writing that to a file and sourcing
it should be equivalent to eval'ing the string.



On Mon, Aug 4, 2008 at 1:49 PM, Peter Stephenson <pws@csr.com> wrote:
> On Mon, 4 Aug 2008 06:08:39 -0400
> "Rocky Bernstein" <rocky.bernstein@gmail.com> wrote:
>> The following code doesn't show $? as nonzero inside trap DEBUG using the
>> CVS source I just downloaded and built.
>>
>> However I don't get this problem on the Ubuntu zsh-beta or zsh.
>> Removing DEBUG_BEFORE_CMD (or I guess having debug run after the
>> command) does set/show $? properly.
>>
>> #!/tmp/zsh/Src/zsh -f
>> #!/src/external-cvs/zsh/Src/zsh -f
>> set -o DEBUG_BEFORE_CMD
>> trap 'print $?' DEBUG
>> fdasfsdafd  # invalid command
>> :
>
> Turns out to be unfinished business with the previous patch:  that code I
> patched needs also to be told when we're not in a trap at all.  It was
> triggering after the trap, resetting the status.
>
> I must write tests for both.
>
> Index: Src/init.c
> ===================================================================
> RCS file: /cvsroot/zsh/zsh/Src/init.c,v
> retrieving revision 1.89
> diff -u -r1.89 init.c
> --- Src/init.c  4 Aug 2008 17:32:20 -0000       1.89
> +++ Src/init.c  4 Aug 2008 17:46:26 -0000
> @@ -191,7 +191,7 @@
>            exit(lastval);
>        if (((!interact || sourcelevel) && errflag) || retflag)
>            break;
> -       if (trapreturn >= 0) {
> +       if (intrap && trapreturn >= 0) {
>            lastval = trapreturn;
>            trapreturn = 0;
>        }
>
>
> --
> Peter Stephenson <pws@csr.com>                  Software Engineer
> CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
> Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070
>


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: eval and resetting $? (Was Re: trap DEBUG + set -o DEBUG_BEFORE_CMD not setting $? nonzero in current CVS)
  2008-08-05  1:33 eval and resetting $? (Was Re: trap DEBUG + set -o DEBUG_BEFORE_CMD not setting $? nonzero in current CVS) Rocky Bernstein
@ 2008-08-06 19:30 ` Peter Stephenson
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Stephenson @ 2008-08-06 19:30 UTC (permalink / raw)
  To: zsh-workers

On Mon, 4 Aug 2008 21:33:16 -0400
"Rocky Bernstein" <rocky.bernstein@gmail.com> wrote:
> However when I use it I run into something else that looks like either
> a bug or at least something whose behavior should be documented. In
> the following program it feels like $? gets changed/reset? before eval
> is run:
> 
> #!/usr/local/bin/zsh -f
> cmd='print $?'
> fdsafsdsfa # Invalid command
> eval $cmd  # print $? works and so does
>                   # ./file-containing: print $?
> 
> print $? works because $? is expanded before print is run. And
> sourcing a file which contains the string I want to eval also works,
> so this gives me a workaround for this problem.
> 
> But somehow I think that a string writing that to a file and sourcing
> it should be equivalent to eval'ing the string.

I think you're right, and it would confuse me, too.  Although this is
explicit behaviour of the eval builtin, it's not tested in the test
suite, and as well as not being documented it's not standard shell
behaviour, so it's probably a bug.  I think nobody's happened
to look at the current status in the first command of an eval
before---if they had, it's hard to see them thinking "great! the status
has been reset! all's well with the world!"

It might be here to ensure that an eval with empty code sets the status
to zero; in many (all?) shells, eval of an empty string or anything
syntactically equivalent resets the status.  We don't want to change
that.  Luckily, the test for that is easy, and unambiguous---if you
follow through execution as far as execlist() you'll see that any time
the test I've added to eval is false, there's shell code to execute.

Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.108
diff -u -r1.108 builtins.yo
--- Doc/Zsh/builtins.yo	10 Jun 2008 08:50:36 -0000	1.108
+++ Doc/Zsh/builtins.yo	6 Aug 2008 19:28:23 -0000
@@ -382,7 +382,10 @@
 cindex(evaluating arguments as commands)
 item(tt(eval) [ var(arg) ... ])(
 Read the arguments as input to the shell and execute the resulting
-command in the current shell process.
+command(s) in the current shell process.  The return status is the
+same as if the commands had been executed directly by the shell;
+if there are no var(args) or they contain no commands (i.e. are
+an empty string or whitespace) the return status is zero.
 )
 item(tt(exec) [ tt(-cl) ] [ tt(-a) var(argv0) ] var(simple command))(
 Replace the current shell with an external command rather than forking.
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.200
diff -u -r1.200 builtin.c
--- Src/builtin.c	31 Jul 2008 08:44:20 -0000	1.200
+++ Src/builtin.c	6 Aug 2008 19:28:24 -0000
@@ -4717,17 +4717,19 @@
 
     prog = parse_string(zjoin(argv, ' ', 1));
     if (prog) {
-	lastval = 0;
-
-	execode(prog, 1, 0);
+	if (wc_code(*prog->prog) != WC_LIST) {
+	    /* No code to execute */
+	    lastval = 0;
+	} else {
+	    execode(prog, 1, 0);
 
-	if (errflag)
-	    lastval = errflag;
+	    if (errflag)
+		lastval = errflag;
+	}
     } else {
 	lastval = 1;
     }
 
-
     errflag = 0;
     scriptname = oscriptname;
     ineval = oineval;
Index: Test/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/.distfiles,v
retrieving revision 1.20
diff -u -r1.20 .distfiles
--- Test/.distfiles	18 Dec 2007 21:16:30 -0000	1.20
+++ Test/.distfiles	6 Aug 2008 19:28:24 -0000
@@ -11,6 +11,7 @@
 B02typeset.ztst
 B03print.ztst
 B04read.ztst
+B05eval.ztst
 C01arith.ztst
 C02cond.ztst
 C03traps.ztst
Index: Test/B05eval.ztst
===================================================================
RCS file: Test/B05eval.ztst
diff -N Test/B05eval.ztst
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Test/B05eval.ztst	6 Aug 2008 19:28:24 -0000
@@ -0,0 +1,34 @@
+# Tests for the eval builtin.
+# This is quite short; eval is widely tested throughout the test suite
+# and its basic behaviour is fairly straightforward.
+
+%prep
+
+  cmd='print $?'
+
+%test
+
+  false
+  eval $cmd
+0:eval retains value of $?
+>1
+
+  # no point getting worked up over what the error message is...
+  ./command_not_found 2>/dev/null
+  eval $cmd
+0:eval after command not found
+>127
+
+  # trick the test system
+  sp=
+  false
+  eval "
+  $sp
+  $sp
+  $sp
+  "
+0:eval with empty command resets the status
+
+  false
+  eval
+0:eval with empty command resets the status

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


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-08-06 19:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-05  1:33 eval and resetting $? (Was Re: trap DEBUG + set -o DEBUG_BEFORE_CMD not setting $? nonzero in current CVS) Rocky Bernstein
2008-08-06 19:30 ` Peter Stephenson

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).