[PATCH 2/2] [cmd] for /l with zero iterations fails to skip its commands

Ann and Jason Edmeades jason at edmeades.me.uk
Sun Sep 2 17:43:44 CDT 2012


If a for /L loop needs no iterations, the body of the for loop needs
to be skipped. Without doing this, the 'do xxxx' is executed as
a command or if a bracketted section follows it, all parts are
incorrectly executed.

[BUG 27894]

Jason Edmeades
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20120902/6d94dcdc/attachment-0001.html>
-------------- next part --------------
From 522371cd8ab2d1d93396681588994b85b177f7fc Mon Sep 17 00:00:00 2001
From: Jason Edmeades <us at edmeades.me.uk>
Date: Sun, 2 Sep 2012 23:25:21 +0100
Subject: [PATCH 2/2] [cmd] for /l with zero iterations fails to skip its
 commands

If a for /L loop needs no iterations, the body of the for loop needs
to be skipped. Without doing this, the 'do xxxx' is executed as
a command or if a bracketted section follows it, all parts are
incorrectly executed.

[BUG 27894]
---
 programs/cmd/builtins.c                  |   18 +++++++++++-------
 programs/cmd/tests/test_builtins.cmd     |    5 +++++
 programs/cmd/tests/test_builtins.cmd.exp |    4 ++--
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index e28ff10..a83947b 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -968,7 +968,7 @@ void WCMD_echo (const WCHAR *command)
  */
 static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
                               const WCHAR *variable, const WCHAR *value,
-                              BOOL isIF, BOOL conditionTRUE)
+                              BOOL isIF, BOOL executecmds)
 {
   CMD_LIST *curPosition = *cmdList;
   int myDepth = (*cmdList)->bracketDepth;
@@ -976,13 +976,13 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
   WINE_TRACE("cmdList(%p), firstCmd(%p), with variable '%s'='%s', doIt(%d)\n",
              cmdList, wine_dbgstr_w(firstcmd),
              wine_dbgstr_w(variable), wine_dbgstr_w(value),
-             conditionTRUE);
+             executecmds);
 
   /* Skip leading whitespace between condition and the command */
   while (firstcmd && *firstcmd && (*firstcmd==' ' || *firstcmd=='\t')) firstcmd++;
 
   /* Process the first command, if there is one */
-  if (conditionTRUE && firstcmd && *firstcmd) {
+  if (executecmds && firstcmd && *firstcmd) {
     WCHAR *command = WCMD_strdupW(firstcmd);
     WCMD_execute (firstcmd, (*cmdList)->redirects, variable, value, cmdList);
     HeapFree(GetProcessHeap(), 0, command);
@@ -994,9 +994,7 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
 
   /* Process any other parts of the command */
   if (*cmdList) {
-    BOOL processThese = TRUE;
-
-    if (isIF) processThese = conditionTRUE;
+    BOOL processThese = executecmds;
 
     while (*cmdList) {
       static const WCHAR ifElse[] = {'e','l','s','e'};
@@ -1372,8 +1370,14 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
 
           thisCmdStart = cmdStart;
           WCMD_part_execute(&thisCmdStart, firstCmd, variable, thisNum, FALSE, TRUE);
-          cmdEnd = thisCmdStart;
       }
+
+      /* 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;
   }
 
   /* When the loop ends, either something like a GOTO or EXIT /b has terminated
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 4856578..36bc73f 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -685,6 +685,11 @@ for /L %%i in (1,1,1) do echo %%i
 for /L %%i in (1,-2,-1) do echo %%i
 for /L %%i in (-1,-1,-1) do echo %%i
 for /L %%i in (1,2, 3) do echo %%i
+rem Test zero iteration skips the body of the for
+for /L %%i in (2,2,1) do (
+  echo %%i
+  echo FAILED
+)
 echo --- for /a
 rem No output when using "set expr" syntax, unless in interactive mode
 rem Need to use "set envvar=expr" to use in a batch script
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 0011d35..c444be6 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -469,8 +469,8 @@ bar
 2
 1
 -1
- at todo_wine@ErrorLevel 0
- at todo_wine@ErrorLevel 0
+ErrorLevel 0
+ErrorLevel 0
 1
 2
 3
-- 
1.7.5.4


More information about the wine-patches mailing list