about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/builtins.yo16
-rw-r--r--Doc/Zsh/func.yo10
-rw-r--r--Src/exec.c7
-rw-r--r--Src/text.c12
-rw-r--r--Test/C05debug.ztst25
6 files changed, 65 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 744a03213..dc1a78ce1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-09-05  Peter Stephenson  <pws@csr.com>
+
+	* 25615: Doc/Zsh/builtins.yo, Doc/Zsh/func.yo, Src/exec.c,
+	Src/text.c, Test/C05debug.ztst: add $ZSH_DEBUG_CMD for
+	DEBUG traps.
+
 2008-09-04  Peter Stephenson  <pws@csr.com>
 
 	* 25608: Completion/compinit: unset CSH_JUNKIE_QUOTES during
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index f8ee29a24..c47ae49e7 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -1307,11 +1307,19 @@ usual case).
 
 If var(sig) is tt(DEBUG) then var(arg) will be executed
 before each command if the option tt(DEBUG_BEFORE_CMD) is set
-(as it is by default), else after each command.  In the former
-case it is possible to skip the next command; see
-the description of the tt(ERR_EXIT) option in
+(as it is by default), else after each command.  Here, a `command' is
+what is described as a `sublist' in the shell grammar, see
+ifnzman(noderef(Simple Commands & Pipelines))\
+ifzman(the section SIMPLE COMMANDS & PIPELINES in zmanref(zshmisc)).
+If tt(DEBUG_BEFORE_CMD) is set various additional features are available.
+First, it is possible to skip the next command by setting the option
+tt(ERR_EXIT); see the description of the tt(ERR_EXIT) option in
 ifzman(zmanref(zshoptions))\
-ifnzman(noderef(Description of Options)).
+ifnzman(noderef(Description of Options)).  Also, the shell parameter
+tt(ZSH_DEBUG_CMD) is set to the string corresponding to the command
+to be executed following the trap.  Note that this string is reconstructed
+from the internal format and may not be formatted the same way as the
+original text.  The parameter is unset after the trap is executed.
 
 If var(sig) is tt(0) or tt(EXIT)
 and the tt(trap) statement is executed inside the body of a function,
diff --git a/Doc/Zsh/func.yo b/Doc/Zsh/func.yo
index 888cf3ce2..aaac5fa5a 100644
--- a/Doc/Zsh/func.yo
+++ b/Doc/Zsh/func.yo
@@ -309,11 +309,11 @@ executed inside other traps.
 findex(TRAPDEBUG)
 item(tt(TRAPDEBUG))(
 If the option tt(DEBUG_BEFORE_CMD) is set (as it is by default), executed
-before each command; otherwise executed after each command.  In the former
-case it is possible to skip the next command; see the description of the
-tt(ERR_EXIT) option in
-ifzman(zmanref(zshoptions))\
-ifnzman(noderef(Description of Options)).
+before each command; otherwise executed after each command.  See
+the description of the tt(trap) builtin in
+ifnzman(noderef(Shell Builtin Commands))\
+ifzman(zmanref(zshbuiltins)) for details of additional features provided
+in debug traps.
 )
 findex(TRAPEXIT)
 item(tt(TRAPEXIT))(
diff --git a/Src/exec.c b/Src/exec.c
index a46dfd683..a147dacd5 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1069,9 +1069,14 @@ execlist(Estate state, int dont_change_job, int exiting)
 	}
 
 	if (sigtrapped[SIGDEBUG] && isset(DEBUGBEFORECMD) && !intrap) {
+	    Wordcode pc2 = state->pc;
 	    int oerrexit_opt = opts[ERREXIT];
+	    Param pm;
 	    opts[ERREXIT] = 0;
 	    noerrexit = 1;
+	    if (ltype & Z_SIMPLE) /* skip the line number */
+		pc2++;
+	    pm = setsparam("ZSH_DEBUG_CMD", getpermtext(state->prog, pc2));
 
 	    exiting = donetrap;
 	    ret = lastval;
@@ -1085,6 +1090,8 @@ execlist(Estate state, int dont_change_job, int exiting)
 	     */
 	    donedebug = isset(ERREXIT) ? 2 : 1;
 	    opts[ERREXIT] = oerrexit_opt;
+	    if (pm)
+		unsetparam_pm(pm, 0, 1);
 	} else
 	    donedebug = intrap ? 1 : 0;
 
diff --git a/Src/text.c b/Src/text.c
index 7fdc5757f..eabb51268 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -135,7 +135,6 @@ getpermtext(Eprog prog, Wordcode c)
     tbuf = (char *)zalloc(tsiz = 32);
     tptr = tbuf;
     tlim = tbuf + tsiz;
-    tindent = 1;
     tjob = 0;
     if (prog->len)
 	gettext2(&s);
@@ -167,7 +166,6 @@ getjobtext(Eprog prog, Wordcode c)
     tbuf = NULL;
     tptr = jbuf;
     tlim = tptr + JOBTEXTSIZE - 1;
-    tindent = 1;
     tjob = 1;
     gettext2(&s);
     *tptr = '\0';
@@ -247,6 +245,16 @@ gettext2(Estate state)
     int stack = 0;
     wordcode code;
 
+    /*
+     * Hack for parsing "simple" format of function definitions.
+     * In this case there is no surrounding context so the initial
+     * indent should be zero.
+     */
+    if (wc_code(*state->pc) == WC_FUNCDEF)
+	tindent = 0;
+    else
+	tindent = 1;
+
     while (1) {
 	if (stack) {
 	    if (!(s = tstack))
diff --git a/Test/C05debug.ztst b/Test/C05debug.ztst
index a6ef54bb4..6594eb8a1 100644
--- a/Test/C05debug.ztst
+++ b/Test/C05debug.ztst
@@ -112,3 +112,28 @@
 >    second
 >    third
 
+  fn() {
+    emulate -L zsh; setopt debugbeforecmd
+    trap 'print "$LINENO: '\''$ZSH_DEBUG_CMD'\''"' DEBUG
+    print foo &&
+    print bar ||
+    print rod
+    x=y
+    print $x
+    fn2() { echo wow }
+    fn2
+  }
+  fn
+0:ZSH_DEBUG_CMD in debug traps
+>3: 'print foo && print bar || print rod'
+>foo
+>bar
+>6: 'x=y '
+>7: 'print $x'
+>y
+>8: 'fn2 () {
+>	echo wow
+>}'
+>9: 'fn2'
+>0: 'echo wow'
+>wow