Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [BUG] Anonymous functions cause funcfiletrace to produce function-relative line numbers



On Mon, 11 Dec 2017 15:57:06 -0600
dana <dana@xxxxxxx> wrote:
> On 11 Dec 2017, at 04:12, Peter Stephenson <p.stephenson@xxxxxxxxxxx> wrote:
> > Oops, try this instead.
>   panic() {
>     print -rC2 -- $functrace $funcfiletrace
>     exit 1
>   }
>   puts() {
>     panic
>   }
>   main() {
>     () { puts }
>   }
>   main
> 
> The output, after applying the patch:
> 
>   puts:1            tracetest.zsh:15
>   (anon):0          tracetest.zsh:9
>   main:1            tracetest.zsh:9
>   tracetest.zsh:11  tracetest.zsh:11

Hmm... it looks like anonymous functions do need special handling after
all, for reasons I haven't put my finger on but will be down to the
different relationship between the point of definition and point of
execution compared with normal functions.

See if this helps...

BTW this also implements one of the (trivial in this case) bits I
proposed for Daniel's problem.

Needs a test; this is very easy to break.

pws

diff --git a/Src/exec.c b/Src/exec.c
index 664d790..a3ac3b1 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -5104,6 +5104,7 @@ execfuncdef(Estate state, Eprog redir_prog)
 	    LinkList args;
 
 	    anon_func = 1;
+	    shf->node.flags |= PM_ANONYMOUS;
 
 	    state->pc = end;
 	    end += *state->pc++;
@@ -5669,11 +5670,13 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
 	funcsave->fstack.caller = funcstack ? funcstack->name :
 	    dupstring(funcsave->argv0 ? funcsave->argv0 : argzero);
 	funcsave->fstack.lineno = lineno;
+	funcsave->fstack.flineno = shfunc->lineno;
+	if (funcstack && (shfunc->node.flags & PM_ANONYMOUS))
+	    funcsave->fstack.flineno += funcstack->flineno;
 	funcsave->fstack.prev = funcstack;
 	funcsave->fstack.tp = FS_FUNC;
 	funcstack = &funcsave->fstack;
 
-	funcsave->fstack.flineno = shfunc->lineno;
 	funcsave->fstack.filename = getshfuncfile(shfunc);
 
 	prog = shfunc->funcdef;
diff --git a/Src/zsh.h b/Src/zsh.h
index 24d06ba..22ae954 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1875,6 +1875,7 @@ struct tieddata {
 #define PM_DONTIMPORT_SUID (1<<19) /* do not import if running setuid */
 #define PM_LOADDIR      (1<<19) /* (function) filename gives load directory */
 #define PM_SINGLE       (1<<20) /* special can only have a single instance  */
+#define PM_ANONYMOUS    (1<<20) /* (function) anonymous function            */
 #define PM_LOCAL	(1<<21) /* this parameter will be made local        */
 #define PM_SPECIAL	(1<<22) /* special builtin parameter                */
 #define PM_DONTIMPORT	(1<<23)	/* do not import this variable              */



Messages sorted by: Reverse Date, Date, Thread, Author