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