cmd: Add suite of tests for the copy command.
[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 for %%i in (foo) do echo '%%~zi'
351 del foo
352 rem file date/time
353 rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar...
354 for %%i in ("a b" c) do echo '%%~ti'
355 rem file size
356 rem Similar issues as above
357 for %%i in ("a b" c) do echo '%%~zi'
358 rem combined options
359 for %%i in ("d e" f) do echo %%~dpi
360 for %%i in ("g h" i) do echo %%~sdi
361 for %%i in ("g h" i) do echo %%~dsi
362 for %%i in ("j k" l.eh) do echo '%%~xsi'
363
364 echo --- in parameters
365 for %%i in ("A B" C) do call :echoFun %%i
366 rem quotes removal
367 for %%i in ("A B" C) do call :echoFunQ %%i
368 rem fully qualified path
369 for %%f in ("C D" E) do call :echoFunF %%f
370 rem drive letter
371 for %%i in ("F G" H) do call :echoFunD %%i
372 rem path
373 for %%d in ("I J" K) do call :echoFunP %%d
374 rem filename
375 for %%i in ("L M" N) do call :echoFunN %%i
376 rem file extension
377 for %%i in ("O. P.OOL" Q.TABC hello) do call :echoFunX %%i
378 rem path with short path names
379 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do call :echoFunS %%I
380 rem NT4 aborts whole script execution when encountering ~a, ~t and ~z substitutions, preventing full testing
381 rem combined options
382 for %%i in ("d e" f) do call :echoFunDP %%i
383 for %%i in ("g h" i) do call :echoFunSD %%i
384 for %%i in ("g h" i) do call :echoFunDS %%i
385 for %%i in ("j k" l.eh) do call :echoFunXS %%i
386
387 goto :endEchoFuns
388 :echoFun
389 echo %1
390 goto :eof
391
392 :echoFunQ
393 echo '%~1'
394 goto :eof
395
396 :echoFunF
397 echo %~f1
398 goto :eof
399
400 :echoFunD
401 echo %~d1
402 goto :eof
403
404 :echoFunP
405 echo %~p1
406 goto :eof
407
408 :echoFunN
409 echo %~n1
410 goto :eof
411
412 :echoFunX
413 echo '%~x1'
414 goto :eof
415
416 :echoFunS
417 rem some NT4 workaround
418 set VAR='%~s1'
419 echo %VAR%
420 set VAR=
421 goto :eof
422
423 :echoFunDP
424 echo %~dp1
425 goto :eof
426
427 :echoFunSD
428 echo %~sd1
429 goto :eof
430
431 :echoFunDS
432 echo %~ds1
433 goto :eof
434
435 :echoFunXS
436 echo '%~xs1'
437 goto :eof
438 :endEchoFuns
439
440 echo ------------ Testing variable delayed expansion ------------
441 rem NT4 doesn't support this
442 echo --- default mode (load-time expansion)
443 set FOO=foo
444 echo %FOO%
445 echo !FOO!
446 if %FOO% == foo (
447     set FOO=bar
448     if %FOO% == bar (echo bar) else echo foo
449 )
450
451 set FOO=foo
452 if %FOO% == foo (
453     set FOO=bar
454     if !FOO! == bar (echo bar) else echo foo
455 )
456
457 echo --- runtime (delayed) expansion mode
458 setlocal EnableDelayedExpansion
459 set FOO=foo
460 echo %FOO%
461 echo !FOO!
462 if %FOO% == foo (
463     set FOO=bar
464     if %FOO% == bar (echo bar) else echo foo
465 )
466
467 set FOO=foo
468 if %FOO% == foo (
469     set FOO=bar
470     if !FOO! == bar (echo bar) else echo foo
471 )
472 echo %ErrorLevel%
473 setlocal DisableDelayedExpansion
474 echo %ErrorLevel%
475 set FOO=foo
476 echo %FOO%
477 echo !FOO!
478 set FOO=
479 echo --- using /V cmd flag
480 echo @echo off> tmp.cmd
481 echo set FOO=foo>> tmp.cmd
482 echo echo %%FOO%%>> tmp.cmd
483 echo echo !FOO!>> tmp.cmd
484 echo set FOO=>> tmp.cmd
485 cmd /V:ON /C tmp.cmd
486 cmd /V:OfF /C tmp.cmd
487 del tmp.cmd
488
489 echo ------------ Testing conditional execution ------------
490 echo --- unconditional ampersand
491 call :setError 123 & echo foo1
492 echo bar2 & echo foo2
493 mkdir foobar & cd foobar
494 echo > foobazbar
495 cd .. & rd /s/q foobar
496 if exist foobazbar (
497     echo foobar not deleted!
498     cd ..
499     rd /s/q foobar
500 ) else echo foobar deleted
501 echo --- on success conditional and
502 call :setError 456 && echo foo3 > foo3
503 if exist foo3 (
504     echo foo3 created
505     del foo3
506 ) else echo foo3 not created
507 echo bar4 && echo foo4
508 echo --- on failure conditional or
509 call :setError 789 || echo foo5
510 echo foo6 || echo bar6 > bar6
511 if exist bar6 (
512     echo bar6 created
513     del bar6
514 )
515
516 echo ------------ Testing cd ------------
517 mkdir foobar
518 cd foobar
519 echo blabla > singleFile
520 dir /b
521 echo Current dir: %CD%
522 cd
523 cd ..
524 cd
525 cd foobar@space@
526 cd
527 cd ..
528 cd
529 cd @space@foobar
530 cd
531 cd..
532 cd
533 cd foobar
534 cd..@space@
535 cd
536 if not exist foobar (cd ..)
537 cd foobar
538 cd@tab@..@tab@@space@@tab@
539 cd
540 if not exist foobar (cd ..)
541 cd foobar
542 mkdir "bar bak"
543 cd "bar bak"
544 cd
545 cd ..
546 cd ".\bar bak"
547 cd
548 cd ..
549 cd .\"bar bak"
550 cd
551 cd ..
552 cd bar bak
553 cd
554 cd "bar bak@space@"@tab@@space@
555 cd
556 cd ..\..
557 cd
558 rd /Q/s foobar
559 mkdir foobar
560 cd /d@tab@foobar
561 cd
562 cd ..
563 rd /q/s foobar
564
565 echo ------------ Testing type ------------
566 echo bar> foobaz
567 @echo on
568 type foobaz
569 echo ---
570 @echo off
571 type foobaz@tab@
572 echo ---1
573 type ."\foobaz"
574 echo ---2
575 type ".\foobaz"
576 echo ---3
577 del foobaz
578
579 echo ------------ Testing NUL ------------
580 md foobar & cd foobar
581 rem NUL file (non) creation + case insensitivity
582 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
583 echo > bar
584 echo foo > NUL
585 dir /b /a-d
586 echo foo > nul
587 dir /b /a-d
588 echo foo > NuL
589 @tab@dir /b@tab@/a-d
590 del bar
591 rem NUL not special everywhere
592 call :setError 123
593 echo NUL> foo
594 if not exist foo (echo foo should have been created) else (
595     type foo
596     del foo
597 )
598 rem Empty file creation
599 copy nul foo > nul
600 if exist foo (
601     echo foo created
602     del foo
603     type foo
604 ) else (
605     echo ***
606 )
607 cd .. & rd foobar
608
609 echo ------------ Testing if/else ------------
610 echo if/else should work with blocks
611 if 0 == 0 (
612   echo if seems to work
613 ) else (
614   echo if seems to be broken
615 )
616 if 1 == 0 (
617   echo else seems to be broken
618 ) else (
619   echo else seems to work
620 )
621 if /c==/c (
622   echo if seems not to detect /c as parameter
623 ) else (
624   echo parameter detection seems to be broken
625 )
626 echo Testing case sensitivity with and without /i option
627 if bar==BAR echo if does not default to case sensitivity
628 if not bar==BAR echo if seems to default to case sensitivity
629 if /i foo==FOO echo if /i seems to work
630 if /i not foo==FOO echo if /i seems to be broken
631 if /I foo==FOO echo if /I seems to work
632 if /I not foo==FOO echo if /I seems to be broken
633 echo Testing string comparisons
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 if "abc"== "abc" (echo equal) else echo non equal
638 echo Testing tabs handling
639 if@tab@1==1 echo doom
640 if @tab@1==1 echo doom
641 if 1==1 (echo doom) else@tab@echo quake
642 if@tab@not @tab@1==@tab@0 @tab@echo lol
643 if 1==0@tab@(echo doom) else echo quake
644 if 1==0 (echo doom)@tab@else echo quake
645 if 1==0 (echo doom) else@tab@echo quake
646
647 echo ------------ Testing for ------------
648 echo --- plain FOR
649 for %%i in (A B C) do echo %%i
650 for %%i in (A B C) do echo %%I
651 for %%i in (A B C) do echo %%j
652 for %%i in (A B C) do call :forTestFun1 %%i
653 for %%i in (1,4,1) do echo %%i
654 for %%i in (A, B,C) do echo %%i
655 for %%i in  (X) do echo %%i
656 for@tab@%%i in  (X2) do echo %%i
657 for %%i in@tab@(X3) do echo %%i
658 for %%i in (@tab@ foo@tab@) do echo %%i
659 for@tab@ %%i in@tab@(@tab@M) do echo %%i
660 for %%i@tab@in (X)@tab@do@tab@echo %%i
661 for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
662 for %%i in (`echo A B`) do echo %%i
663 for %%i in ('echo A B') do echo %%i
664 for %%i in ("echo A B") do echo %%i
665 for %%i in ("A B" C) do echo %%i
666 goto :endForTestFun1
667 :forTestFun1
668 echo %1
669 goto :eof
670 :endForTestFun1
671 echo --- imbricated FORs
672 for %%i in (X) do (
673     for %%j in (Y) do (
674         echo %%i %%j))
675 for %%i in (X) do (
676     for %%I in (Y) do (
677         echo %%i %%I))
678 for %%i in (A B) do (
679     for %%j in (C D) do (
680         echo %%i %%j))
681 for %%i in (A B) do (
682     for %%j in (C D) do (
683         call :forTestFun2 %%i %%j ))
684 goto :endForTestFun2
685 :forTestFun2
686 echo %1 %2
687 goto :eof
688 :endForTestFun2
689 mkdir foobar & cd foobar
690 mkdir foo
691 mkdir bar
692 mkdir baz
693 echo > bazbaz
694 echo --- basic wildcards
695 for %%i in (ba*) do echo %%i
696 echo --- for /d
697 for /d %%i in (baz foo bar) do echo %%i 2>&1
698 rem Confirm we don't match files:
699 for /d %%i in (bazb*) do echo %%i 2>&1
700 for /d %%i in (bazb2*) do echo %%i 2>&1
701 rem Show we pass through non wildcards
702 for /d %%i in (PASSED) do echo %%i
703 for /d %%i in (xxx) do (
704   echo %%i - Should be xxx
705   echo Expected second line
706 )
707 rem Show we issue no messages on failures
708 for /d %%i in (FAILED?) do echo %%i 2>&1
709 for /d %%i in (FAILED?) do (
710   echo %%i - Unexpected!
711   echo FAILED Unexpected second line
712 )
713 for /d %%i in (FAILED*) do echo %%i 2>&1
714 for /d %%i in (FAILED*) do (
715   echo %%i - Unexpected!
716   echo FAILED Unexpected second line
717 )
718 rem FIXME can't test wildcard expansion here since it's listed in directory
719 rem order, and not in alphabetic order.
720 rem Proper testing would need a currently missing "sort" program implementation.
721 rem for /d %%i in (ba*) do echo %%i>> tmp
722 rem sort < tmp
723 rem del tmp
724 rem for /d %%i in (?a*) do echo %%i>> tmp
725 rem sort < tmp
726 rem del tmp
727 rem for /d %%i in (*) do echo %%i>> tmp
728 rem sort < tmp
729 rem del tmp
730 echo > baz\bazbaz
731 goto :TestForR
732
733 :SetExpected
734 del temp.bat 2>nul
735 call :WriteLine set found=N
736 for /l %%i in (1,1,%expectedresults%) do (
737   call :WriteLine if "%%%%expectedresults.%%i%%%%"=="%%%%1" set found=Y
738   call :WriteLine if "%%%%found%%%%"=="Y" set expectedresults.%%i=
739   call :WriteLine if "%%%%found%%%%"=="Y" goto :eof
740 )
741 call :WriteLine echo Got unexpected result: "%%%%1"
742 goto :eof
743
744 :WriteLine
745 echo %*>> temp.bat
746 goto :EOF
747
748 :ValidateExpected
749 del temp.bat 2>nul
750 for /l %%i in (1,1,%expectedresults%) do  call :WriteLine if not "%%%%expectedresults.%%i%%%%"=="" echo Found missing result: "%%%%expectedresults.%%i%%%%"
751 call temp.bat
752 del temp.bat 2>nul
753 goto :eof
754
755 :TestForR
756 rem %CD% does not tork on NT4 so use the following workaround
757 for /d %%i in (.) do set CURDIR=%%~dpnxi
758
759 echo --- for /R
760 echo Plain directory enumeration
761 set expectedresults=4
762 set expectedresults.1=%CURDIR%\.
763 set expectedresults.2=%CURDIR%\bar\.
764 set expectedresults.3=%CURDIR%\baz\.
765 set expectedresults.4=%CURDIR%\foo\.
766 call :SetExpected
767 for /R %%i in (.) do call temp.bat %%i
768 call :ValidateExpected
769
770 echo Plain directory enumeration from provided root
771 set expectedresults=4
772 set expectedresults.1=%CURDIR%\.
773 set expectedresults.2=%CURDIR%\bar\.
774 set expectedresults.3=%CURDIR%\baz\.
775 set expectedresults.4=%CURDIR%\foo\.
776 if "%CD%"=="" goto :SkipBrokenNT4
777 call :SetExpected
778 for /R "%CURDIR%" %%i in (.) do call temp.bat %%i
779 call :ValidateExpected
780 :SkipBrokenNT4
781
782 echo File enumeration
783 set expectedresults=2
784 set expectedresults.1=%CURDIR%\baz\bazbaz
785 set expectedresults.2=%CURDIR%\bazbaz
786 call :SetExpected
787 for /R %%i in (baz*) do call temp.bat %%i
788 call :ValidateExpected
789
790 echo File enumeration from provided root
791 set expectedresults=2
792 set expectedresults.1=%CURDIR%\baz\bazbaz
793 set expectedresults.2=%CURDIR%\bazbaz
794 call :SetExpected
795 for /R %%i in (baz*) do call temp.bat %%i
796 call :ValidateExpected
797
798 echo Mixed enumeration
799 set expectedresults=6
800 set expectedresults.1=%CURDIR%\.
801 set expectedresults.2=%CURDIR%\bar\.
802 set expectedresults.3=%CURDIR%\baz\.
803 set expectedresults.4=%CURDIR%\baz\bazbaz
804 set expectedresults.5=%CURDIR%\bazbaz
805 set expectedresults.6=%CURDIR%\foo\.
806 call :SetExpected
807 for /R %%i in (. baz*) do call temp.bat %%i
808 call :ValidateExpected
809
810 echo Mixed enumeration from provided root
811 set expectedresults=6
812 set expectedresults.1=%CURDIR%\.
813 set expectedresults.2=%CURDIR%\bar\.
814 set expectedresults.3=%CURDIR%\baz\.
815 set expectedresults.4=%CURDIR%\baz\bazbaz
816 set expectedresults.5=%CURDIR%\bazbaz
817 set expectedresults.6=%CURDIR%\foo\.
818 call :SetExpected
819 for /R %%i in (. baz*) do call temp.bat %%i
820 call :ValidateExpected
821
822 echo With duplicates enumeration
823 set expectedresults=12
824 set expectedresults.1=%CURDIR%\bar\bazbaz
825 set expectedresults.2=%CURDIR%\bar\fred
826 set expectedresults.3=%CURDIR%\baz\bazbaz
827 set expectedresults.4=%CURDIR%\baz\bazbaz
828 set expectedresults.5=%CURDIR%\baz\bazbaz
829 set expectedresults.6=%CURDIR%\baz\fred
830 set expectedresults.7=%CURDIR%\bazbaz
831 set expectedresults.8=%CURDIR%\bazbaz
832 set expectedresults.9=%CURDIR%\bazbaz
833 set expectedresults.10=%CURDIR%\foo\bazbaz
834 set expectedresults.11=%CURDIR%\foo\fred
835 set expectedresults.12=%CURDIR%\fred
836 call :SetExpected
837 for /R %%i in (baz* bazbaz fred ba*) do call temp.bat %%i
838 call :ValidateExpected
839
840 echo Strip missing wildcards, keep unwildcarded names
841 set expectedresults=6
842 set expectedresults.1=%CURDIR%\bar\jim
843 set expectedresults.2=%CURDIR%\baz\bazbaz
844 set expectedresults.3=%CURDIR%\baz\jim
845 set expectedresults.4=%CURDIR%\bazbaz
846 set expectedresults.5=%CURDIR%\foo\jim
847 set expectedresults.6=%CURDIR%\jim
848 call :SetExpected
849 for /R %%i in (baz* fred* jim) do call temp.bat %%i
850 call :ValidateExpected
851
852 echo for /R passed
853 cd .. & rd /s/Q foobar
854 echo --- for /L
855 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
856 for /L %%i in (1,2,0) do echo %%i
857 for@tab@/L %%i in (1,2,0) do echo %%i
858 for /L %%i in (1,2,6) do echo %%i
859 for /l %%i in (1 ,2,6) do echo %%i
860 for /L %%i in (a,2,3) do echo %%i
861 for /L %%i in (1,2,-1) do echo %%i
862 for /L %%i in (-4,-1,-1) do echo %%i
863 for /L %%i in (1,-2,-2) do echo %%i
864 for /L %%i in (1,2,a) do echo %%i
865 echo ErrorLevel %ErrorLevel%
866 for /L %%i in (1,a,b) do echo %%i
867 echo ErrorLevel %ErrorLevel%
868 rem Test boundaries
869 for /l %%i in (1,1,4) do echo %%i
870 for /l %%i in (1,2,4) do echo %%i
871 for /l %%i in (4,-1,1) do echo %%i
872 for /l %%i in (4,-2,1) do echo %%i
873 for /l %%i in (1,-1,4) do echo %%i
874 for /l %%i in (4,1,1) do echo %%i
875 for /L %%i in (a,2,b) do echo %%i
876 for /L %%i in (1,1,1) do echo %%i
877 for /L %%i in (1,-2,-1) do echo %%i
878 for /L %%i in (-1,-1,-1) do echo %%i
879 for /L %%i in (1,2, 3) do echo %%i
880 rem Test zero iteration skips the body of the for
881 for /L %%i in (2,2,1) do (
882   echo %%i
883   echo FAILED
884 )
885 echo --- for /a
886 rem No output when using "set expr" syntax, unless in interactive mode
887 rem Need to use "set envvar=expr" to use in a batch script
888 echo ------ individual operations
889 set var=0
890 set /a var=1 +2 & echo %var%
891 set /a var=1 +-2 & echo %var%
892 set /a var=1 --2 & echo %var%
893 set /a var=2* 3 & echo %var%
894 set /a var=-2* -5 & echo %var%
895 set /a var=12/3 & echo %var%
896 set /a var=13/3 & echo %var%
897 set /a var=-13/3 & echo %var%
898 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
899 set /a var=5 %% 5 & echo %var%
900 set /a var=5 %% 3 & echo %var%
901 set /a var=5 %% -3 & echo %var%
902 set /a var=-5 %% -3 & echo %var%
903 set /a var=1 ^<^< 0 & 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=-1 ^<^< 2 & echo %var%
908 set /a var=9 ^>^> 0 & 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=-9 ^>^> 2 & echo %var%
913 set /a var=5 ^& 0 & echo %var%
914 set /a var=5 ^& 1 & echo %var%
915 set /a var=5 ^& 3 & echo %var%
916 set /a var=5 ^& 4 & echo %var%
917 set /a var=5 ^& 1 & echo %var%
918 set /a var=5 ^| 0 & echo %var%
919 set /a var=5 ^| 1 & echo %var%
920 set /a var=5 ^| 3 & echo %var%
921 set /a var=5 ^| 4 & echo %var%
922 set /a var=5 ^| 1 & echo %var%
923 set /a var=5 ^^ 0 & echo %var%
924 set /a var=5 ^^ 1 & echo %var%
925 set /a var=5 ^^ 3 & echo %var%
926 set /a var=5 ^^ 4 & echo %var%
927 set /a var=5 ^^ 1 & echo %var%
928 echo ------ precedence and grouping
929 set /a var=4 + 2*3 & echo %var%
930 set /a var=(4+2)*3 & echo %var%
931 set /a var=4 * 3/5 & echo %var%
932 set /a var=(4 * 3)/5 & echo %var%
933 set /a var=4 * 5 %% 4 & echo %var%
934 set /a var=4 * (5 %% 4) & echo %var%
935 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
936 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
937 echo ------ octal and hexadecimal
938 set /a var=0xf + 3 & echo %var%
939 set /a var=0xF + 3 & echo %var%
940 set /a var=015 + 2 & echo %var%
941 set /a var=3, 8+3,0 & echo %var%
942 echo ------ variables
943 set /a var=foo=3, foo+1 & echo %var%
944 if defined foo (echo %foo%) else (
945     echo foo not defined
946 )
947 set /a var=foo=3, foo+=1 & echo %var%
948 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
949 set /a var=foo*= foo & echo %var%
950 set /a var=whateverNonExistingVar & echo %var%
951 set /a var=whateverNonExistingVar + bar & echo %var%
952 set /a var=foo -= foo + 7 & echo %var%
953 set /a var=foo /= 3 + 2 & echo %var%
954 set /a var=foo=5, 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 ^&= 2 & echo %var%
958 set /a var=foo=5, foo ^|= 2 & echo %var%
959 set /a var=foo=5, foo ^^= 2 & echo %var%
960 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
961 set foo=
962 set bar=
963 set var=
964 echo --- for /F
965 mkdir foobar & cd foobar
966 echo ------ string argument
967 for /F %%i in ("a b c") 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 for /f %%i in (" a ") do echo %%i
972 echo ------ fileset argument
973 echo --------- basic blank handling
974 echo a b c>foo
975 for /f %%i in (foo) do echo %%i
976 echo a >foo
977 for /f %%i in (foo) do echo %%i
978 echo a>foo
979 for /f %%i in (foo) do echo %%i
980 echo  a>foo
981 for /f %%i in (foo) do echo %%i
982 echo  a >foo
983 for /f %%i in (foo) do echo %%i
984 echo. > foo
985 for /f %%i in (foo) do echo %%i
986 echo. >> foo
987 echo b > foo
988 for /f %%i in (foo) do echo %%i
989 echo --------- multi-line with empty lines
990 echo a Z f> foo
991 echo. >> foo
992 echo.>> foo
993 echo b bC>> foo
994 echo c>> foo
995 echo. >> foo
996 for /f %%b in (foo) do echo %%b
997 echo --------- multiple files
998 echo q w > bar
999 echo.>> bar
1000 echo kkk>>bar
1001 for /f %%k in (foo bar) do echo %%k
1002 for /f %%k in (bar foo) do echo %%k
1003 rem echo ------ command argument
1004 rem Not implemented on NT4
1005 rem FIXME: Not testable right now in wine: not implemented and would need
1006 rem preliminary grep-like program implementation (e.g. like findstr or fc) even
1007 rem for a simple todo_wine test
1008 rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported
1009 rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported
1010 echo ------ eol option
1011 for /f "eol=@" %%i in ("    ad") do echo %%i
1012 for /f "eol=@" %%i in (" z@y") do echo %%i
1013 for /f "eol=|" %%i in ("a|d") do echo %%i
1014 for /f "eol=@" %%i in ("@y") do echo %%i > output_file
1015 if not exist output_file (echo no output) else (del output_file)
1016 for /f "eol==" %%i in ("=y") do echo %%i > output_file
1017 if not exist output_file (echo no output) else (del output_file)
1018 echo ------ delims option
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 ("a d|") do echo %%i
1023 for /f "delims==" %%i in ("C r=d|") do echo %%i
1024 for /f "delims=" %%i in ("foo bar baz") do echo %%i
1025 for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi
1026 echo ------ skip option
1027 echo a > foo
1028 echo b >> foo
1029 echo c >> foo
1030 for /f "skip=2" %%i in (foo) do echo %%i
1031 for /f "skip=3" %%i in (foo) do echo %%i > output_file
1032 if not exist output_file (echo no output) else (del output_file)
1033 for /f "skip=4" %%i in (foo) do echo %%i > output_file
1034 if not exist output_file (echo no output) else (del output_file)
1035 cd ..
1036 rd /s/q foobar
1037
1038 echo ------------ Testing del /a ------------
1039 del /f/q *.test > nul
1040 echo r > r.test
1041 attrib +r r.test
1042 echo not-r > not-r.test
1043
1044 if not exist not-r.test echo not-r.test not found before delete, bad
1045 del /a:-r *.test
1046 if not exist not-r.test echo not-r.test not found after delete, good
1047
1048 if not exist r.test echo r.test not found before delete, bad
1049 if exist r.test echo r.test found before delete, good
1050 del /a:r *.test
1051 if not exist r.test echo r.test not found after delete, good
1052 if exist r.test echo r.test found after delete, bad
1053
1054 echo ------------ Testing del /q ------------
1055 mkdir del_q_dir
1056 cd del_q_dir
1057 echo abc > file1
1058 echo abc > file2.dat
1059 rem If /q doesn't work, cmd will prompt and the test case should hang
1060 del /q * > nul
1061 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
1062 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
1063 cd ..
1064 rmdir del_q_dir
1065
1066 echo ------------ Testing del /s ------------
1067 mkdir "foo bar"
1068 cd "foo bar"
1069 mkdir "foo:"
1070 echo hi > file1.dat
1071 echo there > file2.dat
1072 echo bub > file3.dat
1073 echo bye > "file with spaces.dat"
1074 cd ..
1075 del /s file1.dat > nul
1076 del file2.dat /s > nul
1077 del "file3.dat" /s > nul
1078 del "file with spaces.dat" /s > nul
1079 cd "foo bar"
1080 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
1081 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
1082 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
1083 if exist "file with spaces.dat" del "file with spaces.dat"
1084 rmdir "foo:"
1085 cd ..
1086 rmdir "foo bar"
1087
1088 echo ------------ Testing rename ------------
1089 mkdir foobar & cd foobar
1090 echo --- ren and rename are synonymous
1091 echo > foo
1092 rename foo bar
1093 if exist foo echo foo should be renamed!
1094 if exist bar echo foo renamed to bar
1095 ren bar foo
1096 if exist bar echo bar should be renamed!
1097 if exist foo echo bar renamed to foo
1098 echo --- name collision
1099 echo foo>foo
1100 echo bar>bar
1101 ren foo bar 2> nul
1102 type foo
1103 type bar
1104 rem no-op
1105 ren foo foo
1106 mkdir baz
1107 ren foo baz\abc
1108 echo --- rename read-only files
1109 echo > file1
1110 attrib +r file1
1111 ren file1 file2
1112 if not exist file1 (
1113     if exist file2 (
1114         echo read-only file renamed
1115     )
1116 ) else (
1117     echo read-only file not renamed!
1118 )
1119 echo --- rename directories
1120 mkdir rep1
1121 ren rep1 rep2
1122 if not exist rep1 (
1123     if exist rep2 (
1124         echo dir renamed
1125     )
1126 )
1127 attrib +r rep2
1128 ren rep2 rep1
1129 if not exist rep2 (
1130     if exist rep1 (
1131         echo read-only dir renamed
1132     )
1133 )
1134 echo --- rename in other directory
1135 if not exist baz\abc (
1136     echo rename impossible in other directory
1137     if exist foo echo original file still present
1138 ) else (
1139     echo shouldn't rename in other directory!
1140     if not exist foo echo original file not present anymore
1141 )
1142 cd .. & rd /s/q foobar
1143
1144 echo ------------ Testing move ------------
1145 mkdir foobar & cd foobar
1146 echo --- file move
1147 echo >foo
1148 move foo bar > nul 2>&1
1149 if not exist foo (
1150     if exist bar (
1151         echo file move succeeded
1152     )
1153 )
1154 echo bar>bar
1155 echo baz> baz
1156 move /Y bar baz > nul 2>&1
1157 if not exist bar (
1158     if exist baz (
1159         echo file move with overwrite succeeded
1160     )
1161 ) else (
1162     echo file overwrite impossible!
1163     del bar
1164 )
1165 type baz
1166
1167 attrib +r baz
1168 move baz bazro > nul 2>&1
1169 if not exist baz (
1170     if exist bazro (
1171         echo read-only files are moveable
1172         move bazro baz > nul 2>&1
1173     )
1174 ) else (
1175     echo read-only file not moved!
1176 )
1177 attrib -r baz
1178 mkdir rep
1179 move baz rep > nul 2>&1
1180 if not exist baz (
1181     if exist rep\baz (
1182         echo file moved in subdirectory
1183     )
1184 )
1185 call :setError 0
1186 move rep\baz . > nul 2>&1
1187 move /Y baz baz > nul 2>&1
1188 if errorlevel 1 (
1189     echo moving a file to itself should be a no-op!
1190 ) else (
1191     echo moving a file to itself is a no-op
1192 )
1193 echo ErrorLevel: %ErrorLevel%
1194 call :setError 0
1195 del baz
1196 echo --- directory move
1197 mkdir foo\bar
1198 mkdir baz
1199 echo baz2>baz\baz2
1200 move baz foo\bar > nul 2>&1
1201 if not exist baz (
1202     if exist foo\bar\baz\baz2 (
1203         echo simple directory move succeeded
1204     )
1205 )
1206 call :setError 0
1207 mkdir baz
1208 move baz baz > nul 2>&1
1209 echo moving a directory to itself gives error; errlevel %ErrorLevel%
1210 echo ------ dir in dir move
1211 rd /s/q foo
1212 mkdir foo bar
1213 echo foo2>foo\foo2
1214 echo bar2>bar\bar2
1215 move foo bar > nul 2>&1
1216 if not exist foo (
1217     if exist bar (
1218         dir /b /ad bar
1219         dir /b /a-d bar
1220         dir /b bar\foo
1221     )
1222 )
1223 cd .. & rd /s/q foobar
1224
1225 echo ------------ Testing mkdir ------------
1226 call :setError 0
1227 echo --- md and mkdir are synonymous
1228 mkdir foobar
1229 echo %ErrorLevel%
1230 rmdir foobar
1231 md foobar
1232 echo %ErrorLevel%
1233 rmdir foobar
1234 echo --- creating an already existing directory/file must fail
1235 mkdir foobar
1236 md foobar
1237 echo %ErrorLevel%
1238 rmdir foobar
1239 echo > foobar
1240 mkdir foobar
1241 echo %ErrorLevel%
1242 del foobar
1243 echo --- multilevel path creation
1244 mkdir foo
1245 echo %ErrorLevel%
1246 mkdir foo\bar\baz
1247 echo %ErrorLevel%
1248 cd foo
1249 echo %ErrorLevel%
1250 cd bar
1251 echo %ErrorLevel%
1252 cd baz
1253 echo %ErrorLevel%
1254 echo > ..\..\bar2
1255 mkdir ..\..\..\foo\bar2
1256 echo %ErrorLevel%
1257 del ..\..\bar2
1258 mkdir ..\..\..\foo\bar2
1259 echo %ErrorLevel%
1260 rmdir ..\..\..\foo\bar2
1261 cd ..
1262 rmdir baz
1263 cd ..
1264 rmdir bar
1265 cd ..
1266 rmdir foo
1267 echo %ErrorLevel%
1268 echo --- trailing backslashes
1269 mkdir foo\\\\
1270 echo %ErrorLevel%
1271 if exist foo (rmdir foo & echo dir created
1272 ) else ( echo dir not created )
1273 echo %ErrorLevel%
1274 echo --- invalid chars
1275 mkdir ?
1276 echo mkdir ? gives errorlevel %ErrorLevel%
1277 call :setError 0
1278 mkdir ?\foo
1279 echo mkdir ?\foo gives errorlevel %ErrorLevel%
1280 call :setError 0
1281 mkdir foo\?
1282 echo mkdir foo\? gives errorlevel %ErrorLevel%
1283 if exist foo (rmdir foo & echo ok, foo created
1284 ) else ( echo foo not created )
1285 call :setError 0
1286 mkdir foo\bar\?
1287 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
1288 call :setError 0
1289 if not exist foo (
1290     echo bad, foo not created
1291 ) else (
1292     cd foo
1293     if exist bar (
1294         echo ok, foo\bar created
1295         rmdir bar
1296     )
1297     cd ..
1298     rmdir foo
1299 )
1300 echo --- multiple directories at once
1301 mkdir foobaz & cd foobaz
1302 mkdir foo bar\baz foobar "bazbaz" .\"zabzab"
1303 if exist foo (echo foo created) else echo foo not created!
1304 if exist bar (echo bar created) else echo bar not created!
1305 if exist foobar (echo foobar created) else echo foobar not created!
1306 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
1307 if exist bazbaz (echo bazbaz created) else echo bazbaz not created!
1308 if exist zabzab (echo zabzab created) else echo zabzab not created!
1309 cd .. & rd /s/q foobaz
1310 call :setError 0
1311 mkdir foo\*
1312 echo mkdir foo\* errorlevel %ErrorLevel%
1313 if exist foo (rmdir foo & echo ok, foo created
1314 ) else ( echo bad, foo not created )
1315
1316 echo ------------ Testing rmdir ------------
1317 call :setError 0
1318 rem rd and rmdir are synonymous
1319 mkdir foobar
1320 rmdir foobar
1321 echo %ErrorLevel%
1322 if not exist foobar echo dir removed
1323 mkdir foobar
1324 rd foobar
1325 echo %ErrorLevel%
1326 if not exist foobar echo dir removed
1327 rem Removing nonexistent directory
1328 rmdir foobar
1329 echo %ErrorLevel%
1330 rem Removing single-level directories
1331 echo > foo
1332 rmdir foo
1333 echo %ErrorLevel%
1334 if exist foo echo file not removed
1335 del foo
1336 mkdir foo
1337 echo > foo\bar
1338 rmdir foo
1339 echo %ErrorLevel%
1340 if exist foo echo non-empty dir not removed
1341 del foo\bar
1342 mkdir foo\bar
1343 rmdir foo
1344 echo %ErrorLevel%
1345 if exist foo echo non-empty dir not removed
1346 rmdir foo\bar
1347 rmdir foo
1348 rem Recursive rmdir
1349 mkdir foo\bar\baz
1350 rmdir /s /Q foo
1351 if not exist foo (
1352     echo recursive rmdir succeeded
1353 ) else (
1354     rd foo\bar\baz
1355     rd foo\bar
1356     rd foo
1357 )
1358 mkdir foo\bar\baz
1359 echo foo > foo\bar\brol
1360 rmdir /s /Q foo 2>&1
1361 if not exist foo (
1362     echo recursive rmdir succeeded
1363 ) else (
1364     rd foo\bar\baz
1365     del foo\bar\brol
1366     rd foo\bar
1367     rd foo
1368 )
1369 rem multiples directories at once
1370 mkdir foobaz & cd foobaz
1371 mkdir foo
1372 mkdir bar\baz
1373 mkdir foobar
1374 rd /s/q foo bar foobar
1375 if not exist foo (echo foo removed) else echo foo not removed!
1376 if not exist bar (echo bar removed) else echo bar not removed!
1377 if not exist foobar (echo foobar removed) else echo foobar not removed!
1378 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
1379 cd .. & rd /s/q foobaz
1380
1381 echo ------------ Testing pushd/popd ------------
1382 cd
1383 echo --- popd is no-op when dir stack is empty
1384 popd
1385 cd
1386 echo --- pushing non-existing dir
1387 pushd foobar
1388 cd
1389 echo --- basic behaviour
1390 mkdir foobar\baz
1391 pushd foobar
1392 cd
1393 popd
1394 cd
1395 pushd foobar
1396 pushd baz
1397 cd
1398 popd
1399 cd
1400 pushd baz
1401 popd
1402 cd
1403 popd
1404 cd
1405 pushd .
1406 cd foobar\baz
1407 pushd ..
1408 cd
1409 popd
1410 popd
1411 cd
1412 rd /s/q foobar
1413
1414 echo ------------ Testing attrib ------------
1415 rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications
1416 mkdir foobar & cd foobar
1417 echo foo original contents> foo
1418 attrib foo
1419 echo > bar
1420 echo --- read-only attribute
1421 rem Read-only files cannot be altered or deleted, unless forced
1422 attrib +R foo
1423 attrib foo
1424 dir /Ar /B
1425 echo bar>> foo
1426 type foo
1427 del foo > NUL 2>&1
1428 if exist foo (
1429     echo Read-only file not deleted
1430 ) else (
1431     echo Should not delete read-only file!
1432 )
1433 del /F foo
1434 if not exist foo (
1435     echo Read-only file forcibly deleted
1436 ) else (
1437     echo Should delete read-only file with del /F!
1438     attrib -r foo
1439     del foo
1440 )
1441 cd .. & rd /s/q foobar
1442 echo --- recursive behaviour
1443 mkdir foobar\baz & cd foobar
1444 echo > level1
1445 echo > whatever
1446 echo > baz\level2
1447 attrib baz\level2
1448 cd ..
1449 attrib +R l*vel? /S > nul 2>&1
1450 cd foobar
1451 attrib level1
1452 attrib baz\level2
1453 echo > bar
1454 attrib bar
1455 cd .. & rd /s/q foobar
1456 echo --- folders processing
1457 mkdir foobar
1458 attrib foobar
1459 cd foobar
1460 mkdir baz
1461 echo toto> baz\toto
1462 attrib +r baz /s /d > nul 2>&1
1463 attrib baz
1464 attrib baz\toto
1465 echo lulu>>baz\toto
1466 type baz\toto
1467 echo > baz\lala
1468 rem Oddly windows allows file creation in a read-only directory...
1469 if exist baz\lala (echo file created in read-only dir) else echo file not created
1470 cd .. & rd /s/q foobar
1471
1472 echo ------------ Testing assoc ------------
1473 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
1474 rem FIXME Revise once || conditional execution is fixed
1475 mkdir foobar & cd foobar
1476 echo --- setting association
1477 assoc .foo > baz
1478 type baz
1479 echo ---
1480
1481 assoc .foo=bar
1482 assoc .foo
1483
1484 rem association set system-wide
1485 echo @echo off> tmp.cmd
1486 echo echo +++>> tmp.cmd
1487 echo assoc .foo>> tmp.cmd
1488 cmd /c tmp.cmd
1489
1490 echo --- resetting association
1491 assoc .foo=
1492 assoc .foo > baz
1493 type baz
1494 echo ---
1495
1496 rem association removal set system-wide
1497 cmd /c tmp.cmd > baz
1498 type baz
1499 echo ---
1500 cd .. & rd /s/q foobar
1501
1502 echo ------------ Testing ftype ------------
1503 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
1504 rem FIXME Revise once || conditional execution is fixed
1505 mkdir foobar & cd foobar
1506 echo --- setting association
1507 ftype footype> baz
1508 type baz
1509 echo ---
1510
1511 ftype footype=foo_opencmd
1512 assoc .foo=footype
1513 ftype footype
1514
1515 rem association set system-wide
1516 echo @echo off> tmp.cmd
1517 echo echo +++>> tmp.cmd
1518 echo ftype footype>> tmp.cmd
1519 cmd /c tmp.cmd
1520
1521 echo --- resetting association
1522 assoc .foo=
1523
1524 rem Removing a file type association doesn't work on XP due to a bug, so a workaround is needed
1525 setlocal EnableDelayedExpansion
1526 set FOO=original value
1527 ftype footype=
1528 ftype footype > baz
1529 for /F %%i in ('type baz') do (set FOO=buggyXP)
1530 rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion)
1531 rem FIXME Revisit once a grep-like program like ftype is implemented
1532 rem (e.g. to check baz's size using dir /b instead)
1533 echo !FOO!
1534
1535 rem cleanup registry
1536 echo REGEDIT4> regCleanup.reg
1537 echo.>> regCleanup.reg
1538 echo [-HKEY_CLASSES_ROOT\footype]>> regCleanup.reg
1539 regedit /s regCleanup.reg
1540 set FOO=
1541 endlocal
1542 cd .. & rd /s/q foobar
1543
1544 echo ------------ Testing CALL ------------
1545 mkdir foobar & cd foobar
1546 echo --- external script
1547 echo echo foo %%1> foo.cmd
1548 call foo
1549 call foo.cmd 8
1550 echo echo %%1 %%2 > foo.cmd
1551 call foo.cmd foo
1552 call foo.cmd foo bar
1553 call foo.cmd foo ""
1554 call foo.cmd "" bar
1555 call foo.cmd foo ''
1556 call foo.cmd '' bar
1557 del foo.cmd
1558
1559 echo --- internal routines
1560 call :testRoutine :testRoutine
1561 goto :endTestRoutine
1562 :testRoutine
1563 echo bar %1
1564 goto :eof
1565 :endTestRoutine
1566
1567 call :testRoutineArgs foo
1568 call :testRoutineArgs foo bar
1569 call :testRoutineArgs foo ""
1570 call :testRoutineArgs ""  bar
1571 call :testRoutineArgs foo ''
1572 call :testRoutineArgs ''  bar
1573 goto :endTestRoutineArgs
1574 :testRoutineArgs
1575 echo %1 %2
1576 goto :eof
1577 :endTestRoutineArgs
1578
1579 echo --- with builtins
1580 call mkdir foo
1581 echo %ErrorLevel%
1582 if exist foo (echo foo created) else echo foo should exist!
1583 rmdir foo
1584 set FOOBAZ_VAR=foobaz
1585 call echo Should expand %FOOBAZ_VAR%
1586 set FOOBAZ_VAR=
1587 echo>batfile
1588 call dir /b
1589 echo>robinfile
1590 if 1==1 call del batfile
1591 dir /b
1592 if exist batfile echo batfile shouldn't exist
1593 rem ... but not for 'if' or 'for'
1594 call if 1==1 echo bar 2> nul
1595 echo %ErrorLevel%
1596 call :setError 0
1597 call for %%i in (foo bar baz) do echo %%i 2> nul
1598 echo %ErrorLevel%
1599 rem First look for programs in the path before trying a builtin
1600 echo echo non-builtin dir> dir.cmd
1601 call dir /b
1602 cd .. & rd /s/q foobar
1603
1604 echo ------------ Testing SHIFT ------------
1605
1606 call :shiftFun p1 p2 p3 p4 p5
1607 goto :endShiftFun
1608
1609 :shiftFun
1610 echo '%1' '%2' '%3' '%4' '%5'
1611 shift
1612 echo '%1' '%2' '%3' '%4' '%5'
1613 shift@tab@ /1
1614 echo '%1' '%2' '%3' '%4' '%5'
1615 shift /2
1616 echo '%1' '%2' '%3' '%4' '%5'
1617 shift /-1
1618 echo '%1' '%2' '%3' '%4' '%5'
1619 shift /0
1620 echo '%1' '%2' '%3' '%4' '%5'
1621 goto :eof
1622 :endShiftFun
1623
1624 echo ------------ Testing cmd invocation ------------
1625 rem FIXME: only a stub ATM
1626 echo --- a batch file can delete itself
1627 echo del foo.cmd>foo.cmd
1628 cmd /q /c foo.cmd
1629 if not exist foo.cmd (
1630     echo file correctly deleted
1631 ) else (
1632     echo file should be deleted!
1633     del foo.cmd
1634 )
1635 echo --- a batch file can alter itself
1636 echo echo bar^>foo.cmd>foo.cmd
1637 cmd /q /c foo.cmd > NUL 2>&1
1638 if exist foo.cmd (
1639     type foo.cmd
1640     del foo.cmd
1641 ) else (
1642     echo file not created!
1643 )
1644
1645 echo ---------- Testing copy
1646 md foobar2
1647 cd foobar2
1648 rem Note echo adds 0x0d 0x0a on the end of the line in the file
1649 echo AAA> file1
1650 echo BBBBBB> file2
1651 echo CCCCCCCCC> file3
1652 md dir1
1653 goto :testcopy
1654
1655 :CheckExist
1656 if exist "%1" (
1657   echo Passed: Found expected %1
1658 ) else (
1659   echo Failed: Did not find expected %1
1660 )
1661 del /q "%1" >nul 2>&1
1662 shift
1663 if not "%1"=="" goto :CheckExist
1664 goto :eof
1665
1666 :CheckNotExist
1667 if not exist "%1" (
1668   echo Passed: Did not find %1
1669 ) else (
1670   echo Failed: Unexpectedly found %1
1671   del /q "%1" >nul 2>&1
1672 )
1673 shift
1674 if not "%1"=="" goto :CheckNotExist
1675 goto :eof
1676
1677 rem Note: No way to check file size on NT4 so skip the test
1678 :CheckFileSize
1679 if not exist "%1" (
1680   echo Failed: File missing when requested filesize check [%2]
1681   goto :ContinueFileSizeChecks
1682 )
1683 for %%i in (%1) do set filesize=%%~zi
1684 if "%filesize%"=="%2" (
1685     echo Passed: file size check on %1 [%filesize%]
1686 ) else (
1687   if "%filesize%"=="%%~zi" (
1688     echo Skipping file size check on NT4
1689   ) else (
1690     echo Failed: file size check on %1 [%filesize% != %2]
1691   )
1692 )
1693 :ContinueFileSizeChecks
1694 shift
1695 shift
1696 if not "%1"=="" goto :CheckFileSize
1697 goto :eof
1698
1699 :testcopy
1700
1701 rem -----------------------
1702 rem Simple single file copy
1703 rem -----------------------
1704 rem Simple single file copy, normally used syntax
1705 copy file1 dummy.file >nul 2>&1
1706 if errorlevel 1 echo Incorrect errorlevel
1707 call :CheckExist dummy.file
1708
1709 rem Simple single file copy, destination supplied as two forms of directory
1710 copy file1 dir1 >nul 2>&1
1711 if errorlevel 1 echo Incorrect errorlevel
1712 call :CheckExist dir1\file1
1713
1714 copy file1 dir1\ >nul 2>&1
1715 if errorlevel 1 echo Incorrect errorlevel
1716 call :CheckExist dir1\file1
1717
1718 rem Simple single file copy, destination supplied as fully qualified destination
1719 copy file1 dir1\file99 >nul 2>&1
1720 if errorlevel 1 echo Incorrect errorlevel
1721 call :CheckExist dir1\file99
1722
1723 rem Simple single file copy, destination not supplied
1724 cd dir1
1725 copy ..\file1 >nul 2>&1
1726 if errorlevel 1 echo Incorrect errorlevel
1727 call :CheckExist file1
1728 cd ..
1729
1730 rem Simple single file copy, destination supplied as non existant directory
1731 copy file1 dir2\ >nul 2>&1
1732 if not errorlevel 1 echo Incorrect errorlevel
1733 call :CheckNotExist dir2 dir2\file1
1734
1735 rem -----------------------
1736 rem Wildcarded copy
1737 rem -----------------------
1738 rem Simple single file copy, destination supplied as two forms of directory
1739 copy file? dir1 >nul 2>&1
1740 if errorlevel 1 echo Incorrect errorlevel
1741 call :CheckExist dir1\file1 dir1\file2 dir1\file3
1742
1743 copy file* dir1\ >nul 2>&1
1744 if errorlevel 1 echo Incorrect errorlevel
1745 call :CheckExist dir1\file1 dir1\file2 dir1\file3
1746
1747 rem Simple single file copy, destination not supplied
1748 cd dir1
1749 copy ..\file*.* >nul 2>&1
1750 if errorlevel 1 echo Incorrect errorlevel
1751 call :CheckExist file1 file2 file3
1752 cd ..
1753
1754 rem Simple wildcarded file copy, destination supplied as non existant directory
1755 copy file? dir2\ >nul 2>&1
1756 if not errorlevel 1 echo Incorrect errorlevel
1757 call :CheckNotExist dir2 dir2\file1 dir2\file2 dir2\file3
1758
1759 rem ------------------------------------------------
1760 rem Confirm overwrite works (cannot test prompting!)
1761 rem ------------------------------------------------
1762 copy file1 testfile >nul 2>&1
1763 copy /y file2 testfile >nul 2>&1
1764 call :CheckExist testfile
1765
1766 rem ------------------------------------------------
1767 rem Test concatenation
1768 rem ------------------------------------------------
1769 rem simple case, no wildcards
1770 copy file1+file2 testfile >nul 2>&1
1771 if errorlevel 1 echo Incorrect errorlevel
1772 call :CheckExist testfile
1773
1774 rem simple case, wildcards, no concatenation
1775 copy file* testfile >nul 2>&1
1776 if errorlevel 1 echo Incorrect errorlevel
1777 call :CheckExist testfile
1778
1779 rem simple case, wildcards, and concatenation
1780 echo ddddd > fred
1781 copy file*+fred testfile >nul 2>&1
1782 if errorlevel 1 echo Incorrect errorlevel
1783 call :CheckExist testfile
1784
1785 rem simple case, wildcards, and concatenation
1786 copy fred+file* testfile >nul 2>&1
1787 if errorlevel 1 echo Incorrect errorlevel
1788 call :CheckExist testfile
1789
1790 rem Calculate destination name
1791 copy fred+file* dir1 >nul 2>&1
1792 if errorlevel 1 echo Incorrect errorlevel
1793 call :CheckExist dir1\fred
1794
1795 rem Calculate destination name
1796 copy fred+file* dir1\ >nul 2>&1
1797 if errorlevel 1 echo Incorrect errorlevel
1798 call :CheckExist dir1\fred
1799
1800 rem Calculate destination name (none supplied)
1801 cd dir1
1802 copy ..\fred+..\file* >nul 2>&1
1803 if errorlevel 1 echo Incorrect errorlevel
1804 call :CheckExist fred
1805
1806 copy ..\fr*+..\file1  >nul 2>&1
1807 if errorlevel 1 echo Incorrect errorlevel
1808 call :CheckExist fred
1809 cd ..
1810
1811 rem ******************************************************************
1812 rem ASCII and BINARY tests
1813 rem Note: hard coded numbers deliberate because need to ensure whether
1814 rem an additional EOF has been added or not. There is no way to handle
1815 rem EOFs in batch, so assume if a single byte appears, its an EOF!
1816 rem ******************************************************************
1817
1818 rem Confirm original sizes of file1,2,3
1819 call :CheckFileSize file1 5 file2 8 file3 11
1820
1821 cd dir1
1822
1823 rem ----------------------------------------------
1824 rem Show concatenation defaults copy to ascii mode
1825 rem ----------------------------------------------
1826 rem Simple default copy source to destination (should not append EOF 5)
1827 copy ..\file1 file1_default >nul 2>&1
1828 call :CheckFileSize file1_default 5
1829
1830 rem Simple binary copy source to destination (should not append EOF 5)
1831 copy /b ..\file1 file1_default2 >nul 2>&1
1832 call :CheckFileSize file1_default2 5
1833
1834 rem Simple ascii copy source to destination (should append EOF 5+1, 8+1, 11+1)
1835 copy /a ..\file1 file1_plus_eof >nul 2>&1
1836 call :CheckFileSize file1_plus_eof 6
1837 copy /a ..\file2 file2_plus_eof >nul 2>&1
1838 call :CheckFileSize file2_plus_eof 9
1839 copy /a ..\file3 file3_plus_eof >nul 2>&1
1840 call :CheckFileSize file3_plus_eof 12
1841
1842 rem Concat 2 files, ascii mode - (only one EOF on the end 5+8+1)
1843 copy /a ..\file1+..\file2 file12_plus_eof >nul 2>&1
1844 call :CheckFileSize file12_plus_eof 14
1845
1846 rem Concat 2 files, binary mode - (no EOF on the end 5+8)
1847 copy /b ..\file1+..\file2 file12_no_eof >nul 2>&1
1848 call :CheckFileSize file12_no_eof 13
1849
1850 rem Concat 2 files, default mode - (one EOF on the end 5+8+1)
1851 copy ..\file1+..\file2 file12_eof2 >nul 2>&1
1852 call :CheckFileSize file12_eof2 14
1853
1854 rem --------------------------------------------------------------
1855 rem Show ascii source copy stops at first EOF, binary does the lot
1856 rem --------------------------------------------------------------
1857 copy file1_plus_eof /b file1_binary_srccopy /b >nul 2>&1
1858 call :CheckFileSize file1_binary_srccopy 6
1859
1860 copy file1_plus_eof /a file1_ascii_srccopy /b >nul 2>&1
1861 call :CheckFileSize file1_ascii_srccopy 5
1862
1863 rem --------------------------------------------------------------
1864 rem Show results of concatenating files (ending in EOFs) and /a /b
1865 rem --------------------------------------------------------------
1866
1867 rem Default and ascii copy reads as ascii, stripping EOFs, so 6-1 + 9-1 + 12-1 + 1
1868 copy file1_plus_eof+file2_plus_eof+file3_plus_eof file123_default_copy >nul 2>&1
1869 call :CheckFileSize file123_default_copy 25
1870 copy /a file1_plus_eof+file2_plus_eof+file3_plus_eof file123_ascii_copy >nul 2>&1
1871 call :CheckFileSize file123_ascii_copy 25
1872
1873 rem In binary mode, we get 3 eofs, so 6 + 9 + 12 = 27
1874 copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_binary_copy >nul 2>&1
1875 call :CheckFileSize file123_binary_copy 27
1876
1877 rem We can select which we want the eofs from by postfixing it with /a or /b
1878 rem so here have first and third with eof, second as ascii 6 + 9-1 + 12
1879 copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy1 >nul 2>&1
1880 call :CheckFileSize file123_mixed_copy1 26
1881
1882 rem By postfixing the destination with /a, we ask for an ascii destination which appends EOF
1883 rem so here have first and third with eof, second as ascii 6 + 9-1 + 12 + extra EOF
1884 rem Note the delta between this and the previous one also shows that the destination
1885 rem ascii/binary is inherited from the last /a or /b on the line
1886 copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy2 /a >nul 2>&1
1887 call :CheckFileSize file123_mixed_copy2 27
1888
1889 rem so here have second with eof, first and third as ascii 6-1 + 9 + 12-1
1890 rem Note the delta between the next two also shows that the destination ascii/binary is
1891 rem inherited from the last /a or /b on the line, so the first has an extra EOF
1892 copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy3 >nul 2>&1
1893 call :CheckFileSize file123_mixed_copy3 26
1894 copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy4 /b >nul 2>&1
1895 call :CheckFileSize file123_mixed_copy4 25
1896
1897 rem -------------------------------------------------------------------------------------------
1898 rem This shows when concatenating, an ascii destination always adds on an EOF but when we
1899 rem are not concatenating, its a direct copy regardless of destination if being read as binary
1900 rem -------------------------------------------------------------------------------------------
1901
1902 rem All 3 have eof's, plus an extra = 6 + 9 + 12 + eof
1903 copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_mixed_copy5 /a >nul 2>&1
1904 call :CheckFileSize file123_mixed_copy5 28
1905
1906 rem All 2 have eof's, plus an extra = 6 + 12 + eof
1907 copy /b file1_plus_eof + file3_plus_eof file123_mixed_copy6 /a >nul 2>&1
1908 call :CheckFileSize file123_mixed_copy6 19
1909
1910 rem One file has EOF, but doesnt get an extra one, ie 6
1911 copy /b file1_plus_eof file123_mixed_copy7 /a >nul 2>&1
1912 call :CheckFileSize file123_mixed_copy7 6
1913
1914 del *.* /q
1915 cd ..
1916
1917 rem ---------------------------------------
1918 rem Error combinations
1919 rem ---------------------------------------
1920 rem Specify source directory but name is a file
1921 call :setError 0
1922 copy file1\ dir1\ >NUL 2>&1
1923 if errorlevel 1 echo Passed: errorlevel invalid check 1
1924 if not errorlevel 1 echo Failed: errorlevel invalid check 1
1925 call :CheckNotExist dir1\file1
1926
1927 rem Overwrite same file
1928 call :setError 0
1929 copy file1 file1 >NUL 2>&1
1930 if errorlevel 1 echo Passed: errorlevel invalid check 2
1931 if not errorlevel 1 echo Failed: errorlevel invalid check 2
1932
1933 rem Supply same file identified as a directory
1934 call :setError 0
1935 copy file1 file1\ >NUL 2>&1
1936 if errorlevel 1 echo Passed: errorlevel invalid check 3
1937 if not errorlevel 1 echo Failed: errorlevel invalid check 3
1938
1939 cd ..
1940 rd foobar2 /s /q
1941
1942 echo ------------ Testing setlocal/endlocal ------------
1943 call :setError 0
1944 rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test section
1945 mkdir foobar & cd foobar
1946 echo --- enable/disable extensions
1947 setlocal DisableEXTensions
1948 echo ErrLev: %ErrorLevel%
1949 endlocal
1950 echo ErrLev: %ErrorLevel%
1951 echo @echo off> tmp.cmd
1952 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
1953 rem Enabled by default
1954 cmd /C tmp.cmd
1955 cmd /E:OfF /C tmp.cmd
1956 cmd /e:oN /C tmp.cmd
1957
1958 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
1959 echo --- setlocal with corresponding endlocal
1960 rem %CD% does not tork on NT4 so use the following workaround
1961 for /d %%i in (.) do set CURDIR=%%~dpnxi
1962 echo @echo off> test.cmd
1963 echo echo %%VAR%%>> test.cmd
1964 echo setlocal>> test.cmd
1965 echo set VAR=localval>> test.cmd
1966 echo md foobar2>> test.cmd
1967 echo cd foobar2>> test.cmd
1968 echo echo %%VAR%%>> test.cmd
1969 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1970 echo endlocal>> test.cmd
1971 echo echo %%VAR%%>> test.cmd
1972 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1973 set VAR=globalval
1974 call test.cmd
1975 echo %VAR%
1976 for /d %%i in (.) do echo %%~dpnxi
1977 cd /d %curdir%
1978 rd foobar2
1979 set VAR=
1980 echo --- setlocal with no corresponding endlocal
1981 echo @echo off> test.cmd
1982 echo echo %%VAR%%>> test.cmd
1983 echo setlocal>> test.cmd
1984 echo set VAR=localval>> test.cmd
1985 echo md foobar2>> test.cmd
1986 echo cd foobar2>> test.cmd
1987 echo echo %%VAR%%>> test.cmd
1988 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1989 set VAR=globalval
1990 rem %CD% does not tork on NT4 so use the following workaround
1991 for /d %%i in (.) do set CURDIR=%%~dpnxi
1992 call test.cmd
1993 echo %VAR%
1994 for /d %%i in (.) do echo %%~dpnxi
1995 cd /d %curdir%
1996 rd foobar2
1997 set VAR=
1998 echo --- setlocal within same batch program
1999 set var1=one
2000 set var2=
2001 set var3=
2002 rem %CD% does not tork on NT4 so use the following workaround
2003 for /d %%i in (.) do set CURDIR=%%~dpnxi
2004 setlocal
2005 set var2=two
2006 mkdir foobar2
2007 cd foobar2
2008 setlocal
2009 set var3=three
2010 if "%var1%"=="one" echo Var1 ok 1
2011 if "%var2%"=="two" echo Var2 ok 2
2012 if "%var3%"=="three" echo Var3 ok 3
2013 for /d %%i in (.) do set curdir2=%%~dpnxi
2014 if "%curdir2%"=="%curdir%\foobar2" echo Directory is ok 1
2015 endlocal
2016 if "%var1%"=="one" echo Var1 ok 1
2017 if "%var2%"=="two" echo Var2 ok 2
2018 if "%var3%"=="" echo Var3 ok 3
2019 for /d %%i in (.) do set curdir2=%%~dpnxi
2020 if "%curdir2%"=="%curdir%\foobar2" echo Directory is ok 2
2021 endlocal
2022 if "%var1%"=="one" echo Var1 ok 1
2023 if "%var2%"=="" echo Var2 ok 2
2024 if "%var3%"=="" echo Var3 ok 3
2025 for /d %%i in (.) do set curdir2=%%~dpnxi
2026 if "%curdir2%"=="%curdir%" echo Directory is ok 3
2027 rd foobar2 /s /q
2028 set var1=
2029
2030 echo --- Mismatched set and end locals
2031 mkdir foodir2 2>nul
2032 mkdir foodir3 2>nul
2033 mkdir foodir4 2>nul
2034 rem %CD% does not tork on NT4 so use the following workaround
2035 for /d %%i in (.) do set curdir=%%~dpnxi
2036
2037 echo @echo off> 2set1end.cmd
2038 echo echo %%VAR%%>> 2set1end.cmd
2039 echo setlocal>> 2set1end.cmd
2040 echo set VAR=2set1endvalue1>> 2set1end.cmd
2041 echo cd ..\foodir3>> 2set1end.cmd
2042 echo setlocal>> 2set1end.cmd
2043 echo set VAR=2set1endvalue2>> 2set1end.cmd
2044 echo cd ..\foodir4>> 2set1end.cmd
2045 echo endlocal>> 2set1end.cmd
2046 echo echo %%VAR%%>> 2set1end.cmd
2047 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 2set1end.cmd
2048
2049 echo @echo off> 1set2end.cmd
2050 echo echo %%VAR%%>> 1set2end.cmd
2051 echo setlocal>> 1set2end.cmd
2052 echo set VAR=1set2endvalue1>> 1set2end.cmd
2053 echo cd ..\foodir3>> 1set2end.cmd
2054 echo endlocal>> 1set2end.cmd
2055 echo echo %%VAR%%>> 1set2end.cmd
2056 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
2057 echo endlocal>> 1set2end.cmd
2058 echo echo %%VAR%%>> 1set2end.cmd
2059 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
2060
2061 echo --- Extra setlocal in called batch
2062 set VAR=value1
2063 rem -- setlocal1 == this batch, should never be used inside a called routine
2064 setlocal
2065 set var=value2
2066 cd foodir2
2067 call %curdir%\2set1end.cmd
2068 echo Finished:
2069 echo %VAR%
2070 for /d %%i in (.) do echo %%~dpnxi
2071 endlocal
2072 echo %VAR%
2073 for /d %%i in (.) do echo %%~dpnxi
2074 cd /d %curdir%
2075
2076 echo --- Extra endlocal in called batch
2077 set VAR=value1
2078 rem -- setlocal1 == this batch, should never be used inside a called routine
2079 setlocal
2080 set var=value2
2081 cd foodir2
2082 call %curdir%\1set2end.cmd
2083 echo Finished:
2084 echo %VAR%
2085 for /d %%i in (.) do echo %%~dpnxi
2086 endlocal
2087 echo %VAR%
2088 for /d %%i in (.) do echo %%~dpnxi
2089 cd /d %curdir%
2090
2091 echo --- endlocal in called function rather than batch pgm is ineffective
2092 @echo off
2093 set var=1
2094 set var2=1
2095 setlocal
2096 set var=2
2097 call :endlocalroutine
2098 echo %var%
2099 endlocal
2100 echo %var%
2101 goto :endlocalfinished
2102 :endlocalroutine
2103 echo %var%
2104 endlocal
2105 echo %var%
2106 setlocal
2107 set var2=2
2108 endlocal
2109 echo %var2%
2110 endlocal
2111 echo %var%
2112 echo %var2%
2113 goto :eof
2114 :endlocalfinished
2115 echo %var%
2116
2117 set var=
2118 set var2=
2119 cd .. & rd /q/s foobar
2120
2121 echo ------------ Testing Errorlevel ------------
2122 rem WARNING: Do *not* add tests using ErrorLevel after this section
2123 should_not_exist 2> nul > nul
2124 echo %ErrorLevel%
2125 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
2126 rem See http://www.robvanderwoude.com/exit.php
2127 call :setError 1
2128 echo %ErrorLevel%
2129 if errorlevel 2 echo errorlevel too high, bad
2130 if errorlevel 1 echo errorlevel just right, good
2131 if errorlevel 01 echo errorlevel with leading zero just right, good
2132 if errorlevel -1 echo errorlevel with negative number OK
2133 if errorlevel 0x1 echo hexa should not be recognized!
2134 if errorlevel 1a echo invalid error level recognized!
2135 call :setError 0
2136 echo abc%ErrorLevel%def
2137 if errorlevel 1 echo errorlevel nonzero, bad
2138 if not errorlevel 1 echo errorlevel zero, good
2139 if not errorlevel 0x1 echo hexa should not be recognized!
2140 if not errorlevel 1a echo invalid error level recognized!
2141 rem Now verify that setting a real variable hides its magic variable
2142 set errorlevel=7
2143 echo %ErrorLevel% should be 7
2144 if errorlevel 7 echo setting var worked too well, bad
2145 call :setError 3
2146 echo %ErrorLevel% should still be 7
2147
2148 echo ------------ Testing GOTO ------------
2149 if a==a goto dest1
2150 :dest1
2151 echo goto with no leading space worked
2152 if b==b goto dest2
2153  :dest2
2154 echo goto with a leading space worked
2155 if c==c goto dest3
2156         :dest3
2157 echo goto with a leading tab worked
2158 if d==d goto dest4
2159 :dest4@space@
2160 echo goto with a following space worked
2161
2162 echo ------------ Testing PATH ------------
2163 set backup_path=%path%
2164 set path=original
2165 path
2166 path try2
2167 path
2168 path=try3
2169 path
2170 set path=%backup_path%
2171 set backup_path=
2172
2173 echo ------------ Testing combined CALLs/GOTOs ------------
2174 echo @echo off>foo.cmd
2175 echo goto :eof>>foot.cmd
2176 echo :eof>>foot.cmd
2177 echo echo world>>foo.cmd
2178
2179 echo @echo off>foot.cmd
2180 echo echo cheball>>foot.cmd
2181 echo.>>foot.cmd
2182 echo call :bar>>foot.cmd
2183 echo if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmd
2184 echo goto :eof>>foot.cmd
2185 echo.>>foot.cmd
2186 echo :bar>>foot.cmd
2187 echo echo barbare>>foot.cmd
2188 echo goto :eof>>foot.cmd
2189
2190 call foo.cmd
2191 call foot
2192 call :bar
2193 del foo.cmd
2194 rem Script execution stops after the following line
2195 foot deleteMe
2196 call :foo
2197 call :foot
2198 goto :endFuns
2199
2200 :foot
2201 echo foot
2202
2203 :foo
2204 echo foo
2205 goto :eof
2206
2207 :endFuns
2208
2209 :bar
2210 echo bar
2211 call :foo
2212
2213 :baz
2214 echo baz
2215 goto :eof
2216
2217 echo Final message is not output since earlier 'foot' processing stops script execution
2218 echo Do NOT add any tests below this line
2219
2220 echo ------------ Done, jumping to EOF -----------
2221 goto :eof
2222 rem Subroutine to set errorlevel and return
2223 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
2224 :setError
2225 exit /B %1
2226 rem This line runs under cmd in windows NT 4, but not in more modern versions.