45583/0008: Add the 'function -T' syntax.

Config/version.mk was bumped in the previous commit.
This commit is contained in:
Daniel Shahaf 2020-03-19 18:00:16 +00:00
parent a3c6c5513d
commit 386d9ac8ff
6 changed files with 61 additions and 6 deletions

View file

@ -1,5 +1,8 @@
2020-03-22 Daniel Shahaf <d.s@daniel.shahaf.name>
* 45583/0008: Doc/Zsh/grammar.yo, README, Src/exec.c,
Src/parse.c, Test/E02xtrace.ztst: Add the 'function -T' syntax.
* 45583/0007: Config/version.mk, Src/exec.c, Src/parse.c,
Src/text.c: WC_FUNCDEF: Add a placeholder element.

View file

@ -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

7
README
View file

@ -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
-----------------------------

View file

@ -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 =

View file

@ -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;

View file

@ -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