From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5221 invoked from network); 6 Aug 2008 17:01:21 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.5 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 6 Aug 2008 17:01:21 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 95747 invoked from network); 6 Aug 2008 17:01:03 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 6 Aug 2008 17:01:03 -0000 Received: (qmail 19448 invoked by alias); 6 Aug 2008 17:00:42 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 25406 Received: (qmail 19420 invoked from network); 6 Aug 2008 17:00:39 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 6 Aug 2008 17:00:39 -0000 Received: from py-out-1112.google.com (py-out-1112.google.com [64.233.166.179]) by bifrost.dotsrc.org (Postfix) with ESMTP id B920A8056E06 for ; Wed, 6 Aug 2008 19:00:31 +0200 (CEST) Received: by py-out-1112.google.com with SMTP id u77so6104pyb.23 for ; Wed, 06 Aug 2008 10:00:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:in-reply-to:mime-version:content-type :content-transfer-encoding:content-disposition:references; bh=SRUjaNlO4X99SunaXHXVopox6RwY+MnZRrJLpnBU6UM=; b=q3OX+QYhm+lmY8n3tI6FgRJwR4fAeZP90+9E3GnWSdcJsxfWReXwMAieIFQdTDenQY q6OhdjwVqUoKQBJVidk5Gt4Isx0KZPTLGOrHd7t1HqZ7KaKdbmNTjRakYZuGpm0magkh Q6J4qobXS42ChV2F0qMHIfkk/hPhdbsIEcSIY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version :content-type:content-transfer-encoding:content-disposition :references; b=Nb8qz+dpMAxXJs6IidtvEeWH2OenOJOqR6HDKiJoEAek09+fGdHwisJxF5tzTrQzwf kkeRGBAZCnPe80Hw4xIOVYhyGJ5SW6KoGbfrvkuzdjrOOc2HEFBq5/vIOpC808dc4KEQ RLK3OKMB4CqFScOECyTq5uVdQ3WX4NeDmB09A= Received: by 10.114.151.13 with SMTP id y13mr558564wad.134.1218042028485; Wed, 06 Aug 2008 10:00:28 -0700 (PDT) Received: by 10.114.159.2 with HTTP; Wed, 6 Aug 2008 10:00:28 -0700 (PDT) Message-ID: <6cd6de210808061000l5c6e0a8fheb06db75560a1598@mail.gmail.com> Date: Wed, 6 Aug 2008 13:00:28 -0400 From: "Rocky Bernstein" To: "Zsh hackers list" Subject: Re: PATCH: skip command from debug trap In-Reply-To: <20080806104716.44647a75@news01> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <27237.1217946438@csr.com> <6cd6de210808051647k17f14902nce840ca3edd6ddb@mail.gmail.com> <20080806104716.44647a75@news01> X-Virus-Scanned: ClamAV 0.92.1/7959/Wed Aug 6 15:06:37 2008 on bifrost X-Virus-Status: Clean On Wed, Aug 6, 2008 at 5:47 AM, Peter Stephenson wrote: > On Tue, 5 Aug 2008 19:47:12 -0400 > "Rocky Bernstein" wrote: >> First and foremost, thanks for the change. >> >> When I first read this I was eager to try it out. So I rushed to apply >> the patch and put in a "skip" command. When this didn't work I then >> reread - there is more unfinished work? > > Yes. There are about four cases: in a script, in a function, debugging > trap is inline, debugging trap is a function. This now covers all four > cases. (I'll need to add tests for all.) > > I've now got the following to work as a script and a function: > > trap '[[ $LINENO = 3 ]] && return 255' DEBUG; print $$; sleep 5 > print $LINENO two > print $LINENO three > print $LINENO four > > prints "2 two" and "4 four". It also works if the top line is replaced > with > > integer l=0; TRAPDEBUG() { (( l++ == 3 )) && return 255 }; print $$; sleep 5 > > (it's documented that LINENO in a trap function applies to the function > itself, as with any other function). > >> I'm not fussy about the number used. I don't understand why 255 is any >> more special than say 4366 as a return from the TRAP instruction, but >> 255 is okay. >> >> And if one wants to use a negative number I don't see why that can't >> be accommodated for either. > > An option to "return" is quite tempting. This separates out this behaviour > from any other. It removes any reliance on obscure numerology. Others have noted the challenges in adding an option to return. Making the semantics of the return statement already more complicated doesn't seem wise. A couple other approaches are setting a variable or calling a routine. For example "trap_return --skip" or TRAP_RETURN="skip" > It makes it > quite explicit this particular mechanism is in use. Currently return > doesn't take options at all, so the result is also completely compatible > with existing versions. (In fact, the lack of option parsing, even --, in > return is strictly a bug, so this even makes it more compatible with other > shells.) > > Stephane's suggestions don't really work: we don't have an exception > framework, and at this level we are dealing in parsed command structures, > not text. > > > Index: README > =================================================================== > RCS file: /cvsroot/zsh/zsh/README,v > retrieving revision 1.53 > diff -u -r1.53 README > --- README 1 Jun 2008 18:35:50 -0000 1.53 > +++ README 6 Aug 2008 09:43:20 -0000 > @@ -56,6 +56,12 @@ > applies to expressions with forced splitting such as ${=1+"$@"}, but > otherwise the case where SH_WORD_SPLIT is not set is unaffected. > > +Debug traps (`trap ... DEBUG' or the function TRAPDEBUG) now run by default > +before the command to which they refer instead of after. This is almost > +always the right behaviour for the intended purpose of debugging and is > +consistent with recent versions of other shells. The option > +DEBUG_BEFORE_CMD can be unset to revert to the previous behaviour. > + > In previous versions of the shell it was possible to use index 0 in an > array or string subscript to refer to the same element as index 1 if the > option KSH_ARRAYS was not in effect. This was a limited approximation to > Index: Doc/Zsh/builtins.yo > =================================================================== > RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v > retrieving revision 1.108 > diff -u -r1.108 builtins.yo > --- Doc/Zsh/builtins.yo 10 Jun 2008 08:50:36 -0000 1.108 > +++ Doc/Zsh/builtins.yo 6 Aug 2008 09:43:21 -0000 > @@ -1301,8 +1301,13 @@ > after each command with a nonzero exit status. tt(ERR) is an alias > for tt(ZERR) on systems that have no tt(SIGERR) signal (this is the > usual case). > + > If var(sig) is tt(DEBUG) then var(arg) will be executed > -after each command. > +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, > +executing a tt(return) with the value of 255 within the trap causes > +the command referred to to be skipped. > + > If var(sig) is tt(0) or tt(EXIT) > and the tt(trap) statement is executed inside the body of a function, > then the command var(arg) is executed after the function completes. > Index: Doc/Zsh/func.yo > =================================================================== > RCS file: /cvsroot/zsh/zsh/Doc/Zsh/func.yo,v > retrieving revision 1.20 > diff -u -r1.20 func.yo > --- Doc/Zsh/func.yo 30 Jul 2008 19:46:20 -0000 1.20 > +++ Doc/Zsh/func.yo 6 Aug 2008 09:43:21 -0000 > @@ -308,8 +308,10 @@ > ) > findex(TRAPDEBUG) > item(tt(TRAPDEBUG))( > -Executed after each command. If the option tt(DEBUG_BEFORE_CMD) > -is set, executed before each command instead. > +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, returning the value 255 from the trap function causes > +execution of the command to be skipped. > ) > findex(TRAPEXIT) > item(tt(TRAPEXIT))( > Index: Doc/Zsh/options.yo > =================================================================== > RCS file: /cvsroot/zsh/zsh/Doc/Zsh/options.yo,v > retrieving revision 1.61 > diff -u -r1.61 options.yo > --- Doc/Zsh/options.yo 12 Jun 2008 13:45:05 -0000 1.61 > +++ Doc/Zsh/options.yo 6 Aug 2008 09:43:21 -0000 > @@ -1046,7 +1046,7 @@ > ifzman(the section ARITHMETIC EVALUATION in zmanref(zshmisc)) > has an explicit list. > ) > -pindex(DEBUG_BEFORE_CMD) > +pindex(DEBUG_BEFORE_CMD ) > cindex(traps, DEBUG, before or after command) > cindex(DEBUG trap, before or after command) > item(tt(DEBUG_BEFORE_CMD))( > Index: Src/builtin.c > =================================================================== > RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v > retrieving revision 1.200 > diff -u -r1.200 builtin.c > --- Src/builtin.c 31 Jul 2008 08:44:20 -0000 1.200 > +++ Src/builtin.c 6 Aug 2008 09:43:22 -0000 > @@ -4458,6 +4458,16 @@ > breaks = nump ? minimum(num,loops) : 1; > break; > case BIN_RETURN: > + if (trapreturn == -2 && num == 255) { > + /* skip a single command */ > + trapreturn = lastval = num; > + if (trapisfunc) { > + /* If trap is a function, return from that first */ > + retflag = 1; > + breaks = loops; > + } > + return lastval; > + } > if (isset(INTERACTIVE) || locallevel || sourcelevel) { > retflag = 1; > breaks = loops; > Index: Src/exec.c > =================================================================== > RCS file: /cvsroot/zsh/zsh/Src/exec.c,v > retrieving revision 1.136 > diff -u -r1.136 exec.c > --- Src/exec.c 1 Aug 2008 13:53:44 -0000 1.136 > +++ Src/exec.c 6 Aug 2008 09:43:22 -0000 > @@ -1061,6 +1061,9 @@ > } > > if (sigtrapped[SIGDEBUG] && isset(DEBUGBEFORECMD)) { > + int otrapskip = trapskip; > + trapskip = 0; > + > exiting = donetrap; > ret = lastval; > dotrap(SIGDEBUG); > @@ -1071,7 +1074,8 @@ > * Only execute the trap once per sublist, even > * if the DEBUGBEFORECMD option changes. > */ > - donedebug = 1; > + donedebug = trapskip ? 2 : 1; > + trapskip = otrapskip; > } else > donedebug = 0; > > @@ -1087,6 +1091,18 @@ > > /* Loop through code followed by &&, ||, or end of sublist. */ > code = *state->pc++; > + if (donedebug == 2) { > + /* Skip sublist. */ > + while (wc_code(code) == WC_SUBLIST) { > + state->pc = state->pc + WC_SUBLIST_SKIP(code); > + if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END) > + break; > + code = *state->pc++; > + } > + donetrap = 1; > + /* yucky but consistent... */ > + goto sublist_done; > + } > while (wc_code(code) == WC_SUBLIST) { > next = state->pc + WC_SUBLIST_SKIP(code); > if (!oldnoerrexit) > Index: Src/options.c > =================================================================== > RCS file: /cvsroot/zsh/zsh/Src/options.c,v > retrieving revision 1.43 > diff -u -r1.43 options.c > --- Src/options.c 31 Jul 2008 08:44:21 -0000 1.43 > +++ Src/options.c 6 Aug 2008 09:43:22 -0000 > @@ -112,7 +112,7 @@ > {{NULL, "cshjunkiequotes", OPT_EMULATE|OPT_CSH}, CSHJUNKIEQUOTES}, > {{NULL, "cshnullcmd", OPT_EMULATE|OPT_CSH}, CSHNULLCMD}, > {{NULL, "cshnullglob", OPT_EMULATE|OPT_CSH}, CSHNULLGLOB}, > -{{NULL, "debugbeforecmd", OPT_EMULATE}, DEBUGBEFORECMD}, > +{{NULL, "debugbeforecmd", OPT_ALL}, DEBUGBEFORECMD}, > {{NULL, "emacs", 0}, EMACSMODE}, > {{NULL, "equals", OPT_EMULATE|OPT_ZSH}, EQUALS}, > {{NULL, "errexit", OPT_EMULATE}, ERREXIT}, > Index: Src/signals.c > =================================================================== > RCS file: /cvsroot/zsh/zsh/Src/signals.c,v > retrieving revision 1.48 > diff -u -r1.48 signals.c > --- Src/signals.c 1 Aug 2008 13:53:45 -0000 1.48 > +++ Src/signals.c 6 Aug 2008 09:43:22 -0000 > @@ -1076,6 +1076,11 @@ > /**/ > int trapisfunc; > > +/* Signal to list code that we should skip the next statement. */ > + > +/**/ > +int trapskip; > + > /**/ > void > dotrapargs(int sig, int *sigtr, void *sigfn) > @@ -1165,7 +1170,9 @@ > } > runhookdef(AFTERTRAPHOOK, NULL); > > - if (trapreturn > 0 && isfunc) { > + if (trapreturn == 255 && sig == SIGDEBUG) { > + trapskip = 1; > + } else if (trapreturn > 0 && isfunc) { > /* > * Context was its own function. We propagate the return > * value specially. Return value zero means don't do > @@ -1188,7 +1195,7 @@ > execrestore(); > lexrestore(); > > - if (trapret > 0) { > + if (!trapskip && trapret > 0) { > if (isfunc) { > breaks = loops; > errflag = 1; > >