mshtml: Properly report history update for location.replace call.
[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
627 echo --- case sensitivity with and without /i option
628 if bar==BAR echo if does not default to case sensitivity
629 if not bar==BAR echo if seems to default to case sensitivity
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 if /I foo==FOO echo if /I seems to work
633 if /I not foo==FOO echo if /I seems to be broken
634
635 echo --- string comparisons
636 if abc == abc  (echo equal) else echo non equal
637 if abc =="abc" (echo equal) else echo non equal
638 if "abc"== abc (echo equal) else echo non equal
639 if "abc"== "abc" (echo equal) else echo non equal
640
641 echo --- tabs handling
642 if@tab@1==1 echo doom
643 if @tab@1==1 echo doom
644 if 1==1 (echo doom) else@tab@echo quake
645 if@tab@not @tab@1==@tab@0 @tab@echo lol
646 if 1==0@tab@(echo doom) else echo quake
647 if 1==0 (echo doom)@tab@else echo quake
648 if 1==0 (echo doom) else@tab@echo quake
649
650 echo --- comparison operators
651 rem NT4 misevaluates conditionals in for loops so we have to use subroutines as workarounds
652 echo ------ for strings
653 rem NT4 stops processing of the whole batch file as soon as it finds a
654 rem comparison operator non fully uppercased, such as lss instead of LSS, so we
655 rem can't test those here.
656 if LSS LSS LSSfoo (echo LSS string can be used as operand for LSS comparison)
657 if LSS LSS LSS (echo bar)
658 if 1.1 LSS 1.10 (echo floats are handled as strings)
659 if "9" LSS "10" (echo numbers in quotes recognized!) else echo numbers in quotes are handled as strings
660 if not "-1" LSS "1" (echo negative numbers as well) else echo NT4
661 if /i foo LSS FoOc echo if /i seems to work for LSS
662 if /I not foo LSS FOOb echo if /I seems to be broken for LSS
663 set STR_PARMS=A B AB BA AA
664 for %%i in (%STR_PARMS%) do (
665     for %%j in (%STR_PARMS%) do (
666         call :LSStest %%i %%j))
667 if b LSS B (echo b LSS B) else echo NT4
668 if /I b LSS B echo b LSS B insensitive
669 if b LSS A echo b LSS A
670 if /I b LSS A echo b LSS A insensitive
671 if a LSS B (echo a LSS B) else echo NT4
672 if /I a LSS B echo a LSS B insensitive
673 if A LSS b echo A LSS b
674 if /I A LSS b echo A LSS b insensitive
675 for %%i in (%STR_PARMS%) do (
676     for %%j in (%STR_PARMS%) do (
677         call :LEQtest %%i %%j))
678 if b LEQ B (echo b LEQ B) else echo NT4
679 if /I b LEQ B echo b LEQ B insensitive
680 if b LEQ A echo b LEQ A
681 if /I b LEQ A echo b LEQ A insensitive
682 if a LEQ B (echo a LEQ B) else echo NT4
683 if /I a LEQ B echo a LEQ B insensitive
684 if A LEQ b echo A LEQ b
685 if /I A LEQ b echo A LEQ b insensitive
686 for %%i in (%STR_PARMS%) do (
687     for %%j in (%STR_PARMS%) do (
688         call :EQUtest %%i %%j))
689 if /I A EQU a echo A EQU a insensitive
690 for %%i in (%STR_PARMS%) do (
691     for %%j in (%STR_PARMS%) do (
692         call :NEQtest %%i %%j))
693 for %%i in (%STR_PARMS%) do (
694     for %%j in (%STR_PARMS%) do (
695         call :GEQtest %%i %%j))
696 for %%i in (%STR_PARMS%) do (
697     for %%j in (%STR_PARMS%) do (
698         call :GTRtest %%i %%j))
699 echo ------ for numbers
700 if -1 LSS 1 (echo negative numbers handled)
701 if not -1 LSS -10 (echo negative numbers handled)
702 if not 9 LSS 010 (echo octal handled)
703 if not -010 LSS -8 (echo also in negative form)
704 if 4 LSS 0x5 (echo hexa handled)
705 if not -1 LSS -0x1A (echo also in negative form)
706 if 11 LSS 101 (echo 11 LSS 101)
707 set INT_PARMS=0 1 10 9
708 for %%i in (%INT_PARMS%) do (
709     for %%j in (%INT_PARMS%) do (
710         call :LSStest %%i %%j))
711 for %%i in (%INT_PARMS%) do (
712     for %%j in (%INT_PARMS%) do (
713         call :LEQtest %%i %%j))
714 for %%i in (%INT_PARMS%) do (
715     for %%j in (%INT_PARMS%) do (
716         call :EQUtest %%i %%j))
717 if 011 EQU 9 (echo octal ok)
718 if 0xA1 EQU 161 (echo hexa ok)
719 if 0xA1 EQU "161" (echo hexa should be recognized) else (echo string/hexa compare ok)
720 if "0xA1" EQU 161 (echo hexa should be recognized) else (echo string/hexa compare ok)
721 for %%i in (%INT_PARMS%) do (
722     for %%j in (%INT_PARMS%) do (
723         call :NEQtest %%i %%j))
724 for %%i in (%INT_PARMS%) do (
725     for %%j in (%INT_PARMS%) do (
726         call :GEQtest %%i %%j))
727 for %%i in (%INT_PARMS%) do (
728     for %%j in (%INT_PARMS%) do (
729         call :GTRtest %%i %%j))
730 echo ------ for numbers and stringified numbers
731 if not "1" EQU 1 (echo strings and integers not equal) else echo foo
732 if not 1 EQU "1" (echo strings and integers not equal) else echo foo
733 if '1' EQU 1 echo '1' EQU 1
734 if 1 EQU '1' echo 1 EQU '1'
735 if not "1" GEQ 1 (echo foo) else echo bar
736 if "10" GEQ "1" echo "10" GEQ "1"
737 if '1' GEQ 1 (echo '1' GEQ 1) else echo NT4
738 if 1 GEQ "1" echo 1 GEQ "1"
739 if "1" GEQ "1" echo "1" GEQ "1"
740 if '1' GEQ "1" echo '1' GEQ "1"
741 if "10" GEQ "1" echo "10" GEQ "1"
742 if not 1 GEQ '1' (echo non NT4) else echo 1 GEQ '1'
743 for %%i in ("1" '1') do call :GEQtest %%i '1'
744 if "10" GEQ '1' (echo "10" GEQ '1') else echo foo
745 if 1 GEQ "10" (echo 1 GEQ "10") else echo foo
746 if "1" GEQ "10" (echo 1 GEQ "10") else echo foo
747 if '1' GEQ "10" (echo '1' GEQ "10") else echo foo
748 if "10" GEQ "10" (echo "10" GEQ "10")
749 goto :endIfCompOpsSubroutines
750
751 rem IF subroutines helpers
752 :LSStest
753 if %1 LSS %2 echo %1 LSS %2
754 goto :eof
755 :LEQtest
756 if %1 LEQ %2 echo %1 LEQ %2
757 goto :eof
758 :EQUtest
759 if %1 EQU %2 echo %1 EQU %2
760 goto :eof
761 :NEQtest
762 if %1 NEQ %2 echo %1 NEQ %2
763 goto :eof
764 :GEQtest
765 if %1 GEQ %2 echo %1 GEQ %2
766 goto :eof
767 :GTRtest
768 if %1 GTR %2 echo %1 GTR %2
769 goto :eof
770
771 :endIfCompOpsSubroutines
772 set STR_PARMS=
773 set INT_PARMS=
774
775 echo ------------ Testing for ------------
776 echo --- plain FOR
777 for %%i in (A B C) do echo %%i
778 for %%i in (A B C) do echo %%I
779 for %%i in (A B C) do echo %%j
780 for %%i in (A B C) do call :forTestFun1 %%i
781 for %%i in (1,4,1) do echo %%i
782 for %%i in (A, B,C) do echo %%i
783 for %%i in  (X) do echo %%i
784 for@tab@%%i in  (X2) do echo %%i
785 for %%i in@tab@(X3) do echo %%i
786 for %%i in (@tab@ foo@tab@) do echo %%i
787 for@tab@ %%i in@tab@(@tab@M) do echo %%i
788 for %%i@tab@in (X)@tab@do@tab@echo %%i
789 for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
790 for %%i in (`echo A B`) do echo %%i
791 for %%i in ('echo A B') do echo %%i
792 for %%i in ("echo A B") do echo %%i
793 for %%i in ("A B" C) do echo %%i
794 goto :endForTestFun1
795 :forTestFun1
796 echo %1
797 goto :eof
798 :endForTestFun1
799 echo --- imbricated FORs
800 for %%i in (X) do (
801     for %%j in (Y) do (
802         echo %%i %%j))
803 for %%i in (X) do (
804     for %%I in (Y) do (
805         echo %%i %%I))
806 for %%i in (A B) do (
807     for %%j in (C D) do (
808         echo %%i %%j))
809 for %%i in (A B) do (
810     for %%j in (C D) do (
811         call :forTestFun2 %%i %%j ))
812 goto :endForTestFun2
813 :forTestFun2
814 echo %1 %2
815 goto :eof
816 :endForTestFun2
817 mkdir foobar & cd foobar
818 mkdir foo
819 mkdir bar
820 mkdir baz
821 echo > bazbaz
822 echo --- basic wildcards
823 for %%i in (ba*) do echo %%i
824 echo --- for /d
825 for /d %%i in (baz foo bar) do echo %%i 2>&1
826 rem Confirm we don't match files:
827 for /d %%i in (bazb*) do echo %%i 2>&1
828 for /d %%i in (bazb2*) do echo %%i 2>&1
829 rem Show we pass through non wildcards
830 for /d %%i in (PASSED) do echo %%i
831 for /d %%i in (xxx) do (
832   echo %%i - Should be xxx
833   echo Expected second line
834 )
835 rem Show we issue no messages on failures
836 for /d %%i in (FAILED?) do echo %%i 2>&1
837 for /d %%i in (FAILED?) do (
838   echo %%i - Unexpected!
839   echo FAILED Unexpected second line
840 )
841 for /d %%i in (FAILED*) do echo %%i 2>&1
842 for /d %%i in (FAILED*) do (
843   echo %%i - Unexpected!
844   echo FAILED Unexpected second line
845 )
846 rem FIXME can't test wildcard expansion here since it's listed in directory
847 rem order, and not in alphabetic order.
848 rem Proper testing would need a currently missing "sort" program implementation.
849 rem for /d %%i in (ba*) do echo %%i>> tmp
850 rem sort < tmp
851 rem del tmp
852 rem for /d %%i in (?a*) do echo %%i>> tmp
853 rem sort < tmp
854 rem del tmp
855 rem for /d %%i in (*) do echo %%i>> tmp
856 rem sort < tmp
857 rem del tmp
858 echo > baz\bazbaz
859 goto :TestForR
860
861 :SetExpected
862 del temp.bat 2>nul
863 call :WriteLine set found=N
864 for /l %%i in (1,1,%expectedresults%) do (
865   call :WriteLine if "%%%%expectedresults.%%i%%%%"=="%%%%1" set found=Y
866   call :WriteLine if "%%%%found%%%%"=="Y" set expectedresults.%%i=
867   call :WriteLine if "%%%%found%%%%"=="Y" goto :eof
868 )
869 call :WriteLine echo Got unexpected result: "%%%%1"
870 goto :eof
871
872 :WriteLine
873 echo %*>> temp.bat
874 goto :EOF
875
876 :ValidateExpected
877 del temp.bat 2>nul
878 for /l %%i in (1,1,%expectedresults%) do  call :WriteLine if not "%%%%expectedresults.%%i%%%%"=="" echo Found missing result: "%%%%expectedresults.%%i%%%%"
879 call temp.bat
880 del temp.bat 2>nul
881 goto :eof
882
883 :TestForR
884 rem %CD% does not tork on NT4 so use the following workaround
885 for /d %%i in (.) do set CURDIR=%%~dpnxi
886
887 echo --- for /R
888 echo Plain directory enumeration
889 set expectedresults=4
890 set expectedresults.1=%CURDIR%\.
891 set expectedresults.2=%CURDIR%\bar\.
892 set expectedresults.3=%CURDIR%\baz\.
893 set expectedresults.4=%CURDIR%\foo\.
894 call :SetExpected
895 for /R %%i in (.) do call temp.bat %%i
896 call :ValidateExpected
897
898 echo Plain directory enumeration from provided root
899 set expectedresults=4
900 set expectedresults.1=%CURDIR%\.
901 set expectedresults.2=%CURDIR%\bar\.
902 set expectedresults.3=%CURDIR%\baz\.
903 set expectedresults.4=%CURDIR%\foo\.
904 if "%CD%"=="" goto :SkipBrokenNT4
905 call :SetExpected
906 for /R "%CURDIR%" %%i in (.) do call temp.bat %%i
907 call :ValidateExpected
908 :SkipBrokenNT4
909
910 echo File enumeration
911 set expectedresults=2
912 set expectedresults.1=%CURDIR%\baz\bazbaz
913 set expectedresults.2=%CURDIR%\bazbaz
914 call :SetExpected
915 for /R %%i in (baz*) do call temp.bat %%i
916 call :ValidateExpected
917
918 echo File enumeration from provided root
919 set expectedresults=2
920 set expectedresults.1=%CURDIR%\baz\bazbaz
921 set expectedresults.2=%CURDIR%\bazbaz
922 call :SetExpected
923 for /R %%i in (baz*) do call temp.bat %%i
924 call :ValidateExpected
925
926 echo Mixed enumeration
927 set expectedresults=6
928 set expectedresults.1=%CURDIR%\.
929 set expectedresults.2=%CURDIR%\bar\.
930 set expectedresults.3=%CURDIR%\baz\.
931 set expectedresults.4=%CURDIR%\baz\bazbaz
932 set expectedresults.5=%CURDIR%\bazbaz
933 set expectedresults.6=%CURDIR%\foo\.
934 call :SetExpected
935 for /R %%i in (. baz*) do call temp.bat %%i
936 call :ValidateExpected
937
938 echo Mixed enumeration from provided root
939 set expectedresults=6
940 set expectedresults.1=%CURDIR%\.
941 set expectedresults.2=%CURDIR%\bar\.
942 set expectedresults.3=%CURDIR%\baz\.
943 set expectedresults.4=%CURDIR%\baz\bazbaz
944 set expectedresults.5=%CURDIR%\bazbaz
945 set expectedresults.6=%CURDIR%\foo\.
946 call :SetExpected
947 for /R %%i in (. baz*) do call temp.bat %%i
948 call :ValidateExpected
949
950 echo With duplicates enumeration
951 set expectedresults=12
952 set expectedresults.1=%CURDIR%\bar\bazbaz
953 set expectedresults.2=%CURDIR%\bar\fred
954 set expectedresults.3=%CURDIR%\baz\bazbaz
955 set expectedresults.4=%CURDIR%\baz\bazbaz
956 set expectedresults.5=%CURDIR%\baz\bazbaz
957 set expectedresults.6=%CURDIR%\baz\fred
958 set expectedresults.7=%CURDIR%\bazbaz
959 set expectedresults.8=%CURDIR%\bazbaz
960 set expectedresults.9=%CURDIR%\bazbaz
961 set expectedresults.10=%CURDIR%\foo\bazbaz
962 set expectedresults.11=%CURDIR%\foo\fred
963 set expectedresults.12=%CURDIR%\fred
964 call :SetExpected
965 for /R %%i in (baz* bazbaz fred ba*) do call temp.bat %%i
966 call :ValidateExpected
967
968 echo Strip missing wildcards, keep unwildcarded names
969 set expectedresults=6
970 set expectedresults.1=%CURDIR%\bar\jim
971 set expectedresults.2=%CURDIR%\baz\bazbaz
972 set expectedresults.3=%CURDIR%\baz\jim
973 set expectedresults.4=%CURDIR%\bazbaz
974 set expectedresults.5=%CURDIR%\foo\jim
975 set expectedresults.6=%CURDIR%\jim
976 call :SetExpected
977 for /R %%i in (baz* fred* jim) do call temp.bat %%i
978 call :ValidateExpected
979
980 echo for /R passed
981 cd .. & rd /s/Q foobar
982 echo --- for /L
983 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
984 for /L %%i in (1,2,0) do echo %%i
985 for@tab@/L %%i in (1,2,0) do echo %%i
986 for /L %%i in (1,2,6) do echo %%i
987 for /l %%i in (1 ,2,6) do echo %%i
988 for /L %%i in (a,2,3) do echo %%i
989 for /L %%i in (1,2,-1) do echo %%i
990 for /L %%i in (-4,-1,-1) do echo %%i
991 for /L %%i in (1,-2,-2) do echo %%i
992 for /L %%i in (1,2,a) do echo %%i
993 echo ErrorLevel %ErrorLevel%
994 for /L %%i in (1,a,b) do echo %%i
995 echo ErrorLevel %ErrorLevel%
996 rem Test boundaries
997 for /l %%i in (1,1,4) do echo %%i
998 for /l %%i in (1,2,4) do echo %%i
999 for /l %%i in (4,-1,1) do echo %%i
1000 for /l %%i in (4,-2,1) do echo %%i
1001 for /l %%i in (1,-1,4) do echo %%i
1002 for /l %%i in (4,1,1) do echo %%i
1003 for /L %%i in (a,2,b) do echo %%i
1004 for /L %%i in (1,1,1) do echo %%i
1005 for /L %%i in (1,-2,-1) do echo %%i
1006 for /L %%i in (-1,-1,-1) do echo %%i
1007 for /L %%i in (1,2, 3) do echo %%i
1008 rem Test zero iteration skips the body of the for
1009 for /L %%i in (2,2,1) do (
1010   echo %%i
1011   echo FAILED
1012 )
1013 echo --- for /a
1014 rem No output when using "set expr" syntax, unless in interactive mode
1015 rem Need to use "set envvar=expr" to use in a batch script
1016 echo ------ individual operations
1017 set var=0
1018 set /a var=1 +2 & echo %var%
1019 set /a var=1 +-2 & echo %var%
1020 set /a var=1 --2 & echo %var%
1021 set /a var=2* 3 & echo %var%
1022 set /a var=-2* -5 & echo %var%
1023 set /a var=12/3 & echo %var%
1024 set /a var=13/3 & echo %var%
1025 set /a var=-13/3 & echo %var%
1026 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
1027 set /a var=5 %% 5 & echo %var%
1028 set /a var=5 %% 3 & echo %var%
1029 set /a var=5 %% -3 & echo %var%
1030 set /a var=-5 %% -3 & echo %var%
1031 set /a var=1 ^<^< 0 & echo %var%
1032 set /a var=1 ^<^< 2 & echo %var%
1033 set /a var=1 ^<^< -2 & echo %var%
1034 set /a var=-1 ^<^< -2 & echo %var%
1035 set /a var=-1 ^<^< 2 & echo %var%
1036 set /a var=9 ^>^> 0 & echo %var%
1037 set /a var=9 ^>^> 2 & echo %var%
1038 set /a var=9 ^>^> -2 & echo %var%
1039 set /a var=-9 ^>^> -2 & echo %var%
1040 set /a var=-9 ^>^> 2 & echo %var%
1041 set /a var=5 ^& 0 & echo %var%
1042 set /a var=5 ^& 1 & echo %var%
1043 set /a var=5 ^& 3 & echo %var%
1044 set /a var=5 ^& 4 & echo %var%
1045 set /a var=5 ^& 1 & echo %var%
1046 set /a var=5 ^| 0 & echo %var%
1047 set /a var=5 ^| 1 & echo %var%
1048 set /a var=5 ^| 3 & echo %var%
1049 set /a var=5 ^| 4 & echo %var%
1050 set /a var=5 ^| 1 & echo %var%
1051 set /a var=5 ^^ 0 & echo %var%
1052 set /a var=5 ^^ 1 & echo %var%
1053 set /a var=5 ^^ 3 & echo %var%
1054 set /a var=5 ^^ 4 & echo %var%
1055 set /a var=5 ^^ 1 & echo %var%
1056 echo ------ precedence and grouping
1057 set /a var=4 + 2*3 & echo %var%
1058 set /a var=(4+2)*3 & echo %var%
1059 set /a var=4 * 3/5 & echo %var%
1060 set /a var=(4 * 3)/5 & echo %var%
1061 set /a var=4 * 5 %% 4 & echo %var%
1062 set /a var=4 * (5 %% 4) & echo %var%
1063 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
1064 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
1065 echo ------ octal and hexadecimal
1066 set /a var=0xf + 3 & echo %var%
1067 set /a var=0xF + 3 & echo %var%
1068 set /a var=015 + 2 & echo %var%
1069 set /a var=3, 8+3,0 & echo %var%
1070 echo ------ variables
1071 set /a var=foo=3, foo+1 & echo %var%
1072 if defined foo (echo %foo%) else (
1073     echo foo not defined
1074 )
1075 set /a var=foo=3, foo+=1 & echo %var%
1076 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
1077 set /a var=foo*= foo & echo %var%
1078 set /a var=whateverNonExistingVar & echo %var%
1079 set /a var=whateverNonExistingVar + bar & echo %var%
1080 set /a var=foo -= foo + 7 & echo %var%
1081 set /a var=foo /= 3 + 2 & echo %var%
1082 set /a var=foo=5, foo %%=2 & echo %var%
1083 set /a var=foo ^<^<= 2 & echo %var%
1084 set /a var=foo ^>^>= 2 & echo %var%
1085 set /a var=foo ^&= 2 & echo %var%
1086 set /a var=foo=5, foo ^|= 2 & echo %var%
1087 set /a var=foo=5, foo ^^= 2 & echo %var%
1088 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
1089 set foo=
1090 set bar=
1091 set var=
1092 echo --- for /F
1093 mkdir foobar & cd foobar
1094 echo ------ string argument
1095 rem NT4 does not support usebackq
1096 for /F %%i in ("a b c") do echo %%i
1097 for /f usebackq %%i in ('a b c') do echo %%i>output_file
1098 if not exist output_file (echo no output) else (type output_file & del output_file)
1099 for /f %%i in ("a ") do echo %%i
1100 for /f usebackq %%i in ('a ') do echo %%i>output_file
1101 if not exist output_file (echo no output) else (type output_file & del output_file)
1102 for /f %%i in ("a") do echo %%i
1103 for /f usebackq %%i in ('a') do echo %%i>output_file
1104 if not exist output_file (echo no output) else (type output_file & del output_file)
1105 fOr /f %%i in (" a") do echo %%i
1106 for /f usebackq %%i in (' a') do echo %%i>output_file
1107 if not exist output_file (echo no output) else (type output_file & del output_file)
1108 for /f %%i in (" a ") do echo %%i
1109 for /f usebackq %%i in (' a ') do echo %%i>output_file
1110 if not exist output_file (echo no output) else (type output_file & del output_file)
1111 echo ------ fileset argument
1112 echo --------- basic blank handling
1113 echo a b c>foo
1114 for /f %%i in (foo) do echo %%i
1115 echo a >foo
1116 for /f %%i in (foo) do echo %%i
1117 echo a>foo
1118 for /f %%i in (foo) do echo %%i
1119 echo  a>foo
1120 for /f %%i in (foo) do echo %%i
1121 echo  a >foo
1122 for /f %%i in (foo) do echo %%i
1123 echo. > foo
1124 for /f %%i in (foo) do echo %%i
1125 echo. >> foo
1126 echo b > foo
1127 for /f %%i in (foo) do echo %%i
1128 echo --------- multi-line with empty lines
1129 echo a Z f> foo
1130 echo. >> foo
1131 echo.>> foo
1132 echo b bC>> foo
1133 echo c>> foo
1134 echo. >> foo
1135 for /f %%b in (foo) do echo %%b
1136 echo --------- multiple files
1137 echo q w > bar
1138 echo.>> bar
1139 echo kkk>>bar
1140 for /f %%k in (foo bar) do echo %%k
1141 for /f %%k in (bar foo) do echo %%k
1142 echo ------ command argument
1143 rem Not implemented on NT4, need to skip it as no way to get output otherwise
1144 if "%CD%"=="" goto :SkipFORFcmdNT4
1145 for /f %%i in ('echo.Passed1') do echo %%i
1146 for /f "usebackq" %%i in (`echo.Passed2`) do echo %%i
1147 for /f usebackq %%i in (`echo.Passed3`) do echo %%i
1148 goto :ContinueFORF
1149 :SkipFORFcmdNT4
1150 for /l %%i in (1,1,3) do echo Missing functionality - Broken%%i
1151 :ContinueFORF
1152 rem FIXME: Rest not testable right now in wine: not implemented and would need
1153 rem preliminary grep-like program implementation (e.g. like findstr or fc) even
1154 rem for a simple todo_wine test
1155 rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported
1156 rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported
1157 echo ------ eol option
1158 if "%CD%"=="" goto :SkipFORFeolNT4
1159 echo Line one>foo
1160 echo and Line two>>foo
1161 echo Line three>>foo
1162 for /f "eol=L" %%i in (foo) do echo %%i
1163 for /f "eol=a" %%i in (foo) do echo %%i
1164 del foo
1165 goto :ContinueFORFeol
1166 :SkipFORFeolNT4
1167 for /l %%i in (1,1,3) do echo Broken NT4 functionality%%i
1168 :ContinueFORFeol
1169 for /f "eol=@" %%i in ("    ad") do echo %%i
1170 for /f "eol=@" %%i in (" z@y") do echo %%i
1171 for /f "eol=|" %%i in ("a|d") do echo %%i
1172 for /f "eol=@" %%i in ("@y") do echo %%i > output_file
1173 if not exist output_file (echo no output) else (del output_file)
1174 for /f "eol==" %%i in ("=y") do echo %%i > output_file
1175 if not exist output_file (echo no output) else (del output_file)
1176 echo ------ delims option
1177 for /f "delims=|" %%i in ("a|d") do echo %%i
1178 for /f "delims=|" %%i in ("a |d") do echo %%i
1179 for /f "delims=|" %%i in ("a d|") do echo %%i
1180 for /f "delims=| " %%i in ("a d|") do echo %%i
1181 for /f "delims==" %%i in ("C r=d|") do echo %%i
1182 for /f "delims=" %%i in ("foo bar baz") do echo %%i
1183 for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi
1184 echo ------ skip option
1185 echo a > foo
1186 echo b >> foo
1187 echo c >> foo
1188 for /f "skip=2" %%i in (foo) do echo %%i
1189 for /f "skip=3" %%i in (foo) do echo %%i > output_file
1190 if not exist output_file (echo no output) else (del output_file)
1191 for /f "skip=4" %%i in (foo) do echo %%i > output_file
1192 if not exist output_file (echo no output) else (del output_file)
1193 for /f "skip=02" %%i in (foo) do echo %%i
1194 for /f "skip=0x2" %%i in (foo) do echo %%i
1195 for /f "skip=1" %%i in ("skipme") do echo %%i > output_file
1196 if not exist output_file (echo no output) else (del output_file)
1197 cd ..
1198 rd /s/q foobar
1199
1200 echo ------------ Testing del /a ------------
1201 del /f/q *.test > nul
1202 echo r > r.test
1203 attrib +r r.test
1204 echo not-r > not-r.test
1205
1206 if not exist not-r.test echo not-r.test not found before delete, bad
1207 del /a:-r *.test
1208 if not exist not-r.test echo not-r.test not found after delete, good
1209
1210 if not exist r.test echo r.test not found before delete, bad
1211 if exist r.test echo r.test found before delete, good
1212 del /a:r *.test
1213 if not exist r.test echo r.test not found after delete, good
1214 if exist r.test echo r.test found after delete, bad
1215
1216 echo ------------ Testing del /q ------------
1217 mkdir del_q_dir
1218 cd del_q_dir
1219 echo abc > file1
1220 echo abc > file2.dat
1221 rem If /q doesn't work, cmd will prompt and the test case should hang
1222 del /q * > nul
1223 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
1224 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
1225 cd ..
1226 rmdir del_q_dir
1227
1228 echo ------------ Testing del /s ------------
1229 mkdir "foo bar"
1230 cd "foo bar"
1231 mkdir "foo:"
1232 echo hi > file1.dat
1233 echo there > file2.dat
1234 echo bub > file3.dat
1235 echo bye > "file with spaces.dat"
1236 cd ..
1237 del /s file1.dat > nul
1238 del file2.dat /s > nul
1239 del "file3.dat" /s > nul
1240 del "file with spaces.dat" /s > nul
1241 cd "foo bar"
1242 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
1243 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
1244 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
1245 if exist "file with spaces.dat" del "file with spaces.dat"
1246 rmdir "foo:"
1247 cd ..
1248 rmdir "foo bar"
1249
1250 echo ------------ Testing rename ------------
1251 mkdir foobar & cd foobar
1252 echo --- ren and rename are synonymous
1253 echo > foo
1254 rename foo bar
1255 if exist foo echo foo should be renamed!
1256 if exist bar echo foo renamed to bar
1257 ren bar foo
1258 if exist bar echo bar should be renamed!
1259 if exist foo echo bar renamed to foo
1260 echo --- name collision
1261 echo foo>foo
1262 echo bar>bar
1263 ren foo bar 2> nul
1264 type foo
1265 type bar
1266 rem no-op
1267 ren foo foo
1268 mkdir baz
1269 ren foo baz\abc
1270 echo --- rename read-only files
1271 echo > file1
1272 attrib +r file1
1273 ren file1 file2
1274 if not exist file1 (
1275     if exist file2 (
1276         echo read-only file renamed
1277     )
1278 ) else (
1279     echo read-only file not renamed!
1280 )
1281 echo --- rename directories
1282 mkdir rep1
1283 ren rep1 rep2
1284 if not exist rep1 (
1285     if exist rep2 (
1286         echo dir renamed
1287     )
1288 )
1289 attrib +r rep2
1290 ren rep2 rep1
1291 if not exist rep2 (
1292     if exist rep1 (
1293         echo read-only dir renamed
1294     )
1295 )
1296 echo --- rename in other directory
1297 if not exist baz\abc (
1298     echo rename impossible in other directory
1299     if exist foo echo original file still present
1300 ) else (
1301     echo shouldn't rename in other directory!
1302     if not exist foo echo original file not present anymore
1303 )
1304 cd .. & rd /s/q foobar
1305
1306 echo ------------ Testing move ------------
1307 mkdir foobar & cd foobar
1308 echo --- file move
1309 echo >foo
1310 move foo bar > nul 2>&1
1311 if not exist foo (
1312     if exist bar (
1313         echo file move succeeded
1314     )
1315 )
1316 echo bar>bar
1317 echo baz> baz
1318 move /Y bar baz > nul 2>&1
1319 if not exist bar (
1320     if exist baz (
1321         echo file move with overwrite succeeded
1322     )
1323 ) else (
1324     echo file overwrite impossible!
1325     del bar
1326 )
1327 type baz
1328
1329 attrib +r baz
1330 move baz bazro > nul 2>&1
1331 if not exist baz (
1332     if exist bazro (
1333         echo read-only files are moveable
1334         move bazro baz > nul 2>&1
1335     )
1336 ) else (
1337     echo read-only file not moved!
1338 )
1339 attrib -r baz
1340 mkdir rep
1341 move baz rep > nul 2>&1
1342 if not exist baz (
1343     if exist rep\baz (
1344         echo file moved in subdirectory
1345     )
1346 )
1347 call :setError 0
1348 move rep\baz . > nul 2>&1
1349 move /Y baz baz > nul 2>&1
1350 if errorlevel 1 (
1351     echo moving a file to itself should be a no-op!
1352 ) else (
1353     echo moving a file to itself is a no-op
1354 )
1355 echo ErrorLevel: %ErrorLevel%
1356 call :setError 0
1357 del baz
1358 echo --- directory move
1359 mkdir foo\bar
1360 mkdir baz
1361 echo baz2>baz\baz2
1362 move baz foo\bar > nul 2>&1
1363 if not exist baz (
1364     if exist foo\bar\baz\baz2 (
1365         echo simple directory move succeeded
1366     )
1367 )
1368 call :setError 0
1369 mkdir baz
1370 move baz baz > nul 2>&1
1371 echo moving a directory to itself gives error; errlevel %ErrorLevel%
1372 echo ------ dir in dir move
1373 rd /s/q foo
1374 mkdir foo bar
1375 echo foo2>foo\foo2
1376 echo bar2>bar\bar2
1377 move foo bar > nul 2>&1
1378 if not exist foo (
1379     if exist bar (
1380         dir /b /ad bar
1381         dir /b /a-d bar
1382         dir /b bar\foo
1383     )
1384 )
1385 cd .. & rd /s/q foobar
1386
1387 echo ------------ Testing mkdir ------------
1388 call :setError 0
1389 echo --- md and mkdir are synonymous
1390 mkdir foobar
1391 echo %ErrorLevel%
1392 rmdir foobar
1393 md foobar
1394 echo %ErrorLevel%
1395 rmdir foobar
1396 echo --- creating an already existing directory/file must fail
1397 mkdir foobar
1398 md foobar
1399 echo %ErrorLevel%
1400 rmdir foobar
1401 echo > foobar
1402 mkdir foobar
1403 echo %ErrorLevel%
1404 del foobar
1405 echo --- multilevel path creation
1406 mkdir foo
1407 echo %ErrorLevel%
1408 mkdir foo\bar\baz
1409 echo %ErrorLevel%
1410 cd foo
1411 echo %ErrorLevel%
1412 cd bar
1413 echo %ErrorLevel%
1414 cd baz
1415 echo %ErrorLevel%
1416 echo > ..\..\bar2
1417 mkdir ..\..\..\foo\bar2
1418 echo %ErrorLevel%
1419 del ..\..\bar2
1420 mkdir ..\..\..\foo\bar2
1421 echo %ErrorLevel%
1422 rmdir ..\..\..\foo\bar2
1423 cd ..
1424 rmdir baz
1425 cd ..
1426 rmdir bar
1427 cd ..
1428 rmdir foo
1429 echo %ErrorLevel%
1430 echo --- trailing backslashes
1431 mkdir foo\\\\
1432 echo %ErrorLevel%
1433 if exist foo (rmdir foo & echo dir created
1434 ) else ( echo dir not created )
1435 echo %ErrorLevel%
1436 echo --- invalid chars
1437 mkdir ?
1438 echo mkdir ? gives errorlevel %ErrorLevel%
1439 call :setError 0
1440 mkdir ?\foo
1441 echo mkdir ?\foo gives errorlevel %ErrorLevel%
1442 call :setError 0
1443 mkdir foo\?
1444 echo mkdir foo\? gives errorlevel %ErrorLevel%
1445 if exist foo (rmdir foo & echo ok, foo created
1446 ) else ( echo foo not created )
1447 call :setError 0
1448 mkdir foo\bar\?
1449 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
1450 call :setError 0
1451 if not exist foo (
1452     echo bad, foo not created
1453 ) else (
1454     cd foo
1455     if exist bar (
1456         echo ok, foo\bar created
1457         rmdir bar
1458     )
1459     cd ..
1460     rmdir foo
1461 )
1462 echo --- multiple directories at once
1463 mkdir foobaz & cd foobaz
1464 mkdir foo bar\baz foobar "bazbaz" .\"zabzab"
1465 if exist foo (echo foo created) else echo foo not created!
1466 if exist bar (echo bar created) else echo bar not created!
1467 if exist foobar (echo foobar created) else echo foobar not created!
1468 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
1469 if exist bazbaz (echo bazbaz created) else echo bazbaz not created!
1470 if exist zabzab (echo zabzab created) else echo zabzab not created!
1471 cd .. & rd /s/q foobaz
1472 call :setError 0
1473 mkdir foo\*
1474 echo mkdir foo\* errorlevel %ErrorLevel%
1475 if exist foo (rmdir foo & echo ok, foo created
1476 ) else ( echo bad, foo not created )
1477
1478 echo ------------ Testing rmdir ------------
1479 call :setError 0
1480 rem rd and rmdir are synonymous
1481 mkdir foobar
1482 rmdir foobar
1483 echo %ErrorLevel%
1484 if not exist foobar echo dir removed
1485 mkdir foobar
1486 rd foobar
1487 echo %ErrorLevel%
1488 if not exist foobar echo dir removed
1489 rem Removing nonexistent directory
1490 rmdir foobar
1491 echo %ErrorLevel%
1492 rem Removing single-level directories
1493 echo > foo
1494 rmdir foo
1495 echo %ErrorLevel%
1496 if exist foo echo file not removed
1497 del foo
1498 mkdir foo
1499 echo > foo\bar
1500 rmdir foo
1501 echo %ErrorLevel%
1502 if exist foo echo non-empty dir not removed
1503 del foo\bar
1504 mkdir foo\bar
1505 rmdir foo
1506 echo %ErrorLevel%
1507 if exist foo echo non-empty dir not removed
1508 rmdir foo\bar
1509 rmdir foo
1510 rem Recursive rmdir
1511 mkdir foo\bar\baz
1512 rmdir /s /Q foo
1513 if not exist foo (
1514     echo recursive rmdir succeeded
1515 ) else (
1516     rd foo\bar\baz
1517     rd foo\bar
1518     rd foo
1519 )
1520 mkdir foo\bar\baz
1521 echo foo > foo\bar\brol
1522 rmdir /s /Q foo 2>&1
1523 if not exist foo (
1524     echo recursive rmdir succeeded
1525 ) else (
1526     rd foo\bar\baz
1527     del foo\bar\brol
1528     rd foo\bar
1529     rd foo
1530 )
1531 rem multiples directories at once
1532 mkdir foobaz & cd foobaz
1533 mkdir foo
1534 mkdir bar\baz
1535 mkdir foobar
1536 rd /s/q foo bar foobar
1537 if not exist foo (echo foo removed) else echo foo not removed!
1538 if not exist bar (echo bar removed) else echo bar not removed!
1539 if not exist foobar (echo foobar removed) else echo foobar not removed!
1540 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
1541 cd .. & rd /s/q foobaz
1542
1543 echo ------------ Testing pushd/popd ------------
1544 cd
1545 echo --- popd is no-op when dir stack is empty
1546 popd
1547 cd
1548 echo --- pushing non-existing dir
1549 pushd foobar
1550 cd
1551 echo --- basic behaviour
1552 mkdir foobar\baz
1553 pushd foobar
1554 cd
1555 popd
1556 cd
1557 pushd foobar
1558 pushd baz
1559 cd
1560 popd
1561 cd
1562 pushd baz
1563 popd
1564 cd
1565 popd
1566 cd
1567 pushd .
1568 cd foobar\baz
1569 pushd ..
1570 cd
1571 popd
1572 popd
1573 cd
1574 rd /s/q foobar
1575
1576 echo ------------ Testing attrib ------------
1577 rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications
1578 mkdir foobar & cd foobar
1579 echo foo original contents> foo
1580 attrib foo
1581 echo > bar
1582 echo --- read-only attribute
1583 rem Read-only files cannot be altered or deleted, unless forced
1584 attrib +R foo
1585 attrib foo
1586 dir /Ar /B
1587 echo bar>> foo
1588 type foo
1589 del foo > NUL 2>&1
1590 if exist foo (
1591     echo Read-only file not deleted
1592 ) else (
1593     echo Should not delete read-only file!
1594 )
1595 del /F foo
1596 if not exist foo (
1597     echo Read-only file forcibly deleted
1598 ) else (
1599     echo Should delete read-only file with del /F!
1600     attrib -r foo
1601     del foo
1602 )
1603 cd .. & rd /s/q foobar
1604 echo --- recursive behaviour
1605 mkdir foobar\baz & cd foobar
1606 echo > level1
1607 echo > whatever
1608 echo > baz\level2
1609 attrib baz\level2
1610 cd ..
1611 attrib +R l*vel? /S > nul 2>&1
1612 cd foobar
1613 attrib level1
1614 attrib baz\level2
1615 echo > bar
1616 attrib bar
1617 cd .. & rd /s/q foobar
1618 echo --- folders processing
1619 mkdir foobar
1620 attrib foobar
1621 cd foobar
1622 mkdir baz
1623 echo toto> baz\toto
1624 attrib +r baz /s /d > nul 2>&1
1625 attrib baz
1626 attrib baz\toto
1627 echo lulu>>baz\toto
1628 type baz\toto
1629 echo > baz\lala
1630 rem Oddly windows allows file creation in a read-only directory...
1631 if exist baz\lala (echo file created in read-only dir) else echo file not created
1632 cd .. & rd /s/q foobar
1633
1634 echo ------------ Testing assoc ------------
1635 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
1636 rem FIXME Revise once || conditional execution is fixed
1637 mkdir foobar & cd foobar
1638 echo --- setting association
1639 assoc .foo > baz
1640 type baz
1641 echo ---
1642
1643 assoc .foo=bar
1644 assoc .foo
1645
1646 rem association set system-wide
1647 echo @echo off> tmp.cmd
1648 echo echo +++>> tmp.cmd
1649 echo assoc .foo>> tmp.cmd
1650 cmd /c tmp.cmd
1651
1652 echo --- resetting association
1653 assoc .foo=
1654 assoc .foo > baz
1655 type baz
1656 echo ---
1657
1658 rem association removal set system-wide
1659 cmd /c tmp.cmd > baz
1660 type baz
1661 echo ---
1662 cd .. & rd /s/q foobar
1663
1664 echo ------------ Testing ftype ------------
1665 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
1666 rem FIXME Revise once || conditional execution is fixed
1667 mkdir foobar & cd foobar
1668 echo --- setting association
1669 ftype footype> baz
1670 type baz
1671 echo ---
1672
1673 ftype footype=foo_opencmd
1674 assoc .foo=footype
1675 ftype footype
1676
1677 rem association set system-wide
1678 echo @echo off> tmp.cmd
1679 echo echo +++>> tmp.cmd
1680 echo ftype footype>> tmp.cmd
1681 cmd /c tmp.cmd
1682
1683 echo --- resetting association
1684 assoc .foo=
1685
1686 rem Removing a file type association doesn't work on XP due to a bug, so a workaround is needed
1687 setlocal EnableDelayedExpansion
1688 set FOO=original value
1689 ftype footype=
1690 ftype footype > baz
1691 for /F %%i in ('type baz') do (set FOO=buggyXP)
1692 rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion)
1693 rem FIXME Revisit once a grep-like program like ftype is implemented
1694 rem (e.g. to check baz's size using dir /b instead)
1695 echo !FOO!
1696
1697 rem cleanup registry
1698 echo REGEDIT4> regCleanup.reg
1699 echo.>> regCleanup.reg
1700 echo [-HKEY_CLASSES_ROOT\footype]>> regCleanup.reg
1701 regedit /s regCleanup.reg
1702 set FOO=
1703 endlocal
1704 cd .. & rd /s/q foobar
1705
1706 echo ------------ Testing CALL ------------
1707 mkdir foobar & cd foobar
1708 echo --- external script
1709 echo echo foo %%1> foo.cmd
1710 call foo
1711 call foo.cmd 8
1712 echo echo %%1 %%2 > foo.cmd
1713 call foo.cmd foo
1714 call foo.cmd foo bar
1715 call foo.cmd foo ""
1716 call foo.cmd "" bar
1717 call foo.cmd foo ''
1718 call foo.cmd '' bar
1719 del foo.cmd
1720
1721 echo --- internal routines
1722 call :testRoutine :testRoutine
1723 goto :endTestRoutine
1724 :testRoutine
1725 echo bar %1
1726 goto :eof
1727 :endTestRoutine
1728
1729 call :testRoutineArgs foo
1730 call :testRoutineArgs foo bar
1731 call :testRoutineArgs foo ""
1732 call :testRoutineArgs ""  bar
1733 call :testRoutineArgs foo ''
1734 call :testRoutineArgs ''  bar
1735 goto :endTestRoutineArgs
1736 :testRoutineArgs
1737 echo %1 %2
1738 goto :eof
1739 :endTestRoutineArgs
1740
1741 echo --- with builtins
1742 call mkdir foo
1743 echo %ErrorLevel%
1744 if exist foo (echo foo created) else echo foo should exist!
1745 rmdir foo
1746 set FOOBAZ_VAR=foobaz
1747 call echo Should expand %FOOBAZ_VAR%
1748 set FOOBAZ_VAR=
1749 echo>batfile
1750 call dir /b
1751 echo>robinfile
1752 if 1==1 call del batfile
1753 dir /b
1754 if exist batfile echo batfile shouldn't exist
1755 rem ... but not for 'if' or 'for'
1756 call if 1==1 echo bar 2> nul
1757 echo %ErrorLevel%
1758 call :setError 0
1759 call for %%i in (foo bar baz) do echo %%i 2> nul
1760 echo %ErrorLevel%
1761 rem First look for programs in the path before trying a builtin
1762 echo echo non-builtin dir> dir.cmd
1763 call dir /b
1764 del dir.cmd
1765 rem The below line equates to call (, which does nothing, then the
1766 rem subsequent lines are executed.
1767 call (
1768   echo Line one
1769   echo Line two
1770 )
1771 rem The below line equates to call if, which always fails, then the
1772 rem subsequent lines are executed. Note cmd.exe swallows all lines
1773 rem starting with )
1774 call if 1==1 (
1775   echo Get if
1776 ) else (
1777   echo ... and else!
1778 )
1779 call call call echo passed
1780 cd .. & rd /s/q foobar
1781
1782 echo ------------ Testing SHIFT ------------
1783
1784 call :shiftFun p1 p2 p3 p4 p5
1785 goto :endShiftFun
1786
1787 :shiftFun
1788 echo '%1' '%2' '%3' '%4' '%5'
1789 shift
1790 echo '%1' '%2' '%3' '%4' '%5'
1791 shift@tab@ /1
1792 echo '%1' '%2' '%3' '%4' '%5'
1793 shift /2
1794 echo '%1' '%2' '%3' '%4' '%5'
1795 shift /-1
1796 echo '%1' '%2' '%3' '%4' '%5'
1797 shift /0
1798 echo '%1' '%2' '%3' '%4' '%5'
1799 goto :eof
1800 :endShiftFun
1801
1802 echo ------------ Testing cmd invocation ------------
1803 rem FIXME: only a stub ATM
1804 echo --- a batch file can delete itself
1805 echo del foo.cmd>foo.cmd
1806 cmd /q /c foo.cmd
1807 if not exist foo.cmd (
1808     echo file correctly deleted
1809 ) else (
1810     echo file should be deleted!
1811     del foo.cmd
1812 )
1813 echo --- a batch file can alter itself
1814 echo echo bar^>foo.cmd>foo.cmd
1815 cmd /q /c foo.cmd > NUL 2>&1
1816 if exist foo.cmd (
1817     type foo.cmd
1818     del foo.cmd
1819 ) else (
1820     echo file not created!
1821 )
1822
1823 echo ---------- Testing copy
1824 md foobar2
1825 cd foobar2
1826 rem Note echo adds 0x0d 0x0a on the end of the line in the file
1827 echo AAA> file1
1828 echo BBBBBB> file2
1829 echo CCCCCCCCC> file3
1830 md dir1
1831 goto :testcopy
1832
1833 :CheckExist
1834 if exist "%1" (
1835   echo Passed: Found expected %1
1836 ) else (
1837   echo Failed: Did not find expected %1
1838 )
1839 del /q "%1" >nul 2>&1
1840 shift
1841 if not "%1"=="" goto :CheckExist
1842 goto :eof
1843
1844 :CheckNotExist
1845 if not exist "%1" (
1846   echo Passed: Did not find %1
1847 ) else (
1848   echo Failed: Unexpectedly found %1
1849   del /q "%1" >nul 2>&1
1850 )
1851 shift
1852 if not "%1"=="" goto :CheckNotExist
1853 goto :eof
1854
1855 rem Note: No way to check file size on NT4 so skip the test
1856 :CheckFileSize
1857 if not exist "%1" (
1858   echo Failed: File missing when requested filesize check [%2]
1859   goto :ContinueFileSizeChecks
1860 )
1861 for %%i in (%1) do set filesize=%%~zi
1862 if "%filesize%"=="%2" (
1863     echo Passed: file size check on %1 [%filesize%]
1864 ) else (
1865   if "%filesize%"=="%%~zi" (
1866     echo Skipping file size check on NT4
1867   ) else (
1868     echo Failed: file size check on %1 [%filesize% != %2]
1869   )
1870 )
1871 :ContinueFileSizeChecks
1872 shift
1873 shift
1874 if not "%1"=="" goto :CheckFileSize
1875 goto :eof
1876
1877 :testcopy
1878
1879 rem -----------------------
1880 rem Simple single file copy
1881 rem -----------------------
1882 rem Simple single file copy, normally used syntax
1883 copy file1 dummy.file >nul 2>&1
1884 if errorlevel 1 echo Incorrect errorlevel
1885 call :CheckExist dummy.file
1886
1887 rem Simple single file copy, destination supplied as two forms of directory
1888 copy file1 dir1 >nul 2>&1
1889 if errorlevel 1 echo Incorrect errorlevel
1890 call :CheckExist dir1\file1
1891
1892 copy file1 dir1\ >nul 2>&1
1893 if errorlevel 1 echo Incorrect errorlevel
1894 call :CheckExist dir1\file1
1895
1896 rem Simple single file copy, destination supplied as fully qualified destination
1897 copy file1 dir1\file99 >nul 2>&1
1898 if errorlevel 1 echo Incorrect errorlevel
1899 call :CheckExist dir1\file99
1900
1901 rem Simple single file copy, destination not supplied
1902 cd dir1
1903 copy ..\file1 >nul 2>&1
1904 if errorlevel 1 echo Incorrect errorlevel
1905 call :CheckExist file1
1906 cd ..
1907
1908 rem Simple single file copy, destination supplied as nonexistent directory
1909 copy file1 dir2\ >nul 2>&1
1910 if not errorlevel 1 echo Incorrect errorlevel
1911 call :CheckNotExist dir2 dir2\file1
1912
1913 rem -----------------------
1914 rem Wildcarded copy
1915 rem -----------------------
1916 rem Simple single file copy, destination supplied as two forms of directory
1917 copy file? dir1 >nul 2>&1
1918 if errorlevel 1 echo Incorrect errorlevel
1919 call :CheckExist dir1\file1 dir1\file2 dir1\file3
1920
1921 copy file* dir1\ >nul 2>&1
1922 if errorlevel 1 echo Incorrect errorlevel
1923 call :CheckExist dir1\file1 dir1\file2 dir1\file3
1924
1925 rem Simple single file copy, destination not supplied
1926 cd dir1
1927 copy ..\file*.* >nul 2>&1
1928 if errorlevel 1 echo Incorrect errorlevel
1929 call :CheckExist file1 file2 file3
1930 cd ..
1931
1932 rem Simple wildcarded file copy, destination supplied as nonexistent directory
1933 copy file? dir2\ >nul 2>&1
1934 if not errorlevel 1 echo Incorrect errorlevel
1935 call :CheckNotExist dir2 dir2\file1 dir2\file2 dir2\file3
1936
1937 rem ------------------------------------------------
1938 rem Confirm overwrite works (cannot test prompting!)
1939 rem ------------------------------------------------
1940 copy file1 testfile >nul 2>&1
1941 copy /y file2 testfile >nul 2>&1
1942 call :CheckExist testfile
1943
1944 rem ------------------------------------------------
1945 rem Test concatenation
1946 rem ------------------------------------------------
1947 rem simple case, no wildcards
1948 copy file1+file2 testfile >nul 2>&1
1949 if errorlevel 1 echo Incorrect errorlevel
1950 call :CheckExist testfile
1951
1952 rem simple case, wildcards, no concatenation
1953 copy file* testfile >nul 2>&1
1954 if errorlevel 1 echo Incorrect errorlevel
1955 call :CheckExist testfile
1956
1957 rem simple case, wildcards, and concatenation
1958 echo ddddd > fred
1959 copy file*+fred testfile >nul 2>&1
1960 if errorlevel 1 echo Incorrect errorlevel
1961 call :CheckExist testfile
1962
1963 rem simple case, wildcards, and concatenation
1964 copy fred+file* testfile >nul 2>&1
1965 if errorlevel 1 echo Incorrect errorlevel
1966 call :CheckExist testfile
1967
1968 rem Calculate destination name
1969 copy fred+file* dir1 >nul 2>&1
1970 if errorlevel 1 echo Incorrect errorlevel
1971 call :CheckExist dir1\fred
1972
1973 rem Calculate destination name
1974 copy fred+file* dir1\ >nul 2>&1
1975 if errorlevel 1 echo Incorrect errorlevel
1976 call :CheckExist dir1\fred
1977
1978 rem Calculate destination name (none supplied)
1979 cd dir1
1980 copy ..\fred+..\file* >nul 2>&1
1981 if errorlevel 1 echo Incorrect errorlevel
1982 call :CheckExist fred
1983
1984 copy ..\fr*+..\file1  >nul 2>&1
1985 if errorlevel 1 echo Incorrect errorlevel
1986 call :CheckExist fred
1987 cd ..
1988
1989 rem ******************************************************************
1990 rem ASCII and BINARY tests
1991 rem Note: hard coded numbers deliberate because need to ensure whether
1992 rem an additional EOF has been added or not. There is no way to handle
1993 rem EOFs in batch, so assume if a single byte appears, its an EOF!
1994 rem ******************************************************************
1995
1996 rem Confirm original sizes of file1,2,3
1997 call :CheckFileSize file1 5 file2 8 file3 11
1998
1999 cd dir1
2000
2001 rem ----------------------------------------------
2002 rem Show concatenation defaults copy to ascii mode
2003 rem ----------------------------------------------
2004 rem Simple default copy source to destination (should not append EOF 5)
2005 copy ..\file1 file1_default >nul 2>&1
2006 call :CheckFileSize file1_default 5
2007
2008 rem Simple binary copy source to destination (should not append EOF 5)
2009 copy /b ..\file1 file1_default2 >nul 2>&1
2010 call :CheckFileSize file1_default2 5
2011
2012 rem Simple ascii copy source to destination (should append EOF 5+1, 8+1, 11+1)
2013 copy /a ..\file1 file1_plus_eof >nul 2>&1
2014 call :CheckFileSize file1_plus_eof 6
2015 copy /a ..\file2 file2_plus_eof >nul 2>&1
2016 call :CheckFileSize file2_plus_eof 9
2017 copy /a ..\file3 file3_plus_eof >nul 2>&1
2018 call :CheckFileSize file3_plus_eof 12
2019
2020 rem Concat 2 files, ascii mode - (only one EOF on the end 5+8+1)
2021 copy /a ..\file1+..\file2 file12_plus_eof >nul 2>&1
2022 call :CheckFileSize file12_plus_eof 14
2023
2024 rem Concat 2 files, binary mode - (no EOF on the end 5+8)
2025 copy /b ..\file1+..\file2 file12_no_eof >nul 2>&1
2026 call :CheckFileSize file12_no_eof 13
2027
2028 rem Concat 2 files, default mode - (one EOF on the end 5+8+1)
2029 copy ..\file1+..\file2 file12_eof2 >nul 2>&1
2030 call :CheckFileSize file12_eof2 14
2031
2032 rem --------------------------------------------------------------
2033 rem Show ascii source copy stops at first EOF, binary does the lot
2034 rem --------------------------------------------------------------
2035 copy file1_plus_eof /b file1_binary_srccopy /b >nul 2>&1
2036 call :CheckFileSize file1_binary_srccopy 6
2037
2038 copy file1_plus_eof /a file1_ascii_srccopy /b >nul 2>&1
2039 call :CheckFileSize file1_ascii_srccopy 5
2040
2041 rem --------------------------------------------------------------
2042 rem Show results of concatenating files (ending in EOFs) and /a /b
2043 rem --------------------------------------------------------------
2044
2045 rem Default and ascii copy reads as ascii, stripping EOFs, so 6-1 + 9-1 + 12-1 + 1
2046 copy file1_plus_eof+file2_plus_eof+file3_plus_eof file123_default_copy >nul 2>&1
2047 call :CheckFileSize file123_default_copy 25
2048 copy /a file1_plus_eof+file2_plus_eof+file3_plus_eof file123_ascii_copy >nul 2>&1
2049 call :CheckFileSize file123_ascii_copy 25
2050
2051 rem In binary mode, we get 3 eofs, so 6 + 9 + 12 = 27
2052 copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_binary_copy >nul 2>&1
2053 call :CheckFileSize file123_binary_copy 27
2054
2055 rem We can select which we want the eofs from by postfixing it with /a or /b
2056 rem so here have first and third with eof, second as ascii 6 + 9-1 + 12
2057 copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy1 >nul 2>&1
2058 call :CheckFileSize file123_mixed_copy1 26
2059
2060 rem By postfixing the destination with /a, we ask for an ascii destination which appends EOF
2061 rem so here have first and third with eof, second as ascii 6 + 9-1 + 12 + extra EOF
2062 rem Note the delta between this and the previous one also shows that the destination
2063 rem ascii/binary is inherited from the last /a or /b on the line
2064 copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy2 /a >nul 2>&1
2065 call :CheckFileSize file123_mixed_copy2 27
2066
2067 rem so here have second with eof, first and third as ascii 6-1 + 9 + 12-1
2068 rem Note the delta between the next two also shows that the destination ascii/binary is
2069 rem inherited from the last /a or /b on the line, so the first has an extra EOF
2070 copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy3 >nul 2>&1
2071 call :CheckFileSize file123_mixed_copy3 26
2072 copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy4 /b >nul 2>&1
2073 call :CheckFileSize file123_mixed_copy4 25
2074
2075 rem -------------------------------------------------------------------------------------------
2076 rem This shows when concatenating, an ascii destination always adds on an EOF but when we
2077 rem are not concatenating, its a direct copy regardless of destination if being read as binary
2078 rem -------------------------------------------------------------------------------------------
2079
2080 rem All 3 have eof's, plus an extra = 6 + 9 + 12 + eof
2081 copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_mixed_copy5 /a >nul 2>&1
2082 call :CheckFileSize file123_mixed_copy5 28
2083
2084 rem All 2 have eof's, plus an extra = 6 + 12 + eof
2085 copy /b file1_plus_eof + file3_plus_eof file123_mixed_copy6 /a >nul 2>&1
2086 call :CheckFileSize file123_mixed_copy6 19
2087
2088 rem One file has EOF, but doesn't get an extra one, i.e. 6
2089 copy /b file1_plus_eof file123_mixed_copy7 /a >nul 2>&1
2090 call :CheckFileSize file123_mixed_copy7 6
2091
2092 rem Syntax means concatenate so ascii destination kicks in
2093 copy /b file1_plus_eof* file123_mixed_copy8 /a >nul 2>&1
2094 call :CheckFileSize file123_mixed_copy8 7
2095
2096 del *.* /q
2097 cd ..
2098
2099 rem ---------------------------------------
2100 rem Error combinations
2101 rem ---------------------------------------
2102 rem Specify source directory but name is a file
2103 call :setError 0
2104 copy file1\ dir1\ >NUL 2>&1
2105 if errorlevel 1 echo Passed: errorlevel invalid check 1
2106 if not errorlevel 1 echo Failed: errorlevel invalid check 1
2107 call :CheckNotExist dir1\file1
2108
2109 rem Overwrite same file
2110 call :setError 0
2111 copy file1 file1 >NUL 2>&1
2112 if errorlevel 1 echo Passed: errorlevel invalid check 2
2113 if not errorlevel 1 echo Failed: errorlevel invalid check 2
2114
2115 rem Supply same file identified as a directory
2116 call :setError 0
2117 copy file1 file1\ >NUL 2>&1
2118 if errorlevel 1 echo Passed: errorlevel invalid check 3
2119 if not errorlevel 1 echo Failed: errorlevel invalid check 3
2120
2121 cd ..
2122 rd foobar2 /s /q
2123
2124 echo ------------ Testing setlocal/endlocal ------------
2125 call :setError 0
2126 rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test section
2127 mkdir foobar & cd foobar
2128 echo --- enable/disable extensions
2129 setlocal DisableEXTensions
2130 echo ErrLev: %ErrorLevel%
2131 endlocal
2132 echo ErrLev: %ErrorLevel%
2133 echo @echo off> tmp.cmd
2134 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
2135 rem Enabled by default
2136 cmd /C tmp.cmd
2137 cmd /E:OfF /C tmp.cmd
2138 cmd /e:oN /C tmp.cmd
2139
2140 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
2141 echo --- setlocal with corresponding endlocal
2142 rem %CD% does not tork on NT4 so use the following workaround
2143 for /d %%i in (.) do set CURDIR=%%~dpnxi
2144 echo @echo off> test.cmd
2145 echo echo %%VAR%%>> test.cmd
2146 echo setlocal>> test.cmd
2147 echo set VAR=localval>> test.cmd
2148 echo md foobar2>> test.cmd
2149 echo cd foobar2>> test.cmd
2150 echo echo %%VAR%%>> test.cmd
2151 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
2152 echo endlocal>> test.cmd
2153 echo echo %%VAR%%>> test.cmd
2154 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
2155 set VAR=globalval
2156 call test.cmd
2157 echo %VAR%
2158 for /d %%i in (.) do echo %%~dpnxi
2159 cd /d %curdir%
2160 rd foobar2
2161 set VAR=
2162 echo --- setlocal with no corresponding endlocal
2163 echo @echo off> test.cmd
2164 echo echo %%VAR%%>> test.cmd
2165 echo setlocal>> test.cmd
2166 echo set VAR=localval>> test.cmd
2167 echo md foobar2>> test.cmd
2168 echo cd foobar2>> test.cmd
2169 echo echo %%VAR%%>> test.cmd
2170 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
2171 set VAR=globalval
2172 rem %CD% does not tork on NT4 so use the following workaround
2173 for /d %%i in (.) do set CURDIR=%%~dpnxi
2174 call test.cmd
2175 echo %VAR%
2176 for /d %%i in (.) do echo %%~dpnxi
2177 cd /d %curdir%
2178 rd foobar2
2179 set VAR=
2180 echo --- setlocal within same batch program
2181 set var1=one
2182 set var2=
2183 set var3=
2184 rem %CD% does not tork on NT4 so use the following workaround
2185 for /d %%i in (.) do set CURDIR=%%~dpnxi
2186 setlocal
2187 set var2=two
2188 mkdir foobar2
2189 cd foobar2
2190 setlocal
2191 set var3=three
2192 if "%var1%"=="one" echo Var1 ok 1
2193 if "%var2%"=="two" echo Var2 ok 2
2194 if "%var3%"=="three" echo Var3 ok 3
2195 for /d %%i in (.) do set curdir2=%%~dpnxi
2196 if "%curdir2%"=="%curdir%\foobar2" echo Directory is ok 1
2197 endlocal
2198 if "%var1%"=="one" echo Var1 ok 1
2199 if "%var2%"=="two" echo Var2 ok 2
2200 if "%var3%"=="" echo Var3 ok 3
2201 for /d %%i in (.) do set curdir2=%%~dpnxi
2202 if "%curdir2%"=="%curdir%\foobar2" echo Directory is ok 2
2203 endlocal
2204 if "%var1%"=="one" echo Var1 ok 1
2205 if "%var2%"=="" echo Var2 ok 2
2206 if "%var3%"=="" echo Var3 ok 3
2207 for /d %%i in (.) do set curdir2=%%~dpnxi
2208 if "%curdir2%"=="%curdir%" echo Directory is ok 3
2209 rd foobar2 /s /q
2210 set var1=
2211
2212 echo --- Mismatched set and end locals
2213 mkdir foodir2 2>nul
2214 mkdir foodir3 2>nul
2215 mkdir foodir4 2>nul
2216 rem %CD% does not tork on NT4 so use the following workaround
2217 for /d %%i in (.) do set curdir=%%~dpnxi
2218
2219 echo @echo off> 2set1end.cmd
2220 echo echo %%VAR%%>> 2set1end.cmd
2221 echo setlocal>> 2set1end.cmd
2222 echo set VAR=2set1endvalue1>> 2set1end.cmd
2223 echo cd ..\foodir3>> 2set1end.cmd
2224 echo setlocal>> 2set1end.cmd
2225 echo set VAR=2set1endvalue2>> 2set1end.cmd
2226 echo cd ..\foodir4>> 2set1end.cmd
2227 echo endlocal>> 2set1end.cmd
2228 echo echo %%VAR%%>> 2set1end.cmd
2229 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 2set1end.cmd
2230
2231 echo @echo off> 1set2end.cmd
2232 echo echo %%VAR%%>> 1set2end.cmd
2233 echo setlocal>> 1set2end.cmd
2234 echo set VAR=1set2endvalue1>> 1set2end.cmd
2235 echo cd ..\foodir3>> 1set2end.cmd
2236 echo endlocal>> 1set2end.cmd
2237 echo echo %%VAR%%>> 1set2end.cmd
2238 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
2239 echo endlocal>> 1set2end.cmd
2240 echo echo %%VAR%%>> 1set2end.cmd
2241 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
2242
2243 echo --- Extra setlocal in called batch
2244 set VAR=value1
2245 rem -- setlocal1 == this batch, should never be used inside a called routine
2246 setlocal
2247 set var=value2
2248 cd foodir2
2249 call %curdir%\2set1end.cmd
2250 echo Finished:
2251 echo %VAR%
2252 for /d %%i in (.) do echo %%~dpnxi
2253 endlocal
2254 echo %VAR%
2255 for /d %%i in (.) do echo %%~dpnxi
2256 cd /d %curdir%
2257
2258 echo --- Extra endlocal in called batch
2259 set VAR=value1
2260 rem -- setlocal1 == this batch, should never be used inside a called routine
2261 setlocal
2262 set var=value2
2263 cd foodir2
2264 call %curdir%\1set2end.cmd
2265 echo Finished:
2266 echo %VAR%
2267 for /d %%i in (.) do echo %%~dpnxi
2268 endlocal
2269 echo %VAR%
2270 for /d %%i in (.) do echo %%~dpnxi
2271 cd /d %curdir%
2272
2273 echo --- endlocal in called function rather than batch pgm is ineffective
2274 @echo off
2275 set var=1
2276 set var2=1
2277 setlocal
2278 set var=2
2279 call :endlocalroutine
2280 echo %var%
2281 endlocal
2282 echo %var%
2283 goto :endlocalfinished
2284 :endlocalroutine
2285 echo %var%
2286 endlocal
2287 echo %var%
2288 setlocal
2289 set var2=2
2290 endlocal
2291 echo %var2%
2292 endlocal
2293 echo %var%
2294 echo %var2%
2295 goto :eof
2296 :endlocalfinished
2297 echo %var%
2298
2299 set var=
2300 set var2=
2301 cd .. & rd /q/s foobar
2302
2303 echo ------------ Testing Errorlevel ------------
2304 rem WARNING: Do *not* add tests using ErrorLevel after this section
2305 should_not_exist 2> nul > nul
2306 echo %ErrorLevel%
2307 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
2308 rem See http://www.robvanderwoude.com/exit.php
2309 call :setError 1
2310 echo %ErrorLevel%
2311 if errorlevel 2 echo errorlevel too high, bad
2312 if errorlevel 1 echo errorlevel just right, good
2313 if errorlevel 01 echo errorlevel with leading zero just right, good
2314 if errorlevel -1 echo errorlevel with negative number OK
2315 if errorlevel 0x1 echo hexa should not be recognized!
2316 if errorlevel 1a echo invalid error level recognized!
2317 call :setError 0
2318 echo abc%ErrorLevel%def
2319 if errorlevel 1 echo errorlevel nonzero, bad
2320 if not errorlevel 1 echo errorlevel zero, good
2321 if not errorlevel 0x1 echo hexa should not be recognized!
2322 if not errorlevel 1a echo invalid error level recognized!
2323 rem Now verify that setting a real variable hides its magic variable
2324 set errorlevel=7
2325 echo %ErrorLevel% should be 7
2326 if errorlevel 7 echo setting var worked too well, bad
2327 call :setError 3
2328 echo %ErrorLevel% should still be 7
2329
2330 echo ------------ Testing GOTO ------------
2331 if a==a goto dest1
2332 :dest1
2333 echo goto with no leading space worked
2334 if b==b goto dest2
2335  :dest2
2336 echo goto with a leading space worked
2337 if c==c goto dest3
2338         :dest3
2339 echo goto with a leading tab worked
2340 if d==d goto dest4
2341 :dest4@space@
2342 echo goto with a following space worked
2343
2344 echo ------------ Testing PATH ------------
2345 set backup_path=%path%
2346 set path=original
2347 path
2348 path try2
2349 path
2350 path=try3
2351 path
2352 set path=%backup_path%
2353 set backup_path=
2354
2355 echo ------------ Testing combined CALLs/GOTOs ------------
2356 echo @echo off>foo.cmd
2357 echo goto :eof>>foot.cmd
2358 echo :eof>>foot.cmd
2359 echo echo world>>foo.cmd
2360
2361 echo @echo off>foot.cmd
2362 echo echo cheball>>foot.cmd
2363 echo.>>foot.cmd
2364 echo call :bar>>foot.cmd
2365 echo if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmd
2366 echo goto :eof>>foot.cmd
2367 echo.>>foot.cmd
2368 echo :bar>>foot.cmd
2369 echo echo barbare>>foot.cmd
2370 echo goto :eof>>foot.cmd
2371
2372 call foo.cmd
2373 call foot
2374 call :bar
2375 del foo.cmd
2376 rem Script execution stops after the following line
2377 foot deleteMe
2378 call :foo
2379 call :foot
2380 goto :endFuns
2381
2382 :foot
2383 echo foot
2384
2385 :foo
2386 echo foo
2387 goto :eof
2388
2389 :endFuns
2390
2391 :bar
2392 echo bar
2393 call :foo
2394
2395 :baz
2396 echo baz
2397 goto :eof
2398
2399 echo Final message is not output since earlier 'foot' processing stops script execution
2400 echo Do NOT add any tests below this line
2401
2402 echo ------------ Done, jumping to EOF -----------
2403 goto :eof
2404 rem Subroutine to set errorlevel and return
2405 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
2406 :setError
2407 exit /B %1
2408 rem This line runs under cmd in windows NT 4, but not in more modern versions.