summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/exec.c32
-rw-r--r--Src/zsh.h11
2 files changed, 36 insertions, 7 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 487838a25..1d07bffcf 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -866,6 +866,35 @@ execlist(Estate state, int dont_change_job, int exiting)
     code = *state->pc++;
     while (wc_code(code) == WC_LIST && !breaks && !retflag) {
 	int donedebug;
+
+	ltype = WC_LIST_TYPE(code);
+	csp = cmdsp;
+
+	if ((!intrap || trapisfunc) && !ineval) {
+	    /*
+	     * Ensure we have a valid line number for debugging,
+	     * unless we are in an evaluated trap in which case
+	     * we retain the line number from the context.
+	     * This was added for DEBUGBEFORECMD but I've made
+	     * it unconditional to keep dependencies to a minimum.
+	     *
+	     * The line number is updated for individual pipelines.
+	     * This isn't necessary for debug traps since they only
+	     * run once per sublist.
+	     */
+	    wordcode code2 = *state->pc, lnp1 = 0;
+	    if (ltype & Z_SIMPLE) {
+		lnp1 = code2;
+	    } else if (wc_code(code2) == WC_SUBLIST) {
+		if (WC_SUBLIST_FLAGS(code2) == WC_SUBLIST_SIMPLE)
+		    lnp1 = state->pc[2];
+		else
+		    lnp1 = WC_PIPE_LINENO(state->pc[1]);
+	    }
+	    if (lnp1)
+		lineno = lnp1 - 1;
+	}
+
 	if (sigtrapped[SIGDEBUG] && isset(DEBUGBEFORECMD)) {
 	    exiting = donetrap;
 	    ret = lastval;
@@ -881,9 +910,6 @@ execlist(Estate state, int dont_change_job, int exiting)
 	} else
 	    donedebug = 0;
 
-	ltype = WC_LIST_TYPE(code);
-	csp = cmdsp;
-
 	if (ltype & Z_SIMPLE) {
 	    next = state->pc + WC_LIST_SKIP(code);
 	    execsimple(state);
diff --git a/Src/zsh.h b/Src/zsh.h
index 6f70fd0df..27c344809 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -703,8 +703,9 @@ struct eccstr {
 #define WC_LIST_TYPE(C)     wc_data(C)
 #define Z_END               (1<<4) 
 #define Z_SIMPLE            (1<<5)
-#define WC_LIST_SKIP(C)     (wc_data(C) >> 6)
-#define WCB_LIST(T,O)       wc_bld(WC_LIST, ((T) | ((O) << 6)))
+#define WC_LIST_FREE        (6)	/* Next bit available in integer */
+#define WC_LIST_SKIP(C)     (wc_data(C) >> WC_LIST_FREE)
+#define WCB_LIST(T,O)       wc_bld(WC_LIST, ((T) | ((O) << WC_LIST_FREE)))
 
 #define WC_SUBLIST_TYPE(C)  (wc_data(C) & ((wordcode) 3))
 #define WC_SUBLIST_END      0
@@ -714,8 +715,10 @@ struct eccstr {
 #define WC_SUBLIST_COPROC   4
 #define WC_SUBLIST_NOT      8
 #define WC_SUBLIST_SIMPLE  16
-#define WC_SUBLIST_SKIP(C)  (wc_data(C) >> 5)
-#define WCB_SUBLIST(T,F,O)  wc_bld(WC_SUBLIST, ((T) | (F) | ((O) << 5)))
+#define WC_SUBLIST_FREE    (5)	/* Next bit available in integer */
+#define WC_SUBLIST_SKIP(C)  (wc_data(C) >> WC_SUBLIST_FREE)
+#define WCB_SUBLIST(T,F,O)  wc_bld(WC_SUBLIST, \
+				   ((T) | (F) | ((O) << WC_SUBLIST_FREE)))
 
 #define WC_PIPE_TYPE(C)     (wc_data(C) & ((wordcode) 1))
 #define WC_PIPE_END         0