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

PATCH: $ZSH_DEBUG_CMD



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



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