cmd/tests: Move command line tests to separate file.
[wine] / programs / cmd / tests / test_builtins.cmd
1 echo Tests for cmd's builtin commands
2
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 off now
19 echo word@space@
20 echo word@space@@space@
21  echo word
22 echo@tab@word
23 echo@tab@word @tab@
24 echo@tab@word@tab@@space@
25 @tab@echo word
26 echo @tab@word
27 echo  @tab@word
28 echo@tab@@tab@word
29 echo @tab@ on @space@
30
31 @echo off
32 echo off@tab@@space@
33 @echo noecho1
34  @echo noecho2
35 @@@@@echo echo3
36 echo ------------ Testing 'echo' [OFF] ------------
37 echo word
38 echo 'singlequotedword'
39 echo "doublequotedword"
40 @echo at-echoed-word
41 echo "/?"
42 echo.
43 echo .
44 echo.word
45 echo .word
46 echo:
47 echo :
48 echo:word
49 echo :word
50 echo on again
51 echo word@space@
52 echo word@space@@space@
53  echo word
54 echo@tab@word
55 echo@tab@word @tab@
56 echo@tab@word@tab@@space@
57 @tab@echo word
58 echo @tab@word
59 echo  @tab@word
60 echo@tab@@tab@word
61
62 echo ------------ Testing mixed echo modes ------------
63 echo @echo on> mixedEchoModes.cmd
64 echo if 1==1 echo foo>> mixedEchoModes.cmd
65 echo if 1==1 @echo bar>> mixedEchoModes.cmd
66 echo @echo off>> mixedEchoModes.cmd
67 echo if 1==1 echo foo2>> mixedEchoModes.cmd
68 echo if 1==1 @echo bar2>> mixedEchoModes.cmd
69 type mixedEchoModes.cmd
70 cmd /c mixedEchoModes.cmd
71 del mixedEchoModes.cmd
72
73 echo ------------ Testing parameterization ------------
74 call :TestParm a b c
75 call :TestParm "a b c"
76 call :TestParm "a b"\c
77 call :TestParm a=~`+,.{}!+b
78 call :TestParm a;b
79 call :TestParm "a;b"
80 call :TestParm a^;b
81 call :TestParm a[b]{c}(d)e
82 call :TestParm a&echo second line
83 call :TestParm a   b,,,c
84 call :TestParm a==b;;c
85 call :TestParm       a,,,  b
86 goto :TestRem
87
88 :TestParm
89 echo '%1', '%2', '%3'
90 goto :eof
91
92 :TestRem
93 echo ------------ Testing rem ------------
94 rem Hello
95 rem  Hello
96 rem   Hello || foo
97 rem echo lol
98 rem echo foo & echo bar
99 rem @tab@  Hello
100 rem@tab@  Hello
101 rem@tab@echo foo & echo bar
102 @echo on
103 rem Hello
104 rem  Hello
105 rem   Hello || foo
106 rem echo lol
107 rem echo foo & echo bar
108 rem @tab@  Hello
109 rem@tab@  Hello
110 rem@tab@echo foo & echo bar
111 @echo off
112
113 echo ------------ Testing redirection operators ------------
114 mkdir foobar & cd foobar
115 echo --- stdout redirection
116 echo foo>foo
117 type foo
118 echo foo 1> foo
119 type foo
120 echo foo@tab@1> foo
121 type foo
122 echo foo 1>@tab@foo
123 type foo
124 echo foo@tab@1>@tab@foo
125 type foo
126 echo foo7 7> foo
127 type foo
128 echo foo9 9> foo
129 type foo
130 echo foo1> foo
131 type foo
132 echo foo11> foo
133 type foo
134 echo foo12> foo
135 type foo
136 echo foo13>"foo"
137 type foo
138 echo foo14>."\foo"
139 type foo
140 echo foo15>."\f"oo
141 type foo
142 del foo
143 echo1>foo
144 type foo
145 echo --- stdout appending
146 echo foo>foo
147 echo foo >>foo
148 type foo
149 del foo
150 echo foob >> foo
151 type foo
152 echo fooc 1>>foo
153 type foo
154 echo food1>>foo
155 type foo
156 echo food2>>"foo"
157 type foo
158 del foo
159 echo food21>>foo
160 type foo
161 del foo
162 echo foo> foo
163 echo foo7 7>> foo || (echo not supported & del foo)
164 if exist foo (type foo) else echo not supported
165 echo --- redirections within IF statements
166 if 1==1 echo foo1>bar
167 type bar & del bar
168 echo -----
169 if 1==1 (echo foo2>bar) else echo baz2>bar
170 type bar & del bar
171 if 1==1 (echo foo3) else echo baz3>bar
172 type bar || echo file does not exist, ok
173 if 1==1 (echo foo4>bar) else echo baz4>bar
174 type bar & del bar
175 if 1==0 (echo foo5>bar) else echo baz5>bar
176 type bar & del bar
177 if 1==0 (echo foo6) else echo baz6 1>bar
178 type bar & del bar
179 if 1==0 (echo foo7 1>bar) else echo baz7>bar
180 type bar & del bar
181 if 1==0 (echo foo8 1>bar) else echo baz8>bak
182 type bak
183 if 1==1 (echo foo>bar & echo baz)
184 type bar
185 if 1==1 (
186    echo foo>bar
187    echo baz
188 )
189 type bar
190 (if 1==1 (echo A) else echo B) > C
191 type C
192 (if 1==0 (echo A) else echo B) > C
193 type C
194 (if 1==0 (echo A > B) else echo C)
195 cd .. & rd /s/q foobar
196
197 echo ------------ Testing circumflex escape character ------------
198 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
199 echo ^hell^o, world
200 echo hell^o, world
201 echo hell^^o, world
202 echo hell^^^o, world
203 echo hello^
204 world
205 echo hello^
206
207 world
208 echo hello^
209
210
211 echo finished
212 mkdir foobar
213 echo baz> foobar\baz
214 type foobar\baz
215 type foobar^\baz
216 rd /s/q foobar
217 echo foo ^| echo bar
218 echo foo ^& echo bar
219 call :setError 0
220 echo bak ^&& echo baz 2> nul
221 echo %ErrorLevel%
222 echo foo ^> foo
223 echo ^<> foo
224 type foo
225 del foo
226 set FOO=oof
227 echo ff^%FOO%
228 set FOO=bar ^| baz
229 set FOO
230 rem FIXME: echoing %FOO% gives an error (baz not recognized) but prematurely
231 rem exits the script on windows; redirecting stdout and/or stderr doesn't help
232 echo %ErrorLevel%
233 call :setError 0
234 set FOO=bar ^^^| baz
235 set FOO
236 echo %FOO%
237 echo %ErrorLevel%
238 set FOO=
239
240 echo ------------ Testing 'set' ------------
241 call :setError 0
242 set FOOBAR 2> nul > nul
243 echo %ErrorLevel%
244 set FOOBAR =  baz
245 echo %ErrorLevel%
246 echo %FOOBAR%FOOBAR not defined
247 echo %FOOBAR %
248 set FOOBAR 2> nul
249 set FOOBAR =  baz2
250 echo %ErrorLevel%
251 echo %fOObAr %
252 set FOOBAR= bar
253 echo %ErrorLevel%
254 echo %FOOBAR%
255 set FOO
256 set FOOBAR=
257 set FOOB
258 echo %FOOBAR%FOOBAR not defined
259 set FOOBAR =
260 set FOOBA 2> nul > nul
261 echo %ErrorLevel%
262 set FOO=bar
263 echo %FOO%
264 set FOO=foo
265 set BAR=bar
266 echo %FOO%%BAR%
267 set BAR=
268 set FOO=
269 set FOO=%FOO%
270 echo %FOO%FOO not defined
271 set BAZ%=bazbaz
272 set BA
273 echo %BAZ%%
274 set BAZ%=
275 echo set "FOO=bar" should not include the quotes in the variable value
276 set "FOO=bar"
277 echo %FOO%
278 set@tab@FOO=foo
279 echo %FOO%
280 set@tab@FOO=
281 echo '%FOO%'
282 set FOO=foo@space@
283 echo '%FOO%'
284 set FOO=foo@tab@
285 echo '%FOO%'
286 set FOO=
287
288 echo ------------ Testing variable expansion ------------
289 call :setError 0
290 echo ~dp0 should be directory containing batch file
291 echo %~dp0
292 mkdir dummydir
293 cd dummydir
294 echo %~dp0
295 cd ..
296 rmdir dummydir
297 echo CD value %CD%
298 echo %%
299 echo P%
300 echo %P
301 echo %UNKNOWN%S
302 echo P%UNKNOWN%
303 echo P%UNKNOWN%S
304 echo %ERRORLEVEL
305 echo %ERRORLEVEL%
306 echo %ERRORLEVEL%%ERRORLEVEL%
307 echo %ERRORLEVEL%ERRORLEVEL%
308 echo %ERRORLEVEL%%
309 echo %ERRORLEVEL%%%
310 echo P%ERRORLEVEL%
311 echo %ERRORLEVEL%S
312 echo P%ERRORLEVEL%S
313
314 echo ------------ Testing variable substrings ------------
315 set VAR=qwerty
316 echo %VAR:~0,1%
317 echo %VAR:~0,3%
318 echo %VAR:~2,2%
319 echo '%VAR:~-2,3%'
320 echo '%VAR:~-2,1%'
321 echo %VAR:~2,-1%
322 echo %VAR:~2,-3%
323 echo '%VAR:~-2,-4%'
324 echo %VAR:~-3,-2%
325 set VAR=
326
327 echo ------------ Testing variable substitution ------------
328 echo --- in FOR variables
329 for %%i in ("A B" C) do echo %%i
330 rem check works when prefix with @
331 @for %%i in ("A B" C) do echo %%i
332 rem quotes removal
333 for %%i in ("A B" C) do echo '%%~i'
334 rem fully qualified path
335 for %%f in ("C D" E) do echo %%~ff
336 rem drive letter
337 for %%i in ("F G" H) do echo %%~di
338 rem path
339 for %%d in ("I J" K) do echo %%~pd
340 rem filename
341 for %%i in ("L M" N) do echo %%~ni
342 rem file extension
343 for %%i in ("O. P.OOL" Q.TABC hello) do echo '%%~xi'
344 rem path with short path names
345 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do echo '%%~sI'
346 rem file attribute
347 for %%i in ("U V" W) do echo '%%~ai'
348 echo foo> foo
349 for %%i in (foo) do echo '%%~ai'
350 del foo
351 rem file date/time
352 rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar...
353 for %%i in ("a b" c) do echo '%%~ti'
354 rem file size
355 rem Similar issues as above
356 for %%i in ("a b" c) do echo '%%~zi'
357 rem combined options
358 for %%i in ("d e" f) do echo %%~dpi
359 for %%i in ("g h" i) do echo %%~sdi
360 for %%i in ("g h" i) do echo %%~dsi
361 for %%i in ("j k" l.eh) do echo '%%~xsi'
362
363 echo --- in parameters
364 for %%i in ("A B" C) do call :echoFun %%i
365 rem quotes removal
366 for %%i in ("A B" C) do call :echoFunQ %%i
367 rem fully qualified path
368 for %%f in ("C D" E) do call :echoFunF %%f
369 rem drive letter
370 for %%i in ("F G" H) do call :echoFunD %%i
371 rem path
372 for %%d in ("I J" K) do call :echoFunP %%d
373 rem filename
374 for %%i in ("L M" N) do call :echoFunN %%i
375 rem file extension
376 for %%i in ("O. P.OOL" Q.TABC hello) do call :echoFunX %%i
377 rem path with short path names
378 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do call :echoFunS %%I
379 rem NT4 aborts whole script execution when encountering ~a, ~t and ~z substitutions, preventing full testing
380 rem combined options
381 for %%i in ("d e" f) do call :echoFunDP %%i
382 for %%i in ("g h" i) do call :echoFunSD %%i
383 for %%i in ("g h" i) do call :echoFunDS %%i
384 for %%i in ("j k" l.eh) do call :echoFunXS %%i
385
386 goto :endEchoFuns
387 :echoFun
388 echo %1
389 goto :eof
390
391 :echoFunQ
392 echo '%~1'
393 goto :eof
394
395 :echoFunF
396 echo %~f1
397 goto :eof
398
399 :echoFunD
400 echo %~d1
401 goto :eof
402
403 :echoFunP
404 echo %~p1
405 goto :eof
406
407 :echoFunN
408 echo %~n1
409 goto :eof
410
411 :echoFunX
412 echo '%~x1'
413 goto :eof
414
415 :echoFunS
416 rem some NT4 workaround
417 set VAR='%~s1'
418 echo %VAR%
419 set VAR=
420 goto :eof
421
422 :echoFunDP
423 echo %~dp1
424 goto :eof
425
426 :echoFunSD
427 echo %~sd1
428 goto :eof
429
430 :echoFunDS
431 echo %~ds1
432 goto :eof
433
434 :echoFunXS
435 echo '%~xs1'
436 goto :eof
437 :endEchoFuns
438
439 echo ------------ Testing variable delayed expansion ------------
440 rem NT4 doesn't support this
441 echo --- default mode (load-time expansion)
442 set FOO=foo
443 echo %FOO%
444 echo !FOO!
445 if %FOO% == foo (
446     set FOO=bar
447     if %FOO% == bar (echo bar) else echo foo
448 )
449
450 set FOO=foo
451 if %FOO% == foo (
452     set FOO=bar
453     if !FOO! == bar (echo bar) else echo foo
454 )
455
456 echo --- runtime (delayed) expansion mode
457 setlocal EnableDelayedExpansion
458 set FOO=foo
459 echo %FOO%
460 echo !FOO!
461 if %FOO% == foo (
462     set FOO=bar
463     if %FOO% == bar (echo bar) else echo foo
464 )
465
466 set FOO=foo
467 if %FOO% == foo (
468     set FOO=bar
469     if !FOO! == bar (echo bar) else echo foo
470 )
471 echo %ErrorLevel%
472 setlocal DisableDelayedExpansion
473 echo %ErrorLevel%
474 set FOO=foo
475 echo %FOO%
476 echo !FOO!
477 set FOO=
478 echo --- using /V cmd flag
479 echo @echo off> tmp.cmd
480 echo set FOO=foo>> tmp.cmd
481 echo echo %%FOO%%>> tmp.cmd
482 echo echo !FOO!>> tmp.cmd
483 echo set FOO=>> tmp.cmd
484 cmd /V:ON /C tmp.cmd
485 cmd /V:OfF /C tmp.cmd
486 del tmp.cmd
487
488 echo ------------ Testing conditional execution ------------
489 echo --- unconditional ampersand
490 call :setError 123 & echo foo1
491 echo bar2 & echo foo2
492 mkdir foobar & cd foobar
493 echo > foobazbar
494 cd .. & rd /s/q foobar
495 if exist foobazbar (
496     echo foobar not deleted!
497     cd ..
498     rd /s/q foobar
499 ) else echo foobar deleted
500 echo --- on success conditional and
501 call :setError 456 && echo foo3 > foo3
502 if exist foo3 (
503     echo foo3 created
504     del foo3
505 ) else echo foo3 not created
506 echo bar4 && echo foo4
507 echo --- on failure conditional or
508 call :setError 789 || echo foo5
509 echo foo6 || echo bar6 > bar6
510 if exist bar6 (
511     echo bar6 created
512     del bar6
513 )
514
515 echo ------------ Testing cd ------------
516 mkdir foobar
517 cd foobar
518 echo blabla > singleFile
519 dir /b
520 echo Current dir: %CD%
521 cd
522 cd ..
523 cd
524 cd foobar@space@
525 cd
526 cd ..
527 cd
528 cd @space@foobar
529 cd
530 cd..
531 cd
532 cd foobar
533 cd..@space@
534 cd
535 if not exist foobar (cd ..)
536 cd foobar
537 cd@tab@..@tab@@space@@tab@
538 cd
539 if not exist foobar (cd ..)
540 cd foobar
541 mkdir "bar bak"
542 cd "bar bak"
543 cd
544 cd ..
545 cd ".\bar bak"
546 cd
547 cd ..
548 cd .\"bar bak"
549 cd
550 cd ..
551 cd bar bak
552 cd
553 cd "bar bak@space@"@tab@@space@
554 cd
555 cd ..\..
556 cd
557 rd /Q/s foobar
558 mkdir foobar
559 cd /d@tab@foobar
560 cd
561 cd ..
562 rd /q/s foobar
563
564 echo ------------ Testing type ------------
565 echo bar> foobaz
566 @echo on
567 type foobaz
568 echo ---
569 @echo off
570 type foobaz@tab@
571 echo ---1
572 type ."\foobaz"
573 echo ---2
574 type ".\foobaz"
575 echo ---3
576 del foobaz
577
578 echo ------------ Testing NUL ------------
579 md foobar & cd foobar
580 rem NUL file (non) creation + case insensitivity
581 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
582 echo > bar
583 echo foo > NUL
584 dir /b /a-d
585 echo foo > nul
586 dir /b /a-d
587 echo foo > NuL
588 @tab@dir /b@tab@/a-d
589 del bar
590 rem NUL not special everywhere
591 call :setError 123
592 echo NUL> foo
593 if not exist foo (echo foo should have been created) else (
594     type foo
595     del foo
596 )
597 rem Empty file creation
598 copy nul foo > nul
599 if exist foo (
600     echo foo created
601     del foo
602     type foo
603 ) else (
604     echo ***
605 )
606 cd .. & rd foobar
607
608 echo ------------ Testing if/else ------------
609 echo if/else should work with blocks
610 if 0 == 0 (
611   echo if seems to work
612 ) else (
613   echo if seems to be broken
614 )
615 if 1 == 0 (
616   echo else seems to be broken
617 ) else (
618   echo else seems to work
619 )
620 if /c==/c (
621   echo if seems not to detect /c as parameter
622 ) else (
623   echo parameter detection seems to be broken
624 )
625 echo Testing case sensitivity with and without /i option
626 if bar==BAR echo if does not default to case sensitivity
627 if not bar==BAR echo if seems to default to case sensitivity
628 if /i foo==FOO echo if /i seems to work
629 if /i not foo==FOO echo if /i seems to be broken
630 if /I foo==FOO echo if /I seems to work
631 if /I not foo==FOO echo if /I seems to be broken
632 echo Testing string comparisons
633 if abc == abc  (echo equal) else echo non equal
634 if abc =="abc" (echo equal) else echo non equal
635 if "abc"== abc (echo equal) else echo non equal
636 if "abc"== "abc" (echo equal) else echo non equal
637 echo Testing tabs handling
638 if@tab@1==1 echo doom
639 if @tab@1==1 echo doom
640 if 1==1 (echo doom) else@tab@echo quake
641 if@tab@not @tab@1==@tab@0 @tab@echo lol
642 if 1==0@tab@(echo doom) else echo quake
643 if 1==0 (echo doom)@tab@else echo quake
644 if 1==0 (echo doom) else@tab@echo quake
645
646 echo ------------ Testing for ------------
647 echo --- plain FOR
648 for %%i in (A B C) do echo %%i
649 for %%i in (A B C) do echo %%I
650 for %%i in (A B C) do echo %%j
651 for %%i in (A B C) do call :forTestFun1 %%i
652 for %%i in (1,4,1) do echo %%i
653 for %%i in (A, B,C) do echo %%i
654 for %%i in  (X) do echo %%i
655 for@tab@%%i in  (X2) do echo %%i
656 for %%i in@tab@(X3) do echo %%i
657 for %%i in (@tab@ foo@tab@) do echo %%i
658 for@tab@ %%i in@tab@(@tab@M) do echo %%i
659 for %%i@tab@in (X)@tab@do@tab@echo %%i
660 for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
661 for %%i in (`echo A B`) do echo %%i
662 for %%i in ('echo A B') do echo %%i
663 for %%i in ("echo A B") do echo %%i
664 for %%i in ("A B" C) do echo %%i
665 goto :endForTestFun1
666 :forTestFun1
667 echo %1
668 goto :eof
669 :endForTestFun1
670 echo --- imbricated FORs
671 for %%i in (X) do (
672     for %%j in (Y) do (
673         echo %%i %%j))
674 for %%i in (X) do (
675     for %%I in (Y) do (
676         echo %%i %%I))
677 for %%i in (A B) do (
678     for %%j in (C D) do (
679         echo %%i %%j))
680 for %%i in (A B) do (
681     for %%j in (C D) do (
682         call :forTestFun2 %%i %%j ))
683 goto :endForTestFun2
684 :forTestFun2
685 echo %1 %2
686 goto :eof
687 :endForTestFun2
688 mkdir foobar & cd foobar
689 mkdir foo
690 mkdir bar
691 mkdir baz
692 echo > bazbaz
693 echo --- basic wildcards
694 for %%i in (ba*) do echo %%i
695 echo --- for /d
696 for /d %%i in (baz foo bar) do echo %%i 2>&1
697 rem Confirm we don't match files:
698 for /d %%i in (bazb*) do echo %%i 2>&1
699 for /d %%i in (bazb2*) do echo %%i 2>&1
700 rem Show we pass through non wildcards
701 for /d %%i in (PASSED) do echo %%i
702 for /d %%i in (xxx) do (
703   echo %%i - Should be xxx
704   echo Expected second line
705 )
706 rem Show we issue no messages on failures
707 for /d %%i in (FAILED?) do echo %%i 2>&1
708 for /d %%i in (FAILED?) do (
709   echo %%i - Unexpected!
710   echo FAILED Unexpected second line
711 )
712 for /d %%i in (FAILED*) do echo %%i 2>&1
713 for /d %%i in (FAILED*) do (
714   echo %%i - Unexpected!
715   echo FAILED Unexpected second line
716 )
717 rem FIXME can't test wildcard expansion here since it's listed in directory
718 rem order, and not in alphabetic order.
719 rem Proper testing would need a currently missing "sort" program implementation.
720 rem for /d %%i in (ba*) do echo %%i>> tmp
721 rem sort < tmp
722 rem del tmp
723 rem for /d %%i in (?a*) do echo %%i>> tmp
724 rem sort < tmp
725 rem del tmp
726 rem for /d %%i in (*) do echo %%i>> tmp
727 rem sort < tmp
728 rem del tmp
729 echo > baz\bazbaz
730 goto :TestForR
731
732 :SetExpected
733 del temp.bat 2>nul
734 call :WriteLine set found=N
735 for /l %%i in (1,1,%expectedresults%) do (
736   call :WriteLine if "%%%%expectedresults.%%i%%%%"=="%%%%1" set found=Y
737   call :WriteLine if "%%%%found%%%%"=="Y" set expectedresults.%%i=
738   call :WriteLine if "%%%%found%%%%"=="Y" goto :eof
739 )
740 call :WriteLine echo Got unexpected result: "%%%%1"
741 goto :eof
742
743 :WriteLine
744 echo %*>> temp.bat
745 goto :EOF
746
747 :ValidateExpected
748 del temp.bat 2>nul
749 for /l %%i in (1,1,%expectedresults%) do  call :WriteLine if not "%%%%expectedresults.%%i%%%%"=="" echo Found missing result: "%%%%expectedresults.%%i%%%%"
750 call temp.bat
751 del temp.bat 2>nul
752 goto :eof
753
754 :TestForR
755 rem %CD% does not tork on NT4 so use the following workaround
756 for /d %%i in (.) do set CURDIR=%%~dpnxi
757
758 echo --- for /R
759 echo Plain directory enumeration
760 set expectedresults=4
761 set expectedresults.1=%CURDIR%\.
762 set expectedresults.2=%CURDIR%\bar\.
763 set expectedresults.3=%CURDIR%\baz\.
764 set expectedresults.4=%CURDIR%\foo\.
765 call :SetExpected
766 for /R %%i in (.) do call temp.bat %%i
767 call :ValidateExpected
768
769 echo Plain directory enumeration from provided root
770 set expectedresults=4
771 set expectedresults.1=%CURDIR%\.
772 set expectedresults.2=%CURDIR%\bar\.
773 set expectedresults.3=%CURDIR%\baz\.
774 set expectedresults.4=%CURDIR%\foo\.
775 if "%CD%"=="" goto :SkipBrokenNT4
776 call :SetExpected
777 for /R "%CURDIR%" %%i in (.) do call temp.bat %%i
778 call :ValidateExpected
779 :SkipBrokenNT4
780
781 echo File enumeration
782 set expectedresults=2
783 set expectedresults.1=%CURDIR%\baz\bazbaz
784 set expectedresults.2=%CURDIR%\bazbaz
785 call :SetExpected
786 for /R %%i in (baz*) do call temp.bat %%i
787 call :ValidateExpected
788
789 echo File enumeration from provided root
790 set expectedresults=2
791 set expectedresults.1=%CURDIR%\baz\bazbaz
792 set expectedresults.2=%CURDIR%\bazbaz
793 call :SetExpected
794 for /R %%i in (baz*) do call temp.bat %%i
795 call :ValidateExpected
796
797 echo Mixed enumeration
798 set expectedresults=6
799 set expectedresults.1=%CURDIR%\.
800 set expectedresults.2=%CURDIR%\bar\.
801 set expectedresults.3=%CURDIR%\baz\.
802 set expectedresults.4=%CURDIR%\baz\bazbaz
803 set expectedresults.5=%CURDIR%\bazbaz
804 set expectedresults.6=%CURDIR%\foo\.
805 call :SetExpected
806 for /R %%i in (. baz*) do call temp.bat %%i
807 call :ValidateExpected
808
809 echo Mixed enumeration from provided root
810 set expectedresults=6
811 set expectedresults.1=%CURDIR%\.
812 set expectedresults.2=%CURDIR%\bar\.
813 set expectedresults.3=%CURDIR%\baz\.
814 set expectedresults.4=%CURDIR%\baz\bazbaz
815 set expectedresults.5=%CURDIR%\bazbaz
816 set expectedresults.6=%CURDIR%\foo\.
817 call :SetExpected
818 for /R %%i in (. baz*) do call temp.bat %%i
819 call :ValidateExpected
820
821 echo With duplicates enumeration
822 set expectedresults=12
823 set expectedresults.1=%CURDIR%\bar\bazbaz
824 set expectedresults.2=%CURDIR%\bar\fred
825 set expectedresults.3=%CURDIR%\baz\bazbaz
826 set expectedresults.4=%CURDIR%\baz\bazbaz
827 set expectedresults.5=%CURDIR%\baz\bazbaz
828 set expectedresults.6=%CURDIR%\baz\fred
829 set expectedresults.7=%CURDIR%\bazbaz
830 set expectedresults.8=%CURDIR%\bazbaz
831 set expectedresults.9=%CURDIR%\bazbaz
832 set expectedresults.10=%CURDIR%\foo\bazbaz
833 set expectedresults.11=%CURDIR%\foo\fred
834 set expectedresults.12=%CURDIR%\fred
835 call :SetExpected
836 for /R %%i in (baz* bazbaz fred ba*) do call temp.bat %%i
837 call :ValidateExpected
838
839 echo Strip missing wildcards, keep unwildcarded names
840 set expectedresults=6
841 set expectedresults.1=%CURDIR%\bar\jim
842 set expectedresults.2=%CURDIR%\baz\bazbaz
843 set expectedresults.3=%CURDIR%\baz\jim
844 set expectedresults.4=%CURDIR%\bazbaz
845 set expectedresults.5=%CURDIR%\foo\jim
846 set expectedresults.6=%CURDIR%\jim
847 call :SetExpected
848 for /R %%i in (baz* fred* jim) do call temp.bat %%i
849 call :ValidateExpected
850
851 echo for /R passed
852 cd .. & rd /s/Q foobar
853 echo --- for /L
854 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
855 for /L %%i in (1,2,0) do echo %%i
856 for@tab@/L %%i in (1,2,0) do echo %%i
857 for /L %%i in (1,2,6) do echo %%i
858 for /l %%i in (1 ,2,6) do echo %%i
859 for /L %%i in (a,2,3) do echo %%i
860 for /L %%i in (1,2,-1) do echo %%i
861 for /L %%i in (-4,-1,-1) do echo %%i
862 for /L %%i in (1,-2,-2) do echo %%i
863 for /L %%i in (1,2,a) do echo %%i
864 echo ErrorLevel %ErrorLevel%
865 for /L %%i in (1,a,b) do echo %%i
866 echo ErrorLevel %ErrorLevel%
867 rem Test boundaries
868 for /l %%i in (1,1,4) do echo %%i
869 for /l %%i in (1,2,4) do echo %%i
870 for /l %%i in (4,-1,1) do echo %%i
871 for /l %%i in (4,-2,1) do echo %%i
872 for /l %%i in (1,-1,4) do echo %%i
873 for /l %%i in (4,1,1) do echo %%i
874 for /L %%i in (a,2,b) do echo %%i
875 for /L %%i in (1,1,1) do echo %%i
876 for /L %%i in (1,-2,-1) do echo %%i
877 for /L %%i in (-1,-1,-1) do echo %%i
878 for /L %%i in (1,2, 3) do echo %%i
879 rem Test zero iteration skips the body of the for
880 for /L %%i in (2,2,1) do (
881   echo %%i
882   echo FAILED
883 )
884 echo --- for /a
885 rem No output when using "set expr" syntax, unless in interactive mode
886 rem Need to use "set envvar=expr" to use in a batch script
887 echo ------ individual operations
888 set var=0
889 set /a var=1 +2 & echo %var%
890 set /a var=1 +-2 & echo %var%
891 set /a var=1 --2 & echo %var%
892 set /a var=2* 3 & echo %var%
893 set /a var=-2* -5 & echo %var%
894 set /a var=12/3 & echo %var%
895 set /a var=13/3 & echo %var%
896 set /a var=-13/3 & echo %var%
897 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
898 set /a var=5 %% 5 & echo %var%
899 set /a var=5 %% 3 & echo %var%
900 set /a var=5 %% -3 & echo %var%
901 set /a var=-5 %% -3 & echo %var%
902 set /a var=1 ^<^< 0 & echo %var%
903 set /a var=1 ^<^< 2 & echo %var%
904 set /a var=1 ^<^< -2 & echo %var%
905 set /a var=-1 ^<^< -2 & echo %var%
906 set /a var=-1 ^<^< 2 & echo %var%
907 set /a var=9 ^>^> 0 & echo %var%
908 set /a var=9 ^>^> 2 & echo %var%
909 set /a var=9 ^>^> -2 & echo %var%
910 set /a var=-9 ^>^> -2 & echo %var%
911 set /a var=-9 ^>^> 2 & echo %var%
912 set /a var=5 ^& 0 & echo %var%
913 set /a var=5 ^& 1 & echo %var%
914 set /a var=5 ^& 3 & echo %var%
915 set /a var=5 ^& 4 & echo %var%
916 set /a var=5 ^& 1 & echo %var%
917 set /a var=5 ^| 0 & echo %var%
918 set /a var=5 ^| 1 & echo %var%
919 set /a var=5 ^| 3 & echo %var%
920 set /a var=5 ^| 4 & echo %var%
921 set /a var=5 ^| 1 & echo %var%
922 set /a var=5 ^^ 0 & echo %var%
923 set /a var=5 ^^ 1 & echo %var%
924 set /a var=5 ^^ 3 & echo %var%
925 set /a var=5 ^^ 4 & echo %var%
926 set /a var=5 ^^ 1 & echo %var%
927 echo ------ precedence and grouping
928 set /a var=4 + 2*3 & echo %var%
929 set /a var=(4+2)*3 & echo %var%
930 set /a var=4 * 3/5 & echo %var%
931 set /a var=(4 * 3)/5 & echo %var%
932 set /a var=4 * 5 %% 4 & echo %var%
933 set /a var=4 * (5 %% 4) & echo %var%
934 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
935 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
936 echo ------ octal and hexadecimal
937 set /a var=0xf + 3 & echo %var%
938 set /a var=0xF + 3 & echo %var%
939 set /a var=015 + 2 & echo %var%
940 set /a var=3, 8+3,0 & echo %var%
941 echo ------ variables
942 set /a var=foo=3, foo+1 & echo %var%
943 if defined foo (echo %foo%) else (
944     echo foo not defined
945 )
946 set /a var=foo=3, foo+=1 & echo %var%
947 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
948 set /a var=foo*= foo & echo %var%
949 set /a var=whateverNonExistingVar & echo %var%
950 set /a var=whateverNonExistingVar + bar & echo %var%
951 set /a var=foo -= foo + 7 & echo %var%
952 set /a var=foo /= 3 + 2 & echo %var%
953 set /a var=foo=5, foo %%=2 & echo %var%
954 set /a var=foo ^<^<= 2 & echo %var%
955 set /a var=foo ^>^>= 2 & echo %var%
956 set /a var=foo ^&= 2 & echo %var%
957 set /a var=foo=5, foo ^|= 2 & echo %var%
958 set /a var=foo=5, foo ^^= 2 & echo %var%
959 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
960 set foo=
961 set bar=
962 set var=
963 echo --- for /F
964 mkdir foobar & cd foobar
965 echo ------ string argument
966 for /F %%i in ("a b c") do echo %%i
967 for /f %%i in ("a ") do echo %%i
968 for /f %%i in ("a") do echo %%i
969 fOr /f %%i in (" a") do echo %%i
970 for /f %%i in (" a ") do echo %%i
971 echo ------ fileset argument
972 echo --------- basic blank handling
973 echo a b c>foo
974 for /f %%i in (foo) do echo %%i
975 echo a >foo
976 for /f %%i in (foo) do echo %%i
977 echo a>foo
978 for /f %%i in (foo) do echo %%i
979 echo  a>foo
980 for /f %%i in (foo) do echo %%i
981 echo  a >foo
982 for /f %%i in (foo) do echo %%i
983 echo. > foo
984 for /f %%i in (foo) do echo %%i
985 echo. >> foo
986 echo b > foo
987 for /f %%i in (foo) do echo %%i
988 echo --------- multi-line with empty lines
989 echo a Z f> foo
990 echo. >> foo
991 echo.>> foo
992 echo b bC>> foo
993 echo c>> foo
994 echo. >> foo
995 for /f %%b in (foo) do echo %%b
996 echo --------- multiple files
997 echo q w > bar
998 echo.>> bar
999 echo kkk>>bar
1000 for /f %%k in (foo bar) do echo %%k
1001 for /f %%k in (bar foo) do echo %%k
1002 rem echo ------ command argument
1003 rem Not implemented on NT4
1004 rem FIXME: Not testable right now in wine: not implemented and would need
1005 rem preliminary grep-like program implementation (e.g. like findstr or fc) even
1006 rem for a simple todo_wine test
1007 rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported
1008 rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported
1009 echo ------ eol option
1010 for /f "eol=@" %%i in ("    ad") do echo %%i
1011 for /f "eol=@" %%i in (" z@y") do echo %%i
1012 for /f "eol=|" %%i in ("a|d") do echo %%i
1013 for /f "eol=@" %%i in ("@y") do echo %%i > output_file
1014 if not exist output_file (echo no output) else (del output_file)
1015 for /f "eol==" %%i in ("=y") do echo %%i > output_file
1016 if not exist output_file (echo no output) else (del output_file)
1017 echo ------ delims option
1018 for /f "delims=|" %%i in ("a|d") do echo %%i
1019 for /f "delims=|" %%i in ("a |d") do echo %%i
1020 for /f "delims=|" %%i in ("a d|") do echo %%i
1021 for /f "delims=| " %%i in ("a d|") do echo %%i
1022 for /f "delims==" %%i in ("C r=d|") do echo %%i
1023 for /f "delims=" %%i in ("foo bar baz") do echo %%i
1024 for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi
1025 echo ------ skip option
1026 echo a > foo
1027 echo b >> foo
1028 echo c >> foo
1029 for /f "skip=2" %%i in (foo) do echo %%i
1030 for /f "skip=3" %%i in (foo) do echo %%i > output_file
1031 if not exist output_file (echo no output) else (del output_file)
1032 for /f "skip=4" %%i in (foo) do echo %%i > output_file
1033 if not exist output_file (echo no output) else (del output_file)
1034 cd ..
1035 rd /s/q foobar
1036
1037 echo ------------ Testing del /a ------------
1038 del /f/q *.test > nul
1039 echo r > r.test
1040 attrib +r r.test
1041 echo not-r > not-r.test
1042
1043 if not exist not-r.test echo not-r.test not found before delete, bad
1044 del /a:-r *.test
1045 if not exist not-r.test echo not-r.test not found after delete, good
1046
1047 if not exist r.test echo r.test not found before delete, bad
1048 if exist r.test echo r.test found before delete, good
1049 del /a:r *.test
1050 if not exist r.test echo r.test not found after delete, good
1051 if exist r.test echo r.test found after delete, bad
1052
1053 echo ------------ Testing del /q ------------
1054 mkdir del_q_dir
1055 cd del_q_dir
1056 echo abc > file1
1057 echo abc > file2.dat
1058 rem If /q doesn't work, cmd will prompt and the test case should hang
1059 del /q * > nul
1060 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
1061 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
1062 cd ..
1063 rmdir del_q_dir
1064
1065 echo ------------ Testing del /s ------------
1066 mkdir "foo bar"
1067 cd "foo bar"
1068 mkdir "foo:"
1069 echo hi > file1.dat
1070 echo there > file2.dat
1071 echo bub > file3.dat
1072 echo bye > "file with spaces.dat"
1073 cd ..
1074 del /s file1.dat > nul
1075 del file2.dat /s > nul
1076 del "file3.dat" /s > nul
1077 del "file with spaces.dat" /s > nul
1078 cd "foo bar"
1079 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
1080 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
1081 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
1082 if exist "file with spaces.dat" del "file with spaces.dat"
1083 rmdir "foo:"
1084 cd ..
1085 rmdir "foo bar"
1086
1087 echo ------------ Testing rename ------------
1088 mkdir foobar & cd foobar
1089 echo --- ren and rename are synonymous
1090 echo > foo
1091 rename foo bar
1092 if exist foo echo foo should be renamed!
1093 if exist bar echo foo renamed to bar
1094 ren bar foo
1095 if exist bar echo bar should be renamed!
1096 if exist foo echo bar renamed to foo
1097 echo --- name collision
1098 echo foo>foo
1099 echo bar>bar
1100 ren foo bar 2> nul
1101 type foo
1102 type bar
1103 rem no-op
1104 ren foo foo
1105 mkdir baz
1106 ren foo baz\abc
1107 echo --- rename read-only files
1108 echo > file1
1109 attrib +r file1
1110 ren file1 file2
1111 if not exist file1 (
1112     if exist file2 (
1113         echo read-only file renamed
1114     )
1115 ) else (
1116     echo read-only file not renamed!
1117 )
1118 echo --- rename directories
1119 mkdir rep1
1120 ren rep1 rep2
1121 if not exist rep1 (
1122     if exist rep2 (
1123         echo dir renamed
1124     )
1125 )
1126 attrib +r rep2
1127 ren rep2 rep1
1128 if not exist rep2 (
1129     if exist rep1 (
1130         echo read-only dir renamed
1131     )
1132 )
1133 echo --- rename in other directory
1134 if not exist baz\abc (
1135     echo rename impossible in other directory
1136     if exist foo echo original file still present
1137 ) else (
1138     echo shouldn't rename in other directory!
1139     if not exist foo echo original file not present anymore
1140 )
1141 cd .. & rd /s/q foobar
1142
1143 echo ------------ Testing move ------------
1144 mkdir foobar & cd foobar
1145 echo --- file move
1146 echo >foo
1147 move foo bar > nul 2>&1
1148 if not exist foo (
1149     if exist bar (
1150         echo file move succeeded
1151     )
1152 )
1153 echo bar>bar
1154 echo baz> baz
1155 move /Y bar baz > nul 2>&1
1156 if not exist bar (
1157     if exist baz (
1158         echo file move with overwrite succeeded
1159     )
1160 ) else (
1161     echo file overwrite impossible!
1162     del bar
1163 )
1164 type baz
1165
1166 attrib +r baz
1167 move baz bazro > nul 2>&1
1168 if not exist baz (
1169     if exist bazro (
1170         echo read-only files are moveable
1171         move bazro baz > nul 2>&1
1172     )
1173 ) else (
1174     echo read-only file not moved!
1175 )
1176 attrib -r baz
1177 mkdir rep
1178 move baz rep > nul 2>&1
1179 if not exist baz (
1180     if exist rep\baz (
1181         echo file moved in subdirectory
1182     )
1183 )
1184 call :setError 0
1185 move rep\baz . > nul 2>&1
1186 move /Y baz baz > nul 2>&1
1187 if errorlevel 1 (
1188     echo moving a file to itself should be a no-op!
1189 ) else (
1190     echo moving a file to itself is a no-op
1191 )
1192 echo ErrorLevel: %ErrorLevel%
1193 call :setError 0
1194 del baz
1195 echo --- directory move
1196 mkdir foo\bar
1197 mkdir baz
1198 echo baz2>baz\baz2
1199 move baz foo\bar > nul 2>&1
1200 if not exist baz (
1201     if exist foo\bar\baz\baz2 (
1202         echo simple directory move succeeded
1203     )
1204 )
1205 call :setError 0
1206 mkdir baz
1207 move baz baz > nul 2>&1
1208 echo moving a directory to itself gives error; errlevel %ErrorLevel%
1209 echo ------ dir in dir move
1210 rd /s/q foo
1211 mkdir foo bar
1212 echo foo2>foo\foo2
1213 echo bar2>bar\bar2
1214 move foo bar > nul 2>&1
1215 if not exist foo (
1216     if exist bar (
1217         dir /b /ad bar
1218         dir /b /a-d bar
1219         dir /b bar\foo
1220     )
1221 )
1222 cd .. & rd /s/q foobar
1223
1224 echo ------------ Testing mkdir ------------
1225 call :setError 0
1226 echo --- md and mkdir are synonymous
1227 mkdir foobar
1228 echo %ErrorLevel%
1229 rmdir foobar
1230 md foobar
1231 echo %ErrorLevel%
1232 rmdir foobar
1233 echo --- creating an already existing directory/file must fail
1234 mkdir foobar
1235 md foobar
1236 echo %ErrorLevel%
1237 rmdir foobar
1238 echo > foobar
1239 mkdir foobar
1240 echo %ErrorLevel%
1241 del foobar
1242 echo --- multilevel path creation
1243 mkdir foo
1244 echo %ErrorLevel%
1245 mkdir foo\bar\baz
1246 echo %ErrorLevel%
1247 cd foo
1248 echo %ErrorLevel%
1249 cd bar
1250 echo %ErrorLevel%
1251 cd baz
1252 echo %ErrorLevel%
1253 echo > ..\..\bar2
1254 mkdir ..\..\..\foo\bar2
1255 echo %ErrorLevel%
1256 del ..\..\bar2
1257 mkdir ..\..\..\foo\bar2
1258 echo %ErrorLevel%
1259 rmdir ..\..\..\foo\bar2
1260 cd ..
1261 rmdir baz
1262 cd ..
1263 rmdir bar
1264 cd ..
1265 rmdir foo
1266 echo %ErrorLevel%
1267 echo --- trailing backslashes
1268 mkdir foo\\\\
1269 echo %ErrorLevel%
1270 if exist foo (rmdir foo & echo dir created
1271 ) else ( echo dir not created )
1272 echo %ErrorLevel%
1273 echo --- invalid chars
1274 mkdir ?
1275 echo mkdir ? gives errorlevel %ErrorLevel%
1276 call :setError 0
1277 mkdir ?\foo
1278 echo mkdir ?\foo gives errorlevel %ErrorLevel%
1279 call :setError 0
1280 mkdir foo\?
1281 echo mkdir foo\? gives errorlevel %ErrorLevel%
1282 if exist foo (rmdir foo & echo ok, foo created
1283 ) else ( echo foo not created )
1284 call :setError 0
1285 mkdir foo\bar\?
1286 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
1287 call :setError 0
1288 if not exist foo (
1289     echo bad, foo not created
1290 ) else (
1291     cd foo
1292     if exist bar (
1293         echo ok, foo\bar created
1294         rmdir bar
1295     )
1296     cd ..
1297     rmdir foo
1298 )
1299 echo --- multiple directories at once
1300 mkdir foobaz & cd foobaz
1301 mkdir foo bar\baz foobar "bazbaz" .\"zabzab"
1302 if exist foo (echo foo created) else echo foo not created!
1303 if exist bar (echo bar created) else echo bar not created!
1304 if exist foobar (echo foobar created) else echo foobar not created!
1305 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
1306 if exist bazbaz (echo bazbaz created) else echo bazbaz not created!
1307 if exist zabzab (echo zabzab created) else echo zabzab not created!
1308 cd .. & rd /s/q foobaz
1309 call :setError 0
1310 mkdir foo\*
1311 echo mkdir foo\* errorlevel %ErrorLevel%
1312 if exist foo (rmdir foo & echo ok, foo created
1313 ) else ( echo bad, foo not created )
1314
1315 echo ------------ Testing rmdir ------------
1316 call :setError 0
1317 rem rd and rmdir are synonymous
1318 mkdir foobar
1319 rmdir foobar
1320 echo %ErrorLevel%
1321 if not exist foobar echo dir removed
1322 mkdir foobar
1323 rd foobar
1324 echo %ErrorLevel%
1325 if not exist foobar echo dir removed
1326 rem Removing nonexistent directory
1327 rmdir foobar
1328 echo %ErrorLevel%
1329 rem Removing single-level directories
1330 echo > foo
1331 rmdir foo
1332 echo %ErrorLevel%
1333 if exist foo echo file not removed
1334 del foo
1335 mkdir foo
1336 echo > foo\bar
1337 rmdir foo
1338 echo %ErrorLevel%
1339 if exist foo echo non-empty dir not removed
1340 del foo\bar
1341 mkdir foo\bar
1342 rmdir foo
1343 echo %ErrorLevel%
1344 if exist foo echo non-empty dir not removed
1345 rmdir foo\bar
1346 rmdir foo
1347 rem Recursive rmdir
1348 mkdir foo\bar\baz
1349 rmdir /s /Q foo
1350 if not exist foo (
1351     echo recursive rmdir succeeded
1352 ) else (
1353     rd foo\bar\baz
1354     rd foo\bar
1355     rd foo
1356 )
1357 mkdir foo\bar\baz
1358 echo foo > foo\bar\brol
1359 rmdir /s /Q foo 2>&1
1360 if not exist foo (
1361     echo recursive rmdir succeeded
1362 ) else (
1363     rd foo\bar\baz
1364     del foo\bar\brol
1365     rd foo\bar
1366     rd foo
1367 )
1368 rem multiples directories at once
1369 mkdir foobaz & cd foobaz
1370 mkdir foo
1371 mkdir bar\baz
1372 mkdir foobar
1373 rd /s/q foo bar foobar
1374 if not exist foo (echo foo removed) else echo foo not removed!
1375 if not exist bar (echo bar removed) else echo bar not removed!
1376 if not exist foobar (echo foobar removed) else echo foobar not removed!
1377 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
1378 cd .. & rd /s/q foobaz
1379
1380 echo ------------ Testing pushd/popd ------------
1381 cd
1382 echo --- popd is no-op when dir stack is empty
1383 popd
1384 cd
1385 echo --- pushing non-existing dir
1386 pushd foobar
1387 cd
1388 echo --- basic behaviour
1389 mkdir foobar\baz
1390 pushd foobar
1391 cd
1392 popd
1393 cd
1394 pushd foobar
1395 pushd baz
1396 cd
1397 popd
1398 cd
1399 pushd baz
1400 popd
1401 cd
1402 popd
1403 cd
1404 pushd .
1405 cd foobar\baz
1406 pushd ..
1407 cd
1408 popd
1409 popd
1410 cd
1411 rd /s/q foobar
1412
1413 echo ------------ Testing attrib ------------
1414 rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications
1415 mkdir foobar & cd foobar
1416 echo foo original contents> foo
1417 attrib foo
1418 echo > bar
1419 echo --- read-only attribute
1420 rem Read-only files cannot be altered or deleted, unless forced
1421 attrib +R foo
1422 attrib foo
1423 dir /Ar /B
1424 echo bar>> foo
1425 type foo
1426 del foo > NUL 2>&1
1427 if exist foo (
1428     echo Read-only file not deleted
1429 ) else (
1430     echo Should not delete read-only file!
1431 )
1432 del /F foo
1433 if not exist foo (
1434     echo Read-only file forcibly deleted
1435 ) else (
1436     echo Should delete read-only file with del /F!
1437     attrib -r foo
1438     del foo
1439 )
1440 cd .. & rd /s/q foobar
1441 echo --- recursive behaviour
1442 mkdir foobar\baz & cd foobar
1443 echo > level1
1444 echo > whatever
1445 echo > baz\level2
1446 attrib baz\level2
1447 cd ..
1448 attrib +R l*vel? /S > nul 2>&1
1449 cd foobar
1450 attrib level1
1451 attrib baz\level2
1452 echo > bar
1453 attrib bar
1454 cd .. & rd /s/q foobar
1455 echo --- folders processing
1456 mkdir foobar
1457 attrib foobar
1458 cd foobar
1459 mkdir baz
1460 echo toto> baz\toto
1461 attrib +r baz /s /d > nul 2>&1
1462 attrib baz
1463 attrib baz\toto
1464 echo lulu>>baz\toto
1465 type baz\toto
1466 echo > baz\lala
1467 rem Oddly windows allows file creation in a read-only directory...
1468 if exist baz\lala (echo file created in read-only dir) else echo file not created
1469 cd .. & rd /s/q foobar
1470
1471 echo ------------ Testing assoc ------------
1472 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
1473 rem FIXME Revise once || conditional execution is fixed
1474 mkdir foobar & cd foobar
1475 echo --- setting association
1476 assoc .foo > baz
1477 type baz
1478 echo ---
1479
1480 assoc .foo=bar
1481 assoc .foo
1482
1483 rem association set system-wide
1484 echo @echo off> tmp.cmd
1485 echo echo +++>> tmp.cmd
1486 echo assoc .foo>> tmp.cmd
1487 cmd /c tmp.cmd
1488
1489 echo --- resetting association
1490 assoc .foo=
1491 assoc .foo > baz
1492 type baz
1493 echo ---
1494
1495 rem association removal set system-wide
1496 cmd /c tmp.cmd > baz
1497 type baz
1498 echo ---
1499 cd .. & rd /s/q foobar
1500
1501 echo ------------ Testing ftype ------------
1502 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
1503 rem FIXME Revise once || conditional execution is fixed
1504 mkdir foobar & cd foobar
1505 echo --- setting association
1506 ftype footype> baz
1507 type baz
1508 echo ---
1509
1510 ftype footype=foo_opencmd
1511 assoc .foo=footype
1512 ftype footype
1513
1514 rem association set system-wide
1515 echo @echo off> tmp.cmd
1516 echo echo +++>> tmp.cmd
1517 echo ftype footype>> tmp.cmd
1518 cmd /c tmp.cmd
1519
1520 echo --- resetting association
1521 assoc .foo=
1522
1523 rem Removing a file type association doesn't work on XP due to a bug, so a workaround is needed
1524 setlocal EnableDelayedExpansion
1525 set FOO=original value
1526 ftype footype=
1527 ftype footype > baz
1528 for /F %%i in ('type baz') do (set FOO=buggyXP)
1529 rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion)
1530 rem FIXME Revisit once a grep-like program like ftype is implemented
1531 rem (e.g. to check baz's size using dir /b instead)
1532 echo !FOO!
1533
1534 rem cleanup registry
1535 echo REGEDIT4> regCleanup.reg
1536 echo.>> regCleanup.reg
1537 echo [-HKEY_CLASSES_ROOT\footype]>> regCleanup.reg
1538 regedit /s regCleanup.reg
1539 set FOO=
1540 endlocal
1541 cd .. & rd /s/q foobar
1542
1543 echo ------------ Testing CALL ------------
1544 mkdir foobar & cd foobar
1545 echo --- external script
1546 echo echo foo %%1> foo.cmd
1547 call foo
1548 call foo.cmd 8
1549 echo echo %%1 %%2 > foo.cmd
1550 call foo.cmd foo
1551 call foo.cmd foo bar
1552 call foo.cmd foo ""
1553 call foo.cmd "" bar
1554 call foo.cmd foo ''
1555 call foo.cmd '' bar
1556 del foo.cmd
1557
1558 echo --- internal routines
1559 call :testRoutine :testRoutine
1560 goto :endTestRoutine
1561 :testRoutine
1562 echo bar %1
1563 goto :eof
1564 :endTestRoutine
1565
1566 call :testRoutineArgs foo
1567 call :testRoutineArgs foo bar
1568 call :testRoutineArgs foo ""
1569 call :testRoutineArgs ""  bar
1570 call :testRoutineArgs foo ''
1571 call :testRoutineArgs ''  bar
1572 goto :endTestRoutineArgs
1573 :testRoutineArgs
1574 echo %1 %2
1575 goto :eof
1576 :endTestRoutineArgs
1577
1578 echo --- with builtins
1579 call mkdir foo
1580 echo %ErrorLevel%
1581 if exist foo (echo foo created) else echo foo should exist!
1582 rmdir foo
1583 set FOOBAZ_VAR=foobaz
1584 call echo Should expand %FOOBAZ_VAR%
1585 set FOOBAZ_VAR=
1586 echo>batfile
1587 call dir /b
1588 echo>robinfile
1589 if 1==1 call del batfile
1590 dir /b
1591 if exist batfile echo batfile shouldn't exist
1592 rem ... but not for 'if' or 'for'
1593 call if 1==1 echo bar 2> nul
1594 echo %ErrorLevel%
1595 call :setError 0
1596 call for %%i in (foo bar baz) do echo %%i 2> nul
1597 echo %ErrorLevel%
1598 rem First look for programs in the path before trying a builtin
1599 echo echo non-builtin dir> dir.cmd
1600 call dir /b
1601 cd .. & rd /s/q foobar
1602
1603 echo ------------ Testing SHIFT ------------
1604
1605 call :shiftFun p1 p2 p3 p4 p5
1606 goto :endShiftFun
1607
1608 :shiftFun
1609 echo '%1' '%2' '%3' '%4' '%5'
1610 shift
1611 echo '%1' '%2' '%3' '%4' '%5'
1612 shift@tab@ /1
1613 echo '%1' '%2' '%3' '%4' '%5'
1614 shift /2
1615 echo '%1' '%2' '%3' '%4' '%5'
1616 shift /-1
1617 echo '%1' '%2' '%3' '%4' '%5'
1618 shift /0
1619 echo '%1' '%2' '%3' '%4' '%5'
1620 goto :eof
1621 :endShiftFun
1622
1623 echo ------------ Testing cmd invocation ------------
1624 rem FIXME: only a stub ATM
1625 echo --- a batch file can delete itself
1626 echo del foo.cmd>foo.cmd
1627 cmd /q /c foo.cmd
1628 if not exist foo.cmd (
1629     echo file correctly deleted
1630 ) else (
1631     echo file should be deleted!
1632     del foo.cmd
1633 )
1634 echo --- a batch file can alter itself
1635 echo echo bar^>foo.cmd>foo.cmd
1636 cmd /q /c foo.cmd > NUL 2>&1
1637 if exist foo.cmd (
1638     type foo.cmd
1639     del foo.cmd
1640 ) else (
1641     echo file not created!
1642 )
1643
1644 echo ------------ Testing setlocal/endlocal ------------
1645 call :setError 0
1646 rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test section
1647 mkdir foobar & cd foobar
1648 echo --- enable/disable extensions
1649 setlocal DisableEXTensions
1650 echo ErrLev: %ErrorLevel%
1651 endlocal
1652 echo ErrLev: %ErrorLevel%
1653 echo @echo off> tmp.cmd
1654 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
1655 rem Enabled by default
1656 cmd /C tmp.cmd
1657 cmd /E:OfF /C tmp.cmd
1658 cmd /e:oN /C tmp.cmd
1659
1660 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
1661 echo --- setlocal with corresponding endlocal
1662 rem %CD% does not tork on NT4 so use the following workaround
1663 for /d %%i in (.) do set CURDIR=%%~dpnxi
1664 echo @echo off> test.cmd
1665 echo echo %%VAR%%>> test.cmd
1666 echo setlocal>> test.cmd
1667 echo set VAR=localval>> test.cmd
1668 echo md foobar2>> test.cmd
1669 echo cd foobar2>> test.cmd
1670 echo echo %%VAR%%>> test.cmd
1671 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1672 echo endlocal>> test.cmd
1673 echo echo %%VAR%%>> test.cmd
1674 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1675 set VAR=globalval
1676 call test.cmd
1677 echo %VAR%
1678 for /d %%i in (.) do echo %%~dpnxi
1679 cd /d %curdir%
1680 rd foobar2
1681 set VAR=
1682 echo --- setlocal with no corresponding endlocal
1683 echo @echo off> test.cmd
1684 echo echo %%VAR%%>> test.cmd
1685 echo setlocal>> test.cmd
1686 echo set VAR=localval>> test.cmd
1687 echo md foobar2>> test.cmd
1688 echo cd foobar2>> test.cmd
1689 echo echo %%VAR%%>> test.cmd
1690 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1691 set VAR=globalval
1692 rem %CD% does not tork on NT4 so use the following workaround
1693 for /d %%i in (.) do set CURDIR=%%~dpnxi
1694 call test.cmd
1695 echo %VAR%
1696 for /d %%i in (.) do echo %%~dpnxi
1697 cd /d %curdir%
1698 rd foobar2
1699 set VAR=
1700 echo --- setlocal within same batch program
1701 set var1=one
1702 set var2=
1703 set var3=
1704 rem %CD% does not tork on NT4 so use the following workaround
1705 for /d %%i in (.) do set CURDIR=%%~dpnxi
1706 setlocal
1707 set var2=two
1708 mkdir foobar2
1709 cd foobar2
1710 setlocal
1711 set var3=three
1712 if "%var1%"=="one" echo Var1 ok 1
1713 if "%var2%"=="two" echo Var2 ok 2
1714 if "%var3%"=="three" echo Var3 ok 3
1715 for /d %%i in (.) do set curdir2=%%~dpnxi
1716 if "%curdir2%"=="%curdir%\foobar2" echo Directory is ok 1
1717 endlocal
1718 if "%var1%"=="one" echo Var1 ok 1
1719 if "%var2%"=="two" echo Var2 ok 2
1720 if "%var3%"=="" echo Var3 ok 3
1721 for /d %%i in (.) do set curdir2=%%~dpnxi
1722 if "%curdir2%"=="%curdir%\foobar2" echo Directory is ok 2
1723 endlocal
1724 if "%var1%"=="one" echo Var1 ok 1
1725 if "%var2%"=="" echo Var2 ok 2
1726 if "%var3%"=="" echo Var3 ok 3
1727 for /d %%i in (.) do set curdir2=%%~dpnxi
1728 if "%curdir2%"=="%curdir%" echo Directory is ok 3
1729 rd foobar2 /s /q
1730 set var1=
1731
1732 echo --- Mismatched set and end locals
1733 mkdir foodir2 2>nul
1734 mkdir foodir3 2>nul
1735 mkdir foodir4 2>nul
1736 rem %CD% does not tork on NT4 so use the following workaround
1737 for /d %%i in (.) do set curdir=%%~dpnxi
1738
1739 echo @echo off> 2set1end.cmd
1740 echo echo %%VAR%%>> 2set1end.cmd
1741 echo setlocal>> 2set1end.cmd
1742 echo set VAR=2set1endvalue1>> 2set1end.cmd
1743 echo cd ..\foodir3>> 2set1end.cmd
1744 echo setlocal>> 2set1end.cmd
1745 echo set VAR=2set1endvalue2>> 2set1end.cmd
1746 echo cd ..\foodir4>> 2set1end.cmd
1747 echo endlocal>> 2set1end.cmd
1748 echo echo %%VAR%%>> 2set1end.cmd
1749 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 2set1end.cmd
1750
1751 echo @echo off> 1set2end.cmd
1752 echo echo %%VAR%%>> 1set2end.cmd
1753 echo setlocal>> 1set2end.cmd
1754 echo set VAR=1set2endvalue1>> 1set2end.cmd
1755 echo cd ..\foodir3>> 1set2end.cmd
1756 echo endlocal>> 1set2end.cmd
1757 echo echo %%VAR%%>> 1set2end.cmd
1758 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
1759 echo endlocal>> 1set2end.cmd
1760 echo echo %%VAR%%>> 1set2end.cmd
1761 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
1762
1763 echo --- Extra setlocal in called batch
1764 set VAR=value1
1765 rem -- setlocal1 == this batch, should never be used inside a called routine
1766 setlocal
1767 set var=value2
1768 cd foodir2
1769 call %curdir%\2set1end.cmd
1770 echo Finished:
1771 echo %VAR%
1772 for /d %%i in (.) do echo %%~dpnxi
1773 endlocal
1774 echo %VAR%
1775 for /d %%i in (.) do echo %%~dpnxi
1776 cd /d %curdir%
1777
1778 echo --- Extra endlocal in called batch
1779 set VAR=value1
1780 rem -- setlocal1 == this batch, should never be used inside a called routine
1781 setlocal
1782 set var=value2
1783 cd foodir2
1784 call %curdir%\1set2end.cmd
1785 echo Finished:
1786 echo %VAR%
1787 for /d %%i in (.) do echo %%~dpnxi
1788 endlocal
1789 echo %VAR%
1790 for /d %%i in (.) do echo %%~dpnxi
1791 cd /d %curdir%
1792
1793 echo --- endlocal in called function rather than batch pgm is ineffective
1794 @echo off
1795 set var=1
1796 set var2=1
1797 setlocal
1798 set var=2
1799 call :endlocalroutine
1800 echo %var%
1801 endlocal
1802 echo %var%
1803 goto :endlocalfinished
1804 :endlocalroutine
1805 echo %var%
1806 endlocal
1807 echo %var%
1808 setlocal
1809 set var2=2
1810 endlocal
1811 echo %var2%
1812 endlocal
1813 echo %var%
1814 echo %var2%
1815 goto :eof
1816 :endlocalfinished
1817 echo %var%
1818
1819 set var=
1820 set var2=
1821 cd .. & rd /q/s foobar
1822
1823 echo ------------ Testing Errorlevel ------------
1824 rem WARNING: Do *not* add tests using ErrorLevel after this section
1825 should_not_exist 2> nul > nul
1826 echo %ErrorLevel%
1827 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
1828 rem See http://www.robvanderwoude.com/exit.php
1829 call :setError 1
1830 echo %ErrorLevel%
1831 if errorlevel 2 echo errorlevel too high, bad
1832 if errorlevel 1 echo errorlevel just right, good
1833 if errorlevel 01 echo errorlevel with leading zero just right, good
1834 if errorlevel -1 echo errorlevel with negative number OK
1835 if errorlevel 0x1 echo hexa should not be recognized!
1836 if errorlevel 1a echo invalid error level recognized!
1837 call :setError 0
1838 echo abc%ErrorLevel%def
1839 if errorlevel 1 echo errorlevel nonzero, bad
1840 if not errorlevel 1 echo errorlevel zero, good
1841 if not errorlevel 0x1 echo hexa should not be recognized!
1842 if not errorlevel 1a echo invalid error level recognized!
1843 rem Now verify that setting a real variable hides its magic variable
1844 set errorlevel=7
1845 echo %ErrorLevel% should be 7
1846 if errorlevel 7 echo setting var worked too well, bad
1847 call :setError 3
1848 echo %ErrorLevel% should still be 7
1849
1850 echo ------------ Testing GOTO ------------
1851 if a==a goto dest1
1852 :dest1
1853 echo goto with no leading space worked
1854 if b==b goto dest2
1855  :dest2
1856 echo goto with a leading space worked
1857 if c==c goto dest3
1858         :dest3
1859 echo goto with a leading tab worked
1860 if d==d goto dest4
1861 :dest4@space@
1862 echo goto with a following space worked
1863
1864 echo ------------ Testing PATH ------------
1865 set backup_path=%path%
1866 set path=original
1867 path
1868 path try2
1869 path
1870 path=try3
1871 path
1872 set path=%backup_path%
1873 set backup_path=
1874
1875 echo ------------ Testing combined CALLs/GOTOs ------------
1876 echo @echo off>foo.cmd
1877 echo goto :eof>>foot.cmd
1878 echo :eof>>foot.cmd
1879 echo echo world>>foo.cmd
1880
1881 echo @echo off>foot.cmd
1882 echo echo cheball>>foot.cmd
1883 echo.>>foot.cmd
1884 echo call :bar>>foot.cmd
1885 echo if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmd
1886 echo goto :eof>>foot.cmd
1887 echo.>>foot.cmd
1888 echo :bar>>foot.cmd
1889 echo echo barbare>>foot.cmd
1890 echo goto :eof>>foot.cmd
1891
1892 call foo.cmd
1893 call foot
1894 call :bar
1895 del foo.cmd
1896 rem Script execution stops after the following line
1897 foot deleteMe
1898 call :foo
1899 call :foot
1900 goto :endFuns
1901
1902 :foot
1903 echo foot
1904
1905 :foo
1906 echo foo
1907 goto :eof
1908
1909 :endFuns
1910
1911 :bar
1912 echo bar
1913 call :foo
1914
1915 :baz
1916 echo baz
1917 goto :eof
1918
1919 echo Final message is not output since earlier 'foot' processing stops script execution
1920 echo Do NOT add any tests below this line
1921
1922 echo ------------ Done, jumping to EOF -----------
1923 goto :eof
1924 rem Subroutine to set errorlevel and return
1925 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
1926 :setError
1927 exit /B %1
1928 rem This line runs under cmd in windows NT 4, but not in more modern versions.