1573 lines
36 KiB
Batchfile
1573 lines
36 KiB
Batchfile
echo Tests for cmd's builtin commands
|
|
|
|
@echo on
|
|
echo ------------ Testing 'echo' [ON] --------------
|
|
echo word
|
|
echo 'singlequotedword'
|
|
echo "doublequotedword"
|
|
@echo at-echoed-word
|
|
echo "/?"
|
|
echo.
|
|
echo .
|
|
echo.word
|
|
echo .word
|
|
echo:
|
|
echo :
|
|
echo:word
|
|
echo :word
|
|
echo off now
|
|
echo word@space@
|
|
echo word@space@@space@
|
|
echo word
|
|
echo@tab@word
|
|
echo@tab@word @tab@
|
|
echo@tab@word@tab@@space@
|
|
@tab@echo word
|
|
echo @tab@word
|
|
echo @tab@word
|
|
echo@tab@@tab@word
|
|
|
|
@echo off
|
|
echo ------------ Testing 'echo' [OFF] --------------
|
|
echo word
|
|
echo 'singlequotedword'
|
|
echo "doublequotedword"
|
|
@echo at-echoed-word
|
|
echo "/?"
|
|
echo.
|
|
echo .
|
|
echo.word
|
|
echo .word
|
|
echo:
|
|
echo :
|
|
echo:word
|
|
echo :word
|
|
echo on again
|
|
echo word@space@
|
|
echo word@space@@space@
|
|
echo word
|
|
echo@tab@word
|
|
echo@tab@word @tab@
|
|
echo@tab@word@tab@@space@
|
|
@tab@echo word
|
|
echo @tab@word
|
|
echo @tab@word
|
|
echo@tab@@tab@word
|
|
|
|
echo ------------ Testing mixed echo modes --------------
|
|
echo @echo on> mixedEchoModes.cmd
|
|
echo if 1==1 echo foo>> mixedEchoModes.cmd
|
|
echo if 1==1 @echo bar>> mixedEchoModes.cmd
|
|
echo @echo off>> mixedEchoModes.cmd
|
|
echo if 1==1 echo foo2>> mixedEchoModes.cmd
|
|
echo if 1==1 @echo bar2>> mixedEchoModes.cmd
|
|
type mixedEchoModes.cmd
|
|
cmd /c mixedEchoModes.cmd
|
|
del mixedEchoModes.cmd
|
|
|
|
echo ------------ Testing rem --------------
|
|
rem Hello
|
|
rem Hello
|
|
rem Hello || foo
|
|
rem echo lol
|
|
rem echo foo & echo bar
|
|
rem @tab@ Hello
|
|
rem@tab@ Hello
|
|
rem@tab@echo foo & echo bar
|
|
@echo on
|
|
rem Hello
|
|
rem Hello
|
|
rem Hello || foo
|
|
rem echo lol
|
|
rem echo foo & echo bar
|
|
rem @tab@ Hello
|
|
rem@tab@ Hello
|
|
rem@tab@echo foo & echo bar
|
|
@echo off
|
|
|
|
echo ------------ Testing redirection operators --------------
|
|
mkdir foobar & cd foobar
|
|
echo ...stdout redirection
|
|
echo foo>foo
|
|
type foo
|
|
echo foo 1> foo
|
|
type foo
|
|
echo foo@tab@1> foo
|
|
type foo
|
|
echo foo 1>@tab@foo
|
|
type foo
|
|
echo foo@tab@1>@tab@foo
|
|
type foo
|
|
echo foo7 7> foo
|
|
type foo
|
|
echo foo9 9> foo
|
|
type foo
|
|
echo foo1> foo
|
|
type foo
|
|
echo foo11> foo
|
|
type foo
|
|
echo foo12> foo
|
|
type foo
|
|
del foo
|
|
echo1>foo
|
|
type foo
|
|
echo ...stdout appending
|
|
echo foo>foo
|
|
echo foo >>foo
|
|
type foo
|
|
del foo
|
|
echo foob >> foo
|
|
type foo
|
|
echo fooc 1>>foo
|
|
type foo
|
|
echo food1>>foo
|
|
type foo
|
|
echo food2>>foo
|
|
type foo
|
|
del foo
|
|
echo food21>>foo
|
|
type foo
|
|
del foo
|
|
echo foo> foo
|
|
echo foo7 7>> foo || (echo not supported & del foo)
|
|
if exist foo (type foo) else echo not supported
|
|
echo ...redirections within IF statements
|
|
if 1==1 echo foo1>bar
|
|
type bar & del bar
|
|
if 1==1 (echo foo2>bar) else echo baz2>bar
|
|
type bar & del bar
|
|
if 1==1 (echo foo3) else echo baz3>bar
|
|
type bar || echo file does not exist, ok
|
|
if 1==1 (echo foo4>bar) else echo baz4>bar
|
|
type bar & del bar
|
|
if 1==0 (echo foo5>bar) else echo baz5>bar
|
|
type bar & del bar
|
|
if 1==0 (echo foo6) else echo baz6 1>bar
|
|
type bar & del bar
|
|
if 1==0 (echo foo7 1>bar) else echo baz7>bar
|
|
type bar & del bar
|
|
if 1==0 (echo foo8 1>bar) else echo baz8>bak
|
|
type bak
|
|
if 1==1 (echo foo>bar & echo baz)
|
|
type bar
|
|
if 1==1 (
|
|
echo foo>bar
|
|
echo baz
|
|
)
|
|
type bar
|
|
(if 1==1 (echo A) else echo B) > C
|
|
type C
|
|
(if 1==0 (echo A) else echo B) > C
|
|
type C
|
|
(if 1==0 (echo A > B) else echo C)
|
|
cd .. & rd /s/q foobar
|
|
|
|
echo ------------ Testing ^^ escape character --------------
|
|
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
|
|
echo ^hell^o, world
|
|
echo hell^o, world
|
|
echo hell^^o, world
|
|
echo hell^^^o, world
|
|
mkdir foobar
|
|
echo baz> foobar\baz
|
|
type foobar\baz
|
|
type foobar^\baz
|
|
rd /s/q foobar
|
|
echo foo ^| echo bar
|
|
echo foo ^& echo bar
|
|
call :setError 0
|
|
echo bak ^&& echo baz 2> nul
|
|
echo %ErrorLevel%
|
|
echo foo ^> foo
|
|
echo ^<> foo
|
|
type foo
|
|
del foo
|
|
set FOO=oof
|
|
echo ff^%FOO%
|
|
set FOO=bar ^| baz
|
|
set FOO
|
|
rem FIXME: echoing %FOO% gives an error (baz not recognized) but prematurely
|
|
rem exits the script on windows; redirecting stdout and/or stderr doesn't help
|
|
echo %ErrorLevel%
|
|
call :setError 0
|
|
set FOO=bar ^^^| baz
|
|
set FOO
|
|
echo %FOO%
|
|
echo %ErrorLevel%
|
|
set FOO=
|
|
|
|
echo ------------ Testing 'set' --------------
|
|
call :setError 0
|
|
set FOOBAR 2> nul > nul
|
|
echo %ErrorLevel%
|
|
set FOOBAR = baz
|
|
echo %ErrorLevel%
|
|
echo %FOOBAR%FOOBAR not defined
|
|
echo %FOOBAR %
|
|
set FOOBAR 2> nul
|
|
set FOOBAR = baz2
|
|
echo %ErrorLevel%
|
|
echo %fOObAr %
|
|
set FOOBAR= bar
|
|
echo %ErrorLevel%
|
|
echo %FOOBAR%
|
|
set FOO
|
|
set FOOBAR=
|
|
set FOOB
|
|
echo %FOOBAR%FOOBAR not defined
|
|
set FOOBAR =
|
|
set FOOBA 2> nul > nul
|
|
echo %ErrorLevel%
|
|
set FOO=bar
|
|
echo %FOO%
|
|
set FOO=foo
|
|
set BAR=bar
|
|
echo %FOO%%BAR%
|
|
set BAR=
|
|
set FOO=
|
|
set FOO=%FOO%
|
|
echo %FOO%FOO not defined
|
|
set BAZ%=bazbaz
|
|
set BA
|
|
echo %BAZ%%
|
|
set BAZ%=
|
|
echo set "FOO=bar" should not include the quotes in the variable value
|
|
set "FOO=bar"
|
|
echo %FOO%
|
|
set@tab@FOO=foo
|
|
echo %FOO%
|
|
set@tab@FOO=
|
|
echo '%FOO%'
|
|
set FOO=foo@space@
|
|
echo '%FOO%'
|
|
set FOO=foo@tab@
|
|
echo '%FOO%'
|
|
set FOO=
|
|
|
|
echo ------------ Testing variable expansion --------------
|
|
call :setError 0
|
|
echo ~dp0 should be directory containing batch file
|
|
echo %~dp0
|
|
mkdir dummydir
|
|
cd dummydir
|
|
echo %~dp0
|
|
cd ..
|
|
rmdir dummydir
|
|
echo CD value %CD%
|
|
echo %%
|
|
echo P%
|
|
echo %P
|
|
echo %UNKNOWN%S
|
|
echo P%UNKNOWN%
|
|
echo P%UNKNOWN%S
|
|
echo %ERRORLEVEL
|
|
echo %ERRORLEVEL%
|
|
echo %ERRORLEVEL%%ERRORLEVEL%
|
|
echo %ERRORLEVEL%ERRORLEVEL%
|
|
echo %ERRORLEVEL%%
|
|
echo %ERRORLEVEL%%%
|
|
echo P%ERRORLEVEL%
|
|
echo %ERRORLEVEL%S
|
|
echo P%ERRORLEVEL%S
|
|
|
|
echo ------------ Testing variable substrings --------------
|
|
set VAR=qwerty
|
|
echo %VAR:~0,1%
|
|
echo %VAR:~0,3%
|
|
echo %VAR:~2,2%
|
|
echo '%VAR:~-2,3%'
|
|
echo '%VAR:~-2,1%'
|
|
echo %VAR:~2,-1%
|
|
echo %VAR:~2,-3%
|
|
echo '%VAR:~-2,-4%'
|
|
echo %VAR:~-3,-2%
|
|
set VAR=
|
|
|
|
echo ------------ Testing variable substitution --------------
|
|
echo ...in FOR variables
|
|
for %%i in ("A B" C) do echo %%i
|
|
rem quotes removal
|
|
for %%i in ("A B" C) do echo '%%~i'
|
|
rem fully qualified path
|
|
for %%f in ("C D" E) do echo %%~ff
|
|
rem drive letter
|
|
for %%i in ("F G" H) do echo %%~di
|
|
rem path
|
|
for %%d in ("I J" K) do echo %%~pd
|
|
rem filename
|
|
for %%i in ("L M" N) do echo %%~ni
|
|
rem file extension
|
|
for %%i in ("O. P.OOL" Q.TABC hello) do echo '%%~xi'
|
|
rem path with short path names
|
|
for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do echo '%%~sI'
|
|
rem file attribute
|
|
for %%i in ("U V" W) do echo '%%~ai'
|
|
echo foo> foo
|
|
for %%i in (foo) do echo '%%~ai'
|
|
del foo
|
|
rem file date/time
|
|
rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar...
|
|
for %%i in ("a b" c) do echo '%%~ti'
|
|
rem file size
|
|
rem Similar issues as above
|
|
for %%i in ("a b" c) do echo '%%~zi'
|
|
rem combined options
|
|
for %%i in ("d e" f) do echo %%~dpi
|
|
for %%i in ("g h" i) do echo %%~sdi
|
|
for %%i in ("g h" i) do echo %%~dsi
|
|
for %%i in ("j k" l.eh) do echo '%%~xsi'
|
|
|
|
echo ...in parameters
|
|
for %%i in ("A B" C) do call :echoFun %%i
|
|
rem quotes removal
|
|
for %%i in ("A B" C) do call :echoFunQ %%i
|
|
rem fully qualified path
|
|
for %%f in ("C D" E) do call :echoFunF %%f
|
|
rem drive letter
|
|
for %%i in ("F G" H) do call :echoFunD %%i
|
|
rem path
|
|
for %%d in ("I J" K) do call :echoFunP %%d
|
|
rem filename
|
|
for %%i in ("L M" N) do call :echoFunN %%i
|
|
rem file extension
|
|
for %%i in ("O. P.OOL" Q.TABC hello) do call :echoFunX %%i
|
|
rem path with short path names
|
|
for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do call :echoFunS %%I
|
|
rem NT4 aborts whole script execution when encountering ~a, ~t and ~z substitutions, preventing full testing
|
|
rem combined options
|
|
for %%i in ("d e" f) do call :echoFunDP %%i
|
|
for %%i in ("g h" i) do call :echoFunSD %%i
|
|
for %%i in ("g h" i) do call :echoFunDS %%i
|
|
for %%i in ("j k" l.eh) do call :echoFunXS %%i
|
|
|
|
goto :endEchoFuns
|
|
:echoFun
|
|
echo %1
|
|
goto :eof
|
|
|
|
:echoFunQ
|
|
echo '%~1'
|
|
goto :eof
|
|
|
|
:echoFunF
|
|
echo %~f1
|
|
goto :eof
|
|
|
|
:echoFunD
|
|
echo %~d1
|
|
goto :eof
|
|
|
|
:echoFunP
|
|
echo %~p1
|
|
goto :eof
|
|
|
|
:echoFunN
|
|
echo %~n1
|
|
goto :eof
|
|
|
|
:echoFunX
|
|
echo '%~x1'
|
|
goto :eof
|
|
|
|
:echoFunS
|
|
rem some NT4 workaround
|
|
set VAR='%~s1'
|
|
echo %VAR%
|
|
set VAR=
|
|
goto :eof
|
|
|
|
:echoFunDP
|
|
echo %~dp1
|
|
goto :eof
|
|
|
|
:echoFunSD
|
|
echo %~sd1
|
|
goto :eof
|
|
|
|
:echoFunDS
|
|
echo %~ds1
|
|
goto :eof
|
|
|
|
:echoFunXS
|
|
echo '%~xs1'
|
|
goto :eof
|
|
:endEchoFuns
|
|
|
|
echo ------------ Testing variable delayed expansion --------------
|
|
rem NT4 doesn't support this
|
|
echo ...default mode (load-time expansion)
|
|
set FOO=foo
|
|
echo %FOO%
|
|
echo !FOO!
|
|
if %FOO% == foo (
|
|
set FOO=bar
|
|
if %FOO% == bar (echo bar) else echo foo
|
|
)
|
|
|
|
set FOO=foo
|
|
if %FOO% == foo (
|
|
set FOO=bar
|
|
if !FOO! == bar (echo bar) else echo foo
|
|
)
|
|
|
|
echo ...runtime (delayed) expansion mode
|
|
setlocal EnableDelayedExpansion
|
|
set FOO=foo
|
|
echo %FOO%
|
|
echo !FOO!
|
|
if %FOO% == foo (
|
|
set FOO=bar
|
|
if %FOO% == bar (echo bar) else echo foo
|
|
)
|
|
|
|
set FOO=foo
|
|
if %FOO% == foo (
|
|
set FOO=bar
|
|
if !FOO! == bar (echo bar) else echo foo
|
|
)
|
|
echo %ErrorLevel%
|
|
setlocal DisableDelayedExpansion
|
|
echo %ErrorLevel%
|
|
set FOO=foo
|
|
echo %FOO%
|
|
echo !FOO!
|
|
set FOO=
|
|
echo ...using /V cmd flag
|
|
echo @echo off> tmp.cmd
|
|
echo set FOO=foo>> tmp.cmd
|
|
echo echo %%FOO%%>> tmp.cmd
|
|
echo echo !FOO!>> tmp.cmd
|
|
echo set FOO=>> tmp.cmd
|
|
cmd /V:ON /C tmp.cmd
|
|
cmd /V:OfF /C tmp.cmd
|
|
del tmp.cmd
|
|
|
|
echo ------------ Testing conditional execution --------------
|
|
echo ...unconditional ^&
|
|
call :setError 123 & echo foo1
|
|
echo bar2 & echo foo2
|
|
mkdir foobar & cd foobar
|
|
echo > foobazbar
|
|
cd .. & rd /s/q foobar
|
|
if exist foobazbar (
|
|
echo foobar not deleted!
|
|
cd ..
|
|
rd /s/q foobar
|
|
) else echo foobar deleted
|
|
echo ...on success conditional ^&^&
|
|
call :setError 456 && echo foo3 > foo3
|
|
if exist foo3 (
|
|
echo foo3 created
|
|
del foo3
|
|
) else echo foo3 not created
|
|
echo bar4 && echo foo4
|
|
echo ...on failure conditional ^|^|
|
|
call :setError 789 || echo foo5
|
|
echo foo6 || echo bar6 > bar6
|
|
if exist bar6 (
|
|
echo bar6 created
|
|
del bar6
|
|
)
|
|
|
|
echo ------------ Testing cd ------------
|
|
mkdir foobar
|
|
cd foobar
|
|
echo blabla > singleFile
|
|
dir /b
|
|
echo Current dir: %CD%
|
|
cd
|
|
cd ..
|
|
cd
|
|
cd foobar@space@
|
|
cd
|
|
cd ..
|
|
cd
|
|
cd @space@foobar
|
|
cd
|
|
cd..
|
|
cd
|
|
cd foobar
|
|
cd..@space@
|
|
cd
|
|
if not exist foobar (cd ..)
|
|
cd foobar
|
|
cd@tab@..@tab@@space@@tab@
|
|
cd
|
|
if not exist foobar (cd ..)
|
|
cd foobar
|
|
mkdir "bar bak"
|
|
cd "bar bak"
|
|
cd
|
|
cd ..
|
|
cd bar bak
|
|
cd
|
|
cd "bar bak@space@"@tab@@space@
|
|
cd
|
|
cd ..\..
|
|
cd
|
|
rd /Q/s foobar
|
|
mkdir foobar
|
|
cd /d@tab@foobar
|
|
cd
|
|
cd ..
|
|
rd /q/s foobar
|
|
|
|
echo ------------ Testing type ------------
|
|
echo bar> foobaz
|
|
@echo on
|
|
type foobaz
|
|
echo ***
|
|
@echo off
|
|
type foobaz@tab@
|
|
echo ***
|
|
del foobaz
|
|
|
|
echo ------------ Testing NUL ------------
|
|
md foobar & cd foobar
|
|
rem NUL file (non) creation + case insensitivity
|
|
rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
|
|
echo > bar
|
|
echo foo > NUL
|
|
dir /b /a-d
|
|
echo foo > nul
|
|
dir /b /a-d
|
|
echo foo > NuL
|
|
@tab@dir /b@tab@/a-d
|
|
del bar
|
|
rem NUL not special everywhere
|
|
call :setError 123
|
|
echo NUL> foo
|
|
if not exist foo (echo foo should have been created) else (
|
|
type foo
|
|
del foo
|
|
)
|
|
rem Empty file creation
|
|
copy nul foo > nul
|
|
if exist foo (
|
|
echo foo created
|
|
del foo
|
|
type foo
|
|
) else (
|
|
echo ***
|
|
)
|
|
cd .. & rd foobar
|
|
|
|
echo ------------ Testing if/else --------------
|
|
echo if/else should work with blocks
|
|
if 0 == 0 (
|
|
echo if seems to work
|
|
) else (
|
|
echo if seems to be broken
|
|
)
|
|
if 1 == 0 (
|
|
echo else seems to be broken
|
|
) else (
|
|
echo else seems to work
|
|
)
|
|
if /c==/c (
|
|
echo if seems not to detect /c as parameter
|
|
) else (
|
|
echo parameter detection seems to be broken
|
|
)
|
|
echo Testing case sensitivity with and without /i option
|
|
if bar==BAR echo if does not default to case sensitivity
|
|
if not bar==BAR echo if seems to default to case sensitivity
|
|
if /i foo==FOO echo if /i seems to work
|
|
if /i not foo==FOO echo if /i seems to be broken
|
|
if /I foo==FOO echo if /I seems to work
|
|
if /I not foo==FOO echo if /I seems to be broken
|
|
echo Testing string comparisons
|
|
if abc == abc (echo equal) else echo non equal
|
|
if abc =="abc" (echo equal) else echo non equal
|
|
if "abc"== abc (echo equal) else echo non equal
|
|
if "abc"== "abc" (echo equal) else echo non equal
|
|
echo Testing tabs handling
|
|
if@tab@1==1 echo doom
|
|
if @tab@1==1 echo doom
|
|
if 1==1 (echo doom) else@tab@echo quake
|
|
if@tab@not @tab@1==@tab@0 @tab@echo lol
|
|
if 1==0@tab@(echo doom) else echo quake
|
|
if 1==0 (echo doom)@tab@else echo quake
|
|
if 1==0 (echo doom) else@tab@echo quake
|
|
|
|
echo -----------Testing for -----------
|
|
echo ...plain FOR
|
|
for %%i in (A B C) do echo %%i
|
|
for %%i in (A B C) do echo %%I
|
|
for %%i in (A B C) do echo %%j
|
|
for %%i in (A B C) do call :forTestFun1 %%i
|
|
for %%i in (1,4,1) do echo %%i
|
|
for %%i in (A, B,C) do echo %%i
|
|
for %%i in (X) do echo %%i
|
|
for@tab@%%i in (X2) do echo %%i
|
|
for %%i in@tab@(X3) do echo %%i
|
|
for %%i in (@tab@ foo@tab@) do echo %%i
|
|
for@tab@ %%i in@tab@(@tab@M) do echo %%i
|
|
for %%i@tab@in (X)@tab@do@tab@echo %%i
|
|
for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
|
|
for %%i in (`echo A B`) do echo %%i
|
|
for %%i in ('echo A B') do echo %%i
|
|
for %%i in ("echo A B") do echo %%i
|
|
for %%i in ("A B" C) do echo %%i
|
|
goto :endForTestFun1
|
|
:forTestFun1
|
|
echo %1
|
|
goto :eof
|
|
:endForTestFun1
|
|
echo ...imbricated FORs
|
|
for %%i in (X) do (
|
|
for %%j in (Y) do (
|
|
echo %%i %%j))
|
|
for %%i in (X) do (
|
|
for %%I in (Y) do (
|
|
echo %%i %%I))
|
|
for %%i in (A B) do (
|
|
for %%j in (C D) do (
|
|
echo %%i %%j))
|
|
for %%i in (A B) do (
|
|
for %%j in (C D) do (
|
|
call :forTestFun2 %%i %%j ))
|
|
goto :endForTestFun2
|
|
:forTestFun2
|
|
echo %1 %2
|
|
goto :eof
|
|
:endForTestFun2
|
|
mkdir foobar & cd foobar
|
|
mkdir foo
|
|
mkdir bar
|
|
mkdir baz
|
|
echo > bazbaz
|
|
echo ...basic wildcards
|
|
for %%i in (ba*) do echo %%i
|
|
echo ...for /d
|
|
for /d %%i in (baz foo bar) do echo %%i
|
|
rem FIXME for /d incorrectly parses when wildcards are used
|
|
rem for /d %%i in (bazb*) do echo %%i
|
|
rem FIXME can't test wildcard expansion here since it's listed in directory
|
|
rem order, and not in alphabetic order.
|
|
rem Proper testing would need a currently missing "sort" program implementation.
|
|
rem for /d %%i in (ba*) do echo %%i>> tmp
|
|
rem sort < tmp
|
|
rem del tmp
|
|
rem for /d %%i in (?a*) do echo %%i>> tmp
|
|
rem sort < tmp
|
|
rem del tmp
|
|
rem for /d %%i in (*) do echo %%i>> tmp
|
|
rem sort < tmp
|
|
rem del tmp
|
|
cd .. & rd /s/Q foobar
|
|
echo ...for /L
|
|
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
|
|
for /L %%i in (1,2,0) do echo %%i
|
|
for@tab@/L %%i in (1,2,0) do echo %%i
|
|
for /L %%i in (1,2,6) do echo %%i
|
|
for /l %%i in (1 ,2,6) do echo %%i
|
|
for /L %%i in (a,2,3) do echo %%i
|
|
for /L %%i in (1,2,-1) do echo %%i
|
|
for /L %%i in (-4,-1,-1) do echo %%i
|
|
for /L %%i in (1,-2,-2) do echo %%i
|
|
for /L %%i in (1,2,a) do echo %%i
|
|
echo ErrorLevel %ErrorLevel%
|
|
for /L %%i in (1,a,b) do echo %%i
|
|
echo ErrorLevel %ErrorLevel%
|
|
rem FIXME: following test cases cannot be currently tested due to an inconsistent/buggy 'for /L' parsing.
|
|
rem for /L %%i in (a,2,b) do echo %%i
|
|
rem for /L %%i in (1,1,1) do echo %%i
|
|
rem for /L %%i in (1,-2,-1) do echo %%i
|
|
rem for /L %%i in (-1,-1,-1) do echo %%i
|
|
rem for /L %%i in (1,2, 3) do echo %%i
|
|
echo ...for /a
|
|
rem No output when using "set expr" syntax, unless in interactive mode
|
|
rem Need to use "set envvar=expr" to use in a batch script
|
|
echo ......individual operations
|
|
set var=0
|
|
set /a var=1 +2 & echo %var%
|
|
set /a var=1 +-2 & echo %var%
|
|
set /a var=1 --2 & echo %var%
|
|
set /a var=2* 3 & echo %var%
|
|
set /a var=-2* -5 & echo %var%
|
|
set /a var=12/3 & echo %var%
|
|
set /a var=13/3 & echo %var%
|
|
set /a var=-13/3 & echo %var%
|
|
rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
|
|
set /a var=5 %% 5 & echo %var%
|
|
set /a var=5 %% 3 & echo %var%
|
|
set /a var=5 %% -3 & echo %var%
|
|
set /a var=-5 %% -3 & echo %var%
|
|
set /a var=1 ^<^< 0 & echo %var%
|
|
set /a var=1 ^<^< 2 & echo %var%
|
|
set /a var=1 ^<^< -2 & echo %var%
|
|
set /a var=-1 ^<^< -2 & echo %var%
|
|
set /a var=-1 ^<^< 2 & echo %var%
|
|
set /a var=9 ^>^> 0 & echo %var%
|
|
set /a var=9 ^>^> 2 & echo %var%
|
|
set /a var=9 ^>^> -2 & echo %var%
|
|
set /a var=-9 ^>^> -2 & echo %var%
|
|
set /a var=-9 ^>^> 2 & echo %var%
|
|
set /a var=5 ^& 0 & echo %var%
|
|
set /a var=5 ^& 1 & echo %var%
|
|
set /a var=5 ^& 3 & echo %var%
|
|
set /a var=5 ^& 4 & echo %var%
|
|
set /a var=5 ^& 1 & echo %var%
|
|
set /a var=5 ^| 0 & echo %var%
|
|
set /a var=5 ^| 1 & echo %var%
|
|
set /a var=5 ^| 3 & echo %var%
|
|
set /a var=5 ^| 4 & echo %var%
|
|
set /a var=5 ^| 1 & echo %var%
|
|
set /a var=5 ^^ 0 & echo %var%
|
|
set /a var=5 ^^ 1 & echo %var%
|
|
set /a var=5 ^^ 3 & echo %var%
|
|
set /a var=5 ^^ 4 & echo %var%
|
|
set /a var=5 ^^ 1 & echo %var%
|
|
echo ......precedence and grouping
|
|
set /a var=4 + 2*3 & echo %var%
|
|
set /a var=(4+2)*3 & echo %var%
|
|
set /a var=4 * 3/5 & echo %var%
|
|
set /a var=(4 * 3)/5 & echo %var%
|
|
set /a var=4 * 5 %% 4 & echo %var%
|
|
set /a var=4 * (5 %% 4) & echo %var%
|
|
set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
|
|
set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
|
|
echo ......octal and hexadecimal
|
|
set /a var=0xf + 3 & echo %var%
|
|
set /a var=0xF + 3 & echo %var%
|
|
set /a var=015 + 2 & echo %var%
|
|
set /a var=3, 8+3,0 & echo %var%
|
|
echo ......variables
|
|
set /a var=foo=3, foo+1 & echo %var%
|
|
if defined foo (echo %foo%) else (
|
|
echo foo not defined
|
|
)
|
|
set /a var=foo=3, foo+=1 & echo %var%
|
|
set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
|
|
set /a var=foo*= foo & echo %var%
|
|
set /a var=whateverNonExistingVar & echo %var%
|
|
set /a var=whateverNonExistingVar + bar & echo %var%
|
|
set /a var=foo -= foo + 7 & echo %var%
|
|
set /a var=foo /= 3 + 2 & echo %var%
|
|
set /a var=foo=5, foo %%=2 & echo %var%
|
|
set /a var=foo ^<^<= 2 & echo %var%
|
|
set /a var=foo ^>^>= 2 & echo %var%
|
|
set /a var=foo ^&= 2 & echo %var%
|
|
set /a var=foo=5, foo ^|= 2 & echo %var%
|
|
set /a var=foo=5, foo ^^= 2 & echo %var%
|
|
set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
|
|
set foo=
|
|
set bar=
|
|
set var=
|
|
echo ...for /F
|
|
mkdir foobar & cd foobar
|
|
echo ......string argument
|
|
for /F %%i in ("a b c") do echo %%i
|
|
for /f %%i in ("a ") do echo %%i
|
|
for /f %%i in ("a") do echo %%i
|
|
fOr /f %%i in (" a") do echo %%i
|
|
for /f %%i in (" a ") do echo %%i
|
|
echo ......fileset argument
|
|
echo .........basic blank handling
|
|
echo a b c>foo
|
|
for /f %%i in (foo) do echo %%i
|
|
echo a >foo
|
|
for /f %%i in (foo) do echo %%i
|
|
echo a>foo
|
|
for /f %%i in (foo) do echo %%i
|
|
echo a>foo
|
|
for /f %%i in (foo) do echo %%i
|
|
echo a >foo
|
|
for /f %%i in (foo) do echo %%i
|
|
echo. > foo
|
|
for /f %%i in (foo) do echo %%i
|
|
echo. >> foo
|
|
echo b > foo
|
|
for /f %%i in (foo) do echo %%i
|
|
echo .........multi-line with empty lines
|
|
echo a Z f> foo
|
|
echo. >> foo
|
|
echo.>> foo
|
|
echo b bC>> foo
|
|
echo c>> foo
|
|
echo. >> foo
|
|
for /f %%b in (foo) do echo %%b
|
|
echo .........multiple files
|
|
echo q w > bar
|
|
echo.>> bar
|
|
echo kkk>>bar
|
|
for /f %%k in (foo bar) do echo %%k
|
|
for /f %%k in (bar foo) do echo %%k
|
|
rem echo ......command argument
|
|
rem Not implemented on NT4
|
|
rem FIXME: Not testable right now in wine: not implemented and would need
|
|
rem preliminary grep-like program implementation (e.g. like findstr or fc) even
|
|
rem for a simple todo_wine test
|
|
rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported
|
|
rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported
|
|
echo ......eol option
|
|
for /f "eol=@" %%i in (" ad") do echo %%i
|
|
for /f "eol=@" %%i in (" z@y") do echo %%i
|
|
for /f "eol=|" %%i in ("a|d") do echo %%i
|
|
for /f "eol=@" %%i in ("@y") do echo %%i > output_file
|
|
if not exist output_file (echo no output) else (del output_file)
|
|
for /f "eol==" %%i in ("=y") do echo %%i > output_file
|
|
if not exist output_file (echo no output) else (del output_file)
|
|
echo ......delims option
|
|
for /f "delims=|" %%i in ("a|d") do echo %%i
|
|
for /f "delims=|" %%i in ("a |d") do echo %%i
|
|
for /f "delims=|" %%i in ("a d|") do echo %%i
|
|
for /f "delims=| " %%i in ("a d|") do echo %%i
|
|
for /f "delims==" %%i in ("C r=d|") do echo %%i
|
|
for /f "delims=" %%i in ("foo bar baz") do echo %%i
|
|
for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi
|
|
echo ......skip option
|
|
echo a > foo
|
|
echo b >> foo
|
|
echo c >> foo
|
|
for /f "skip=2" %%i in (foo) do echo %%i
|
|
for /f "skip=3" %%i in (foo) do echo %%i > output_file
|
|
if not exist output_file (echo no output) else (del output_file)
|
|
for /f "skip=4" %%i in (foo) do echo %%i > output_file
|
|
if not exist output_file (echo no output) else (del output_file)
|
|
cd ..
|
|
rd /s/q foobar
|
|
|
|
echo -----------Testing del /a-----------
|
|
del /f/q *.test > nul
|
|
echo r > r.test
|
|
attrib +r r.test
|
|
echo not-r > not-r.test
|
|
|
|
if not exist not-r.test echo not-r.test not found before delete, bad
|
|
del /a:-r *.test
|
|
if not exist not-r.test echo not-r.test not found after delete, good
|
|
|
|
if not exist r.test echo r.test not found before delete, bad
|
|
if exist r.test echo r.test found before delete, good
|
|
del /a:r *.test
|
|
if not exist r.test echo r.test not found after delete, good
|
|
if exist r.test echo r.test found after delete, bad
|
|
|
|
echo ------------ Testing del /q --------------
|
|
mkdir del_q_dir
|
|
cd del_q_dir
|
|
echo abc > file1
|
|
echo abc > file2.dat
|
|
rem If /q doesn't work, cmd will prompt and the test case should hang
|
|
del /q * > nul
|
|
for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
|
|
for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
|
|
cd ..
|
|
rmdir del_q_dir
|
|
|
|
echo ------------ Testing del /s --------------
|
|
mkdir "foo bar"
|
|
cd "foo bar"
|
|
mkdir "foo:"
|
|
echo hi > file1.dat
|
|
echo there > file2.dat
|
|
echo bub > file3.dat
|
|
echo bye > "file with spaces.dat"
|
|
cd ..
|
|
del /s file1.dat > nul
|
|
del file2.dat /s > nul
|
|
del "file3.dat" /s > nul
|
|
del "file with spaces.dat" /s > nul
|
|
cd "foo bar"
|
|
for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
|
|
for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
|
|
if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
|
|
if exist "file with spaces.dat" del "file with spaces.dat"
|
|
rmdir "foo:"
|
|
cd ..
|
|
rmdir "foo bar"
|
|
|
|
echo ------------ Testing rename ------------
|
|
mkdir foobar & cd foobar
|
|
echo ... ren and rename are synonymous ...
|
|
echo > foo
|
|
rename foo bar
|
|
if exist foo echo foo should be renamed!
|
|
if exist bar echo foo renamed to bar
|
|
ren bar foo
|
|
if exist bar echo bar should be renamed!
|
|
if exist foo echo bar renamed to foo
|
|
echo ... name collision ...
|
|
echo foo>foo
|
|
echo bar>bar
|
|
ren foo bar 2> nul
|
|
type foo
|
|
type bar
|
|
rem no-op
|
|
ren foo foo
|
|
mkdir baz
|
|
ren foo baz\abc
|
|
echo ... rename read-only files ...
|
|
echo > file1
|
|
attrib +r file1
|
|
ren file1 file2
|
|
if not exist file1 (
|
|
if exist file2 (
|
|
echo read-only file renamed
|
|
)
|
|
) else (
|
|
echo read-only file not renamed!
|
|
)
|
|
echo ... rename directories ...
|
|
mkdir rep1
|
|
ren rep1 rep2
|
|
if not exist rep1 (
|
|
if exist rep2 (
|
|
echo dir renamed
|
|
)
|
|
)
|
|
attrib +r rep2
|
|
ren rep2 rep1
|
|
if not exist rep2 (
|
|
if exist rep1 (
|
|
echo read-only dir renamed
|
|
)
|
|
)
|
|
echo ... rename in other directory ...
|
|
if not exist baz\abc (
|
|
echo rename impossible in other directory
|
|
if exist foo echo original file still present
|
|
) else (
|
|
echo shouldn't rename in other directory!
|
|
if not exist foo echo original file not present anymore
|
|
)
|
|
cd .. & rd /s/q foobar
|
|
|
|
echo ------------ Testing move ------------
|
|
mkdir foobar & cd foobar
|
|
echo ... file move ...
|
|
echo >foo
|
|
move foo bar > nul 2>&1
|
|
if not exist foo (
|
|
if exist bar (
|
|
echo file move succeeded
|
|
)
|
|
)
|
|
echo bar>bar
|
|
echo baz> baz
|
|
move /Y bar baz > nul 2>&1
|
|
if not exist bar (
|
|
if exist baz (
|
|
echo file move with overwrite succeeded
|
|
)
|
|
) else (
|
|
echo file overwrite impossible!
|
|
del bar
|
|
)
|
|
type baz
|
|
|
|
attrib +r baz
|
|
move baz bazro > nul 2>&1
|
|
if not exist baz (
|
|
if exist bazro (
|
|
echo read-only files are moveable
|
|
move bazro baz > nul 2>&1
|
|
)
|
|
) else (
|
|
echo read-only file not moved!
|
|
)
|
|
attrib -r baz
|
|
mkdir rep
|
|
move baz rep > nul 2>&1
|
|
if not exist baz (
|
|
if exist rep\baz (
|
|
echo file moved in subdirectory
|
|
)
|
|
)
|
|
call :setError 0
|
|
move rep\baz . > nul 2>&1
|
|
move /Y baz baz > nul 2>&1
|
|
if errorlevel 1 (
|
|
echo moving a file to itself should be a no-op!
|
|
) else (
|
|
echo moving a file to itself is a no-op
|
|
)
|
|
echo ErrorLevel: %ErrorLevel%
|
|
call :setError 0
|
|
del baz
|
|
echo ... directory move ...
|
|
mkdir foo\bar
|
|
mkdir baz
|
|
echo baz2>baz\baz2
|
|
move baz foo\bar > nul 2>&1
|
|
if not exist baz (
|
|
if exist foo\bar\baz\baz2 (
|
|
echo simple directory move succeeded
|
|
)
|
|
)
|
|
call :setError 0
|
|
mkdir baz
|
|
move baz baz > nul 2>&1
|
|
echo moving a directory to itself gives error; errlevel %ErrorLevel%
|
|
echo ...... dir in dir move ......
|
|
rd /s/q foo
|
|
mkdir foo bar
|
|
echo foo2>foo\foo2
|
|
echo bar2>bar\bar2
|
|
move foo bar > nul 2>&1
|
|
if not exist foo (
|
|
if exist bar (
|
|
dir /b /ad bar
|
|
dir /b /a-d bar
|
|
dir /b bar\foo
|
|
)
|
|
)
|
|
cd .. & rd /s/q foobar
|
|
|
|
echo ------------ Testing mkdir ------------
|
|
call :setError 0
|
|
echo ... md and mkdir are synonymous ...
|
|
mkdir foobar
|
|
echo %ErrorLevel%
|
|
rmdir foobar
|
|
md foobar
|
|
echo %ErrorLevel%
|
|
rmdir foobar
|
|
echo ... creating an already existing directory/file must fail ...
|
|
mkdir foobar
|
|
md foobar
|
|
echo %ErrorLevel%
|
|
rmdir foobar
|
|
echo > foobar
|
|
mkdir foobar
|
|
echo %ErrorLevel%
|
|
del foobar
|
|
echo ... multilevel path creation ...
|
|
mkdir foo
|
|
echo %ErrorLevel%
|
|
mkdir foo\bar\baz
|
|
echo %ErrorLevel%
|
|
cd foo
|
|
echo %ErrorLevel%
|
|
cd bar
|
|
echo %ErrorLevel%
|
|
cd baz
|
|
echo %ErrorLevel%
|
|
echo > ..\..\bar2
|
|
mkdir ..\..\..\foo\bar2
|
|
echo %ErrorLevel%
|
|
del ..\..\bar2
|
|
mkdir ..\..\..\foo\bar2
|
|
echo %ErrorLevel%
|
|
rmdir ..\..\..\foo\bar2
|
|
cd ..
|
|
rmdir baz
|
|
cd ..
|
|
rmdir bar
|
|
cd ..
|
|
rmdir foo
|
|
echo %ErrorLevel%
|
|
echo ... trailing backslashes ...
|
|
mkdir foo\\\\
|
|
echo %ErrorLevel%
|
|
if exist foo (rmdir foo & echo dir created
|
|
) else ( echo dir not created )
|
|
echo %ErrorLevel%
|
|
echo ... invalid chars ...
|
|
mkdir ?
|
|
echo mkdir ? gives errorlevel %ErrorLevel%
|
|
call :setError 0
|
|
mkdir ?\foo
|
|
echo mkdir ?\foo gives errorlevel %ErrorLevel%
|
|
call :setError 0
|
|
mkdir foo\?
|
|
echo mkdir foo\? gives errorlevel %ErrorLevel%
|
|
if exist foo (rmdir foo & echo ok, foo created
|
|
) else ( echo foo not created )
|
|
call :setError 0
|
|
mkdir foo\bar\?
|
|
echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
|
|
call :setError 0
|
|
if not exist foo (
|
|
echo bad, foo not created
|
|
) else (
|
|
cd foo
|
|
if exist bar (
|
|
echo ok, foo\bar created
|
|
rmdir bar
|
|
)
|
|
cd ..
|
|
rmdir foo
|
|
)
|
|
echo ... multiple directories at once ...
|
|
mkdir foobaz & cd foobaz
|
|
mkdir foo bar\baz foobar
|
|
if exist foo (echo foo created) else echo foo not created!
|
|
if exist bar (echo bar created) else echo bar not created!
|
|
if exist foobar (echo foobar created) else echo foobar not created!
|
|
if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
|
|
cd .. & rd /s/q foobaz
|
|
call :setError 0
|
|
mkdir foo\*
|
|
echo mkdir foo\* errorlevel %ErrorLevel%
|
|
if exist foo (rmdir foo & echo ok, foo created
|
|
) else ( echo bad, foo not created )
|
|
|
|
echo ----------- Testing rmdir -----------
|
|
call :setError 0
|
|
rem rd and rmdir are synonymous
|
|
mkdir foobar
|
|
rmdir foobar
|
|
echo %ErrorLevel%
|
|
if not exist foobar echo dir removed
|
|
mkdir foobar
|
|
rd foobar
|
|
echo %ErrorLevel%
|
|
if not exist foobar echo dir removed
|
|
rem Removing nonexistent directory
|
|
rmdir foobar
|
|
echo %ErrorLevel%
|
|
rem Removing single-level directories
|
|
echo > foo
|
|
rmdir foo
|
|
echo %ErrorLevel%
|
|
if exist foo echo file not removed
|
|
del foo
|
|
mkdir foo
|
|
echo > foo\bar
|
|
rmdir foo
|
|
echo %ErrorLevel%
|
|
if exist foo echo non-empty dir not removed
|
|
del foo\bar
|
|
mkdir foo\bar
|
|
rmdir foo
|
|
echo %ErrorLevel%
|
|
if exist foo echo non-empty dir not removed
|
|
rmdir foo\bar
|
|
rmdir foo
|
|
rem Recursive rmdir
|
|
mkdir foo\bar\baz
|
|
rmdir /s /Q foo
|
|
if not exist foo (
|
|
echo recursive rmdir succeeded
|
|
) else (
|
|
rd foo\bar\baz
|
|
rd foo\bar
|
|
rd foo
|
|
)
|
|
mkdir foo\bar\baz
|
|
echo foo > foo\bar\brol
|
|
rmdir /s /Q foo
|
|
if not exist foo (
|
|
echo recursive rmdir succeeded
|
|
) else (
|
|
rd foo\bar\baz
|
|
del foo\bar\brol
|
|
rd foo\bar
|
|
rd foo
|
|
)
|
|
rem multiples directories at once
|
|
mkdir foobaz & cd foobaz
|
|
mkdir foo
|
|
mkdir bar\baz
|
|
mkdir foobar
|
|
rd /s/q foo bar foobar
|
|
if not exist foo (echo foo removed) else echo foo not removed!
|
|
if not exist bar (echo bar removed) else echo bar not removed!
|
|
if not exist foobar (echo foobar removed) else echo foobar not removed!
|
|
if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
|
|
cd .. & rd /s/q foobaz
|
|
|
|
echo ----------- Testing pushd/popd -----------
|
|
cd
|
|
echo ...popd is no-op when dir stack is empty
|
|
popd
|
|
cd
|
|
echo ...pushing non-existing dir
|
|
pushd foobar
|
|
cd
|
|
echo ...basic behaviour
|
|
mkdir foobar\baz
|
|
pushd foobar
|
|
cd
|
|
popd
|
|
cd
|
|
pushd foobar
|
|
pushd baz
|
|
cd
|
|
popd
|
|
cd
|
|
pushd baz
|
|
popd
|
|
cd
|
|
popd
|
|
cd
|
|
pushd .
|
|
cd foobar\baz
|
|
pushd ..
|
|
cd
|
|
popd
|
|
popd
|
|
cd
|
|
rd /s/q foobar
|
|
|
|
echo ------------ Testing attrib --------------
|
|
rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications
|
|
mkdir foobar & cd foobar
|
|
echo foo original contents> foo
|
|
attrib foo
|
|
echo > bar
|
|
echo ... read-only attribute
|
|
rem Read-only files cannot be altered or deleted, unless forced
|
|
attrib +R foo
|
|
attrib foo
|
|
dir /Ar /B
|
|
echo bar>> foo
|
|
type foo
|
|
del foo > NUL 2>&1
|
|
if exist foo (
|
|
echo Read-only file not deleted
|
|
) else (
|
|
echo Should not delete read-only file!
|
|
)
|
|
del /F foo
|
|
if not exist foo (
|
|
echo Read-only file forcibly deleted
|
|
) else (
|
|
echo Should delete read-only file with del /F!
|
|
attrib -r foo
|
|
del foo
|
|
)
|
|
cd .. & rd /s/q foobar
|
|
echo ... recursive behaviour
|
|
mkdir foobar\baz & cd foobar
|
|
echo > level1
|
|
echo > whatever
|
|
echo > baz\level2
|
|
attrib baz\level2
|
|
cd ..
|
|
attrib +R l*vel? /S > nul 2>&1
|
|
cd foobar
|
|
attrib level1
|
|
attrib baz\level2
|
|
echo > bar
|
|
attrib bar
|
|
cd .. & rd /s/q foobar
|
|
echo ... folders processing
|
|
mkdir foobar
|
|
attrib foobar
|
|
cd foobar
|
|
mkdir baz
|
|
echo toto> baz\toto
|
|
attrib +r baz /s /d > nul 2>&1
|
|
attrib baz
|
|
attrib baz\toto
|
|
echo lulu>>baz\toto
|
|
type baz\toto
|
|
echo > baz\lala
|
|
rem Oddly windows allows file creation in a read-only directory...
|
|
if exist baz\lala (echo file created in read-only dir) else echo file not created
|
|
cd .. & rd /s/q foobar
|
|
|
|
echo ------------ Testing assoc --------------
|
|
rem FIXME Can't test error messages in the current test system, so we have to use some kludges
|
|
rem FIXME Revise once || conditional execution is fixed
|
|
mkdir foobar & cd foobar
|
|
echo ...setting association
|
|
assoc .foo > baz
|
|
type baz
|
|
echo ***
|
|
|
|
assoc .foo=bar
|
|
assoc .foo
|
|
|
|
rem association set system-wide
|
|
echo @echo off> tmp.cmd
|
|
echo echo +++>> tmp.cmd
|
|
echo assoc .foo>> tmp.cmd
|
|
cmd /c tmp.cmd
|
|
|
|
echo ...resetting association
|
|
assoc .foo=
|
|
assoc .foo > baz
|
|
type baz
|
|
echo ***
|
|
|
|
rem association removal set system-wide
|
|
cmd /c tmp.cmd > baz
|
|
type baz
|
|
echo ***
|
|
cd .. & rd /s/q foobar
|
|
|
|
echo ------------ Testing ftype --------------
|
|
rem FIXME Can't test error messages in the current test system, so we have to use some kludges
|
|
rem FIXME Revise once || conditional execution is fixed
|
|
mkdir foobar & cd foobar
|
|
echo ...setting association
|
|
ftype footype> baz
|
|
type baz
|
|
echo ***
|
|
|
|
ftype footype=foo_opencmd
|
|
assoc .foo=footype
|
|
ftype footype
|
|
|
|
rem association set system-wide
|
|
echo @echo off> tmp.cmd
|
|
echo echo +++>> tmp.cmd
|
|
echo ftype footype>> tmp.cmd
|
|
cmd /c tmp.cmd
|
|
|
|
echo ...resetting association
|
|
assoc .foo=
|
|
|
|
rem Removing a file type association doesn't work on XP due to a bug, so a workaround is needed
|
|
setlocal EnableDelayedExpansion
|
|
set FOO=original value
|
|
ftype footype=
|
|
ftype footype > baz
|
|
for /F %%i in ('type baz') do (set FOO=buggyXP)
|
|
rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion)
|
|
rem FIXME Revisit once a grep-like program like ftype is implemented
|
|
rem (e.g. to check baz's size using dir /b instead)
|
|
echo !FOO!
|
|
|
|
rem cleanup registry
|
|
echo REGEDIT4> regCleanup.reg
|
|
echo.>> regCleanup.reg
|
|
echo [-HKEY_CLASSES_ROOT\footype]>> regCleanup.reg
|
|
regedit /s regCleanup.reg
|
|
set FOO=
|
|
endlocal
|
|
cd .. & rd /s/q foobar
|
|
|
|
echo ------------ Testing CALL ------------
|
|
mkdir foobar & cd foobar
|
|
echo ... external script ...
|
|
echo echo foo %%1> foo.cmd
|
|
call foo
|
|
call foo.cmd 8
|
|
echo echo %%1 %%2 > foo.cmd
|
|
call foo.cmd foo
|
|
call foo.cmd foo bar
|
|
call foo.cmd foo ""
|
|
call foo.cmd "" bar
|
|
call foo.cmd foo ''
|
|
call foo.cmd '' bar
|
|
del foo.cmd
|
|
|
|
echo ... internal routines ...
|
|
call :testRoutine :testRoutine
|
|
goto :endTestRoutine
|
|
:testRoutine
|
|
echo bar %1
|
|
goto :eof
|
|
:endTestRoutine
|
|
|
|
call :testRoutineArgs foo
|
|
call :testRoutineArgs foo bar
|
|
call :testRoutineArgs foo ""
|
|
call :testRoutineArgs "" bar
|
|
call :testRoutineArgs foo ''
|
|
call :testRoutineArgs '' bar
|
|
goto :endTestRoutineArgs
|
|
:testRoutineArgs
|
|
echo %1 %2
|
|
goto :eof
|
|
:endTestRoutineArgs
|
|
|
|
echo ... with builtins ...
|
|
call mkdir foo
|
|
echo %ErrorLevel%
|
|
if exist foo (echo foo created) else echo foo should exist!
|
|
rmdir foo
|
|
set FOOBAZ_VAR=foobaz
|
|
call echo Should expand %FOOBAZ_VAR%
|
|
set FOOBAZ_VAR=
|
|
echo>batfile
|
|
call dir /b
|
|
echo>robinfile
|
|
if 1==1 call del batfile
|
|
dir /b
|
|
if exist batfile echo batfile shouldn't exist
|
|
rem ... but not for 'if' or 'for'
|
|
call if 1==1 echo bar 2> nul
|
|
echo %ErrorLevel%
|
|
call :setError 0
|
|
call for %%i in (foo bar baz) do echo %%i 2> nul
|
|
echo %ErrorLevel%
|
|
rem First look for programs in the path before trying a builtin
|
|
echo echo non-builtin dir> dir.cmd
|
|
call dir /b
|
|
cd .. & rd /s/q foobar
|
|
|
|
echo ------------ Testing SHIFT ------------
|
|
|
|
call :shiftFun p1 p2 p3 p4 p5
|
|
goto :endShiftFun
|
|
|
|
:shiftFun
|
|
echo '%1' '%2' '%3' '%4' '%5'
|
|
shift
|
|
echo '%1' '%2' '%3' '%4' '%5'
|
|
shift@tab@ /1
|
|
echo '%1' '%2' '%3' '%4' '%5'
|
|
shift /2
|
|
echo '%1' '%2' '%3' '%4' '%5'
|
|
shift /-1
|
|
echo '%1' '%2' '%3' '%4' '%5'
|
|
shift /0
|
|
echo '%1' '%2' '%3' '%4' '%5'
|
|
goto :eof
|
|
:endShiftFun
|
|
|
|
echo ------------ Testing cmd invocation ------------
|
|
rem FIXME: only a stub ATM
|
|
echo ... a batch file can delete itself ...
|
|
echo del foo.cmd>foo.cmd
|
|
cmd /q /c foo.cmd
|
|
if not exist foo.cmd (
|
|
echo file correctly deleted
|
|
) else (
|
|
echo file should be deleted!
|
|
del foo.cmd
|
|
)
|
|
echo ... a batch file can alter itself ...
|
|
echo echo bar^>foo.cmd>foo.cmd
|
|
cmd /q /c foo.cmd > NUL 2>&1
|
|
if exist foo.cmd (
|
|
type foo.cmd
|
|
del foo.cmd
|
|
) else (
|
|
echo file not created!
|
|
)
|
|
|
|
echo ------------ Testing setlocal/endlocal ------------
|
|
call :setError 0
|
|
rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test section
|
|
mkdir foobar & cd foobar
|
|
echo ...enable/disable extensions
|
|
setlocal DisableEXTensions
|
|
echo ErrLev: %ErrorLevel%
|
|
endlocal
|
|
echo ErrLev: %ErrorLevel%
|
|
echo @echo off> tmp.cmd
|
|
echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
|
|
rem Enabled by default
|
|
cmd /C tmp.cmd
|
|
cmd /E:OfF /C tmp.cmd
|
|
cmd /e:oN /C tmp.cmd
|
|
|
|
rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
|
|
echo ...setlocal with corresponding endlocal
|
|
echo @echo off> test.cmd
|
|
echo echo %%VAR%%>> test.cmd
|
|
echo setlocal>> test.cmd
|
|
echo set VAR=localval>> test.cmd
|
|
echo echo %%VAR%%>> test.cmd
|
|
echo endlocal>> test.cmd
|
|
echo echo %%VAR%%>> test.cmd
|
|
set VAR=globalval
|
|
call test.cmd
|
|
echo %VAR%
|
|
set VAR=
|
|
echo ...setlocal with no corresponding endlocal
|
|
echo @echo off> test.cmd
|
|
echo echo %%VAR%%>> test.cmd
|
|
echo setlocal>> test.cmd
|
|
echo set VAR=localval>> test.cmd
|
|
echo echo %%VAR%%>> test.cmd
|
|
set VAR=globalval
|
|
call test.cmd
|
|
echo %VAR%
|
|
set VAR=
|
|
cd .. & rd /q/s foobar
|
|
|
|
echo -----------Testing Errorlevel-----------
|
|
rem WARNING: Do *not* add tests using ErrorLevel after this section
|
|
should_not_exist 2> nul > nul
|
|
echo %ErrorLevel%
|
|
rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
|
|
rem See http://www.robvanderwoude.com/exit.php
|
|
call :setError 1
|
|
echo %ErrorLevel%
|
|
if errorlevel 2 echo errorlevel too high, bad
|
|
if errorlevel 1 echo errorlevel just right, good
|
|
if errorlevel 01 echo errorlevel with leading zero just right, good
|
|
if errorlevel -1 echo errorlevel with negative number OK
|
|
if errorlevel 0x1 echo hexa should not be recognized!
|
|
if errorlevel 1a echo invalid error level recognized!
|
|
call :setError 0
|
|
echo abc%ErrorLevel%def
|
|
if errorlevel 1 echo errorlevel nonzero, bad
|
|
if not errorlevel 1 echo errorlevel zero, good
|
|
if not errorlevel 0x1 echo hexa should not be recognized!
|
|
if not errorlevel 1a echo invalid error level recognized!
|
|
rem Now verify that setting a real variable hides its magic variable
|
|
set errorlevel=7
|
|
echo %ErrorLevel% should be 7
|
|
if errorlevel 7 echo setting var worked too well, bad
|
|
call :setError 3
|
|
echo %ErrorLevel% should still be 7
|
|
|
|
echo -----------Testing GOTO-----------
|
|
if a==a goto dest1
|
|
:dest1
|
|
echo goto with no leading space worked
|
|
if b==b goto dest2
|
|
:dest2
|
|
echo goto with a leading space worked
|
|
if c==c goto dest3
|
|
:dest3
|
|
echo goto with a leading tab worked
|
|
if d==d goto dest4
|
|
:dest4@space@
|
|
echo goto with a following space worked
|
|
|
|
echo ---------- Testing combined CALLs/GOTOs -----------
|
|
echo @echo off>foo.cmd
|
|
echo goto :eof>>foot.cmd
|
|
echo :eof>>foot.cmd
|
|
echo echo world>>foo.cmd
|
|
|
|
echo @echo off>foot.cmd
|
|
echo echo cheball>>foot.cmd
|
|
echo.>>foot.cmd
|
|
echo call :bar>>foot.cmd
|
|
echo if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmd
|
|
echo goto :eof>>foot.cmd
|
|
echo.>>foot.cmd
|
|
echo :bar>>foot.cmd
|
|
echo echo barbare>>foot.cmd
|
|
echo goto :eof>>foot.cmd
|
|
|
|
call foo.cmd
|
|
call foot
|
|
call :bar
|
|
del foo.cmd
|
|
rem Script execution stops after the following line
|
|
foot deleteMe
|
|
call :foo
|
|
call :foot
|
|
goto :endFuns
|
|
|
|
:foot
|
|
echo foot
|
|
|
|
:foo
|
|
echo foo
|
|
goto :eof
|
|
|
|
:endFuns
|
|
|
|
:bar
|
|
echo bar
|
|
call :foo
|
|
|
|
:baz
|
|
echo baz
|
|
goto :eof
|
|
|
|
echo Final message is not output since earlier 'foot' processing stops script execution
|
|
echo Do NOT add any tests below this line
|
|
|
|
echo -----------Done, jumping to EOF-----------
|
|
goto :eof
|
|
rem Subroutine to set errorlevel and return
|
|
rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
|
|
:setError
|
|
exit /B %1
|
|
rem This line runs under cmd in windows NT 4, but not in more modern versions.
|