about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Src/exec.c18
-rw-r--r--Test/A01grammar.ztst18
3 files changed, 41 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 55a211d69..d97c7dbd3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2002-09-17  Peter Stephenson  <pws@csr.com>
+
+	* 17673: Src/exec.c, Test/A01grammar.ztst:
+	  for X in Y; true || B; done && X
+	executed X on every iteration.  Same bug with true -> false,
+	|| -> &&, && -> ||.
+
 2002-09-10  Clint Adams  <clint@zsh.org>
 
         * 17189: Sven: Completion/Unix/Type/_path_files: better
diff --git a/Src/exec.c b/Src/exec.c
index f1206e93c..4ed4f0671 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -848,8 +848,15 @@ execlist(Estate state, int dont_change_job, int exiting)
 			 * for this sublist.                                   */
 			donetrap = 1;
 			goto sublist_done;
-		    } else if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END)
+		    } else if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END) {
 			donetrap = 1;
+			/*
+			 * Treat this in the same way as if we reached
+			 * the end of the sublist normally.
+			 */
+			state->pc = next;
+			goto sublist_done;
+		    }
 		}
 		cmdpush(CS_CMDAND);
 		break;
@@ -874,8 +881,15 @@ execlist(Estate state, int dont_change_job, int exiting)
 			 * for this sublist.                                   */
 			donetrap = 1;
 			goto sublist_done;
-		    } else if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END)
+		    } else if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END) {
 			donetrap = 1;
+			/*
+			 * Treat this in the same way as if we reached
+			 * the end of the sublist normally.
+			 */
+			state->pc = next;
+			goto sublist_done;
+		    }
 		}
 		cmdpush(CS_CMDOR);
 		break;
diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst
index 8b6b403fb..7a1e39934 100644
--- a/Test/A01grammar.ztst
+++ b/Test/A01grammar.ztst
@@ -319,3 +319,21 @@
   done < /dev/null | { read name; print done }
 0:Bug regression: `while' loop with redirection and pipeline
 >done
+
+# This used to be buggy and print X at the end of each iteration.
+  for f in 1 2 3 4; do
+    print $f || break
+  done && print X
+0:Handling of ||'s and &&'s with a for loop in between
+>1
+>2
+>3
+>4
+>X
+
+# Same bug for &&, used to print `no' at the end of each iteration
+  for f in 1 2 3 4; do
+    false && print strange
+  done || print no
+0:Handling of &&'s and ||'s with a for loop in between
+>no