From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from primenet.com.au (ns1.primenet.com.au [203.24.36.2]) by inbox.vuxu.org (OpenSMTPD) with ESMTP id 44ed78c1 for ; Sat, 21 Dec 2019 12:42:06 +0000 (UTC) Received: (qmail 5617 invoked by alias); 21 Dec 2019 12:41:42 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 45111 Received: (qmail 12720 invoked by uid 1010); 21 Dec 2019 12:41:42 -0000 X-Qmail-Scanner-Diagnostics: from out4-smtp.messagingengine.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.102.1/25663. spamassassin: 3.4.2. Clear:RC:0(66.111.4.28):SA:0(-1.9/5.0):. Processed in 0.649387 secs); 21 Dec 2019 12:41:42 -0000 X-Envelope-From: danielsh@apache.org X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: softfail (ns1.primenet.com.au: transitioning SPF record at amazonses.com does not designate 66.111.4.28 as permitted sender) X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedufedrvdduhedggedvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofestddtredtredttd enucfhrhhomhepffgrnhhivghlucfuhhgrhhgrfhcuoegurghnihgvlhhshhesrghprggt hhgvrdhorhhgqeenucfkphepjeelrddukedtrdehjedrudduleenucfrrghrrghmpehmrg hilhhfrhhomhepuggrnhhivghlshhhsegrphgrtghhvgdrohhrghenucevlhhushhtvghr ufhiiigvpedt X-ME-Proxy: From: Daniel Shahaf To: zsh-workers@zsh.org Subject: [PATCH 1/2] zshmisc(1): Clarify the documentation of 'return' and 'exit' in conjunction with try/always Date: Sat, 21 Dec 2019 12:41:03 +0000 Message-Id: <20191221124104.22751-1-danielsh@apache.org> X-Mailer: git-send-email 2.11.0 Having reviewed 20076, 20084, 21734, and 21735, my understanding is that the original intention was: - A 'return' in a function does run always-list - An 'exit' outside a function does not run always-list - A 'return' outside a function is treated as an 'exit' All of which are the case today. The remaining case, of 'exit' used inside a function, was not specified by the referenced -workers@ posts; does, as implemented, run the always-list; and furthermore, based in 21734 it's fair to assume that the original documentation was assuming that 'exit' would be used outside of any function, just like it assumed 'return' would be used inside a function. Therefore, have the documentation specify only the behaviour of 'exit' outside any function, and leave the behaviour of 'exit' inside a function unspecified. Anyone who relied on the documentation of 'exit' as documented until this commit would have run into the documentation/implementation discrepancy described in 45075. --- Doc/Zsh/grammar.yo | 16 +++++++++++----- Etc/BUGS | 3 --- NEWS | 10 ++++++++++ Test/A01grammar.ztst | 2 ++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo index d30c9d2d7..a66358ed6 100644 --- a/Doc/Zsh/grammar.yo +++ b/Doc/Zsh/grammar.yo @@ -297,11 +297,11 @@ findex(always) cindex(always blocks) cindex(try blocks) item(tt({) var(try-list) tt(} always {) var(always-list) tt(}))( -First execute var(try-list). Regardless of errors, or tt(break), -tt(continue), or tt(return) commands encountered within var(try-list), +First execute var(try-list). Regardless of errors, or tt(break) or +tt(continue) commands encountered within var(try-list), execute var(always-list). Execution then continues from the result of the execution of var(try-list); in other words, any error, -or tt(break), tt(continue), or tt(return) command is treated in the +or tt(break) or tt(continue) command is treated in the normal way, as if var(always-list) were not present. The two chunks of code are referred to as the `try block' and the `always block'. @@ -345,10 +345,16 @@ example({ } # The error condition has been reset.) -An tt(exit) command (or a tt(return) command executed at the outermost -function level of a script) encountered in tt(try-list) does em(not) cause +When a tt(try) block occurs outside of any function, +a tt(return) or a tt(exit) encountered in var(try-list) does em(not) cause the execution of var(always-list). Instead, the shell exits immediately after any tt(EXIT) trap has been executed. +Otherwise, a tt(return) command encountered in var(try-list) will cause the +execution of var(always-list), just like tt(break) and tt(continue). + +COMMENT(The semantics of calling 'exit' in try-list inside a function are +deliberately left unspecified, because historically there was a mismatch between +the documented and implemented behaviours. Cf. 20076, 21734/21735, 45075.) ) findex(function) xitem(tt(function) var(word) ... [ tt(()) ] [ var(term) ] tt({) var(list) tt(})) diff --git a/Etc/BUGS b/Etc/BUGS index 8244677f6..3fbe81831 100644 --- a/Etc/BUGS +++ b/Etc/BUGS @@ -39,6 +39,3 @@ fn trap1 trap2 echo out2 ]]] ------------------------------------------------------------------------ -45075 - Daniel Shahaf - '{ exit } always { foo }' - docs/code mismatch -and return/exit differences ------------------------------------------------------------------------- diff --git a/NEWS b/NEWS index c1322ed0f..af59cb4e6 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,16 @@ path the leading '/' counts as one component. The functions builtin gained a -c option to efficiently copy functions. +The zshmisc(1) manual page incorrectly stated that when 'exit' is used +in a `try' block inside a function, the corresponding `always' block will +be executed. The manual page has been corrected. The shell's behaviour +has not changed, but code such as the following: +. + f() { { exit } always { echo Hello world } } +. +should be changed either to use 'return' instead of 'exit', or to have +the try/always block outside of any function. + Changes from 5.6.2 to 5.7.1 --------------------------- diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst index 2649c29c8..d3a591761 100644 --- a/Test/A01grammar.ztst +++ b/Test/A01grammar.ztst @@ -729,6 +729,7 @@ 3:Exit and always block with functions: simple >BEGIN >END +F:Note that the behaviour of 'exit' inside try-list inside a function is unspecified. ( mytrue() { echo mytrue; return 0 } @@ -741,6 +742,7 @@ >BEGIN >mytrue >END +F:Note that the behaviour of 'exit' inside try-list inside a function is unspecified. (emulate sh -c ' fn() {