This is the first serie of a major rewrite of cmd.exe's command engine (lexer, parser, command handling).
The goal is to implement correctly: - command chaining (&&, ||) operators, - fix a number of issues (eg. 32679, 55401, 44063...) - remove some spaghetti code from engine, - allow to move forward on some pending MR (5246 5242 5194 4504...)
This first part mainly extends the tests with the issues listed in above bug tickets & MR.
From: Eric Pouech epouech@codeweavers.com
Based on a test case from Dimitry Sokolov.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd | 2 ++ programs/cmd/tests/test_builtins.cmd.exp | 3 +++ 2 files changed, 5 insertions(+)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 7517cca343f..3b5fd384b54 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -744,6 +744,8 @@ echo '%~xs1' goto :eof :endEchoFuns
+echo --- in digit variables +for %%0 in (a b) do echo %%0 %%1 %%2 echo ------------ Testing parameter zero ------------ call :func parm1 parm2 goto :endParm0 diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 1365a5c3474..3e5cdbe9942 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -600,6 +600,9 @@ N @drive@ '' '.eh'@or_broken@'' +--- in digit variables +@todo_wine@a %1 %2 +@todo_wine@b %1 %2 ------------ Testing parameter zero ------------ :func parm1 [:func] [@drive@] [@path@] [test] [.cmd] [@drive@@shortpath@test.cmd]
From: Eric Pouech epouech@codeweavers.com
Based on a patch by Dimitry Sokolov.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd | 12 ++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 3 +++ 2 files changed, 15 insertions(+)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 3b5fd384b54..00d87a805d8 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -1403,6 +1403,18 @@ goto :endForTestFun2 echo %1 %2 goto :eof :endForTestFun2 +echo --- nested FORs and args tempering +set "WINE_ARGS= -foo=bar -x=y" +:test_for_loop_params_parse +for /F "tokens=1,* delims= " %%a in ("%WINE_ARGS%") do ( + for /F "tokens=1,2 delims==" %%1 in ("%%a") do ( + echo inner argument {%%1, %%2} + ) + set "WINE_ARGS=%%b" + goto :test_for_loop_params_parse +) +set "WINE_ARGS=" + mkdir foobar & cd foobar mkdir foo mkdir bar diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 3e5cdbe9942..fab7c8742ec 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -1000,6 +1000,9 @@ A C A D B C B D +--- nested FORs and args tempering +@todo_wine@inner argument {-foo, bar} +@todo_wine@inner argument {-x, y} --- basic wildcards bazbaz --- wildcards in subdirs
From: Eric Pouech epouech@codeweavers.com
Based on a patch by Alex Henrie.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd | 17 +++++++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 4 ++++ 2 files changed, 21 insertions(+)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 00d87a805d8..c0707e129b5 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -744,6 +744,17 @@ echo '%~xs1' goto :eof :endEchoFuns
+setlocal EnableDelayedExpansion +set WINE_FOO=foo bar +for %%i in ("!WINE_FOO!") do echo %%i +for %%i in (!WINE_FOO!) do echo %%i +rem tests disabled for now... wine's cmd loops endlessly here +rem set WINE_FOO=4 4 4 +rem for /l %%i in (!WINE_FOO!) do echo %%i +rem set WINE_FOO=4 +rem for /l %%i in (1 2 !WINE_FOO!) do echo %%i +setlocal DisableDelayedExpansion + echo --- in digit variables for %%0 in (a b) do echo %%0 %%1 %%2 echo ------------ Testing parameter zero ------------ @@ -794,6 +805,12 @@ set WINE_FOO=foo echo %WINE_FOO% echo !WINE_FOO! set WINE_FOO= + +setlocal EnableDelayedExpansion +set WINE_FOO=foo bar +if !WINE_FOO!=="" (echo empty) else echo not empty +setlocal DisableDelayedExpansion + echo --- using /V cmd flag echo @echo off> tmp.cmd echo set WINE_FOO=foo>> tmp.cmd diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index fab7c8742ec..7146bdaf26b 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -600,6 +600,9 @@ N @drive@ '' '.eh'@or_broken@'' +"foo bar" +@todo_wine@foo +@todo_wine@bar --- in digit variables @todo_wine@a %1 %2 @todo_wine@b %1 %2 @@ -621,6 +624,7 @@ bar@or_broken@foo 0@or_broken@1 foo !WINE_FOO! +@todo_wine@not empty --- using /V cmd flag foo foo@or_broken@!WINE_FOO!
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd | 20 ++++++++++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 11 +++++++++++ 2 files changed, 31 insertions(+)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index c0707e129b5..77207318223 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -2711,7 +2711,13 @@ echo>robinfile if 1==1 call del batfile dir /b if exist batfile echo batfile shouldn't exist +rem arcane command, first resets errorlevel, second sets it to one +(call ) +echo %ErrorLevel% +(call) +echo %ErrorLevel% rem ... but not for 'if' or 'for' +call :setError 0 call if 1==1 echo bar 2> nul echo %ErrorLevel% call :setError 0 @@ -2738,6 +2744,20 @@ call if 1==1 ( call call call echo passed cd .. & rd /s/q foobar
+echo --- mixing batch and builtins +erase /q echo.bat test.bat 2> NUL +echo @echo foo> echo.bat +echo @echo bar> test.bat & call test.bat +echo @echo.bat bar> test.bat & call test.bat +echo @call echo bar> test.bat & call test.bat +echo @call echo.bat bar> test.bat & call test.bat +erase /q echo.bat 2> NUL +echo @echo bar> test.bat & call test.bat +echo @echo.bat bar> test.bat & call test.bat +echo @call echo bar> test.bat & call test.bat +echo @call echo.bat bar> test.bat & call test.bat +erase /q test.bat 2> NUL + echo ------------ Testing SHIFT ------------
call :shiftFun p1 p2 p3 p4 p5 diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 7146bdaf26b..026befada11 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -1537,6 +1537,8 @@ foo created Should expand foobaz batfile robinfile +0 +@todo_wine@1 1 1 non-builtin dir @@ -1545,6 +1547,15 @@ Line two Get if ... and else! passed +--- mixing batch and builtins +bar@space@ +@todo_wine@foo +foo +foo +bar@space@ +bat bar@space@ +bar@space@ +bat bar@space@ ------------ Testing SHIFT ------------ 'p1' 'p2' 'p3' 'p4' 'p5' 'p2' 'p3' 'p4' 'p5' ''
From: Eric Pouech epouech@codeweavers.com
The || and && operators to chain commands rely on the LHS command to be successful (or unsucessful) to decide upon launching the RHS command.
Unfortunately, success/failure is not always when errorlevel is 0 (non zero).
Some exmaples: - if a redirection fails (eg. appending to a non existing file), the command (builtin/external) is always unsuccessful (and the error level is untouched, - external command (when redirection is ok) is succesful when program exit code is zero, - ditto for a call to a label inside the batch file, with the 'exit /b' parameter, - it's way more complicated for builtins. Eg 'type' is unsuccessful on a non existing file, while 'dir' (on the same unexisting file) succeeds.
So start adding some tests about success / failure of some commands.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/tests/test_builtins.cmd | 9 +++++++++ programs/cmd/tests/test_builtins.cmd.exp | 9 +++++++++ 2 files changed, 18 insertions(+)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 77207318223..8fa724c2682 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -450,6 +450,15 @@ if 1==0 (echo o1) else echo o2&&echo o3 if 1==0 (echo p1) else echo p2||echo p3 echo --- if 1==0 (echo q1) else echo q2&echo q3 +echo ------------- Testing internal commands return codes +call :setError 0 &&echo SUCCESS||echo FAILURE %errorlevel% +call :setError 33 &&echo SUCCESS||echo FAILURE %errorlevel% +call :setError 666 +echo foo &&echo SUCCESS||echo FAILURE %errorlevel% +echo foo >> h:\i\dont\exist\at\all.txt &&echo SUCCESS||echo FAILURE %errorlevel% +type NUL &&echo SUCCESS||echo FAILURE %errorlevel% +type h:\i\dont\exist\at\all.txt &&echo SUCCESS||echo FAILURE %errorlevel% +echo --- echo ------------ Testing 'set' ------------ call :setError 0 rem Remove any WINE_FOO* WINE_BA* environment variables from shell before proceeding diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 026befada11..76665765b26 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -449,6 +449,15 @@ p2 @todo_wine@--- q2 q3 +------------- Testing internal commands return codes +SUCCESS +FAILURE 0 +@todo_wine@foo@space@ +@todo_wine@SUCCESS +@todo_wine@FAILURE 666 +SUCCESS +@todo_wine@FAILURE 0 +@todo_wine@--- ------------ Testing 'set' ------------ 1 0