Jason Edmeades : cmd: More generic zero iteration for loop fix.

Alexandre Julliard julliard at winehq.org
Wed Sep 5 15:36:45 CDT 2012


Module: wine
Branch: master
Commit: 141e33b845bff271fd8aebdd8ec24b32a95be454
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=141e33b845bff271fd8aebdd8ec24b32a95be454

Author: Jason Edmeades <jason at edmeades.me.uk>
Date:   Tue Sep  4 21:11:51 2012 +0100

cmd: More generic zero iteration for loop fix.

---

 programs/cmd/builtins.c                  |   23 +++++++++++++++++------
 programs/cmd/tests/test_builtins.cmd     |   24 +++++++++++++++++++++---
 programs/cmd/tests/test_builtins.cmd.exp |    9 ++++++---
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index b2546d4..4ce78f7 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -1084,6 +1084,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
   BOOL   expandDirs  = FALSE;
   BOOL   useNumbers  = FALSE;
   BOOL   doFileset   = FALSE;
+  BOOL   doExecuted  = FALSE;  /* Has the 'do' part been executed */
   LONG   numbers[3] = {0,0,0}; /* Defaults to 0 in native */
   int    itemNum;
   CMD_LIST *thisCmdStart;
@@ -1233,6 +1234,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
                 {
                   thisCmdStart = cmdStart;
                   WINE_TRACE("Processing FOR filename %s\n", wine_dbgstr_w(fd.cFileName));
+                  doExecuted = TRUE;
                   WCMD_part_execute (&thisCmdStart, firstCmd, variable,
                                                fd.cFileName, FALSE, TRUE);
                 }
@@ -1241,6 +1243,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
               FindClose (hff);
             }
           } else {
+            doExecuted = TRUE;
             WCMD_part_execute(&thisCmdStart, firstCmd, variable, item, FALSE, TRUE);
           }
 
@@ -1310,6 +1313,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
                   /* FIXME: The following should be moved into its own routine and
                      reused for the string literal parsing below                  */
                   thisCmdStart = cmdStart;
+                  doExecuted = TRUE;
                   WCMD_part_execute(&thisCmdStart, firstCmd, variable, parm, FALSE, TRUE);
                   cmdEnd = thisCmdStart;
               }
@@ -1340,6 +1344,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
               /* FIXME: The following should be moved into its own routine and
                  reused for the string literal parsing below                  */
               thisCmdStart = cmdStart;
+              doExecuted = TRUE;
               WCMD_part_execute(&thisCmdStart, firstCmd, variable, parm, FALSE, TRUE);
               cmdEnd = thisCmdStart;
           }
@@ -1369,17 +1374,23 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
           WINE_TRACE("Processing FOR number %s\n", wine_dbgstr_w(thisNum));
 
           thisCmdStart = cmdStart;
+          doExecuted = TRUE;
           WCMD_part_execute(&thisCmdStart, firstCmd, variable, thisNum, FALSE, TRUE);
       }
-
-      /* Now skip over the subsequent commands if we did not perform the for loop */
-      if (thisCmdStart == cmdStart) {
-        WINE_TRACE("Skipping for loop commands due to no valid iterations\n");
-        WCMD_part_execute(&thisCmdStart, firstCmd, variable, thisNum, FALSE, FALSE);
-      }
       cmdEnd = thisCmdStart;
   }
 
+  /* Now skip over the do part if we did not perform the for loop so far.
+     We store in cmdEnd the next command after the do block, but we only
+     know this if something was run. If it has not been, we need to calculate
+     it.                                                                      */
+  if (!doExecuted) {
+    thisCmdStart = cmdStart;
+    WINE_TRACE("Skipping for loop commands due to no valid iterations\n");
+    WCMD_part_execute(&thisCmdStart, firstCmd, NULL, NULL, FALSE, FALSE);
+    cmdEnd = thisCmdStart;
+  }
+
   /* When the loop ends, either something like a GOTO or EXIT /b has terminated
      all processing, OR it should be pointing to the end of && processing OR
      it should be pointing at the NULL end of bracket for the DO. The return
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 093cc23..77086ed 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -643,9 +643,27 @@ echo > bazbaz
 echo --- basic wildcards
 for %%i in (ba*) do echo %%i
 echo --- for /d
-for /d %%i in (baz foo bar) do echo %%i
-rem FIXME for /d incorrectly parses when wildcards are used
-rem for /d %%i in (bazb*) do echo %%i
+for /d %%i in (baz foo bar) do echo %%i 2>&1
+rem Confirm we dont match files:
+for /d %%i in (bazb*) do echo %%i 2>&1
+for /d %%i in (bazb2*) do echo %%i 2>&1
+rem Show we pass through non wildcards
+for /d %%i in (PASSED) do echo %%i
+for /d %%i in (xxx) do (
+  echo %%i - Should be xxx
+  echo Expected second line
+)
+rem Show we issue no messages on failures
+for /d %%i in (FAILED?) do echo %%i 2>&1
+for /d %%i in (FAILED?) do (
+  echo %%i - Unexpected!
+  echo FAILED Unexpected second line
+)
+for /d %%i in (FAILED*) do echo %%i 2>&1
+for /d %%i in (FAILED*) do (
+  echo %%i - Unexpected!
+  echo FAILED Unexpected second line
+)
 rem FIXME can't test wildcard expansion here since it's listed in directory
 rem order, and not in alphabetic order.
 rem Proper testing would need a currently missing "sort" program implementation.
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 93b11e5..fe4c30c 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -455,9 +455,12 @@ C
 --- basic wildcards
 bazbaz
 --- for /d
-baz
-foo
-bar
+baz at space@
+foo at space@
+bar at space@
+PASSED
+xxx - Should be xxx
+Expected second line
 --- for /L
 1
 3




More information about the wine-cvs mailing list