1 echo Tests for cmd's builtin commands
4 echo ------------ Testing 'echo' [ON] ------------
6 echo 'singlequotedword'
7 echo "doublequotedword"
20 echo word@space@@space@
24 echo@tab@word@tab@@space@
36 echo ------------ Testing 'echo' [OFF] ------------
38 echo 'singlequotedword'
39 echo "doublequotedword"
52 echo word@space@@space@
56 echo@tab@word@tab@@space@
62 echo ------------ Testing mixed echo modes ------------
63 echo @echo on> mixedEchoModes.cmd
64 echo if 1==1 echo foo>> mixedEchoModes.cmd
65 echo if 1==1 @echo bar>> mixedEchoModes.cmd
66 echo @echo off>> mixedEchoModes.cmd
67 echo if 1==1 echo foo2>> mixedEchoModes.cmd
68 echo if 1==1 @echo bar2>> mixedEchoModes.cmd
69 type mixedEchoModes.cmd
70 cmd /c mixedEchoModes.cmd
71 del mixedEchoModes.cmd
73 echo ------------ Testing parameterization ------------
75 call :TestParm "a b c"
76 call :TestParm "a b"\c
77 call :TestParm a=~`+,.{}!+b
81 call :TestParm a[b]{c}(d)e
82 call :TestParm a&echo second line
83 call :TestParm a b,,,c
84 call :TestParm a==b;;c
93 echo ------------ Testing rem ------------
98 rem echo foo & echo bar
101 rem@tab@echo foo & echo bar
107 rem echo foo & echo bar
110 rem@tab@echo foo & echo bar
113 echo ------------ Testing redirection operators ------------
114 mkdir foobar & cd foobar
115 echo --- stdout redirection
124 echo foo@tab@1>@tab@foo
145 echo --- stdout appending
163 echo foo7 7>> foo || (echo not supported & del foo)
164 if exist foo (type foo) else echo not supported
165 echo --- redirections within IF statements
166 if 1==1 echo foo1>bar
169 if 1==1 (echo foo2>bar) else echo baz2>bar
171 if 1==1 (echo foo3) else echo baz3>bar
172 type bar || echo file does not exist, ok
173 if 1==1 (echo foo4>bar) else echo baz4>bar
175 if 1==0 (echo foo5>bar) else echo baz5>bar
177 if 1==0 (echo foo6) else echo baz6 1>bar
179 if 1==0 (echo foo7 1>bar) else echo baz7>bar
181 if 1==0 (echo foo8 1>bar) else echo baz8>bak
183 if 1==1 (echo foo>bar & echo baz)
190 (if 1==1 (echo A) else echo B) > C
192 (if 1==0 (echo A) else echo B) > C
194 (if 1==0 (echo A > B) else echo C)
195 cd .. & rd /s/q foobar
197 echo ------------ Testing circumflex escape character ------------
198 rem Using something like "echo foo^" asks for an additional char after a "More?" prompt on the following line; it's not possible to currently test that non-interactively
220 echo bak ^&& echo baz 2> nul
230 rem FIXME: echoing %FOO% gives an error (baz not recognized) but prematurely
231 rem exits the script on windows; redirecting stdout and/or stderr doesn't help
240 echo ------------ Testing 'set' ------------
242 set FOOBAR 2> nul > nul
246 echo %FOOBAR%FOOBAR not defined
258 echo %FOOBAR%FOOBAR not defined
260 set FOOBA 2> nul > nul
270 echo %FOO%FOO not defined
275 echo set "FOO=bar" should not include the quotes in the variable value
288 echo ------------ Testing variable expansion ------------
290 echo ~dp0 should be directory containing batch file
306 echo %ERRORLEVEL%%ERRORLEVEL%
307 echo %ERRORLEVEL%ERRORLEVEL%
314 echo ------------ Testing variable substrings ------------
327 echo ------------ Testing variable substitution ------------
328 echo --- in FOR variables
329 for %%i in ("A B" C) do echo %%i
330 rem check works when prefix with @
331 @for %%i in ("A B" C) do echo %%i
333 for %%i in ("A B" C) do echo '%%~i'
334 rem fully qualified path
335 for %%f in ("C D" E) do echo %%~ff
337 for %%i in ("F G" H) do echo %%~di
339 for %%d in ("I J" K) do echo %%~pd
341 for %%i in ("L M" N) do echo %%~ni
343 for %%i in ("O. P.OOL" Q.TABC hello) do echo '%%~xi'
344 rem path with short path names
345 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do echo '%%~sI'
347 for %%i in ("U V" W) do echo '%%~ai'
349 for %%i in (foo) do echo '%%~ai'
352 rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar...
353 for %%i in ("a b" c) do echo '%%~ti'
355 rem Similar issues as above
356 for %%i in ("a b" c) do echo '%%~zi'
358 for %%i in ("d e" f) do echo %%~dpi
359 for %%i in ("g h" i) do echo %%~sdi
360 for %%i in ("g h" i) do echo %%~dsi
361 for %%i in ("j k" l.eh) do echo '%%~xsi'
363 echo --- in parameters
364 for %%i in ("A B" C) do call :echoFun %%i
366 for %%i in ("A B" C) do call :echoFunQ %%i
367 rem fully qualified path
368 for %%f in ("C D" E) do call :echoFunF %%f
370 for %%i in ("F G" H) do call :echoFunD %%i
372 for %%d in ("I J" K) do call :echoFunP %%d
374 for %%i in ("L M" N) do call :echoFunN %%i
376 for %%i in ("O. P.OOL" Q.TABC hello) do call :echoFunX %%i
377 rem path with short path names
378 for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do call :echoFunS %%I
379 rem NT4 aborts whole script execution when encountering ~a, ~t and ~z substitutions, preventing full testing
381 for %%i in ("d e" f) do call :echoFunDP %%i
382 for %%i in ("g h" i) do call :echoFunSD %%i
383 for %%i in ("g h" i) do call :echoFunDS %%i
384 for %%i in ("j k" l.eh) do call :echoFunXS %%i
416 rem some NT4 workaround
439 echo ------------ Testing variable delayed expansion ------------
440 rem NT4 doesn't support this
441 echo --- default mode (load-time expansion)
447 if %FOO% == bar (echo bar) else echo foo
453 if !FOO! == bar (echo bar) else echo foo
456 echo --- runtime (delayed) expansion mode
457 setlocal EnableDelayedExpansion
463 if %FOO% == bar (echo bar) else echo foo
469 if !FOO! == bar (echo bar) else echo foo
472 setlocal DisableDelayedExpansion
478 echo --- using /V cmd flag
479 echo @echo off> tmp.cmd
480 echo set FOO=foo>> tmp.cmd
481 echo echo %%FOO%%>> tmp.cmd
482 echo echo !FOO!>> tmp.cmd
483 echo set FOO=>> tmp.cmd
485 cmd /V:OfF /C tmp.cmd
488 echo ------------ Testing conditional execution ------------
489 echo --- unconditional ampersand
490 call :setError 123 & echo foo1
491 echo bar2 & echo foo2
492 mkdir foobar & cd foobar
494 cd .. & rd /s/q foobar
496 echo foobar not deleted!
499 ) else echo foobar deleted
500 echo --- on success conditional and
501 call :setError 456 && echo foo3 > foo3
505 ) else echo foo3 not created
506 echo bar4 && echo foo4
507 echo --- on failure conditional or
508 call :setError 789 || echo foo5
509 echo foo6 || echo bar6 > bar6
515 echo ------------ Testing cd ------------
518 echo blabla > singleFile
520 echo Current dir: %CD%
535 if not exist foobar (cd ..)
537 cd@tab@..@tab@@space@@tab@
539 if not exist foobar (cd ..)
553 cd "bar bak@space@"@tab@@space@
564 echo ------------ Testing type ------------
578 echo ------------ Testing NUL ------------
579 md foobar & cd foobar
580 rem NUL file (non) creation + case insensitivity
581 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
590 rem NUL not special everywhere
593 if not exist foo (echo foo should have been created) else (
597 rem Empty file creation
608 echo ------------ Testing if/else ------------
609 echo if/else should work with blocks
611 echo if seems to work
613 echo if seems to be broken
616 echo else seems to be broken
618 echo else seems to work
621 echo if seems not to detect /c as parameter
623 echo parameter detection seems to be broken
625 echo Testing case sensitivity with and without /i option
626 if bar==BAR echo if does not default to case sensitivity
627 if not bar==BAR echo if seems to default to case sensitivity
628 if /i foo==FOO echo if /i seems to work
629 if /i not foo==FOO echo if /i seems to be broken
630 if /I foo==FOO echo if /I seems to work
631 if /I not foo==FOO echo if /I seems to be broken
632 echo Testing string comparisons
633 if abc == abc (echo equal) else echo non equal
634 if abc =="abc" (echo equal) else echo non equal
635 if "abc"== abc (echo equal) else echo non equal
636 if "abc"== "abc" (echo equal) else echo non equal
637 echo Testing tabs handling
638 if@tab@1==1 echo doom
639 if @tab@1==1 echo doom
640 if 1==1 (echo doom) else@tab@echo quake
641 if@tab@not @tab@1==@tab@0 @tab@echo lol
642 if 1==0@tab@(echo doom) else echo quake
643 if 1==0 (echo doom)@tab@else echo quake
644 if 1==0 (echo doom) else@tab@echo quake
646 echo ------------ Testing for ------------
648 for %%i in (A B C) do echo %%i
649 for %%i in (A B C) do echo %%I
650 for %%i in (A B C) do echo %%j
651 for %%i in (A B C) do call :forTestFun1 %%i
652 for %%i in (1,4,1) do echo %%i
653 for %%i in (A, B,C) do echo %%i
654 for %%i in (X) do echo %%i
655 for@tab@%%i in (X2) do echo %%i
656 for %%i in@tab@(X3) do echo %%i
657 for %%i in (@tab@ foo@tab@) do echo %%i
658 for@tab@ %%i in@tab@(@tab@M) do echo %%i
659 for %%i@tab@in (X)@tab@do@tab@echo %%i
660 for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
661 for %%i in (`echo A B`) do echo %%i
662 for %%i in ('echo A B') do echo %%i
663 for %%i in ("echo A B") do echo %%i
664 for %%i in ("A B" C) do echo %%i
670 echo --- imbricated FORs
677 for %%i in (A B) do (
678 for %%j in (C D) do (
680 for %%i in (A B) do (
681 for %%j in (C D) do (
682 call :forTestFun2 %%i %%j ))
688 mkdir foobar & cd foobar
693 echo --- basic wildcards
694 for %%i in (ba*) do echo %%i
696 for /d %%i in (baz foo bar) do echo %%i 2>&1
697 rem Confirm we don't match files:
698 for /d %%i in (bazb*) do echo %%i 2>&1
699 for /d %%i in (bazb2*) do echo %%i 2>&1
700 rem Show we pass through non wildcards
701 for /d %%i in (PASSED) do echo %%i
702 for /d %%i in (xxx) do (
703 echo %%i - Should be xxx
704 echo Expected second line
706 rem Show we issue no messages on failures
707 for /d %%i in (FAILED?) do echo %%i 2>&1
708 for /d %%i in (FAILED?) do (
709 echo %%i - Unexpected!
710 echo FAILED Unexpected second line
712 for /d %%i in (FAILED*) do echo %%i 2>&1
713 for /d %%i in (FAILED*) do (
714 echo %%i - Unexpected!
715 echo FAILED Unexpected second line
717 rem FIXME can't test wildcard expansion here since it's listed in directory
718 rem order, and not in alphabetic order.
719 rem Proper testing would need a currently missing "sort" program implementation.
720 rem for /d %%i in (ba*) do echo %%i>> tmp
723 rem for /d %%i in (?a*) do echo %%i>> tmp
726 rem for /d %%i in (*) do echo %%i>> tmp
734 call :WriteLine set found=N
735 for /l %%i in (1,1,%expectedresults%) do (
736 call :WriteLine if "%%%%expectedresults.%%i%%%%"=="%%%%1" set found=Y
737 call :WriteLine if "%%%%found%%%%"=="Y" set expectedresults.%%i=
738 call :WriteLine if "%%%%found%%%%"=="Y" goto :eof
740 call :WriteLine echo Got unexpected result: "%%%%1"
749 for /l %%i in (1,1,%expectedresults%) do call :WriteLine if not "%%%%expectedresults.%%i%%%%"=="" echo Found missing result: "%%%%expectedresults.%%i%%%%"
755 rem %CD% does not tork on NT4 so use the following workaround
756 for /d %%i in (.) do set CURDIR=%%~dpnxi
759 echo Plain directory enumeration
760 set expectedresults=4
761 set expectedresults.1=%CURDIR%\.
762 set expectedresults.2=%CURDIR%\bar\.
763 set expectedresults.3=%CURDIR%\baz\.
764 set expectedresults.4=%CURDIR%\foo\.
766 for /R %%i in (.) do call temp.bat %%i
767 call :ValidateExpected
769 echo Plain directory enumeration from provided root
770 set expectedresults=4
771 set expectedresults.1=%CURDIR%\.
772 set expectedresults.2=%CURDIR%\bar\.
773 set expectedresults.3=%CURDIR%\baz\.
774 set expectedresults.4=%CURDIR%\foo\.
775 if "%CD%"=="" goto :SkipBrokenNT4
777 for /R "%CURDIR%" %%i in (.) do call temp.bat %%i
778 call :ValidateExpected
781 echo File enumeration
782 set expectedresults=2
783 set expectedresults.1=%CURDIR%\baz\bazbaz
784 set expectedresults.2=%CURDIR%\bazbaz
786 for /R %%i in (baz*) do call temp.bat %%i
787 call :ValidateExpected
789 echo File enumeration from provided root
790 set expectedresults=2
791 set expectedresults.1=%CURDIR%\baz\bazbaz
792 set expectedresults.2=%CURDIR%\bazbaz
794 for /R %%i in (baz*) do call temp.bat %%i
795 call :ValidateExpected
797 echo Mixed enumeration
798 set expectedresults=6
799 set expectedresults.1=%CURDIR%\.
800 set expectedresults.2=%CURDIR%\bar\.
801 set expectedresults.3=%CURDIR%\baz\.
802 set expectedresults.4=%CURDIR%\baz\bazbaz
803 set expectedresults.5=%CURDIR%\bazbaz
804 set expectedresults.6=%CURDIR%\foo\.
806 for /R %%i in (. baz*) do call temp.bat %%i
807 call :ValidateExpected
809 echo Mixed enumeration from provided root
810 set expectedresults=6
811 set expectedresults.1=%CURDIR%\.
812 set expectedresults.2=%CURDIR%\bar\.
813 set expectedresults.3=%CURDIR%\baz\.
814 set expectedresults.4=%CURDIR%\baz\bazbaz
815 set expectedresults.5=%CURDIR%\bazbaz
816 set expectedresults.6=%CURDIR%\foo\.
818 for /R %%i in (. baz*) do call temp.bat %%i
819 call :ValidateExpected
821 echo With duplicates enumeration
822 set expectedresults=12
823 set expectedresults.1=%CURDIR%\bar\bazbaz
824 set expectedresults.2=%CURDIR%\bar\fred
825 set expectedresults.3=%CURDIR%\baz\bazbaz
826 set expectedresults.4=%CURDIR%\baz\bazbaz
827 set expectedresults.5=%CURDIR%\baz\bazbaz
828 set expectedresults.6=%CURDIR%\baz\fred
829 set expectedresults.7=%CURDIR%\bazbaz
830 set expectedresults.8=%CURDIR%\bazbaz
831 set expectedresults.9=%CURDIR%\bazbaz
832 set expectedresults.10=%CURDIR%\foo\bazbaz
833 set expectedresults.11=%CURDIR%\foo\fred
834 set expectedresults.12=%CURDIR%\fred
836 for /R %%i in (baz* bazbaz fred ba*) do call temp.bat %%i
837 call :ValidateExpected
839 echo Strip missing wildcards, keep unwildcarded names
840 set expectedresults=6
841 set expectedresults.1=%CURDIR%\bar\jim
842 set expectedresults.2=%CURDIR%\baz\bazbaz
843 set expectedresults.3=%CURDIR%\baz\jim
844 set expectedresults.4=%CURDIR%\bazbaz
845 set expectedresults.5=%CURDIR%\foo\jim
846 set expectedresults.6=%CURDIR%\jim
848 for /R %%i in (baz* fred* jim) do call temp.bat %%i
849 call :ValidateExpected
852 cd .. & rd /s/Q foobar
854 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
855 for /L %%i in (1,2,0) do echo %%i
856 for@tab@/L %%i in (1,2,0) do echo %%i
857 for /L %%i in (1,2,6) do echo %%i
858 for /l %%i in (1 ,2,6) do echo %%i
859 for /L %%i in (a,2,3) do echo %%i
860 for /L %%i in (1,2,-1) do echo %%i
861 for /L %%i in (-4,-1,-1) do echo %%i
862 for /L %%i in (1,-2,-2) do echo %%i
863 for /L %%i in (1,2,a) do echo %%i
864 echo ErrorLevel %ErrorLevel%
865 for /L %%i in (1,a,b) do echo %%i
866 echo ErrorLevel %ErrorLevel%
868 for /l %%i in (1,1,4) do echo %%i
869 for /l %%i in (1,2,4) do echo %%i
870 for /l %%i in (4,-1,1) do echo %%i
871 for /l %%i in (4,-2,1) do echo %%i
872 for /l %%i in (1,-1,4) do echo %%i
873 for /l %%i in (4,1,1) do echo %%i
874 for /L %%i in (a,2,b) do echo %%i
875 for /L %%i in (1,1,1) do echo %%i
876 for /L %%i in (1,-2,-1) do echo %%i
877 for /L %%i in (-1,-1,-1) do echo %%i
878 for /L %%i in (1,2, 3) do echo %%i
879 rem Test zero iteration skips the body of the for
880 for /L %%i in (2,2,1) do (
885 rem No output when using "set expr" syntax, unless in interactive mode
886 rem Need to use "set envvar=expr" to use in a batch script
887 echo ------ individual operations
889 set /a var=1 +2 & echo %var%
890 set /a var=1 +-2 & echo %var%
891 set /a var=1 --2 & echo %var%
892 set /a var=2* 3 & echo %var%
893 set /a var=-2* -5 & echo %var%
894 set /a var=12/3 & echo %var%
895 set /a var=13/3 & echo %var%
896 set /a var=-13/3 & echo %var%
897 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
898 set /a var=5 %% 5 & echo %var%
899 set /a var=5 %% 3 & echo %var%
900 set /a var=5 %% -3 & echo %var%
901 set /a var=-5 %% -3 & echo %var%
902 set /a var=1 ^<^< 0 & echo %var%
903 set /a var=1 ^<^< 2 & echo %var%
904 set /a var=1 ^<^< -2 & echo %var%
905 set /a var=-1 ^<^< -2 & echo %var%
906 set /a var=-1 ^<^< 2 & echo %var%
907 set /a var=9 ^>^> 0 & echo %var%
908 set /a var=9 ^>^> 2 & echo %var%
909 set /a var=9 ^>^> -2 & echo %var%
910 set /a var=-9 ^>^> -2 & echo %var%
911 set /a var=-9 ^>^> 2 & echo %var%
912 set /a var=5 ^& 0 & echo %var%
913 set /a var=5 ^& 1 & echo %var%
914 set /a var=5 ^& 3 & echo %var%
915 set /a var=5 ^& 4 & echo %var%
916 set /a var=5 ^& 1 & echo %var%
917 set /a var=5 ^| 0 & echo %var%
918 set /a var=5 ^| 1 & echo %var%
919 set /a var=5 ^| 3 & echo %var%
920 set /a var=5 ^| 4 & echo %var%
921 set /a var=5 ^| 1 & echo %var%
922 set /a var=5 ^^ 0 & echo %var%
923 set /a var=5 ^^ 1 & echo %var%
924 set /a var=5 ^^ 3 & echo %var%
925 set /a var=5 ^^ 4 & echo %var%
926 set /a var=5 ^^ 1 & echo %var%
927 echo ------ precedence and grouping
928 set /a var=4 + 2*3 & echo %var%
929 set /a var=(4+2)*3 & echo %var%
930 set /a var=4 * 3/5 & echo %var%
931 set /a var=(4 * 3)/5 & echo %var%
932 set /a var=4 * 5 %% 4 & echo %var%
933 set /a var=4 * (5 %% 4) & echo %var%
934 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
935 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
936 echo ------ octal and hexadecimal
937 set /a var=0xf + 3 & echo %var%
938 set /a var=0xF + 3 & echo %var%
939 set /a var=015 + 2 & echo %var%
940 set /a var=3, 8+3,0 & echo %var%
941 echo ------ variables
942 set /a var=foo=3, foo+1 & echo %var%
943 if defined foo (echo %foo%) else (
946 set /a var=foo=3, foo+=1 & echo %var%
947 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
948 set /a var=foo*= foo & echo %var%
949 set /a var=whateverNonExistingVar & echo %var%
950 set /a var=whateverNonExistingVar + bar & echo %var%
951 set /a var=foo -= foo + 7 & echo %var%
952 set /a var=foo /= 3 + 2 & echo %var%
953 set /a var=foo=5, foo %%=2 & echo %var%
954 set /a var=foo ^<^<= 2 & echo %var%
955 set /a var=foo ^>^>= 2 & echo %var%
956 set /a var=foo ^&= 2 & echo %var%
957 set /a var=foo=5, foo ^|= 2 & echo %var%
958 set /a var=foo=5, foo ^^= 2 & echo %var%
959 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
964 mkdir foobar & cd foobar
965 echo ------ string argument
966 for /F %%i in ("a b c") do echo %%i
967 for /f %%i in ("a ") do echo %%i
968 for /f %%i in ("a") do echo %%i
969 fOr /f %%i in (" a") do echo %%i
970 for /f %%i in (" a ") do echo %%i
971 echo ------ fileset argument
972 echo --------- basic blank handling
974 for /f %%i in (foo) do echo %%i
976 for /f %%i in (foo) do echo %%i
978 for /f %%i in (foo) do echo %%i
980 for /f %%i in (foo) do echo %%i
982 for /f %%i in (foo) do echo %%i
984 for /f %%i in (foo) do echo %%i
987 for /f %%i in (foo) do echo %%i
988 echo --------- multi-line with empty lines
995 for /f %%b in (foo) do echo %%b
996 echo --------- multiple files
1000 for /f %%k in (foo bar) do echo %%k
1001 for /f %%k in (bar foo) do echo %%k
1002 rem echo ------ command argument
1003 rem Not implemented on NT4
1004 rem FIXME: Not testable right now in wine: not implemented and would need
1005 rem preliminary grep-like program implementation (e.g. like findstr or fc) even
1006 rem for a simple todo_wine test
1007 rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported
1008 rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported
1009 echo ------ eol option
1010 for /f "eol=@" %%i in (" ad") do echo %%i
1011 for /f "eol=@" %%i in (" z@y") do echo %%i
1012 for /f "eol=|" %%i in ("a|d") do echo %%i
1013 for /f "eol=@" %%i in ("@y") do echo %%i > output_file
1014 if not exist output_file (echo no output) else (del output_file)
1015 for /f "eol==" %%i in ("=y") do echo %%i > output_file
1016 if not exist output_file (echo no output) else (del output_file)
1017 echo ------ delims option
1018 for /f "delims=|" %%i in ("a|d") do echo %%i
1019 for /f "delims=|" %%i in ("a |d") do echo %%i
1020 for /f "delims=|" %%i in ("a d|") do echo %%i
1021 for /f "delims=| " %%i in ("a d|") do echo %%i
1022 for /f "delims==" %%i in ("C r=d|") do echo %%i
1023 for /f "delims=" %%i in ("foo bar baz") do echo %%i
1024 for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi
1025 echo ------ skip option
1029 for /f "skip=2" %%i in (foo) do echo %%i
1030 for /f "skip=3" %%i in (foo) do echo %%i > output_file
1031 if not exist output_file (echo no output) else (del output_file)
1032 for /f "skip=4" %%i in (foo) do echo %%i > output_file
1033 if not exist output_file (echo no output) else (del output_file)
1037 echo ------------ Testing del /a ------------
1038 del /f/q *.test > nul
1041 echo not-r > not-r.test
1043 if not exist not-r.test echo not-r.test not found before delete, bad
1045 if not exist not-r.test echo not-r.test not found after delete, good
1047 if not exist r.test echo r.test not found before delete, bad
1048 if exist r.test echo r.test found before delete, good
1050 if not exist r.test echo r.test not found after delete, good
1051 if exist r.test echo r.test found after delete, bad
1053 echo ------------ Testing del /q ------------
1057 echo abc > file2.dat
1058 rem If /q doesn't work, cmd will prompt and the test case should hang
1060 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
1061 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
1065 echo ------------ Testing del /s ------------
1070 echo there > file2.dat
1071 echo bub > file3.dat
1072 echo bye > "file with spaces.dat"
1074 del /s file1.dat > nul
1075 del file2.dat /s > nul
1076 del "file3.dat" /s > nul
1077 del "file with spaces.dat" /s > nul
1079 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
1080 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
1081 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
1082 if exist "file with spaces.dat" del "file with spaces.dat"
1087 echo ------------ Testing rename ------------
1088 mkdir foobar & cd foobar
1089 echo --- ren and rename are synonymous
1092 if exist foo echo foo should be renamed!
1093 if exist bar echo foo renamed to bar
1095 if exist bar echo bar should be renamed!
1096 if exist foo echo bar renamed to foo
1097 echo --- name collision
1107 echo --- rename read-only files
1111 if not exist file1 (
1113 echo read-only file renamed
1116 echo read-only file not renamed!
1118 echo --- rename directories
1130 echo read-only dir renamed
1133 echo --- rename in other directory
1134 if not exist baz\abc (
1135 echo rename impossible in other directory
1136 if exist foo echo original file still present
1138 echo shouldn't rename in other directory!
1139 if not exist foo echo original file not present anymore
1141 cd .. & rd /s/q foobar
1143 echo ------------ Testing move ------------
1144 mkdir foobar & cd foobar
1147 move foo bar > nul 2>&1
1150 echo file move succeeded
1155 move /Y bar baz > nul 2>&1
1158 echo file move with overwrite succeeded
1161 echo file overwrite impossible!
1167 move baz bazro > nul 2>&1
1170 echo read-only files are moveable
1171 move bazro baz > nul 2>&1
1174 echo read-only file not moved!
1178 move baz rep > nul 2>&1
1181 echo file moved in subdirectory
1185 move rep\baz . > nul 2>&1
1186 move /Y baz baz > nul 2>&1
1188 echo moving a file to itself should be a no-op!
1190 echo moving a file to itself is a no-op
1192 echo ErrorLevel: %ErrorLevel%
1195 echo --- directory move
1199 move baz foo\bar > nul 2>&1
1201 if exist foo\bar\baz\baz2 (
1202 echo simple directory move succeeded
1207 move baz baz > nul 2>&1
1208 echo moving a directory to itself gives error; errlevel %ErrorLevel%
1209 echo ------ dir in dir move
1214 move foo bar > nul 2>&1
1222 cd .. & rd /s/q foobar
1224 echo ------------ Testing mkdir ------------
1226 echo --- md and mkdir are synonymous
1233 echo --- creating an already existing directory/file must fail
1242 echo --- multilevel path creation
1254 mkdir ..\..\..\foo\bar2
1257 mkdir ..\..\..\foo\bar2
1259 rmdir ..\..\..\foo\bar2
1267 echo --- trailing backslashes
1270 if exist foo (rmdir foo & echo dir created
1271 ) else ( echo dir not created )
1273 echo --- invalid chars
1275 echo mkdir ? gives errorlevel %ErrorLevel%
1278 echo mkdir ?\foo gives errorlevel %ErrorLevel%
1281 echo mkdir foo\? gives errorlevel %ErrorLevel%
1282 if exist foo (rmdir foo & echo ok, foo created
1283 ) else ( echo foo not created )
1286 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
1289 echo bad, foo not created
1293 echo ok, foo\bar created
1299 echo --- multiple directories at once
1300 mkdir foobaz & cd foobaz
1301 mkdir foo bar\baz foobar "bazbaz" .\"zabzab"
1302 if exist foo (echo foo created) else echo foo not created!
1303 if exist bar (echo bar created) else echo bar not created!
1304 if exist foobar (echo foobar created) else echo foobar not created!
1305 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
1306 if exist bazbaz (echo bazbaz created) else echo bazbaz not created!
1307 if exist zabzab (echo zabzab created) else echo zabzab not created!
1308 cd .. & rd /s/q foobaz
1311 echo mkdir foo\* errorlevel %ErrorLevel%
1312 if exist foo (rmdir foo & echo ok, foo created
1313 ) else ( echo bad, foo not created )
1315 echo ------------ Testing rmdir ------------
1317 rem rd and rmdir are synonymous
1321 if not exist foobar echo dir removed
1325 if not exist foobar echo dir removed
1326 rem Removing nonexistent directory
1329 rem Removing single-level directories
1333 if exist foo echo file not removed
1339 if exist foo echo non-empty dir not removed
1344 if exist foo echo non-empty dir not removed
1351 echo recursive rmdir succeeded
1358 echo foo > foo\bar\brol
1359 rmdir /s /Q foo 2>&1
1361 echo recursive rmdir succeeded
1368 rem multiples directories at once
1369 mkdir foobaz & cd foobaz
1373 rd /s/q foo bar foobar
1374 if not exist foo (echo foo removed) else echo foo not removed!
1375 if not exist bar (echo bar removed) else echo bar not removed!
1376 if not exist foobar (echo foobar removed) else echo foobar not removed!
1377 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
1378 cd .. & rd /s/q foobaz
1380 echo ------------ Testing pushd/popd ------------
1382 echo --- popd is no-op when dir stack is empty
1385 echo --- pushing non-existing dir
1388 echo --- basic behaviour
1413 echo ------------ Testing attrib ------------
1414 rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications
1415 mkdir foobar & cd foobar
1416 echo foo original contents> foo
1419 echo --- read-only attribute
1420 rem Read-only files cannot be altered or deleted, unless forced
1428 echo Read-only file not deleted
1430 echo Should not delete read-only file!
1434 echo Read-only file forcibly deleted
1436 echo Should delete read-only file with del /F!
1440 cd .. & rd /s/q foobar
1441 echo --- recursive behaviour
1442 mkdir foobar\baz & cd foobar
1448 attrib +R l*vel? /S > nul 2>&1
1454 cd .. & rd /s/q foobar
1455 echo --- folders processing
1461 attrib +r baz /s /d > nul 2>&1
1467 rem Oddly windows allows file creation in a read-only directory...
1468 if exist baz\lala (echo file created in read-only dir) else echo file not created
1469 cd .. & rd /s/q foobar
1471 echo ------------ Testing assoc ------------
1472 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
1473 rem FIXME Revise once || conditional execution is fixed
1474 mkdir foobar & cd foobar
1475 echo --- setting association
1483 rem association set system-wide
1484 echo @echo off> tmp.cmd
1485 echo echo +++>> tmp.cmd
1486 echo assoc .foo>> tmp.cmd
1489 echo --- resetting association
1495 rem association removal set system-wide
1496 cmd /c tmp.cmd > baz
1499 cd .. & rd /s/q foobar
1501 echo ------------ Testing ftype ------------
1502 rem FIXME Can't test error messages in the current test system, so we have to use some kludges
1503 rem FIXME Revise once || conditional execution is fixed
1504 mkdir foobar & cd foobar
1505 echo --- setting association
1510 ftype footype=foo_opencmd
1514 rem association set system-wide
1515 echo @echo off> tmp.cmd
1516 echo echo +++>> tmp.cmd
1517 echo ftype footype>> tmp.cmd
1520 echo --- resetting association
1523 rem Removing a file type association doesn't work on XP due to a bug, so a workaround is needed
1524 setlocal EnableDelayedExpansion
1525 set FOO=original value
1528 for /F %%i in ('type baz') do (set FOO=buggyXP)
1529 rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion)
1530 rem FIXME Revisit once a grep-like program like ftype is implemented
1531 rem (e.g. to check baz's size using dir /b instead)
1534 rem cleanup registry
1535 echo REGEDIT4> regCleanup.reg
1536 echo.>> regCleanup.reg
1537 echo [-HKEY_CLASSES_ROOT\footype]>> regCleanup.reg
1538 regedit /s regCleanup.reg
1541 cd .. & rd /s/q foobar
1543 echo ------------ Testing CALL ------------
1544 mkdir foobar & cd foobar
1545 echo --- external script
1546 echo echo foo %%1> foo.cmd
1549 echo echo %%1 %%2 > foo.cmd
1551 call foo.cmd foo bar
1558 echo --- internal routines
1559 call :testRoutine :testRoutine
1560 goto :endTestRoutine
1566 call :testRoutineArgs foo
1567 call :testRoutineArgs foo bar
1568 call :testRoutineArgs foo ""
1569 call :testRoutineArgs "" bar
1570 call :testRoutineArgs foo ''
1571 call :testRoutineArgs '' bar
1572 goto :endTestRoutineArgs
1578 echo --- with builtins
1581 if exist foo (echo foo created) else echo foo should exist!
1583 set FOOBAZ_VAR=foobaz
1584 call echo Should expand %FOOBAZ_VAR%
1589 if 1==1 call del batfile
1591 if exist batfile echo batfile shouldn't exist
1592 rem ... but not for 'if' or 'for'
1593 call if 1==1 echo bar 2> nul
1596 call for %%i in (foo bar baz) do echo %%i 2> nul
1598 rem First look for programs in the path before trying a builtin
1599 echo echo non-builtin dir> dir.cmd
1601 cd .. & rd /s/q foobar
1603 echo ------------ Testing SHIFT ------------
1605 call :shiftFun p1 p2 p3 p4 p5
1609 echo '%1' '%2' '%3' '%4' '%5'
1611 echo '%1' '%2' '%3' '%4' '%5'
1613 echo '%1' '%2' '%3' '%4' '%5'
1615 echo '%1' '%2' '%3' '%4' '%5'
1617 echo '%1' '%2' '%3' '%4' '%5'
1619 echo '%1' '%2' '%3' '%4' '%5'
1623 echo ------------ Testing cmd invocation ------------
1624 rem FIXME: only a stub ATM
1625 echo --- a batch file can delete itself
1626 echo del foo.cmd>foo.cmd
1628 if not exist foo.cmd (
1629 echo file correctly deleted
1631 echo file should be deleted!
1634 echo --- a batch file can alter itself
1635 echo echo bar^>foo.cmd>foo.cmd
1636 cmd /q /c foo.cmd > NUL 2>&1
1641 echo file not created!
1644 echo ------------ Testing setlocal/endlocal ------------
1646 rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test section
1647 mkdir foobar & cd foobar
1648 echo --- enable/disable extensions
1649 setlocal DisableEXTensions
1650 echo ErrLev: %ErrorLevel%
1652 echo ErrLev: %ErrorLevel%
1653 echo @echo off> tmp.cmd
1654 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
1655 rem Enabled by default
1657 cmd /E:OfF /C tmp.cmd
1658 cmd /e:oN /C tmp.cmd
1660 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
1661 echo --- setlocal with corresponding endlocal
1662 rem %CD% does not tork on NT4 so use the following workaround
1663 for /d %%i in (.) do set CURDIR=%%~dpnxi
1664 echo @echo off> test.cmd
1665 echo echo %%VAR%%>> test.cmd
1666 echo setlocal>> test.cmd
1667 echo set VAR=localval>> test.cmd
1668 echo md foobar2>> test.cmd
1669 echo cd foobar2>> test.cmd
1670 echo echo %%VAR%%>> test.cmd
1671 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1672 echo endlocal>> test.cmd
1673 echo echo %%VAR%%>> test.cmd
1674 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1678 for /d %%i in (.) do echo %%~dpnxi
1682 echo --- setlocal with no corresponding endlocal
1683 echo @echo off> test.cmd
1684 echo echo %%VAR%%>> test.cmd
1685 echo setlocal>> test.cmd
1686 echo set VAR=localval>> test.cmd
1687 echo md foobar2>> test.cmd
1688 echo cd foobar2>> test.cmd
1689 echo echo %%VAR%%>> test.cmd
1690 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd
1692 rem %CD% does not tork on NT4 so use the following workaround
1693 for /d %%i in (.) do set CURDIR=%%~dpnxi
1696 for /d %%i in (.) do echo %%~dpnxi
1700 echo --- setlocal within same batch program
1704 rem %CD% does not tork on NT4 so use the following workaround
1705 for /d %%i in (.) do set CURDIR=%%~dpnxi
1712 if "%var1%"=="one" echo Var1 ok 1
1713 if "%var2%"=="two" echo Var2 ok 2
1714 if "%var3%"=="three" echo Var3 ok 3
1715 for /d %%i in (.) do set curdir2=%%~dpnxi
1716 if "%curdir2%"=="%curdir%\foobar2" echo Directory is ok 1
1718 if "%var1%"=="one" echo Var1 ok 1
1719 if "%var2%"=="two" echo Var2 ok 2
1720 if "%var3%"=="" echo Var3 ok 3
1721 for /d %%i in (.) do set curdir2=%%~dpnxi
1722 if "%curdir2%"=="%curdir%\foobar2" echo Directory is ok 2
1724 if "%var1%"=="one" echo Var1 ok 1
1725 if "%var2%"=="" echo Var2 ok 2
1726 if "%var3%"=="" echo Var3 ok 3
1727 for /d %%i in (.) do set curdir2=%%~dpnxi
1728 if "%curdir2%"=="%curdir%" echo Directory is ok 3
1732 echo --- Mismatched set and end locals
1736 rem %CD% does not tork on NT4 so use the following workaround
1737 for /d %%i in (.) do set curdir=%%~dpnxi
1739 echo @echo off> 2set1end.cmd
1740 echo echo %%VAR%%>> 2set1end.cmd
1741 echo setlocal>> 2set1end.cmd
1742 echo set VAR=2set1endvalue1>> 2set1end.cmd
1743 echo cd ..\foodir3>> 2set1end.cmd
1744 echo setlocal>> 2set1end.cmd
1745 echo set VAR=2set1endvalue2>> 2set1end.cmd
1746 echo cd ..\foodir4>> 2set1end.cmd
1747 echo endlocal>> 2set1end.cmd
1748 echo echo %%VAR%%>> 2set1end.cmd
1749 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 2set1end.cmd
1751 echo @echo off> 1set2end.cmd
1752 echo echo %%VAR%%>> 1set2end.cmd
1753 echo setlocal>> 1set2end.cmd
1754 echo set VAR=1set2endvalue1>> 1set2end.cmd
1755 echo cd ..\foodir3>> 1set2end.cmd
1756 echo endlocal>> 1set2end.cmd
1757 echo echo %%VAR%%>> 1set2end.cmd
1758 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
1759 echo endlocal>> 1set2end.cmd
1760 echo echo %%VAR%%>> 1set2end.cmd
1761 echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
1763 echo --- Extra setlocal in called batch
1765 rem -- setlocal1 == this batch, should never be used inside a called routine
1769 call %curdir%\2set1end.cmd
1772 for /d %%i in (.) do echo %%~dpnxi
1775 for /d %%i in (.) do echo %%~dpnxi
1778 echo --- Extra endlocal in called batch
1780 rem -- setlocal1 == this batch, should never be used inside a called routine
1784 call %curdir%\1set2end.cmd
1787 for /d %%i in (.) do echo %%~dpnxi
1790 for /d %%i in (.) do echo %%~dpnxi
1793 echo --- endlocal in called function rather than batch pgm is ineffective
1799 call :endlocalroutine
1803 goto :endlocalfinished
1821 cd .. & rd /q/s foobar
1823 echo ------------ Testing Errorlevel ------------
1824 rem WARNING: Do *not* add tests using ErrorLevel after this section
1825 should_not_exist 2> nul > nul
1827 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
1828 rem See http://www.robvanderwoude.com/exit.php
1831 if errorlevel 2 echo errorlevel too high, bad
1832 if errorlevel 1 echo errorlevel just right, good
1833 if errorlevel 01 echo errorlevel with leading zero just right, good
1834 if errorlevel -1 echo errorlevel with negative number OK
1835 if errorlevel 0x1 echo hexa should not be recognized!
1836 if errorlevel 1a echo invalid error level recognized!
1838 echo abc%ErrorLevel%def
1839 if errorlevel 1 echo errorlevel nonzero, bad
1840 if not errorlevel 1 echo errorlevel zero, good
1841 if not errorlevel 0x1 echo hexa should not be recognized!
1842 if not errorlevel 1a echo invalid error level recognized!
1843 rem Now verify that setting a real variable hides its magic variable
1845 echo %ErrorLevel% should be 7
1846 if errorlevel 7 echo setting var worked too well, bad
1848 echo %ErrorLevel% should still be 7
1850 echo ------------ Testing GOTO ------------
1853 echo goto with no leading space worked
1856 echo goto with a leading space worked
1859 echo goto with a leading tab worked
1862 echo goto with a following space worked
1864 echo ------------ Testing PATH ------------
1865 set backup_path=%path%
1872 set path=%backup_path%
1875 echo ------------ Testing combined CALLs/GOTOs ------------
1876 echo @echo off>foo.cmd
1877 echo goto :eof>>foot.cmd
1879 echo echo world>>foo.cmd
1881 echo @echo off>foot.cmd
1882 echo echo cheball>>foot.cmd
1884 echo call :bar>>foot.cmd
1885 echo if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmd
1886 echo goto :eof>>foot.cmd
1889 echo echo barbare>>foot.cmd
1890 echo goto :eof>>foot.cmd
1896 rem Script execution stops after the following line
1919 echo Final message is not output since earlier 'foot' processing stops script execution
1920 echo Do NOT add any tests below this line
1922 echo ------------ Done, jumping to EOF -----------
1924 rem Subroutine to set errorlevel and return
1925 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
1928 rem This line runs under cmd in windows NT 4, but not in more modern versions.