zsh-users
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.stephenson@samsung.com>
To: Ronald Fischer <ynnor@mm.st>, Zsh Mailing-List <zsh-users@zsh.org>
Subject: Re: Possible bug: Zsh function does not terminate when ${name:?word} fails
Date: Wed, 14 Sep 2016 10:19:29 +0100	[thread overview]
Message-ID: <20160914101929.772d4606@pwslap01u.europe.root.pri> (raw)
In-Reply-To: <1473840044.77968.725190513.460F8572@webmail.messagingengine.com>

On Wed, 14 Sep 2016 10:00:44 +0200
Ronald Fischer <ynnor@mm.st> wrote:
> I have in my .zshrc the following function definition (simplified
> example):
> 
> function foo {
>   local p=${1:?parameter missing}
>   echo continue ....
> }
> 
> Running the function by just typing foo produces, as expected, the
> message parameter missing, but it also outputs continue. I had expected
> that the function terminates when the :? check fails, but it continues
> to run.

Yes, that's a bug.  As documented it should return to the top-level
prompt when interactive --- that means it will abort not just the
function but any surrounding code.  If that's not what you want you
might want to look at the ERR_RETURN option as an alternative.

I have to admit the resetting of error flags in zsh is something I've
never got properly to grips with, but now we have individual bits in the
errflag status variable this is straightforward to fix; most of the
logic we need is already there.  The lack of that until a couple of
years ago may be why this has been the way it has for so long.

pws

diff --git a/Src/subst.c b/Src/subst.c
index 1c2027f..92fde45 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -2922,6 +2922,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
                 if (isset(EXECOPT)) {
                     *idend = '\0';
                     zerr("%s: %s", idbeg, *s ? s : "parameter not set");
+                    /*
+                     * In interactive shell we need to return to
+                     * top-level prompt --- don't clear this error
+                     * after handling a command as we do with
+                     * most errors.
+                     */
+                    errflag |= ERRFLAG_HARD;
                     if (!interact) {
                         if (mypid == getpid()) {
                             /*
diff --git a/Src/zsh.h b/Src/zsh.h
index 996bc33..2dc5e7e 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2807,7 +2807,14 @@ enum errflag_bits {
     /*
      * User interrupt.
      */
-    ERRFLAG_INT = 2
+    ERRFLAG_INT = 2,
+    /*
+     * Hard error --- return to top-level prompt in interactive
+     * shell.  In non-interactive shell we'll typically already
+     * have exited.  This is reset by "errflag = 0" in
+     * loop(toplevel = 1, ...).
+     */
+    ERRFLAG_HARD = 4
 };
 
 /***********/
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index be6e104..7623051 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -95,6 +95,20 @@
 ?(eval):1: unset1: exiting1
 ?(eval):2: null1: exiting2
 
+  PROMPT="" $ZTST_testdir/../Src/zsh -fis <<<'
+  unsetopt PROMPT_SP
+  PS2="" PS3="" PS4="" RPS1="" RPS2=""
+  foo() {
+      print ${1:?no arguments given}
+      print not reached
+  }
+  foo
+  print reached
+  '
+0:interactive shell returns to top level on ${...?...} error
+?foo:1: 1: no arguments given
+>reached
+
   print ${set1:+word1} ${set1+word2} ${null1:+word3} ${null1+word4}
   print ${unset1:+word5} ${unset1+word6}
 0:${...:+...}, ${...+...}


      parent reply	other threads:[~2016-09-14  9:19 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20160914080154eucas1p11c49e4dd5f0d45f92deaef1ce08099de@eucas1p1.samsung.com>
2016-09-14  8:00 ` Ronald Fischer
2016-09-14  8:19   ` Mikael Magnusson
2016-09-14 11:21     ` Ronald Fischer
2016-09-14 16:20       ` Bart Schaefer
2016-09-14 19:08         ` Mikael Magnusson
2016-09-14  9:19   ` Peter Stephenson [this message]

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=20160914101929.772d4606@pwslap01u.europe.root.pri \
    --to=p.stephenson@samsung.com \
    --cc=ynnor@mm.st \
    --cc=zsh-users@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).