From c7b30b127659fce57329dbf1b646021454d0f5e3 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 19 Mar 2020 18:00:16 +0000 Subject: [PATCH 8/9] Add the 'function -T' syntax. Config/version.mk was bumped in the previous commit. --- Doc/Zsh/grammar.yo | 13 ++++++++++++- README | 7 +++++++ Src/exec.c | 8 +++++--- Src/parse.c | 11 +++++++++-- Test/E02xtrace.ztst | 25 +++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo index e028c8512..fa0d72ff5 100644 --- a/Doc/Zsh/grammar.yo +++ b/Doc/Zsh/grammar.yo @@ -357,7 +357,7 @@ 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(})) +xitem(tt(function) [ tt(-T) ] var(word) ... [ tt(()) ] [ var(term) ] tt({) var(list) tt(})) xitem(var(word) ... tt(()) [ var(term) ] tt({) var(list) tt(})) item(var(word) ... tt(()) [ var(term) ] var(command))( where var(term) is one or more newline or tt(;). @@ -367,6 +367,17 @@ are usually only useful for setting traps. The body of the function is the var(list) between the tt({) and tt(}). See noderef(Functions). +The options of tt(function) have the following meanings: + +startitem() +item(-T)( +Enable tracing for this function, as though with tt(functions -T). See the +documentation of the tt(-f) option to the tt(typeset) builtin, in +ifzman(zmanref(zshbuiltins))\ +ifnzman(noderef(Shell Builtin Commands)). +) +enditem() + If the option tt(SH_GLOB) is set for compatibility with other shells, then whitespace may appear between the left and right parentheses when there is a single var(word); otherwise, the parentheses will be treated as diff --git a/README b/README index 2bd5c2179..ae4f788bc 100644 --- a/README +++ b/README @@ -43,6 +43,13 @@ name of an external command. Now it may also be a shell function. Normal command word precedece rules apply, so if you have a function and a command with the same name, the function will be used. +The syntax "function -T { ... }" used to define a function named "-T". +It now defines an anonymous function with single-level tracing enabled --- +same as "function f { ... }; functions -T f; f", but without naming the +function. The syntax "function -T foo { ... }" is similarly affected: it +now defines a function "foo" with tracing enabled; previously it defined +two functions, named "-T" and "foo" (see the MULTI_FUNC_DEF option). + Incompatibilities since 5.7.1 ----------------------------- diff --git a/Src/exec.c b/Src/exec.c index 3c3fcfa3e..2b8e2167f 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5157,23 +5157,25 @@ execfuncdef(Estate state, Eprog redir_prog) { Shfunc shf; char *s = NULL; - int signum, nprg, sbeg, nstrs, npats, len, plen, i, htok = 0, ret = 0; + int signum, nprg, sbeg, nstrs, npats, do_tracing, len, plen, i, htok = 0, ret = 0; int anon_func = 0; Wordcode beg = state->pc, end; Eprog prog; Patprog *pp; LinkList names; + int tracing_flags; end = beg + WC_FUNCDEF_SKIP(state->pc[-1]); names = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok); sbeg = *state->pc++; nstrs = *state->pc++; npats = *state->pc++; - (void) *state->pc++; + do_tracing = *state->pc++; nprg = (end - state->pc); plen = nprg * sizeof(wordcode); len = plen + (npats * sizeof(Patprog)) + nstrs; + tracing_flags = do_tracing ? PM_TAGGED_LOCAL : 0; if (htok && names) { execsubst(names); @@ -5223,7 +5225,7 @@ execfuncdef(Estate state, Eprog redir_prog) shf = (Shfunc) zalloc(sizeof(*shf)); shf->funcdef = prog; - shf->node.flags = 0; + shf->node.flags = tracing_flags; /* No dircache here, not a directory */ shf->filename = ztrdup(scriptfilename); shf->lineno = diff --git a/Src/parse.c b/Src/parse.c index eb32d4faf..dafc8cca6 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -173,7 +173,7 @@ struct heredocs *hdocs; * - followed by offset to first string * - followed by length of string table * - followed by number of patterns for body - * - followed by a placeholder + * - followed by an integer indicating tracing status * - followed by codes for body * - followed by strings for body * - if number of names is 0, followed by: @@ -1670,6 +1670,7 @@ par_funcdef(int *cmplx) int oecused = ecused, num = 0, onp, p, c = 0; int so, oecssub = ecssub; zlong oldlineno = lineno; + int do_tracing = 0; lineno = 0; nocorrect = 1; @@ -1679,6 +1680,12 @@ par_funcdef(int *cmplx) p = ecadd(0); ecadd(0); /* p + 1 */ + if (tok == STRING && tokstr[0] == Dash && + tokstr[1] == 'T' && !tokstr[2]) { + ++do_tracing; + zshlex(); + } + while (tok == STRING) { if ((*tokstr == Inbrace || *tokstr == '{') && !tokstr[1]) { @@ -1732,7 +1739,7 @@ par_funcdef(int *cmplx) ecbuf[p + num + 2] = so - oecssub; ecbuf[p + num + 3] = ecsoffs - so; /* "length of string table" */ ecbuf[p + num + 4] = ecnpats; /* "number of patterns for body" */ - ecbuf[p + num + 5] = 0; + ecbuf[p + num + 5] = do_tracing; ecbuf[p + 1] = num; /* "number of names" */ ecnpats = onp; diff --git a/Test/E02xtrace.ztst b/Test/E02xtrace.ztst index 795f7e616..d72b2d000 100644 --- a/Test/E02xtrace.ztst +++ b/Test/E02xtrace.ztst @@ -180,3 +180,28 @@ > # traced > echo inner >} + + function -T { echo traced anonymous function } + functions -- -T # no output +1:define traced function: anonymous function +?+(anon):0> echo traced anonymous function +>traced anonymous function + + function -T f { echo traced named function } + functions -- -T # no output + functions f + f +0:define traced function: named function +>f () { +> # traced +> echo traced named function +>} +?+f:0> echo traced named function +>traced named function + + function -T -T { echo trace function literally named "-T" } + -T +0:define traced function: parse test +?+-T:0> echo trace function literally named -T +>trace function literally named -T +