Jason Edmeades : cmd: Fix statements after 'else' inside for loops.

Alexandre Julliard julliard at winehq.org
Thu Sep 13 03:49:17 CDT 2018


Module: wine
Branch: stable
Commit: ecdcf1ba42feaebbd8ed976efb397501eaa32950
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ecdcf1ba42feaebbd8ed976efb397501eaa32950

Author: Jason Edmeades <us at edmeades.me.uk>
Date:   Sun Jul 15 23:15:29 2018 +0100

cmd: Fix statements after 'else' inside for loops.

When inside a for loop, an 'if' statement is processed and the true part
taken. Once all the commands in the true are processed, the else part is
parsed, and a flag set to skip all commands in the else part. Unfortunately
this flag is left on even when the if statement ends, meaning subsequent
commands are also skipped.

Signed-off-by: Jason Edmeades <us at edmeades.me.uk>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 6cb520476a79fd7ff5a67c1a1064de9c267fdbc1)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 programs/cmd/builtins.c                  | 18 +++++++++++++++--
 programs/cmd/tests/test_builtins.cmd     | 34 ++++++++++++++++++++++++++++++++
 programs/cmd/tests/test_builtins.cmd.exp | 14 +++++++++++++
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 7c2122e..160940e 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -1571,10 +1571,12 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
       /* execute all appropriate commands */
       curPosition = *cmdList;
 
-      WINE_TRACE("Processing cmdList(%p) - delim(%d) bd(%d / %d)\n",
+      WINE_TRACE("Processing cmdList(%p) - delim(%d) bd(%d / %d) processThese(%d)\n",
                  *cmdList,
                  (*cmdList)->prevDelim,
-                 (*cmdList)->bracketDepth, myDepth);
+                 (*cmdList)->bracketDepth,
+                 myDepth,
+                 processThese);
 
       /* Execute any statements appended to the line */
       /* FIXME: Only if previous call worked for && or failed for || */
@@ -1613,6 +1615,18 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
             if (*cmd) {
               WCMD_execute (cmd, (*cmdList)->redirects, cmdList, FALSE);
             }
+          } else {
+              /* Loop skipping all commands until we get back to the current
+                 depth, including skipping commands and their subsequent
+                 pipes (eg cmd | prog)                                       */
+              do {
+                *cmdList = (*cmdList)->nextcommand;
+              } while (*cmdList &&
+                      ((*cmdList)->bracketDepth > myDepth ||
+                      (*cmdList)->prevDelim));
+
+              /* After the else is complete, we need to now process subsequent commands */
+              processThese = TRUE;
           }
           if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand;
         } else if (!processThese) {
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index f344de2..236238c 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -418,6 +418,7 @@ if 1==1 (echo n1) else echo n2|echo n3
 if 1==1 (echo o1) else echo o2&&echo o3
 if 1==1 (echo p1) else echo p2||echo p3
 if 1==1 (echo q1) else echo q2&echo q3
+echo ---
 echo --- chain else (if false)
 if 1==0 echo a1 else echo a2
 if 1==0 echo b1|echo b2 else echo b3
@@ -1328,6 +1329,39 @@ for /L %%i in (2,2,1) do (
   echo %%i
   echo FAILED
 )
+echo --- ifs inside for loops
+for %%i in (test) do (
+    echo a1
+    if 1==1 (
+        echo b1
+    ) else (
+        echo c1
+    )
+    echo d1
+)
+for %%i in (test) do (
+    echo a2
+    if 1==1 (
+        echo b2
+    ) else echo c2
+    echo d2
+)
+for %%i in (test) do (
+    echo a3
+    if 1==0 (
+        echo b3
+    ) else echo c3
+    echo d3
+)
+for %%i in (test) do (
+    echo a4
+    if 1==0 (
+        echo b4
+    ) else (
+        echo c4
+    )
+    echo d4
+)
 echo --- set /a
 goto :testseta
 
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index cab4a35..eb60620 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -428,6 +428,7 @@ n1
 o1
 p1
 q1
+ at todo_wine@---
 --- chain else (if false)
 @todo_wine at j3
 ---
@@ -974,6 +975,19 @@ ErrorLevel 0
 -1
 1
 3
+--- ifs inside for loops
+a1
+b1
+d1
+a2
+b2
+d2
+a3
+c3
+d3
+a4
+c4
+d4
 --- set /a
 ------ individual operations
 WINE_foo correctly 3




More information about the wine-cvs mailing list