From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, T_SCC_BODY_TEXT_LINE,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 30334 invoked from network); 31 May 2022 09:05:47 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 31 May 2022 09:05:47 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1653987947; b=EG0s6ShlPCfh6KtP1vqAOZYcp5T7r8NA4pEt+EVfNSiOBtP4mN+GgVXxfHQFgmtmv+YOTepv6E PlH5xx2AHzZVATjp8Cnkn3npy7LxFeqy1FLZoQGpvwC7BXvZmU2Xyl3zZn0y3hCx6x646+Kk82 GE1UWrC29FSYk1itwhQ01x+dV17xv3iBpu880LLrPMzKwYWwfag0DQxuYA2BxCBiCmDCPJzk/L 7SVpWKC8UpAuPixGMyw/nbDcwG7vdiKWNzPbwQlWY/mP0pxVc9YQVP3ZK59k4VpUpMZbnioGxa 2kIY31ExwdpYL4jvpIvGvYuBWIH5EiMSGCI2oUamEiDq+Q==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (smtpq2.tb.ukmail.iss.as9143.net) smtp.remote-ip=212.54.57.97; dkim=pass header.d=ntlworld.com header.s=meg.feb2017 header.a=rsa-sha256; dmarc=pass header.from=ntlworld.com; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1653987947; bh=tKOLMh35TQZnEXVdTXEJ/yZKnyfO71oj5kC4jbWtZZY=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject: References:In-Reply-To:Message-ID:To:From:Date:DKIM-Signature: DKIM-Signature; b=pUyAa2ubyQQT8G17Fo7zu5zu+vntGD/D4SQHIwwmWHzQUiBs+QrODhzGpLY5MfIitLpBkTVMzT 0uPGEEfv+6bxzJIOLxBq+hYAusDZQyzhYE0R388bNVveIosdzsRTUIDlmA8rUAN/6OTSyjrD3r H3mo79we8uy82txGqUMotOxAFJp7YeYZu8uZQkzBPselTRd1nQuyx0nxYu3nHmsWO7GP3q5nTS T4UTOByrDXJ/+/4Tt7xXtuwC6wNdiij57V5OfpZc0UL8rWpYxkrDaJtq0rQ8tJl74M/xAEF9uc b9TGSWRrLGu7rM6khm+wgFgO6W+RNgwtRD/+zKMSBoQqcA==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Subject:References:In-Reply-To:Message-ID:To:From: Date:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=+MSqg+bmQ2jOp7rw8+scbIdiHt3uBNGf08NV97DnrOk=; b=SLnsbzFeYwb6bw2sgPi5xJoNdj yJSfIyipvMHsxGPc9sILEm2N0oxLTVQKjGJlBYjv6mf/jVjqI0kCUOyk4QGhsD7Mx5Tj44TG+rysX IOZ1H9JrrxLooV760d4t03KCsGIVAPP8uEjSDTMKrZ6Ank+ayk/K2p9LdcjENdghmDIjbZ4wscA0N YkQxLRQ336V04qkzKSqbMoec5BWyLR9BCPNQHoO1nt0Pitf5ZfzAAYylCkM3gYFqCZfNB1+FKxTEP y8GfXWa6hCJ9lwB6ZSiuthqkv1bWuk854iVujnFTR/JL8Ox3SIfWjN4KVj4wPfe2zZgIid+0WnrGf 9dDEfAiA==; Received: from authenticated user by zero.zsh.org with local id 1nvxov-00024H-Pr; Tue, 31 May 2022 09:05:45 +0000 Authentication-Results: zsh.org; iprev=pass (smtpq2.tb.ukmail.iss.as9143.net) smtp.remote-ip=212.54.57.97; dkim=pass header.d=ntlworld.com header.s=meg.feb2017 header.a=rsa-sha256; dmarc=pass header.from=ntlworld.com; arc=none Received: from smtpq2.tb.ukmail.iss.as9143.net ([212.54.57.97]:34548) by zero.zsh.org with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) id 1nvxmX-0001TK-OD; Tue, 31 May 2022 09:03:20 +0000 Received: from [212.54.57.80] (helo=smtp1.tb.ukmail.iss.as9143.net) by smtpq2.tb.ukmail.iss.as9143.net with esmtp (Exim 4.90_1) (envelope-from ) id 1nvxmX-00064d-4n for zsh-workers@zsh.org; Tue, 31 May 2022 11:03:17 +0200 Received: from oxbe13.tb.ukmail.iss.as9143.net ([172.25.160.144]) by smtp1.tb.ukmail.iss.as9143.net with ESMTP id vxmXnEgAuVu5XvxmXnrTEW; Tue, 31 May 2022 11:03:17 +0200 X-Env-Mailfrom: p.w.stephenson@ntlworld.com X-Env-Rcptto: zsh-workers@zsh.org X-SourceIP: 172.25.160.144 X-CNFS-Analysis: v=2.4 cv=LNR1/ba9 c=1 sm=1 tr=0 ts=6295d9d5 cx=a_exe a=wuFMYA7voKp1dZz7Z+vj5Q==:117 a=wbvTLvLwOfMA:10 a=IkcTkHD0fZMA:10 a=7H6ixmLU1AQA:10 a=q2GGsy2AAAAA:8 a=KxBxwhSdVVhDGkRRuHUA:9 a=QEXdDO2ut3YA:10 a=ImwWUX5h3JJ3gRE9moBe:22 a=z9dJwno5l634igLiVhy-:22 X-Authenticated-Sender: p.w.stephenson@ntlworld.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ntlworld.com; s=meg.feb2017; t=1653987797; bh=tKOLMh35TQZnEXVdTXEJ/yZKnyfO71oj5kC4jbWtZZY=; h=Date:From:To:In-Reply-To:References:Subject; b=WZ3PJAOZ61e4jcFQLQSEDUKL5bvTwh5WblRhyDLXi4uBJKpIYjBNCmGoJxzKNkutR h9o5aEaYjDdR8S95ko06ARNwZwEI+3mzc94t+PkcbNX+6KFcyqN/1KXzYBTdEnqUBa NA9WYqwnWDlYa6C+PsFJkwXBX002cfC55UJdqk908eb77GeuGr76C6QBtUlayzxvSo 33AaE7vDKcmaRLaHdV9JXE2brJhqZzAyjxRO0WAHhbgymDadDjtFXa3G7ImQaoB097 ksy88WfhZNUdeUBX/ToHycYJ/h2zcLklD2X+hokeeFlmlAwgY97+8LfnpZv9m3Pk0v PlA5ojQC71Hsg== Date: Tue, 31 May 2022 10:03:17 +0100 (BST) From: Peter Stephenson To: Zsh hackers list Message-ID: <1980097513.514587.1653987797049@mail2.virginmedia.com> In-Reply-To: References: Subject: Re: Minor bug(s) with NO_MULTI_FUNC_DEF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Priority: 3 Importance: Medium X-Mailer: Open-Xchange Mailer v7.8.4-Rev72 X-Originating-IP: 147.161.167.85 X-Originating-Client: open-xchange-appsuite X-CMAE-Envelope: MS4xfFkZrfWlV0tqt2CwdiVZ+Sw4pcjIRdk8lrJIA8TVox+47+nM7/q7p5BAUkIclPkp1VNBJHzORiRfxvhu325/Ksk0gePWioIHgNDR38mfrYXhpPlvvANH 6ykdjU8OQCNwose7TTGe8oIbPyJE9Wx9CTbOXzdB5xoHkDyTijT1YS3otYJ/BxNGBRa9XBwLx8qZCxfrblAkeqTZFjRdatlvsRl3vBXAldn+lR6buYRs6Qm7 X-Seq: 50312 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: > On 30 May 2022 at 21:31 Bart Schaefer wrote: > Even with that option set, "functions" outputs multifuncdef syntax. > > % setopt nomultifuncdef > % foo() { > function foo1 foo2 foo3 { echo $0 } > function> } > % functions foo > foo () { > foo1 foo2 foo3 () { > echo $0 > } > } So the question is, is it time to output all functions (except anonymous) using the other syntax, which is the one we recommend anyway? Updating the tests as below suggests this is basically OK; I suppose we have to think up interesting edge cases. I don't see a good argument for doing it differently depending on the option setting. >From my point, actually, it's a step in the right direction --- I just tried eval "$(functions)" before and after the change; before it gave me zsh: defining function based on alias `d' zsh: parse error near `()' whereas after it's silent. I presume the latter error is a consequence of the previous warning, but I haven't looked further. Of course, silent doesn't mean the same as completely functional. Strictly, we can print anonymous functions the other way, too, but it somehow seems less natural, as well as reasonable to have some visual discriminator, so I've left them as "()" here. > As an aside, something like this: > > TRAP{HUP,INT,QUIT,TERM} () { print -u2 Got $1 } > > bypasses the nomultifuncdef syntax check and successfully defines all > four functions. We could probably document our way out here. It is a single command line word in origin so the intention must be the obvious one. pws diff --git a/Src/hashtable.c b/Src/hashtable.c index bb165505e..74e838829 100644 --- a/Src/hashtable.c +++ b/Src/hashtable.c @@ -942,10 +942,11 @@ printshfuncnode(HashNode hn, int printflags) putchar('\n'); return; } - + + printf("function "); quotedzputs(f->node.nam, stdout); if (f->funcdef || f->node.flags & PM_UNDEFINED) { - printf(" () {\n"); + printf(" {\n"); zoutputtab(stdout); if (f->node.flags & PM_UNDEFINED) { printf("%c undefined\n", hashchar); @@ -983,7 +984,7 @@ printshfuncnode(HashNode hn, int printflags) } printf("\n}"); } else { - printf(" () { }"); + printf(" { }"); } if (f->redir) { t = getpermtext(f->redir, NULL, 1); diff --git a/Src/text.c b/Src/text.c index 5cd7685fd..89de27ea5 100644 --- a/Src/text.c +++ b/Src/text.c @@ -578,11 +578,16 @@ gettext2(Estate state) Wordcode end = p + WC_FUNCDEF_SKIP(code); int nargs = *state->pc++; - taddlist(state, nargs); - if (nargs) + if (nargs) { + taddstr("function "); + taddlist(state, nargs); taddstr(" "); + } else { + /* Anonymous function */ + taddstr("() "); + } if (tjob) { - taddstr("() { ... }"); + taddstr("{ ... }"); state->pc = end; if (!nargs) { /* @@ -594,7 +599,7 @@ gettext2(Estate state) } stack = 1; } else { - taddstr("() {"); + taddstr("{"); tindent++; taddnl(1); n = tpush(code, 1); diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst index 0312fe94e..719a43c3d 100644 --- a/Test/A01grammar.ztst +++ b/Test/A01grammar.ztst @@ -80,7 +80,7 @@ functions -x3 fn fn 0:End of sublist containing ! with no command ->fn () { +>function fn { > : && ! > : >} @@ -95,7 +95,7 @@ functions -x2 fn fn 0:exclamation marks without following commands ->fn () { +>function fn { > ! { > ! > } && ! ( @@ -473,19 +473,19 @@ fn3() { ( echo foo; ) } functions fn1 fn2 fn3 0:Output of syntactic structures with and without always blocks ->fn1 () { +>function fn1 { > { > echo foo > } >} ->fn2 () { +>function fn2 { > { > echo foo > } always { > echo bar > } >} ->fn3 () { +>function fn3 { > ( > echo foo > ) @@ -776,7 +776,7 @@ F:Note that the behaviour of 'exit' inside try-list inside a function is unspeci fn abecedinarian fn xylophone) 0: case word handling in sh emulation (SH_GLOB parentheses) ->fn () { +>function fn { > case $1 in > (one | two | three) print Matched $1 ;; > (fo* | fi* | si*) print Pattern matched $1 ;; @@ -846,7 +846,7 @@ F:Note that the behaviour of 'exit' inside try-list inside a function is unspeci which fn fn 0:Long case with parsed alternatives turned back into text ->fn () { +>function fn { > typeset ac_file="the else branch" > case $ac_file in > (*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj) ;; diff --git a/Test/A04redirect.ztst b/Test/A04redirect.ztst index 17f6dfa29..855c44782 100644 --- a/Test/A04redirect.ztst +++ b/Test/A04redirect.ztst @@ -230,7 +230,7 @@ eval $'fn-varid() { print {\x18}<<0 }' { which -x2 fn-varid; fn-varid } | tr $'\x18' '?' 0:Regression test for off-by-one in varid check ->fn-varid () { +>function fn-varid { > print {?} <<0 >0 >} @@ -575,7 +575,7 @@ which redirfn 0:text output of function with redirections ->redirfn () { +>function redirfn { > local var > read var > print I want to tell you about $var @@ -653,7 +653,7 @@ fn-two-heres print $functions[fn-two-heres] 0:Two here-documents in a line are shown correctly. ->fn-two-heres () { +>function fn-two-heres { > cat <foo >x @@ -679,7 +679,7 @@ which fn-here-pipe 0:Combination of HERE-document and |& >FOO ->fn-here-pipe () { +>function fn-here-pipe { > cat <&1 | cat >FOO >HERE diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst index d95ee363c..22c84aaec 100644 --- a/Test/A05execution.ztst +++ b/Test/A05execution.ztst @@ -272,7 +272,7 @@ F:anonymous function, and a descriptor leak when backgrounding a pipeline 0: >No output yet >Autoloaded ksh style ->autoload_redir () { +>function autoload_redir { > print Autoloaded ksh style >} > autoload.log diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index 8b3988151..7ec43adee 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -797,10 +797,10 @@ fn2() { typeset assignfirst=(why not); } which -x2 fn2 0:text output from typeset ->fn () { +>function fn { > typeset foo bar thing=this stuff=(that other) more=woevva >} ->fn2 () { +>function fn2 { > typeset assignfirst=(why not) >} diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 4366b4142..502365d05 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -355,7 +355,7 @@ F:scenario if you encounter it. } which crashme 0:Regression test for examining code with regular expression match ->crashme () { +>function crashme { > if [[ $1 =~ ^http:* ]] > then > url=${1#*=} @@ -424,7 +424,7 @@ F:scenario if you encounter it. fn() { [[ 'a' == 'b' || 'b' = 'c' || 'c' != 'd' ]] } which -x2 fn 0: = and == appear as input ->fn () { +>function fn { > [[ 'a' == 'b' || 'b' = 'c' || 'c' != 'd' ]] >} diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index f120809a7..6483494d3 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -101,13 +101,13 @@ } fn1 0: Nested TRAPINT, not triggered ->TRAPINT () { +>function TRAPINT { > print INT1 >} ->TRAPINT () { +>function TRAPINT { > print INT2 >} ->TRAPINT () { +>function TRAPINT { > print INT1 >} @@ -391,10 +391,10 @@ fn2 fn1') 0:POSIX_TRAPS option ->TRAPEXIT () { +>function TRAPEXIT { > print Exited >} ->TRAPEXIT () { +>function TRAPEXIT { > print No, really exited >} >No, really exited diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index af469c527..2f8ee1fe3 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -259,7 +259,7 @@ } functions fn 0:Text representation of anonymous function with arguments ->fn () { +>function fn { > () { > print Anonymous function 1 $* > } with args @@ -321,7 +321,7 @@ barexpansion() { print This is the correct output.; } funcwithalias 0:Alias expanded in command substitution does not appear expanded in text ->funcwithalias () { +>function funcwithalias { > echo $(fooalias) >} >This is the correct output. @@ -348,7 +348,7 @@ ) 0:autoload containing eval >oops was successfully autoloaded ->oops () { +>function oops { > print oops was successfully autoloaded >} diff --git a/Test/C05debug.ztst b/Test/C05debug.ztst index 9a8df1dad..3a428cba0 100644 --- a/Test/C05debug.ztst +++ b/Test/C05debug.ztst @@ -137,7 +137,7 @@ >6: 'x=y ' >7: 'print $x' >y ->8: 'fn2 () { +>8: 'function fn2 { > echo wow >}' >9: 'fn2' diff --git a/Test/E02xtrace.ztst b/Test/E02xtrace.ztst index 56bc20f1a..59cdfdc5b 100644 --- a/Test/E02xtrace.ztst +++ b/Test/E02xtrace.ztst @@ -164,19 +164,19 @@ " done 0:a function that redefines itself preserves tracing ->f () { +>function f { > # traced > echo inner >} ->foo-bar () { +>function foo-bar { > # traced > echo inner >} ->$'\M-c\M-\C-C\M-\C-L' () { +>function $'\M-c\M-\C-C\M-\C-L' { > # traced > echo inner >} ->$'ba\C-@z' () { +>function $'ba\C-@z' { > # traced > echo inner >} @@ -192,7 +192,7 @@ functions f f 0:define traced function: named function ->f () { +>function f { > # traced > echo traced named function >}