From e3fd25b18198709348af195dedadaceb88feb568 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 29 Sep 2008 21:46:58 +0000 Subject: 25775: fix logical problem with function line numbering inside eval-style traps --- ChangeLog | 6 ++++++ Src/exec.c | 8 +++++--- Src/prompt.c | 4 ++-- Src/signals.c | 8 ++++++++ Src/zsh.h | 4 ++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 660088c50..ea1e497c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-09-29 Peter Stephenson + * 25775: Src/exec.c, Src/prompt.c, Src/signals.c, Src/zsh.h: + line numbering in functions inside eval-style traps on the + function stack was screwy. Simplest fix is to restore normal + line numbering within the functions so that only the immediate + eval-style trap environment is special. + * 25774: Src/params.c: fix in 25772 was applied too widely. 2008-09-29 Peter Stephenson diff --git a/Src/exec.c b/Src/exec.c index bf23a34da..1685c799e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -992,7 +992,7 @@ execsimple(Estate state) return (lastval = 1); /* In evaluated traps, don't modify the line number. */ - if ((!intrap || trapisfunc) && !ineval && code) + if (!IN_EVAL_TRAP() && !ineval && code) lineno = code - 1; code = wc_code(*state->pc++); @@ -1053,7 +1053,7 @@ execlist(Estate state, int dont_change_job, int exiting) ltype = WC_LIST_TYPE(code); csp = cmdsp; - if ((!intrap || trapisfunc) && !ineval) { + if (!IN_EVAL_TRAP() && !ineval) { /* * Ensure we have a valid line number for debugging, * unless we are in an evaluated trap in which case @@ -1543,7 +1543,7 @@ execpline2(Estate state, wordcode pcode, return; /* In evaluated traps, don't modify the line number. */ - if ((!intrap || trapisfunc) && !ineval && WC_PIPE_LINENO(pcode)) + if (!IN_EVAL_TRAP() && !ineval && WC_PIPE_LINENO(pcode)) lineno = WC_PIPE_LINENO(pcode) - 1; if (pline_level == 1) { @@ -4628,6 +4628,7 @@ execsave(void) es->trap_return = trap_return; es->trap_state = trap_state; es->trapisfunc = trapisfunc; + es->traplocallevel = traplocallevel; es->noerrs = noerrs; es->subsh_close = subsh_close; es->underscore = ztrdup(underscore); @@ -4657,6 +4658,7 @@ execrestore(void) trap_return = exstack->trap_return; trap_state = exstack->trap_state; trapisfunc = exstack->trapisfunc; + traplocallevel = exstack->traplocallevel; noerrs = exstack->noerrs; subsh_close = exstack->subsh_close; setunderscore(exstack->underscore); diff --git a/Src/prompt.c b/Src/prompt.c index 870632ec5..80547e419 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -727,7 +727,7 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) break; case 'I': if (funcstack && funcstack->tp != FS_SOURCE && - (!intrap || trapisfunc)) { + !IN_EVAL_TRAP()) { /* * We're in a function or an eval with * EVALLINENO. Calculate the line number in @@ -751,7 +751,7 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) break; case 'x': if (funcstack && funcstack->tp != FS_SOURCE && - (!intrap || trapisfunc)) + !IN_EVAL_TRAP()) promptpath(funcstack->filename ? funcstack->filename : "", arg, 0); else diff --git a/Src/signals.c b/Src/signals.c index 2cedeb2b9..ac5ffaa21 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -1076,6 +1076,13 @@ int intrap; /**/ int trapisfunc; +/* + * If the current trap is not a function, at what function depth + * did the trap get called? + */ +/**/ +int traplocallevel; + /* * sig is the signal number. * *sigtr is the value to be taken as the field in sigtrapped (since @@ -1132,6 +1139,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) /* execsave will save the old trap_return and trap_state */ execsave(); breaks = retflag = 0; + traplocallevel = locallevel; runhookdef(BEFORETRAPHOOK, NULL); if (*sigtr & ZSIG_FUNC) { int osc = sfcontext; diff --git a/Src/zsh.h b/Src/zsh.h index ddbf24048..2ceab1dca 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -924,6 +924,7 @@ struct execstack { int trap_return; int trap_state; int trapisfunc; + int traplocallevel; int noerrs; int subsh_close; char *underscore; @@ -2261,6 +2262,9 @@ enum trap_state { TRAP_STATE_FORCE_RETURN }; +#define IN_EVAL_TRAP() \ + (intrap && !trapisfunc && traplocallevel == locallevel) + /***********/ /* Sorting */ /***********/ -- cgit 1.4.1