Great! It will go into git source in zshdb over the weekend. Thanks.
On Thu, Sep 4, 2008 at 12:56 PM, Peter Stephenson
<pws@xxxxxxx> wrote:
This adds the variable ZSH_DEBUG_CMD which gives the code about to be
executed in a DEBUG trap (as long as DEBUG_BEFORE_CMD is set).
The key changes took about 30 seconds, working out what was going on
with the "simple" parse tree optimization for assignments and function
definitions took hours.
Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.111
diff -u -r1.111 builtins.yo
--- Doc/Zsh/builtins.yo 11 Aug 2008 09:20:38 -0000 1.111
+++ Doc/Zsh/builtins.yo 4 Sep 2008 16:51:04 -0000
@@ -1307,11 +1307,19 @@
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,
Index: Doc/Zsh/func.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/func.yo,v
retrieving revision 1.22
diff -u -r1.22 func.yo
--- Doc/Zsh/func.yo 11 Aug 2008 09:18:20 -0000 1.22
+++ Doc/Zsh/func.yo 4 Sep 2008 16:51:04 -0000
@@ -309,11 +309,11 @@
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))(
Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.146
diff -u -r1.146 exec.c
--- Src/exec.c 3 Sep 2008 09:08:22 -0000 1.146
+++ Src/exec.c 4 Sep 2008 16:51:05 -0000
@@ -1069,9 +1069,14 @@
}
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 @@
*/
donedebug = isset(ERREXIT) ? 2 : 1;
opts[ERREXIT] = oerrexit_opt;
+ if (pm)
+ unsetparam_pm(pm, 0, 1);
} else
donedebug = intrap ? 1 : 0;
Index: Src/text.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/text.c,v
retrieving revision 1.22
diff -u -r1.22 text.c
--- Src/text.c 14 Mar 2008 11:40:59 -0000 1.22
+++ Src/text.c 4 Sep 2008 16:51:05 -0000
@@ -135,7 +135,6 @@
tbuf = (char *)zalloc(tsiz = 32);
tptr = tbuf;
tlim = tbuf + tsiz;
- tindent = 1;
tjob = 0;
if (prog->len)
gettext2(&s);
@@ -167,7 +166,6 @@
tbuf = NULL;
tptr = jbuf;
tlim = tptr + JOBTEXTSIZE - 1;
- tindent = 1;
tjob = 1;
gettext2(&s);
*tptr = '\0';
@@ -247,6 +245,16 @@
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))
Index: Test/C05debug.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/C05debug.ztst,v
retrieving revision 1.1
diff -u -r1.1 C05debug.ztst
--- Test/C05debug.ztst 31 Aug 2008 19:50:49 -0000 1.1
+++ Test/C05debug.ztst 4 Sep 2008 16:51:06 -0000
@@ -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
--
Peter Stephenson <pws@xxxxxxx> Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070