diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Doc/Zsh/builtins.yo | 3 | ||||
-rw-r--r-- | Src/exec.c | 12 | ||||
-rw-r--r-- | Test/E02xtrace.ztst | 17 |
4 files changed, 32 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog index b31543b4f..f6e70e50e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2016-06-13 Daniel Shahaf <d.s@daniel.shahaf.name> + * 38653 + 38657: Doc/Zsh/builtins.yo, Src/exec.c, + Test/E02xtrace.ztst: 'functions -T' tracing: recurse into + anonymous functions. + * 38651: Completion/Unix/Command/_git: Escape parameter arguments to _call_program. diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 1ca1f24a8..5c33cd1cf 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -2028,7 +2028,8 @@ The names refer to functions rather than parameters. No assignments 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 +for any named (not anonymous) 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 function to be marked for autoloading; tt(-U) also causes alias expansion to be suppressed when the function is loaded. See the diff --git a/Src/exec.c b/Src/exec.c index 2dcd5bcf5..515406f33 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 093a587bd..6e425e703 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 |