cmd/tests: Add tests for mixed echo modes.
[wine.git] / programs / cmd / tests / test_builtins.cmd
blob1250e899fe7a621aca29060d758a3da5ce1238e5
1 echo Tests for cmd's builtin commands
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
30 @echo off
31 echo ------------ Testing 'echo' [OFF] --------------
32 echo word
33 echo 'singlequotedword'
34 echo "doublequotedword"
35 @echo at-echoed-word
36 echo "/?"
37 echo.
38 echo .
39 echo.word
40 echo .word
41 echo:
42 echo :
43 echo:word
44 echo :word
45 echo on again
46 echo word@space@
47 echo word@space@@space@
48 echo word
49 echo@tab@word
50 echo@tab@word @tab@
51 echo@tab@word@tab@@space@
52 @tab@echo word
53 echo @tab@word
54 echo @tab@word
55 echo@tab@@tab@word
57 echo ------------ Testing mixed echo modes --------------
58 echo @echo on> mixedEchoModes.cmd
59 echo if 1==1 echo foo>> mixedEchoModes.cmd
60 echo if 1==1 @echo bar>> mixedEchoModes.cmd
61 echo @echo off>> mixedEchoModes.cmd
62 echo if 1==1 echo foo2>> mixedEchoModes.cmd
63 echo if 1==1 @echo bar2>> mixedEchoModes.cmd
64 type mixedEchoModes.cmd
65 cmd /c mixedEchoModes.cmd
66 del mixedEchoModes.cmd
68 echo ------------ Testing rem --------------
69 rem Hello
70 rem Hello
71 rem Hello || foo
72 rem echo lol
73 rem echo foo & echo bar
74 rem @tab@ Hello
75 rem@tab@ Hello
76 rem@tab@echo foo & echo bar
77 @echo on
78 rem Hello
79 rem Hello
80 rem Hello || foo
81 rem echo lol
82 rem echo foo & echo bar
83 rem @tab@ Hello
84 rem@tab@ Hello
85 rem@tab@echo foo & echo bar
86 @echo off
88 echo ------------ Testing redirection operators --------------
89 mkdir foobar & cd foobar
90 echo ...stdout redirection
91 echo foo>foo
92 type foo
93 echo foo 1> foo
94 type foo
95 echo foo@tab@1> foo
96 type foo
97 echo foo 1>@tab@foo
98 type foo
99 echo foo@tab@1>@tab@foo
100 type foo
101 echo foo7 7> foo
102 type foo
103 echo foo9 9> foo
104 type foo
105 echo foo1> foo
106 type foo
107 echo foo11> foo
108 type foo
109 echo foo12> foo
110 type foo
111 del foo
112 echo1>foo
113 type foo
114 echo ...stdout appending
115 echo foo>foo
116 echo foo >>foo
117 type foo
118 del foo
119 echo foob >> foo
120 type foo
121 echo fooc 1>>foo
122 type foo
123 echo food1>>foo
124 type foo
125 echo food2>>foo
126 type foo
127 del foo
128 echo food21>>foo
129 type foo
130 del foo
131 echo foo> foo
132 echo foo7 7>> foo || (echo not supported & del foo)
133 if exist foo (type foo) else echo not supported
134 echo ...redirections within IF statements
135 if 1==1 echo foo1>bar
136 type bar & del bar
137 if 1==1 (echo foo2>bar) else echo baz2>bar
138 type bar & del bar
139 if 1==1 (echo foo3) else echo baz3>bar
140 type bar || echo file does not exist, ok
141 if 1==1 (echo foo4>bar) else echo baz4>bar
142 type bar & del bar
143 if 1==0 (echo foo5>bar) else echo baz5>bar
144 type bar & del bar
145 if 1==0 (echo foo6) else echo baz6 1>bar
146 type bar & del bar
147 if 1==0 (echo foo7 1>bar) else echo baz7>bar
148 type bar & del bar
149 if 1==0 (echo foo8 1>bar) else echo baz8>bak
150 type bak
151 if 1==1 (echo foo>bar & echo baz)
152 type bar
153 if 1==1 (
154 echo foo>bar
155 echo baz
157 type bar
158 (if 1==1 (echo A) else echo B) > C
159 type C
160 (if 1==0 (echo A) else echo B) > C
161 type C
162 (if 1==0 (echo A > B) else echo C)
163 cd .. & rd /s/q foobar
165 echo ------------ Testing ^^ escape character --------------
166 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
167 echo ^hell^o, world
168 echo hell^o, world
169 echo hell^^o, world
170 echo hell^^^o, world
171 mkdir foobar
172 echo baz> foobar\baz
173 type foobar\baz
174 type foobar^\baz
175 rd /s/q foobar
176 echo foo ^| echo bar
177 echo foo ^& echo bar
178 call :setError 0
179 echo bak ^&& echo baz 2> nul
180 echo %ErrorLevel%
181 echo foo ^> foo
182 echo ^<> foo
183 type foo
184 del foo
185 set FOO=oof
186 echo ff^%FOO%
187 set FOO=bar ^| baz
188 set FOO
189 rem FIXME: echoing %FOO% gives an error (baz not recognized) but prematurely
190 rem exits the script on windows; redirecting stdout and/or stderr doesn't help
191 echo %ErrorLevel%
192 call :setError 0
193 set FOO=bar ^^^| baz
194 set FOO
195 echo %FOO%
196 echo %ErrorLevel%
197 set FOO=
199 echo ------------ Testing 'set' --------------
200 call :setError 0
201 set FOOBAR 2> nul > nul
202 echo %ErrorLevel%
203 set FOOBAR = baz
204 echo %ErrorLevel%
205 echo %FOOBAR%FOOBAR not defined
206 echo %FOOBAR %
207 set FOOBAR 2> nul
208 set FOOBAR = baz2
209 echo %ErrorLevel%
210 echo %fOObAr %
211 set FOOBAR= bar
212 echo %ErrorLevel%
213 echo %FOOBAR%
214 set FOO
215 set FOOBAR=
216 set FOOB
217 echo %FOOBAR%FOOBAR not defined
218 set FOOBAR =
219 set FOOBA 2> nul > nul
220 echo %ErrorLevel%
221 set FOO=bar
222 echo %FOO%
223 set FOO=foo
224 set BAR=bar
225 echo %FOO%%BAR%
226 set BAR=
227 set FOO=
228 set FOO=%FOO%
229 echo %FOO%FOO not defined
230 set BAZ%=bazbaz
231 set BA
232 echo %BAZ%%
233 set BAZ%=
234 echo set "FOO=bar" should not include the quotes in the variable value
235 set "FOO=bar"
236 echo %FOO%
237 set@tab@FOO=foo
238 echo %FOO%
239 set@tab@FOO=
240 echo '%FOO%'
241 set FOO=foo@space@
242 echo '%FOO%'
243 set FOO=foo@tab@
244 echo '%FOO%'
245 set FOO=
247 echo ------------ Testing variable expansion --------------
248 call :setError 0
249 echo ~dp0 should be directory containing batch file
250 echo %~dp0
251 mkdir dummydir
252 cd dummydir
253 echo %~dp0
254 cd ..
255 rmdir dummydir
256 echo CD value %CD%
257 echo %%
258 echo P%
259 echo %P
260 echo %UNKNOWN%S
261 echo P%UNKNOWN%
262 echo P%UNKNOWN%S
263 echo %ERRORLEVEL
264 echo %ERRORLEVEL%
265 echo %ERRORLEVEL%%ERRORLEVEL%
266 echo %ERRORLEVEL%ERRORLEVEL%
267 echo %ERRORLEVEL%%
268 echo %ERRORLEVEL%%%
269 echo P%ERRORLEVEL%
270 echo %ERRORLEVEL%S
271 echo P%ERRORLEVEL%S
273 echo ------------ Testing variable substrings --------------
274 set VAR=qwerty
275 echo %VAR:~0,1%
276 echo %VAR:~0,3%
277 echo %VAR:~2,2%
278 echo '%VAR:~-2,3%'
279 echo '%VAR:~-2,1%'
280 echo %VAR:~2,-1%
281 echo %VAR:~2,-3%
282 echo '%VAR:~-2,-4%'
283 echo %VAR:~-3,-2%
284 set VAR=
286 echo ------------ Testing variable substitution --------------
287 echo ...in FOR variables
288 for %%i in ("A B" C) do echo %%i
289 rem quotes removal
290 for %%i in ("A B" C) do echo '%%~i'
291 rem fully qualified path
292 for %%f in ("C D" E) do echo %%~ff
293 rem drive letter
294 for %%i in ("F G" H) do echo %%~di
295 rem path
296 for %%d in ("I J" K) do echo %%~pd
297 rem filename
298 for %%i in ("L M" N) do echo %%~ni
299 rem file extension
300 for %%i in ("O. P.OOL" Q.TABC hello) do echo '%%~xi'
301 rem path with short path names
302 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do echo '%%~sI'
303 rem file attribute
304 for %%i in ("U V" W) do echo '%%~ai'
305 echo foo> foo
306 for %%i in (foo) do echo '%%~ai'
307 del foo
308 rem file date/time
309 rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar...
310 for %%i in ("a b" c) do echo '%%~ti'
311 rem file size
312 rem Similar issues as above
313 for %%i in ("a b" c) do echo '%%~zi'
314 rem combined options
315 for %%i in ("d e" f) do echo %%~dpi
316 for %%i in ("g h" i) do echo %%~sdi
317 for %%i in ("g h" i) do echo %%~dsi
318 for %%i in ("j k" l.eh) do echo '%%~xsi'
320 echo ...in parameters
321 for %%i in ("A B" C) do call :echoFun %%i
322 rem quotes removal
323 for %%i in ("A B" C) do call :echoFunQ %%i
324 rem fully qualified path
325 for %%f in ("C D" E) do call :echoFunF %%f
326 rem drive letter
327 for %%i in ("F G" H) do call :echoFunD %%i
328 rem path
329 for %%d in ("I J" K) do call :echoFunP %%d
330 rem filename
331 for %%i in ("L M" N) do call :echoFunN %%i
332 rem file extension
333 for %%i in ("O. P.OOL" Q.TABC hello) do call :echoFunX %%i
334 rem path with short path names
335 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do call :echoFunS %%I
336 rem NT4 aborts whole script execution when encountering ~a, ~t and ~z substitutions, preventing full testing
337 rem combined options
338 for %%i in ("d e" f) do call :echoFunDP %%i
339 for %%i in ("g h" i) do call :echoFunSD %%i
340 for %%i in ("g h" i) do call :echoFunDS %%i
341 for %%i in ("j k" l.eh) do call :echoFunXS %%i
343 goto :endEchoFuns
344 :echoFun
345 echo %1
346 goto :eof
348 :echoFunQ
349 echo '%~1'
350 goto :eof
352 :echoFunF
353 echo %~f1
354 goto :eof
356 :echoFunD
357 echo %~d1
358 goto :eof
360 :echoFunP
361 echo %~p1
362 goto :eof
364 :echoFunN
365 echo %~n1
366 goto :eof
368 :echoFunX
369 echo '%~x1'
370 goto :eof
372 :echoFunS
373 rem some NT4 workaround
374 set VAR='%~s1'
375 echo %VAR%
376 set VAR=
377 goto :eof
379 :echoFunDP
380 echo %~dp1
381 goto :eof
383 :echoFunSD
384 echo %~sd1
385 goto :eof
387 :echoFunDS
388 echo %~ds1
389 goto :eof
391 :echoFunXS
392 echo '%~xs1'
393 goto :eof
394 :endEchoFuns
396 echo ------------ Testing variable delayed expansion --------------
397 rem NT4 doesn't support this
398 echo ...default mode (load-time expansion)
399 set FOO=foo
400 echo %FOO%
401 echo !FOO!
402 if %FOO% == foo (
403 set FOO=bar
404 if %FOO% == bar (echo bar) else echo foo
407 set FOO=foo
408 if %FOO% == foo (
409 set FOO=bar
410 if !FOO! == bar (echo bar) else echo foo
413 echo ...runtime (delayed) expansion mode
414 setlocal EnableDelayedExpansion
415 set FOO=foo
416 echo %FOO%
417 echo !FOO!
418 if %FOO% == foo (
419 set FOO=bar
420 if %FOO% == bar (echo bar) else echo foo
423 set FOO=foo
424 if %FOO% == foo (
425 set FOO=bar
426 if !FOO! == bar (echo bar) else echo foo
428 echo %ErrorLevel%
429 setlocal DisableDelayedExpansion
430 echo %ErrorLevel%
431 set FOO=foo
432 echo %FOO%
433 echo !FOO!
434 set FOO=
435 echo ...using /V cmd flag
436 echo @echo off> tmp.cmd
437 echo set FOO=foo>> tmp.cmd
438 echo echo %%FOO%%>> tmp.cmd
439 echo echo !FOO!>> tmp.cmd
440 echo set FOO=>> tmp.cmd
441 cmd /V:ON /C tmp.cmd
442 cmd /V:OfF /C tmp.cmd
443 del tmp.cmd
445 echo ------------ Testing conditional execution --------------
446 echo ...unconditional ^&
447 call :setError 123 & echo foo1
448 echo bar2 & echo foo2
449 mkdir foobar & cd foobar
450 echo > foobazbar
451 cd .. & rd /s/q foobar
452 if exist foobazbar (
453 echo foobar not deleted!
454 cd ..
455 rd /s/q foobar
456 ) else echo foobar deleted
457 echo ...on success conditional ^&^&
458 call :setError 456 && echo foo3 > foo3
459 if exist foo3 (
460 echo foo3 created
461 del foo3
462 ) else echo foo3 not created
463 echo bar4 && echo foo4
464 echo ...on failure conditional ^|^|
465 call :setError 789 || echo foo5
466 echo foo6 || echo bar6 > bar6
467 if exist bar6 (
468 echo bar6 created
469 del bar6
472 echo ------------ Testing cd ------------
473 mkdir foobar
474 cd foobar
475 echo blabla > singleFile
476 dir /b
477 echo Current dir: %CD%
479 cd ..
481 cd foobar@space@
483 cd ..
485 cd @space@foobar
487 cd..
489 cd foobar
490 cd..@space@
492 if not exist foobar (cd ..)
493 cd foobar
494 cd@tab@..@tab@@space@@tab@
496 if not exist foobar (cd ..)
497 cd foobar
498 mkdir "bar bak"
499 cd "bar bak"
501 cd ..
502 cd bar bak
504 cd "bar bak@space@"@tab@@space@
506 cd ..\..
508 rd /Q/s foobar
509 mkdir foobar
510 cd /d@tab@foobar
512 cd ..
513 rd /q/s foobar
515 echo ------------ Testing type ------------
516 echo bar> foobaz
517 @echo on
518 type foobaz
519 echo ***
520 @echo off
521 type foobaz@tab@
522 echo ***
523 del foobaz
525 echo ------------ Testing NUL ------------
526 md foobar & cd foobar
527 rem NUL file (non) creation + case insensitivity
528 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
529 echo > bar
530 echo foo > NUL
531 dir /b /a-d
532 echo foo > nul
533 dir /b /a-d
534 echo foo > NuL
535 @tab@dir /b@tab@/a-d
536 del bar
537 rem NUL not special everywhere
538 call :setError 123
539 echo NUL> foo
540 if not exist foo (echo foo should have been created) else (
541 type foo
542 del foo
544 rem Empty file creation
545 copy nul foo > nul
546 if exist foo (
547 echo foo created
548 del foo
549 type foo
550 ) else (
551 echo ***
553 cd .. & rd foobar
555 echo ------------ Testing if/else --------------
556 echo if/else should work with blocks
557 if 0 == 0 (
558 echo if seems to work
559 ) else (
560 echo if seems to be broken
562 if 1 == 0 (
563 echo else seems to be broken
564 ) else (
565 echo else seems to work
567 if /c==/c (
568 echo if seems not to detect /c as parameter
569 ) else (
570 echo parameter detection seems to be broken
572 echo Testing case sensitivity with and without /i option
573 if bar==BAR echo if does not default to case sensitivity
574 if not bar==BAR echo if seems to default to case sensitivity
575 if /i foo==FOO echo if /i seems to work
576 if /i not foo==FOO echo if /i seems to be broken
577 if /I foo==FOO echo if /I seems to work
578 if /I not foo==FOO echo if /I seems to be broken
579 if@tab@1==1 echo doom
580 if @tab@1==1 echo doom
581 if 1==1 (echo doom) else@tab@echo quake
582 if@tab@not @tab@1==@tab@0 @tab@echo lol
583 if 1==0@tab@(echo doom) else echo quake
584 if 1==0 (echo doom)@tab@else echo quake
585 if 1==0 (echo doom) else@tab@echo quake
587 echo -----------Testing for -----------
588 echo ...plain FOR
589 for %%i in (A B C) do echo %%i
590 for %%i in (A B C) do echo %%I
591 for %%i in (A B C) do echo %%j
592 for %%i in (A B C) do call :forTestFun1 %%i
593 for %%i in (1,4,1) do echo %%i
594 for %%i in (A, B,C) do echo %%i
595 for %%i in (X) do echo %%i
596 for@tab@%%i in (X2) do echo %%i
597 for %%i in@tab@(X3) do echo %%i
598 for %%i in (@tab@ foo@tab@) do echo %%i
599 for@tab@ %%i in@tab@(@tab@M) do echo %%i
600 for %%i@tab@in (X)@tab@do@tab@echo %%i
601 for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
602 for %%i in (`echo A B`) do echo %%i
603 for %%i in ('echo A B') do echo %%i
604 for %%i in ("echo A B") do echo %%i
605 for %%i in ("A B" C) do echo %%i
606 goto :endForTestFun1
607 :forTestFun1
608 echo %1
609 goto :eof
610 :endForTestFun1
611 echo ...imbricated FORs
612 for %%i in (X) do (
613 for %%j in (Y) do (
614 echo %%i %%j))
615 for %%i in (X) do (
616 for %%I in (Y) do (
617 echo %%i %%I))
618 for %%i in (A B) do (
619 for %%j in (C D) do (
620 echo %%i %%j))
621 for %%i in (A B) do (
622 for %%j in (C D) do (
623 call :forTestFun2 %%i %%j ))
624 goto :endForTestFun2
625 :forTestFun2
626 echo %1 %2
627 goto :eof
628 :endForTestFun2
629 mkdir foobar & cd foobar
630 mkdir foo
631 mkdir bar
632 mkdir baz
633 echo > bazbaz
634 echo ...basic wildcards
635 for %%i in (ba*) do echo %%i
636 echo ...for /d
637 for /d %%i in (baz foo bar) do echo %%i
638 rem FIXME for /d incorrectly parses when wildcards are used
639 rem for /d %%i in (bazb*) do echo %%i
640 rem FIXME can't test wildcard expansion here since it's listed in directory
641 rem order, and not in alphabetic order.
642 rem Proper testing would need a currently missing "sort" program implementation.
643 rem for /d %%i in (ba*) do echo %%i>> tmp
644 rem sort < tmp
645 rem del tmp
646 rem for /d %%i in (?a*) do echo %%i>> tmp
647 rem sort < tmp
648 rem del tmp
649 rem for /d %%i in (*) do echo %%i>> tmp
650 rem sort < tmp
651 rem del tmp
652 cd .. & rd /s/Q foobar
653 echo ...for /L
654 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
655 for /L %%i in (1,2,0) do echo %%i
656 for@tab@/L %%i in (1,2,0) do echo %%i
657 for /L %%i in (1,2,6) do echo %%i
658 for /l %%i in (1 ,2,6) do echo %%i
659 for /L %%i in (a,2,3) do echo %%i
660 for /L %%i in (1,2,-1) do echo %%i
661 for /L %%i in (-4,-1,-1) do echo %%i
662 for /L %%i in (1,-2,-2) do echo %%i
663 for /L %%i in (1,2,a) do echo %%i
664 echo ErrorLevel %ErrorLevel%
665 for /L %%i in (1,a,b) do echo %%i
666 echo ErrorLevel %ErrorLevel%
667 rem FIXME: following test cases cannot be currently tested due to an inconsistent/buggy 'for /L' parsing.
668 rem for /L %%i in (a,2,b) do echo %%i
669 rem for /L %%i in (1,1,1) do echo %%i
670 rem for /L %%i in (1,-2,-1) do echo %%i
671 rem for /L %%i in (-1,-1,-1) do echo %%i
672 rem for /L %%i in (1,2, 3) do echo %%i
673 echo ...for /a
674 rem No output when using "set expr" syntax, unless in interactive mode
675 rem Need to use "set envvar=expr" to use in a batch script
676 echo ......individual operations
677 set var=0
678 set /a var=1 +2 & echo %var%
679 set /a var=1 +-2 & echo %var%
680 set /a var=1 --2 & echo %var%
681 set /a var=2* 3 & echo %var%
682 set /a var=-2* -5 & echo %var%
683 set /a var=12/3 & echo %var%
684 set /a var=13/3 & echo %var%
685 set /a var=-13/3 & echo %var%
686 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
687 set /a var=5 %% 5 & echo %var%
688 set /a var=5 %% 3 & echo %var%
689 set /a var=5 %% -3 & echo %var%
690 set /a var=-5 %% -3 & echo %var%
691 set /a var=1 ^<^< 0 & echo %var%
692 set /a var=1 ^<^< 2 & echo %var%
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=9 ^>^> 0 & echo %var%
697 set /a var=9 ^>^> 2 & echo %var%
698 set /a var=9 ^>^> -2 & echo %var%
699 set /a var=-9 ^>^> -2 & echo %var%
700 set /a var=-9 ^>^> 2 & echo %var%
701 set /a var=5 ^& 0 & echo %var%
702 set /a var=5 ^& 1 & echo %var%
703 set /a var=5 ^& 3 & echo %var%
704 set /a var=5 ^& 4 & echo %var%
705 set /a var=5 ^& 1 & echo %var%
706 set /a var=5 ^| 0 & echo %var%
707 set /a var=5 ^| 1 & echo %var%
708 set /a var=5 ^| 3 & echo %var%
709 set /a var=5 ^| 4 & echo %var%
710 set /a var=5 ^| 1 & echo %var%
711 set /a var=5 ^^ 0 & echo %var%
712 set /a var=5 ^^ 1 & echo %var%
713 set /a var=5 ^^ 3 & echo %var%
714 set /a var=5 ^^ 4 & echo %var%
715 set /a var=5 ^^ 1 & echo %var%
716 echo ......precedence and grouping
717 set /a var=4 + 2*3 & echo %var%
718 set /a var=(4+2)*3 & echo %var%
719 set /a var=4 * 3/5 & echo %var%
720 set /a var=(4 * 3)/5 & echo %var%
721 set /a var=4 * 5 %% 4 & echo %var%
722 set /a var=4 * (5 %% 4) & echo %var%
723 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
724 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
725 echo ......octal and hexadecimal
726 set /a var=0xf + 3 & echo %var%
727 set /a var=0xF + 3 & echo %var%
728 set /a var=015 + 2 & echo %var%
729 set /a var=3, 8+3,0 & echo %var%
730 echo ......variables
731 set /a var=foo=3, foo+1 & echo %var%
732 if defined foo (echo %foo%) else (
733 echo foo not defined
735 set /a var=foo=3, foo+=1 & echo %var%
736 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
737 set /a var=foo*= foo & echo %var%
738 set /a var=whateverNonExistingVar & echo %var%
739 set /a var=whateverNonExistingVar + bar & echo %var%
740 set /a var=foo -= foo + 7 & echo %var%
741 set /a var=foo /= 3 + 2 & echo %var%
742 set /a var=foo=5, foo %%=2 & echo %var%
743 set /a var=foo ^<^<= 2 & echo %var%
744 set /a var=foo ^>^>= 2 & echo %var%
745 set /a var=foo ^&= 2 & echo %var%
746 set /a var=foo=5, foo ^|= 2 & echo %var%
747 set /a var=foo=5, foo ^^= 2 & echo %var%
748 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
749 set foo=
750 set bar=
751 set var=
752 echo ...for /F
753 mkdir foobar & cd foobar
754 echo ......string argument
755 for /F %%i in ("a b c") do echo %%i
756 for /f %%i in ("a ") do echo %%i
757 for /f %%i in ("a") do echo %%i
758 fOr /f %%i in (" a") do echo %%i
759 for /f %%i in (" a ") do echo %%i
760 echo ......fileset argument
761 echo .........basic blank handling
762 echo a b c>foo
763 for /f %%i in (foo) do echo %%i
764 echo a >foo
765 for /f %%i in (foo) do echo %%i
766 echo a>foo
767 for /f %%i in (foo) do echo %%i
768 echo a>foo
769 for /f %%i in (foo) do echo %%i
770 echo a >foo
771 for /f %%i in (foo) do echo %%i
772 echo. > foo
773 for /f %%i in (foo) do echo %%i
774 echo. >> foo
775 echo b > foo
776 for /f %%i in (foo) do echo %%i
777 echo .........multi-line with empty lines
778 echo a Z f> foo
779 echo. >> foo
780 echo.>> foo
781 echo b bC>> foo
782 echo c>> foo
783 echo. >> foo
784 for /f %%b in (foo) do echo %%b
785 echo .........multiple files
786 echo q w > bar
787 echo.>> bar
788 echo kkk>>bar
789 for /f %%k in (foo bar) do echo %%k
790 for /f %%k in (bar foo) do echo %%k
791 rem echo ......command argument
792 rem Not implemented on NT4
793 rem FIXME: Not testable right now in wine: not implemented and would need
794 rem preliminary grep-like program implementation (e.g. like findstr or fc) even
795 rem for a simple todo_wine test
796 rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported
797 rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported
798 echo ......eol option
799 for /f "eol=@" %%i in (" ad") do echo %%i
800 for /f "eol=@" %%i in (" z@y") do echo %%i
801 for /f "eol=|" %%i in ("a|d") do echo %%i
802 for /f "eol=@" %%i in ("@y") do echo %%i > output_file
803 if not exist output_file (echo no output) else (del output_file)
804 for /f "eol==" %%i in ("=y") do echo %%i > output_file
805 if not exist output_file (echo no output) else (del output_file)
806 echo ......delims option
807 for /f "delims=|" %%i in ("a|d") do echo %%i
808 for /f "delims=|" %%i in ("a |d") do echo %%i
809 for /f "delims=|" %%i in ("a d|") do echo %%i
810 for /f "delims=| " %%i in ("a d|") do echo %%i
811 for /f "delims==" %%i in ("C r=d|") do echo %%i
812 for /f "delims=" %%i in ("foo bar baz") do echo %%i
813 for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi
814 echo ......skip option
815 echo a > foo
816 echo b >> foo
817 echo c >> foo
818 for /f "skip=2" %%i in (foo) do echo %%i
819 for /f "skip=3" %%i in (foo) do echo %%i > output_file
820 if not exist output_file (echo no output) else (del output_file)
821 for /f "skip=4" %%i in (foo) do echo %%i > output_file
822 if not exist output_file (echo no output) else (del output_file)
823 cd ..
824 rd /s/q foobar
826 echo -----------Testing del /a-----------
827 del /f/q *.test > nul
828 echo r > r.test
829 attrib +r r.test
830 echo not-r > not-r.test
832 if not exist not-r.test echo not-r.test not found before delete, bad
833 del /a:-r *.test
834 if not exist not-r.test echo not-r.test not found after delete, good
836 if not exist r.test echo r.test not found before delete, bad
837 if exist r.test echo r.test found before delete, good
838 del /a:r *.test
839 if not exist r.test echo r.test not found after delete, good
840 if exist r.test echo r.test found after delete, bad
842 echo ------------ Testing del /q --------------
843 mkdir del_q_dir
844 cd del_q_dir
845 echo abc > file1
846 echo abc > file2.dat
847 rem If /q doesn't work, cmd will prompt and the test case should hang
848 del /q * > nul
849 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
850 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
851 cd ..
852 rmdir del_q_dir
854 echo ------------ Testing del /s --------------
855 mkdir "foo bar"
856 cd "foo bar"
857 echo hi > file1.dat
858 echo there > file2.dat
859 echo bub > file3.dat
860 echo bye > "file with spaces.dat"
861 cd ..
862 del /s file1.dat > nul
863 del file2.dat /s > nul
864 del "file3.dat" /s > nul
865 del "file with spaces.dat" /s > nul
866 cd "foo bar"
867 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
868 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
869 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
870 if exist "file with spaces.dat" del "file with spaces.dat"
871 cd ..
872 rmdir "foo bar"
874 echo ----------- Testing mkdir -----------
875 call :setError 0
876 rem md and mkdir are synonymous
877 mkdir foobar
878 echo %ErrorLevel%
879 rmdir foobar
880 md foobar
881 echo %ErrorLevel%
882 rmdir foobar
883 rem Creating an already existing directory/file must fail
884 mkdir foobar
885 md foobar
886 echo %ErrorLevel%
887 rmdir foobar
888 echo > foobar
889 mkdir foobar
890 echo %ErrorLevel%
891 del foobar
892 rem Multi-level path creation
893 mkdir foo
894 echo %ErrorLevel%
895 mkdir foo\bar\baz
896 echo %ErrorLevel%
897 cd foo
898 echo %ErrorLevel%
899 cd bar
900 echo %ErrorLevel%
901 cd baz
902 echo %ErrorLevel%
903 echo > ..\..\bar2
904 mkdir ..\..\..\foo\bar2
905 echo %ErrorLevel%
906 del ..\..\bar2
907 mkdir ..\..\..\foo\bar2
908 echo %ErrorLevel%
909 rmdir ..\..\..\foo\bar2
910 cd ..
911 rmdir baz
912 cd ..
913 rmdir bar
914 cd ..
915 rmdir foo
916 echo %ErrorLevel%
917 rem Trailing backslashes
918 mkdir foo\\\\
919 echo %ErrorLevel%
920 if exist foo (rmdir foo & echo dir created
921 ) else ( echo dir not created )
922 echo %ErrorLevel%
923 rem Invalid chars
924 mkdir ?
925 echo mkdir ? gives errorlevel %ErrorLevel%
926 call :setError 0
927 mkdir ?\foo
928 echo mkdir ?\foo gives errorlevel %ErrorLevel%
929 call :setError 0
930 mkdir foo\?
931 echo mkdir foo\? gives errorlevel %ErrorLevel%
932 if exist foo (rmdir foo & echo ok, foo created
933 ) else ( echo foo not created )
934 call :setError 0
935 mkdir foo\bar\?
936 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
937 call :setError 0
938 if not exist foo (
939 echo bad, foo not created
940 ) else (
941 cd foo
942 if exist bar (
943 echo ok, foo\bar created
944 rmdir bar
946 cd ..
947 rmdir foo
949 rem multiples directories at once
950 mkdir foobaz & cd foobaz
951 mkdir foo bar\baz foobar
952 if exist foo (echo foo created) else echo foo not created!
953 if exist bar (echo bar created) else echo bar not created!
954 if exist foobar (echo foobar created) else echo foobar not created!
955 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
956 cd .. & rd /s/q foobaz
957 call :setError 0
958 mkdir foo\*
959 echo mkdir foo\* errorlevel %ErrorLevel%
960 if exist foo (rmdir foo & echo ok, foo created
961 ) else ( echo bad, foo not created )
963 echo ----------- Testing rmdir -----------
964 call :setError 0
965 rem rd and rmdir are synonymous
966 mkdir foobar
967 rmdir foobar
968 echo %ErrorLevel%
969 if not exist foobar echo dir removed
970 mkdir foobar
971 rd foobar
972 echo %ErrorLevel%
973 if not exist foobar echo dir removed
974 rem Removing nonexistent directory
975 rmdir foobar
976 echo %ErrorLevel%
977 rem Removing single-level directories
978 echo > foo
979 rmdir foo
980 echo %ErrorLevel%
981 if exist foo echo file not removed
982 del foo
983 mkdir foo
984 echo > foo\bar
985 rmdir foo
986 echo %ErrorLevel%
987 if exist foo echo non-empty dir not removed
988 del foo\bar
989 mkdir foo\bar
990 rmdir foo
991 echo %ErrorLevel%
992 if exist foo echo non-empty dir not removed
993 rmdir foo\bar
994 rmdir foo
995 rem Recursive rmdir
996 mkdir foo\bar\baz
997 rmdir /s /Q foo
998 if not exist foo (
999 echo recursive rmdir succeeded
1000 ) else (
1001 rd foo\bar\baz
1002 rd foo\bar
1003 rd foo
1005 mkdir foo\bar\baz
1006 echo foo > foo\bar\brol
1007 rmdir /s /Q foo
1008 if not exist foo (
1009 echo recursive rmdir succeeded
1010 ) else (
1011 rd foo\bar\baz
1012 del foo\bar\brol
1013 rd foo\bar
1014 rd foo
1016 rem multiples directories at once
1017 mkdir foobaz & cd foobaz
1018 mkdir foo
1019 mkdir bar\baz
1020 mkdir foobar
1021 rd /s/q foo bar foobar
1022 if not exist foo (echo foo removed) else echo foo not removed!
1023 if not exist bar (echo bar removed) else echo bar not removed!
1024 if not exist foobar (echo foobar removed) else echo foobar not removed!
1025 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
1026 cd .. & rd /s/q foobaz
1028 echo ------------ Testing attrib --------------
1029 rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications
1030 mkdir foobar & cd foobar
1031 echo foo original contents> foo
1032 attrib foo
1033 echo > bar
1034 echo ... read-only attribute
1035 rem Read-only files cannot be altered or deleted, unless forced
1036 attrib +R foo
1037 attrib foo
1038 dir /Ar /B
1039 echo bar>> foo
1040 type foo
1041 del foo > NUL 2>&1
1042 if exist foo (
1043 echo Read-only file not deleted
1044 ) else (
1045 echo Should not delete read-only file!
1047 del /F foo
1048 if not exist foo (
1049 echo Read-only file forcibly deleted
1050 ) else (
1051 echo Should delete read-only file with del /F!
1052 attrib -r foo
1053 del foo
1055 cd .. & rd /s/q foobar
1056 echo ... recursive behaviour
1057 mkdir foobar\baz & cd foobar
1058 echo > level1
1059 echo > whatever
1060 echo > baz\level2
1061 attrib baz\level2
1062 cd ..
1063 attrib +R l*vel? /S > nul 2>&1
1064 cd foobar
1065 attrib level1
1066 attrib baz\level2
1067 echo > bar
1068 attrib bar
1069 cd .. & rd /s/q foobar
1070 echo ... folders processing
1071 mkdir foobar
1072 attrib foobar
1073 cd foobar
1074 mkdir baz
1075 echo toto> baz\toto
1076 attrib +r baz /s /d > nul 2>&1
1077 attrib baz
1078 attrib baz\toto
1079 echo lulu>>baz\toto
1080 type baz\toto
1081 echo > baz\lala
1082 rem Oddly windows allows file creation in a read-only directory...
1083 if exist baz\lala (echo file created in read-only dir) else echo file not created
1084 cd .. & rd /s/q foobar
1086 echo ------------ Testing CALL --------------
1087 mkdir foobar & cd foobar
1088 rem External script
1089 echo echo foo %%1> foo.cmd
1090 call foo
1091 call foo.cmd 8
1092 echo echo %%1 %%2 > foo.cmd
1093 call foo.cmd foo
1094 call foo.cmd foo bar
1095 call foo.cmd foo ""
1096 call foo.cmd "" bar
1097 call foo.cmd foo ''
1098 call foo.cmd '' bar
1099 del foo.cmd
1100 rem Internal routines
1101 call :testRoutine :testRoutine
1102 goto :endTestRoutine
1103 :testRoutine
1104 echo bar %1
1105 goto :eof
1106 :endTestRoutine
1108 call :testRoutineArgs foo
1109 call :testRoutineArgs foo bar
1110 call :testRoutineArgs foo ""
1111 call :testRoutineArgs "" bar
1112 call :testRoutineArgs foo ''
1113 call :testRoutineArgs '' bar
1114 goto :endTestRoutineArgs
1115 :testRoutineArgs
1116 echo %1 %2
1117 goto :eof
1118 :endTestRoutineArgs
1120 rem Should work for builtins...
1121 call mkdir foo
1122 echo %ErrorLevel%
1123 if exist foo (echo foo created) else echo foo should exist!
1124 rmdir foo
1125 set FOOBAZ_VAR=foobaz
1126 call echo Should expand %FOOBAZ_VAR%
1127 set FOOBAZ_VAR=
1128 echo>batfile
1129 call dir /b
1130 echo>robinfile
1131 if 1==1 call del batfile
1132 dir /b
1133 if exist batfile echo batfile shouldn't exist
1134 rem ... but not for 'if' or 'for'
1135 call if 1==1 echo bar 2> nul
1136 echo %ErrorLevel%
1137 call :setError 0
1138 call for %%i in (foo bar baz) do echo %%i 2> nul
1139 echo %ErrorLevel%
1140 rem First look for programs in the path before trying a builtin
1141 echo echo non-builtin dir> dir.cmd
1142 call dir /b
1143 cd .. & rd /s/q foobar
1145 echo ------------ Testing setlocal/endlocal ------------
1146 call :setError 0
1147 rem Note: setlocal EnableDelayedExtension already tested in the variable delayed expansion test section
1148 mkdir foobar & cd foobar
1149 echo ...enable/disable extensions
1150 setlocal DisableEXTensions
1151 echo ErrLev: %ErrorLevel%
1152 endlocal
1153 echo ErrLev: %ErrorLevel%
1154 echo @echo off> tmp.cmd
1155 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
1156 rem Enabled by default
1157 cmd /C tmp.cmd
1158 cmd /E:OfF /C tmp.cmd
1159 cmd /e:oN /C tmp.cmd
1161 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
1162 echo ...setlocal with corresponding endlocal
1163 echo @echo off> test.cmd
1164 echo echo %%VAR%%>> test.cmd
1165 echo setlocal>> test.cmd
1166 echo set VAR=localval>> test.cmd
1167 echo echo %%VAR%%>> test.cmd
1168 echo endlocal>> test.cmd
1169 echo echo %%VAR%%>> test.cmd
1170 set VAR=globalval
1171 call test.cmd
1172 echo %VAR%
1173 set VAR=
1174 echo ...setlocal with no corresponding endlocal
1175 echo @echo off> test.cmd
1176 echo echo %%VAR%%>> test.cmd
1177 echo setlocal>> test.cmd
1178 echo set VAR=localval>> test.cmd
1179 echo echo %%VAR%%>> test.cmd
1180 set VAR=globalval
1181 call test.cmd
1182 echo %VAR%
1183 set VAR=
1184 cd .. & rd /q/s foobar
1186 echo -----------Testing Errorlevel-----------
1187 rem WARNING: Do *not* add tests using ErrorLevel after this section
1188 should_not_exist 2> nul > nul
1189 echo %ErrorLevel%
1190 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
1191 rem See http://www.robvanderwoude.com/exit.php
1192 call :setError 1
1193 echo %ErrorLevel%
1194 if errorlevel 2 echo errorlevel too high, bad
1195 if errorlevel 1 echo errorlevel just right, good
1196 call :setError 0
1197 echo abc%ErrorLevel%def
1198 if errorlevel 1 echo errorlevel nonzero, bad
1199 if not errorlevel 1 echo errorlevel zero, good
1200 rem Now verify that setting a real variable hides its magic variable
1201 set errorlevel=7
1202 echo %ErrorLevel% should be 7
1203 if errorlevel 7 echo setting var worked too well, bad
1204 call :setError 3
1205 echo %ErrorLevel% should still be 7
1207 echo -----------Testing GOTO-----------
1208 if a==a goto dest1
1209 :dest1
1210 echo goto with no leading space worked
1211 if b==b goto dest2
1212 :dest2
1213 echo goto with a leading space worked
1214 if c==c goto dest3
1215 :dest3
1216 echo goto with a leading tab worked
1217 if d==d goto dest4
1218 :dest4@space@
1219 echo goto with a following space worked
1221 echo -----------Done, jumping to EOF-----------
1222 goto :eof
1223 rem Subroutine to set errorlevel and return
1224 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
1225 :setError
1226 exit /B %1
1227 rem This line runs under cmd in windows NT 4, but not in more modern versions.