zsh-users
 help / color / mirror / code / Atom feed
* Possible bug: Zsh function does not terminate when ${name:?word} fails
@ 2016-09-14  8:00 ` Ronald Fischer
  2016-09-14  8:19   ` Mikael Magnusson
  2016-09-14  9:19   ` Peter Stephenson
  0 siblings, 2 replies; 6+ messages in thread
From: Ronald Fischer @ 2016-09-14  8:00 UTC (permalink / raw)
  To: Zsh Mailing-List

(See also for a complete discussion:
http://stackoverflow.com/questions/39463547/zsh-function-does-not-terminate-when-nameword-fails?noredirect=1#comment66276136_39463547)

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.

I tested this with zsh 5.1.1, but I was informed that this behaviour
also can be reproduced with zsh 5.2

Ronald


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

* Re: Possible bug: Zsh function does not terminate when ${name:?word} fails
  2016-09-14  8:00 ` Possible bug: Zsh function does not terminate when ${name:?word} fails Ronald Fischer
@ 2016-09-14  8:19   ` Mikael Magnusson
  2016-09-14 11:21     ` Ronald Fischer
  2016-09-14  9:19   ` Peter Stephenson
  1 sibling, 1 reply; 6+ messages in thread
From: Mikael Magnusson @ 2016-09-14  8:19 UTC (permalink / raw)
  To: Ronald Fischer; +Cc: Zsh Mailing-List

On Wed, Sep 14, 2016 at 10:00 AM, Ronald Fischer <ynnor@mm.st> wrote:
> (See also for a complete discussion:
> http://stackoverflow.com/questions/39463547/zsh-function-does-not-terminate-when-nameword-fails?noredirect=1#comment66276136_39463547)
>
> 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.
>
> I tested this with zsh 5.1.1, but I was informed that this behaviour
> also can be reproduced with zsh 5.2

This seems to be a side effect of the reserved word handling, if you do
disable -r local
then it behaves as expected. Being in a function or not makes no
difference, the same thing happens if you do
local p=${foo:?hello}; echo continue
on the command line.

-- 
Mikael Magnusson


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

* Re: Possible bug: Zsh function does not terminate when ${name:?word} fails
  2016-09-14  8:00 ` Possible bug: Zsh function does not terminate when ${name:?word} fails Ronald Fischer
  2016-09-14  8:19   ` Mikael Magnusson
@ 2016-09-14  9:19   ` Peter Stephenson
  1 sibling, 0 replies; 6+ messages in thread
From: Peter Stephenson @ 2016-09-14  9:19 UTC (permalink / raw)
  To: Ronald Fischer, Zsh Mailing-List

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:${...:+...}, ${...+...}


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

* Re: Possible bug: Zsh function does not terminate when ${name:?word} fails
  2016-09-14  8:19   ` Mikael Magnusson
@ 2016-09-14 11:21     ` Ronald Fischer
  2016-09-14 16:20       ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Ronald Fischer @ 2016-09-14 11:21 UTC (permalink / raw)
  To: Mikael Magnusson, Zsh Mailing-List

> This seems to be a side effect of the reserved word handling, if you do
> disable -r local
> then it behaves as expected. 

I don't think this would be a good idea. If I understand correctly, this
would make the variables global (with all consequences from a name
clash). There are other nasty consequences too.

A better workaround is IMO to separate parameter check and assignment,
for instance by

: ${foo:?hello}
local p=$foo # foo is guaranteed to have a value here

Ronald


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

* Re: Possible bug: Zsh function does not terminate when ${name:?word} fails
  2016-09-14 11:21     ` Ronald Fischer
@ 2016-09-14 16:20       ` Bart Schaefer
  2016-09-14 19:08         ` Mikael Magnusson
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2016-09-14 16:20 UTC (permalink / raw)
  To: Zsh Mailing-List

On Sep 14,  1:21pm, Ronald Fischer wrote:
} Subject: Re: Possible bug: Zsh function does not terminate when ${name:?wo
}
} > This seems to be a side effect of the reserved word handling, if you do
} > disable -r local
} > then it behaves as expected. 
} 
} I don't think this would be a good idea.

I think this was being presented as a diagnostic tool, not as a work-
around for real usage.


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

* Re: Possible bug: Zsh function does not terminate when ${name:?word} fails
  2016-09-14 16:20       ` Bart Schaefer
@ 2016-09-14 19:08         ` Mikael Magnusson
  0 siblings, 0 replies; 6+ messages in thread
From: Mikael Magnusson @ 2016-09-14 19:08 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Mailing-List

On Wed, Sep 14, 2016 at 6:20 PM, Bart Schaefer
<schaefer@brasslantern.com> wrote:
> On Sep 14,  1:21pm, Ronald Fischer wrote:
> } Subject: Re: Possible bug: Zsh function does not terminate when ${name:?wo
> }
> } > This seems to be a side effect of the reserved word handling, if you do
> } > disable -r local
> } > then it behaves as expected.
> }
> } I don't think this would be a good idea.
>
> I think this was being presented as a diagnostic tool, not as a work-
> around for real usage.

Disabling local as a reserved word does not disable the builtin, and
only reverts to the old behavior of not being able to specify arrays'
values on the parameter declaration line.

% a=${foo:?bar}; echo hello
zsh: foo: bar
% local a=${foo:?bar}; echo hello
zsh: foo: bar
hello
% \local a=${foo:?bar}; echo hello
zsh: foo: bar

(the backslash has the same effect of overriding the reserved word handling)

-- 
Mikael Magnusson


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

end of thread, other threads:[~2016-09-14 19:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20160914080154eucas1p11c49e4dd5f0d45f92deaef1ce08099de@eucas1p1.samsung.com>
2016-09-14  8:00 ` Possible bug: Zsh function does not terminate when ${name:?word} fails 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

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