1echo Tests for cmd's builtin commands 2 3@echo on 4echo ------------ Testing 'echo' [ON] ------------ 5echo word 6echo 'singlequotedword' 7echo "doublequotedword" 8@echo at-echoed-word 9echo "/?" 10echo. 11echo . 12echo.word 13echo .word 14echo: 15echo : 16echo:word 17echo :word 18echo/ 19echo / 20echo/word 21echo /word 22echo off now 23echo word@space@ 24echo word@space@@space@ 25 echo word 26echo@tab@word 27echo@tab@word @tab@ 28echo@tab@word@tab@@space@ 29@tab@echo word 30echo @tab@word 31echo @tab@word 32echo@tab@@tab@word 33echo @tab@ on @space@ 34@echo --- @ with chains and brackets 35(echo the @ character chains until&&@echo we leave the current depth||( 36echo hidden 37@echo hidden 38))&&echo and can hide brackets||(@echo command hidden)||@(echo brackets hidden) 39@echo --- 40 41@echo off 42echo off@tab@@space@ 43@echo noecho1 44 @echo noecho2 45@@@@@echo echo3 46echo ------------ Testing 'echo' [OFF] ------------ 47echo word 48echo 'singlequotedword' 49echo "doublequotedword" 50@echo at-echoed-word 51echo "/?" 52echo. 53echo . 54echo.word 55echo .word 56echo: 57echo : 58echo:word 59echo :word 60echo/ 61echo / 62echo/word 63echo /word 64echo on again 65echo word@space@ 66echo word@space@@space@ 67 echo word 68echo@tab@word 69echo@tab@word @tab@ 70echo@tab@word@tab@@space@ 71@tab@echo word 72echo @tab@word 73echo @tab@word 74echo@tab@@tab@word 75 76echo ------------ Testing mixed echo modes ------------ 77echo @echo on> mixedEchoModes.cmd 78echo if 1==1 echo foo>> mixedEchoModes.cmd 79echo if 1==1 @echo bar>> mixedEchoModes.cmd 80echo @echo off>> mixedEchoModes.cmd 81echo if 1==1 echo foo2>> mixedEchoModes.cmd 82echo if 1==1 @echo bar2>> mixedEchoModes.cmd 83type mixedEchoModes.cmd 84cmd /c mixedEchoModes.cmd 85del mixedEchoModes.cmd 86 87echo ------------ Testing parameterization ------------ 88call :TestParm a b c 89call :TestParm "a b c" 90call :TestParm "a b"\c 91call :TestParm a=~`+,.{}!+b 92call :TestParm a;b 93call :TestParm "a;b" 94call :TestParm a^;b 95call :TestParm a[b]{c}(d)e 96call :TestParm a&echo second line 97call :TestParm a b,,,c 98call :TestParm a==b;;c 99call :TestParm a,,, b 100goto :TestRem 101 102:TestParm 103echo '%1', '%2', '%3' 104goto :eof 105 106:TestRem 107echo ------------ Testing rem ------------ 108rem Hello 109rem Hello 110rem Hello || foo 111rem echo lol 112rem echo foo & echo bar 113rem @tab@ Hello 114rem@tab@ Hello 115rem@tab@echo foo & echo bar 116@echo on 117rem Hello 118rem Hello 119rem Hello || foo 120rem echo lol 121rem echo foo & echo bar 122rem @tab@ Hello 123rem@tab@ Hello 124rem@tab@echo foo & echo bar 125@echo off 126 127echo ------------ Testing redirection operators ------------ 128mkdir foobar & cd foobar 129echo --- stdout redirection 130echo foo>foo 131type foo 132echo foo 1> foo 133type foo 134echo foo@tab@1> foo 135type foo 136echo foo 1>@tab@foo 137type foo 138echo foo@tab@1>@tab@foo 139type foo 140echo foo7 7> foo 141type foo 142echo foo9 9> foo 143type foo 144echo foo1> foo 145type foo 146echo foo11> foo 147type foo 148echo foo12> foo 149type foo 150echo foo13>"foo" 151type foo 152echo foo14>."\foo" 153type foo 154echo foo15>."\f"oo 155type foo 156del foo 157echo1>foo 158type foo 159echo --- stdout appending 160echo foo>foo 161echo foo >>foo 162type foo 163del foo 164echo foob >> foo 165type foo 166echo fooc 1>>foo 167type foo 168echo food1>>foo 169type foo 170echo food2>>"foo" 171type foo 172del foo 173echo food21>>foo 174type foo 175del foo 176echo foo> foo 177echo foo7 7>> foo || (echo not supported & del foo) 178if exist foo (type foo) else echo not supported 179echo --- redirections within IF statements 180if 1==1 echo foo1>bar 181type bar & del bar 182if 1==1 echo foo2>>bar 183type bar & del bar 184echo ----- 185if 1==1 (echo foo2>bar) else echo baz2>bar 186type bar & del bar 187if 1==1 (echo foo3) else echo baz3>bar 188type bar || echo file does not exist, ok 189if 1==1 (echo foo4>bar) else echo baz4>bar 190type bar & del bar 191if 1==0 (echo foo5>bar) else echo baz5>bar 192type bar & del bar 193if 1==0 (echo foo6) else echo baz6 1>bar 194type bar & del bar 195if 1==0 (echo foo7 1>bar) else echo baz7>bar 196type bar & del bar 197if 1==0 (echo foo8 1>bar) else echo baz8>bak 198type bak 199if 1==1 (echo foo>bar & echo baz) 200type bar 201if 1==1 ( 202 echo foo>bar 203 echo baz 204) 205type bar 206(if 1==1 (echo A) else echo B) > C 207type C 208(if 1==0 (echo A) else echo B) > C 209type C 210(if 1==0 (echo A > B) else echo C) 211cd .. & rd /s/q foobar 212 213echo ------------ Testing circumflex escape character ------------ 214rem 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 215echo ^hell^o, world 216echo hell^o, world 217echo hell^^o, world 218echo hell^^^o, world 219echo hello^ 220world 221echo hello^ 222 223world 224echo hello^ 225 226 227echo finished 228mkdir foobar 229echo baz> foobar\baz 230type foobar\baz 231type foobar^\baz 232rd /s/q foobar 233echo foo ^| echo bar 234echo foo ^& echo bar 235call :setError 0 236echo bak ^&& echo baz 2> nul 237echo %ErrorLevel% 238echo foo ^> foo 239echo ^<> foo 240type foo 241del foo 242set WINE_FOO=oof 243echo ff^%WINE_FOO% 244set WINE_FOO=bar ^| baz 245set WINE_FOO 246rem FIXME: echoing %WINE_FOO% gives an error (baz not recognized) but prematurely 247rem exits the script on windows; redirecting stdout and/or stderr doesn't help 248echo %ErrorLevel% 249call :setError 0 250set WINE_FOO=bar ^^^| baz 251set WINE_FOO 252echo %WINE_FOO% 253echo %ErrorLevel% 254set WINE_FOO= 255 256echo ------------ Testing chains ------------ 257rem The chain operators have the following bottom-up precedence: 258rem 'else' precedes nothing and matches the closest unmatched 'if' in the same bracket depth 259rem '&' precedes 'else' 260rem '||' precedes '&' and 'else' 261rem '&&' precedes '||', '&' and 'else' 262rem '|' precedes '&&', '||', '&' and 'else' 263rem 264rem Example: 'if 1==1 if 2==2 if 3==3 a | b && c || d & e else f else g' is interpreted as 265rem 'if 1==1 (if 2==2 (if 3==3 ((((a | b) && c) || d) & e) else f) else g)' 266goto :cfailend 267:cfail 268echo %1 269call :setError 1 270goto :eof 271:cfailend 272echo --- chain success 273echo a1&echo a2 274echo b1&&echo b2 275echo c1||echo c2 276echo --- 277echo d1&echo d2&echo d3 278echo e1&echo e2&&echo e3 279echo f1&echo f2||echo f3 280echo --- 281echo g1&&echo g2&echo g3 282echo h1&&echo h2&&echo h3 283echo i1&&echo i2||echo i3 284echo --- 285echo j1||echo j2&echo j3 286echo --- 287echo k1||echo k2&&echo k3 288echo --- 289echo l1||echo l2||echo l3 290echo --- 291echo --- chain failure 292call :cfail a1&call :cfail a2 293call :cfail b1&&call :cfail b2 294echo --- 295call :cfail c1||call :cfail c2 296call :cfail d1&call :cfail d2&call :cfail d3 297call :cfail e1&call :cfail e2&&call :cfail e3 298echo --- 299call :cfail f1&call :cfail f2||call :cfail f3 300call :cfail g1&&call :cfail g2&call :cfail g3 301echo --- 302call :cfail h1&&call :cfail h2&&call :cfail h3 303echo --- 304call :cfail i1&&call :cfail i2||call :cfail i3 305echo --- 306call :cfail j1||call :cfail j2&call :cfail j3 307call :cfail k1||call :cfail k2&&call :cfail k3 308echo --- 309call :cfail l1||call :cfail l2||call :cfail l3 310echo --- chain brackets 311rem Brackets are like regular commands, they support redirections 312rem and have the same precedence as regular commands. 313echo a1&(echo a2&echo a3) 314echo b1&(echo b2&&echo b3) 315echo c1&(echo c2||echo c3) 316echo --- 317echo d1&&(echo d2&echo d3) 318echo e1&&(echo e2&&echo e3) 319echo f1&&(echo f2||echo f3) 320echo --- 321echo g1||(echo g2&echo g3) 322echo --- 323echo h1||(echo h2&&echo h3) 324echo --- 325echo i1||(echo i2||echo i3) 326echo --- 327call :cfail j1&(call :cfail j2&call :cfail j3) 328call :cfail k1&(call :cfail k2&&call :cfail k3) 329echo --- 330call :cfail l1&(call :cfail l2||call :cfail l3) 331call :cfail m1&&(call :cfail m2&call :cfail m3) 332echo --- 333call :cfail n1&&(call :cfail n2&&call :cfail n3) 334echo --- 335call :cfail o1&&(call :cfail o2||call :cfail o3) 336echo --- 337call :cfail p1||(call :cfail p2&call :cfail p3) 338call :cfail q1||(call :cfail q2&&call :cfail q3) 339echo --- 340call :cfail r1||(call :cfail r2||call :cfail r3) 341echo --- chain pipe 342rem Piped commands run at the same time, so the print order varies. 343rem Additionally, they don't run in the batch script context, as shown by 344rem 'call :existing_label|echo read the error message'. 345(echo a 1>&2|echo a 1>&2) 2>&1 346echo --- 347echo b1|echo b2 348echo c1&&echo c2|echo c3 349echo d1||echo d2|echo d3 350echo --- 351echo e1&echo e2|echo e3 352echo f1|echo f2&&echo f3 353echo g1|echo g2||echo g3 354echo --- 355echo h1|echo h2&echo h3 356echo i1|echo i2|echo i3 357echo --- chain pipe input 358rem The output data of the left side of a pipe can disappear, probably 359rem because it finished too fast and closed the pipe before it could be read, 360rem which means we can get broken results for the tests of this section. 361echo @echo off> tmp.cmd 362echo set IN=X>> tmp.cmd 363echo set /p IN=%%1:>> tmp.cmd 364echo setlocal EnableDelayedExpansion>> tmp.cmd 365echo echo [!IN!,%%1]>> tmp.cmd 366echo endlocal>> tmp.cmd 367echo set IN=>> tmp.cmd 368echo a1|cmd /ctmp.cmd a2 369echo b1|cmd /ctmp.cmd b2|cmd /ctmp.cmd b3 370echo c1|cmd /ctmp.cmd c2|cmd /ctmp.cmd c3|cmd /ctmp.cmd c4 371echo d1|call tmp.cmd d2 372echo e1|call tmp.cmd e2|call tmp.cmd e3 373echo f1|call tmp.cmd f2|call tmp.cmd f3|call tmp.cmd f4 374rem FIXME these 3 tests cause "unexpected end of output" 375rem test : echo g1|tmp.cmd g2 376rem result: g2:[g1,g2] 377rem test : echo h1|tmp.cmd h2|tmp.cmd h3 378rem result: h3:[h2:[h1,h2],h3]@or_broken@h3:[h2:,h3] 379rem test : echo i1|tmp.cmd i2|tmp.cmd i3|tmp.cmd i4 380rem result: i4:[i3:[i2:[i1,i2],i3],i4]@or_broken@i4:[i3:[i2:,i3],i4]@or_broken@i4:[i3:,i4] 381del tmp.cmd 382echo --- chain else 383rem Command arguments are gready and eat up the 'else' unless terminated by 384rem brackets, which means the 'else' can only be recognized when the 385rem 'if true' command chain ends with brackets. 386if 1==1 if 2==2 if 3==3 (echo a1) else (echo a2) else echo a3 387if 1==1 if 2==2 if 3==0 (echo b1) else (echo b2) else echo b3 388echo --- 389if 1==1 if 2==0 if 3==3 (echo c1) else (echo c2) else echo c3 390echo --- 391if 1==1 if 2==0 if 3==0 (echo d1) else (echo d2) else echo d3 392echo --- 393if 1==0 if 2==2 if 3==3 (echo e1) else (echo e2) else echo e3 394echo --- 395if 1==0 if 2==2 if 3==0 (echo f1) else (echo f2) else echo f3 396echo --- 397if 1==0 if 2==0 if 3==3 (echo g1) else (echo g2) else echo g3 398echo --- 399if 1==0 if 2==0 if 3==0 (echo h1) else (echo h2) else echo h3 400echo --- 401echo --- chain else (if true) 402if 1==1 echo a1 else echo a2 403if 1==1 echo b1|echo b2 else echo b3 404if 1==1 echo c1&&echo c2 else echo c3 405if 1==1 echo d1||echo d2 else echo d3 406echo --- 407if 1==1 echo e1&echo e2 else echo e3 408if 1==1 echo f1 else echo f2|echo f3 409if 1==1 echo g1 else echo g2&&echo g3 410if 1==1 echo h1 else echo h2||echo h3 411echo --- 412if 1==1 echo i1 else echo i2&echo i3 413if 1==1 echo j1|(echo j2) else echo j3 414echo --- 415if 1==1 echo k1&&(echo k2) else echo k3 416if 1==1 echo l1||(echo l2) else echo l3 417echo --- 418if 1==1 echo m1&(echo m2) else echo m3 419if 1==1 (echo n1) else echo n2|echo n3 420if 1==1 (echo o1) else echo o2&&echo o3 421if 1==1 (echo p1) else echo p2||echo p3 422if 1==1 (echo q1) else echo q2&echo q3 423echo --- 424echo --- chain else (if false) 425if 1==0 echo a1 else echo a2 426if 1==0 echo b1|echo b2 else echo b3 427if 1==0 echo c1&&echo c2 else echo c3 428if 1==0 echo d1||echo d2 else echo d3 429if 1==0 echo e1&echo e2 else echo e3 430if 1==0 echo f1 else echo f2|echo f3 431if 1==0 echo g1 else echo g2&&echo g3 432if 1==0 echo h1 else echo h2||echo h3 433if 1==0 echo i1 else echo i2&echo i3 434if 1==0 echo j1|(echo j2) else echo j3 435echo --- 436if 1==0 echo k1&&(echo k2) else echo k3 437if 1==0 echo l1||(echo l2) else echo l3 438if 1==0 echo m1&(echo m2) else echo m3 439if 1==0 (echo n1) else echo n2|echo n3 440if 1==0 (echo o1) else echo o2&&echo o3 441if 1==0 (echo p1) else echo p2||echo p3 442echo --- 443if 1==0 (echo q1) else echo q2&echo q3 444echo ------------ Testing 'set' ------------ 445call :setError 0 446rem Remove any WINE_FOO* WINE_BA* environment variables from shell before proceeding 447for /f "delims==" %%i in ('set WINE_ba') do set %%i= 448for /f "delims==" %%i in ('set WINE_foo') do set %%i= 449set WINE_FOOBAR 2> nul > nul 450echo %ErrorLevel% 451set WINE_FOOBAR = baz 452echo %ErrorLevel% 453echo %WINE_FOOBAR%WINE_FOOBAR not defined 454echo %WINE_FOOBAR % 455set WINE_FOOBAR 2> nul 456set WINE_FOOBAR = baz2 457echo %ErrorLevel% 458echo %WINE_fOObAr % 459set WINE_FOOBAR= bar 460echo %ErrorLevel% 461echo %WINE_FOOBAR% 462set WINE_FOO 463set WINE_FOOBAR= 464set WINE_FOOB 465echo %WINE_FOOBAR%WINE_FOOBAR not defined 466set WINE_FOOBAR = 467set WINE_FOOBA 2> nul > nul 468echo %ErrorLevel% 469set WINE_FOO=bar 470echo %WINE_FOO% 471set WINE_FOO=foo 472set WINE_BAR=bar 473echo %WINE_FOO%%WINE_BAR% 474set WINE_BAR= 475set WINE_FOO= 476set WINE_FOO=%WINE_FOO% 477echo %WINE_FOO%WINE_FOO not defined 478set WINE_BAZ%=bazbaz 479set WINE_BA 480echo %WINE_BAZ%% 481set WINE_BAZ%= 482echo set "WINE_FOO=bar" should not include the quotes in the variable value 483set "WINE_FOO=bar" 484echo %WINE_FOO% 485set@tab@WINE_FOO=foo 486echo %WINE_FOO% 487set@tab@WINE_FOO= 488echo '%WINE_FOO%' 489set WINE_FOO=foo@space@ 490echo '%WINE_FOO%' 491set WINE_FOO=foo@tab@ 492echo '%WINE_FOO%' 493rem Space symbol must appear in `var` 494set WINE_FOO=value@space@ 495echo '%WINE_FOO%' 496rem Space symbol must NOT appear in `var` 497set "WINE_FOO=value"@space@ 498echo '%WINE_FOO%' 499rem Mixed examples: 500set WINE_FOO=jim fred 501echo '%WINE_FOO%' 502set WINE_FOO="jim" fred 503echo '%WINE_FOO%' 504set "WINE_FOO=jim fred" 505echo '%WINE_FOO%' 506set "WINE_FOO=jim" fred 507echo '%WINE_FOO%' 508rem Only the final quote ends the string 509set "WINE_FOO=apple"banana"grape"orange 510echo '%WINE_FOO%' 511set WINE_FOO= 512rem set PATH must work with quotes 513set PATH_BACKUP=%PATH% 514mkdir folder 515mkdir "fol;der" 516echo echo I'm here! > "fol;der\sub1.bat" 517echo echo I'm here! > folder\sub1.bat 518set PATH=nothing;"fol;der" 519call sub1 520set PATH="folder 521call sub1 522set PATH=folder" 523call sub1 524del "fol;der\sub1.bat" 525del folder\sub1.bat 526rmdir "fol;der" 527rmdir folder 528PATH=%PATH_BACKUP% 529 530echo ------------ Testing 'choice' ------------ 531 532rem Windows XP and Windows 2000 do not come with choice 533rem echo is used for @or_broken@ formatting 534choice /C:ABC /M "Example message" /D A /T:0 535if %ERRORLEVEL% EQU 9009 ( 536 echo choice unavailable 537) 538echo %ERRORLEVEL% 539choice /C ABC "/M:Example message" /D:B /T 0 540if %ERRORLEVEL% EQU 9009 ( 541 echo choice unavailable 542) 543echo %ERRORLEVEL% 544choice /C def /D:f /T:0 545if %ERRORLEVEL% EQU 9009 ( 546 echo choice unavailable 547) 548echo %ERRORLEVEL% 549REM If a pipe fails due to a nonexistent command 550REM it will stop the whole program's execution 551if %ERRORLEVEL% NEQ 9009 ( 552 echo Y | choice /C ABCXYZ /D A /T 2 553) 554if %ERRORLEVEL% EQU 9009 ( 555 echo choice unavailable 556) 557echo %ERRORLEVEL% 558choice /C ABC /N /D A /T 0 559if %ERRORLEVEL% EQU 9009 ( 560 echo choice unavailable 561) 562echo %ERRORLEVEL% 563choice /C abcABC /CS /D:A /T:0 564if %ERRORLEVEL% EQU 9009 ( 565 echo choice unavailable 566) 567echo %ERRORLEVEL% 568rem intentional error 569choice /C abcABC /D:A /T:0 >NUL 2>NUL 570echo %ERRORLEVEL% 571 572echo ------------ Testing variable expansion ------------ 573call :setError 0 574echo ~p0 should be path containing batch file 575echo %~p0 576mkdir dummydir 577cd dummydir 578echo %~p0 579cd .. 580rmdir dummydir 581echo ~dp0 should be directory containing batch file 582echo %~dp0 583mkdir dummydir 584cd dummydir 585echo %~dp0 586cd .. 587rmdir dummydir 588echo CD value %CD% 589echo %% 590echo P% 591echo %P 592echo %WINE_UNKNOWN%S 593echo P%WINE_UNKNOWN% 594echo P%WINE_UNKNOWN%S 595echo %ERRORLEVEL 596echo %ERRORLEVEL% 597echo %ERRORLEVEL%%ERRORLEVEL% 598echo %ERRORLEVEL%ERRORLEVEL% 599echo %ERRORLEVEL%% 600echo %ERRORLEVEL%%% 601echo P%ERRORLEVEL% 602echo %ERRORLEVEL%S 603echo P%ERRORLEVEL%S 604 605echo ------------ Testing variable substrings ------------ 606set WINE_VAR=qwerty 607echo %WINE_VAR:~0,1% 608echo %WINE_VAR:~0,3% 609echo %WINE_VAR:~2,2% 610echo '%WINE_VAR:~-2,3%' 611echo '%WINE_VAR:~-2,1%' 612echo %WINE_VAR:~2,-1% 613echo %WINE_VAR:~2,-3% 614echo '%WINE_VAR:~-2,-4%' 615echo %WINE_VAR:~-3,-2% 616set WINE_VAR= 617 618echo ------------ Testing variable substitution ------------ 619echo --- in FOR variables 620for %%i in ("A B" C) do echo %%i 621rem check works when prefix with @ 622@for %%i in ("A B" C) do echo %%i 623rem quotes removal 624for %%i in ("A B" C) do echo '%%~i' 625rem fully qualified path 626for %%f in ("C D" E) do echo %%~ff 627rem drive letter 628for %%i in ("F G" H) do echo %%~di 629rem path 630for %%d in ("I J" K) do echo %%~pd 631rem filename 632for %%i in ("L M" N) do echo %%~ni 633rem file extension 634for %%i in ("O. P.OOL" Q.TABC hello) do echo '%%~xi' 635rem path with short path names 636for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do echo '%%~sI' 637rem file attribute 638for %%i in ("U V" W) do echo '%%~ai' 639echo foo> foo 640for %%i in (foo) do echo '%%~ai' 641for %%i in (foo) do echo '%%~zi' 642del foo 643rem file date/time 644rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar... 645for %%i in ("a b" c) do echo '%%~ti' 646rem file size 647rem Similar issues as above 648for %%i in ("a b" c) do echo '%%~zi' 649rem combined options 650for %%i in ("d e" f) do echo %%~dpi 651for %%i in ("g h" i) do echo %%~sdi 652for %%i in ("g h" i) do echo %%~dsi 653for %%i in ("j k" l.eh) do echo '%%~xsi' 654for %%i in ("") do echo '%%~i,%%~fi,%%~di,%%~pi,%%~ni,%%~xi,%%~si,%%~ai,%%~ti,%%~zi' 655 656echo --- in parameters 657for %%i in ("A B" C) do call :echoFun %%i 658rem quotes removal 659for %%i in ("A B" C) do call :echoFunQ %%i 660rem fully qualified path 661for %%f in ("C D" E) do call :echoFunF %%f 662rem drive letter 663for %%i in ("F G" H) do call :echoFunD %%i 664rem path 665for %%d in ("I J" K) do call :echoFunP %%d 666rem filename 667for %%i in ("L M" N) do call :echoFunN %%i 668rem file extension 669for %%i in ("O. P.OOL" Q.TABC hello) do call :echoFunX %%i 670rem path with short path names 671for %%I in ("R S" T ABCDEFGHIJK.LMNOP) do call :echoFunS %%I 672rem NT4 aborts whole script execution when encountering ~a, ~t and ~z substitutions, preventing full testing 673rem combined options 674for %%i in ("d e" f) do call :echoFunDP %%i 675for %%i in ("g h" i) do call :echoFunSD %%i 676for %%i in ("g h" i) do call :echoFunDS %%i 677for %%i in ("j k" l.eh) do call :echoFunXS %%i 678 679goto :endEchoFuns 680:echoFun 681echo %1 682goto :eof 683 684:echoFunQ 685echo '%~1' 686goto :eof 687 688:echoFunF 689echo %~f1 690goto :eof 691 692:echoFunD 693echo %~d1 694goto :eof 695 696:echoFunP 697echo %~p1 698goto :eof 699 700:echoFunN 701echo %~n1 702goto :eof 703 704:echoFunX 705echo '%~x1' 706goto :eof 707 708:echoFunS 709rem some NT4 workaround 710set WINE_VAR='%~s1' 711echo %WINE_VAR% 712set WINE_VAR= 713goto :eof 714 715:echoFunDP 716echo %~dp1 717goto :eof 718 719:echoFunSD 720echo %~sd1 721goto :eof 722 723:echoFunDS 724echo %~ds1 725goto :eof 726 727:echoFunXS 728echo '%~xs1' 729goto :eof 730:endEchoFuns 731 732echo ------------ Testing parameter zero ------------ 733call :func parm1 parm2 734goto :endParm0 735:func 736echo %~0 %~1 737echo [%0] [%~d0] [%~p0] [%~n0] [%~x0] [%~s0] 738goto :EOF 739:endParm0 740 741echo ------------ Testing variable delayed expansion ------------ 742rem NT4 doesn't support this 743echo --- default mode (load-time expansion) 744set WINE_FOO=foo 745echo %WINE_FOO% 746echo !WINE_FOO! 747if %WINE_FOO% == foo ( 748 set WINE_FOO=bar 749 if %WINE_FOO% == bar (echo bar) else echo foo 750) 751 752set WINE_FOO=foo 753if %WINE_FOO% == foo ( 754 set WINE_FOO=bar 755 if !WINE_FOO! == bar (echo bar) else echo foo 756) 757 758echo --- runtime (delayed) expansion mode 759setlocal EnableDelayedExpansion 760set WINE_FOO=foo 761echo %WINE_FOO% 762echo !WINE_FOO! 763if %WINE_FOO% == foo ( 764 set WINE_FOO=bar 765 if %WINE_FOO% == bar (echo bar) else echo foo 766) 767 768set WINE_FOO=foo 769if %WINE_FOO% == foo ( 770 set WINE_FOO=bar 771 if !WINE_FOO! == bar (echo bar) else echo foo 772) 773echo %ErrorLevel% 774setlocal DisableDelayedExpansion 775echo %ErrorLevel% 776set WINE_FOO=foo 777echo %WINE_FOO% 778echo !WINE_FOO! 779set WINE_FOO= 780echo --- using /V cmd flag 781echo @echo off> tmp.cmd 782echo set WINE_FOO=foo>> tmp.cmd 783echo echo %%WINE_FOO%%>> tmp.cmd 784echo echo !WINE_FOO!>> tmp.cmd 785echo set WINE_FOO=>> tmp.cmd 786cmd /V:ON /C tmp.cmd 787cmd /V:OfF /C tmp.cmd 788del tmp.cmd 789 790echo ------------ Testing conditional execution ------------ 791echo --- unconditional ampersand 792call :setError 123 & echo foo1 793echo bar2 & echo foo2 794mkdir foobar & cd foobar 795echo > foobazbar 796cd .. & rd /s/q foobar 797if exist foobazbar ( 798 echo foobar not deleted! 799 cd .. 800 rd /s/q foobar 801) else echo foobar deleted 802echo --- on success conditional and 803call :setError 456 && echo foo3 > foo3 804if exist foo3 ( 805 echo foo3 created 806 del foo3 807) else echo foo3 not created 808echo bar4 && echo foo4 809echo --- on failure conditional or 810call :setError 789 || echo foo5 811echo foo6 || echo bar6 > bar6 812if exist bar6 ( 813 echo bar6 created 814 del bar6 815) 816 817echo ------------ Testing cd ------------ 818mkdir foobar 819cd foobar 820echo blabla > singleFile 821dir /b 822echo Current dir: %CD% 823cd 824cd .. 825cd 826cd foobar@space@ 827cd 828cd .. 829cd 830cd @space@foobar 831cd 832cd.. 833cd 834cd foobar 835cd..@space@ 836cd 837if not exist foobar (cd ..) 838cd foobar 839cd@tab@..@tab@@space@@tab@ 840cd 841if not exist foobar (cd ..) 842cd foobar 843mkdir "bar bak" 844cd "bar bak" 845cd 846cd .. 847cd ".\bar bak" 848cd 849cd .. 850cd .\"bar bak" 851cd 852cd .. 853cd bar bak 854cd 855cd "bar bak@space@"@tab@@space@ 856cd 857cd ..\.. 858cd 859rd /Q/s foobar 860mkdir foobar 861cd /d@tab@foobar 862cd 863cd .. 864rd /q/s foobar 865 866echo ------------ Testing type ------------ 867echo bar> foobaz 868@echo on 869type foobaz 870echo --- 871@echo off 872type foobaz@tab@ 873echo ---1 874type ."\foobaz" 875echo ---2 876type ".\foobaz" 877echo ---3 878echo foo> foobay 879echo ---4 880type foobaz foobay > foobax 2> foobaw 881echo ---5 882type foobax 883echo ---6 884type foobaw 885echo ---7 886del foobaz foobay foobax foobaw 887 888echo ------------ Testing NUL ------------ 889md foobar & cd foobar 890rem NUL file (non) creation + case insensitivity 891rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround 892echo > bar 893echo foo > NUL 894dir /b /a-d 895echo foo > nul 896dir /b /a-d 897echo foo > NuL 898@tab@dir /b@tab@/a-d 899del bar 900rem NUL not special everywhere 901call :setError 123 902echo NUL> foo 903if not exist foo (echo foo should have been created) else ( 904 type foo 905 del foo 906) 907rem Empty file creation 908copy nul foo > nul 909if exist foo ( 910 echo foo created 911 del foo 912 type foo 913) else ( 914 echo *** 915) 916echo 1234 >a.a 917copy a.a+NUL b.b >nul 918call :CheckFileSize a.a 7 b.b 8 919copy NUL+a.a b.b >nul 920call :CheckFileSize a.a 7 b.b 8 921mkdir subdir 922copy a.a+NUL subdir\ >nul 923call :CheckFileSize a.a 7 subdir\a.a 8 924del subdir\a.a 925cd subdir 926copy ..\a.a NUL >nul 927if exist a.a echo Failed 928cd .. 929rd subdir /s /q 930del a.a b.b 931cd .. & rd foobar /s /q 932 933echo ------------ Testing if/else ------------ 934echo --- if/else should work with blocks 935if 0 == 0 ( 936 echo if seems to work 937) else ( 938 echo if seems to be broken 939) 940if 1 == 0 ( 941 echo else seems to be broken 942) else ( 943 echo else seems to work 944) 945if /c==/c ( 946 echo if seems not to detect /c as parameter 947) else ( 948 echo parameter detection seems to be broken 949) 950SET elseIF=0 951if 1 == 1 ( 952 SET /a elseIF=%elseIF%+1 953) else if 1 == 1 ( 954 SET /a elseIF=%elseIF%+2 955) else ( 956 SET /a elseIF=%elseIF%+2 957) 958if %elseIF% == 1 ( 959 echo else if seems to work 960) else ( 961 echo else if seems to be broken 962) 963SET elseIF=0 964if 1 == 2 ( 965 SET /a elseIF=%elseIF%+2 966) else if 1 == 1 ( 967 SET /a elseIF=%elseIF%+1 968) else ( 969 SET /a elseIF=%elseIF%+2 970) 971if %elseIF% == 1 ( 972 echo else if seems to work 973) else ( 974 echo else if seems to be broken 975) 976SET elseIF=0 977if 1 == 2 ( 978 SET /a elseIF=%elseIF%+2 979) else if 1 == 2 ( 980 SET /a elseIF=%elseIF%+2 981) else ( 982 SET /a elseIF=%elseIF%+1 983) 984if %elseIF% == 1 ( 985 echo else if seems to work 986) else ( 987 echo else if seems to be broken 988) 989if "x" == "a" ( 990 echo broken1 991) else ( 992 echo expected1 993 if "y" == "b" echo broken2 994 echo expected post-embedded if 995) 996if ()==() ( 997 echo comparison operators surrounded by brackets seem to work 998) else ( 999 echo comparison operators surrounded by brackets seem to be broken 1000) 1001if 1(==1( ( 1002 echo comparison operators surrounded by brackets seem to work 1003) else ( 1004 echo comparison operators surrounded by brackets seem to be broken 1005) 1006if )==) ( 1007 echo comparison operators surrounded by brackets seem to work 1008) else ( 1009 echo comparison operators surrounded by brackets seem to be broken 1010) 1011if /i not (a)==(b) ( 1012 echo comparison operators surrounded by brackets seem to work 1013) else ( 1014 echo comparison operators surrounded by brackets seem to be broken 1015) 1016if defined windir echo windir is defined 1017if not defined windir echo windir is defined 1018if not exist %windir% ( 1019 echo windir does not exist 1020) else ( 1021 echo windir does exist 1022) 1023echo --- case sensitivity with and without /i option 1024if bar==BAR echo if does not default to case sensitivity 1025if not bar==BAR echo if seems to default to case sensitivity 1026if /i foo==FOO echo if /i seems to work 1027if /i not foo==FOO echo if /i seems to be broken 1028if /I foo==FOO echo if /I seems to work 1029if /I not foo==FOO echo if /I seems to be broken 1030 1031echo --- string comparisons 1032if abc == abc (echo equal) else echo non equal 1033if abc =="abc" (echo equal) else echo non equal 1034if "abc"== abc (echo equal) else echo non equal 1035if "abc"== "abc" (echo equal) else echo non equal 1036 1037echo --- tabs handling 1038if@tab@1==1 echo doom 1039if @tab@1==1 echo doom 1040if 1==1 (echo doom) else@tab@echo quake 1041if@tab@not @tab@1==@tab@0 @tab@echo lol 1042if 1==0@tab@(echo doom) else echo quake 1043if 1==0 (echo doom)@tab@else echo quake 1044if 1==0 (echo doom) else@tab@echo quake 1045 1046echo --- comparison operators 1047rem NT4 misevaluates conditionals in for loops so we have to use subroutines as workarounds 1048echo ------ for strings 1049rem NT4 stops processing of the whole batch file as soon as it finds a 1050rem comparison operator non fully uppercased, such as lss instead of LSS, so we 1051rem can't test those here. 1052if LSS LSS LSSfoo (echo LSS string can be used as operand for LSS comparison) 1053if LSS LSS LSS (echo bar) 1054if 1.1 LSS 1.10 (echo floats are handled as strings) 1055if "9" LSS "10" (echo numbers in quotes recognized!) else echo numbers in quotes are handled as strings 1056if not "-1" LSS "1" (echo negative numbers as well) else echo NT4 1057if /i foo LSS FoOc echo if /i seems to work for LSS 1058if /I not foo LSS FOOb echo if /I seems to be broken for LSS 1059set WINE_STR_PARMS=A B AB BA AA 1060for %%i in (%WINE_STR_PARMS%) do ( 1061 for %%j in (%WINE_STR_PARMS%) do ( 1062 call :LSStest %%i %%j)) 1063if b LSS B (echo b LSS B) else echo NT4 1064if /I b LSS B echo b LSS B insensitive 1065if b LSS A echo b LSS A 1066if /I b LSS A echo b LSS A insensitive 1067if a LSS B (echo a LSS B) else echo NT4 1068if /I a LSS B echo a LSS B insensitive 1069if A LSS b echo A LSS b 1070if /I A LSS b echo A LSS b insensitive 1071for %%i in (%WINE_STR_PARMS%) do ( 1072 for %%j in (%WINE_STR_PARMS%) do ( 1073 call :LEQtest %%i %%j)) 1074if b LEQ B (echo b LEQ B) else echo NT4 1075if /I b LEQ B echo b LEQ B insensitive 1076if b LEQ A echo b LEQ A 1077if /I b LEQ A echo b LEQ A insensitive 1078if a LEQ B (echo a LEQ B) else echo NT4 1079if /I a LEQ B echo a LEQ B insensitive 1080if A LEQ b echo A LEQ b 1081if /I A LEQ b echo A LEQ b insensitive 1082for %%i in (%WINE_STR_PARMS%) do ( 1083 for %%j in (%WINE_STR_PARMS%) do ( 1084 call :EQUtest %%i %%j)) 1085if /I A EQU a echo A EQU a insensitive 1086for %%i in (%WINE_STR_PARMS%) do ( 1087 for %%j in (%WINE_STR_PARMS%) do ( 1088 call :NEQtest %%i %%j)) 1089for %%i in (%WINE_STR_PARMS%) do ( 1090 for %%j in (%WINE_STR_PARMS%) do ( 1091 call :GEQtest %%i %%j)) 1092for %%i in (%WINE_STR_PARMS%) do ( 1093 for %%j in (%WINE_STR_PARMS%) do ( 1094 call :GTRtest %%i %%j)) 1095 1096echo ------------ Testing if/exist ------------ 1097mkdir subdir 1098echo something>subdir\bar 1099echo something else>foo 1100if exist foo ( 1101 echo exist explicit works 1102) else ( 1103 echo ERROR exist explicit broken 1104) 1105if exist bar ( 1106 echo ERROR exist explicit unknown file broken 1107) else ( 1108 echo exist explicit unknown file works 1109) 1110if exist subdir\bar ( 1111 echo exist explicit in subdir works 1112) else ( 1113 echo ERROR exist explicit in subdir broken 1114) 1115if exist fo* ( 1116 echo exist simple wildcard works 1117) else ( 1118 echo ERROR exist simple wildcard broken 1119) 1120if exist subdir\ba* ( 1121 echo exist wildcard works 1122) else ( 1123 echo ERROR exist wildcard broken 1124) 1125if not exist subdir\ba* ( 1126 echo ERROR negate exist wildcard broken 1127) else ( 1128 echo negate exist wildcard works 1129) 1130if exist idontexist\ba* ( 1131 echo ERROR exist wildcard bad subdir broken 1132) else ( 1133 echo exist wildcard bad subdir broken works 1134) 1135if exist subdir ( 1136 echo exist subdir ok 1137) else ( 1138 echo ERROR exist subdir not working 1139) 1140if exist subdir\. ( 1141 echo exist subdir with . ok 1142) else ( 1143 echo ERROR exist subdir with . not working 1144) 1145if exist subdir\ ( 1146 echo exist subdir with \ ok 1147) else ( 1148 echo ERROR exist subdir with \ not working 1149) 1150if exist "subdir\" ( 1151 echo exist subdir with \ and quotes ok 1152) else ( 1153 echo ERROR exist subdir with \ and quotes not working 1154) 1155del foo subdir\bar 1156rd subdir 1157 1158echo ------ for numbers 1159if -1 LSS 1 (echo negative numbers handled) 1160if not -1 LSS -10 (echo negative numbers handled) 1161if not 9 LSS 010 (echo octal handled) 1162if not -010 LSS -8 (echo also in negative form) 1163if 4 LSS 0x5 (echo hexa handled) 1164if not -1 LSS -0x1A (echo also in negative form) 1165if 11 LSS 101 (echo 11 LSS 101) 1166set WINE_INT_PARMS=0 1 10 9 1167for %%i in (%WINE_INT_PARMS%) do ( 1168 for %%j in (%WINE_INT_PARMS%) do ( 1169 call :LSStest %%i %%j)) 1170for %%i in (%WINE_INT_PARMS%) do ( 1171 for %%j in (%WINE_INT_PARMS%) do ( 1172 call :LEQtest %%i %%j)) 1173for %%i in (%WINE_INT_PARMS%) do ( 1174 for %%j in (%WINE_INT_PARMS%) do ( 1175 call :EQUtest %%i %%j)) 1176if 011 EQU 9 (echo octal ok) 1177if 0xA1 EQU 161 (echo hexa ok) 1178if 0xA1 EQU "161" (echo hexa should be recognized) else (echo string/hexa compare ok) 1179if "0xA1" EQU 161 (echo hexa should be recognized) else (echo string/hexa compare ok) 1180for %%i in (%WINE_INT_PARMS%) do ( 1181 for %%j in (%WINE_INT_PARMS%) do ( 1182 call :NEQtest %%i %%j)) 1183for %%i in (%WINE_INT_PARMS%) do ( 1184 for %%j in (%WINE_INT_PARMS%) do ( 1185 call :GEQtest %%i %%j)) 1186for %%i in (%WINE_INT_PARMS%) do ( 1187 for %%j in (%WINE_INT_PARMS%) do ( 1188 call :GTRtest %%i %%j)) 1189echo ------ for numbers and stringified numbers 1190if not "1" EQU 1 (echo strings and integers not equal) else echo foo 1191if not 1 EQU "1" (echo strings and integers not equal) else echo foo 1192if '1' EQU 1 echo '1' EQU 1 1193if 1 EQU '1' echo 1 EQU '1' 1194if not "1" GEQ 1 (echo foo) else echo bar 1195if "10" GEQ "1" echo "10" GEQ "1" 1196if '1' GEQ 1 (echo '1' GEQ 1) else echo NT4 1197if 1 GEQ "1" echo 1 GEQ "1" 1198if "1" GEQ "1" echo "1" GEQ "1" 1199if '1' GEQ "1" echo '1' GEQ "1" 1200if "10" GEQ "1" echo "10" GEQ "1" 1201if not 1 GEQ '1' (echo non NT4) else echo 1 GEQ '1' 1202for %%i in ("1" '1') do call :GEQtest %%i '1' 1203if "10" GEQ '1' (echo "10" GEQ '1') else echo foo 1204if 1 GEQ "10" (echo 1 GEQ "10") else echo foo 1205if "1" GEQ "10" (echo 1 GEQ "10") else echo foo 1206if '1' GEQ "10" (echo '1' GEQ "10") else echo foo 1207if "10" GEQ "10" (echo "10" GEQ "10") 1208echo --- unconditional ampersand after if one line 1209if "0"=="0" echo 1 & echo 2 & echo 3 else echo 4 1210echo --- 1211echo x & if "0"=="1" echo 1 & echo 2 1212echo --- 1213echo x & if "0"=="1" echo 1 & echo 2 & echo 3 1214echo --- 1215echo x & if "0"=="1" (echo 1 & echo 2 & echo 3) 1216echo --- 1217echo x & if "0"=="1" echo 1 & echo 2 & echo 3 else echo 4 1218echo --- 1219goto :endIfCompOpsSubroutines 1220 1221rem IF subroutines helpers 1222:LSStest 1223if %1 LSS %2 echo %1 LSS %2 1224goto :eof 1225:LEQtest 1226if %1 LEQ %2 echo %1 LEQ %2 1227goto :eof 1228:EQUtest 1229if %1 EQU %2 echo %1 EQU %2 1230goto :eof 1231:NEQtest 1232if %1 NEQ %2 echo %1 NEQ %2 1233goto :eof 1234:GEQtest 1235if %1 GEQ %2 echo %1 GEQ %2 1236goto :eof 1237:GTRtest 1238if %1 GTR %2 echo %1 GTR %2 1239goto :eof 1240 1241:endIfCompOpsSubroutines 1242set WINE_STR_PARMS= 1243set WINE_INT_PARMS= 1244 1245echo ------------ Testing for ------------ 1246echo --- plain FOR 1247for %%i in (A B C) do echo %%i 1248for %%i in (A B C) do echo %%I 1249for %%i in (A B C) do echo %%j 1250for %%i in (A B C) do call :forTestFun1 %%i 1251for %%i in (1,4,1) do echo %%i 1252for %%i in (A, B,C) do echo %%i 1253for %%i in (X) do echo %%i 1254for@tab@%%i in (X2) do echo %%i 1255for %%i in@tab@(X3) do echo %%i 1256for %%i in (@tab@ foo@tab@) do echo %%i 1257for@tab@ %%i in@tab@(@tab@M) do echo %%i 1258for %%i@tab@in (X)@tab@do@tab@echo %%i 1259for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j 1260for %%i in (`echo A B`) do echo %%i 1261for %%i in ('echo A B') do echo %%i 1262for %%i in ("echo A B") do echo %%i 1263for %%i in ("A B" C) do echo %%i 1264goto :endForTestFun1 1265:forTestFun1 1266echo %1 1267goto :eof 1268:endForTestFun1 1269echo --- imbricated FORs 1270for %%i in (X) do ( 1271 for %%j in (Y) do ( 1272 echo %%i %%j)) 1273for %%i in (X) do ( 1274 for %%I in (Y) do ( 1275 echo %%i %%I)) 1276for %%i in (A B) do ( 1277 for %%j in (C D) do ( 1278 echo %%i %%j)) 1279for %%i in (A B) do ( 1280 for %%j in (C D) do ( 1281 call :forTestFun2 %%i %%j )) 1282goto :endForTestFun2 1283:forTestFun2 1284echo %1 %2 1285goto :eof 1286:endForTestFun2 1287mkdir foobar & cd foobar 1288mkdir foo 1289mkdir bar 1290mkdir baz 1291mkdir pop 1292echo > bazbaz 1293echo --- basic wildcards 1294for %%i in (ba*) do echo %%i 1295echo --- wildcards in subdirs 1296echo something>pop\bar1 1297echo something>pop\bar2.txt 1298echo something>pop\bar3 1299for %%f in (pop\ba*) do ( call echo %%f ) 1300rmdir /s/q pop 1301echo --- for /d 1302for /d %%i in (baz foo bar) do echo %%i 2>&1 1303rem Confirm we don't match files: 1304for /d %%i in (bazb*) do echo %%i 2>&1 1305for /d %%i in (bazb2*) do echo %%i 2>&1 1306rem Show we pass through non wildcards 1307for /d %%i in (PASSED) do echo %%i 1308for /d %%i in (xxx) do ( 1309 echo %%i - Should be xxx 1310 echo Expected second line 1311) 1312rem Show we issue no messages on failures 1313for /d %%i in (FAILED?) do echo %%i 2>&1 1314for /d %%i in (FAILED?) do ( 1315 echo %%i - Unexpected! 1316 echo FAILED Unexpected second line 1317) 1318for /d %%i in (FAILED*) do echo %%i 2>&1 1319for /d %%i in (FAILED*) do ( 1320 echo %%i - Unexpected! 1321 echo FAILED Unexpected second line 1322) 1323rem FIXME can't test wildcard expansion here since it's listed in directory 1324rem order, and not in alphabetic order. 1325rem Proper testing would need a currently missing "sort" program implementation. 1326rem for /d %%i in (ba*) do echo %%i>> tmp 1327rem sort < tmp 1328rem del tmp 1329rem for /d %%i in (?a*) do echo %%i>> tmp 1330rem sort < tmp 1331rem del tmp 1332rem for /d %%i in (*) do echo %%i>> tmp 1333rem sort < tmp 1334rem del tmp 1335echo > baz\bazbaz 1336goto :TestForR 1337 1338:SetExpected 1339del temp.bat 2>nul 1340call :WriteLine set WINE_found=N 1341for /l %%i in (1,1,%WINE_expectedresults%) do ( 1342 call :WriteLine if "%%%%WINE_expectedresults.%%i%%%%"=="%%%%~1" set WINE_found=Y 1343 call :WriteLine if "%%%%WINE_found%%%%"=="Y" set WINE_expectedresults.%%i= 1344 call :WriteLine if "%%%%WINE_found%%%%"=="Y" goto :eof 1345) 1346call :WriteLine echo Got unexpected result: "%%%%~1" 1347goto :eof 1348 1349:WriteLine 1350echo %*>> temp.bat 1351goto :EOF 1352 1353:ValidateExpected 1354del temp.bat 2>nul 1355for /l %%i in (1,1,%WINE_expectedresults%) do ( 1356 call :WriteLine if not "%%%%WINE_expectedresults.%%i%%%%"=="" echo Found missing result: "%%%%WINE_expectedresults.%%i%%%%" 1357) 1358call temp.bat 1359del temp.bat 2>nul 1360goto :eof 1361 1362:TestForR 1363rem %CD% does not work on NT4 so use the following workaround 1364for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi 1365 1366echo --- for /R 1367echo Plain directory enumeration 1368set WINE_expectedresults=4 1369set WINE_expectedresults.1=%WINE_CURDIR%\. 1370set WINE_expectedresults.2=%WINE_CURDIR%\bar\. 1371set WINE_expectedresults.3=%WINE_CURDIR%\baz\. 1372set WINE_expectedresults.4=%WINE_CURDIR%\foo\. 1373call :SetExpected 1374for /R %%i in (.) do call temp.bat "%%i" 1375call :ValidateExpected 1376 1377echo Plain directory enumeration from provided root 1378set WINE_expectedresults=4 1379set WINE_expectedresults.1=%WINE_CURDIR%\. 1380set WINE_expectedresults.2=%WINE_CURDIR%\bar\. 1381set WINE_expectedresults.3=%WINE_CURDIR%\baz\. 1382set WINE_expectedresults.4=%WINE_CURDIR%\foo\. 1383if "%CD%"=="" goto :SkipBrokenNT4 1384call :SetExpected 1385for /R "%WINE_CURDIR%" %%i in (.) do call temp.bat "%%i" 1386call :ValidateExpected 1387:SkipBrokenNT4 1388 1389echo File enumeration 1390set WINE_expectedresults=2 1391set WINE_expectedresults.1=%WINE_CURDIR%\baz\bazbaz 1392set WINE_expectedresults.2=%WINE_CURDIR%\bazbaz 1393call :SetExpected 1394for /R %%i in (baz*) do call temp.bat "%%i" 1395call :ValidateExpected 1396 1397echo File enumeration from provided root 1398set WINE_expectedresults=2 1399set WINE_expectedresults.1=%WINE_CURDIR%\baz\bazbaz 1400set WINE_expectedresults.2=%WINE_CURDIR%\bazbaz 1401call :SetExpected 1402for /R %%i in (baz*) do call temp.bat "%%i" 1403call :ValidateExpected 1404 1405echo Mixed enumeration 1406set WINE_expectedresults=6 1407set WINE_expectedresults.1=%WINE_CURDIR%\. 1408set WINE_expectedresults.2=%WINE_CURDIR%\bar\. 1409set WINE_expectedresults.3=%WINE_CURDIR%\baz\. 1410set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz 1411set WINE_expectedresults.5=%WINE_CURDIR%\bazbaz 1412set WINE_expectedresults.6=%WINE_CURDIR%\foo\. 1413call :SetExpected 1414for /R %%i in (. baz*) do call temp.bat "%%i" 1415call :ValidateExpected 1416 1417echo Mixed enumeration from provided root 1418set WINE_expectedresults=6 1419set WINE_expectedresults.1=%WINE_CURDIR%\. 1420set WINE_expectedresults.2=%WINE_CURDIR%\bar\. 1421set WINE_expectedresults.3=%WINE_CURDIR%\baz\. 1422set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz 1423set WINE_expectedresults.5=%WINE_CURDIR%\bazbaz 1424set WINE_expectedresults.6=%WINE_CURDIR%\foo\. 1425call :SetExpected 1426for /R %%i in (. baz*) do call temp.bat "%%i" 1427call :ValidateExpected 1428 1429echo With duplicates enumeration 1430set WINE_expectedresults=12 1431set WINE_expectedresults.1=%WINE_CURDIR%\bar\bazbaz 1432set WINE_expectedresults.2=%WINE_CURDIR%\bar\fred 1433set WINE_expectedresults.3=%WINE_CURDIR%\baz\bazbaz 1434set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz 1435set WINE_expectedresults.5=%WINE_CURDIR%\baz\bazbaz 1436set WINE_expectedresults.6=%WINE_CURDIR%\baz\fred 1437set WINE_expectedresults.7=%WINE_CURDIR%\bazbaz 1438set WINE_expectedresults.8=%WINE_CURDIR%\bazbaz 1439set WINE_expectedresults.9=%WINE_CURDIR%\bazbaz 1440set WINE_expectedresults.10=%WINE_CURDIR%\foo\bazbaz 1441set WINE_expectedresults.11=%WINE_CURDIR%\foo\fred 1442set WINE_expectedresults.12=%WINE_CURDIR%\fred 1443call :SetExpected 1444for /R %%i in (baz* bazbaz fred ba*) do call temp.bat "%%i" 1445call :ValidateExpected 1446 1447echo Strip missing wildcards, keep unwildcarded names 1448set WINE_expectedresults=6 1449set WINE_expectedresults.1=%WINE_CURDIR%\bar\jim 1450set WINE_expectedresults.2=%WINE_CURDIR%\baz\bazbaz 1451set WINE_expectedresults.3=%WINE_CURDIR%\baz\jim 1452set WINE_expectedresults.4=%WINE_CURDIR%\bazbaz 1453set WINE_expectedresults.5=%WINE_CURDIR%\foo\jim 1454set WINE_expectedresults.6=%WINE_CURDIR%\jim 1455call :SetExpected 1456for /R %%i in (baz* fred* jim) do call temp.bat "%%i" 1457call :ValidateExpected 1458 1459echo for /R passed 1460echo --- Complex wildcards unix and windows slash 1461cd .. 1462echo Windows slashes, valid path 1463for %%f in (foobar\baz\bazbaz) do echo ASIS: %%f 1464for %%f in (foobar\baz\*) do echo WC : %%f 1465echo Windows slashes, invalid path 1466for %%f in (foobar\jim\bazbaz) do echo ASIS: %%f 1467for %%f in (foobar\jim\*) do echo WC : %%f 1468echo Unix slashes, valid path 1469for %%f in (foobar/baz/bazbaz) do echo ASIS: %%f 1470for %%f in (foobar/baz/*) do echo WC : %%f 1471echo Unix slashes, invalid path 1472for %%f in (foobar/jim/bazbaz) do echo ASIS: %%f 1473for %%f in (foobar/jim/*) do echo WC : %%f 1474echo Done 1475rd /s/Q foobar 1476echo --- for /L 1477rem 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 1478for /L %%i in (1,2,0) do echo %%i 1479for@tab@/L %%i in (1,2,0) do echo %%i 1480for /L %%i in (1,2,6) do echo %%i 1481for /l %%i in (1 ,2,6) do echo %%i 1482for /L %%i in (a,2,3) do echo %%i 1483for /L %%i in (1,2,-1) do echo %%i 1484for /L %%i in (-4,-1,-1) do echo %%i 1485for /L %%i in (1,-2,-2) do echo %%i 1486for /L %%i in (1,2,a) do echo %%i 1487echo ErrorLevel %ErrorLevel% 1488for /L %%i in (1,a,b) do echo %%i 1489echo ErrorLevel %ErrorLevel% 1490rem Test boundaries 1491for /l %%i in (1,1,4) do echo %%i 1492for /l %%i in (1,2,4) do echo %%i 1493for /l %%i in (4,-1,1) do echo %%i 1494for /l %%i in (4,-2,1) do echo %%i 1495for /l %%i in (1,-1,4) do echo %%i 1496for /l %%i in (4,1,1) do echo %%i 1497for /L %%i in (a,2,b) do echo %%i 1498for /L %%i in (1,1,1) do echo %%i 1499for /L %%i in (1,-2,-1) do echo %%i 1500for /L %%i in (-1,-1,-1) do echo %%i 1501for /L %%i in (1,2, 3) do echo %%i 1502rem Test zero iteration skips the body of the for 1503for /L %%i in (2,2,1) do ( 1504 echo %%i 1505 echo FAILED 1506) 1507echo --- rems inside for loops 1508for /f %%i IN ("hello") DO ( 1509 REM foo|echo ERROR unexpected execution 1 1510 @REM foo|echo ERROR unexpected execution 2 1511 @ REM foo|echo ERROR unexpected execution 3 1512) 1513echo --- ifs inside for loops 1514for %%i in (test) do ( 1515 echo a1 1516 if 1==1 ( 1517 echo b1 1518 ) else ( 1519 echo c1 1520 ) 1521 echo d1 1522) 1523for %%i in (test) do ( 1524 echo a2 1525 if 1==1 ( 1526 echo b2 1527 ) else echo c2 1528 echo d2 1529) 1530for %%i in (test) do ( 1531 echo a3 1532 if 1==0 ( 1533 echo b3 1534 ) else echo c3 1535 echo d3 1536) 1537for %%i in (test) do ( 1538 echo a4 1539 if 1==0 ( 1540 echo b4 1541 ) else ( 1542 echo c4 1543 ) 1544 echo d4 1545) 1546echo --- set /a 1547goto :testseta 1548 1549Rem Ideally for /f can be used rather than building a command to execute 1550rem but that does not work on NT4 1551:checkenvvars 1552if "%1"=="" goto :eof 1553call :executecmd set wine_result=%%%1%% 1554if "%wine_result%"=="%2" ( 1555 echo %1 correctly %2 1556) else echo ERROR: %1 incorrectly %wine_result% [%2] 1557set %1= 1558shift 1559shift 1560rem shift 1561goto :checkenvvars 1562:executecmd 1563%* 1564goto :eof 1565 1566:testseta 1567rem No output when using "set expr" syntax, unless in interactive mode 1568rem Need to use "set envvar=expr" to use in a batch script 1569echo ------ individual operations 1570set WINE_foo=0 1571set /a WINE_foo=1 +2 & call :checkenvvars WINE_foo 3 1572set /a WINE_foo=1 +-2 & call :checkenvvars WINE_foo -1 1573set /a WINE_foo=1 --2 & call :checkenvvars WINE_foo 3 1574set /a WINE_foo=2* 3 & call :checkenvvars WINE_foo 6 1575set /a WINE_foo=-2* -5 & call :checkenvvars WINE_foo 10 1576set /a WINE_foo=12/3 & call :checkenvvars WINE_foo 4 1577set /a WINE_foo=13/3 & call :checkenvvars WINE_foo 4 1578set /a WINE_foo=-13/3 & call :checkenvvars WINE_foo -4 1579rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure 1580set /a WINE_foo=5 %% 5 & call :checkenvvars WINE_foo 0 1581set /a WINE_foo=5 %% 3 & call :checkenvvars WINE_foo 2 1582set /a WINE_foo=5 %% -3 & call :checkenvvars WINE_foo 2 1583set /a WINE_foo=-5 %% -3 & call :checkenvvars WINE_foo -2 1584set /a WINE_foo=1 ^<^< 0 & call :checkenvvars WINE_foo 1 1585set /a WINE_foo=1 ^<^< 2 & call :checkenvvars WINE_foo 4 1586set /a WINE_foo=1 ^<^< -2 & call :checkenvvars WINE_foo 0 1587set /a WINE_foo=-1 ^<^< -2 & call :checkenvvars WINE_foo 0 1588set /a WINE_foo=-1 ^<^< 2 & call :checkenvvars WINE_foo -4 1589set /a WINE_foo=9 ^>^> 0 & call :checkenvvars WINE_foo 9 1590set /a WINE_foo=9 ^>^> 2 & call :checkenvvars WINE_foo 2 1591set /a WINE_foo=9 ^>^> -2 & call :checkenvvars WINE_foo 0 1592set /a WINE_foo=-9 ^>^> -2 & call :checkenvvars WINE_foo -1 1593set /a WINE_foo=-9 ^>^> 2 & call :checkenvvars WINE_foo -3 1594set /a WINE_foo=5 ^& 0 & call :checkenvvars WINE_foo 0 1595set /a WINE_foo=5 ^& 1 & call :checkenvvars WINE_foo 1 1596set /a WINE_foo=5 ^& 3 & call :checkenvvars WINE_foo 1 1597set /a WINE_foo=5 ^& 4 & call :checkenvvars WINE_foo 4 1598set /a WINE_foo=5 ^& 1 & call :checkenvvars WINE_foo 1 1599set /a WINE_foo=5 ^| 0 & call :checkenvvars WINE_foo 5 1600set /a WINE_foo=5 ^| 1 & call :checkenvvars WINE_foo 5 1601set /a WINE_foo=5 ^| 3 & call :checkenvvars WINE_foo 7 1602set /a WINE_foo=5 ^| 4 & call :checkenvvars WINE_foo 5 1603set /a WINE_foo=5 ^| 1 & call :checkenvvars WINE_foo 5 1604set /a WINE_foo=5 ^^ 0 & call :checkenvvars WINE_foo 5 1605set /a WINE_foo=5 ^^ 1 & call :checkenvvars WINE_foo 4 1606set /a WINE_foo=5 ^^ 3 & call :checkenvvars WINE_foo 6 1607set /a WINE_foo=5 ^^ 4 & call :checkenvvars WINE_foo 1 1608set /a WINE_foo=5 ^^ 1 & call :checkenvvars WINE_foo 4 1609echo ------ precedence and grouping 1610set /a WINE_foo=4 + 2*3 & call :checkenvvars WINE_foo 10 1611set /a WINE_foo=(4+2)*3 & call :checkenvvars WINE_foo 18 1612set /a WINE_foo=4 * 3/5 & call :checkenvvars WINE_foo 2 1613set /a WINE_foo=(4 * 3)/5 & call :checkenvvars WINE_foo 2 1614set /a WINE_foo=4 * 5 %% 4 & call :checkenvvars WINE_foo 0 1615set /a WINE_foo=4 * (5 %% 4) & call :checkenvvars WINE_foo 4 1616set /a WINE_foo=3 %% (5 + 8 %% 3 ^^ 2) & call :checkenvvars WINE_foo 3 1617set /a WINE_foo=3 %% (5 + 8 %% 3 ^^ -2) & call :checkenvvars WINE_foo 3 1618echo ------ octal and hexadecimal 1619set /a WINE_foo=0xf + 3 & call :checkenvvars WINE_foo 18 1620set /a WINE_foo=0xF + 3 & call :checkenvvars WINE_foo 18 1621set /a WINE_foo=015 + 2 & call :checkenvvars WINE_foo 15 1622set /a WINE_foo=3, 8+3,0 & call :checkenvvars WINE_foo 3 1623echo ------ variables 1624set /a WINE_foo=WINE_bar=3, WINE_bar+1 & call :checkenvvars WINE_foo 3 WINE_bar 3 1625set /a WINE_foo=WINE_bar=3, WINE_bar+=1 & call :checkenvvars WINE_foo 3 WINE_bar 4 1626set /a WINE_foo=WINE_bar=3, WINE_baz=1, WINE_baz+=WINE_bar, WINE_baz & call :checkenvvars WINE_foo 3 WINE_bar 3 WINE_baz 4 1627set WINE_bar=3 1628set /a WINE_foo=WINE_bar*= WINE_bar & call :checkenvvars WINE_foo 9 WINE_bar 9 1629set /a WINE_foo=WINE_whateverNonExistingVar & call :checkenvvars WINE_foo 0 1630set WINE_bar=4 1631set /a WINE_foo=WINE_whateverNonExistingVar + WINE_bar & call :checkenvvars WINE_foo 4 WINE_bar 4 1632set WINE_bar=4 1633set /a WINE_foo=WINE_bar -= WINE_bar + 7 & call :checkenvvars WINE_foo -7 WINE_bar -7 1634set WINE_bar=-7 1635set /a WINE_foo=WINE_bar /= 3 + 2 & call :checkenvvars WINE_foo -1 WINE_bar -1 1636set /a WINE_foo=WINE_bar=5, WINE_bar %%=2 & call :checkenvvars WINE_foo 5 WINE_bar 1 1637set WINE_bar=1 1638set /a WINE_foo=WINE_bar ^<^<= 2 & call :checkenvvars WINE_foo 4 WINE_bar 4 1639set WINE_bar=4 1640set /a WINE_foo=WINE_bar ^>^>= 2 & call :checkenvvars WINE_foo 1 WINE_bar 1 1641set WINE_bar=1 1642set /a WINE_foo=WINE_bar ^&= 2 & call :checkenvvars WINE_foo 0 WINE_bar 0 1643set /a WINE_foo=WINE_bar=5, WINE_bar ^|= 2 & call :checkenvvars WINE_foo 5 WINE_bar 7 1644set /a WINE_foo=WINE_bar=5, WINE_bar ^^= 2 & call :checkenvvars WINE_foo 5 WINE_bar 7 1645set WINE_baz=4 1646set /a WINE_foo=WINE_bar=19, WINE_bar %%= 4 + (WINE_baz %%= 7) & call :checkenvvars WINE_foo 19 WINE_bar 3 WINE_baz 4 1647echo --- quotes 1648set /a WINE_foo=1 1649call :checkenvvars WINE_foo 1 1650set /a "WINE_foo=1" 1651call :checkenvvars WINE_foo 1 1652set /a WINE_foo=1,WINE_bar=2 1653call :checkenvvars WINE_foo 1 WINE_bar 2 1654set /a "WINE_foo=1,WINE_bar=2" 1655call :checkenvvars WINE_foo 1 WINE_bar 2 1656set /a "WINE_foo=1","WINE_bar=2" 1657call :checkenvvars WINE_foo 1 WINE_bar 2 1658set /a ""WINE_foo=1","WINE_bar=2"" 1659call :checkenvvars WINE_foo 1 WINE_bar 2 1660set /a WINE_foo=1,WINE_bar=2,WINE_baz=3 1661call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1662set /a "WINE_foo=1,WINE_bar=2,WINE_baz=3" 1663call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1664set /a "WINE_foo=1","WINE_bar=2","WINE_baz=3" 1665call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1666set /a ""WINE_foo=1","WINE_bar=2","WINE_baz=3"" 1667call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1668set /a ""WINE_foo=1","WINE_bar=2"","WINE_baz=3" 1669call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1670set /a """"""WINE_foo=1"""""" 1671call :checkenvvars WINE_foo 1 1672set /a """"""WINE_foo=1","WINE_bar=5""","WINE_baz=2"" 1673call :checkenvvars WINE_foo 1 WINE_bar 5 WINE_baz 2 1674set /a WINE_foo="3"+"4"+"5+6" 1675call :checkenvvars WINE_foo 18 1676set WINE_foo=3 1677set /a WINE_bar="WINE_""foo"+4 1678call :checkenvvars WINE_foo 3 WINE_bar 7 1679echo --- whitespace are ignored between double char operators 1680set WINE_foo=4 1681set WINE_bar=5 1682set /a WINE_foo + = 6 1683set /a WINE_bar * = WINE_foo 1684call :checkenvvars WINE_foo 10 WINE_bar 50 1685set WINE_foo=4 1686set WINE_bar=5 1687set /a WINE_foo + = "6 < < 7" 1688set /a WINE_bar * = WINE_foo + WINE_foo 1689call :checkenvvars WINE_foo 772 WINE_bar 7720 1690set /a WINE_foo=6 7 1691set /a WINE_ var1=8 1692set WINE_foo= 1693echo --- invalid operator sequence 1694set WINE_foo=4 1695set /a =4 1696set /a *=4 1697set /a ^>=4" 1698set /a ^<=4" 1699set /a WINE_foo^>^<=4 1700echo %WINE_foo% 1701set /a WINE_foo^>^>^>=4 1702echo %WINE_foo% 1703echo ----- negative prefix 1704set /a WINE_foo=-1 1705call :checkenvvars WINE_foo -1 1706set /a WINE_foo=--1 1707call :checkenvvars WINE_foo 1 1708set /a WINE_foo=3--3 1709call :checkenvvars WINE_foo 6 1710set /a WINE_foo=3---3 1711call :checkenvvars WINE_foo 0 1712set /a WINE_foo=3----3 1713call :checkenvvars WINE_foo 6 1714set /a WINE_foo=-~1 1715call :checkenvvars WINE_foo 2 1716set /a WINE_foo=~-1 1717call :checkenvvars WINE_foo 0 1718set /a WINE_foo=3+-~1 1719call :checkenvvars WINE_foo 5 1720set /a WINE_foo=3+~-1 1721call :checkenvvars WINE_foo 3 1722echo ----- assignment tests involving the end destination 1723set WINE_foo=3 1724set /a WINE_foo+=3+(WINE_foo=4) 1725call :checkenvvars WINE_foo 11 1726set WINE_foo=2 1727set /a WINE_bar=3+(WINE_foo=6) 1728call :checkenvvars WINE_foo 6 WINE_bar 9 1729set WINE_foo=2 1730set /a WINE_bar=3+(WINE_foo=6,WINE_baz=7) 1731call :checkenvvars WINE_foo 6 WINE_bar 10 WINE_baz 7 1732set WINE_foo=2 1733set /a WINE_bar=WINE_foo=7 1734call :checkenvvars WINE_foo 7 WINE_bar 7 1735echo ----- equal precedence on stack 1736rem Unary - don't reduce if precedence is equal 1737set /a WINE_foo=!!1 1738call :checkenvvars WINE_foo 1 1739set /a WINE_foo=!!0 1740call :checkenvvars WINE_foo 0 1741set /a WINE_foo=~~1 1742call :checkenvvars WINE_foo 1 1743set /a WINE_foo=~~0 1744call :checkenvvars WINE_foo 0 1745set /a WINE_foo=--1 1746call :checkenvvars WINE_foo 1 1747set /a WINE_foo=+-1 1748call :checkenvvars WINE_foo -1 1749set /a WINE_foo=-+1 1750call :checkenvvars WINE_foo -1 1751set /a WINE_foo=++1 1752call :checkenvvars WINE_foo 1 1753set /a WINE_foo=!~1 1754call :checkenvvars WINE_foo 0 1755set /a WINE_foo=~!1 1756call :checkenvvars WINE_foo -1 1757set /a WINE_foo=!-1 1758call :checkenvvars WINE_foo 0 1759set /a WINE_foo=-!1 1760call :checkenvvars WINE_foo 0 1761set /a WINE_foo=!-0 1762call :checkenvvars WINE_foo 1 1763set /a WINE_foo=-!0 1764call :checkenvvars WINE_foo -1 1765rem Aritmatic - Reduce if precedence is equal 1766set /a WINE_foo=10*5/2 1767call :checkenvvars WINE_foo 25 1768set /a WINE_foo=5/2*10 1769call :checkenvvars WINE_foo 20 1770set /a WINE_foo=10/5/2 1771call :checkenvvars WINE_foo 1 1772set /a WINE_foo=5%%2*4 1773call :checkenvvars WINE_foo 4 1774set /a WINE_foo=10-5+2 1775call :checkenvvars WINE_foo 7 1776set /a WINE_foo=1^<^<4^>^>1 1777call :checkenvvars WINE_foo 8 1778rem Assignment - don't reduce if precedence is equal 1779set /a WINE_foo=5 1780set /a WINE_bar=WINE_foo=6 1781call :checkenvvars WINE_foo 6 WINE_bar 6 1782 1783echo --- for /F 1784mkdir foobar & cd foobar 1785echo ------ string argument 1786rem NT4 does not support usebackq 1787for /F %%i in ("a b c") do echo %%i 1788for /F %%i in ( "a b c" ) do echo X%%iX 1789for /f usebackq %%i in ('a b c') do echo %%i>output_file 1790if not exist output_file (echo no output) else (type output_file & del output_file) 1791for /f usebackq %%i in ( 'a b c' ) do echo X%%iX>output_file 1792if not exist output_file (echo no output) else (type output_file & del output_file) 1793for /f %%i in ("a ") do echo %%i 1794for /f usebackq %%i in ('a ') do echo %%i>output_file 1795if not exist output_file (echo no output) else (type output_file & del output_file) 1796for /f %%i in ("a") do echo %%i 1797for /f usebackq %%i in ('a') do echo %%i>output_file 1798if not exist output_file (echo no output) else (type output_file & del output_file) 1799fOr /f %%i in (" a") do echo %%i 1800for /f usebackq %%i in (' a') do echo %%i>output_file 1801if not exist output_file (echo no output) else (type output_file & del output_file) 1802for /f %%i in (" a ") do echo %%i 1803for /f usebackq %%i in (' a ') do echo %%i>output_file 1804if not exist output_file (echo no output) else (type output_file & del output_file) 1805echo ------ fileset argument 1806echo --------- basic blank handling 1807echo a b c>foo 1808for /f %%i in (foo) do echo %%i 1809echo a >foo 1810for /f %%i in (foo) do echo %%i 1811echo a>foo 1812for /f %%i in (foo) do echo %%i 1813echo a>foo 1814for /f %%i in (foo) do echo %%i 1815echo a >foo 1816for /f %%i in (foo) do echo %%i 1817echo. > foo 1818for /f %%i in (foo) do echo %%i 1819echo. >> foo 1820echo b > foo 1821for /f %%i in (foo) do echo %%i 1822echo --------- multi-line with empty lines 1823echo a Z f> foo 1824echo. >> foo 1825echo.>> foo 1826echo b bC>> foo 1827echo c>> foo 1828echo. >> foo 1829for /f %%b in (foo) do echo %%b 1830echo --------- multiple files 1831echo q w > bar 1832echo.>> bar 1833echo kkk>>bar 1834for /f %%k in (foo bar) do echo %%k 1835for /f %%k in (bar foo) do echo %%k 1836echo ------ command argument 1837rem Not implemented on NT4, need to skip it as no way to get output otherwise 1838if "%CD%"=="" goto :SkipFORFcmdNT4 1839for /f %%i in ('echo.Passed1') do echo %%i 1840for /f "usebackq" %%i in (`echo.Passed2`) do echo %%i 1841for /f usebackq %%i in (`echo.Passed3`) do echo %%i 1842for /f "usebackq" %%i in (`"c:\windows\system32\cmd.exe" /C echo Passed4`) do echo %%i 1843for /f "usebackq" %%i in (`""c:\windows\system32\cmd.exe" /C echo Passed5"`) do echo %%i 1844for /f %%i in ( 'echo.Passed6' ) do echo %%i 1845for /f "usebackq" %%i in ( `echo.Passed7` ) do echo %%i 1846goto :ContinueFORF 1847:SkipFORFcmdNT4 1848for /l %%i in (1,1,7) do echo Missing functionality - Broken%%i 1849:ContinueFORF 1850rem FIXME: Rest not testable right now in wine: not implemented and would need 1851rem preliminary grep-like program implementation (e.g. like findstr or fc) even 1852rem for a simple todo_wine test 1853rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported 1854rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported 1855echo ------ eol option 1856if "%CD%"=="" goto :SkipFORFeolNT4 1857echo Line one>foo 1858echo and Line two>>foo 1859echo Line three>>foo 1860for /f "eol=L" %%i in (foo) do echo %%i 1861for /f "eol=a" %%i in (foo) do echo %%i 1862del foo 1863goto :ContinueFORFeol 1864:SkipFORFeolNT4 1865for /l %%i in (1,1,3) do echo Broken NT4 functionality%%i 1866:ContinueFORFeol 1867for /f "eol=@" %%i in (" ad") do echo %%i 1868for /f "eol=@" %%i in (" z@y") do echo %%i 1869for /f "eol=|" %%i in ("a|d") do echo %%i 1870for /f "eol=@" %%i in ("@y") do echo %%i > output_file 1871if not exist output_file (echo no output) else (del output_file) 1872for /f "eol==" %%i in ("=y") do echo %%i > output_file 1873if not exist output_file (echo no output) else (del output_file) 1874echo ------ delims option 1875for /f "delims=|" %%i in ("a|d") do echo %%i 1876for /f "delims=|" %%i in ("a |d") do echo %%i 1877for /f "delims=|" %%i in ("a d|") do echo %%i 1878for /f "delims=| " %%i in ("a d|") do echo %%i 1879for /f "delims==" %%i in ("C r=d|") do echo %%i 1880for /f "delims=" %%i in ("foo bar baz") do echo %%i 1881for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi 1882echo ------ skip option 1883echo a > foo 1884echo b >> foo 1885echo c >> foo 1886for /f "skip=2" %%i in (foo) do echo %%i 1887for /f "skip=3" %%i in (foo) do echo %%i > output_file 1888if not exist output_file (echo no output) else (del output_file) 1889for /f "skip=4" %%i in (foo) do echo %%i > output_file 1890if not exist output_file (echo no output) else (del output_file) 1891for /f "skip=02" %%i in (foo) do echo %%i 1892for /f "skip=0x2" %%i in (foo) do echo %%i 1893for /f "skip=1" %%i in ("skipme") do echo %%i > output_file 1894if not exist output_file (echo no output) else (del output_file) 1895echo ------ tokens= option 1896rem Basic 1897for /f %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o 1898for /f "tokens=2" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o 1899for /f "tokens=1,3,5-7" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o 1900rem Show * means the rest 1901for /f "tokens=1,5*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o 1902for /f "tokens=6,9*" %%i in ("a b c d e f g h i j k l m n o p q r s t u v w x y z") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o 1903rem Show * means the rest (not tokenized and rebuilt) 1904for /f "tokens=6,9*" %%i in ("a b c d e f g h i j k l m n;;== o p q r s t u v w x y z") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o 1905rem Order is irrelevant 1906for /f "tokens=1,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1907for /f "tokens=3,2,1*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1908rem Duplicates are ignored 1909for /f "tokens=1,2,1*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1910rem Large tokens are allowed 1911for /f "tokens=25,1,5*" %%i in ("a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1912rem Show tokens blanked in advance regardless of uniqueness of requested tokens 1913for /f "tokens=1,1,1,2*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1914for /f "tokens=1-2,1-2,1-2" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1915rem Show No wrapping from z to A BUT wrapping sort of occurs Z to a occurs 1916for /f "tokens=1-20" %%u in ("a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z") do echo u=%%u v=%%v w=%%w x=%%x y=%%y z=%%z A=%%A a=%%a 1917for /f "tokens=1-20" %%U in ("a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z") do echo U=%%U V=%%V W=%%W X=%%X Y=%%Y Z=%%Z A=%%A a=%%a 1918rem Show negative ranges have no effect 1919for /f "tokens=1-3,5" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o 1920for /f "tokens=3-1,5" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m o=%%o 1921rem Show duplicates stop * from working 1922for /f "tokens=1,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1923for /f "tokens=1,1,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1924for /f "tokens=2,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1925for /f "tokens=3,2,3*" %%i in ("a b c d e f g") do echo h=%%h i=%%i j=%%j k=%%k l=%%l m=%%m n=%%n o=%%o 1926rem Special case tokens=* or tokens=n,* 1927echo 3.14>testfile 1928FOR /F "tokens=*" %%A IN (testfile) DO @echo 1:%%A,%%B 1929FOR /F "tokens=1*" %%A IN (testfile) DO @echo 2:%%A,%%B 1930FOR /F "tokens=2*" %%A IN (testfile) DO @echo 3:%%A,%%B 1931FOR /F "tokens=1,* delims=." %%A IN (testfile) DO @echo 4:%%A,%%B 1932del testfile 1933cd .. 1934rd /s/q foobar 1935echo ------ parameter splitting 1936echo forFParameterSplittingFunc "myparam1=myvalue1 myparam2=myparam2" mytest> foo 1937for /f "tokens=1 delims=;" %%i in (foo) do (call :%%i) 1938del foo 1939for /f "tokens=1 delims=;" %%i in ("forFParameterSplittingFunc "myparam1^=myvalue1 myparam2^=myparam2" mytest") do (call :%%i) 1940goto :forFParameterSplittingEnd 1941:forFParameterSplittingFunc 1942echo %~0 %~1 %~2 %~3 %~4 %~5 1943goto :eof 1944:forFParameterSplittingEnd 1945echo 3.14>testfile 1946FOR /F "delims=. tokens=*" %%A IN (testfile) DO @echo 4:%%A,%%B 1947FOR /F "delims=. tokens=1*" %%A IN (testfile) DO @echo 5:%%A,%%B 1948FOR /F "delims=. tokens=2*" %%A IN (testfile) DO @echo 6:%%A,%%B 1949FOR /F "delims=. tokens=3*" %%A IN (testfile) DO @echo 7:%%A,%%B 1950del testfile 1951 1952echo ------------ Testing del ------------ 1953echo abc > file 1954echo deleting 'file' 1955del file 1956if errorlevel 0 ( 1957 echo errorlevel is 0, good 1958) else ( 1959 echo unexpected errorlevel, got %errorlevel% 1960) 1961if not exist file ( 1962 echo successfully deleted 'file' 1963) else ( 1964 echo error deleting 'file' 1965) 1966echo attempting to delete 'file', even though it is not present 1967del file 1968if errorlevel 0 ( 1969 echo errorlevel is 0, good 1970) else ( 1971 echo unexpected errorlevel, got %errorlevel% 1972) 1973 1974echo ------------ Testing del /a ------------ 1975del /f/q *.test > nul 1976echo r > r.test 1977attrib +r r.test 1978echo not-r > not-r.test 1979 1980if not exist not-r.test echo not-r.test not found before delete, bad 1981del /a:-r *.test 1982if not exist not-r.test echo not-r.test not found after delete, good 1983 1984if not exist r.test echo r.test not found before delete, bad 1985if exist r.test echo r.test found before delete, good 1986del /a:r *.test 1987if not exist r.test echo r.test not found after delete, good 1988if exist r.test echo r.test found after delete, bad 1989 1990echo ------------ Testing del /q ------------ 1991mkdir del_q_dir 1992cd del_q_dir 1993echo abc > file1 1994echo abc > file2.dat 1995rem If /q doesn't work, cmd will prompt and the test case should hang 1996del /q * > nul 1997for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a 1998for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a 1999cd .. 2000rmdir del_q_dir 2001 2002echo ------------ Testing del /s ------------ 2003mkdir "foo bar" 2004cd "foo bar" 2005mkdir "foo:" 2006echo hi > file1.dat 2007echo there > file2.dat 2008echo bub > file3.dat 2009echo bye > "file with spaces.dat" 2010cd .. 2011del /s file1.dat > nul 2012del file2.dat /s > nul 2013del "file3.dat" /s > nul 2014del "file with spaces.dat" /s > nul 2015cd "foo bar" 2016for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f 2017for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat 2018if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat" 2019if exist "file with spaces.dat" del "file with spaces.dat" 2020rmdir "foo:" 2021cd .. 2022rmdir "foo bar" 2023 2024echo ------------ Testing rename ------------ 2025mkdir foobar & cd foobar 2026echo --- ren and rename are synonymous 2027echo > foo 2028rename foo bar 2029if exist foo echo foo should be renamed! 2030if exist bar echo foo renamed to bar 2031ren bar foo 2032if exist bar echo bar should be renamed! 2033if exist foo echo bar renamed to foo 2034echo --- name collision 2035echo foo>foo 2036echo bar>bar 2037ren foo bar 2> nul 2038type foo 2039type bar 2040rem no-op 2041ren foo foo 2042mkdir baz 2043ren foo baz\abc 2044echo --- rename read-only files 2045echo > file1 2046attrib +r file1 2047ren file1 file2 2048if not exist file1 ( 2049 if exist file2 ( 2050 echo read-only file renamed 2051 ) 2052) else ( 2053 echo read-only file not renamed! 2054) 2055echo --- rename directories 2056mkdir rep1 2057ren rep1 rep2 2058if not exist rep1 ( 2059 if exist rep2 ( 2060 echo dir renamed 2061 ) 2062) 2063attrib +r rep2 2064ren rep2 rep1 2065if not exist rep2 ( 2066 if exist rep1 ( 2067 echo read-only dir renamed 2068 ) 2069) 2070echo --- rename in other directory 2071if not exist baz\abc ( 2072 echo rename impossible in other directory 2073 if exist foo echo original file still present 2074) else ( 2075 echo shouldn't rename in other directory! 2076 if not exist foo echo original file not present anymore 2077) 2078cd .. & rd /s/q foobar 2079 2080echo ------------ Testing move ------------ 2081mkdir foobar & cd foobar 2082echo --- file move 2083echo >foo 2084move foo bar > nul 2>&1 2085if not exist foo ( 2086 if exist bar ( 2087 echo file move succeeded 2088 ) 2089) 2090echo bar>bar 2091echo baz> baz 2092move /Y bar baz > nul 2>&1 2093if not exist bar ( 2094 if exist baz ( 2095 echo file move with overwrite succeeded 2096 ) 2097) else ( 2098 echo file overwrite impossible! 2099 del bar 2100) 2101type baz 2102 2103attrib +r baz 2104move baz bazro > nul 2>&1 2105if not exist baz ( 2106 if exist bazro ( 2107 echo read-only files are moveable 2108 move bazro baz > nul 2>&1 2109 ) 2110) else ( 2111 echo read-only file not moved! 2112) 2113attrib -r baz 2114mkdir rep 2115move baz rep > nul 2>&1 2116if not exist baz ( 2117 if exist rep\baz ( 2118 echo file moved in subdirectory 2119 ) 2120) 2121call :setError 0 2122move rep\baz . > nul 2>&1 2123move /Y baz baz > nul 2>&1 2124if errorlevel 1 ( 2125 echo moving a file to itself should be a no-op! 2126) else ( 2127 echo moving a file to itself is a no-op 2128) 2129echo ErrorLevel: %ErrorLevel% 2130call :setError 0 2131del baz 2132echo --- directory move 2133mkdir foo\bar 2134mkdir baz 2135echo baz2>baz\baz2 2136move baz foo\bar > nul 2>&1 2137if not exist baz ( 2138 if exist foo\bar\baz\baz2 ( 2139 echo simple directory move succeeded 2140 ) 2141) 2142call :setError 0 2143mkdir baz 2144move baz baz > nul 2>&1 2145echo moving a directory to itself gives error; errlevel %ErrorLevel% 2146echo ------ dir in dir move 2147rd /s/q foo 2148mkdir foo bar 2149echo foo2>foo\foo2 2150echo bar2>bar\bar2 2151move foo bar > nul 2>&1 2152if not exist foo ( 2153 if exist bar ( 2154 dir /b /ad bar 2155 dir /b /a-d bar 2156 dir /b bar\foo 2157 ) 2158) 2159cd .. & rd /s/q foobar 2160 2161echo ------------ Testing mkdir ------------ 2162call :setError 0 2163echo --- md and mkdir are synonymous 2164mkdir foobar 2165echo %ErrorLevel% 2166rmdir foobar 2167md foobar 2168echo %ErrorLevel% 2169rmdir foobar 2170echo --- creating an already existing directory/file must fail 2171mkdir foobar 2172md foobar 2173echo %ErrorLevel% 2174rmdir foobar 2175echo > foobar 2176mkdir foobar 2177echo %ErrorLevel% 2178del foobar 2179echo --- multilevel path creation 2180mkdir foo 2181echo %ErrorLevel% 2182mkdir foo\bar\baz 2183echo %ErrorLevel% 2184cd foo 2185echo %ErrorLevel% 2186cd bar 2187echo %ErrorLevel% 2188cd baz 2189echo %ErrorLevel% 2190echo > ..\..\bar2 2191mkdir ..\..\..\foo\bar2 2192echo %ErrorLevel% 2193del ..\..\bar2 2194mkdir ..\..\..\foo\bar2 2195echo %ErrorLevel% 2196rmdir ..\..\..\foo\bar2 2197cd .. 2198rmdir baz 2199cd .. 2200rmdir bar 2201cd .. 2202rmdir foo 2203echo %ErrorLevel% 2204echo --- trailing backslashes 2205mkdir foo\\\\ 2206echo %ErrorLevel% 2207if exist foo (rmdir foo & echo dir created 2208) else ( echo dir not created ) 2209echo %ErrorLevel% 2210echo --- invalid chars 2211mkdir ? 2212echo mkdir ? gives errorlevel %ErrorLevel% 2213call :setError 0 2214mkdir ?\foo 2215echo mkdir ?\foo gives errorlevel %ErrorLevel% 2216call :setError 0 2217mkdir foo\? 2218echo mkdir foo\? gives errorlevel %ErrorLevel% 2219if exist foo (rmdir foo & echo ok, foo created 2220) else ( echo foo not created ) 2221call :setError 0 2222mkdir foo\bar\? 2223echo mkdir foo\bar\? gives errorlevel %ErrorLevel% 2224call :setError 0 2225if not exist foo ( 2226 echo bad, foo not created 2227) else ( 2228 cd foo 2229 if exist bar ( 2230 echo ok, foo\bar created 2231 rmdir bar 2232 ) 2233 cd .. 2234 rmdir foo 2235) 2236echo --- multiple directories at once 2237mkdir foobaz & cd foobaz 2238mkdir foo bar\baz foobar "bazbaz" .\"zabzab" 2239if exist foo (echo foo created) else echo foo not created! 2240if exist bar (echo bar created) else echo bar not created! 2241if exist foobar (echo foobar created) else echo foobar not created! 2242if exist bar\baz (echo bar\baz created) else echo bar\baz not created! 2243if exist bazbaz (echo bazbaz created) else echo bazbaz not created! 2244if exist zabzab (echo zabzab created) else echo zabzab not created! 2245cd .. & rd /s/q foobaz 2246call :setError 0 2247mkdir foo\* 2248echo mkdir foo\* errorlevel %ErrorLevel% 2249if exist foo (rmdir foo & echo ok, foo created 2250) else ( echo bad, foo not created ) 2251 2252echo ------------ Testing rmdir ------------ 2253call :setError 0 2254rem rd and rmdir are synonymous 2255mkdir foobar 2256rmdir foobar 2257echo %ErrorLevel% 2258if not exist foobar echo dir removed 2259mkdir foobar 2260rd foobar 2261echo %ErrorLevel% 2262if not exist foobar echo dir removed 2263rem Removing nonexistent directory 2264rmdir foobar 2265echo %ErrorLevel% 2266rem Removing single-level directories 2267echo > foo 2268rmdir foo 2269echo %ErrorLevel% 2270if exist foo echo file not removed 2271del foo 2272mkdir foo 2273echo > foo\bar 2274rmdir foo 2275echo %ErrorLevel% 2276if exist foo echo non-empty dir not removed 2277del foo\bar 2278mkdir foo\bar 2279rmdir foo 2280echo %ErrorLevel% 2281if exist foo echo non-empty dir not removed 2282rmdir foo\bar 2283rmdir foo 2284rem Recursive rmdir 2285mkdir foo\bar\baz 2286rmdir /s /Q foo 2287if not exist foo ( 2288 echo recursive rmdir succeeded 2289) else ( 2290 rd foo\bar\baz 2291 rd foo\bar 2292 rd foo 2293) 2294mkdir foo\bar\baz 2295echo foo > foo\bar\brol 2296rmdir /s /Q foo 2>&1 2297if not exist foo ( 2298 echo recursive rmdir succeeded 2299) else ( 2300 rd foo\bar\baz 2301 del foo\bar\brol 2302 rd foo\bar 2303 rd foo 2304) 2305rem multiples directories at once 2306mkdir foobaz & cd foobaz 2307mkdir foo 2308mkdir bar\baz 2309mkdir foobar 2310rd /s/q foo bar foobar 2311if not exist foo (echo foo removed) else echo foo not removed! 2312if not exist bar (echo bar removed) else echo bar not removed! 2313if not exist foobar (echo foobar removed) else echo foobar not removed! 2314if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed! 2315cd .. & rd /s/q foobaz 2316 2317echo ------------ Testing pushd/popd ------------ 2318cd 2319echo --- popd is no-op when dir stack is empty 2320popd 2321cd 2322echo --- pushing non-existing dir 2323pushd foobar 2324cd 2325echo --- basic behaviour 2326mkdir foobar\baz 2327pushd foobar 2328cd 2329popd 2330cd 2331pushd foobar 2332pushd baz 2333cd 2334popd 2335cd 2336pushd baz 2337popd 2338cd 2339popd 2340cd 2341pushd . 2342cd foobar\baz 2343pushd .. 2344cd 2345popd 2346popd 2347cd 2348rd /s/q foobar 2349 2350echo ------------ Testing attrib ------------ 2351rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications 2352mkdir foobar & cd foobar 2353echo foo original contents> foo 2354attrib foo 2355echo > bar 2356echo --- read-only attribute 2357rem Read-only files cannot be altered or deleted, unless forced 2358attrib +R foo 2359attrib foo 2360dir /Ar /B 2361echo bar>> foo 2362type foo 2363del foo > NUL 2>&1 2364if exist foo ( 2365 echo Read-only file not deleted 2366) else ( 2367 echo Should not delete read-only file! 2368) 2369del /F foo 2370if not exist foo ( 2371 echo Read-only file forcibly deleted 2372) else ( 2373 echo Should delete read-only file with del /F! 2374 attrib -r foo 2375 del foo 2376) 2377cd .. & rd /s/q foobar 2378echo --- recursive behaviour 2379mkdir foobar\baz & cd foobar 2380echo > level1 2381echo > whatever 2382echo > baz\level2 2383attrib baz\level2 2384cd .. 2385attrib +R l*vel? /S > nul 2>&1 2386cd foobar 2387attrib level1 2388attrib baz\level2 2389echo > bar 2390attrib bar 2391cd .. & rd /s/q foobar 2392echo --- folders processing 2393mkdir foobar 2394attrib foobar 2395cd foobar 2396mkdir baz 2397echo toto> baz\toto 2398attrib +r baz /s /d > nul 2>&1 2399attrib baz 2400attrib baz\toto 2401echo lulu>>baz\toto 2402type baz\toto 2403echo > baz\lala 2404rem Oddly windows allows file creation in a read-only directory... 2405if exist baz\lala (echo file created in read-only dir) else echo file not created 2406cd .. & rd /s/q foobar 2407 2408echo ------------ Testing assoc ------------ 2409rem Modifying associations requires some privileges... 2410net session >nul 2>&1 2411if errorlevel 1 goto :SkipAssoc 2412 2413rem FIXME Can't test error messages in the current test system, so we have to use some kludges 2414rem FIXME Revise once || conditional execution is fixed 2415mkdir foobar & cd foobar 2416echo --- setting association 2417assoc .foo > baz 2418type baz 2419echo --- 2420 2421assoc .foo=bar 2422assoc .foo 2423 2424rem association set system-wide 2425echo @echo off> tmp.cmd 2426echo echo +++>> tmp.cmd 2427echo assoc .foo>> tmp.cmd 2428cmd /c tmp.cmd 2429 2430echo --- resetting association 2431assoc .foo= 2432assoc .foo > baz 2433type baz 2434echo --- 2435 2436rem association removal set system-wide 2437cmd /c tmp.cmd > baz 2438type baz 2439echo --- 2440cd .. & rd /s/q foobar 2441goto ContinueFType 2442:SkipAssoc 2443echo --- setting association 2444echo --- 2445echo .foo=bar 2446echo .foo=bar 2447echo +++ 2448echo .foo=bar 2449echo --- resetting association 2450echo --- 2451echo +++ 2452echo --- 2453 2454 2455:ContinueFType 2456echo ------------ Testing ftype ------------ 2457rem Modifying associations requires some privileges... 2458net session >nul 2>&1 2459if errorlevel 1 goto :SkipFType 2460rem FIXME Can't test error messages in the current test system, so we have to use some kludges 2461rem FIXME Revise once || conditional execution is fixed 2462mkdir foobar & cd foobar 2463echo --- setting association 2464ftype footype> baz 2465type baz 2466echo --- 2467 2468ftype footype=foo_opencmd 2469assoc .foo=footype 2470ftype footype 2471 2472rem association set system-wide 2473echo @echo off> tmp.cmd 2474echo echo +++>> tmp.cmd 2475echo ftype footype>> tmp.cmd 2476cmd /c tmp.cmd 2477 2478echo --- resetting association 2479assoc .foo= 2480 2481rem Removing a file type association doesn't work on XP due to a bug, so a workaround is needed 2482setlocal EnableDelayedExpansion 2483set WINE_FOO=original value 2484ftype footype= 2485ftype footype > baz 2486for /F %%i in ('type baz') do (set WINE_FOO=buggyXP) 2487rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion) 2488rem FIXME Revisit once a grep-like program like ftype is implemented 2489rem (e.g. to check baz's size using dir /b instead) 2490echo !WINE_FOO! 2491 2492rem cleanup registry 2493echo REGEDIT4> regCleanup.reg 2494echo.>> regCleanup.reg 2495echo [-HKEY_CLASSES_ROOT\footype]>> regCleanup.reg 2496regedit /s regCleanup.reg 2497set WINE_FOO= 2498endlocal 2499cd .. & rd /s/q foobar 2500goto ContinueCall 2501:SkipFType 2502echo --- setting association 2503echo --- 2504echo footype=foo_opencmd 2505echo .foo=footype 2506echo footype=foo_opencmd 2507echo +++ 2508echo footype=foo_opencmd 2509echo --- resetting association 2510echo original value 2511 2512:ContinueCall 2513echo ------------ Testing CALL ------------ 2514mkdir foobar & cd foobar 2515echo --- external script 2516echo echo foo %%1> foo.cmd 2517call foo 2518call foo.cmd 8 2519echo echo %%1 %%2 > foo.cmd 2520call foo.cmd foo 2521call foo.cmd foo bar 2522call foo.cmd foo "" 2523call foo.cmd "" bar 2524call foo.cmd foo '' 2525call foo.cmd '' bar 2526del foo.cmd 2527 2528echo --- internal routines 2529call :testRoutine :testRoutine 2530goto :endTestRoutine 2531:testRoutine 2532echo bar %1 2533goto :eof 2534:endTestRoutine 2535 2536call :testRoutineArgs foo 2537call :testRoutineArgs foo bar 2538call :testRoutineArgs foo "" 2539call :testRoutineArgs "" bar 2540call :testRoutineArgs foo '' 2541call :testRoutineArgs '' bar 2542goto :endTestRoutineArgs 2543:testRoutineArgs 2544echo %1 %2 2545goto :eof 2546:endTestRoutineArgs 2547 2548echo --- with builtins 2549call mkdir foo 2550echo %ErrorLevel% 2551if exist foo (echo foo created) else echo foo should exist! 2552rmdir foo 2553set WINE_FOOBAZ_VAR=foobaz 2554call echo Should expand %WINE_FOOBAZ_VAR% 2555set WINE_FOOBAZ_VAR= 2556echo>batfile 2557call dir /b 2558echo>robinfile 2559if 1==1 call del batfile 2560dir /b 2561if exist batfile echo batfile shouldn't exist 2562rem ... but not for 'if' or 'for' 2563call if 1==1 echo bar 2> nul 2564echo %ErrorLevel% 2565call :setError 0 2566call for %%i in (foo bar baz) do echo %%i 2> nul 2567echo %ErrorLevel% 2568rem First look for programs in the path before trying a builtin 2569echo echo non-builtin dir> dir.cmd 2570call dir /b 2571del dir.cmd 2572rem The below line equates to call (, which does nothing, then the 2573rem subsequent lines are executed. 2574call ( 2575 echo Line one 2576 echo Line two 2577) 2578rem The below line equates to call if, which always fails, then the 2579rem subsequent lines are executed. Note cmd.exe swallows all lines 2580rem starting with ) 2581call if 1==1 ( 2582 echo Get if 2583) else ( 2584 echo ... and else! 2585) 2586call call call echo passed 2587cd .. & rd /s/q foobar 2588 2589echo ------------ Testing SHIFT ------------ 2590 2591call :shiftFun p1 p2 p3 p4 p5 2592goto :endShiftFun 2593 2594:shiftFun 2595echo '%1' '%2' '%3' '%4' '%5' 2596shift 2597echo '%1' '%2' '%3' '%4' '%5' 2598shift@tab@ /1 2599echo '%1' '%2' '%3' '%4' '%5' 2600shift /2 2601echo '%1' '%2' '%3' '%4' '%5' 2602shift /-1 2603echo '%1' '%2' '%3' '%4' '%5' 2604shift /0 2605echo '%1' '%2' '%3' '%4' '%5' 2606goto :eof 2607:endShiftFun 2608 2609echo ------------ Testing cmd invocation ------------ 2610rem FIXME: only a stub ATM 2611echo --- a batch file can delete itself 2612echo del foo.cmd>foo.cmd 2613cmd /q /c foo.cmd 2614if not exist foo.cmd ( 2615 echo file correctly deleted 2616) else ( 2617 echo file should be deleted! 2618 del foo.cmd 2619) 2620echo --- a batch file can alter itself 2621echo echo bar^>foo.cmd>foo.cmd 2622cmd /q /c foo.cmd > NUL 2>&1 2623if exist foo.cmd ( 2624 type foo.cmd 2625 del foo.cmd 2626) else ( 2627 echo file not created! 2628) 2629 2630echo ---------- Testing copy 2631md foobar2 2632cd foobar2 2633rem Note echo adds 0x0d 0x0a on the end of the line in the file 2634echo AAA> file1 2635echo BBBBBB> file2 2636echo CCCCCCCCC> file3 2637md dir1 2638goto :testcopy 2639 2640:CheckExist 2641if exist "%1" ( 2642 echo Passed: Found expected %1 2643) else ( 2644 echo Failed: Did not find expected %1 2645) 2646del /q "%1" >nul 2>&1 2647shift 2648if not "%1"=="" goto :CheckExist 2649goto :eof 2650 2651:CheckNotExist 2652if not exist "%1" ( 2653 echo Passed: Did not find %1 2654) else ( 2655 echo Failed: Unexpectedly found %1 2656 del /q "%1" >nul 2>&1 2657) 2658shift 2659if not "%1"=="" goto :CheckNotExist 2660goto :eof 2661 2662rem Note: No way to check file size on NT4 so skip the test 2663:CheckFileSize 2664if not exist "%1" ( 2665 echo Failed: File missing when requested filesize check [%2] 2666 goto :ContinueFileSizeChecks 2667) 2668for %%i in (%1) do set WINE_filesize=%%~zi 2669if "%WINE_filesize%"=="%2" ( 2670 echo Passed: file size check on %1 [%WINE_filesize%] 2671) else ( 2672 if "%WINE_filesize%"=="%%~zi" ( 2673 echo Skipping file size check on NT4 2674 ) else ( 2675 echo Failed: file size check on %1 [%WINE_filesize% != %2] 2676 ) 2677) 2678:ContinueFileSizeChecks 2679shift 2680shift 2681if not "%1"=="" goto :CheckFileSize 2682goto :eof 2683 2684:testcopy 2685 2686rem ----------------------- 2687rem Simple single file copy 2688rem ----------------------- 2689rem Simple single file copy, normally used syntax 2690copy file1 dummy.file >nul 2>&1 2691if errorlevel 1 echo Incorrect errorlevel 2692call :CheckExist dummy.file 2693 2694rem Simple single file copy, destination supplied as two forms of directory 2695copy file1 dir1 >nul 2>&1 2696if errorlevel 1 echo Incorrect errorlevel 2697call :CheckExist dir1\file1 2698 2699copy file1 dir1\ >nul 2>&1 2700if errorlevel 1 echo Incorrect errorlevel 2701call :CheckExist dir1\file1 2702 2703rem Simple single file copy, destination supplied as fully qualified destination 2704copy file1 dir1\file99 >nul 2>&1 2705if errorlevel 1 echo Incorrect errorlevel 2706call :CheckExist dir1\file99 2707 2708rem Simple single file copy, destination not supplied 2709cd dir1 2710copy ..\file1 >nul 2>&1 2711if errorlevel 1 echo Incorrect errorlevel 2712call :CheckExist file1 2713cd .. 2714 2715rem Simple single file copy, destination supplied as nonexistent directory 2716copy file1 dir2\ >nul 2>&1 2717if not errorlevel 1 echo Incorrect errorlevel 2718call :CheckNotExist dir2 dir2\file1 2719 2720rem ----------------------- 2721rem Wildcarded copy 2722rem ----------------------- 2723rem Simple single file copy, destination supplied as two forms of directory 2724copy file? dir1 >nul 2>&1 2725if errorlevel 1 echo Incorrect errorlevel 2726call :CheckExist dir1\file1 dir1\file2 dir1\file3 2727 2728copy file* dir1\ >nul 2>&1 2729if errorlevel 1 echo Incorrect errorlevel 2730call :CheckExist dir1\file1 dir1\file2 dir1\file3 2731 2732rem Simple single file copy, destination not supplied 2733cd dir1 2734copy ..\file*.* >nul 2>&1 2735if errorlevel 1 echo Incorrect errorlevel 2736call :CheckExist file1 file2 file3 2737cd .. 2738 2739rem Simple wildcarded file copy, destination supplied as nonexistent directory 2740copy file? dir2\ >nul 2>&1 2741if not errorlevel 1 echo Incorrect errorlevel 2742call :CheckNotExist dir2 dir2\file1 dir2\file2 dir2\file3 2743 2744rem ------------------------------------------------ 2745rem Confirm overwrite works (cannot test prompting!) 2746rem ------------------------------------------------ 2747copy file1 testfile >nul 2>&1 2748copy /y file2 testfile >nul 2>&1 2749call :CheckExist testfile 2750 2751rem ------------------------------------------------ 2752rem Test concatenation 2753rem ------------------------------------------------ 2754rem simple case, no wildcards 2755copy file1+file2 testfile >nul 2>&1 2756if errorlevel 1 echo Incorrect errorlevel 2757call :CheckExist testfile 2758 2759rem simple case, wildcards, no concatenation 2760copy file* testfile >nul 2>&1 2761if errorlevel 1 echo Incorrect errorlevel 2762call :CheckExist testfile 2763 2764rem simple case, wildcards, and concatenation 2765echo ddddd > fred 2766copy file*+fred testfile >nul 2>&1 2767if errorlevel 1 echo Incorrect errorlevel 2768call :CheckExist testfile 2769 2770rem simple case, wildcards, and concatenation 2771copy fred+file* testfile >nul 2>&1 2772if errorlevel 1 echo Incorrect errorlevel 2773call :CheckExist testfile 2774 2775rem Calculate destination name 2776copy fred+file* dir1 >nul 2>&1 2777if errorlevel 1 echo Incorrect errorlevel 2778call :CheckExist dir1\fred 2779 2780rem Calculate destination name 2781copy fred+file* dir1\ >nul 2>&1 2782if errorlevel 1 echo Incorrect errorlevel 2783call :CheckExist dir1\fred 2784 2785rem Calculate destination name (none supplied) 2786cd dir1 2787copy ..\fred+..\file* >nul 2>&1 2788if errorlevel 1 echo Incorrect errorlevel 2789call :CheckExist fred 2790 2791copy ..\fr*+..\file1 >nul 2>&1 2792if errorlevel 1 echo Incorrect errorlevel 2793call :CheckExist fred 2794cd .. 2795 2796rem ****************************************************************** 2797rem ASCII and BINARY tests 2798rem Note: hard coded numbers deliberate because need to ensure whether 2799rem an additional EOF has been added or not. There is no way to handle 2800rem EOFs in batch, so assume if a single byte appears, it's an EOF! 2801rem ****************************************************************** 2802 2803rem Confirm original sizes of file1,2,3 2804call :CheckFileSize file1 5 file2 8 file3 11 2805 2806cd dir1 2807 2808rem ---------------------------------------------- 2809rem Show concatenation defaults copy to ascii mode 2810rem ---------------------------------------------- 2811rem Simple default copy source to destination (should not append EOF 5) 2812copy ..\file1 file1_default >nul 2>&1 2813call :CheckFileSize file1_default 5 2814 2815rem Simple binary copy source to destination (should not append EOF 5) 2816copy /b ..\file1 file1_default2 >nul 2>&1 2817call :CheckFileSize file1_default2 5 2818 2819rem Simple ascii copy source to destination (should append EOF 5+1, 8+1, 11+1) 2820copy /a ..\file1 file1_plus_eof >nul 2>&1 2821call :CheckFileSize file1_plus_eof 6 2822copy /a ..\file2 file2_plus_eof >nul 2>&1 2823call :CheckFileSize file2_plus_eof 9 2824copy /a ..\file3 file3_plus_eof >nul 2>&1 2825call :CheckFileSize file3_plus_eof 12 2826 2827rem Concat 2 files, ascii mode - (only one EOF on the end 5+8+1) 2828copy /a ..\file1+..\file2 file12_plus_eof >nul 2>&1 2829call :CheckFileSize file12_plus_eof 14 2830 2831rem Concat 2 files, binary mode - (no EOF on the end 5+8) 2832copy /b ..\file1+..\file2 file12_no_eof >nul 2>&1 2833call :CheckFileSize file12_no_eof 13 2834 2835rem Concat 2 files, default mode - (one EOF on the end 5+8+1) 2836copy ..\file1+..\file2 file12_eof2 >nul 2>&1 2837call :CheckFileSize file12_eof2 14 2838 2839rem Test copying when destination is one of the sources. 2840rem Concat file1+file2+file3 into file1, should produce file1+file2+file3 = 24 2841copy /y ..\file? .\ >nul 2>&1 2842copy /y /b file1+file2+file3 file1 >nul 2>&1 2843call :CheckFileSize file1 24 2844 2845rem Concat file1+file2+file3 into file2, should produce file1+file3 = 16 2846copy /y ..\file? .\ >nul 2>&1 2847copy /y /b file1+file2+file3 file2 >nul 2>&1 2848call :CheckFileSize file2 16 2849 2850rem Concat file1+file2+file3 into file3, should produce file1+file2 = 13 2851copy /y ..\file? .\ >nul 2>&1 2852copy /y /b file1+file2+file3 file3 >nul 2>&1 2853call :CheckFileSize file3 13 2854 2855rem -------------------------------------------------------------- 2856rem Show ascii source copy stops at first EOF, binary does the lot 2857rem -------------------------------------------------------------- 2858copy file1_plus_eof /b file1_binary_srccopy /b >nul 2>&1 2859call :CheckFileSize file1_binary_srccopy 6 2860 2861copy file1_plus_eof /a file1_ascii_srccopy /b >nul 2>&1 2862call :CheckFileSize file1_ascii_srccopy 5 2863 2864rem -------------------------------------------------------------- 2865rem Show results of concatenating files (ending in EOFs) and /a /b 2866rem -------------------------------------------------------------- 2867 2868rem Default and ascii copy reads as ascii, stripping EOFs, so 6-1 + 9-1 + 12-1 + 1 2869copy file1_plus_eof+file2_plus_eof+file3_plus_eof file123_default_copy >nul 2>&1 2870call :CheckFileSize file123_default_copy 25 2871copy /a file1_plus_eof+file2_plus_eof+file3_plus_eof file123_ascii_copy >nul 2>&1 2872call :CheckFileSize file123_ascii_copy 25 2873 2874rem In binary mode, we get 3 eofs, so 6 + 9 + 12 = 27 2875copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_binary_copy >nul 2>&1 2876call :CheckFileSize file123_binary_copy 27 2877 2878rem We can select which we want the eofs from by postfixing it with /a or /b 2879rem so here have first and third with eof, second as ascii 6 + 9-1 + 12 2880copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy1 >nul 2>&1 2881call :CheckFileSize file123_mixed_copy1 26 2882 2883rem By postfixing the destination with /a, we ask for an ascii destination which appends EOF 2884rem so here have first and third with eof, second as ascii 6 + 9-1 + 12 + extra EOF 2885rem Note the delta between this and the previous one also shows that the destination 2886rem ascii/binary is inherited from the last /a or /b on the line 2887copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy2 /a >nul 2>&1 2888call :CheckFileSize file123_mixed_copy2 27 2889 2890rem so here have second with eof, first and third as ascii 6-1 + 9 + 12-1 2891rem Note the delta between the next two also shows that the destination ascii/binary is 2892rem inherited from the last /a or /b on the line, so the first has an extra EOF 2893copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy3 >nul 2>&1 2894call :CheckFileSize file123_mixed_copy3 26 2895copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy4 /b >nul 2>&1 2896call :CheckFileSize file123_mixed_copy4 25 2897 2898rem ------------------------------------------------------------------------------------------- 2899rem This shows when concatenating, an ascii destination always adds on an EOF but when we 2900rem are not concatenating, it's a direct copy regardless of destination if being read as binary 2901rem ------------------------------------------------------------------------------------------- 2902 2903rem All 3 have eof's, plus an extra = 6 + 9 + 12 + eof 2904copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_mixed_copy5 /a >nul 2>&1 2905call :CheckFileSize file123_mixed_copy5 28 2906 2907rem All 2 have eof's, plus an extra = 6 + 12 + eof 2908copy /b file1_plus_eof + file3_plus_eof file123_mixed_copy6 /a >nul 2>&1 2909call :CheckFileSize file123_mixed_copy6 19 2910 2911rem One file has EOF, but doesn't get an extra one, i.e. 6 2912copy /b file1_plus_eof file123_mixed_copy7 /a >nul 2>&1 2913call :CheckFileSize file123_mixed_copy7 6 2914 2915rem Syntax means concatenate so ascii destination kicks in 2916copy /b file1_plus_eof* file123_mixed_copy8 /a >nul 2>&1 2917call :CheckFileSize file123_mixed_copy8 7 2918 2919del *.* /q 2920cd .. 2921 2922rem --------------------------------------- 2923rem Error combinations 2924rem --------------------------------------- 2925rem Specify source directory but name is a file 2926call :setError 0 2927copy file1\ dir1\ >NUL 2>&1 2928if errorlevel 1 echo Passed: errorlevel invalid check 1 2929if not errorlevel 1 echo Failed: errorlevel invalid check 1 2930call :CheckNotExist dir1\file1 2931 2932rem Overwrite same file 2933call :setError 0 2934copy file1 file1 >NUL 2>&1 2935if errorlevel 1 echo Passed: errorlevel invalid check 2 2936if not errorlevel 1 echo Failed: errorlevel invalid check 2 2937 2938rem Supply same file identified as a directory 2939call :setError 0 2940copy file1 file1\ >NUL 2>&1 2941if errorlevel 1 echo Passed: errorlevel invalid check 3 2942if not errorlevel 1 echo Failed: errorlevel invalid check 3 2943 2944cd .. 2945rd foobar2 /s /q 2946 2947echo ------------ Testing setlocal/endlocal ------------ 2948call :setError 0 2949rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test section 2950mkdir foobar & cd foobar 2951echo --- enable/disable extensions 2952setlocal DisableEXTensions 2953echo ErrLev: %ErrorLevel% 2954endlocal 2955echo ErrLev: %ErrorLevel% 2956echo @echo off> tmp.cmd 2957echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd 2958rem Enabled by default 2959cmd /C tmp.cmd 2960cmd /E:OfF /C tmp.cmd 2961cmd /e:oN /C tmp.cmd 2962 2963rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet) 2964echo --- setlocal with corresponding endlocal 2965rem %CD% does not work on NT4 so use the following workaround 2966for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi 2967echo @echo off> test.cmd 2968echo echo %%WINE_VAR%%>> test.cmd 2969echo setlocal>> test.cmd 2970echo set WINE_VAR=localval>> test.cmd 2971echo md foobar2>> test.cmd 2972echo cd foobar2>> test.cmd 2973echo echo %%WINE_VAR%%>> test.cmd 2974echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd 2975echo endlocal>> test.cmd 2976echo echo %%WINE_VAR%%>> test.cmd 2977echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd 2978set WINE_VAR=globalval 2979call test.cmd 2980echo %WINE_VAR% 2981for /d %%i in (.) do echo %%~dpnxi 2982cd /d %WINE_CURDIR% 2983rd foobar2 2984set WINE_VAR= 2985echo --- setlocal with no corresponding endlocal 2986echo @echo off> test.cmd 2987echo echo %%WINE_VAR%%>> test.cmd 2988echo setlocal>> test.cmd 2989echo set WINE_VAR=localval>> test.cmd 2990echo md foobar2>> test.cmd 2991echo cd foobar2>> test.cmd 2992echo echo %%WINE_VAR%%>> test.cmd 2993echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd 2994set WINE_VAR=globalval 2995rem %CD% does not work on NT4 so use the following workaround 2996for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi 2997call test.cmd 2998echo %WINE_VAR% 2999for /d %%i in (.) do echo %%~dpnxi 3000cd /d %WINE_CURDIR% 3001rd foobar2 3002set WINE_VAR= 3003echo --- setlocal within same batch program 3004set WINE_var1=one 3005set WINE_var2= 3006set WINE_var3= 3007rem %CD% does not work on NT4 so use the following workaround 3008for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi 3009setlocal 3010set WINE_var2=two 3011mkdir foobar2 3012cd foobar2 3013setlocal 3014set WINE_var3=three 3015if "%WINE_var1%"=="one" echo Var1 ok 1 3016if "%WINE_var2%"=="two" echo Var2 ok 2 3017if "%WINE_var3%"=="three" echo Var3 ok 3 3018for /d %%i in (.) do set WINE_curdir2=%%~dpnxi 3019if "%WINE_curdir2%"=="%WINE_CURDIR%\foobar2" echo Directory is ok 1 3020endlocal 3021if "%WINE_var1%"=="one" echo Var1 ok 1 3022if "%WINE_var2%"=="two" echo Var2 ok 2 3023if "%WINE_var3%"=="" echo Var3 ok 3 3024for /d %%i in (.) do set WINE_curdir2=%%~dpnxi 3025if "%WINE_curdir2%"=="%WINE_CURDIR%\foobar2" echo Directory is ok 2 3026endlocal 3027if "%WINE_var1%"=="one" echo Var1 ok 1 3028if "%WINE_var2%"=="" echo Var2 ok 2 3029if "%WINE_var3%"=="" echo Var3 ok 3 3030for /d %%i in (.) do set WINE_curdir2=%%~dpnxi 3031if "%WINE_curdir2%"=="%WINE_CURDIR%" echo Directory is ok 3 3032rd foobar2 /s /q 3033set WINE_var1= 3034 3035echo --- Mismatched set and end locals 3036mkdir foodir2 2>nul 3037mkdir foodir3 2>nul 3038mkdir foodir4 2>nul 3039rem %CD% does not work on NT4 so use the following workaround 3040for /d %%i in (.) do set WINE_curdir=%%~dpnxi 3041 3042echo @echo off> 2set1end.cmd 3043echo echo %%WINE_var%%>> 2set1end.cmd 3044echo setlocal>> 2set1end.cmd 3045echo set WINE_VAR=2set1endvalue1>> 2set1end.cmd 3046echo cd ..\foodir3>> 2set1end.cmd 3047echo setlocal>> 2set1end.cmd 3048echo set WINE_VAR=2set1endvalue2>> 2set1end.cmd 3049echo cd ..\foodir4>> 2set1end.cmd 3050echo endlocal>> 2set1end.cmd 3051echo echo %%WINE_var%%>> 2set1end.cmd 3052echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 2set1end.cmd 3053 3054echo @echo off> 1set2end.cmd 3055echo echo %%WINE_var%%>> 1set2end.cmd 3056echo setlocal>> 1set2end.cmd 3057echo set WINE_VAR=1set2endvalue1>> 1set2end.cmd 3058echo cd ..\foodir3>> 1set2end.cmd 3059echo endlocal>> 1set2end.cmd 3060echo echo %%WINE_var%%>> 1set2end.cmd 3061echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd 3062echo endlocal>> 1set2end.cmd 3063echo echo %%WINE_var%%>> 1set2end.cmd 3064echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd 3065 3066echo --- Extra setlocal in called batch 3067set WINE_VAR=value1 3068rem -- setlocal1 == this batch, should never be used inside a called routine 3069setlocal 3070set WINE_var=value2 3071cd foodir2 3072call "%WINE_CURDIR%\2set1end.cmd" 3073echo Finished: 3074echo %WINE_VAR% 3075for /d %%i in (.) do echo %%~dpnxi 3076endlocal 3077echo %WINE_VAR% 3078for /d %%i in (.) do echo %%~dpnxi 3079cd /d %WINE_CURDIR% 3080 3081echo --- Extra endlocal in called batch 3082set WINE_VAR=value1 3083rem -- setlocal1 == this batch, should never be used inside a called routine 3084setlocal 3085set WINE_var=value2 3086cd foodir2 3087call "%WINE_CURDIR%\1set2end.cmd" 3088echo Finished: 3089echo %WINE_VAR% 3090for /d %%i in (.) do echo %%~dpnxi 3091endlocal 3092echo %WINE_VAR% 3093for /d %%i in (.) do echo %%~dpnxi 3094cd /d %WINE_CURDIR% 3095 3096echo --- endlocal in called function rather than batch pgm is ineffective 3097@echo off 3098set WINE_var=1 3099set WINE_var2=1 3100setlocal 3101set WINE_var=2 3102call :endlocalroutine 3103echo %WINE_var% 3104endlocal 3105echo %WINE_var% 3106goto :endlocalfinished 3107:endlocalroutine 3108echo %WINE_var% 3109endlocal 3110echo %WINE_var% 3111setlocal 3112set WINE_var2=2 3113endlocal 3114echo %WINE_var2% 3115endlocal 3116echo %WINE_var% 3117echo %WINE_var2% 3118goto :eof 3119:endlocalfinished 3120echo %WINE_var% 3121 3122set WINE_var= 3123set WINE_var2= 3124cd .. & rd /q/s foobar 3125 3126echo ------------ Testing Errorlevel ------------ 3127rem WARNING: Do *not* add tests using ErrorLevel after this section 3128should_not_exist 2> nul > nul 3129echo %ErrorLevel% 3130rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak 3131rem See http://www.robvanderwoude.com/exit.php 3132call :setError 1 3133echo %ErrorLevel% 3134if errorlevel 2 echo errorlevel too high, bad 3135if errorlevel 1 echo errorlevel just right, good 3136if errorlevel 01 echo errorlevel with leading zero just right, good 3137if errorlevel -1 echo errorlevel with negative number OK 3138if errorlevel 0x1 echo hexa should not be recognized! 3139if errorlevel 1a echo invalid error level recognized! 3140call :setError 0 3141echo abc%ErrorLevel%def 3142if errorlevel 1 echo errorlevel nonzero, bad 3143if not errorlevel 1 echo errorlevel zero, good 3144if not errorlevel 0x1 echo hexa should not be recognized! 3145if not errorlevel 1a echo invalid error level recognized! 3146rem Now verify that setting a real variable hides its magic variable 3147set errorlevel=7 3148echo %ErrorLevel% should be 7 3149if errorlevel 7 echo setting var worked too well, bad 3150call :setError 3 3151echo %ErrorLevel% should still be 7 3152 3153echo ------------ Testing GOTO ------------ 3154if a==a goto dest1 3155echo FAILURE at dest 1 3156:dest1 3157echo goto with no leading space worked 3158if a==a goto :dest1b 3159echo FAILURE at dest 1b 3160:dest1b 3161echo goto with colon and no leading space worked 3162if b==b goto dest2 3163echo FAILURE at dest 2 3164 :dest2 3165echo goto with a leading space worked 3166if c==c goto dest3 3167echo FAILURE at dest 3 3168 :dest3 3169echo goto with a leading tab worked 3170if d==d goto dest4 3171echo FAILURE at dest 4 3172:dest4@space@ 3173echo goto with a following space worked 3174if e==e goto dest5 3175echo FAILURE at dest 5 3176:dest5&& echo FAILURE 3177echo goto with following amphersands worked 3178 3179del failure.txt >nul 2>&1 3180if f==f goto dest6 3181echo FAILURE at dest 6 3182:dest6>FAILURE.TXT 3183if exist FAILURE.TXT echo FAILURE at dest 6 as file exists 3184echo goto with redirections worked 3185del FAILURE.TXT >nul 2>&1 3186 3187:: some text that is ignored | dir >cmd_output | another test 3188if exist cmd_output echo FAILURE at dest 6 as file exists 3189echo Ignoring double colons worked 3190del cmd_output >nul 2>&1 3191 3192rem goto a label which does not exist issues an error message and 3193rem acts the same as goto :EOF, and ensure ::label is never matched 3194del testgoto.bat >nul 2>&1 3195echo goto :dest7 ^>nul 2^>^&1 >> testgoto.bat 3196echo echo FAILURE at dest 7 - Should have not found label and issued an error plus ended the batch>> testgoto.bat 3197echo ::dest7>> testgoto.bat 3198echo echo FAILURE at dest 7 - Incorrectly went to label >> testgoto.bat 3199call testgoto.bat 3200del testgoto.bat >nul 2>&1 3201 3202del testgoto.bat >nul 2>&1 3203echo goto ::dest8 ^>nul 2^>^&1 >> testgoto.bat 3204echo echo FAILURE at dest 8 - Should have not found label and issued an error plus ended the batch>> testgoto.bat 3205echo ::dest8>> testgoto.bat 3206echo echo FAILURE at dest 8 - Incorrectly went to label >> testgoto.bat 3207call testgoto.bat 3208del testgoto.bat >nul 2>&1 3209 3210if g==g goto dest9 3211echo FAILURE at dest 9 3212:dest91 3213echo FAILURE at dest 91 3214@ : dest9>rubbish 3215echo label with mixed whitespace and no echo worked 3216 3217if h==h goto :dest10:this is ignored 3218echo FAILURE at dest 10 3219:dest10:this is also ignored 3220echo Correctly ignored trailing information 3221 3222rem Testing which label is reached when there are many options 3223echo Begin: 3224set nextlabel= 3225call :sub 3226set nextlabel=middle 3227goto :sub 3228 3229:sub 3230echo ..First sub 3231if not "%nextlabel%"=="" goto :%nextlabel% 3232goto :EOF 3233 3234:sub 3235echo ..Second sub 3236if not "%nextlabel%"=="" goto :%nextlabel% 3237goto :EOF 3238 3239:middle 3240echo Middle: 3241set nextlabel= 3242call :sub 3243set nextlabel=nearend 3244goto :sub 3245 3246:sub 3247echo ..Third sub 3248if not "%nextlabel%"=="" goto :%nextlabel% 3249goto :EOF 3250 3251:nearend 3252echo Near end: 3253set nextlabel= 3254call :sub 3255set nextlabel=end 3256goto :sub 3257 3258:sub 3259echo ..Fourth sub 3260if not "%nextlabel%"=="" goto :%nextlabel% 3261goto :EOF 3262 3263:end 3264echo At end: 3265set nextlabel= 3266call :sub 3267set nextlabel=done 3268goto :sub 3269 3270:done 3271echo Finished 3272 3273echo ------------ Testing PATH ------------ 3274set WINE_backup_path=%path% 3275set path=original 3276path 3277path try2 3278path 3279path=try3 3280path 3281set path=%WINE_backup_path% 3282set WINE_backup_path= 3283 3284echo ------------ Testing start /W ------------ 3285echo start /W failed to wait>foobar.txt 3286start /W "" cmd /C "ping -n1 & echo start /W seems to really wait>foobar.txt"& type foobar.txt& del foobar.txt 3287 3288echo ------------ Testing changing the drive letter ---------- 3289pushd C:\ 3290 3291echo Normal: 3292call :setError 0 3293C: 3294if errorlevel 1 echo Normal drive change failed 3295 3296echo Normal+space 3297call :setError 0 3298C:@space@ 3299if errorlevel 1 echo Normal+space drive change failed 3300 3301echo Normal+space+garbage 3302call :setError 0 3303C: garbage 3304if errorlevel 1 echo Normal+space+garbage drive change failed 3305 3306call :setError 0 3307echo Quoted should fail 3308"C:" 3309if not errorlevel 1 echo quoted drive change unexpectedly worked 3310 3311echo Normal+tab 3312call :setError 0 3313C:@tab@ 3314if errorlevel 1 echo Normal+tab drive change failed 3315 3316echo Normal+tab+garbage 3317call :setError 0 3318C:@tab@garbagetab 3319if errorlevel 1 echo Normal+tab+garbage drive change failed 3320 3321popd 3322 3323echo ------------ Testing combined CALLs/GOTOs ------------ 3324echo @echo off>foo.cmd 3325echo goto :eof>>foot.cmd 3326echo :eof>>foot.cmd 3327echo echo world>>foo.cmd 3328 3329echo @echo off>foot.cmd 3330echo echo cheball>>foot.cmd 3331echo.>>foot.cmd 3332echo call :bar>>foot.cmd 3333echo if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmd 3334echo goto :eof>>foot.cmd 3335echo.>>foot.cmd 3336echo :bar>>foot.cmd 3337echo echo barbare>>foot.cmd 3338echo goto :eof>>foot.cmd 3339 3340call foo.cmd 3341call foot 3342call :bar 3343del foo.cmd 3344rem Script execution stops after the following line 3345foot deleteMe 3346call :foo 3347call :foot 3348goto :endFuns 3349 3350:foot 3351echo foot 3352 3353:foo 3354echo foo 3355goto :eof 3356 3357:endFuns 3358 3359:bar 3360echo bar 3361call :foo 3362 3363:baz 3364echo baz 3365goto :eof 3366 3367echo Final message is not output since earlier 'foot' processing stops script execution 3368echo Do NOT add any tests below this line 3369 3370echo ------------ Done, jumping to EOF ----------- 3371goto :eof 3372rem Subroutine to set errorlevel and return 3373rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported 3374:setError 3375exit /B %1 3376rem This line runs under cmd in windows NT 4, but not in more modern versions. 3377