From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gatech.edu (gatech.edu [130.207.244.244]) by werple.mira.net.au (8.6.12/8.6.9) with SMTP id EAA02109 for ; Thu, 1 Jun 1995 04:22:27 +1000 Received: from math (math.skiles.gatech.edu) by gatech.edu with SMTP id AA25314 (5.65c/Gatech-10.0-IDA for ); Wed, 31 May 1995 14:20:30 -0400 Received: by math (5.x/SMI-SVR4) id AA24218; Wed, 31 May 1995 13:51:29 -0400 Resent-Date: Wed, 31 May 95 18:45:24 +0100 Old-Return-Path: Message-Id: <8882.9505311745@pyro.swan.ac.uk> To: zsh-workers@math.gatech.edu (Zsh hackers list) Subject: Re: Some bugreports and a fix In-Reply-To: "hzoli@cs.elte.hu"'s message of "Mon, 29 May 95 19:50:34 BST." <9505291750.AA01021@turan.elte.hu> Date: Wed, 31 May 95 18:45:24 +0100 From: P.Stephenson@swansea.ac.uk X-Mts: smtp Resent-Message-Id: <"qX4iC3.0.Kw5.WoApl"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/59 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu I just realised that the three patches I sent fixing the problems below went to Zoltan and not the list because of the new reply behaviour (again). I'm not wasting time reconstructing the original messages, but this should fix all the problems as well as a couple of others: multiple TRAPZERR's in a list didn't work properly and 'return && foo' executed foo when it shouldn't. I made some comments about non-fatal errors and resetting errflag (at the moment there are possible problems with signal handling), too. I think I've found all the bits. hzoli@cs.elte.hu wrote: > There is a similar problem which is not fixed by this patch: > > % let '8#8' ; echo right > > again does not print `right'. That's because execcmd() does not executes > a command if errflag is true. This particular problem can be fixed by > uncommenting the errflag = 0; assignment in exec.c in execlist but it > probably has unwanted side effects. I really do not know this part of > the code so someone more expert should look at it. > > An other bug is that TRAPZERR is not executed in the above cases. > > But TRAPZERR is exectued in other cases when it shouldn't: both > % false || foo=bug > and > % if false; then true; else foo=bug; fi > calls TRAPZERR. I think the problem is that a single assignment does not > reset lastval. > > Also a bug (or sh incompatibility) is that > % false && true > exits the shell if ERR_EXIT is set. It's a problem since foo && bar is > a common idiom in shell scripts. The general idea is that ERR_EXIT and > TRAPZERR should be ignored for a command whose return value is used to > decide wether to execute something or not. *** Src/builtin.c.mer Tue May 30 12:34:09 1995 --- Src/builtin.c Tue May 30 14:00:12 1995 *************** *** 5692,5697 **** --- 5692,5699 ---- while (*argv) val = matheval(*argv++); + /* Errors in math evaluation in let are non-fatal. */ + errflag = 0; return !val; } *** Src/exec.c.vst Thu May 25 10:35:42 1995 --- Src/exec.c Wed May 31 16:10:59 1995 *************** *** 476,502 **** if (sourcelevel && unset(SHINSTDIN)) pline_level = list_pipe = 0; - donetrap = 0; while (list && list != &dummy_list && !breaks && !retflag) { simplifyright(list); slist = list->left; while (slist) { if (slist->type == END) { execpline(slist, list->type, !list->right && exiting); break; } ret = execpline(slist, Z_SYNC, 0); ornext = (slist->type == ORNEXT); if (ornext ^ ret) { alt = ornext ? ANDNEXT : ORNEXT; while ((slist = slist->right)) if (slist->type == alt) break; ! if (!slist) break; } slist = slist->right; --- 476,531 ---- if (sourcelevel && unset(SHINSTDIN)) pline_level = list_pipe = 0; + /* + * Loop over all sets of comands separated by newline, + * semi-colon or ampersand (`sublists'). + */ while (list && list != &dummy_list && !breaks && !retflag) { + /* + * Reset donetrap: this ensures that a trap is only called + * once for each sublist that fails. + */ + donetrap = 0; simplifyright(list); slist = list->left; while (slist) { + /* + * Loop through code followed by &&, ||, or end of sublist. + */ if (slist->type == END) { + /* End of sublist; just execute, ignoring status. */ execpline(slist, list->type, !list->right && exiting); break; } ret = execpline(slist, Z_SYNC, 0); + /* + * Next pipeline is either or'd or and'd with this one; + * find which. + */ ornext = (slist->type == ORNEXT); if (ornext ^ ret) { + /* + * If either (1) it's an or, and the return code + * was zero, or (2) it's an and, and the return + * code was non-zero, skip pipelines until we find + * a sublist followed by the opposite type. + */ alt = ornext ? ANDNEXT : ORNEXT; while ((slist = slist->right)) if (slist->type == alt) break; ! if (!slist) { ! /* ! * We've skipped to the end of the list, not executing ! * the final pipeline, so don't perform error handling ! * for this sublist. ! */ ! donetrap = 1; break; + } } slist = slist->right; *************** *** 505,510 **** --- 534,543 ---- if (sigtrapped[SIGDEBUG]) dotrap(SIGDEBUG); if (sourcelevel < 32768 && !donetrap) { + /* + * Only perform traps/errorexit if not in initialisation + * scripts, and if we haven't performed them for this sublist. + */ if (sigtrapped[SIGZERR] && lastval) { dotrap(SIGZERR); donetrap = 1; *************** *** 710,716 **** int pipes[2]; int oldlineno = lineno; ! if (breaks) return; if (!pline) return; --- 743,749 ---- int pipes[2]; int oldlineno = lineno; ! if (breaks || retflag) return; if (!pline) return; *************** *** 1041,1048 **** addnode(args, dupstring(nullcmd)); else { addvars(cmd->vars, 0); ! if (errflag) ! lastval = 1; if (isset(XTRACE)) { fputc('\n', stderr); fflush(stderr); --- 1074,1080 ---- addnode(args, dupstring(nullcmd)); else { addvars(cmd->vars, 0); ! lastval = errflag; if (isset(XTRACE)) { fputc('\n', stderr); fflush(stderr); -- Peter Stephenson Tel: +44 1792 205678 extn. 4461 WWW: http://python.swan.ac.uk/~pypeters/ Fax: +44 1792 295324 Department of Physics, University of Wales, Swansea, Singleton Park, Swansea, SA2 8PP, U.K.