ntdll: Translate signal to trap when trap code is 0 on ARM.
[wine.git] / programs / cmd / tests / test_builtins.cmd
blobf4dfc9f26d89d5ed08a82f0d2243bcc1b2a330c1
1 echo Tests for cmd's builtin commands
3 @echo on
4 echo ------------ Testing 'echo' [ON] ------------
5 echo word
6 echo 'singlequotedword'
7 echo "doublequotedword"
8 @echo at-echoed-word
9 echo "/?"
10 echo.
11 echo .
12 echo.word
13 echo .word
14 echo:
15 echo :
16 echo:word
17 echo :word
18 echo/
19 echo /
20 echo/word
21 echo /word
22 echo off now
23 echo word@space@
24 echo word@space@@space@
25 echo word
26 echo@tab@word
27 echo@tab@word @tab@
28 echo@tab@word@tab@@space@
29 @tab@echo word
30 echo @tab@word
31 echo @tab@word
32 echo@tab@@tab@word
33 echo @tab@ on @space@
34 @echo --- @ with chains and brackets
35 (echo the @ character chains until&&@echo we leave the current depth||(
36 echo hidden
37 @echo hidden
38 ))&&echo and can hide brackets||(@echo command hidden)||@(echo brackets hidden)
39 @echo ---
41 @echo off
42 echo off@tab@@space@
43 @echo noecho1
44 @echo noecho2
45 @@@@@echo echo3
46 echo ------------ Testing 'echo' [OFF] ------------
47 echo word
48 echo 'singlequotedword'
49 echo "doublequotedword"
50 @echo at-echoed-word
51 echo "/?"
52 echo.
53 echo .
54 echo.word
55 echo .word
56 echo:
57 echo :
58 echo:word
59 echo :word
60 echo/
61 echo /
62 echo/word
63 echo /word
64 echo on again
65 echo word@space@
66 echo word@space@@space@
67 echo word
68 echo@tab@word
69 echo@tab@word @tab@
70 echo@tab@word@tab@@space@
71 @tab@echo word
72 echo @tab@word
73 echo @tab@word
74 echo@tab@@tab@word
76 echo ------------ Testing mixed echo modes ------------
77 echo @echo on> mixedEchoModes.cmd
78 echo if 1==1 echo foo>> mixedEchoModes.cmd
79 echo if 1==1 @echo bar>> mixedEchoModes.cmd
80 echo @echo off>> mixedEchoModes.cmd
81 echo if 1==1 echo foo2>> mixedEchoModes.cmd
82 echo if 1==1 @echo bar2>> mixedEchoModes.cmd
83 type mixedEchoModes.cmd
84 cmd /c mixedEchoModes.cmd
85 del mixedEchoModes.cmd
87 echo ------------ Testing parameterization ------------
88 call :TestParm a b c
89 call :TestParm "a b c"
90 call :TestParm "a b"\c
91 call :TestParm a=~`+,.{}!+b
92 call :TestParm a;b
93 call :TestParm "a;b"
94 call :TestParm a^;b
95 call :TestParm a[b]{c}(d)e
96 call :TestParm a&echo second line
97 call :TestParm a b,,,c
98 call :TestParm a==b;;c
99 call :TestParm a,,, b
100 goto :TestRem
102 :TestParm
103 echo '%1', '%2', '%3'
104 goto :eof
106 :TestRem
107 echo ------------ Testing rem ------------
108 rem Hello
109 rem Hello
110 rem Hello || foo
111 rem echo lol
112 rem echo foo & echo bar
113 rem @tab@ Hello
114 rem@tab@ Hello
115 rem@tab@echo foo & echo bar
116 @echo on
117 rem Hello
118 rem Hello
119 rem Hello || foo
120 rem echo lol
121 rem echo foo & echo bar
122 rem @tab@ Hello
123 rem@tab@ Hello
124 rem@tab@echo foo & echo bar
125 @echo off
127 echo ------------ Testing redirection operators ------------
128 mkdir foobar & cd foobar
129 echo --- stdout redirection
130 echo foo>foo
131 type foo
132 echo foo 1> foo
133 type foo
134 echo foo@tab@1> foo
135 type foo
136 echo foo 1>@tab@foo
137 type foo
138 echo foo@tab@1>@tab@foo
139 type foo
140 echo foo7 7> foo
141 type foo
142 echo foo9 9> foo
143 type foo
144 echo foo1> foo
145 type foo
146 echo foo11> foo
147 type foo
148 echo foo12> foo
149 type foo
150 echo foo13>"foo"
151 type foo
152 echo foo14>."\foo"
153 type foo
154 echo foo15>."\f"oo
155 type foo
156 del foo
157 echo1>foo
158 type foo
159 echo --- stdout appending
160 echo foo>foo
161 echo foo >>foo
162 type foo
163 del foo
164 echo foob >> foo
165 type foo
166 echo fooc 1>>foo
167 type foo
168 echo food1>>foo
169 type foo
170 echo food2>>"foo"
171 type foo
172 del foo
173 echo food21>>foo
174 type foo
175 del foo
176 echo foo> foo
177 echo foo7 7>> foo || (echo not supported & del foo)
178 if exist foo (type foo) else echo not supported
179 echo --- redirections within IF statements
180 if 1==1 echo foo1>bar
181 type bar & del bar
182 if 1==1 echo foo2>>bar
183 type bar & del bar
184 echo -----
185 if 1==1 (echo foo2>bar) else echo baz2>bar
186 type bar & del bar
187 if 1==1 (echo foo3) else echo baz3>bar
188 type bar || echo file does not exist, ok
189 if 1==1 (echo foo4>bar) else echo baz4>bar
190 type bar & del bar
191 if 1==0 (echo foo5>bar) else echo baz5>bar
192 type bar & del bar
193 if 1==0 (echo foo6) else echo baz6 1>bar
194 type bar & del bar
195 if 1==0 (echo foo7 1>bar) else echo baz7>bar
196 type bar & del bar
197 if 1==0 (echo foo8 1>bar) else echo baz8>bak
198 type bak
199 if 1==1 (echo foo>bar & echo baz)
200 type bar
201 if 1==1 (
202 echo foo>bar
203 echo baz
205 type bar
206 (if 1==1 (echo A) else echo B) > C
207 type C
208 (if 1==0 (echo A) else echo B) > C
209 type C
210 (if 1==0 (echo A > B) else echo C)
211 cd .. & rd /s/q foobar
213 echo ------------ Testing circumflex escape character ------------
214 rem Using something like "echo foo^" asks for an additional char after a "More?" prompt on the following line; it's not possible to currently test that non-interactively
215 echo ^hell^o, world
216 echo hell^o, world
217 echo hell^^o, world
218 echo hell^^^o, world
219 echo hello^
220 world
221 echo hello^
223 world
224 echo hello^
227 echo finished
228 mkdir foobar
229 echo baz> foobar\baz
230 type foobar\baz
231 type foobar^\baz
232 rd /s/q foobar
233 echo foo ^| echo bar
234 echo foo ^& echo bar
235 call :setError 0
236 echo bak ^&& echo baz 2> nul
237 echo %ErrorLevel%
238 echo foo ^> foo
239 echo ^<> foo
240 type foo
241 del foo
242 set WINE_FOO=oof
243 echo ff^%WINE_FOO%
244 set WINE_FOO=bar ^| baz
245 set WINE_FOO
246 rem FIXME: echoing %WINE_FOO% gives an error (baz not recognized) but prematurely
247 rem exits the script on windows; redirecting stdout and/or stderr doesn't help
248 echo %ErrorLevel%
249 call :setError 0
250 set WINE_FOO=bar ^^^| baz
251 set WINE_FOO
252 echo %WINE_FOO%
253 echo %ErrorLevel%
254 set WINE_FOO=
256 echo ------------ Testing chains ------------
257 rem The chain operators have the following bottom-up precedence:
258 rem 'else' precedes nothing and matches the closest unmatched 'if' in the same bracket depth
259 rem '&' precedes 'else'
260 rem '||' precedes '&' and 'else'
261 rem '&&' precedes '||', '&' and 'else'
262 rem '|' precedes '&&', '||', '&' and 'else'
264 rem Example: 'if 1==1 if 2==2 if 3==3 a | b && c || d & e else f else g' is interpreted as
265 rem 'if 1==1 (if 2==2 (if 3==3 ((((a | b) && c) || d) & e) else f) else g)'
266 goto :cfailend
267 :cfail
268 echo %1
269 call :setError 1
270 goto :eof
271 :cfailend
272 echo --- chain success
273 echo a1&echo a2
274 echo b1&&echo b2
275 echo c1||echo c2
276 echo ---
277 echo d1&echo d2&echo d3
278 echo e1&echo e2&&echo e3
279 echo f1&echo f2||echo f3
280 echo ---
281 echo g1&&echo g2&echo g3
282 echo h1&&echo h2&&echo h3
283 echo i1&&echo i2||echo i3
284 echo ---
285 echo j1||echo j2&echo j3
286 echo ---
287 echo k1||echo k2&&echo k3
288 echo ---
289 echo l1||echo l2||echo l3
290 echo ---
291 echo --- chain failure
292 call :cfail a1&call :cfail a2
293 call :cfail b1&&call :cfail b2
294 echo ---
295 call :cfail c1||call :cfail c2
296 call :cfail d1&call :cfail d2&call :cfail d3
297 call :cfail e1&call :cfail e2&&call :cfail e3
298 echo ---
299 call :cfail f1&call :cfail f2||call :cfail f3
300 call :cfail g1&&call :cfail g2&call :cfail g3
301 echo ---
302 call :cfail h1&&call :cfail h2&&call :cfail h3
303 echo ---
304 call :cfail i1&&call :cfail i2||call :cfail i3
305 echo ---
306 call :cfail j1||call :cfail j2&call :cfail j3
307 call :cfail k1||call :cfail k2&&call :cfail k3
308 echo ---
309 call :cfail l1||call :cfail l2||call :cfail l3
310 echo --- chain brackets
311 rem Brackets are like regular commands, they support redirections
312 rem and have the same precedence as regular commands.
313 echo a1&(echo a2&echo a3)
314 echo b1&(echo b2&&echo b3)
315 echo c1&(echo c2||echo c3)
316 echo ---
317 echo d1&&(echo d2&echo d3)
318 echo e1&&(echo e2&&echo e3)
319 echo f1&&(echo f2||echo f3)
320 echo ---
321 echo g1||(echo g2&echo g3)
322 echo ---
323 echo h1||(echo h2&&echo h3)
324 echo ---
325 echo i1||(echo i2||echo i3)
326 echo ---
327 call :cfail j1&(call :cfail j2&call :cfail j3)
328 call :cfail k1&(call :cfail k2&&call :cfail k3)
329 echo ---
330 call :cfail l1&(call :cfail l2||call :cfail l3)
331 call :cfail m1&&(call :cfail m2&call :cfail m3)
332 echo ---
333 call :cfail n1&&(call :cfail n2&&call :cfail n3)
334 echo ---
335 call :cfail o1&&(call :cfail o2||call :cfail o3)
336 echo ---
337 call :cfail p1||(call :cfail p2&call :cfail p3)
338 call :cfail q1||(call :cfail q2&&call :cfail q3)
339 echo ---
340 call :cfail r1||(call :cfail r2||call :cfail r3)
341 echo --- chain pipe
342 rem Piped commands run at the same time, so the print order varies.
343 rem Additionally, they don't run in the batch script context, as shown by
344 rem 'call :existing_label|echo read the error message'.
345 (echo a 1>&2|echo a 1>&2) 2>&1
346 echo ---
347 echo b1|echo b2
348 echo c1&&echo c2|echo c3
349 echo d1||echo d2|echo d3
350 echo ---
351 echo e1&echo e2|echo e3
352 echo f1|echo f2&&echo f3
353 echo g1|echo g2||echo g3
354 echo ---
355 echo h1|echo h2&echo h3
356 echo i1|echo i2|echo i3
357 echo --- chain pipe input
358 rem The output data of the left side of a pipe can disappear, probably
359 rem because it finished too fast and closed the pipe before it could be read,
360 rem which means we can get broken results for the tests of this section.
361 echo @echo off> tmp.cmd
362 echo set IN=X>> tmp.cmd
363 echo set /p IN=%%1:>> tmp.cmd
364 echo setlocal EnableDelayedExpansion>> tmp.cmd
365 echo echo [!IN!,%%1]>> tmp.cmd
366 echo endlocal>> tmp.cmd
367 echo set IN=>> tmp.cmd
368 echo a1|cmd /ctmp.cmd a2
369 echo b1|cmd /ctmp.cmd b2|cmd /ctmp.cmd b3
370 echo c1|cmd /ctmp.cmd c2|cmd /ctmp.cmd c3|cmd /ctmp.cmd c4
371 echo d1|call tmp.cmd d2
372 echo e1|call tmp.cmd e2|call tmp.cmd e3
373 echo f1|call tmp.cmd f2|call tmp.cmd f3|call tmp.cmd f4
374 rem FIXME these 3 tests cause "unexpected end of output"
375 rem test : echo g1|tmp.cmd g2
376 rem result: g2:[g1,g2]
377 rem test : echo h1|tmp.cmd h2|tmp.cmd h3
378 rem result: h3:[h2:[h1,h2],h3]@or_broken@h3:[h2:,h3]
379 rem test : echo i1|tmp.cmd i2|tmp.cmd i3|tmp.cmd i4
380 rem result: i4:[i3:[i2:[i1,i2],i3],i4]@or_broken@i4:[i3:[i2:,i3],i4]@or_broken@i4:[i3:,i4]
381 del tmp.cmd
382 echo --- chain else
383 rem Command arguments are gready and eat up the 'else' unless terminated by
384 rem brackets, which means the 'else' can only be recognized when the
385 rem 'if true' command chain ends with brackets.
386 if 1==1 if 2==2 if 3==3 (echo a1) else (echo a2) else echo a3
387 if 1==1 if 2==2 if 3==0 (echo b1) else (echo b2) else echo b3
388 echo ---
389 if 1==1 if 2==0 if 3==3 (echo c1) else (echo c2) else echo c3
390 echo ---
391 if 1==1 if 2==0 if 3==0 (echo d1) else (echo d2) else echo d3
392 echo ---
393 if 1==0 if 2==2 if 3==3 (echo e1) else (echo e2) else echo e3
394 echo ---
395 if 1==0 if 2==2 if 3==0 (echo f1) else (echo f2) else echo f3
396 echo ---
397 if 1==0 if 2==0 if 3==3 (echo g1) else (echo g2) else echo g3
398 echo ---
399 if 1==0 if 2==0 if 3==0 (echo h1) else (echo h2) else echo h3
400 echo ---
401 echo --- chain else (if true)
402 if 1==1 echo a1 else echo a2
403 if 1==1 echo b1|echo b2 else echo b3
404 if 1==1 echo c1&&echo c2 else echo c3
405 if 1==1 echo d1||echo d2 else echo d3
406 echo ---
407 if 1==1 echo e1&echo e2 else echo e3
408 if 1==1 echo f1 else echo f2|echo f3
409 if 1==1 echo g1 else echo g2&&echo g3
410 if 1==1 echo h1 else echo h2||echo h3
411 echo ---
412 if 1==1 echo i1 else echo i2&echo i3
413 if 1==1 echo j1|(echo j2) else echo j3
414 echo ---
415 if 1==1 echo k1&&(echo k2) else echo k3
416 if 1==1 echo l1||(echo l2) else echo l3
417 echo ---
418 if 1==1 echo m1&(echo m2) else echo m3
419 if 1==1 (echo n1) else echo n2|echo n3
420 if 1==1 (echo o1) else echo o2&&echo o3
421 if 1==1 (echo p1) else echo p2||echo p3
422 if 1==1 (echo q1) else echo q2&echo q3
423 echo ---
424 echo --- chain else (if false)
425 if 1==0 echo a1 else echo a2
426 if 1==0 echo b1|echo b2 else echo b3
427 if 1==0 echo c1&&echo c2 else echo c3
428 if 1==0 echo d1||echo d2 else echo d3
429 if 1==0 echo e1&echo e2 else echo e3
430 if 1==0 echo f1 else echo f2|echo f3
431 if 1==0 echo g1 else echo g2&&echo g3
432 if 1==0 echo h1 else echo h2||echo h3
433 if 1==0 echo i1 else echo i2&echo i3
434 if 1==0 echo j1|(echo j2) else echo j3
435 echo ---
436 if 1==0 echo k1&&(echo k2) else echo k3
437 if 1==0 echo l1||(echo l2) else echo l3
438 if 1==0 echo m1&(echo m2) else echo m3
439 if 1==0 (echo n1) else echo n2|echo n3
440 if 1==0 (echo o1) else echo o2&&echo o3
441 if 1==0 (echo p1) else echo p2||echo p3
442 echo ---
443 if 1==0 (echo q1) else echo q2&echo q3
444 echo ------------ Testing 'set' ------------
445 call :setError 0
446 rem Remove any WINE_FOO* WINE_BA* environment variables from shell before proceeding
447 for /f "delims==" %%i in ('set WINE_ba') do set %%i=
448 for /f "delims==" %%i in ('set WINE_foo') do set %%i=
449 set WINE_FOOBAR 2> nul > nul
450 echo %ErrorLevel%
451 set WINE_FOOBAR = baz
452 echo %ErrorLevel%
453 echo %WINE_FOOBAR%WINE_FOOBAR not defined
454 echo %WINE_FOOBAR %
455 set WINE_FOOBAR 2> nul
456 set WINE_FOOBAR = baz2
457 echo %ErrorLevel%
458 echo %WINE_fOObAr %
459 set WINE_FOOBAR= bar
460 echo %ErrorLevel%
461 echo %WINE_FOOBAR%
462 set WINE_FOO
463 set WINE_FOOBAR=
464 set WINE_FOOB
465 echo %WINE_FOOBAR%WINE_FOOBAR not defined
466 set WINE_FOOBAR =
467 set WINE_FOOBA 2> nul > nul
468 echo %ErrorLevel%
469 set WINE_FOO=bar
470 echo %WINE_FOO%
471 set WINE_FOO=foo
472 set WINE_BAR=bar
473 echo %WINE_FOO%%WINE_BAR%
474 set WINE_BAR=
475 set WINE_FOO=
476 set WINE_FOO=%WINE_FOO%
477 echo %WINE_FOO%WINE_FOO not defined
478 set WINE_BAZ%=bazbaz
479 set WINE_BA
480 echo %WINE_BAZ%%
481 set WINE_BAZ%=
482 echo set "WINE_FOO=bar" should not include the quotes in the variable value
483 set "WINE_FOO=bar"
484 echo %WINE_FOO%
485 set@tab@WINE_FOO=foo
486 echo %WINE_FOO%
487 set@tab@WINE_FOO=
488 echo '%WINE_FOO%'
489 set WINE_FOO=foo@space@
490 echo '%WINE_FOO%'
491 set WINE_FOO=foo@tab@
492 echo '%WINE_FOO%'
493 rem Space symbol must appear in `var`
494 set WINE_FOO=value@space@
495 echo '%WINE_FOO%'
496 rem Space symbol must NOT appear in `var`
497 set "WINE_FOO=value"@space@
498 echo '%WINE_FOO%'
499 rem Mixed examples:
500 set WINE_FOO=jim fred
501 echo '%WINE_FOO%'
502 set WINE_FOO="jim" fred
503 echo '%WINE_FOO%'
504 set "WINE_FOO=jim fred"
505 echo '%WINE_FOO%'
506 set "WINE_FOO=jim" fred
507 echo '%WINE_FOO%'
508 rem Only the final quote ends the string
509 set "WINE_FOO=apple"banana"grape"orange
510 echo '%WINE_FOO%'
511 set WINE_FOO=
512 rem set PATH must work with quotes
513 set PATH_BACKUP=%PATH%
514 mkdir folder
515 mkdir "fol;der"
516 echo echo I'm here! > "fol;der\sub1.bat"
517 echo echo I'm here! > folder\sub1.bat
518 set PATH=nothing;"fol;der"
519 call sub1
520 set PATH="folder
521 call sub1
522 set PATH=folder"
523 call sub1
524 del "fol;der\sub1.bat"
525 del folder\sub1.bat
526 rmdir "fol;der"
527 rmdir folder
528 PATH=%PATH_BACKUP%
530 echo ------------ Testing 'choice' ------------
532 rem Windows XP and Windows 2000 do not come with choice
533 rem echo is used for @or_broken@ formatting
534 choice /C:ABC /M "Example message" /D A /T:0
535 if %ERRORLEVEL% EQU 9009 (
536 echo choice unavailable
538 echo %ERRORLEVEL%
539 choice /C ABC "/M:Example message" /D:B /T 0
540 if %ERRORLEVEL% EQU 9009 (
541 echo choice unavailable
543 echo %ERRORLEVEL%
544 choice /C def /D:f /T:0
545 if %ERRORLEVEL% EQU 9009 (
546 echo choice unavailable
548 echo %ERRORLEVEL%
549 REM If a pipe fails due to a nonexistent command
550 REM it will stop the whole program's execution
551 if %ERRORLEVEL% NEQ 9009 (
552 echo Y | choice /C ABCXYZ /D A /T 2
554 if %ERRORLEVEL% EQU 9009 (
555 echo choice unavailable
557 echo %ERRORLEVEL%
558 choice /C ABC /N /D A /T 0
559 if %ERRORLEVEL% EQU 9009 (
560 echo choice unavailable
562 echo %ERRORLEVEL%
563 choice /C abcABC /CS /D:A /T:0
564 if %ERRORLEVEL% EQU 9009 (
565 echo choice unavailable
567 echo %ERRORLEVEL%
568 rem intentional error
569 choice /C abcABC /D:A /T:0 >NUL 2>NUL
570 echo %ERRORLEVEL%
572 echo ------------ Testing variable expansion ------------
573 call :setError 0
574 echo ~p0 should be path containing batch file
575 echo %~p0
576 mkdir dummydir
577 cd dummydir
578 echo %~p0
579 cd ..
580 rmdir dummydir
581 echo ~dp0 should be directory containing batch file
582 echo %~dp0
583 mkdir dummydir
584 cd dummydir
585 echo %~dp0
586 cd ..
587 rmdir dummydir
588 echo CD value %CD%
589 echo %%
590 echo P%
591 echo %P
592 echo %WINE_UNKNOWN%S
593 echo P%WINE_UNKNOWN%
594 echo P%WINE_UNKNOWN%S
595 echo %ERRORLEVEL
596 echo %ERRORLEVEL%
597 echo %ERRORLEVEL%%ERRORLEVEL%
598 echo %ERRORLEVEL%ERRORLEVEL%
599 echo %ERRORLEVEL%%
600 echo %ERRORLEVEL%%%
601 echo P%ERRORLEVEL%
602 echo %ERRORLEVEL%S
603 echo P%ERRORLEVEL%S
605 echo ------------ Testing variable substrings ------------
606 set WINE_VAR=qwerty
607 echo %WINE_VAR:~0,1%
608 echo %WINE_VAR:~0,3%
609 echo %WINE_VAR:~2,2%
610 echo '%WINE_VAR:~-2,3%'
611 echo '%WINE_VAR:~-2,1%'
612 echo %WINE_VAR:~2,-1%
613 echo %WINE_VAR:~2,-3%
614 echo '%WINE_VAR:~-2,-4%'
615 echo %WINE_VAR:~-3,-2%
616 set WINE_VAR=
618 echo ------------ Testing variable substitution ------------
619 echo --- in FOR variables
620 for %%i in ("A B" C) do echo %%i
621 rem check works when prefix with @
622 @for %%i in ("A B" C) do echo %%i
623 rem quotes removal
624 for %%i in ("A B" C) do echo '%%~i'
625 rem fully qualified path
626 for %%f in ("C D" E) do echo %%~ff
627 rem drive letter
628 for %%i in ("F G" H) do echo %%~di
629 rem path
630 for %%d in ("I J" K) do echo %%~pd
631 rem filename
632 for %%i in ("L M" N) do echo %%~ni
633 rem file extension
634 for %%i in ("O. P.OOL" Q.TABC hello) do echo '%%~xi'
635 rem path with short path names
636 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do echo '%%~sI'
637 rem file attribute
638 for %%i in ("U V" W) do echo '%%~ai'
639 echo foo> foo
640 for %%i in (foo) do echo '%%~ai'
641 for %%i in (foo) do echo '%%~zi'
642 del foo
643 rem file date/time
644 rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar...
645 for %%i in ("a b" c) do echo '%%~ti'
646 rem file size
647 rem Similar issues as above
648 for %%i in ("a b" c) do echo '%%~zi'
649 rem combined options
650 for %%i in ("d e" f) do echo %%~dpi
651 for %%i in ("g h" i) do echo %%~sdi
652 for %%i in ("g h" i) do echo %%~dsi
653 for %%i in ("j k" l.eh) do echo '%%~xsi'
654 for %%i in ("") do echo '%%~i,%%~fi,%%~di,%%~pi,%%~ni,%%~xi,%%~si,%%~ai,%%~ti,%%~zi'
656 echo --- in parameters
657 for %%i in ("A B" C) do call :echoFun %%i
658 rem quotes removal
659 for %%i in ("A B" C) do call :echoFunQ %%i
660 rem fully qualified path
661 for %%f in ("C D" E) do call :echoFunF %%f
662 rem drive letter
663 for %%i in ("F G" H) do call :echoFunD %%i
664 rem path
665 for %%d in ("I J" K) do call :echoFunP %%d
666 rem filename
667 for %%i in ("L M" N) do call :echoFunN %%i
668 rem file extension
669 for %%i in ("O. P.OOL" Q.TABC hello) do call :echoFunX %%i
670 rem path with short path names
671 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do call :echoFunS %%I
672 rem NT4 aborts whole script execution when encountering ~a, ~t and ~z substitutions, preventing full testing
673 rem combined options
674 for %%i in ("d e" f) do call :echoFunDP %%i
675 for %%i in ("g h" i) do call :echoFunSD %%i
676 for %%i in ("g h" i) do call :echoFunDS %%i
677 for %%i in ("j k" l.eh) do call :echoFunXS %%i
679 goto :endEchoFuns
680 :echoFun
681 echo %1
682 goto :eof
684 :echoFunQ
685 echo '%~1'
686 goto :eof
688 :echoFunF
689 echo %~f1
690 goto :eof
692 :echoFunD
693 echo %~d1
694 goto :eof
696 :echoFunP
697 echo %~p1
698 goto :eof
700 :echoFunN
701 echo %~n1
702 goto :eof
704 :echoFunX
705 echo '%~x1'
706 goto :eof
708 :echoFunS
709 rem some NT4 workaround
710 set WINE_VAR='%~s1'
711 echo %WINE_VAR%
712 set WINE_VAR=
713 goto :eof
715 :echoFunDP
716 echo %~dp1
717 goto :eof
719 :echoFunSD
720 echo %~sd1
721 goto :eof
723 :echoFunDS
724 echo %~ds1
725 goto :eof
727 :echoFunXS
728 echo '%~xs1'
729 goto :eof
730 :endEchoFuns
732 echo ------------ Testing parameter zero ------------
733 call :func parm1 parm2
734 goto :endParm0
735 :func
736 echo %~0 %~1
737 echo [%0] [%~d0] [%~p0] [%~n0] [%~x0] [%~s0]
738 goto :EOF
739 :endParm0
741 echo ------------ Testing variable delayed expansion ------------
742 rem NT4 doesn't support this
743 echo --- default mode (load-time expansion)
744 set WINE_FOO=foo
745 echo %WINE_FOO%
746 echo !WINE_FOO!
747 if %WINE_FOO% == foo (
748 set WINE_FOO=bar
749 if %WINE_FOO% == bar (echo bar) else echo foo
752 set WINE_FOO=foo
753 if %WINE_FOO% == foo (
754 set WINE_FOO=bar
755 if !WINE_FOO! == bar (echo bar) else echo foo
758 echo --- runtime (delayed) expansion mode
759 setlocal EnableDelayedExpansion
760 set WINE_FOO=foo
761 echo %WINE_FOO%
762 echo !WINE_FOO!
763 if %WINE_FOO% == foo (
764 set WINE_FOO=bar
765 if %WINE_FOO% == bar (echo bar) else echo foo
768 set WINE_FOO=foo
769 if %WINE_FOO% == foo (
770 set WINE_FOO=bar
771 if !WINE_FOO! == bar (echo bar) else echo foo
773 echo %ErrorLevel%
774 setlocal DisableDelayedExpansion
775 echo %ErrorLevel%
776 set WINE_FOO=foo
777 echo %WINE_FOO%
778 echo !WINE_FOO!
779 set WINE_FOO=
780 echo --- using /V cmd flag
781 echo @echo off> tmp.cmd
782 echo set WINE_FOO=foo>> tmp.cmd
783 echo echo %%WINE_FOO%%>> tmp.cmd
784 echo echo !WINE_FOO!>> tmp.cmd
785 echo set WINE_FOO=>> tmp.cmd
786 cmd /V:ON /C tmp.cmd
787 cmd /V:OfF /C tmp.cmd
788 del tmp.cmd
790 echo ------------ Testing conditional execution ------------
791 echo --- unconditional ampersand
792 call :setError 123 & echo foo1
793 echo bar2 & echo foo2
794 mkdir foobar & cd foobar
795 echo > foobazbar
796 cd .. & rd /s/q foobar
797 if exist foobazbar (
798 echo foobar not deleted!
799 cd ..
800 rd /s/q foobar
801 ) else echo foobar deleted
802 echo --- on success conditional and
803 call :setError 456 && echo foo3 > foo3
804 if exist foo3 (
805 echo foo3 created
806 del foo3
807 ) else echo foo3 not created
808 echo bar4 && echo foo4
809 echo --- on failure conditional or
810 call :setError 789 || echo foo5
811 echo foo6 || echo bar6 > bar6
812 if exist bar6 (
813 echo bar6 created
814 del bar6
817 echo ------------ Testing cd ------------
818 mkdir foobar
819 cd foobar
820 echo blabla > singleFile
821 dir /b
822 echo Current dir: %CD%
824 cd ..
826 cd foobar@space@
828 cd ..
830 cd @space@foobar
832 cd..
834 cd foobar
835 cd..@space@
837 if not exist foobar (cd ..)
838 cd foobar
839 cd@tab@..@tab@@space@@tab@
841 if not exist foobar (cd ..)
842 cd foobar
843 mkdir "bar bak"
844 cd "bar bak"
846 cd ..
847 cd ".\bar bak"
849 cd ..
850 cd .\"bar bak"
852 cd ..
853 cd bar bak
855 cd "bar bak@space@"@tab@@space@
857 cd ..\..
859 rd /Q/s foobar
860 mkdir foobar
861 cd /d@tab@foobar
863 cd ..
864 rd /q/s foobar
866 echo ------------ Testing type ------------
867 echo bar> foobaz
868 @echo on
869 type foobaz
870 echo ---
871 @echo off
872 type foobaz@tab@
873 echo ---1
874 type ."\foobaz"
875 echo ---2
876 type ".\foobaz"
877 echo ---3
878 del foobaz
880 echo ------------ Testing NUL ------------
881 md foobar & cd foobar
882 rem NUL file (non) creation + case insensitivity
883 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
884 echo > bar
885 echo foo > NUL
886 dir /b /a-d
887 echo foo > nul
888 dir /b /a-d
889 echo foo > NuL
890 @tab@dir /b@tab@/a-d
891 del bar
892 rem NUL not special everywhere
893 call :setError 123
894 echo NUL> foo
895 if not exist foo (echo foo should have been created) else (
896 type foo
897 del foo
899 rem Empty file creation
900 copy nul foo > nul
901 if exist foo (
902 echo foo created
903 del foo
904 type foo
905 ) else (
906 echo ***
908 echo 1234 >a.a
909 copy a.a+NUL b.b >nul
910 call :CheckFileSize a.a 7 b.b 8
911 copy NUL+a.a b.b >nul
912 call :CheckFileSize a.a 7 b.b 8
913 mkdir subdir
914 copy a.a+NUL subdir\ >nul
915 call :CheckFileSize a.a 7 subdir\a.a 8
916 del subdir\a.a
917 cd subdir
918 copy ..\a.a NUL >nul
919 if exist a.a echo Failed
920 cd ..
921 rd subdir /s /q
922 del a.a b.b
923 cd .. & rd foobar /s /q
925 echo ------------ Testing if/else ------------
926 echo --- if/else should work with blocks
927 if 0 == 0 (
928 echo if seems to work
929 ) else (
930 echo if seems to be broken
932 if 1 == 0 (
933 echo else seems to be broken
934 ) else (
935 echo else seems to work
937 if /c==/c (
938 echo if seems not to detect /c as parameter
939 ) else (
940 echo parameter detection seems to be broken
942 SET elseIF=0
943 if 1 == 1 (
944 SET /a elseIF=%elseIF%+1
945 ) else if 1 == 1 (
946 SET /a elseIF=%elseIF%+2
947 ) else (
948 SET /a elseIF=%elseIF%+2
950 if %elseIF% == 1 (
951 echo else if seems to work
952 ) else (
953 echo else if seems to be broken
955 SET elseIF=0
956 if 1 == 2 (
957 SET /a elseIF=%elseIF%+2
958 ) else if 1 == 1 (
959 SET /a elseIF=%elseIF%+1
960 ) else (
961 SET /a elseIF=%elseIF%+2
963 if %elseIF% == 1 (
964 echo else if seems to work
965 ) else (
966 echo else if seems to be broken
968 SET elseIF=0
969 if 1 == 2 (
970 SET /a elseIF=%elseIF%+2
971 ) else if 1 == 2 (
972 SET /a elseIF=%elseIF%+2
973 ) else (
974 SET /a elseIF=%elseIF%+1
976 if %elseIF% == 1 (
977 echo else if seems to work
978 ) else (
979 echo else if seems to be broken
981 if "x" == "a" (
982 echo broken1
983 ) else (
984 echo expected1
985 if "y" == "b" echo broken2
986 echo expected post-embedded if
988 echo --- case sensitivity with and without /i option
989 if bar==BAR echo if does not default to case sensitivity
990 if not bar==BAR echo if seems to default to case sensitivity
991 if /i foo==FOO echo if /i seems to work
992 if /i not foo==FOO echo if /i seems to be broken
993 if /I foo==FOO echo if /I seems to work
994 if /I not foo==FOO echo if /I seems to be broken
996 echo --- string comparisons
997 if abc == abc (echo equal) else echo non equal
998 if abc =="abc" (echo equal) else echo non equal
999 if "abc"== abc (echo equal) else echo non equal
1000 if "abc"== "abc" (echo equal) else echo non equal
1002 echo --- tabs handling
1003 if@tab@1==1 echo doom
1004 if @tab@1==1 echo doom
1005 if 1==1 (echo doom) else@tab@echo quake
1006 if@tab@not @tab@1==@tab@0 @tab@echo lol
1007 if 1==0@tab@(echo doom) else echo quake
1008 if 1==0 (echo doom)@tab@else echo quake
1009 if 1==0 (echo doom) else@tab@echo quake
1011 echo --- comparison operators
1012 rem NT4 misevaluates conditionals in for loops so we have to use subroutines as workarounds
1013 echo ------ for strings
1014 rem NT4 stops processing of the whole batch file as soon as it finds a
1015 rem comparison operator non fully uppercased, such as lss instead of LSS, so we
1016 rem can't test those here.
1017 if LSS LSS LSSfoo (echo LSS string can be used as operand for LSS comparison)
1018 if LSS LSS LSS (echo bar)
1019 if 1.1 LSS 1.10 (echo floats are handled as strings)
1020 if "9" LSS "10" (echo numbers in quotes recognized!) else echo numbers in quotes are handled as strings
1021 if not "-1" LSS "1" (echo negative numbers as well) else echo NT4
1022 if /i foo LSS FoOc echo if /i seems to work for LSS
1023 if /I not foo LSS FOOb echo if /I seems to be broken for LSS
1024 set WINE_STR_PARMS=A B AB BA AA
1025 for %%i in (%WINE_STR_PARMS%) do (
1026 for %%j in (%WINE_STR_PARMS%) do (
1027 call :LSStest %%i %%j))
1028 if b LSS B (echo b LSS B) else echo NT4
1029 if /I b LSS B echo b LSS B insensitive
1030 if b LSS A echo b LSS A
1031 if /I b LSS A echo b LSS A insensitive
1032 if a LSS B (echo a LSS B) else echo NT4
1033 if /I a LSS B echo a LSS B insensitive
1034 if A LSS b echo A LSS b
1035 if /I A LSS b echo A LSS b insensitive
1036 for %%i in (%WINE_STR_PARMS%) do (
1037 for %%j in (%WINE_STR_PARMS%) do (
1038 call :LEQtest %%i %%j))
1039 if b LEQ B (echo b LEQ B) else echo NT4
1040 if /I b LEQ B echo b LEQ B insensitive
1041 if b LEQ A echo b LEQ A
1042 if /I b LEQ A echo b LEQ A insensitive
1043 if a LEQ B (echo a LEQ B) else echo NT4
1044 if /I a LEQ B echo a LEQ B insensitive
1045 if A LEQ b echo A LEQ b
1046 if /I A LEQ b echo A LEQ b insensitive
1047 for %%i in (%WINE_STR_PARMS%) do (
1048 for %%j in (%WINE_STR_PARMS%) do (
1049 call :EQUtest %%i %%j))
1050 if /I A EQU a echo A EQU a insensitive
1051 for %%i in (%WINE_STR_PARMS%) do (
1052 for %%j in (%WINE_STR_PARMS%) do (
1053 call :NEQtest %%i %%j))
1054 for %%i in (%WINE_STR_PARMS%) do (
1055 for %%j in (%WINE_STR_PARMS%) do (
1056 call :GEQtest %%i %%j))
1057 for %%i in (%WINE_STR_PARMS%) do (
1058 for %%j in (%WINE_STR_PARMS%) do (
1059 call :GTRtest %%i %%j))
1061 echo ------------ Testing if/exist ------------
1062 mkdir subdir
1063 echo something>subdir\bar
1064 echo something else>foo
1065 if exist foo (
1066 echo exist explicit works
1067 ) else (
1068 echo ERROR exist explicit broken
1070 if exist bar (
1071 echo ERROR exist explicit unknown file broken
1072 ) else (
1073 echo exist explicit unknown file works
1075 if exist subdir\bar (
1076 echo exist explicit in subdir works
1077 ) else (
1078 echo ERROR exist explicit in subdir broken
1080 if exist fo* (
1081 echo exist simple wildcard works
1082 ) else (
1083 echo ERROR exist simple wildcard broken
1085 if exist subdir\ba* (
1086 echo exist wildcard works
1087 ) else (
1088 echo ERROR exist wildcard broken
1090 if not exist subdir\ba* (
1091 echo ERROR negate exist wildcard broken
1092 ) else (
1093 echo negate exist wildcard works
1095 if exist idontexist\ba* (
1096 echo ERROR exist wildcard bad subdir broken
1097 ) else (
1098 echo exist wildcard bad subdir broken works
1100 if exist subdir (
1101 echo exist subdir ok
1102 ) else (
1103 echo ERROR exist subdir not working
1105 if exist subdir\. (
1106 echo exist subdir with . ok
1107 ) else (
1108 echo ERROR exist subdir with . not working
1110 if exist subdir\ (
1111 echo exist subdir with \ ok
1112 ) else (
1113 echo ERROR exist subdir with \ not working
1115 if exist "subdir\" (
1116 echo exist subdir with \ and quotes ok
1117 ) else (
1118 echo ERROR exist subdir with \ and quotes not working
1120 del foo subdir\bar
1121 rd subdir
1123 echo ------ for numbers
1124 if -1 LSS 1 (echo negative numbers handled)
1125 if not -1 LSS -10 (echo negative numbers handled)
1126 if not 9 LSS 010 (echo octal handled)
1127 if not -010 LSS -8 (echo also in negative form)
1128 if 4 LSS 0x5 (echo hexa handled)
1129 if not -1 LSS -0x1A (echo also in negative form)
1130 if 11 LSS 101 (echo 11 LSS 101)
1131 set WINE_INT_PARMS=0 1 10 9
1132 for %%i in (%WINE_INT_PARMS%) do (
1133 for %%j in (%WINE_INT_PARMS%) do (
1134 call :LSStest %%i %%j))
1135 for %%i in (%WINE_INT_PARMS%) do (
1136 for %%j in (%WINE_INT_PARMS%) do (
1137 call :LEQtest %%i %%j))
1138 for %%i in (%WINE_INT_PARMS%) do (
1139 for %%j in (%WINE_INT_PARMS%) do (
1140 call :EQUtest %%i %%j))
1141 if 011 EQU 9 (echo octal ok)
1142 if 0xA1 EQU 161 (echo hexa ok)
1143 if 0xA1 EQU "161" (echo hexa should be recognized) else (echo string/hexa compare ok)
1144 if "0xA1" EQU 161 (echo hexa should be recognized) else (echo string/hexa compare ok)
1145 for %%i in (%WINE_INT_PARMS%) do (
1146 for %%j in (%WINE_INT_PARMS%) do (
1147 call :NEQtest %%i %%j))
1148 for %%i in (%WINE_INT_PARMS%) do (
1149 for %%j in (%WINE_INT_PARMS%) do (
1150 call :GEQtest %%i %%j))
1151 for %%i in (%WINE_INT_PARMS%) do (
1152 for %%j in (%WINE_INT_PARMS%) do (
1153 call :GTRtest %%i %%j))
1154 echo ------ for numbers and stringified numbers
1155 if not "1" EQU 1 (echo strings and integers not equal) else echo foo
1156 if not 1 EQU "1" (echo strings and integers not equal) else echo foo
1157 if '1' EQU 1 echo '1' EQU 1
1158 if 1 EQU '1' echo 1 EQU '1'
1159 if not "1" GEQ 1 (echo foo) else echo bar
1160 if "10" GEQ "1" echo "10" GEQ "1"
1161 if '1' GEQ 1 (echo '1' GEQ 1) else echo NT4
1162 if 1 GEQ "1" echo 1 GEQ "1"
1163 if "1" GEQ "1" echo "1" GEQ "1"
1164 if '1' GEQ "1" echo '1' GEQ "1"
1165 if "10" GEQ "1" echo "10" GEQ "1"
1166 if not 1 GEQ '1' (echo non NT4) else echo 1 GEQ '1'
1167 for %%i in ("1" '1') do call :GEQtest %%i '1'
1168 if "10" GEQ '1' (echo "10" GEQ '1') else echo foo
1169 if 1 GEQ "10" (echo 1 GEQ "10") else echo foo
1170 if "1" GEQ "10" (echo 1 GEQ "10") else echo foo
1171 if '1' GEQ "10" (echo '1' GEQ "10") else echo foo
1172 if "10" GEQ "10" (echo "10" GEQ "10")
1173 echo --- unconditional ampersand after if one line
1174 if "0"=="0" echo 1 & echo 2 & echo 3 else echo 4
1175 echo ---
1176 echo x & if "0"=="1" echo 1 & echo 2
1177 echo ---
1178 echo x & if "0"=="1" echo 1 & echo 2 & echo 3
1179 echo ---
1180 echo x & if "0"=="1" (echo 1 & echo 2 & echo 3)
1181 echo ---
1182 echo x & if "0"=="1" echo 1 & echo 2 & echo 3 else echo 4
1183 echo ---
1184 goto :endIfCompOpsSubroutines
1186 rem IF subroutines helpers
1187 :LSStest
1188 if %1 LSS %2 echo %1 LSS %2
1189 goto :eof
1190 :LEQtest
1191 if %1 LEQ %2 echo %1 LEQ %2
1192 goto :eof
1193 :EQUtest
1194 if %1 EQU %2 echo %1 EQU %2
1195 goto :eof
1196 :NEQtest
1197 if %1 NEQ %2 echo %1 NEQ %2
1198 goto :eof
1199 :GEQtest
1200 if %1 GEQ %2 echo %1 GEQ %2
1201 goto :eof
1202 :GTRtest
1203 if %1 GTR %2 echo %1 GTR %2
1204 goto :eof
1206 :endIfCompOpsSubroutines
1207 set WINE_STR_PARMS=
1208 set WINE_INT_PARMS=
1210 echo ------------ Testing for ------------
1211 echo --- plain FOR
1212 for %%i in (A B C) do echo %%i
1213 for %%i in (A B C) do echo %%I
1214 for %%i in (A B C) do echo %%j
1215 for %%i in (A B C) do call :forTestFun1 %%i
1216 for %%i in (1,4,1) do echo %%i
1217 for %%i in (A, B,C) do echo %%i
1218 for %%i in (X) do echo %%i
1219 for@tab@%%i in (X2) do echo %%i
1220 for %%i in@tab@(X3) do echo %%i
1221 for %%i in (@tab@ foo@tab@) do echo %%i
1222 for@tab@ %%i in@tab@(@tab@M) do echo %%i
1223 for %%i@tab@in (X)@tab@do@tab@echo %%i
1224 for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
1225 for %%i in (`echo A B`) do echo %%i
1226 for %%i in ('echo A B') do echo %%i
1227 for %%i in ("echo A B") do echo %%i
1228 for %%i in ("A B" C) do echo %%i
1229 goto :endForTestFun1
1230 :forTestFun1
1231 echo %1
1232 goto :eof
1233 :endForTestFun1
1234 echo --- imbricated FORs
1235 for %%i in (X) do (
1236 for %%j in (Y) do (
1237 echo %%i %%j))
1238 for %%i in (X) do (
1239 for %%I in (Y) do (
1240 echo %%i %%I))
1241 for %%i in (A B) do (
1242 for %%j in (C D) do (
1243 echo %%i %%j))
1244 for %%i in (A B) do (
1245 for %%j in (C D) do (
1246 call :forTestFun2 %%i %%j ))
1247 goto :endForTestFun2
1248 :forTestFun2
1249 echo %1 %2
1250 goto :eof
1251 :endForTestFun2
1252 mkdir foobar & cd foobar
1253 mkdir foo
1254 mkdir bar
1255 mkdir baz
1256 mkdir pop
1257 echo > bazbaz
1258 echo --- basic wildcards
1259 for %%i in (ba*) do echo %%i
1260 echo --- wildcards in subdirs
1261 echo something>pop\bar1
1262 echo something>pop\bar2.txt
1263 echo something>pop\bar3
1264 for %%f in (pop\ba*) do ( call echo %%f )
1265 rmdir /s/q pop
1266 echo --- for /d
1267 for /d %%i in (baz foo bar) do echo %%i 2>&1
1268 rem Confirm we don't match files:
1269 for /d %%i in (bazb*) do echo %%i 2>&1
1270 for /d %%i in (bazb2*) do echo %%i 2>&1
1271 rem Show we pass through non wildcards
1272 for /d %%i in (PASSED) do echo %%i
1273 for /d %%i in (xxx) do (
1274 echo %%i - Should be xxx
1275 echo Expected second line
1277 rem Show we issue no messages on failures
1278 for /d %%i in (FAILED?) do echo %%i 2>&1
1279 for /d %%i in (FAILED?) do (
1280 echo %%i - Unexpected!
1281 echo FAILED Unexpected second line
1283 for /d %%i in (FAILED*) do echo %%i 2>&1
1284 for /d %%i in (FAILED*) do (
1285 echo %%i - Unexpected!
1286 echo FAILED Unexpected second line
1288 rem FIXME can't test wildcard expansion here since it's listed in directory
1289 rem order, and not in alphabetic order.
1290 rem Proper testing would need a currently missing "sort" program implementation.
1291 rem for /d %%i in (ba*) do echo %%i>> tmp
1292 rem sort < tmp
1293 rem del tmp
1294 rem for /d %%i in (?a*) do echo %%i>> tmp
1295 rem sort < tmp
1296 rem del tmp
1297 rem for /d %%i in (*) do echo %%i>> tmp
1298 rem sort < tmp
1299 rem del tmp
1300 echo > baz\bazbaz
1301 goto :TestForR
1303 :SetExpected
1304 del temp.bat 2>nul
1305 call :WriteLine set WINE_found=N
1306 for /l %%i in (1,1,%WINE_expectedresults%) do (
1307 call :WriteLine if "%%%%WINE_expectedresults.%%i%%%%"=="%%%%~1" set WINE_found=Y
1308 call :WriteLine if "%%%%WINE_found%%%%"=="Y" set WINE_expectedresults.%%i=
1309 call :WriteLine if "%%%%WINE_found%%%%"=="Y" goto :eof
1311 call :WriteLine echo Got unexpected result: "%%%%~1"
1312 goto :eof
1314 :WriteLine
1315 echo %*>> temp.bat
1316 goto :EOF
1318 :ValidateExpected
1319 del temp.bat 2>nul
1320 for /l %%i in (1,1,%WINE_expectedresults%) do (
1321 call :WriteLine if not "%%%%WINE_expectedresults.%%i%%%%"=="" echo Found missing result: "%%%%WINE_expectedresults.%%i%%%%"
1323 call temp.bat
1324 del temp.bat 2>nul
1325 goto :eof
1327 :TestForR
1328 rem %CD% does not work on NT4 so use the following workaround
1329 for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi
1331 echo --- for /R
1332 echo Plain directory enumeration
1333 set WINE_expectedresults=4
1334 set WINE_expectedresults.1=%WINE_CURDIR%\.
1335 set WINE_expectedresults.2=%WINE_CURDIR%\bar\.
1336 set WINE_expectedresults.3=%WINE_CURDIR%\baz\.
1337 set WINE_expectedresults.4=%WINE_CURDIR%\foo\.
1338 call :SetExpected
1339 for /R %%i in (.) do call temp.bat "%%i"
1340 call :ValidateExpected
1342 echo Plain directory enumeration from provided root
1343 set WINE_expectedresults=4
1344 set WINE_expectedresults.1=%WINE_CURDIR%\.
1345 set WINE_expectedresults.2=%WINE_CURDIR%\bar\.
1346 set WINE_expectedresults.3=%WINE_CURDIR%\baz\.
1347 set WINE_expectedresults.4=%WINE_CURDIR%\foo\.
1348 if "%CD%"=="" goto :SkipBrokenNT4
1349 call :SetExpected
1350 for /R "%WINE_CURDIR%" %%i in (.) do call temp.bat "%%i"
1351 call :ValidateExpected
1352 :SkipBrokenNT4
1354 echo File enumeration
1355 set WINE_expectedresults=2
1356 set WINE_expectedresults.1=%WINE_CURDIR%\baz\bazbaz
1357 set WINE_expectedresults.2=%WINE_CURDIR%\bazbaz
1358 call :SetExpected
1359 for /R %%i in (baz*) do call temp.bat "%%i"
1360 call :ValidateExpected
1362 echo File enumeration from provided root
1363 set WINE_expectedresults=2
1364 set WINE_expectedresults.1=%WINE_CURDIR%\baz\bazbaz
1365 set WINE_expectedresults.2=%WINE_CURDIR%\bazbaz
1366 call :SetExpected
1367 for /R %%i in (baz*) do call temp.bat "%%i"
1368 call :ValidateExpected
1370 echo Mixed enumeration
1371 set WINE_expectedresults=6
1372 set WINE_expectedresults.1=%WINE_CURDIR%\.
1373 set WINE_expectedresults.2=%WINE_CURDIR%\bar\.
1374 set WINE_expectedresults.3=%WINE_CURDIR%\baz\.
1375 set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz
1376 set WINE_expectedresults.5=%WINE_CURDIR%\bazbaz
1377 set WINE_expectedresults.6=%WINE_CURDIR%\foo\.
1378 call :SetExpected
1379 for /R %%i in (. baz*) do call temp.bat "%%i"
1380 call :ValidateExpected
1382 echo Mixed enumeration from provided root
1383 set WINE_expectedresults=6
1384 set WINE_expectedresults.1=%WINE_CURDIR%\.
1385 set WINE_expectedresults.2=%WINE_CURDIR%\bar\.
1386 set WINE_expectedresults.3=%WINE_CURDIR%\baz\.
1387 set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz
1388 set WINE_expectedresults.5=%WINE_CURDIR%\bazbaz
1389 set WINE_expectedresults.6=%WINE_CURDIR%\foo\.
1390 call :SetExpected
1391 for /R %%i in (. baz*) do call temp.bat "%%i"
1392 call :ValidateExpected
1394 echo With duplicates enumeration
1395 set WINE_expectedresults=12
1396 set WINE_expectedresults.1=%WINE_CURDIR%\bar\bazbaz
1397 set WINE_expectedresults.2=%WINE_CURDIR%\bar\fred
1398 set WINE_expectedresults.3=%WINE_CURDIR%\baz\bazbaz
1399 set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz
1400 set WINE_expectedresults.5=%WINE_CURDIR%\baz\bazbaz
1401 set WINE_expectedresults.6=%WINE_CURDIR%\baz\fred
1402 set WINE_expectedresults.7=%WINE_CURDIR%\bazbaz
1403 set WINE_expectedresults.8=%WINE_CURDIR%\bazbaz
1404 set WINE_expectedresults.9=%WINE_CURDIR%\bazbaz
1405 set WINE_expectedresults.10=%WINE_CURDIR%\foo\bazbaz
1406 set WINE_expectedresults.11=%WINE_CURDIR%\foo\fred
1407 set WINE_expectedresults.12=%WINE_CURDIR%\fred
1408 call :SetExpected
1409 for /R %%i in (baz* bazbaz fred ba*) do call temp.bat "%%i"
1410 call :ValidateExpected
1412 echo Strip missing wildcards, keep unwildcarded names
1413 set WINE_expectedresults=6
1414 set WINE_expectedresults.1=%WINE_CURDIR%\bar\jim
1415 set WINE_expectedresults.2=%WINE_CURDIR%\baz\bazbaz
1416 set WINE_expectedresults.3=%WINE_CURDIR%\baz\jim
1417 set WINE_expectedresults.4=%WINE_CURDIR%\bazbaz
1418 set WINE_expectedresults.5=%WINE_CURDIR%\foo\jim
1419 set WINE_expectedresults.6=%WINE_CURDIR%\jim
1420 call :SetExpected
1421 for /R %%i in (baz* fred* jim) do call temp.bat "%%i"
1422 call :ValidateExpected
1424 echo for /R passed
1425 echo --- Complex wildcards unix and windows slash
1426 cd ..
1427 echo Windows slashes, valid path
1428 for %%f in (foobar\baz\bazbaz) do echo ASIS: %%f
1429 for %%f in (foobar\baz\*) do echo WC : %%f
1430 echo Windows slashes, invalid path
1431 for %%f in (foobar\jim\bazbaz) do echo ASIS: %%f
1432 for %%f in (foobar\jim\*) do echo WC : %%f
1433 echo Unix slashes, valid path
1434 for %%f in (foobar/baz/bazbaz) do echo ASIS: %%f
1435 for %%f in (foobar/baz/*) do echo WC : %%f
1436 echo Unix slashes, invalid path
1437 for %%f in (foobar/jim/bazbaz) do echo ASIS: %%f
1438 for %%f in (foobar/jim/*) do echo WC : %%f
1439 echo Done
1440 rd /s/Q foobar
1441 echo --- for /L
1442 rem Some cases loop forever writing 0s, like e.g. (1,0,1), (1,a,3) or (a,b,c); those can't be tested here
1443 for /L %%i in (1,2,0) do echo %%i
1444 for@tab@/L %%i in (1,2,0) do echo %%i
1445 for /L %%i in (1,2,6) do echo %%i
1446 for /l %%i in (1 ,2,6) do echo %%i
1447 for /L %%i in (a,2,3) do echo %%i
1448 for /L %%i in (1,2,-1) do echo %%i
1449 for /L %%i in (-4,-1,-1) do echo %%i
1450 for /L %%i in (1,-2,-2) do echo %%i
1451 for /L %%i in (1,2,a) do echo %%i
1452 echo ErrorLevel %ErrorLevel%
1453 for /L %%i in (1,a,b) do echo %%i
1454 echo ErrorLevel %ErrorLevel%
1455 rem Test boundaries
1456 for /l %%i in (1,1,4) do echo %%i
1457 for /l %%i in (1,2,4) do echo %%i
1458 for /l %%i in (4,-1,1) do echo %%i
1459 for /l %%i in (4,-2,1) do echo %%i
1460 for /l %%i in (1,-1,4) do echo %%i
1461 for /l %%i in (4,1,1) do echo %%i
1462 for /L %%i in (a,2,b) do echo %%i
1463 for /L %%i in (1,1,1) do echo %%i
1464 for /L %%i in (1,-2,-1) do echo %%i
1465 for /L %%i in (-1,-1,-1) do echo %%i
1466 for /L %%i in (1,2, 3) do echo %%i
1467 rem Test zero iteration skips the body of the for
1468 for /L %%i in (2,2,1) do (
1469 echo %%i
1470 echo FAILED
1472 echo --- rems inside for loops
1473 for /f %%i IN ("hello") DO (
1474 REM foo|echo ERROR unexpected execution 1
1475 @REM foo|echo ERROR unexpected execution 2
1476 @ REM foo|echo ERROR unexpected execution 3
1478 echo --- ifs inside for loops
1479 for %%i in (test) do (
1480 echo a1
1481 if 1==1 (
1482 echo b1
1483 ) else (
1484 echo c1
1486 echo d1
1488 for %%i in (test) do (
1489 echo a2
1490 if 1==1 (
1491 echo b2
1492 ) else echo c2
1493 echo d2
1495 for %%i in (test) do (
1496 echo a3
1497 if 1==0 (
1498 echo b3
1499 ) else echo c3
1500 echo d3
1502 for %%i in (test) do (
1503 echo a4
1504 if 1==0 (
1505 echo b4
1506 ) else (
1507 echo c4
1509 echo d4
1511 echo --- set /a
1512 goto :testseta
1514 Rem Ideally for /f can be used rather than building a command to execute
1515 rem but that does not work on NT4
1516 :checkenvvars
1517 if "%1"=="" goto :eof
1518 call :executecmd set wine_result=%%%1%%
1519 if "%wine_result%"=="%2" (
1520 echo %1 correctly %2
1521 ) else echo ERROR: %1 incorrectly %wine_result% [%2]
1522 set %1=
1523 shift
1524 shift
1525 rem shift
1526 goto :checkenvvars
1527 :executecmd
1529 goto :eof
1531 :testseta
1532 rem No output when using "set expr" syntax, unless in interactive mode
1533 rem Need to use "set envvar=expr" to use in a batch script
1534 echo ------ individual operations
1535 set WINE_foo=0
1536 set /a WINE_foo=1 +2 & call :checkenvvars WINE_foo 3
1537 set /a WINE_foo=1 +-2 & call :checkenvvars WINE_foo -1
1538 set /a WINE_foo=1 --2 & call :checkenvvars WINE_foo 3
1539 set /a WINE_foo=2* 3 & call :checkenvvars WINE_foo 6
1540 set /a WINE_foo=-2* -5 & call :checkenvvars WINE_foo 10
1541 set /a WINE_foo=12/3 & call :checkenvvars WINE_foo 4
1542 set /a WINE_foo=13/3 & call :checkenvvars WINE_foo 4
1543 set /a WINE_foo=-13/3 & call :checkenvvars WINE_foo -4
1544 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
1545 set /a WINE_foo=5 %% 5 & call :checkenvvars WINE_foo 0
1546 set /a WINE_foo=5 %% 3 & call :checkenvvars WINE_foo 2
1547 set /a WINE_foo=5 %% -3 & call :checkenvvars WINE_foo 2
1548 set /a WINE_foo=-5 %% -3 & call :checkenvvars WINE_foo -2
1549 set /a WINE_foo=1 ^<^< 0 & call :checkenvvars WINE_foo 1
1550 set /a WINE_foo=1 ^<^< 2 & call :checkenvvars WINE_foo 4
1551 set /a WINE_foo=1 ^<^< -2 & call :checkenvvars WINE_foo 0
1552 set /a WINE_foo=-1 ^<^< -2 & call :checkenvvars WINE_foo 0
1553 set /a WINE_foo=-1 ^<^< 2 & call :checkenvvars WINE_foo -4
1554 set /a WINE_foo=9 ^>^> 0 & call :checkenvvars WINE_foo 9
1555 set /a WINE_foo=9 ^>^> 2 & call :checkenvvars WINE_foo 2
1556 set /a WINE_foo=9 ^>^> -2 & call :checkenvvars WINE_foo 0
1557 set /a WINE_foo=-9 ^>^> -2 & call :checkenvvars WINE_foo -1
1558 set /a WINE_foo=-9 ^>^> 2 & call :checkenvvars WINE_foo -3
1559 set /a WINE_foo=5 ^& 0 & call :checkenvvars WINE_foo 0
1560 set /a WINE_foo=5 ^& 1 & call :checkenvvars WINE_foo 1
1561 set /a WINE_foo=5 ^& 3 & call :checkenvvars WINE_foo 1
1562 set /a WINE_foo=5 ^& 4 & call :checkenvvars WINE_foo 4
1563 set /a WINE_foo=5 ^& 1 & call :checkenvvars WINE_foo 1
1564 set /a WINE_foo=5 ^| 0 & call :checkenvvars WINE_foo 5
1565 set /a WINE_foo=5 ^| 1 & call :checkenvvars WINE_foo 5
1566 set /a WINE_foo=5 ^| 3 & call :checkenvvars WINE_foo 7
1567 set /a WINE_foo=5 ^| 4 & call :checkenvvars WINE_foo 5
1568 set /a WINE_foo=5 ^| 1 & call :checkenvvars WINE_foo 5
1569 set /a WINE_foo=5 ^^ 0 & call :checkenvvars WINE_foo 5
1570 set /a WINE_foo=5 ^^ 1 & call :checkenvvars WINE_foo 4
1571 set /a WINE_foo=5 ^^ 3 & call :checkenvvars WINE_foo 6
1572 set /a WINE_foo=5 ^^ 4 & call :checkenvvars WINE_foo 1
1573 set /a WINE_foo=5 ^^ 1 & call :checkenvvars WINE_foo 4
1574 echo ------ precedence and grouping
1575 set /a WINE_foo=4 + 2*3 & call :checkenvvars WINE_foo 10
1576 set /a WINE_foo=(4+2)*3 & call :checkenvvars WINE_foo 18
1577 set /a WINE_foo=4 * 3/5 & call :checkenvvars WINE_foo 2
1578 set /a WINE_foo=(4 * 3)/5 & call :checkenvvars WINE_foo 2
1579 set /a WINE_foo=4 * 5 %% 4 & call :checkenvvars WINE_foo 0
1580 set /a WINE_foo=4 * (5 %% 4) & call :checkenvvars WINE_foo 4
1581 set /a WINE_foo=3 %% (5 + 8 %% 3 ^^ 2) & call :checkenvvars WINE_foo 3
1582 set /a WINE_foo=3 %% (5 + 8 %% 3 ^^ -2) & call :checkenvvars WINE_foo 3
1583 echo ------ octal and hexadecimal
1584 set /a WINE_foo=0xf + 3 & call :checkenvvars WINE_foo 18
1585 set /a WINE_foo=0xF + 3 & call :checkenvvars WINE_foo 18
1586 set /a WINE_foo=015 + 2 & call :checkenvvars WINE_foo 15
1587 set /a WINE_foo=3, 8+3,0 & call :checkenvvars WINE_foo 3
1588 echo ------ variables
1589 set /a WINE_foo=WINE_bar=3, WINE_bar+1 & call :checkenvvars WINE_foo 3 WINE_bar 3
1590 set /a WINE_foo=WINE_bar=3, WINE_bar+=1 & call :checkenvvars WINE_foo 3 WINE_bar 4
1591 set /a WINE_foo=WINE_bar=3, WINE_baz=1, WINE_baz+=WINE_bar, WINE_baz & call :checkenvvars WINE_foo 3 WINE_bar 3 WINE_baz 4
1592 set WINE_bar=3
1593 set /a WINE_foo=WINE_bar*= WINE_bar & call :checkenvvars WINE_foo 9 WINE_bar 9
1594 set /a WINE_foo=WINE_whateverNonExistingVar & call :checkenvvars WINE_foo 0
1595 set WINE_bar=4
1596 set /a WINE_foo=WINE_whateverNonExistingVar + WINE_bar & call :checkenvvars WINE_foo 4 WINE_bar 4
1597 set WINE_bar=4
1598 set /a WINE_foo=WINE_bar -= WINE_bar + 7 & call :checkenvvars WINE_foo -7 WINE_bar -7
1599 set WINE_bar=-7
1600 set /a WINE_foo=WINE_bar /= 3 + 2 & call :checkenvvars WINE_foo -1 WINE_bar -1
1601 set /a WINE_foo=WINE_bar=5, WINE_bar %%=2 & call :checkenvvars WINE_foo 5 WINE_bar 1
1602 set WINE_bar=1
1603 set /a WINE_foo=WINE_bar ^<^<= 2 & call :checkenvvars WINE_foo 4 WINE_bar 4
1604 set WINE_bar=4
1605 set /a WINE_foo=WINE_bar ^>^>= 2 & call :checkenvvars WINE_foo 1 WINE_bar 1
1606 set WINE_bar=1
1607 set /a WINE_foo=WINE_bar ^&= 2 & call :checkenvvars WINE_foo 0 WINE_bar 0
1608 set /a WINE_foo=WINE_bar=5, WINE_bar ^|= 2 & call :checkenvvars WINE_foo 5 WINE_bar 7
1609 set /a WINE_foo=WINE_bar=5, WINE_bar ^^= 2 & call :checkenvvars WINE_foo 5 WINE_bar 7
1610 set WINE_baz=4
1611 set /a WINE_foo=WINE_bar=19, WINE_bar %%= 4 + (WINE_baz %%= 7) & call :checkenvvars WINE_foo 19 WINE_bar 3 WINE_baz 4
1612 echo --- quotes
1613 set /a WINE_foo=1
1614 call :checkenvvars WINE_foo 1
1615 set /a "WINE_foo=1"
1616 call :checkenvvars WINE_foo 1
1617 set /a WINE_foo=1,WINE_bar=2
1618 call :checkenvvars WINE_foo 1 WINE_bar 2
1619 set /a "WINE_foo=1,WINE_bar=2"
1620 call :checkenvvars WINE_foo 1 WINE_bar 2
1621 set /a "WINE_foo=1","WINE_bar=2"
1622 call :checkenvvars WINE_foo 1 WINE_bar 2
1623 set /a ""WINE_foo=1","WINE_bar=2""
1624 call :checkenvvars WINE_foo 1 WINE_bar 2
1625 set /a WINE_foo=1,WINE_bar=2,WINE_baz=3
1626 call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3
1627 set /a "WINE_foo=1,WINE_bar=2,WINE_baz=3"
1628 call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3
1629 set /a "WINE_foo=1","WINE_bar=2","WINE_baz=3"
1630 call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3
1631 set /a ""WINE_foo=1","WINE_bar=2","WINE_baz=3""
1632 call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3
1633 set /a ""WINE_foo=1","WINE_bar=2"","WINE_baz=3"
1634 call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3
1635 set /a """"""WINE_foo=1""""""
1636 call :checkenvvars WINE_foo 1
1637 set /a """"""WINE_foo=1","WINE_bar=5""","WINE_baz=2""
1638 call :checkenvvars WINE_foo 1 WINE_bar 5 WINE_baz 2
1639 set /a WINE_foo="3"+"4"+"5+6"
1640 call :checkenvvars WINE_foo 18
1641 set WINE_foo=3
1642 set /a WINE_bar="WINE_""foo"+4
1643 call :checkenvvars WINE_foo 3 WINE_bar 7
1644 echo --- whitespace are ignored between double char operators
1645 set WINE_foo=4
1646 set WINE_bar=5
1647 set /a WINE_foo + = 6
1648 set /a WINE_bar * = WINE_foo
1649 call :checkenvvars WINE_foo 10 WINE_bar 50
1650 set WINE_foo=4
1651 set WINE_bar=5
1652 set /a WINE_foo + = "6 < < 7"
1653 set /a WINE_bar * = WINE_foo + WINE_foo
1654 call :checkenvvars WINE_foo 772 WINE_bar 7720
1655 set /a WINE_foo=6 7
1656 set /a WINE_ var1=8
1657 set WINE_foo=
1658 echo --- invalid operator sequence
1659 set WINE_foo=4
1660 set /a =4
1661 set /a *=4
1662 set /a ^>=4"
1663 set /a ^<=4"
1664 set /a WINE_foo^>^<=4
1665 echo %WINE_foo%
1666 set /a WINE_foo^>^>^>=4
1667 echo %WINE_foo%
1668 echo ----- negative prefix
1669 set /a WINE_foo=-1
1670 call :checkenvvars WINE_foo -1
1671 set /a WINE_foo=--1
1672 call :checkenvvars WINE_foo 1
1673 set /a WINE_foo=3--3
1674 call :checkenvvars WINE_foo 6
1675 set /a WINE_foo=3---3
1676 call :checkenvvars WINE_foo 0
1677 set /a WINE_foo=3----3
1678 call :checkenvvars WINE_foo 6
1679 set /a WINE_foo=-~1
1680 call :checkenvvars WINE_foo 2
1681 set /a WINE_foo=~-1
1682 call :checkenvvars WINE_foo 0
1683 set /a WINE_foo=3+-~1
1684 call :checkenvvars WINE_foo 5
1685 set /a WINE_foo=3+~-1
1686 call :checkenvvars WINE_foo 3
1687 echo ----- assignment tests involving the end destination
1688 set WINE_foo=3
1689 set /a WINE_foo+=3+(WINE_foo=4)
1690 call :checkenvvars WINE_foo 11
1691 set WINE_foo=2
1692 set /a WINE_bar=3+(WINE_foo=6)
1693 call :checkenvvars WINE_foo 6 WINE_bar 9
1694 set WINE_foo=2
1695 set /a WINE_bar=3+(WINE_foo=6,WINE_baz=7)
1696 call :checkenvvars WINE_foo 6 WINE_bar 10 WINE_baz 7
1697 set WINE_foo=2
1698 set /a WINE_bar=WINE_foo=7
1699 call :checkenvvars WINE_foo 7 WINE_bar 7
1700 echo ----- equal precedence on stack
1701 rem Unary - don't reduce if precedence is equal
1702 set /a WINE_foo=!!1
1703 call :checkenvvars WINE_foo 1
1704 set /a WINE_foo=!!0
1705 call :checkenvvars WINE_foo 0
1706 set /a WINE_foo=~~1
1707 call :checkenvvars WINE_foo 1
1708 set /a WINE_foo=~~0
1709 call :checkenvvars WINE_foo 0
1710 set /a WINE_foo=--1
1711 call :checkenvvars WINE_foo 1
1712 set /a WINE_foo=+-1
1713 call :checkenvvars WINE_foo -1
1714 set /a WINE_foo=-+1
1715 call :checkenvvars WINE_foo -1
1716 set /a WINE_foo=++1
1717 call :checkenvvars WINE_foo 1
1718 set /a WINE_foo=!~1
1719 call :checkenvvars WINE_foo 0
1720 set /a WINE_foo=~!1
1721 call :checkenvvars WINE_foo -1
1722 set /a WINE_foo=!-1
1723 call :checkenvvars WINE_foo 0
1724 set /a WINE_foo=-!1
1725 call :checkenvvars WINE_foo 0
1726 set /a WINE_foo=!-0
1727 call :checkenvvars WINE_foo 1
1728 set /a WINE_foo=-!0
1729 call :checkenvvars WINE_foo -1
1730 rem Aritmatic - Reduce if precedence is equal
1731 set /a WINE_foo=10*5/2
1732 call :checkenvvars WINE_foo 25
1733 set /a WINE_foo=5/2*10
1734 call :checkenvvars WINE_foo 20
1735 set /a WINE_foo=10/5/2
1736 call :checkenvvars WINE_foo 1
1737 set /a WINE_foo=5%%2*4
1738 call :checkenvvars WINE_foo 4
1739 set /a WINE_foo=10-5+2
1740 call :checkenvvars WINE_foo 7
1741 set /a WINE_foo=1^<^<4^>^>1
1742 call :checkenvvars WINE_foo 8
1743 rem Assignment - don't reduce if precedence is equal
1744 set /a WINE_foo=5
1745 set /a WINE_bar=WINE_foo=6
1746 call :checkenvvars WINE_foo 6 WINE_bar 6
1748 echo --- for /F
1749 mkdir foobar & cd foobar
1750 echo ------ string argument
1751 rem NT4 does not support usebackq
1752 for /F %%i in ("a b c") do echo %%i
1753 for /F %%i in ( "a b c" ) do echo X%%iX
1754 for /f usebackq %%i in ('a b c') do echo %%i>output_file
1755 if not exist output_file (echo no output) else (type output_file & del output_file)
1756 for /f usebackq %%i in ( 'a b c' ) do echo X%%iX>output_file
1757 if not exist output_file (echo no output) else (type output_file & del output_file)
1758 for /f %%i in ("a ") do echo %%i
1759 for /f usebackq %%i in ('a ') do echo %%i>output_file
1760 if not exist output_file (echo no output) else (type output_file & del output_file)
1761 for /f %%i in ("a") do echo %%i
1762 for /f usebackq %%i in ('a') do echo %%i>output_file
1763 if not exist output_file (echo no output) else (type output_file & del output_file)
1764 fOr /f %%i in (" a") do echo %%i
1765 for /f usebackq %%i in (' a') do echo %%i>output_file
1766 if not exist output_file (echo no output) else (type output_file & del output_file)
1767 for /f %%i in (" a ") do echo %%i
1768 for /f usebackq %%i in (' a ') do echo %%i>output_file
1769 if not exist output_file (echo no output) else (type output_file & del output_file)
1770 echo ------ fileset argument
1771 echo --------- basic blank handling
1772 echo a b c>foo
1773 for /f %%i in (foo) do echo %%i
1774 echo a >foo
1775 for /f %%i in (foo) do echo %%i
1776 echo a>foo
1777 for /f %%i in (foo) do echo %%i
1778 echo a>foo
1779 for /f %%i in (foo) do echo %%i
1780 echo a >foo
1781 for /f %%i in (foo) do echo %%i
1782 echo. > foo
1783 for /f %%i in (foo) do echo %%i
1784 echo. >> foo
1785 echo b > foo
1786 for /f %%i in (foo) do echo %%i
1787 echo --------- multi-line with empty lines
1788 echo a Z f> foo
1789 echo. >> foo
1790 echo.>> foo
1791 echo b bC>> foo
1792 echo c>> foo
1793 echo. >> foo
1794 for /f %%b in (foo) do echo %%b
1795 echo --------- multiple files
1796 echo q w > bar
1797 echo.>> bar
1798 echo kkk>>bar
1799 for /f %%k in (foo bar) do echo %%k
1800 for /f %%k in (bar foo) do echo %%k
1801 echo ------ command argument
1802 rem Not implemented on NT4, need to skip it as no way to get output otherwise
1803 if "%CD%"=="" goto :SkipFORFcmdNT4
1804 for /f %%i in ('echo.Passed1') do echo %%i
1805 for /f "usebackq" %%i in (`echo.Passed2`) do echo %%i
1806 for /f usebackq %%i in (`echo.Passed3`) do echo %%i
1807 for /f "usebackq" %%i in (`"c:\windows\system32\cmd.exe" /C echo Passed4`) do echo %%i
1808 for /f "usebackq" %%i in (`""c:\windows\system32\cmd.exe" /C echo Passed5"`) do echo %%i
1809 for /f %%i in ( 'echo.Passed6' ) do echo %%i
1810 for /f "usebackq" %%i in ( `echo.Passed7` ) do echo %%i
1811 goto :ContinueFORF
1812 :SkipFORFcmdNT4
1813 for /l %%i in (1,1,7) do echo Missing functionality - Broken%%i
1814 :ContinueFORF
1815 rem FIXME: Rest not testable right now in wine: not implemented and would need
1816 rem preliminary grep-like program implementation (e.g. like findstr or fc) even
1817 rem for a simple todo_wine test
1818 rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported
1819 rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported
1820 echo ------ eol option
1821 if "%CD%"=="" goto :SkipFORFeolNT4
1822 echo Line one>foo
1823 echo and Line two>>foo
1824 echo Line three>>foo
1825 for /f "eol=L" %%i in (foo) do echo %%i
1826 for /f "eol=a" %%i in (foo) do echo %%i
1827 del foo
1828 goto :ContinueFORFeol
1829 :SkipFORFeolNT4
1830 for /l %%i in (1,1,3) do echo Broken NT4 functionality%%i
1831 :ContinueFORFeol
1832 for /f "eol=@" %%i in (" ad") do echo %%i
1833 for /f "eol=@" %%i in (" z@y") do echo %%i
1834 for /f "eol=|" %%i in ("a|d") do echo %%i
1835 for /f "eol=@" %%i in ("@y") do echo %%i > output_file
1836 if not exist output_file (echo no output) else (del output_file)
1837 for /f "eol==" %%i in ("=y") do echo %%i > output_file
1838 if not exist output_file (echo no output) else (del output_file)
1839 echo ------ delims option
1840 for /f "delims=|" %%i in ("a|d") do echo %%i
1841 for /f "delims=|" %%i in ("a |d") do echo %%i
1842 for /f "delims=|" %%i in ("a d|") do echo %%i
1843 for /f "delims=| " %%i in ("a d|") do echo %%i
1844 for /f "delims==" %%i in ("C r=d|") do echo %%i
1845 for /f "delims=" %%i in ("foo bar baz") do echo %%i
1846 for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi
1847 echo ------ skip option
1848 echo a > foo
1849 echo b >> foo
1850 echo c >> foo
1851 for /f "skip=2" %%i in (foo) do echo %%i
1852 for /f "skip=3" %%i in (foo) do echo %%i > output_file
1853 if not exist output_file (echo no output) else (del output_file)
1854 for /f "skip=4" %%i in (foo) do echo %%i > output_file
1855 if not exist output_file (echo no output) else (del output_file)
1856 for /f "skip=02" %%i in (foo) do echo %%i
1857 for /f "skip=0x2" %%i in (foo) do echo %%i
1858 for /f "skip=1" %%i in ("skipme") do echo %%i > output_file
1859 if not exist output_file (echo no output) else (del output_file)
1860 echo ------ tokens= option
1861 rem Basic
1862 for /f %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o
1863 for /f "tokens=2" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o
1864 for /f "tokens=1,3,5-7" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o
1865 rem Show * means the rest
1866 for /f "tokens=1,5*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o
1867 for /f "tokens=6,9*" %%i in ("a b c d e f g h i j k l m n o p q r s t u v w x y z") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o
1868 rem Show * means the rest (not tokenized and rebuilt)
1869 for /f "tokens=6,9*" %%i in ("a b c d e f g h i j k l m n;;== o p q r s t u v w x y z") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o
1870 rem Order is irrelevant
1871 for /f "tokens=1,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1872 for /f "tokens=3,2,1*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1873 rem Duplicates are ignored
1874 for /f "tokens=1,2,1*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1875 rem Large tokens are allowed
1876 for /f "tokens=25,1,5*" %%i in ("a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1877 rem Show tokens blanked in advance regardless of uniqueness of requested tokens
1878 for /f "tokens=1,1,1,2*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1879 for /f "tokens=1-2,1-2,1-2" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1880 rem Show No wrapping from z to A BUT wrapping sort of occurs Z to a occurs
1881 for /f "tokens=1-20" %%u in ("a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z") do echo u=%%u v=%%v w=%%w x=%%x y=%%y z=%%z A=%%A a=%%a
1882 for /f "tokens=1-20" %%U in ("a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z") do echo U=%%U V=%%V W=%%W X=%%X Y=%%Y Z=%%Z A=%%A a=%%a
1883 rem Show negative ranges have no effect
1884 for /f "tokens=1-3,5" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o
1885 for /f "tokens=3-1,5" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o
1886 rem Show duplicates stop * from working
1887 for /f "tokens=1,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1888 for /f "tokens=1,1,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1889 for /f "tokens=2,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1890 for /f "tokens=3,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o
1891 rem Special case tokens=* or tokens=n,*
1892 echo 3.14>testfile
1893 FOR /F "tokens=*" %%A IN (testfile) DO @echo 1:%%A,%%B
1894 FOR /F "tokens=1*" %%A IN (testfile) DO @echo 2:%%A,%%B
1895 FOR /F "tokens=2*" %%A IN (testfile) DO @echo 3:%%A,%%B
1896 FOR /F "tokens=1,* delims=." %%A IN (testfile) DO @echo 4:%%A,%%B
1897 del testfile
1898 cd ..
1899 rd /s/q foobar
1900 echo ------ parameter splitting
1901 echo forFParameterSplittingFunc "myparam1=myvalue1 myparam2=myparam2" mytest> foo
1902 for /f "tokens=1 delims=;" %%i in (foo) do (call :%%i)
1903 del foo
1904 for /f "tokens=1 delims=;" %%i in ("forFParameterSplittingFunc "myparam1^=myvalue1 myparam2^=myparam2" mytest") do (call :%%i)
1905 goto :forFParameterSplittingEnd
1906 :forFParameterSplittingFunc
1907 echo %~0 %~1 %~2 %~3 %~4 %~5
1908 goto :eof
1909 :forFParameterSplittingEnd
1910 echo 3.14>testfile
1911 FOR /F "delims=. tokens=*" %%A IN (testfile) DO @echo 4:%%A,%%B
1912 FOR /F "delims=. tokens=1*" %%A IN (testfile) DO @echo 5:%%A,%%B
1913 FOR /F "delims=. tokens=2*" %%A IN (testfile) DO @echo 6:%%A,%%B
1914 FOR /F "delims=. tokens=3*" %%A IN (testfile) DO @echo 7:%%A,%%B
1915 del testfile
1917 echo ------------ Testing del ------------
1918 echo abc > file
1919 echo deleting 'file'
1920 del file
1921 if errorlevel 0 (
1922 echo errorlevel is 0, good
1923 ) else (
1924 echo unexpected errorlevel, got %errorlevel%
1926 if not exist file (
1927 echo successfully deleted 'file'
1928 ) else (
1929 echo error deleting 'file'
1931 echo attempting to delete 'file', even though it is not present
1932 del file
1933 if errorlevel 0 (
1934 echo errorlevel is 0, good
1935 ) else (
1936 echo unexpected errorlevel, got %errorlevel%
1939 echo ------------ Testing del /a ------------
1940 del /f/q *.test > nul
1941 echo r > r.test
1942 attrib +r r.test
1943 echo not-r > not-r.test
1945 if not exist not-r.test echo not-r.test not found before delete, bad
1946 del /a:-r *.test
1947 if not exist not-r.test echo not-r.test not found after delete, good
1949 if not exist r.test echo r.test not found before delete, bad
1950 if exist r.test echo r.test found before delete, good
1951 del /a:r *.test
1952 if not exist r.test echo r.test not found after delete, good
1953 if exist r.test echo r.test found after delete, bad
1955 echo ------------ Testing del /q ------------
1956 mkdir del_q_dir
1957 cd del_q_dir
1958 echo abc > file1
1959 echo abc > file2.dat
1960 rem If /q doesn't work, cmd will prompt and the test case should hang
1961 del /q * > nul
1962 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
1963 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
1964 cd ..
1965 rmdir del_q_dir
1967 echo ------------ Testing del /s ------------
1968 mkdir "foo bar"
1969 cd "foo bar"
1970 mkdir "foo:"
1971 echo hi > file1.dat
1972 echo there > file2.dat
1973 echo bub > file3.dat
1974 echo bye > "file with spaces.dat"
1975 cd ..
1976 del /s file1.dat > nul
1977 del file2.dat /s > nul
1978 del "file3.dat" /s > nul
1979 del "file with spaces.dat" /s > nul
1980 cd "foo bar"
1981 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
1982 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
1983 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
1984 if exist "file with spaces.dat" del "file with spaces.dat"
1985 rmdir "foo:"
1986 cd ..
1987 rmdir "foo bar"
1989 echo ------------ Testing rename ------------
1990 mkdir foobar & cd foobar
1991 echo --- ren and rename are synonymous
1992 echo > foo
1993 rename foo bar
1994 if exist foo echo foo should be renamed!
1995 if exist bar echo foo renamed to bar
1996 ren bar foo
1997 if exist bar echo bar should be renamed!
1998 if exist foo echo bar renamed to foo
1999 echo --- name collision
2000 echo foo>foo
2001 echo bar>bar
2002 ren foo bar 2> nul
2003 type foo
2004 type bar
2005 rem no-op
2006 ren foo foo
2007 mkdir baz
2008 ren foo baz\abc
2009 echo --- rename read-only files
2010 echo > file1
2011 attrib +r file1
2012 ren file1 file2
2013 if not exist file1 (
2014 if exist file2 (
2015 echo read-only file renamed
2017 ) else (
2018 echo read-only file not renamed!
2020 echo --- rename directories
2021 mkdir rep1
2022 ren rep1 rep2
2023 if not exist rep1 (
2024 if exist rep2 (
2025 echo dir renamed
2028 attrib +r rep2
2029 ren rep2 rep1
2030 if not exist rep2 (
2031 if exist rep1 (
2032 echo read-only dir renamed
2035 echo --- rename in other directory
2036 if not exist baz\abc (
2037 echo rename impossible in other directory
2038 if exist foo echo original file still present
2039 ) else (
2040 echo shouldn't rename in other directory!
2041 if not exist foo echo original file not present anymore
2043 cd .. & rd /s/q foobar
2045 echo ------------ Testing move ------------
2046 mkdir foobar & cd foobar
2047 echo --- file move
2048 echo >foo
2049 move foo bar > nul 2>&1
2050 if not exist foo (
2051 if exist bar (
2052 echo file move succeeded
2055 echo bar>bar
2056 echo baz> baz
2057 move /Y bar baz > nul 2>&1
2058 if not exist bar (
2059 if exist baz (
2060 echo file move with overwrite succeeded
2062 ) else (
2063 echo file overwrite impossible!
2064 del bar
2066 type baz
2068 attrib +r baz
2069 move baz bazro > nul 2>&1
2070 if not exist baz (
2071 if exist bazro (
2072 echo read-only files are moveable
2073 move bazro baz > nul 2>&1
2075 ) else (
2076 echo read-only file not moved!
2078 attrib -r baz
2079 mkdir rep
2080 move baz rep > nul 2>&1
2081 if not exist baz (
2082 if exist rep\baz (
2083 echo file moved in subdirectory
2086 call :setError 0
2087 move rep\baz . > nul 2>&1
2088 move /Y baz baz > nul 2>&1
2089 if errorlevel 1 (
2090 echo moving a file to itself should be a no-op!
2091 ) else (
2092 echo moving a file to itself is a no-op
2094 echo ErrorLevel: %ErrorLevel%
2095 call :setError 0
2096 del baz
2097 echo --- directory move
2098 mkdir foo\bar
2099 mkdir baz
2100 echo baz2>baz\baz2
2101 move baz foo\bar > nul 2>&1
2102 if not exist baz (
2103 if exist foo\bar\baz\baz2 (
2104 echo simple directory move succeeded
2107 call :setError 0
2108 mkdir baz
2109 move baz baz > nul 2>&1
2110 echo moving a directory to itself gives error; errlevel %ErrorLevel%
2111 echo ------ dir in dir move
2112 rd /s/q foo
2113 mkdir foo bar
2114 echo foo2>foo\foo2
2115 echo bar2>bar\bar2
2116 move foo bar > nul 2>&1
2117 if not exist foo (
2118 if exist bar (
2119 dir /b /ad bar
2120 dir /b /a-d bar
2121 dir /b bar\foo
2124 cd .. & rd /s/q foobar
2126 echo ------------ Testing mkdir ------------
2127 call :setError 0
2128 echo --- md and mkdir are synonymous
2129 mkdir foobar
2130 echo %ErrorLevel%
2131 rmdir foobar
2132 md foobar
2133 echo %ErrorLevel%
2134 rmdir foobar
2135 echo --- creating an already existing directory/file must fail
2136 mkdir foobar
2137 md foobar
2138 echo %ErrorLevel%
2139 rmdir foobar
2140 echo > foobar
2141 mkdir foobar
2142 echo %ErrorLevel%
2143 del foobar
2144 echo --- multilevel path creation
2145 mkdir foo
2146 echo %ErrorLevel%
2147 mkdir foo\bar\baz
2148 echo %ErrorLevel%
2149 cd foo
2150 echo %ErrorLevel%
2151 cd bar
2152 echo %ErrorLevel%
2153 cd baz
2154 echo %ErrorLevel%
2155 echo > ..\..\bar2
2156 mkdir ..\..\..\foo\bar2
2157 echo %ErrorLevel%
2158 del ..\..\bar2
2159 mkdir ..\..\..\foo\bar2
2160 echo %ErrorLevel%
2161 rmdir ..\..\..\foo\bar2
2162 cd ..
2163 rmdir baz
2164 cd ..
2165 rmdir bar
2166 cd ..
2167 rmdir foo
2168 echo %ErrorLevel%
2169 echo --- trailing backslashes
2170 mkdir foo\\\\
2171 echo %ErrorLevel%
2172 if exist foo (rmdir foo & echo dir created
2173 ) else ( echo dir not created )
2174 echo %ErrorLevel%
2175 echo --- invalid chars
2176 mkdir ?
2177 echo mkdir ? gives errorlevel %ErrorLevel%
2178 call :setError 0
2179 mkdir ?\foo
2180 echo mkdir ?\foo gives errorlevel %ErrorLevel%
2181 call :setError 0
2182 mkdir foo\?
2183 echo mkdir foo\? gives errorlevel %ErrorLevel%
2184 if exist foo (rmdir foo & echo ok, foo created
2185 ) else ( echo foo not created )
2186 call :setError 0
2187 mkdir foo\bar\?
2188 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
2189 call :setError 0
2190 if not exist foo (
2191 echo bad, foo not created
2192 ) else (
2193 cd foo
2194 if exist bar (
2195 echo ok, foo\bar created
2196 rmdir bar
2198 cd ..
2199 rmdir foo
2201 echo --- multiple directories at once
2202 mkdir foobaz & cd foobaz
2203 mkdir foo bar\baz foobar "bazbaz" .\"zabzab"
2204 if exist foo (echo foo created) else echo foo not created!
2205 if exist bar (echo bar created) else echo bar not created!
2206 if exist foobar (echo foobar created) else echo foobar not created!
2207 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
2208 if exist bazbaz (echo bazbaz created) else echo bazbaz not created!
2209 if exist zabzab (echo zabzab created) else echo zabzab not created!
2210 cd .. & rd /s/q foobaz
2211 call :setError 0
2212 mkdir foo\*
2213 echo mkdir foo\* errorlevel %ErrorLevel%
2214 if exist foo (rmdir foo & echo ok, foo created
2215 ) else ( echo bad, foo not created )
2217 echo ------------ Testing rmdir ------------
2218 call :setError 0
2219 rem rd and rmdir are synonymous
2220 mkdir foobar
2221 rmdir foobar
2222 echo %ErrorLevel%
2223 if not exist foobar echo dir removed
2224 mkdir foobar
2225 rd foobar
2226 echo %ErrorLevel%
2227 if not exist foobar echo dir removed
2228 rem Removing nonexistent directory
2229 rmdir foobar
2230 echo %ErrorLevel%
2231 rem Removing single-level directories
2232 echo > foo
2233 rmdir foo
2234 echo %ErrorLevel%
2235 if exist foo echo file not removed
2236 del foo
2237 mkdir foo
2238 echo > foo\bar
2239 rmdir foo
2240 echo %ErrorLevel%
2241 if exist foo echo non-empty dir not removed
2242 del foo\bar
2243 mkdir foo\bar
2244 rmdir foo
2245 echo %ErrorLevel%
2246 if exist foo echo non-empty dir not removed
2247 rmdir foo\bar
2248 rmdir foo
2249 rem Recursive rmdir
2250 mkdir foo\bar\baz
2251 rmdir /s /Q foo
2252 if not exist foo (
2253 echo recursive rmdir succeeded
2254 ) else (
2255 rd foo\bar\baz
2256 rd foo\bar
2257 rd foo
2259 mkdir foo\bar\baz
2260 echo foo > foo\bar\brol
2261 rmdir /s /Q foo 2>&1
2262 if not exist foo (
2263 echo recursive rmdir succeeded
2264 ) else (
2265 rd foo\bar\baz
2266 del foo\bar\brol
2267 rd foo\bar
2268 rd foo
2270 rem multiples directories at once
2271 mkdir foobaz & cd foobaz
2272 mkdir foo
2273 mkdir bar\baz
2274 mkdir foobar
2275 rd /s/q foo bar foobar
2276 if not exist foo (echo foo removed) else echo foo not removed!
2277 if not exist bar (echo bar removed) else echo bar not removed!
2278 if not exist foobar (echo foobar removed) else echo foobar not removed!
2279 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
2280 cd .. & rd /s/q foobaz
2282 echo ------------ Testing pushd/popd ------------
2284 echo --- popd is no-op when dir stack is empty
2285 popd
2287 echo --- pushing non-existing dir
2288 pushd foobar
2290 echo --- basic behaviour
2291 mkdir foobar\baz
2292 pushd foobar
2294 popd
2296 pushd foobar
2297 pushd baz
2299 popd
2301 pushd baz
2302 popd
2304 popd
2306 pushd .
2307 cd foobar\baz
2308 pushd ..
2310 popd
2311 popd
2313 rd /s/q foobar
2315 echo ------------ Testing attrib ------------
2316 rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications
2317 mkdir foobar & cd foobar
2318 echo foo original contents> foo
2319 attrib foo
2320 echo > bar
2321 echo --- read-only attribute
2322 rem Read-only files cannot be altered or deleted, unless forced
2323 attrib +R foo
2324 attrib foo
2325 dir /Ar /B
2326 echo bar>> foo
2327 type foo
2328 del foo > NUL 2>&1
2329 if exist foo (
2330 echo Read-only file not deleted
2331 ) else (
2332 echo Should not delete read-only file!
2334 del /F foo
2335 if not exist foo (
2336 echo Read-only file forcibly deleted
2337 ) else (
2338 echo Should delete read-only file with del /F!
2339 attrib -r foo
2340 del foo
2342 cd .. & rd /s/q foobar
2343 echo --- recursive behaviour
2344 mkdir foobar\baz & cd foobar
2345 echo > level1
2346 echo > whatever
2347 echo > baz\level2
2348 attrib baz\level2
2349 cd ..
2350 attrib +R l*vel? /S > nul 2>&1
2351 cd foobar
2352 attrib level1
2353 attrib baz\level2
2354 echo > bar
2355 attrib bar
2356 cd .. & rd /s/q foobar
2357 echo --- folders processing
2358 mkdir foobar
2359 attrib foobar
2360 cd foobar
2361 mkdir baz
2362 echo toto> baz\toto
2363 attrib +r baz /s /d > nul 2>&1
2364 attrib baz
2365 attrib baz\toto
2366 echo lulu>>baz\toto
2367 type baz\toto
2368 echo > baz\lala
2369 rem Oddly windows allows file creation in a read-only directory...
2370 if exist baz\lala (echo file created in read-only dir) else echo file not created
2371 cd .. & rd /s/q foobar
2373 echo ------------ Testing assoc ------------
2374 rem Modifying associations requires some privileges...
2375 net session >nul 2>&1
2376 if errorlevel 1 goto :SkipAssoc
2378 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
2379 rem FIXME Revise once || conditional execution is fixed
2380 mkdir foobar & cd foobar
2381 echo --- setting association
2382 assoc .foo > baz
2383 type baz
2384 echo ---
2386 assoc .foo=bar
2387 assoc .foo
2389 rem association set system-wide
2390 echo @echo off> tmp.cmd
2391 echo echo +++>> tmp.cmd
2392 echo assoc .foo>> tmp.cmd
2393 cmd /c tmp.cmd
2395 echo --- resetting association
2396 assoc .foo=
2397 assoc .foo > baz
2398 type baz
2399 echo ---
2401 rem association removal set system-wide
2402 cmd /c tmp.cmd > baz
2403 type baz
2404 echo ---
2405 cd .. & rd /s/q foobar
2406 goto ContinueFType
2407 :SkipAssoc
2408 echo --- setting association
2409 echo ---
2410 echo .foo=bar
2411 echo .foo=bar
2412 echo +++
2413 echo .foo=bar
2414 echo --- resetting association
2415 echo ---
2416 echo +++
2417 echo ---
2420 :ContinueFType
2421 echo ------------ Testing ftype ------------
2422 rem Modifying associations requires some privileges...
2423 net session >nul 2>&1
2424 if errorlevel 1 goto :SkipFType
2425 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
2426 rem FIXME Revise once || conditional execution is fixed
2427 mkdir foobar & cd foobar
2428 echo --- setting association
2429 ftype footype> baz
2430 type baz
2431 echo ---
2433 ftype footype=foo_opencmd
2434 assoc .foo=footype
2435 ftype footype
2437 rem association set system-wide
2438 echo @echo off> tmp.cmd
2439 echo echo +++>> tmp.cmd
2440 echo ftype footype>> tmp.cmd
2441 cmd /c tmp.cmd
2443 echo --- resetting association
2444 assoc .foo=
2446 rem Removing a file type association doesn't work on XP due to a bug, so a workaround is needed
2447 setlocal EnableDelayedExpansion
2448 set WINE_FOO=original value
2449 ftype footype=
2450 ftype footype > baz
2451 for /F %%i in ('type baz') do (set WINE_FOO=buggyXP)
2452 rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion)
2453 rem FIXME Revisit once a grep-like program like ftype is implemented
2454 rem (e.g. to check baz's size using dir /b instead)
2455 echo !WINE_FOO!
2457 rem cleanup registry
2458 echo REGEDIT4> regCleanup.reg
2459 echo.>> regCleanup.reg
2460 echo [-HKEY_CLASSES_ROOT\footype]>> regCleanup.reg
2461 regedit /s regCleanup.reg
2462 set WINE_FOO=
2463 endlocal
2464 cd .. & rd /s/q foobar
2465 goto ContinueCall
2466 :SkipFType
2467 echo --- setting association
2468 echo ---
2469 echo footype=foo_opencmd
2470 echo .foo=footype
2471 echo footype=foo_opencmd
2472 echo +++
2473 echo footype=foo_opencmd
2474 echo --- resetting association
2475 echo original value
2477 :ContinueCall
2478 echo ------------ Testing CALL ------------
2479 mkdir foobar & cd foobar
2480 echo --- external script
2481 echo echo foo %%1> foo.cmd
2482 call foo
2483 call foo.cmd 8
2484 echo echo %%1 %%2 > foo.cmd
2485 call foo.cmd foo
2486 call foo.cmd foo bar
2487 call foo.cmd foo ""
2488 call foo.cmd "" bar
2489 call foo.cmd foo ''
2490 call foo.cmd '' bar
2491 del foo.cmd
2493 echo --- internal routines
2494 call :testRoutine :testRoutine
2495 goto :endTestRoutine
2496 :testRoutine
2497 echo bar %1
2498 goto :eof
2499 :endTestRoutine
2501 call :testRoutineArgs foo
2502 call :testRoutineArgs foo bar
2503 call :testRoutineArgs foo ""
2504 call :testRoutineArgs "" bar
2505 call :testRoutineArgs foo ''
2506 call :testRoutineArgs '' bar
2507 goto :endTestRoutineArgs
2508 :testRoutineArgs
2509 echo %1 %2
2510 goto :eof
2511 :endTestRoutineArgs
2513 echo --- with builtins
2514 call mkdir foo
2515 echo %ErrorLevel%
2516 if exist foo (echo foo created) else echo foo should exist!
2517 rmdir foo
2518 set WINE_FOOBAZ_VAR=foobaz
2519 call echo Should expand %WINE_FOOBAZ_VAR%
2520 set WINE_FOOBAZ_VAR=
2521 echo>batfile
2522 call dir /b
2523 echo>robinfile
2524 if 1==1 call del batfile
2525 dir /b
2526 if exist batfile echo batfile shouldn't exist
2527 rem ... but not for 'if' or 'for'
2528 call if 1==1 echo bar 2> nul
2529 echo %ErrorLevel%
2530 call :setError 0
2531 call for %%i in (foo bar baz) do echo %%i 2> nul
2532 echo %ErrorLevel%
2533 rem First look for programs in the path before trying a builtin
2534 echo echo non-builtin dir> dir.cmd
2535 call dir /b
2536 del dir.cmd
2537 rem The below line equates to call (, which does nothing, then the
2538 rem subsequent lines are executed.
2539 call (
2540 echo Line one
2541 echo Line two
2543 rem The below line equates to call if, which always fails, then the
2544 rem subsequent lines are executed. Note cmd.exe swallows all lines
2545 rem starting with )
2546 call if 1==1 (
2547 echo Get if
2548 ) else (
2549 echo ... and else!
2551 call call call echo passed
2552 cd .. & rd /s/q foobar
2554 echo ------------ Testing SHIFT ------------
2556 call :shiftFun p1 p2 p3 p4 p5
2557 goto :endShiftFun
2559 :shiftFun
2560 echo '%1' '%2' '%3' '%4' '%5'
2561 shift
2562 echo '%1' '%2' '%3' '%4' '%5'
2563 shift@tab@ /1
2564 echo '%1' '%2' '%3' '%4' '%5'
2565 shift /2
2566 echo '%1' '%2' '%3' '%4' '%5'
2567 shift /-1
2568 echo '%1' '%2' '%3' '%4' '%5'
2569 shift /0
2570 echo '%1' '%2' '%3' '%4' '%5'
2571 goto :eof
2572 :endShiftFun
2574 echo ------------ Testing cmd invocation ------------
2575 rem FIXME: only a stub ATM
2576 echo --- a batch file can delete itself
2577 echo del foo.cmd>foo.cmd
2578 cmd /q /c foo.cmd
2579 if not exist foo.cmd (
2580 echo file correctly deleted
2581 ) else (
2582 echo file should be deleted!
2583 del foo.cmd
2585 echo --- a batch file can alter itself
2586 echo echo bar^>foo.cmd>foo.cmd
2587 cmd /q /c foo.cmd > NUL 2>&1
2588 if exist foo.cmd (
2589 type foo.cmd
2590 del foo.cmd
2591 ) else (
2592 echo file not created!
2595 echo ---------- Testing copy
2596 md foobar2
2597 cd foobar2
2598 rem Note echo adds 0x0d 0x0a on the end of the line in the file
2599 echo AAA> file1
2600 echo BBBBBB> file2
2601 echo CCCCCCCCC> file3
2602 md dir1
2603 goto :testcopy
2605 :CheckExist
2606 if exist "%1" (
2607 echo Passed: Found expected %1
2608 ) else (
2609 echo Failed: Did not find expected %1
2611 del /q "%1" >nul 2>&1
2612 shift
2613 if not "%1"=="" goto :CheckExist
2614 goto :eof
2616 :CheckNotExist
2617 if not exist "%1" (
2618 echo Passed: Did not find %1
2619 ) else (
2620 echo Failed: Unexpectedly found %1
2621 del /q "%1" >nul 2>&1
2623 shift
2624 if not "%1"=="" goto :CheckNotExist
2625 goto :eof
2627 rem Note: No way to check file size on NT4 so skip the test
2628 :CheckFileSize
2629 if not exist "%1" (
2630 echo Failed: File missing when requested filesize check [%2]
2631 goto :ContinueFileSizeChecks
2633 for %%i in (%1) do set WINE_filesize=%%~zi
2634 if "%WINE_filesize%"=="%2" (
2635 echo Passed: file size check on %1 [%WINE_filesize%]
2636 ) else (
2637 if "%WINE_filesize%"=="%%~zi" (
2638 echo Skipping file size check on NT4
2639 ) else (
2640 echo Failed: file size check on %1 [%WINE_filesize% != %2]
2643 :ContinueFileSizeChecks
2644 shift
2645 shift
2646 if not "%1"=="" goto :CheckFileSize
2647 goto :eof
2649 :testcopy
2651 rem -----------------------
2652 rem Simple single file copy
2653 rem -----------------------
2654 rem Simple single file copy, normally used syntax
2655 copy file1 dummy.file >nul 2>&1
2656 if errorlevel 1 echo Incorrect errorlevel
2657 call :CheckExist dummy.file
2659 rem Simple single file copy, destination supplied as two forms of directory
2660 copy file1 dir1 >nul 2>&1
2661 if errorlevel 1 echo Incorrect errorlevel
2662 call :CheckExist dir1\file1
2664 copy file1 dir1\ >nul 2>&1
2665 if errorlevel 1 echo Incorrect errorlevel
2666 call :CheckExist dir1\file1
2668 rem Simple single file copy, destination supplied as fully qualified destination
2669 copy file1 dir1\file99 >nul 2>&1
2670 if errorlevel 1 echo Incorrect errorlevel
2671 call :CheckExist dir1\file99
2673 rem Simple single file copy, destination not supplied
2674 cd dir1
2675 copy ..\file1 >nul 2>&1
2676 if errorlevel 1 echo Incorrect errorlevel
2677 call :CheckExist file1
2678 cd ..
2680 rem Simple single file copy, destination supplied as nonexistent directory
2681 copy file1 dir2\ >nul 2>&1
2682 if not errorlevel 1 echo Incorrect errorlevel
2683 call :CheckNotExist dir2 dir2\file1
2685 rem -----------------------
2686 rem Wildcarded copy
2687 rem -----------------------
2688 rem Simple single file copy, destination supplied as two forms of directory
2689 copy file? dir1 >nul 2>&1
2690 if errorlevel 1 echo Incorrect errorlevel
2691 call :CheckExist dir1\file1 dir1\file2 dir1\file3
2693 copy file* dir1\ >nul 2>&1
2694 if errorlevel 1 echo Incorrect errorlevel
2695 call :CheckExist dir1\file1 dir1\file2 dir1\file3
2697 rem Simple single file copy, destination not supplied
2698 cd dir1
2699 copy ..\file*.* >nul 2>&1
2700 if errorlevel 1 echo Incorrect errorlevel
2701 call :CheckExist file1 file2 file3
2702 cd ..
2704 rem Simple wildcarded file copy, destination supplied as nonexistent directory
2705 copy file? dir2\ >nul 2>&1
2706 if not errorlevel 1 echo Incorrect errorlevel
2707 call :CheckNotExist dir2 dir2\file1 dir2\file2 dir2\file3
2709 rem ------------------------------------------------
2710 rem Confirm overwrite works (cannot test prompting!)
2711 rem ------------------------------------------------
2712 copy file1 testfile >nul 2>&1
2713 copy /y file2 testfile >nul 2>&1
2714 call :CheckExist testfile
2716 rem ------------------------------------------------
2717 rem Test concatenation
2718 rem ------------------------------------------------
2719 rem simple case, no wildcards
2720 copy file1+file2 testfile >nul 2>&1
2721 if errorlevel 1 echo Incorrect errorlevel
2722 call :CheckExist testfile
2724 rem simple case, wildcards, no concatenation
2725 copy file* testfile >nul 2>&1
2726 if errorlevel 1 echo Incorrect errorlevel
2727 call :CheckExist testfile
2729 rem simple case, wildcards, and concatenation
2730 echo ddddd > fred
2731 copy file*+fred testfile >nul 2>&1
2732 if errorlevel 1 echo Incorrect errorlevel
2733 call :CheckExist testfile
2735 rem simple case, wildcards, and concatenation
2736 copy fred+file* testfile >nul 2>&1
2737 if errorlevel 1 echo Incorrect errorlevel
2738 call :CheckExist testfile
2740 rem Calculate destination name
2741 copy fred+file* dir1 >nul 2>&1
2742 if errorlevel 1 echo Incorrect errorlevel
2743 call :CheckExist dir1\fred
2745 rem Calculate destination name
2746 copy fred+file* dir1\ >nul 2>&1
2747 if errorlevel 1 echo Incorrect errorlevel
2748 call :CheckExist dir1\fred
2750 rem Calculate destination name (none supplied)
2751 cd dir1
2752 copy ..\fred+..\file* >nul 2>&1
2753 if errorlevel 1 echo Incorrect errorlevel
2754 call :CheckExist fred
2756 copy ..\fr*+..\file1 >nul 2>&1
2757 if errorlevel 1 echo Incorrect errorlevel
2758 call :CheckExist fred
2759 cd ..
2761 rem ******************************************************************
2762 rem ASCII and BINARY tests
2763 rem Note: hard coded numbers deliberate because need to ensure whether
2764 rem an additional EOF has been added or not. There is no way to handle
2765 rem EOFs in batch, so assume if a single byte appears, it's an EOF!
2766 rem ******************************************************************
2768 rem Confirm original sizes of file1,2,3
2769 call :CheckFileSize file1 5 file2 8 file3 11
2771 cd dir1
2773 rem ----------------------------------------------
2774 rem Show concatenation defaults copy to ascii mode
2775 rem ----------------------------------------------
2776 rem Simple default copy source to destination (should not append EOF 5)
2777 copy ..\file1 file1_default >nul 2>&1
2778 call :CheckFileSize file1_default 5
2780 rem Simple binary copy source to destination (should not append EOF 5)
2781 copy /b ..\file1 file1_default2 >nul 2>&1
2782 call :CheckFileSize file1_default2 5
2784 rem Simple ascii copy source to destination (should append EOF 5+1, 8+1, 11+1)
2785 copy /a ..\file1 file1_plus_eof >nul 2>&1
2786 call :CheckFileSize file1_plus_eof 6
2787 copy /a ..\file2 file2_plus_eof >nul 2>&1
2788 call :CheckFileSize file2_plus_eof 9
2789 copy /a ..\file3 file3_plus_eof >nul 2>&1
2790 call :CheckFileSize file3_plus_eof 12
2792 rem Concat 2 files, ascii mode - (only one EOF on the end 5+8+1)
2793 copy /a ..\file1+..\file2 file12_plus_eof >nul 2>&1
2794 call :CheckFileSize file12_plus_eof 14
2796 rem Concat 2 files, binary mode - (no EOF on the end 5+8)
2797 copy /b ..\file1+..\file2 file12_no_eof >nul 2>&1
2798 call :CheckFileSize file12_no_eof 13
2800 rem Concat 2 files, default mode - (one EOF on the end 5+8+1)
2801 copy ..\file1+..\file2 file12_eof2 >nul 2>&1
2802 call :CheckFileSize file12_eof2 14
2804 rem Test copying when destination is one of the sources.
2805 rem Concat file1+file2+file3 into file1, should produce file1+file2+file3 = 24
2806 copy /y ..\file? .\ >nul 2>&1
2807 copy /y /b file1+file2+file3 file1 >nul 2>&1
2808 call :CheckFileSize file1 24
2810 rem Concat file1+file2+file3 into file2, should produce file1+file3 = 16
2811 copy /y ..\file? .\ >nul 2>&1
2812 copy /y /b file1+file2+file3 file2 >nul 2>&1
2813 call :CheckFileSize file2 16
2815 rem Concat file1+file2+file3 into file3, should produce file1+file2 = 13
2816 copy /y ..\file? .\ >nul 2>&1
2817 copy /y /b file1+file2+file3 file3 >nul 2>&1
2818 call :CheckFileSize file3 13
2820 rem --------------------------------------------------------------
2821 rem Show ascii source copy stops at first EOF, binary does the lot
2822 rem --------------------------------------------------------------
2823 copy file1_plus_eof /b file1_binary_srccopy /b >nul 2>&1
2824 call :CheckFileSize file1_binary_srccopy 6
2826 copy file1_plus_eof /a file1_ascii_srccopy /b >nul 2>&1
2827 call :CheckFileSize file1_ascii_srccopy 5
2829 rem --------------------------------------------------------------
2830 rem Show results of concatenating files (ending in EOFs) and /a /b
2831 rem --------------------------------------------------------------
2833 rem Default and ascii copy reads as ascii, stripping EOFs, so 6-1 + 9-1 + 12-1 + 1
2834 copy file1_plus_eof+file2_plus_eof+file3_plus_eof file123_default_copy >nul 2>&1
2835 call :CheckFileSize file123_default_copy 25
2836 copy /a file1_plus_eof+file2_plus_eof+file3_plus_eof file123_ascii_copy >nul 2>&1
2837 call :CheckFileSize file123_ascii_copy 25
2839 rem In binary mode, we get 3 eofs, so 6 + 9 + 12 = 27
2840 copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_binary_copy >nul 2>&1
2841 call :CheckFileSize file123_binary_copy 27
2843 rem We can select which we want the eofs from by postfixing it with /a or /b
2844 rem so here have first and third with eof, second as ascii 6 + 9-1 + 12
2845 copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy1 >nul 2>&1
2846 call :CheckFileSize file123_mixed_copy1 26
2848 rem By postfixing the destination with /a, we ask for an ascii destination which appends EOF
2849 rem so here have first and third with eof, second as ascii 6 + 9-1 + 12 + extra EOF
2850 rem Note the delta between this and the previous one also shows that the destination
2851 rem ascii/binary is inherited from the last /a or /b on the line
2852 copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy2 /a >nul 2>&1
2853 call :CheckFileSize file123_mixed_copy2 27
2855 rem so here have second with eof, first and third as ascii 6-1 + 9 + 12-1
2856 rem Note the delta between the next two also shows that the destination ascii/binary is
2857 rem inherited from the last /a or /b on the line, so the first has an extra EOF
2858 copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy3 >nul 2>&1
2859 call :CheckFileSize file123_mixed_copy3 26
2860 copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy4 /b >nul 2>&1
2861 call :CheckFileSize file123_mixed_copy4 25
2863 rem -------------------------------------------------------------------------------------------
2864 rem This shows when concatenating, an ascii destination always adds on an EOF but when we
2865 rem are not concatenating, it's a direct copy regardless of destination if being read as binary
2866 rem -------------------------------------------------------------------------------------------
2868 rem All 3 have eof's, plus an extra = 6 + 9 + 12 + eof
2869 copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_mixed_copy5 /a >nul 2>&1
2870 call :CheckFileSize file123_mixed_copy5 28
2872 rem All 2 have eof's, plus an extra = 6 + 12 + eof
2873 copy /b file1_plus_eof + file3_plus_eof file123_mixed_copy6 /a >nul 2>&1
2874 call :CheckFileSize file123_mixed_copy6 19
2876 rem One file has EOF, but doesn't get an extra one, i.e. 6
2877 copy /b file1_plus_eof file123_mixed_copy7 /a >nul 2>&1
2878 call :CheckFileSize file123_mixed_copy7 6
2880 rem Syntax means concatenate so ascii destination kicks in
2881 copy /b file1_plus_eof* file123_mixed_copy8 /a >nul 2>&1
2882 call :CheckFileSize file123_mixed_copy8 7
2884 del *.* /q
2885 cd ..
2887 rem ---------------------------------------
2888 rem Error combinations
2889 rem ---------------------------------------
2890 rem Specify source directory but name is a file
2891 call :setError 0
2892 copy file1\ dir1\ >NUL 2>&1
2893 if errorlevel 1 echo Passed: errorlevel invalid check 1
2894 if not errorlevel 1 echo Failed: errorlevel invalid check 1
2895 call :CheckNotExist dir1\file1
2897 rem Overwrite same file
2898 call :setError 0
2899 copy file1 file1 >NUL 2>&1
2900 if errorlevel 1 echo Passed: errorlevel invalid check 2
2901 if not errorlevel 1 echo Failed: errorlevel invalid check 2
2903 rem Supply same file identified as a directory
2904 call :setError 0
2905 copy file1 file1\ >NUL 2>&1
2906 if errorlevel 1 echo Passed: errorlevel invalid check 3
2907 if not errorlevel 1 echo Failed: errorlevel invalid check 3
2909 cd ..
2910 rd foobar2 /s /q
2912 echo ------------ Testing setlocal/endlocal ------------
2913 call :setError 0
2914 rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test section
2915 mkdir foobar & cd foobar
2916 echo --- enable/disable extensions
2917 setlocal DisableEXTensions
2918 echo ErrLev: %ErrorLevel%
2919 endlocal
2920 echo ErrLev: %ErrorLevel%
2921 echo @echo off> tmp.cmd
2922 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
2923 rem Enabled by default
2924 cmd /C tmp.cmd
2925 cmd /E:OfF /C tmp.cmd
2926 cmd /e:oN /C tmp.cmd
2928 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
2929 echo --- setlocal with corresponding endlocal
2930 rem %CD% does not work on NT4 so use the following workaround
2931 for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi
2932 echo @echo off> test.cmd
2933 echo echo %%WINE_VAR%%>> test.cmd
2934 echo setlocal>> test.cmd
2935 echo set WINE_VAR=localval>> test.cmd
2936 echo md foobar2>> test.cmd
2937 echo cd foobar2>> test.cmd
2938 echo echo %%WINE_VAR%%>> test.cmd
2939 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
2940 echo endlocal>> test.cmd
2941 echo echo %%WINE_VAR%%>> test.cmd
2942 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
2943 set WINE_VAR=globalval
2944 call test.cmd
2945 echo %WINE_VAR%
2946 for /d %%i in (.) do echo %%~dpnxi
2947 cd /d %WINE_CURDIR%
2948 rd foobar2
2949 set WINE_VAR=
2950 echo --- setlocal with no corresponding endlocal
2951 echo @echo off> test.cmd
2952 echo echo %%WINE_VAR%%>> test.cmd
2953 echo setlocal>> test.cmd
2954 echo set WINE_VAR=localval>> test.cmd
2955 echo md foobar2>> test.cmd
2956 echo cd foobar2>> test.cmd
2957 echo echo %%WINE_VAR%%>> test.cmd
2958 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
2959 set WINE_VAR=globalval
2960 rem %CD% does not work on NT4 so use the following workaround
2961 for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi
2962 call test.cmd
2963 echo %WINE_VAR%
2964 for /d %%i in (.) do echo %%~dpnxi
2965 cd /d %WINE_CURDIR%
2966 rd foobar2
2967 set WINE_VAR=
2968 echo --- setlocal within same batch program
2969 set WINE_var1=one
2970 set WINE_var2=
2971 set WINE_var3=
2972 rem %CD% does not work on NT4 so use the following workaround
2973 for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi
2974 setlocal
2975 set WINE_var2=two
2976 mkdir foobar2
2977 cd foobar2
2978 setlocal
2979 set WINE_var3=three
2980 if "%WINE_var1%"=="one" echo Var1 ok 1
2981 if "%WINE_var2%"=="two" echo Var2 ok 2
2982 if "%WINE_var3%"=="three" echo Var3 ok 3
2983 for /d %%i in (.) do set WINE_curdir2=%%~dpnxi
2984 if "%WINE_curdir2%"=="%WINE_CURDIR%\foobar2" echo Directory is ok 1
2985 endlocal
2986 if "%WINE_var1%"=="one" echo Var1 ok 1
2987 if "%WINE_var2%"=="two" echo Var2 ok 2
2988 if "%WINE_var3%"=="" echo Var3 ok 3
2989 for /d %%i in (.) do set WINE_curdir2=%%~dpnxi
2990 if "%WINE_curdir2%"=="%WINE_CURDIR%\foobar2" echo Directory is ok 2
2991 endlocal
2992 if "%WINE_var1%"=="one" echo Var1 ok 1
2993 if "%WINE_var2%"=="" echo Var2 ok 2
2994 if "%WINE_var3%"=="" echo Var3 ok 3
2995 for /d %%i in (.) do set WINE_curdir2=%%~dpnxi
2996 if "%WINE_curdir2%"=="%WINE_CURDIR%" echo Directory is ok 3
2997 rd foobar2 /s /q
2998 set WINE_var1=
3000 echo --- Mismatched set and end locals
3001 mkdir foodir2 2>nul
3002 mkdir foodir3 2>nul
3003 mkdir foodir4 2>nul
3004 rem %CD% does not work on NT4 so use the following workaround
3005 for /d %%i in (.) do set WINE_curdir=%%~dpnxi
3007 echo @echo off> 2set1end.cmd
3008 echo echo %%WINE_var%%>> 2set1end.cmd
3009 echo setlocal>> 2set1end.cmd
3010 echo set WINE_VAR=2set1endvalue1>> 2set1end.cmd
3011 echo cd ..\foodir3>> 2set1end.cmd
3012 echo setlocal>> 2set1end.cmd
3013 echo set WINE_VAR=2set1endvalue2>> 2set1end.cmd
3014 echo cd ..\foodir4>> 2set1end.cmd
3015 echo endlocal>> 2set1end.cmd
3016 echo echo %%WINE_var%%>> 2set1end.cmd
3017 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 2set1end.cmd
3019 echo @echo off> 1set2end.cmd
3020 echo echo %%WINE_var%%>> 1set2end.cmd
3021 echo setlocal>> 1set2end.cmd
3022 echo set WINE_VAR=1set2endvalue1>> 1set2end.cmd
3023 echo cd ..\foodir3>> 1set2end.cmd
3024 echo endlocal>> 1set2end.cmd
3025 echo echo %%WINE_var%%>> 1set2end.cmd
3026 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
3027 echo endlocal>> 1set2end.cmd
3028 echo echo %%WINE_var%%>> 1set2end.cmd
3029 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
3031 echo --- Extra setlocal in called batch
3032 set WINE_VAR=value1
3033 rem -- setlocal1 == this batch, should never be used inside a called routine
3034 setlocal
3035 set WINE_var=value2
3036 cd foodir2
3037 call "%WINE_CURDIR%\2set1end.cmd"
3038 echo Finished:
3039 echo %WINE_VAR%
3040 for /d %%i in (.) do echo %%~dpnxi
3041 endlocal
3042 echo %WINE_VAR%
3043 for /d %%i in (.) do echo %%~dpnxi
3044 cd /d %WINE_CURDIR%
3046 echo --- Extra endlocal in called batch
3047 set WINE_VAR=value1
3048 rem -- setlocal1 == this batch, should never be used inside a called routine
3049 setlocal
3050 set WINE_var=value2
3051 cd foodir2
3052 call "%WINE_CURDIR%\1set2end.cmd"
3053 echo Finished:
3054 echo %WINE_VAR%
3055 for /d %%i in (.) do echo %%~dpnxi
3056 endlocal
3057 echo %WINE_VAR%
3058 for /d %%i in (.) do echo %%~dpnxi
3059 cd /d %WINE_CURDIR%
3061 echo --- endlocal in called function rather than batch pgm is ineffective
3062 @echo off
3063 set WINE_var=1
3064 set WINE_var2=1
3065 setlocal
3066 set WINE_var=2
3067 call :endlocalroutine
3068 echo %WINE_var%
3069 endlocal
3070 echo %WINE_var%
3071 goto :endlocalfinished
3072 :endlocalroutine
3073 echo %WINE_var%
3074 endlocal
3075 echo %WINE_var%
3076 setlocal
3077 set WINE_var2=2
3078 endlocal
3079 echo %WINE_var2%
3080 endlocal
3081 echo %WINE_var%
3082 echo %WINE_var2%
3083 goto :eof
3084 :endlocalfinished
3085 echo %WINE_var%
3087 set WINE_var=
3088 set WINE_var2=
3089 cd .. & rd /q/s foobar
3091 echo ------------ Testing Errorlevel ------------
3092 rem WARNING: Do *not* add tests using ErrorLevel after this section
3093 should_not_exist 2> nul > nul
3094 echo %ErrorLevel%
3095 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
3096 rem See http://www.robvanderwoude.com/exit.php
3097 call :setError 1
3098 echo %ErrorLevel%
3099 if errorlevel 2 echo errorlevel too high, bad
3100 if errorlevel 1 echo errorlevel just right, good
3101 if errorlevel 01 echo errorlevel with leading zero just right, good
3102 if errorlevel -1 echo errorlevel with negative number OK
3103 if errorlevel 0x1 echo hexa should not be recognized!
3104 if errorlevel 1a echo invalid error level recognized!
3105 call :setError 0
3106 echo abc%ErrorLevel%def
3107 if errorlevel 1 echo errorlevel nonzero, bad
3108 if not errorlevel 1 echo errorlevel zero, good
3109 if not errorlevel 0x1 echo hexa should not be recognized!
3110 if not errorlevel 1a echo invalid error level recognized!
3111 rem Now verify that setting a real variable hides its magic variable
3112 set errorlevel=7
3113 echo %ErrorLevel% should be 7
3114 if errorlevel 7 echo setting var worked too well, bad
3115 call :setError 3
3116 echo %ErrorLevel% should still be 7
3118 echo ------------ Testing GOTO ------------
3119 if a==a goto dest1
3120 echo FAILURE at dest 1
3121 :dest1
3122 echo goto with no leading space worked
3123 if a==a goto :dest1b
3124 echo FAILURE at dest 1b
3125 :dest1b
3126 echo goto with colon and no leading space worked
3127 if b==b goto dest2
3128 echo FAILURE at dest 2
3129 :dest2
3130 echo goto with a leading space worked
3131 if c==c goto dest3
3132 echo FAILURE at dest 3
3133 :dest3
3134 echo goto with a leading tab worked
3135 if d==d goto dest4
3136 echo FAILURE at dest 4
3137 :dest4@space@
3138 echo goto with a following space worked
3139 if e==e goto dest5
3140 echo FAILURE at dest 5
3141 :dest5&& echo FAILURE
3142 echo goto with following amphersands worked
3144 del failure.txt >nul 2>&1
3145 if f==f goto dest6
3146 echo FAILURE at dest 6
3147 :dest6>FAILURE.TXT
3148 if exist FAILURE.TXT echo FAILURE at dest 6 as file exists
3149 echo goto with redirections worked
3150 del FAILURE.TXT >nul 2>&1
3152 :: some text that is ignored | dir >cmd_output | another test
3153 if exist cmd_output echo FAILURE at dest 6 as file exists
3154 echo Ignoring double colons worked
3155 del cmd_output >nul 2>&1
3157 rem goto a label which does not exist issues an error message and
3158 rem acts the same as goto :EOF, and ensure ::label is never matched
3159 del testgoto.bat >nul 2>&1
3160 echo goto :dest7 ^>nul 2^>^&1 >> testgoto.bat
3161 echo echo FAILURE at dest 7 - Should have not found label and issued an error plus ended the batch>> testgoto.bat
3162 echo ::dest7>> testgoto.bat
3163 echo echo FAILURE at dest 7 - Incorrectly went to label >> testgoto.bat
3164 call testgoto.bat
3165 del testgoto.bat >nul 2>&1
3167 del testgoto.bat >nul 2>&1
3168 echo goto ::dest8 ^>nul 2^>^&1 >> testgoto.bat
3169 echo echo FAILURE at dest 8 - Should have not found label and issued an error plus ended the batch>> testgoto.bat
3170 echo ::dest8>> testgoto.bat
3171 echo echo FAILURE at dest 8 - Incorrectly went to label >> testgoto.bat
3172 call testgoto.bat
3173 del testgoto.bat >nul 2>&1
3175 if g==g goto dest9
3176 echo FAILURE at dest 9
3177 :dest91
3178 echo FAILURE at dest 91
3179 @ : dest9>rubbish
3180 echo label with mixed whitespace and no echo worked
3182 if h==h goto :dest10:this is ignored
3183 echo FAILURE at dest 10
3184 :dest10:this is also ignored
3185 echo Correctly ignored trailing information
3187 rem Testing which label is reached when there are many options
3188 echo Begin:
3189 set nextlabel=
3190 call :sub
3191 set nextlabel=middle
3192 goto :sub
3194 :sub
3195 echo ..First sub
3196 if not "%nextlabel%"=="" goto :%nextlabel%
3197 goto :EOF
3199 :sub
3200 echo ..Second sub
3201 if not "%nextlabel%"=="" goto :%nextlabel%
3202 goto :EOF
3204 :middle
3205 echo Middle:
3206 set nextlabel=
3207 call :sub
3208 set nextlabel=nearend
3209 goto :sub
3211 :sub
3212 echo ..Third sub
3213 if not "%nextlabel%"=="" goto :%nextlabel%
3214 goto :EOF
3216 :nearend
3217 echo Near end:
3218 set nextlabel=
3219 call :sub
3220 set nextlabel=end
3221 goto :sub
3223 :sub
3224 echo ..Fourth sub
3225 if not "%nextlabel%"=="" goto :%nextlabel%
3226 goto :EOF
3228 :end
3229 echo At end:
3230 set nextlabel=
3231 call :sub
3232 set nextlabel=done
3233 goto :sub
3235 :done
3236 echo Finished
3238 echo ------------ Testing PATH ------------
3239 set WINE_backup_path=%path%
3240 set path=original
3241 path
3242 path try2
3243 path
3244 path=try3
3245 path
3246 set path=%WINE_backup_path%
3247 set WINE_backup_path=
3249 echo ------------ Testing start /W ------------
3250 echo start /W failed to wait>foobar.txt
3251 start /W "" cmd /C "ping -n1 & echo start /W seems to really wait>foobar.txt"& type foobar.txt& del foobar.txt
3253 echo ------------ Testing changing the drive letter ----------
3254 pushd C:\
3256 echo Normal:
3257 call :setError 0
3259 if errorlevel 1 echo Normal drive change failed
3261 echo Normal+space
3262 call :setError 0
3263 C:@space@
3264 if errorlevel 1 echo Normal+space drive change failed
3266 echo Normal+space+garbage
3267 call :setError 0
3268 C: garbage
3269 if errorlevel 1 echo Normal+space+garbage drive change failed
3271 call :setError 0
3272 echo Quoted should fail
3273 "C:"
3274 if not errorlevel 1 echo quoted drive change unexpectedly worked
3276 echo Normal+tab
3277 call :setError 0
3278 C:@tab@
3279 if errorlevel 1 echo Normal+tab drive change failed
3281 echo Normal+tab+garbage
3282 call :setError 0
3283 C:@tab@garbagetab
3284 if errorlevel 1 echo Normal+tab+garbage drive change failed
3286 popd
3288 echo ------------ Testing combined CALLs/GOTOs ------------
3289 echo @echo off>foo.cmd
3290 echo goto :eof>>foot.cmd
3291 echo :eof>>foot.cmd
3292 echo echo world>>foo.cmd
3294 echo @echo off>foot.cmd
3295 echo echo cheball>>foot.cmd
3296 echo.>>foot.cmd
3297 echo call :bar>>foot.cmd
3298 echo if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmd
3299 echo goto :eof>>foot.cmd
3300 echo.>>foot.cmd
3301 echo :bar>>foot.cmd
3302 echo echo barbare>>foot.cmd
3303 echo goto :eof>>foot.cmd
3305 call foo.cmd
3306 call foot
3307 call :bar
3308 del foo.cmd
3309 rem Script execution stops after the following line
3310 foot deleteMe
3311 call :foo
3312 call :foot
3313 goto :endFuns
3315 :foot
3316 echo foot
3318 :foo
3319 echo foo
3320 goto :eof
3322 :endFuns
3324 :bar
3325 echo bar
3326 call :foo
3328 :baz
3329 echo baz
3330 goto :eof
3332 echo Final message is not output since earlier 'foot' processing stops script execution
3333 echo Do NOT add any tests below this line
3335 echo ------------ Done, jumping to EOF -----------
3336 goto :eof
3337 rem Subroutine to set errorlevel and return
3338 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
3339 :setError
3340 exit /B %1
3341 rem This line runs under cmd in windows NT 4, but not in more modern versions.