zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh-workers@zsh.org
Subject: Bug (?) with "return" from inside "while"
Date: Sat, 5 Nov 2016 15:16:09 -0700	[thread overview]
Message-ID: <161105151609.ZM19059@torch.brasslantern.com> (raw)
In-Reply-To: <161105140043.ZM17511@torch.brasslantern.com>

On Nov 5,  2:00pm, Bart Schaefer wrote:
}
} The change for [execwhile()] is less obvious than with execif(),

As best I can tell, the exit value of a "while" loop is supposed to
be the exit value of the last executed statement in the loop-body,
but the value of $? on entry to the loop body is supposed to be the
value of the last executed statement in the condition.

Thus

    i=0
    while (( i++ < 1 )); do echo $?; (return 27); done
    echo $?

should echo

    0
    27

And

    i=0
    until (( i++ == 1 )); do echo $?; (return 27); done
    echo $?

should echo

    1
    27

The question is what the exit status should be if the conditional
includes an explicit "return N".  dash and zsh up to this point
return the exit status of the loop body, or zero if the loop body
has never executed.  Bash returns N, which seems more correct.

A related question is what happens if the loop is interrupted with
^C.  The most recent changes to execwhile() are all about handling
that (plus making the interrupt possible if the condition or body
or both are empty).  Is an interrupted condition the same as one
that returned false (or true in the case of until)?  This somewhat
obscures what is intended in the case where there is no interrupt.

There's also the question of what $? should be upon entry to the
condition.  On the first loop it's unchanged from the previous
command, but on successive loops it's the value from the loop body.
On the other hand the value of $? on entry to the loop body is the
value from the condition (always 0 for while, nonzero for until).
(Patch below doesn't address this at all.)

I think the following is the minimum sensible change but there may
be corner cases that it's not covering.

diff --git a/Src/loop.c b/Src/loop.c
index f65c72b..367c0df 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -439,13 +439,12 @@ execwhile(Estate state, UNUSED(int do_exec))
             if (!((lastval == 0) ^ isuntil)) {
                 if (breaks)
                     breaks--;
-                lastval = oldval;
+		if (!retflag)
+		    lastval = oldval;
                 break;
             }
-            if (retflag) {
-                lastval = oldval;
+            if (retflag)
                 break;
-            }
 
 	    /* In case the loop body is also a functional no-op,
 	     * make sure signal handlers recognize ^C as above. */


  reply	other threads:[~2016-11-05 22:23 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-05 20:25 Bug with "return" from inside "if" Bart Schaefer
2016-11-05 21:00 ` Bart Schaefer
2016-11-05 22:16   ` Bart Schaefer [this message]
2016-11-07  9:38     ` Bug (?) with "return" from inside "while" 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=161105151609.ZM19059@torch.brasslantern.com \
    --to=schaefer@brasslantern.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).