Reactos

[CMD_ROSTEST] Add tests for batch execution flow with GOTO and CALL commands.

- Tests for GOTO across IF parenthesized block (parser test with line
continuation at closing parenthesis).

- Tests for showing how FOR-loops stop when a GOTO is encountered.

- Tests for EXIT command within IF block.

+459
+6
modules/rostests/win32/cmd/rsrc.rc
··· 28 28 29 29 /* @makedep: test_echoer_parser.cmd.exp */ 30 30 test_echoer_parser.cmd.exp TESTOUT "test_echoer_parser.cmd.exp" 31 + 32 + /* @makedep: test_goto_call.cmd */ 33 + test_goto_call.cmd TESTCMD "test_goto_call.cmd" 34 + 35 + /* @makedep: test_goto_call.cmd.exp */ 36 + test_goto_call.cmd.exp TESTOUT "test_goto_call.cmd.exp"
+239
modules/rostests/win32/cmd/test_goto_call.cmd
··· 1 + @echo off 2 + setlocal enableextensions 3 + setlocal enabledelayedexpansion 4 + 5 + 6 + :: 7 + :: Tests for GOTO and CALL. 8 + :: 9 + 10 + 11 + 12 + :: 13 + :: Testing GOTO/CALL from and to within parenthesized blocks. 14 + :: 15 + 16 + echo --------- Testing GOTO within block --------- 17 + (echo Block-test 1: Single-line& goto :block2 & echo Unexpected Block-test 1^^!) 18 + echo Unexpected echo 1^^! 19 + 20 + :block2 21 + ( 22 + echo Block-test 2: Multi-line 23 + goto :block3 24 + echo Unexpected Block-test 2^^! 25 + ) 26 + echo Unexpected echo 2-3^^! 27 + 28 + :test_call_block 29 + echo Test CALL in block OK from %0 30 + :: We exit this CALL invocation 31 + goto :EOF 32 + 33 + ( 34 + :block3 35 + echo --------- Testing CALL within block --------- 36 + echo Block-test 3: CALL in block 37 + call :test_call_block 38 + echo CALL done 39 + ) 40 + 41 + goto :block4 42 + echo Unexpected echo 4^^! 43 + ( 44 + :block4 45 + echo Block-test 4 OK 46 + ) 47 + 48 + 49 + :: 50 + :: Testing GOTO/CALL from within FOR and IF. 51 + :: This is a situation similar to the parenthesized blocks. 52 + :: See bug-report CORE-13713 53 + :: 54 + 55 + :: Testing CALL within FOR 56 + echo --------- Testing CALL within FOR --------- 57 + for /L %%A IN (0,1,3) DO ( 58 + set Number=%%A 59 + if %%A==2 call :out_of_loop_1 %%A 60 + if %%A==2 (echo %%A IS equal to 2) else (echo %%A IS NOT equal to 2) 61 + ) 62 + goto :continue_2 63 + :out_of_loop_1 64 + echo Out of FOR 1 CALL from %0, number is %1 65 + :: We exit this CALL invocation 66 + goto :EOF 67 + :continue_2 68 + 69 + 70 + :: Testing GOTO within FOR 71 + echo --------- Testing GOTO within FOR --------- 72 + for /L %%A IN (0,1,3) DO ( 73 + set Number=%%A 74 + if %%A==2 goto :out_of_loop_2 75 + echo %%A IS NOT equal to 2 76 + ) 77 + echo Unexpected FOR echo 2^^! 78 + :out_of_loop_2 79 + echo Out of FOR 2, number is %Number% 80 + 81 + 82 + 83 + :: 84 + :: Show how each different FOR-loop stops when a GOTO is encountered. 85 + :: 86 + echo --------- Testing FOR loop stopping with GOTO --------- 87 + 88 + :: FOR - Stops directly 89 + echo --- FOR 90 + @echo on 91 + for %%A in (1,2,3,4,5,6,7,8,9,10) do ( 92 + set Number=%%A 93 + if %%A==5 goto :out_of_loop_2a 94 + ) 95 + echo Unexpected FOR echo 2a^^! 96 + :out_of_loop_2a 97 + echo Out of FOR 2a, number is %Number% 98 + @echo off 99 + 100 + 101 + :: FOR /R - Stops directly 102 + echo --- FOR /R 103 + 104 + :: Use auxiliary directoreis to test for /R 105 + mkdir foobar && cd foobar 106 + mkdir foo1 107 + mkdir foo2 108 + mkdir bar1 109 + 110 + @echo on 111 + for /r %%A in (1,2,3,4,5,6,7,8,9,10) do ( 112 + set Number=%%~nA 113 + if %%~nA==5 goto :out_of_loop_2b 114 + ) 115 + echo Unexpected FOR echo 2b^^! 116 + :out_of_loop_2b 117 + echo Out of FOR 2b, number is %Number% 118 + @echo off 119 + 120 + :: Cleanup 121 + cd .. & rd /s/q foobar 122 + 123 + 124 + :: FOR /L - Does not stop directly. It continues looping until the end 125 + :: but does not execute its body code. This can cause problems e.g. for 126 + :: infinite loops "for /l %a in () do ( ... )" that are exited by EXIT /B, 127 + :: since the body code stops being executed, but the loop itself continues 128 + :: running forever. 129 + echo --- FOR /L 130 + @echo on 131 + for /l %%A in (1,1,10) do ( 132 + set Number=%%A 133 + if %%A==5 goto :out_of_loop_2c 134 + ) 135 + echo Unexpected FOR echo 2c^^! 136 + :out_of_loop_2c 137 + echo Out of FOR 2c, number is %Number% 138 + @echo off 139 + 140 + 141 + :: FOR /F - Stops directly. 142 + echo --- FOR /F 143 + @echo on 144 + for %%T in ( "1:2:3" "4:5:6:7" "8:9:10" ) do ( 145 + set "pc=%%~T" 146 + for /f "delims=" %%A in (^"!pc::^=^ 147 + % New line % 148 + !^") do ( 149 + 150 + set Number=%%A 151 + if %%A==5 goto :out_of_loop_2d 152 + ) 153 + ) 154 + echo Unexpected FOR echo 2d^^! 155 + :out_of_loop_2d 156 + echo Out of FOR 2d, number is %Number% 157 + @echo off 158 + 159 + 160 + 161 + :: Testing CALL within IF 162 + echo --------- Testing CALL within IF --------- 163 + if 1==1 ( 164 + call :out_of_if_1 123 165 + echo Success IF echo 1 166 + ) 167 + goto :continue_3 168 + :out_of_if_1 169 + echo Out of IF CALL from %0, number is %1 170 + :: We exit this CALL invocation 171 + goto :EOF 172 + :continue_3 173 + 174 + 175 + :: Testing GOTO within IF 176 + echo --------- Testing GOTO within IF --------- 177 + if 1==1 ( 178 + goto :out_of_if_2 179 + echo Unexpected IF echo 2a^^! 180 + ) 181 + echo Unexpected IF echo 2b^^! 182 + :out_of_if_2 183 + echo Out of IF ok 184 + 185 + :: Same, but with line-continuation at the closing parenthesis of the IF block. 186 + if 1==1 ( 187 + :labelA 188 + echo A 189 + ) ^ 190 + else ( 191 + :labelB 192 + echo B 193 + goto :continue 194 + ) 195 + :: We are jumping inside the IF, whose block will be interpreted as 196 + :: separate commands; thus we will also run the :labelB block as well. 197 + goto :labelA 198 + 199 + 200 + :: 201 + :: Next suite of tests. 202 + :: 203 + :continue 204 + 205 + :: Testing EXIT within IF 206 + echo --------- Testing EXIT within IF --------- 207 + 208 + :: Use a CALL context, and we will only check EXIT /B. 209 + call :doExitIfTest 1 210 + call :doExitIfTest 2 211 + goto :finished 212 + 213 + :doExitIfTest 214 + if %1==1 ( 215 + echo First block 216 + exit /b 217 + echo Unexpected first block^^! 218 + ) else ( 219 + echo Second block 220 + exit /b 221 + echo Unexpected second block^^! 222 + ) 223 + echo You won't see this^^! 224 + exit /b 225 + 226 + 227 + 228 + :: 229 + :: Finished! 230 + :: 231 + :finished 232 + echo --------- Finished -------------- 233 + goto :EOF 234 + 235 + :: Subroutine to set errorlevel and return 236 + :: in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported 237 + :setError 238 + exit /B %1 239 + :: This line runs under cmd in windows NT 4, but not in more modern versions.
+214
modules/rostests/win32/cmd/test_goto_call.cmd.exp
··· 1 + --------- Testing GOTO within block --------- 2 + Block-test 1: Single-line 3 + Block-test 2: Multi-line 4 + --------- Testing CALL within block --------- 5 + Block-test 3: CALL in block 6 + Test CALL in block OK from :test_call_block 7 + CALL done 8 + Block-test 4 OK 9 + --------- Testing CALL within FOR --------- 10 + 0 IS NOT equal to 2 11 + 1 IS NOT equal to 2 12 + Out of FOR 1 CALL from :out_of_loop_1, number is 2 13 + 2 IS equal to 2 14 + 3 IS NOT equal to 2 15 + --------- Testing GOTO within FOR --------- 16 + 0 IS NOT equal to 2 17 + 1 IS NOT equal to 2 18 + Out of FOR 2, number is 2 19 + --------- Testing FOR loop stopping with GOTO --------- 20 + --- FOR 21 + 22 + @pwd@>for %A in (1 2 3 4 5 6 7 8 9 10) do ( 23 + set Number=%A@space@@space@ 24 + if %A == 5 goto :out_of_loop_2a@space@ 25 + )@space@ 26 + 27 + @pwd@>( 28 + set Number=1@space@@space@ 29 + if 1 == 5 goto :out_of_loop_2a@space@ 30 + )@space@ 31 + 32 + @pwd@>( 33 + set Number=2@space@@space@ 34 + if 2 == 5 goto :out_of_loop_2a@space@ 35 + )@space@ 36 + 37 + @pwd@>( 38 + set Number=3@space@@space@ 39 + if 3 == 5 goto :out_of_loop_2a@space@ 40 + )@space@ 41 + 42 + @pwd@>( 43 + set Number=4@space@@space@ 44 + if 4 == 5 goto :out_of_loop_2a@space@ 45 + )@space@ 46 + 47 + @pwd@>( 48 + set Number=5@space@@space@ 49 + if 5 == 5 goto :out_of_loop_2a@space@ 50 + )@space@ 51 + 52 + @pwd@>echo Out of FOR 2a, number is 5@space@ 53 + Out of FOR 2a, number is 5 54 + --- FOR /R 55 + 56 + @pwd@\foobar>for /R %A in (1 2 3 4 5 6 7 8 9 10) do ( 57 + set Number=%~nA@space@@space@ 58 + if %~nA == 5 goto :out_of_loop_2b@space@ 59 + )@space@ 60 + 61 + @pwd@\foobar>( 62 + set Number=1@space@@space@ 63 + if 1 == 5 goto :out_of_loop_2b@space@ 64 + )@space@ 65 + 66 + @pwd@\foobar>( 67 + set Number=2@space@@space@ 68 + if 2 == 5 goto :out_of_loop_2b@space@ 69 + )@space@ 70 + 71 + @pwd@\foobar>( 72 + set Number=3@space@@space@ 73 + if 3 == 5 goto :out_of_loop_2b@space@ 74 + )@space@ 75 + 76 + @pwd@\foobar>( 77 + set Number=4@space@@space@ 78 + if 4 == 5 goto :out_of_loop_2b@space@ 79 + )@space@ 80 + 81 + @pwd@\foobar>( 82 + set Number=5@space@@space@ 83 + if 5 == 5 goto :out_of_loop_2b@space@ 84 + )@space@ 85 + 86 + @pwd@\foobar>echo Out of FOR 2b, number is 5@space@ 87 + Out of FOR 2b, number is 5 88 + --- FOR /L 89 + 90 + @pwd@>for /L %A in (1 1 10) do ( 91 + set Number=%A@space@@space@ 92 + if %A == 5 goto :out_of_loop_2c@space@ 93 + )@space@ 94 + 95 + @pwd@>( 96 + set Number=1@space@@space@ 97 + if 1 == 5 goto :out_of_loop_2c@space@ 98 + )@space@ 99 + 100 + @pwd@>( 101 + set Number=2@space@@space@ 102 + if 2 == 5 goto :out_of_loop_2c@space@ 103 + )@space@ 104 + 105 + @pwd@>( 106 + set Number=3@space@@space@ 107 + if 3 == 5 goto :out_of_loop_2c@space@ 108 + )@space@ 109 + 110 + @pwd@>( 111 + set Number=4@space@@space@ 112 + if 4 == 5 goto :out_of_loop_2c@space@ 113 + )@space@ 114 + 115 + @pwd@>( 116 + set Number=5@space@@space@ 117 + if 5 == 5 goto :out_of_loop_2c@space@ 118 + )@space@ 119 + 120 + @pwd@>( 121 + set Number=6@space@@space@ 122 + if 6 == 5 goto :out_of_loop_2c@space@ 123 + )@space@ 124 + 125 + @pwd@>( 126 + set Number=7@space@@space@ 127 + if 7 == 5 goto :out_of_loop_2c@space@ 128 + )@space@ 129 + 130 + @pwd@>( 131 + set Number=8@space@@space@ 132 + if 8 == 5 goto :out_of_loop_2c@space@ 133 + )@space@ 134 + 135 + @pwd@>( 136 + set Number=9@space@@space@ 137 + if 9 == 5 goto :out_of_loop_2c@space@ 138 + )@space@ 139 + 140 + @pwd@>( 141 + set Number=10@space@@space@ 142 + if 10 == 5 goto :out_of_loop_2c@space@ 143 + )@space@ 144 + 145 + @pwd@>echo Out of FOR 2c, number is 5@space@ 146 + Out of FOR 2c, number is 5 147 + --- FOR /F 148 + 149 + @pwd@>for %T in ("1:2:3" "4:5:6:7" "8:9:10") do ( 150 + set "pc=%~T"@space@@space@ 151 + for /F "delims=" %A in ("!pc::= 152 + !") do ( 153 + set Number=%A@space@@space@ 154 + if %A == 5 goto :out_of_loop_2d@space@ 155 + )@space@ 156 + )@space@ 157 + 158 + @pwd@>( 159 + set "pc=1:2:3"@space@@space@ 160 + for /F "delims=" %A in ("!pc::= 161 + !") do ( 162 + set Number=%A@space@@space@ 163 + if %A == 5 goto :out_of_loop_2d@space@ 164 + )@space@ 165 + )@space@ 166 + 167 + @pwd@>( 168 + set Number=1@space@@space@ 169 + if 1 == 5 goto :out_of_loop_2d@space@ 170 + )@space@ 171 + 172 + @pwd@>( 173 + set Number=2@space@@space@ 174 + if 2 == 5 goto :out_of_loop_2d@space@ 175 + )@space@ 176 + 177 + @pwd@>( 178 + set Number=3@space@@space@ 179 + if 3 == 5 goto :out_of_loop_2d@space@ 180 + )@space@ 181 + 182 + @pwd@>( 183 + set "pc=4:5:6:7"@space@@space@ 184 + for /F "delims=" %A in ("!pc::= 185 + !") do ( 186 + set Number=%A@space@@space@ 187 + if %A == 5 goto :out_of_loop_2d@space@ 188 + )@space@ 189 + )@space@ 190 + 191 + @pwd@>( 192 + set Number=4@space@@space@ 193 + if 4 == 5 goto :out_of_loop_2d@space@ 194 + )@space@ 195 + 196 + @pwd@>( 197 + set Number=5@space@@space@ 198 + if 5 == 5 goto :out_of_loop_2d@space@ 199 + )@space@ 200 + 201 + @pwd@>echo Out of FOR 2d, number is 5@space@ 202 + Out of FOR 2d, number is 5 203 + --------- Testing CALL within IF --------- 204 + Out of IF CALL from :out_of_if_1, number is 123 205 + Success IF echo 1 206 + --------- Testing GOTO within IF --------- 207 + Out of IF ok 208 + A 209 + A 210 + B 211 + --------- Testing EXIT within IF --------- 212 + First block 213 + Second block 214 + --------- Finished --------------