From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22565 invoked by alias); 10 Jun 2016 17:43:47 -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: X-Seq: 38653 Received: (qmail 27218 invoked from network); 10 Jun 2016 17:43:46 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.1 From: Daniel Shahaf To: zsh-workers@zsh.org Subject: [PATCH] 'functions -T' tracing: recurse into anonymous functions. Date: Fri, 10 Jun 2016 17:37:02 +0000 Message-Id: <1465580222-3300-1-git-send-email-danielsh@tarsus.local2> X-Mailer: git-send-email 2.1.4 --- Doc/Zsh/builtins.yo | 2 +- Src/exec.c | 12 +++++++++--- Test/E02xtrace.ztst | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 1ca1f24..813b725 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2029,7 +2029,7 @@ can be made, and the only other valid flags are tt(-t), tt(-T), tt(-k), tt(-u), tt(-U) and tt(-z). The flag tt(-t) turns on execution tracing for this function; the flag tt(-T) does the same, but turns off tracing on any function called from the present one, unless that function also -has the tt(-t) or tt(-T) flag. The tt(-u) and tt(-U) flags cause the +has the tt(-t) or tt(-T) flag or is anonymous. The tt(-u) and tt(-U) flags cause the function to be marked for autoloading; tt(-U) also causes alias expansion to be suppressed when the function is loaded. See the description of the `tt(autoload)' builtin for details. diff --git a/Src/exec.c b/Src/exec.c index 2dcd5bc..515406f 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4615,6 +4615,8 @@ exectime(Estate state, UNUSED(int do_exec)) /* Define a shell function */ +static const char *const ANONYMOUS_FUNCTION_NAME = "(anon)"; + /**/ static int execfuncdef(Estate state, Eprog redir_prog) @@ -4732,7 +4734,7 @@ execfuncdef(Estate state, Eprog redir_prog) if (!args) args = newlinklist(); - shf->node.nam = "(anon)"; + shf->node.nam = (char *) ANONYMOUS_FUNCTION_NAME; pushnode(args, shf->node.nam); execshfunc(shf, args); @@ -5165,8 +5167,12 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) if (flags & (PM_TAGGED|PM_TAGGED_LOCAL)) opts[XTRACE] = 1; - else if (oflags & PM_TAGGED_LOCAL) - opts[XTRACE] = 0; + else if (oflags & PM_TAGGED_LOCAL) { + if (shfunc->node.nam == ANONYMOUS_FUNCTION_NAME /* pointer comparison */) + flags |= PM_TAGGED_LOCAL; + else + opts[XTRACE] = 0; + } ooflags = oflags; /* * oflags is static, because we compare it on the next recursive diff --git a/Test/E02xtrace.ztst b/Test/E02xtrace.ztst index 093a587..6e425e7 100644 --- a/Test/E02xtrace.ztst +++ b/Test/E02xtrace.ztst @@ -127,3 +127,20 @@ ?+(eval):2> [[ 'f o' == f\ x* || 'b r' != z\ o && 'squashy sound' < 'squishy sound' ]] ?+(eval):3> [[ -e nonexistentfile || -z '' && -t 3 ]] ?+(eval):4> set +x + + # Part 1: Recurses into nested anonymous functions + fn() { + () { () { true } } + } + functions -T fn + fn + # Part 2: Doesn't recurse into named functions + gn() { true } + fn() { gn } + functions -T fn + fn +0:tracing recurses into anonymous functions +?+fn:1> '(anon)' +?+(anon):0> '(anon)' +?+(anon):0> true +?+fn:0> gn