cmd: Fix a FOR parsing bug when multiple spaces follow an IN.
[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 word@space@
19 echo word@space@@space@
20
21 @echo off
22 echo ------------ Testing 'echo' [OFF] --------------
23 echo word
24 echo 'singlequotedword'
25 echo "doublequotedword"
26 @echo at-echoed-word
27 echo "/?"
28 echo.
29 echo .
30 echo.word
31 echo .word
32 echo:
33 echo :
34 echo:word
35 echo :word
36 echo word@space@
37 echo word@space@@space@
38
39 echo ------------ Testing redirection operators --------------
40 mkdir foobar & cd foobar
41 echo ...stdout redirection
42 echo foo>foo
43 type foo
44 echo foo 1> foo
45 type foo
46 echo foo1> foo
47 type foo
48 echo foo11> foo
49 type foo
50 echo foo12> foo
51 type foo
52 echo ...stdout appending
53 echo foo>foo
54 echo foo >>foo
55 type foo
56 del foo
57 echo foob >> foo
58 type foo
59 echo fooc 1>>foo
60 type foo
61 echo food1>>foo
62 type foo
63 echo food2>>foo
64 type foo
65 del foo
66 echo food21>>foo
67 type foo
68 cd ..
69 rd /s/q foobar
70
71 echo ------------ Testing ^^ escape character --------------
72 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
73 echo ^hell^o, world
74 echo hell^o, world
75 echo hell^^o, world
76 echo hell^^^o, world
77 mkdir foobar
78 echo baz> foobar\baz
79 type foobar\baz
80 type foobar^\baz
81 rd /s/q foobar
82 echo foo ^| echo bar
83 echo foo ^& echo bar
84 call :setError 0
85 echo bak ^&& echo baz 2> nul
86 echo %ErrorLevel%
87 echo foo ^> foo
88 echo ^<> foo
89 type foo
90 del foo
91 set FOO=oof
92 echo ff^%FOO%
93 set FOO=bar ^| baz
94 set FOO
95 rem FIXME: echoing %FOO% gives an error (baz not recognized) but prematurely
96 rem exits the script on windows; redirecting stdout and/or stderr doesn't help
97 echo %ErrorLevel%
98 call :setError 0
99 set FOO=bar ^^^| baz
100 set FOO
101 echo %FOO%
102 echo %ErrorLevel%
103 set FOO=
104
105 echo ------------ Testing 'set' --------------
106 call :setError 0
107 set FOOBAR 2> nul > nul
108 echo %ErrorLevel%
109 set FOOBAR =  baz
110 echo %ErrorLevel%
111 echo %FOOBAR%FOOBAR not defined
112 echo %FOOBAR %
113 set FOOBAR 2> nul
114 set FOOBAR =  baz2
115 echo %ErrorLevel%
116 echo %fOObAr %
117 set FOOBAR= bar
118 echo %ErrorLevel%
119 echo %FOOBAR%
120 set FOO
121 set FOOBAR=
122 set FOOB
123 echo %FOOBAR%FOOBAR not defined
124 set FOOBAR =
125 set FOOBA 2> nul > nul
126 echo %ErrorLevel%
127 set FOO=bar
128 echo %FOO%
129 set FOO=foo
130 set BAR=bar
131 echo %FOO%%BAR%
132 set BAR=
133 set FOO=
134 set FOO=%FOO%
135 echo %FOO%FOO not defined
136 set BAZ%=bazbaz
137 set BA
138 echo %BAZ%%
139 set BAZ%=
140 echo set "FOO=bar" should not include the quotes in the variable value
141 set "FOO=bar"
142 echo %FOO%
143 set FOO=
144
145 echo ------------ Testing variable expansion --------------
146 call :setError 0
147 echo ~dp0 should be directory containing batch file
148 echo %~dp0
149 mkdir dummydir
150 cd dummydir
151 echo %~dp0
152 cd ..
153 rmdir dummydir
154 echo CD value %CD%
155 echo %%
156 echo P%
157 echo %P
158 echo %UNKNOWN%S
159 echo P%UNKNOWN%
160 echo P%UNKNOWN%S
161 echo %ERRORLEVEL
162 echo %ERRORLEVEL%
163 echo %ERRORLEVEL%%ERRORLEVEL%
164 echo %ERRORLEVEL%ERRORLEVEL%
165 echo %ERRORLEVEL%%
166 echo %ERRORLEVEL%%%
167 echo P%ERRORLEVEL%
168 echo %ERRORLEVEL%S
169 echo P%ERRORLEVEL%S
170
171 echo ------------ Testing variable delayed expansion --------------
172 rem NT4 doesn't support this
173 echo ...default mode (load-time expansion)
174 set FOO=foo
175 echo %FOO%
176 echo !FOO!
177 if %FOO% == foo (
178     set FOO=bar
179     if %FOO% == bar (echo bar) else echo foo
180 )
181
182 set FOO=foo
183 if %FOO% == foo (
184     set FOO=bar
185     if !FOO! == bar (echo bar) else echo foo
186 )
187
188 echo ...runtime (delayed) expansion mode
189 setlocal EnableDelayedExpansion
190 set FOO=foo
191 echo %FOO%
192 echo !FOO!
193 if %FOO% == foo (
194     set FOO=bar
195     if %FOO% == bar (echo bar) else echo foo
196 )
197
198 set FOO=foo
199 if %FOO% == foo (
200     set FOO=bar
201     if !FOO! == bar (echo bar) else echo foo
202 )
203 echo %ErrorLevel%
204 setlocal DisableDelayedExpansion
205 echo %ErrorLevel%
206 set FOO=foo
207 echo %FOO%
208 echo !FOO!
209 set FOO=
210 echo ...using /V cmd flag
211 echo @echo off> tmp.cmd
212 echo set FOO=foo>> tmp.cmd
213 echo echo %%FOO%%>> tmp.cmd
214 echo echo !FOO!>> tmp.cmd
215 echo set FOO=>> tmp.cmd
216 cmd /V:ON /C tmp.cmd
217 cmd /V:OfF /C tmp.cmd
218 del tmp.cmd
219
220 echo ------------ Testing conditional execution --------------
221 echo ...unconditional ^&
222 call :setError 123 & echo foo1
223 echo bar2 & echo foo2
224 mkdir foobar & cd foobar
225 echo > foobazbar
226 cd .. & rd /s/q foobar
227 if exist foobazbar (
228     echo foobar not deleted!
229     cd ..
230     rd /s/q foobar
231 ) else echo foobar deleted
232 echo ...on success conditional ^&^&
233 call :setError 456 && echo foo3 > foo3
234 if exist foo3 (
235     echo foo3 created
236     del foo3
237 ) else echo foo3 not created
238 echo bar4 && echo foo4
239 echo ...on failure conditional ^|^|
240 call :setError 789 || echo foo5
241 echo foo6 || echo bar6 > bar6
242 if exist bar6 (
243     echo bar6 created
244     del bar6
245 )
246
247 echo ------------ Testing type ------------
248 echo bar> foobaz
249 @echo on
250 type foobaz
251 echo ***
252 @echo off
253 type foobaz
254 echo ***
255 del foobaz
256
257 echo ------------ Testing NUL ------------
258 md foobar & cd foobar
259 rem NUL file (non) creation + case insensitivity
260 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
261 echo > bar
262 echo foo > NUL
263 dir /b /a-d
264 echo foo > nul
265 dir /b /a-d
266 echo foo > NuL
267 dir /b /a-d
268 del bar
269 rem NUL not special everywhere
270 call :setError 123
271 echo NUL> foo
272 if not exist foo (echo foo should have been created) else (
273     type foo
274     del foo
275 )
276 rem Empty file creation
277 copy nul foo > nul
278 if exist foo (
279     echo foo created
280     del foo
281     type foo
282 ) else (
283     echo ***
284 )
285 cd ..
286 rd foobar
287
288 echo ------------ Testing if/else --------------
289 echo if/else should work with blocks
290 if 0 == 0 (
291   echo if seems to work
292 ) else (
293   echo if seems to be broken
294 )
295 if 1 == 0 (
296   echo else seems to be broken
297 ) else (
298   echo else seems to work
299 )
300 if /c==/c (
301   echo if seems not to detect /c as parameter
302 ) else (
303   echo parameter detection seems to be broken
304 )
305 echo Testing case sensitivity with and without /i option
306 if bar==BAR echo if does not default to case sensitivity
307 if not bar==BAR echo if seems to default to case sensitivity
308 if /i foo==FOO echo if /i seems to work
309 if /i not foo==FOO echo if /i seems to be broken
310 if /I foo==FOO echo if /I seems to work
311 if /I not foo==FOO echo if /I seems to be broken
312
313 echo -----------Testing for -----------
314 echo ...plain FOR
315 for %%i in (A B C) do echo %%i
316 for %%i in (A B C) do echo %%I
317 for %%i in (A B C) do echo %%j
318 for %%i in (A B C) do call :forTestFun1 %%i
319 for %%i in (1,4,1) do echo %%i
320 for %%i in (A, B,C) do echo %%i
321 for %%i in  (X) do echo %%i
322 goto :endForTestFun1
323 :forTestFun1
324 echo %1
325 goto :eof
326 :endForTestFun1
327 echo ...imbricated FORs
328 for %%i in (X) do (
329     for %%j in (Y) do (
330         echo %%i %%j))
331 for %%i in (X) do (
332     for %%I in (Y) do (
333         echo %%i %%I))
334 for %%i in (A B) do (
335     for %%j in (C D) do (
336         echo %%i %%j))
337 for %%i in (A B) do (
338     for %%j in (C D) do (
339         call :forTestFun2 %%i %%j ))
340 goto :endForTestFun2
341 :forTestFun2
342 echo %1 %2
343 goto :eof
344 :endForTestFun2
345 mkdir foobar & cd foobar
346 mkdir foo
347 mkdir bar
348 mkdir baz
349 echo > bazbaz
350 echo ...basic wildcards
351 for %%i in (ba*) do echo %%i
352 echo ...for /d
353 for /d %%i in (baz foo bar) do echo %%i
354 rem FIXME for /d incorrectly parses when wildcards are used
355 rem for /d %%i in (bazb*) do echo %%i
356 rem FIXME can't test wildcard expansion here since it's listed in directory
357 rem order, and not in alphabetic order.
358 rem Proper testing would need a currently missing "sort" program implementation.
359 rem for /d %%i in (ba*) do echo %%i>> tmp
360 rem sort < tmp
361 rem del tmp
362 rem for /d %%i in (?a*) do echo %%i>> tmp
363 rem sort < tmp
364 rem del tmp
365 rem for /d %%i in (*) do echo %%i>> tmp
366 rem sort < tmp
367 rem del tmp
368 cd ..
369 rd /s/Q foobar
370 echo ...for /L
371 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
372 for /L %%i in (1,2,0) do echo %%i
373 for /L %%i in (1,2,6) do echo %%i
374 for /l %%i in (1 ,2,6) do echo %%i
375 for /L %%i in (a,2,3) do echo %%i
376 for /L %%i in (1,2,-1) do echo %%i
377 for /L %%i in (-4,-1,-1) do echo %%i
378 for /L %%i in (1,-2,-2) do echo %%i
379 for /L %%i in (1,2,a) do echo %%i
380 echo ErrorLevel %ErrorLevel%
381 for /L %%i in (1,a,b) do echo %%i
382 echo ErrorLevel %ErrorLevel%
383 rem FIXME: following test cases cannot be currently tested due to an inconsistent/buggy 'for /L' parsing.
384 rem for /L %%i in (a,2,b) do echo %%i
385 rem for /L %%i in (1,1,1) do echo %%i
386 rem for /L %%i in (1,-2,-1) do echo %%i
387 rem for /L %%i in (-1,-1,-1) do echo %%i
388 rem for /L %%i in (1,2, 3) do echo %%i
389 echo ...for /a
390 rem No output when using "set expr" syntax, unless in interactive mode
391 rem Need to use "set envvar=expr" to use in a batch script
392 echo ......individual operations
393 set var=0
394 set /a var=1 +2 & echo %var%
395 set /a var=1 +-2 & echo %var%
396 set /a var=1 --2 & echo %var%
397 set /a var=2* 3 & echo %var%
398 set /a var=-2* -5 & echo %var%
399 set /a var=12/3 & echo %var%
400 set /a var=13/3 & echo %var%
401 set /a var=-13/3 & echo %var%
402 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
403 set /a var=5 %% 5 & echo %var%
404 set /a var=5 %% 3 & echo %var%
405 set /a var=5 %% -3 & echo %var%
406 set /a var=-5 %% -3 & echo %var%
407 set /a var=1 ^<^< 0 & echo %var%
408 set /a var=1 ^<^< 2 & echo %var%
409 set /a var=1 ^<^< -2 & echo %var%
410 set /a var=-1 ^<^< -2 & echo %var%
411 set /a var=-1 ^<^< 2 & echo %var%
412 set /a var=9 ^>^> 0 & echo %var%
413 set /a var=9 ^>^> 2 & echo %var%
414 set /a var=9 ^>^> -2 & echo %var%
415 set /a var=-9 ^>^> -2 & echo %var%
416 set /a var=-9 ^>^> 2 & echo %var%
417 set /a var=5 ^& 0 & echo %var%
418 set /a var=5 ^& 1 & echo %var%
419 set /a var=5 ^& 3 & echo %var%
420 set /a var=5 ^& 4 & echo %var%
421 set /a var=5 ^& 1 & echo %var%
422 set /a var=5 ^| 0 & echo %var%
423 set /a var=5 ^| 1 & echo %var%
424 set /a var=5 ^| 3 & echo %var%
425 set /a var=5 ^| 4 & echo %var%
426 set /a var=5 ^| 1 & echo %var%
427 set /a var=5 ^^ 0 & echo %var%
428 set /a var=5 ^^ 1 & echo %var%
429 set /a var=5 ^^ 3 & echo %var%
430 set /a var=5 ^^ 4 & echo %var%
431 set /a var=5 ^^ 1 & echo %var%
432 echo ......precedence and grouping
433 set /a var=4 + 2*3 & echo %var%
434 set /a var=(4+2)*3 & echo %var%
435 set /a var=4 * 3/5 & echo %var%
436 set /a var=(4 * 3)/5 & echo %var%
437 set /a var=4 * 5 %% 4 & echo %var%
438 set /a var=4 * (5 %% 4) & echo %var%
439 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
440 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
441 echo ......octal and hexadecimal
442 set /a var=0xf + 3 & echo %var%
443 set /a var=0xF + 3 & echo %var%
444 set /a var=015 + 2 & echo %var%
445 set /a var=3, 8+3,0 & echo %var%
446 echo ......variables
447 set /a var=foo=3, foo+1 & echo %var%
448 if defined foo (echo %foo%) else (
449     echo foo not defined
450 )
451 set /a var=foo=3, foo+=1 & echo %var%
452 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
453 set /a var=foo*= foo & echo %var%
454 set /a var=whateverNonExistingVar & echo %var%
455 set /a var=whateverNonExistingVar + bar & echo %var%
456 set /a var=foo -= foo + 7 & echo %var%
457 set /a var=foo /= 3 + 2 & echo %var%
458 set /a var=foo=5, foo %%=2 & echo %var%
459 set /a var=foo ^<^<= 2 & echo %var%
460 set /a var=foo ^>^>= 2 & echo %var%
461 set /a var=foo ^&= 2 & echo %var%
462 set /a var=foo=5, foo ^|= 2 & echo %var%
463 set /a var=foo=5, foo ^^= 2 & echo %var%
464 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
465 set foo=
466 set bar=
467 set var=
468
469 echo -----------Testing del /a-----------
470 del /f/q *.test > nul
471 echo r > r.test
472 attrib +r r.test
473 echo not-r > not-r.test
474
475 if not exist not-r.test echo not-r.test not found before delete, bad
476 del /a:-r *.test
477 if not exist not-r.test echo not-r.test not found after delete, good
478
479 if not exist r.test echo r.test not found before delete, bad
480 if exist r.test echo r.test found before delete, good
481 del /a:r *.test
482 if not exist r.test echo r.test not found after delete, good
483 if exist r.test echo r.test found after delete, bad
484
485 echo ------------ Testing del /q --------------
486 mkdir del_q_dir
487 cd del_q_dir
488 echo abc > file1
489 echo abc > file2.dat
490 rem If /q doesn't work, cmd will prompt and the test case should hang
491 del /q * > nul
492 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
493 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
494 cd ..
495 rmdir del_q_dir
496
497 echo ------------ Testing del /s --------------
498 mkdir "foo bar"
499 cd "foo bar"
500 echo hi > file1.dat
501 echo there > file2.dat
502 echo bub > file3.dat
503 echo bye > "file with spaces.dat"
504 cd ..
505 del /s file1.dat > nul
506 del file2.dat /s > nul
507 del "file3.dat" /s > nul
508 del "file with spaces.dat" /s > nul
509 cd "foo bar"
510 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
511 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
512 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
513 if exist "file with spaces.dat" del "file with spaces.dat"
514 cd ..
515 rmdir "foo bar"
516
517 echo ----------- Testing mkdir -----------
518 call :setError 0
519 rem md and mkdir are synonymous
520 mkdir foobar
521 echo %ErrorLevel%
522 rmdir foobar
523 md foobar
524 echo %ErrorLevel%
525 rmdir foobar
526 rem Creating an already existing directory/file must fail
527 mkdir foobar
528 md foobar
529 echo %ErrorLevel%
530 rmdir foobar
531 echo > foobar
532 mkdir foobar
533 echo %ErrorLevel%
534 del foobar
535 rem Multi-level path creation
536 mkdir foo
537 echo %ErrorLevel%
538 mkdir foo\bar\baz
539 echo %ErrorLevel%
540 cd foo
541 echo %ErrorLevel%
542 cd bar
543 echo %ErrorLevel%
544 cd baz
545 echo %ErrorLevel%
546 echo > ..\..\bar2
547 mkdir ..\..\..\foo\bar2
548 echo %ErrorLevel%
549 del ..\..\bar2
550 mkdir ..\..\..\foo\bar2
551 echo %ErrorLevel%
552 rmdir ..\..\..\foo\bar2
553 cd ..
554 rmdir baz
555 cd ..
556 rmdir bar
557 cd ..
558 rmdir foo
559 echo %ErrorLevel%
560 rem Trailing backslashes
561 mkdir foo\\\\
562 echo %ErrorLevel%
563 if exist foo (rmdir foo & echo dir created
564 ) else ( echo dir not created )
565 echo %ErrorLevel%
566 rem Invalid chars
567 mkdir ?
568 echo mkdir ? gives errorlevel %ErrorLevel%
569 call :setError 0
570 mkdir ?\foo
571 echo mkdir ?\foo gives errorlevel %ErrorLevel%
572 call :setError 0
573 mkdir foo\?
574 echo mkdir foo\? gives errorlevel %ErrorLevel%
575 if exist foo (rmdir foo & echo ok, foo created
576 ) else ( echo foo not created )
577 call :setError 0
578 mkdir foo\bar\?
579 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
580 call :setError 0
581 if not exist foo (
582     echo bad, foo not created
583 ) else (
584     cd foo
585     if exist bar (
586         echo ok, foo\bar created
587         rmdir bar
588     )
589     cd ..
590     rmdir foo
591 )
592 rem multiples directories at once
593 mkdir foobaz & cd foobaz
594 mkdir foo bar\baz foobar
595 if exist foo (echo foo created) else echo foo not created!
596 if exist bar (echo bar created) else echo bar not created!
597 if exist foobar (echo foobar created) else echo foobar not created!
598 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
599 cd ..
600 rd /s/q foobaz
601 call :setError 0
602 mkdir foo\*
603 echo mkdir foo\* errorlevel %ErrorLevel%
604 if exist foo (rmdir foo & echo ok, foo created
605 ) else ( echo bad, foo not created )
606
607 echo ----------- Testing rmdir -----------
608 call :setError 0
609 rem rd and rmdir are synonymous
610 mkdir foobar
611 rmdir foobar
612 echo %ErrorLevel%
613 if not exist foobar echo dir removed
614 mkdir foobar
615 rd foobar
616 echo %ErrorLevel%
617 if not exist foobar echo dir removed
618 rem Removing nonexistent directory
619 rmdir foobar
620 echo %ErrorLevel%
621 rem Removing single-level directories
622 echo > foo
623 rmdir foo
624 echo %ErrorLevel%
625 if exist foo echo file not removed
626 del foo
627 mkdir foo
628 echo > foo\bar
629 rmdir foo
630 echo %ErrorLevel%
631 if exist foo echo non-empty dir not removed
632 del foo\bar
633 mkdir foo\bar
634 rmdir foo
635 echo %ErrorLevel%
636 if exist foo echo non-empty dir not removed
637 rmdir foo\bar
638 rmdir foo
639 rem Recursive rmdir
640 mkdir foo\bar\baz
641 rmdir /s /Q foo
642 if not exist foo (
643     echo recursive rmdir succeeded
644 ) else (
645     rd foo\bar\baz
646     rd foo\bar
647     rd foo
648 )
649 mkdir foo\bar\baz
650 echo foo > foo\bar\brol
651 rmdir /s /Q foo
652 if not exist foo (
653     echo recursive rmdir succeeded
654 ) else (
655     rd foo\bar\baz
656     del foo\bar\brol
657     rd foo\bar
658     rd foo
659 )
660 rem multiples directories at once
661 mkdir foobaz & cd foobaz
662 mkdir foo
663 mkdir bar\baz
664 mkdir foobar
665 rd /s/q foo bar foobar
666 if not exist foo (echo foo removed) else echo foo not removed!
667 if not exist bar (echo bar removed) else echo bar not removed!
668 if not exist foobar (echo foobar removed) else echo foobar not removed!
669 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
670 cd ..
671 rd /s/q foobaz
672
673 echo ------------ Testing CALL --------------
674 mkdir foobar & cd foobar
675 rem External script
676 echo echo foo %%1> foo.cmd
677 call foo
678 call foo.cmd 8
679 echo echo %%1 %%2 > foo.cmd
680 call foo.cmd foo
681 call foo.cmd foo bar
682 call foo.cmd foo ""
683 call foo.cmd "" bar
684 call foo.cmd foo ''
685 call foo.cmd '' bar
686 del foo.cmd
687 rem Internal routines
688 call :testRoutine :testRoutine
689 goto :endTestRoutine
690 :testRoutine
691 echo bar %1
692 goto :eof
693 :endTestRoutine
694
695 call :testRoutineArgs foo
696 call :testRoutineArgs foo bar
697 call :testRoutineArgs foo ""
698 call :testRoutineArgs ""  bar
699 call :testRoutineArgs foo ''
700 call :testRoutineArgs ''  bar
701 goto :endTestRoutineArgs
702 :testRoutineArgs
703 echo %1 %2
704 goto :eof
705 :endTestRoutineArgs
706
707 rem Should work for builtins...
708 call mkdir foo
709 echo %ErrorLevel%
710 if exist foo (echo foo created) else echo foo should exist!
711 rmdir foo
712 set FOOBAZ_VAR=foobaz
713 call echo Should expand %FOOBAZ_VAR%
714 set FOOBAZ_VAR=
715 echo>batfile
716 call dir /b
717 echo>robinfile
718 if 1==1 call del batfile
719 dir /b
720 if exist batfile echo batfile shouldn't exist
721 rem ... but not for 'if' or 'for'
722 call if 1==1 echo bar 2> nul
723 echo %ErrorLevel%
724 call :setError 0
725 call for %%i in (foo bar baz) do echo %%i 2> nul
726 echo %ErrorLevel%
727 rem First look for programs in the path before trying a builtin
728 echo echo non-builtin dir> dir.cmd
729 call dir /b
730 cd ..
731 rd /s/q foobar
732
733 echo ------------ Testing setlocal/endlocal ------------
734 call :setError 0
735 rem Note: setlocal EnableDelayedExtension already tested in the variable delayed expansion test section
736 mkdir foobar & cd foobar
737 echo ...enable/disable extensions
738 setlocal DisableEXTensions
739 echo ErrLev: %ErrorLevel%
740 endlocal
741 echo ErrLev: %ErrorLevel%
742 echo @echo off> tmp.cmd
743 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
744 rem Enabled by default
745 cmd /C tmp.cmd
746 cmd /E:OfF /C tmp.cmd
747 cmd /e:oN /C tmp.cmd
748
749 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
750 echo ...setlocal with corresponding endlocal
751 echo @echo off> test.cmd
752 echo echo %%VAR%%>> test.cmd
753 echo setlocal>> test.cmd
754 echo set VAR=localval>> test.cmd
755 echo echo %%VAR%%>> test.cmd
756 echo endlocal>> test.cmd
757 echo echo %%VAR%%>> test.cmd
758 set VAR=globalval
759 call test.cmd
760 echo %VAR%
761 set VAR=
762 echo ...setlocal with no corresponding endlocal
763 echo @echo off> test.cmd
764 echo echo %%VAR%%>> test.cmd
765 echo setlocal>> test.cmd
766 echo set VAR=localval>> test.cmd
767 echo echo %%VAR%%>> test.cmd
768 set VAR=globalval
769 call test.cmd
770 echo %VAR%
771 set VAR=
772 cd ..
773 rd /q/s foobar
774
775 echo -----------Testing Errorlevel-----------
776 rem WARNING: Do *not* add tests using ErrorLevel after this section
777 should_not_exist 2> nul > nul
778 echo %ErrorLevel%
779 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
780 rem See http://www.robvanderwoude.com/exit.php
781 call :setError 1
782 echo %ErrorLevel%
783 if errorlevel 2 echo errorlevel too high, bad
784 if errorlevel 1 echo errorlevel just right, good
785 call :setError 0
786 echo abc%ErrorLevel%def
787 if errorlevel 1 echo errorlevel nonzero, bad
788 if not errorlevel 1 echo errorlevel zero, good
789 rem Now verify that setting a real variable hides its magic variable
790 set errorlevel=7
791 echo %ErrorLevel% should be 7
792 if errorlevel 7 echo setting var worked too well, bad
793 call :setError 3
794 echo %ErrorLevel% should still be 7
795
796 echo -----------Testing GOTO-----------
797 if a==a goto dest1
798 :dest1
799 echo goto with no leading space worked
800 if b==b goto dest2
801  :dest2
802 echo goto with a leading space worked
803 if c==c goto dest3
804         :dest3
805 echo goto with a leading tab worked
806 if d==d goto dest4
807 :dest4@space@
808 echo goto with a following space worked
809
810 echo -----------Done, jumping to EOF-----------
811 goto :eof
812 rem Subroutine to set errorlevel and return
813 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
814 :setError
815 exit /B %1
816 rem This line runs under cmd in windows NT 4, but not in more modern versions.