diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index b2546d4c52f..4ce78f7755c 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 093cc23b502..77086ed37bf 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 93b11e55480..fe4c30caab9 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@space@ +foo@space@ +bar@space@ +PASSED +xxx - Should be xxx +Expected second line --- for /L 1 3