Jason Edmeades : cmd: Fix statements after 'else' inside for loops.
Alexandre Julliard
julliard at winehq.org
Mon Jul 16 14:40:00 CDT 2018
Module: wine
Branch: master
Commit: 6cb520476a79fd7ff5a67c1a1064de9c267fdbc1
URL: https://source.winehq.org/git/wine.git/?a=commit;h=6cb520476a79fd7ff5a67c1a1064de9c267fdbc1
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>
---
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 1ee4fcc..088632f 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 5ca2427..b9e9b25 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
@@ -1371,6 +1372,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 0a7c75a..3118359 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
---
@@ -982,6 +983,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