Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [falk@xxxxxxxxxx: Bug#107528: "while do done" gets into uninterruptable loop]



Clint Adams wrote:

> > The patch below looks stupid (and it may well be), but it's the easiest
> > I can think of.  I think I better not commit this until I get replies.
> > (Most of it is re-indentation of that loop, there's just a tiny bit of
> > added code at the top.)
> 
> This seems to work;  I don't have any objection to its committal.

Nor have I. And since noone else complained I'm just going to commit
it.


Bye
  Sven

Index: Src/loop.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/loop.c,v
retrieving revision 1.7
diff -u -r1.7 loop.c
--- Src/loop.c	23 Oct 2001 16:17:05 -0000	1.7
+++ Src/loop.c	25 Feb 2002 09:18:48 -0000
@@ -380,37 +380,53 @@
     cmdpush(isuntil ? CS_UNTIL : CS_WHILE);
     loops++;
     loop = state->pc;
-    for (;;) {
-	state->pc = loop;
-	noerrexit = 1;
-	execlist(state, 1, 0);
-	noerrexit = olderrexit;
-	if (!((lastval == 0) ^ isuntil)) {
-	    if (breaks)
-		breaks--;
-	    lastval = oldval;
-	    break;
-	}
-	if (retflag) {
-	    lastval = oldval;
-	    break;
-	}
-	execlist(state, 1, 0);
-	if (breaks) {
-	    breaks--;
-	    if (breaks || !contflag)
-		break;
-	    contflag = 0;
-	}
-	if (errflag) {
-	    lastval = 1;
-	    break;
-	}
-	if (retflag)
-	    break;
-	freeheap();
-	oldval = lastval;
-    }
+
+    if (loop[0] == WC_END && loop[1] == WC_END) {
+
+        /* This is an empty loop.  Make sure the signal handler sets the
+        * flags and then just wait for someone hitting ^C. */
+
+        int old_simple_pline = simple_pline;
+
+        simple_pline = 1;
+
+        while (!breaks)
+            ;
+        breaks--;
+
+        simple_pline = old_simple_pline;
+    } else
+        for (;;) {
+            state->pc = loop;
+            noerrexit = 1;
+            execlist(state, 1, 0);
+            noerrexit = olderrexit;
+            if (!((lastval == 0) ^ isuntil)) {
+                if (breaks)
+                    breaks--;
+                lastval = oldval;
+                break;
+            }
+            if (retflag) {
+                lastval = oldval;
+                break;
+            }
+            execlist(state, 1, 0);
+            if (breaks) {
+                breaks--;
+                if (breaks || !contflag)
+                    break;
+                contflag = 0;
+            }
+            if (errflag) {
+                lastval = 1;
+                break;
+            }
+            if (retflag)
+                break;
+            freeheap();
+            oldval = lastval;
+        }
     cmdpop();
     popheap();
     loops--;

-- 
Sven Wischnowsky                          wischnow@xxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author