diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | Src/exec.c | 6 | ||||
-rw-r--r-- | Src/init.c | 27 | ||||
-rw-r--r-- | Src/zsh.h | 11 | ||||
-rw-r--r-- | Test/A01grammar.ztst | 6 | ||||
-rw-r--r-- | Test/C04funcdef.ztst | 7 | ||||
-rw-r--r-- | Test/D08cmdsubst.ztst | 5 |
7 files changed, 64 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog index bf21bd718..4fbb406f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-07-11 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 27129: Src/exec.c, Src/init.c, Src/zsh.h, + Test/A01grammar.ztst, Test/C04funcdef.ztst, + Test/D08cmdsubst.ztst: fix 27126 so as not to break the + case where a status is tested at the start of a function, + command substitution, or "." file. + 2009-07-10 Clint Adams <clint@zsh.org> * 27127: Vincent Bernat: Completion/Debian/Command/_bts: handle @@ -11959,5 +11967,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.4736 $ +* $Revision: 1.4737 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index 0788ecbb9..67d48b1ce 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1056,6 +1056,10 @@ execlist(Estate state, int dont_change_job, int exiting) /* Loop over all sets of comands separated by newline, * * semi-colon or ampersand (`sublists'). */ code = *state->pc++; + if (wc_code(code) != WC_LIST) { + /* Empty list; this returns status zero. */ + lastval = 0; + } while (wc_code(code) == WC_LIST && !breaks && !retflag && !errflag) { int donedebug; @@ -3513,7 +3517,6 @@ getoutput(char *cmd, int qt) return retval; } /* pid == 0 */ - lastval = 0; /* status of empty list is zero */ child_unblock(); zclose(pipes[0]); redup(pipes[1], 1); @@ -4261,7 +4264,6 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval) if (trap_state == TRAP_STATE_PRIMED) trap_return--; oldlastval = lastval; - lastval = 0; /* status of empty function is zero */ oldnumpipestats = numpipestats; if (noreturnval) { /* diff --git a/Src/init.c b/Src/init.c index b3224f65a..b807f0659 100644 --- a/Src/init.c +++ b/Src/init.c @@ -99,11 +99,11 @@ mod_export struct hookdef zshhooks[] = { /* keep executing lists until EOF found */ /**/ -int +enum loop_return loop(int toplevel, int justonce) { Eprog prog; - int err; + int err, non_empty = 0; pushheap(); if (!toplevel) @@ -151,6 +151,7 @@ loop(int toplevel, int justonce) if (hend(prog)) { int toksav = tok; + non_empty = 1; if (toplevel && (getshfunc("preexec") || paramtab->getnode(paramtab, "preexec" HOOK_SUFFIX))) { @@ -207,7 +208,11 @@ loop(int toplevel, int justonce) lexrestore(); popheap(); - return err; + if (err) + return LOOP_ERROR; + if (!non_empty) + return LOOP_EMPTY; + return LOOP_OK; } static char *cmd; @@ -1131,7 +1136,6 @@ source(char *s) fstack.tp = FS_SOURCE; funcstack = &fstack; - lastval = 0; /* status of empty file is zero */ if (prog) { pushheap(); errflag = 0; @@ -1141,8 +1145,21 @@ source(char *s) ret = SOURCE_ERROR; } else { /* loop through the file to be sourced */ - if (loop(0, 0)) + switch (loop(0, 0)) + { + case LOOP_OK: + /* nothing to do but compilers like a complete enum */ + break; + + case LOOP_EMPTY: + /* Empty code resets status */ + lastval = 0; + break; + + case LOOP_ERROR: ret = SOURCE_ERROR; + break; + } } funcstack = funcstack->prev; sourcelevel--; diff --git a/Src/zsh.h b/Src/zsh.h index 2a23ad36a..a230a5058 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1726,6 +1726,17 @@ struct nameddir { #define PRINT_WHENCE_FUNCDEF (1<<9) #define PRINT_WHENCE_WORD (1<<10) +/* Return values from loop() */ + +enum loop_return { + /* Loop executed OK */ + LOOP_OK, + /* Loop executed no code */ + LOOP_EMPTY, + /* Loop encountered an error */ + LOOP_ERROR +}; + /* Return values from source() */ enum source_return { diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst index 1fe249869..3b3f2f915 100644 --- a/Test/A01grammar.ztst +++ b/Test/A01grammar.ztst @@ -553,3 +553,9 @@ 0:Last status of successfully executed "." file is retained >1 >0 + + echo 'echo $?' >dot_status + false + . ./dot_status +0:"." file sees status from previous command +>1 diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index 338c36fab..f71e5ce77 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -15,6 +15,13 @@ fnz 0:Empty function body resets status + fn3() { return 3; } + fnstat() { print $?; } + fn3 + fnstat +0:Status is not reset on non-empty function body +>3 + function f$$ () { print regress expansion of function names } diff --git a/Test/D08cmdsubst.ztst b/Test/D08cmdsubst.ztst index 1b5c7f728..9962c6cad 100644 --- a/Test/D08cmdsubst.ztst +++ b/Test/D08cmdsubst.ztst @@ -93,3 +93,8 @@ false `` 0:Empty command substitution resets status + + false + echo `echo $?` +0:Non-empty command substitution inherits status +>1 |