Great! It will go into git source in zshdb over the weekend. Thanks. On Thu, Sep 4, 2008 at 12:56 PM, Peter Stephenson 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 Software Engineer > CSR PLC, Churchill House, Cambridge Business Park, Cowley Road > Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 >