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 878del foobaz 879 880echo ------------ Testing NUL ------------ 881md foobar & cd foobar 882rem NUL file (non) creation + case insensitivity 883rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround 884echo > bar 885echo foo > NUL 886dir /b /a-d 887echo foo > nul 888dir /b /a-d 889echo foo > NuL 890@tab@dir /b@tab@/a-d 891del bar 892rem NUL not special everywhere 893call :setError 123 894echo NUL> foo 895if not exist foo (echo foo should have been created) else ( 896 type foo 897 del foo 898) 899rem Empty file creation 900copy nul foo > nul 901if exist foo ( 902 echo foo created 903 del foo 904 type foo 905) else ( 906 echo *** 907) 908echo 1234 >a.a 909copy a.a+NUL b.b >nul 910call :CheckFileSize a.a 7 b.b 8 911copy NUL+a.a b.b >nul 912call :CheckFileSize a.a 7 b.b 8 913mkdir subdir 914copy a.a+NUL subdir\ >nul 915call :CheckFileSize a.a 7 subdir\a.a 8 916del subdir\a.a 917cd subdir 918copy ..\a.a NUL >nul 919if exist a.a echo Failed 920cd .. 921rd subdir /s /q 922del a.a b.b 923cd .. & rd foobar /s /q 924 925echo ------------ Testing if/else ------------ 926echo --- if/else should work with blocks 927if 0 == 0 ( 928 echo if seems to work 929) else ( 930 echo if seems to be broken 931) 932if 1 == 0 ( 933 echo else seems to be broken 934) else ( 935 echo else seems to work 936) 937if /c==/c ( 938 echo if seems not to detect /c as parameter 939) else ( 940 echo parameter detection seems to be broken 941) 942SET elseIF=0 943if 1 == 1 ( 944 SET /a elseIF=%elseIF%+1 945) else if 1 == 1 ( 946 SET /a elseIF=%elseIF%+2 947) else ( 948 SET /a elseIF=%elseIF%+2 949) 950if %elseIF% == 1 ( 951 echo else if seems to work 952) else ( 953 echo else if seems to be broken 954) 955SET elseIF=0 956if 1 == 2 ( 957 SET /a elseIF=%elseIF%+2 958) else if 1 == 1 ( 959 SET /a elseIF=%elseIF%+1 960) else ( 961 SET /a elseIF=%elseIF%+2 962) 963if %elseIF% == 1 ( 964 echo else if seems to work 965) else ( 966 echo else if seems to be broken 967) 968SET elseIF=0 969if 1 == 2 ( 970 SET /a elseIF=%elseIF%+2 971) else if 1 == 2 ( 972 SET /a elseIF=%elseIF%+2 973) else ( 974 SET /a elseIF=%elseIF%+1 975) 976if %elseIF% == 1 ( 977 echo else if seems to work 978) else ( 979 echo else if seems to be broken 980) 981if "x" == "a" ( 982 echo broken1 983) else ( 984 echo expected1 985 if "y" == "b" echo broken2 986 echo expected post-embedded if 987) 988echo --- case sensitivity with and without /i option 989if bar==BAR echo if does not default to case sensitivity 990if not bar==BAR echo if seems to default to case sensitivity 991if /i foo==FOO echo if /i seems to work 992if /i not foo==FOO echo if /i seems to be broken 993if /I foo==FOO echo if /I seems to work 994if /I not foo==FOO echo if /I seems to be broken 995 996echo --- string comparisons 997if abc == abc (echo equal) else echo non equal 998if abc =="abc" (echo equal) else echo non equal 999if "abc"== abc (echo equal) else echo non equal 1000if "abc"== "abc" (echo equal) else echo non equal 1001 1002echo --- tabs handling 1003if@tab@1==1 echo doom 1004if @tab@1==1 echo doom 1005if 1==1 (echo doom) else@tab@echo quake 1006if@tab@not @tab@1==@tab@0 @tab@echo lol 1007if 1==0@tab@(echo doom) else echo quake 1008if 1==0 (echo doom)@tab@else echo quake 1009if 1==0 (echo doom) else@tab@echo quake 1010 1011echo --- comparison operators 1012rem NT4 misevaluates conditionals in for loops so we have to use subroutines as workarounds 1013echo ------ for strings 1014rem NT4 stops processing of the whole batch file as soon as it finds a 1015rem comparison operator non fully uppercased, such as lss instead of LSS, so we 1016rem can't test those here. 1017if LSS LSS LSSfoo (echo LSS string can be used as operand for LSS comparison) 1018if LSS LSS LSS (echo bar) 1019if 1.1 LSS 1.10 (echo floats are handled as strings) 1020if "9" LSS "10" (echo numbers in quotes recognized!) else echo numbers in quotes are handled as strings 1021if not "-1" LSS "1" (echo negative numbers as well) else echo NT4 1022if /i foo LSS FoOc echo if /i seems to work for LSS 1023if /I not foo LSS FOOb echo if /I seems to be broken for LSS 1024set WINE_STR_PARMS=A B AB BA AA 1025for %%i in (%WINE_STR_PARMS%) do ( 1026 for %%j in (%WINE_STR_PARMS%) do ( 1027 call :LSStest %%i %%j)) 1028if b LSS B (echo b LSS B) else echo NT4 1029if /I b LSS B echo b LSS B insensitive 1030if b LSS A echo b LSS A 1031if /I b LSS A echo b LSS A insensitive 1032if a LSS B (echo a LSS B) else echo NT4 1033if /I a LSS B echo a LSS B insensitive 1034if A LSS b echo A LSS b 1035if /I A LSS b echo A LSS b insensitive 1036for %%i in (%WINE_STR_PARMS%) do ( 1037 for %%j in (%WINE_STR_PARMS%) do ( 1038 call :LEQtest %%i %%j)) 1039if b LEQ B (echo b LEQ B) else echo NT4 1040if /I b LEQ B echo b LEQ B insensitive 1041if b LEQ A echo b LEQ A 1042if /I b LEQ A echo b LEQ A insensitive 1043if a LEQ B (echo a LEQ B) else echo NT4 1044if /I a LEQ B echo a LEQ B insensitive 1045if A LEQ b echo A LEQ b 1046if /I A LEQ b echo A LEQ b insensitive 1047for %%i in (%WINE_STR_PARMS%) do ( 1048 for %%j in (%WINE_STR_PARMS%) do ( 1049 call :EQUtest %%i %%j)) 1050if /I A EQU a echo A EQU a insensitive 1051for %%i in (%WINE_STR_PARMS%) do ( 1052 for %%j in (%WINE_STR_PARMS%) do ( 1053 call :NEQtest %%i %%j)) 1054for %%i in (%WINE_STR_PARMS%) do ( 1055 for %%j in (%WINE_STR_PARMS%) do ( 1056 call :GEQtest %%i %%j)) 1057for %%i in (%WINE_STR_PARMS%) do ( 1058 for %%j in (%WINE_STR_PARMS%) do ( 1059 call :GTRtest %%i %%j)) 1060 1061echo ------------ Testing if/exist ------------ 1062mkdir subdir 1063echo something>subdir\bar 1064echo something else>foo 1065if exist foo ( 1066 echo exist explicit works 1067) else ( 1068 echo ERROR exist explicit broken 1069) 1070if exist bar ( 1071 echo ERROR exist explicit unknown file broken 1072) else ( 1073 echo exist explicit unknown file works 1074) 1075if exist subdir\bar ( 1076 echo exist explicit in subdir works 1077) else ( 1078 echo ERROR exist explicit in subdir broken 1079) 1080if exist fo* ( 1081 echo exist simple wildcard works 1082) else ( 1083 echo ERROR exist simple wildcard broken 1084) 1085if exist subdir\ba* ( 1086 echo exist wildcard works 1087) else ( 1088 echo ERROR exist wildcard broken 1089) 1090if not exist subdir\ba* ( 1091 echo ERROR negate exist wildcard broken 1092) else ( 1093 echo negate exist wildcard works 1094) 1095if exist idontexist\ba* ( 1096 echo ERROR exist wildcard bad subdir broken 1097) else ( 1098 echo exist wildcard bad subdir broken works 1099) 1100if exist subdir ( 1101 echo exist subdir ok 1102) else ( 1103 echo ERROR exist subdir not working 1104) 1105if exist subdir\. ( 1106 echo exist subdir with . ok 1107) else ( 1108 echo ERROR exist subdir with . not working 1109) 1110if exist subdir\ ( 1111 echo exist subdir with \ ok 1112) else ( 1113 echo ERROR exist subdir with \ not working 1114) 1115if exist "subdir\" ( 1116 echo exist subdir with \ and quotes ok 1117) else ( 1118 echo ERROR exist subdir with \ and quotes not working 1119) 1120del foo subdir\bar 1121rd subdir 1122 1123echo ------ for numbers 1124if -1 LSS 1 (echo negative numbers handled) 1125if not -1 LSS -10 (echo negative numbers handled) 1126if not 9 LSS 010 (echo octal handled) 1127if not -010 LSS -8 (echo also in negative form) 1128if 4 LSS 0x5 (echo hexa handled) 1129if not -1 LSS -0x1A (echo also in negative form) 1130if 11 LSS 101 (echo 11 LSS 101) 1131set WINE_INT_PARMS=0 1 10 9 1132for %%i in (%WINE_INT_PARMS%) do ( 1133 for %%j in (%WINE_INT_PARMS%) do ( 1134 call :LSStest %%i %%j)) 1135for %%i in (%WINE_INT_PARMS%) do ( 1136 for %%j in (%WINE_INT_PARMS%) do ( 1137 call :LEQtest %%i %%j)) 1138for %%i in (%WINE_INT_PARMS%) do ( 1139 for %%j in (%WINE_INT_PARMS%) do ( 1140 call :EQUtest %%i %%j)) 1141if 011 EQU 9 (echo octal ok) 1142if 0xA1 EQU 161 (echo hexa ok) 1143if 0xA1 EQU "161" (echo hexa should be recognized) else (echo string/hexa compare ok) 1144if "0xA1" EQU 161 (echo hexa should be recognized) else (echo string/hexa compare ok) 1145for %%i in (%WINE_INT_PARMS%) do ( 1146 for %%j in (%WINE_INT_PARMS%) do ( 1147 call :NEQtest %%i %%j)) 1148for %%i in (%WINE_INT_PARMS%) do ( 1149 for %%j in (%WINE_INT_PARMS%) do ( 1150 call :GEQtest %%i %%j)) 1151for %%i in (%WINE_INT_PARMS%) do ( 1152 for %%j in (%WINE_INT_PARMS%) do ( 1153 call :GTRtest %%i %%j)) 1154echo ------ for numbers and stringified numbers 1155if not "1" EQU 1 (echo strings and integers not equal) else echo foo 1156if not 1 EQU "1" (echo strings and integers not equal) else echo foo 1157if '1' EQU 1 echo '1' EQU 1 1158if 1 EQU '1' echo 1 EQU '1' 1159if not "1" GEQ 1 (echo foo) else echo bar 1160if "10" GEQ "1" echo "10" GEQ "1" 1161if '1' GEQ 1 (echo '1' GEQ 1) else echo NT4 1162if 1 GEQ "1" echo 1 GEQ "1" 1163if "1" GEQ "1" echo "1" GEQ "1" 1164if '1' GEQ "1" echo '1' GEQ "1" 1165if "10" GEQ "1" echo "10" GEQ "1" 1166if not 1 GEQ '1' (echo non NT4) else echo 1 GEQ '1' 1167for %%i in ("1" '1') do call :GEQtest %%i '1' 1168if "10" GEQ '1' (echo "10" GEQ '1') else echo foo 1169if 1 GEQ "10" (echo 1 GEQ "10") else echo foo 1170if "1" GEQ "10" (echo 1 GEQ "10") else echo foo 1171if '1' GEQ "10" (echo '1' GEQ "10") else echo foo 1172if "10" GEQ "10" (echo "10" GEQ "10") 1173echo --- unconditional ampersand after if one line 1174if "0"=="0" echo 1 & echo 2 & echo 3 else echo 4 1175echo --- 1176echo x & if "0"=="1" echo 1 & echo 2 1177echo --- 1178echo x & if "0"=="1" echo 1 & echo 2 & echo 3 1179echo --- 1180echo x & if "0"=="1" (echo 1 & echo 2 & echo 3) 1181echo --- 1182echo x & if "0"=="1" echo 1 & echo 2 & echo 3 else echo 4 1183echo --- 1184goto :endIfCompOpsSubroutines 1185 1186rem IF subroutines helpers 1187:LSStest 1188if %1 LSS %2 echo %1 LSS %2 1189goto :eof 1190:LEQtest 1191if %1 LEQ %2 echo %1 LEQ %2 1192goto :eof 1193:EQUtest 1194if %1 EQU %2 echo %1 EQU %2 1195goto :eof 1196:NEQtest 1197if %1 NEQ %2 echo %1 NEQ %2 1198goto :eof 1199:GEQtest 1200if %1 GEQ %2 echo %1 GEQ %2 1201goto :eof 1202:GTRtest 1203if %1 GTR %2 echo %1 GTR %2 1204goto :eof 1205 1206:endIfCompOpsSubroutines 1207set WINE_STR_PARMS= 1208set WINE_INT_PARMS= 1209 1210echo ------------ Testing for ------------ 1211echo --- plain FOR 1212for %%i in (A B C) do echo %%i 1213for %%i in (A B C) do echo %%I 1214for %%i in (A B C) do echo %%j 1215for %%i in (A B C) do call :forTestFun1 %%i 1216for %%i in (1,4,1) do echo %%i 1217for %%i in (A, B,C) do echo %%i 1218for %%i in (X) do echo %%i 1219for@tab@%%i in (X2) do echo %%i 1220for %%i in@tab@(X3) do echo %%i 1221for %%i in (@tab@ foo@tab@) do echo %%i 1222for@tab@ %%i in@tab@(@tab@M) do echo %%i 1223for %%i@tab@in (X)@tab@do@tab@echo %%i 1224for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j 1225for %%i in (`echo A B`) do echo %%i 1226for %%i in ('echo A B') do echo %%i 1227for %%i in ("echo A B") do echo %%i 1228for %%i in ("A B" C) do echo %%i 1229goto :endForTestFun1 1230:forTestFun1 1231echo %1 1232goto :eof 1233:endForTestFun1 1234echo --- imbricated FORs 1235for %%i in (X) do ( 1236 for %%j in (Y) do ( 1237 echo %%i %%j)) 1238for %%i in (X) do ( 1239 for %%I in (Y) do ( 1240 echo %%i %%I)) 1241for %%i in (A B) do ( 1242 for %%j in (C D) do ( 1243 echo %%i %%j)) 1244for %%i in (A B) do ( 1245 for %%j in (C D) do ( 1246 call :forTestFun2 %%i %%j )) 1247goto :endForTestFun2 1248:forTestFun2 1249echo %1 %2 1250goto :eof 1251:endForTestFun2 1252mkdir foobar & cd foobar 1253mkdir foo 1254mkdir bar 1255mkdir baz 1256mkdir pop 1257echo > bazbaz 1258echo --- basic wildcards 1259for %%i in (ba*) do echo %%i 1260echo --- wildcards in subdirs 1261echo something>pop\bar1 1262echo something>pop\bar2.txt 1263echo something>pop\bar3 1264for %%f in (pop\ba*) do ( call echo %%f ) 1265rmdir /s/q pop 1266echo --- for /d 1267for /d %%i in (baz foo bar) do echo %%i 2>&1 1268rem Confirm we don't match files: 1269for /d %%i in (bazb*) do echo %%i 2>&1 1270for /d %%i in (bazb2*) do echo %%i 2>&1 1271rem Show we pass through non wildcards 1272for /d %%i in (PASSED) do echo %%i 1273for /d %%i in (xxx) do ( 1274 echo %%i - Should be xxx 1275 echo Expected second line 1276) 1277rem Show we issue no messages on failures 1278for /d %%i in (FAILED?) do echo %%i 2>&1 1279for /d %%i in (FAILED?) do ( 1280 echo %%i - Unexpected! 1281 echo FAILED Unexpected second line 1282) 1283for /d %%i in (FAILED*) do echo %%i 2>&1 1284for /d %%i in (FAILED*) do ( 1285 echo %%i - Unexpected! 1286 echo FAILED Unexpected second line 1287) 1288rem FIXME can't test wildcard expansion here since it's listed in directory 1289rem order, and not in alphabetic order. 1290rem Proper testing would need a currently missing "sort" program implementation. 1291rem for /d %%i in (ba*) do echo %%i>> tmp 1292rem sort < tmp 1293rem del tmp 1294rem for /d %%i in (?a*) do echo %%i>> tmp 1295rem sort < tmp 1296rem del tmp 1297rem for /d %%i in (*) do echo %%i>> tmp 1298rem sort < tmp 1299rem del tmp 1300echo > baz\bazbaz 1301goto :TestForR 1302 1303:SetExpected 1304del temp.bat 2>nul 1305call :WriteLine set WINE_found=N 1306for /l %%i in (1,1,%WINE_expectedresults%) do ( 1307 call :WriteLine if "%%%%WINE_expectedresults.%%i%%%%"=="%%%%~1" set WINE_found=Y 1308 call :WriteLine if "%%%%WINE_found%%%%"=="Y" set WINE_expectedresults.%%i= 1309 call :WriteLine if "%%%%WINE_found%%%%"=="Y" goto :eof 1310) 1311call :WriteLine echo Got unexpected result: "%%%%~1" 1312goto :eof 1313 1314:WriteLine 1315echo %*>> temp.bat 1316goto :EOF 1317 1318:ValidateExpected 1319del temp.bat 2>nul 1320for /l %%i in (1,1,%WINE_expectedresults%) do ( 1321 call :WriteLine if not "%%%%WINE_expectedresults.%%i%%%%"=="" echo Found missing result: "%%%%WINE_expectedresults.%%i%%%%" 1322) 1323call temp.bat 1324del temp.bat 2>nul 1325goto :eof 1326 1327:TestForR 1328rem %CD% does not work on NT4 so use the following workaround 1329for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi 1330 1331echo --- for /R 1332echo Plain directory enumeration 1333set WINE_expectedresults=4 1334set WINE_expectedresults.1=%WINE_CURDIR%\. 1335set WINE_expectedresults.2=%WINE_CURDIR%\bar\. 1336set WINE_expectedresults.3=%WINE_CURDIR%\baz\. 1337set WINE_expectedresults.4=%WINE_CURDIR%\foo\. 1338call :SetExpected 1339for /R %%i in (.) do call temp.bat "%%i" 1340call :ValidateExpected 1341 1342echo Plain directory enumeration from provided root 1343set WINE_expectedresults=4 1344set WINE_expectedresults.1=%WINE_CURDIR%\. 1345set WINE_expectedresults.2=%WINE_CURDIR%\bar\. 1346set WINE_expectedresults.3=%WINE_CURDIR%\baz\. 1347set WINE_expectedresults.4=%WINE_CURDIR%\foo\. 1348if "%CD%"=="" goto :SkipBrokenNT4 1349call :SetExpected 1350for /R "%WINE_CURDIR%" %%i in (.) do call temp.bat "%%i" 1351call :ValidateExpected 1352:SkipBrokenNT4 1353 1354echo File enumeration 1355set WINE_expectedresults=2 1356set WINE_expectedresults.1=%WINE_CURDIR%\baz\bazbaz 1357set WINE_expectedresults.2=%WINE_CURDIR%\bazbaz 1358call :SetExpected 1359for /R %%i in (baz*) do call temp.bat "%%i" 1360call :ValidateExpected 1361 1362echo File enumeration from provided root 1363set WINE_expectedresults=2 1364set WINE_expectedresults.1=%WINE_CURDIR%\baz\bazbaz 1365set WINE_expectedresults.2=%WINE_CURDIR%\bazbaz 1366call :SetExpected 1367for /R %%i in (baz*) do call temp.bat "%%i" 1368call :ValidateExpected 1369 1370echo Mixed enumeration 1371set WINE_expectedresults=6 1372set WINE_expectedresults.1=%WINE_CURDIR%\. 1373set WINE_expectedresults.2=%WINE_CURDIR%\bar\. 1374set WINE_expectedresults.3=%WINE_CURDIR%\baz\. 1375set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz 1376set WINE_expectedresults.5=%WINE_CURDIR%\bazbaz 1377set WINE_expectedresults.6=%WINE_CURDIR%\foo\. 1378call :SetExpected 1379for /R %%i in (. baz*) do call temp.bat "%%i" 1380call :ValidateExpected 1381 1382echo Mixed enumeration from provided root 1383set WINE_expectedresults=6 1384set WINE_expectedresults.1=%WINE_CURDIR%\. 1385set WINE_expectedresults.2=%WINE_CURDIR%\bar\. 1386set WINE_expectedresults.3=%WINE_CURDIR%\baz\. 1387set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz 1388set WINE_expectedresults.5=%WINE_CURDIR%\bazbaz 1389set WINE_expectedresults.6=%WINE_CURDIR%\foo\. 1390call :SetExpected 1391for /R %%i in (. baz*) do call temp.bat "%%i" 1392call :ValidateExpected 1393 1394echo With duplicates enumeration 1395set WINE_expectedresults=12 1396set WINE_expectedresults.1=%WINE_CURDIR%\bar\bazbaz 1397set WINE_expectedresults.2=%WINE_CURDIR%\bar\fred 1398set WINE_expectedresults.3=%WINE_CURDIR%\baz\bazbaz 1399set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbaz 1400set WINE_expectedresults.5=%WINE_CURDIR%\baz\bazbaz 1401set WINE_expectedresults.6=%WINE_CURDIR%\baz\fred 1402set WINE_expectedresults.7=%WINE_CURDIR%\bazbaz 1403set WINE_expectedresults.8=%WINE_CURDIR%\bazbaz 1404set WINE_expectedresults.9=%WINE_CURDIR%\bazbaz 1405set WINE_expectedresults.10=%WINE_CURDIR%\foo\bazbaz 1406set WINE_expectedresults.11=%WINE_CURDIR%\foo\fred 1407set WINE_expectedresults.12=%WINE_CURDIR%\fred 1408call :SetExpected 1409for /R %%i in (baz* bazbaz fred ba*) do call temp.bat "%%i" 1410call :ValidateExpected 1411 1412echo Strip missing wildcards, keep unwildcarded names 1413set WINE_expectedresults=6 1414set WINE_expectedresults.1=%WINE_CURDIR%\bar\jim 1415set WINE_expectedresults.2=%WINE_CURDIR%\baz\bazbaz 1416set WINE_expectedresults.3=%WINE_CURDIR%\baz\jim 1417set WINE_expectedresults.4=%WINE_CURDIR%\bazbaz 1418set WINE_expectedresults.5=%WINE_CURDIR%\foo\jim 1419set WINE_expectedresults.6=%WINE_CURDIR%\jim 1420call :SetExpected 1421for /R %%i in (baz* fred* jim) do call temp.bat "%%i" 1422call :ValidateExpected 1423 1424echo for /R passed 1425echo --- Complex wildcards unix and windows slash 1426cd .. 1427echo Windows slashes, valid path 1428for %%f in (foobar\baz\bazbaz) do echo ASIS: %%f 1429for %%f in (foobar\baz\*) do echo WC : %%f 1430echo Windows slashes, invalid path 1431for %%f in (foobar\jim\bazbaz) do echo ASIS: %%f 1432for %%f in (foobar\jim\*) do echo WC : %%f 1433echo Unix slashes, valid path 1434for %%f in (foobar/baz/bazbaz) do echo ASIS: %%f 1435for %%f in (foobar/baz/*) do echo WC : %%f 1436echo Unix slashes, invalid path 1437for %%f in (foobar/jim/bazbaz) do echo ASIS: %%f 1438for %%f in (foobar/jim/*) do echo WC : %%f 1439echo Done 1440rd /s/Q foobar 1441echo --- for /L 1442rem 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 1443for /L %%i in (1,2,0) do echo %%i 1444for@tab@/L %%i in (1,2,0) do echo %%i 1445for /L %%i in (1,2,6) do echo %%i 1446for /l %%i in (1 ,2,6) do echo %%i 1447for /L %%i in (a,2,3) do echo %%i 1448for /L %%i in (1,2,-1) do echo %%i 1449for /L %%i in (-4,-1,-1) do echo %%i 1450for /L %%i in (1,-2,-2) do echo %%i 1451for /L %%i in (1,2,a) do echo %%i 1452echo ErrorLevel %ErrorLevel% 1453for /L %%i in (1,a,b) do echo %%i 1454echo ErrorLevel %ErrorLevel% 1455rem Test boundaries 1456for /l %%i in (1,1,4) do echo %%i 1457for /l %%i in (1,2,4) do echo %%i 1458for /l %%i in (4,-1,1) do echo %%i 1459for /l %%i in (4,-2,1) do echo %%i 1460for /l %%i in (1,-1,4) do echo %%i 1461for /l %%i in (4,1,1) do echo %%i 1462for /L %%i in (a,2,b) do echo %%i 1463for /L %%i in (1,1,1) do echo %%i 1464for /L %%i in (1,-2,-1) do echo %%i 1465for /L %%i in (-1,-1,-1) do echo %%i 1466for /L %%i in (1,2, 3) do echo %%i 1467rem Test zero iteration skips the body of the for 1468for /L %%i in (2,2,1) do ( 1469 echo %%i 1470 echo FAILED 1471) 1472echo --- rems inside for loops 1473for /f %%i IN ("hello") DO ( 1474 REM foo|echo ERROR unexpected execution 1 1475 @REM foo|echo ERROR unexpected execution 2 1476 @ REM foo|echo ERROR unexpected execution 3 1477) 1478echo --- ifs inside for loops 1479for %%i in (test) do ( 1480 echo a1 1481 if 1==1 ( 1482 echo b1 1483 ) else ( 1484 echo c1 1485 ) 1486 echo d1 1487) 1488for %%i in (test) do ( 1489 echo a2 1490 if 1==1 ( 1491 echo b2 1492 ) else echo c2 1493 echo d2 1494) 1495for %%i in (test) do ( 1496 echo a3 1497 if 1==0 ( 1498 echo b3 1499 ) else echo c3 1500 echo d3 1501) 1502for %%i in (test) do ( 1503 echo a4 1504 if 1==0 ( 1505 echo b4 1506 ) else ( 1507 echo c4 1508 ) 1509 echo d4 1510) 1511echo --- set /a 1512goto :testseta 1513 1514Rem Ideally for /f can be used rather than building a command to execute 1515rem but that does not work on NT4 1516:checkenvvars 1517if "%1"=="" goto :eof 1518call :executecmd set wine_result=%%%1%% 1519if "%wine_result%"=="%2" ( 1520 echo %1 correctly %2 1521) else echo ERROR: %1 incorrectly %wine_result% [%2] 1522set %1= 1523shift 1524shift 1525rem shift 1526goto :checkenvvars 1527:executecmd 1528%* 1529goto :eof 1530 1531:testseta 1532rem No output when using "set expr" syntax, unless in interactive mode 1533rem Need to use "set envvar=expr" to use in a batch script 1534echo ------ individual operations 1535set WINE_foo=0 1536set /a WINE_foo=1 +2 & call :checkenvvars WINE_foo 3 1537set /a WINE_foo=1 +-2 & call :checkenvvars WINE_foo -1 1538set /a WINE_foo=1 --2 & call :checkenvvars WINE_foo 3 1539set /a WINE_foo=2* 3 & call :checkenvvars WINE_foo 6 1540set /a WINE_foo=-2* -5 & call :checkenvvars WINE_foo 10 1541set /a WINE_foo=12/3 & call :checkenvvars WINE_foo 4 1542set /a WINE_foo=13/3 & call :checkenvvars WINE_foo 4 1543set /a WINE_foo=-13/3 & call :checkenvvars WINE_foo -4 1544rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure 1545set /a WINE_foo=5 %% 5 & call :checkenvvars WINE_foo 0 1546set /a WINE_foo=5 %% 3 & call :checkenvvars WINE_foo 2 1547set /a WINE_foo=5 %% -3 & call :checkenvvars WINE_foo 2 1548set /a WINE_foo=-5 %% -3 & call :checkenvvars WINE_foo -2 1549set /a WINE_foo=1 ^<^< 0 & call :checkenvvars WINE_foo 1 1550set /a WINE_foo=1 ^<^< 2 & call :checkenvvars WINE_foo 4 1551set /a WINE_foo=1 ^<^< -2 & call :checkenvvars WINE_foo 0 1552set /a WINE_foo=-1 ^<^< -2 & call :checkenvvars WINE_foo 0 1553set /a WINE_foo=-1 ^<^< 2 & call :checkenvvars WINE_foo -4 1554set /a WINE_foo=9 ^>^> 0 & call :checkenvvars WINE_foo 9 1555set /a WINE_foo=9 ^>^> 2 & call :checkenvvars WINE_foo 2 1556set /a WINE_foo=9 ^>^> -2 & call :checkenvvars WINE_foo 0 1557set /a WINE_foo=-9 ^>^> -2 & call :checkenvvars WINE_foo -1 1558set /a WINE_foo=-9 ^>^> 2 & call :checkenvvars WINE_foo -3 1559set /a WINE_foo=5 ^& 0 & call :checkenvvars WINE_foo 0 1560set /a WINE_foo=5 ^& 1 & call :checkenvvars WINE_foo 1 1561set /a WINE_foo=5 ^& 3 & call :checkenvvars WINE_foo 1 1562set /a WINE_foo=5 ^& 4 & call :checkenvvars WINE_foo 4 1563set /a WINE_foo=5 ^& 1 & call :checkenvvars WINE_foo 1 1564set /a WINE_foo=5 ^| 0 & call :checkenvvars WINE_foo 5 1565set /a WINE_foo=5 ^| 1 & call :checkenvvars WINE_foo 5 1566set /a WINE_foo=5 ^| 3 & call :checkenvvars WINE_foo 7 1567set /a WINE_foo=5 ^| 4 & call :checkenvvars WINE_foo 5 1568set /a WINE_foo=5 ^| 1 & call :checkenvvars WINE_foo 5 1569set /a WINE_foo=5 ^^ 0 & call :checkenvvars WINE_foo 5 1570set /a WINE_foo=5 ^^ 1 & call :checkenvvars WINE_foo 4 1571set /a WINE_foo=5 ^^ 3 & call :checkenvvars WINE_foo 6 1572set /a WINE_foo=5 ^^ 4 & call :checkenvvars WINE_foo 1 1573set /a WINE_foo=5 ^^ 1 & call :checkenvvars WINE_foo 4 1574echo ------ precedence and grouping 1575set /a WINE_foo=4 + 2*3 & call :checkenvvars WINE_foo 10 1576set /a WINE_foo=(4+2)*3 & call :checkenvvars WINE_foo 18 1577set /a WINE_foo=4 * 3/5 & call :checkenvvars WINE_foo 2 1578set /a WINE_foo=(4 * 3)/5 & call :checkenvvars WINE_foo 2 1579set /a WINE_foo=4 * 5 %% 4 & call :checkenvvars WINE_foo 0 1580set /a WINE_foo=4 * (5 %% 4) & call :checkenvvars WINE_foo 4 1581set /a WINE_foo=3 %% (5 + 8 %% 3 ^^ 2) & call :checkenvvars WINE_foo 3 1582set /a WINE_foo=3 %% (5 + 8 %% 3 ^^ -2) & call :checkenvvars WINE_foo 3 1583echo ------ octal and hexadecimal 1584set /a WINE_foo=0xf + 3 & call :checkenvvars WINE_foo 18 1585set /a WINE_foo=0xF + 3 & call :checkenvvars WINE_foo 18 1586set /a WINE_foo=015 + 2 & call :checkenvvars WINE_foo 15 1587set /a WINE_foo=3, 8+3,0 & call :checkenvvars WINE_foo 3 1588echo ------ variables 1589set /a WINE_foo=WINE_bar=3, WINE_bar+1 & call :checkenvvars WINE_foo 3 WINE_bar 3 1590set /a WINE_foo=WINE_bar=3, WINE_bar+=1 & call :checkenvvars WINE_foo 3 WINE_bar 4 1591set /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 1592set WINE_bar=3 1593set /a WINE_foo=WINE_bar*= WINE_bar & call :checkenvvars WINE_foo 9 WINE_bar 9 1594set /a WINE_foo=WINE_whateverNonExistingVar & call :checkenvvars WINE_foo 0 1595set WINE_bar=4 1596set /a WINE_foo=WINE_whateverNonExistingVar + WINE_bar & call :checkenvvars WINE_foo 4 WINE_bar 4 1597set WINE_bar=4 1598set /a WINE_foo=WINE_bar -= WINE_bar + 7 & call :checkenvvars WINE_foo -7 WINE_bar -7 1599set WINE_bar=-7 1600set /a WINE_foo=WINE_bar /= 3 + 2 & call :checkenvvars WINE_foo -1 WINE_bar -1 1601set /a WINE_foo=WINE_bar=5, WINE_bar %%=2 & call :checkenvvars WINE_foo 5 WINE_bar 1 1602set WINE_bar=1 1603set /a WINE_foo=WINE_bar ^<^<= 2 & call :checkenvvars WINE_foo 4 WINE_bar 4 1604set WINE_bar=4 1605set /a WINE_foo=WINE_bar ^>^>= 2 & call :checkenvvars WINE_foo 1 WINE_bar 1 1606set WINE_bar=1 1607set /a WINE_foo=WINE_bar ^&= 2 & call :checkenvvars WINE_foo 0 WINE_bar 0 1608set /a WINE_foo=WINE_bar=5, WINE_bar ^|= 2 & call :checkenvvars WINE_foo 5 WINE_bar 7 1609set /a WINE_foo=WINE_bar=5, WINE_bar ^^= 2 & call :checkenvvars WINE_foo 5 WINE_bar 7 1610set WINE_baz=4 1611set /a WINE_foo=WINE_bar=19, WINE_bar %%= 4 + (WINE_baz %%= 7) & call :checkenvvars WINE_foo 19 WINE_bar 3 WINE_baz 4 1612echo --- quotes 1613set /a WINE_foo=1 1614call :checkenvvars WINE_foo 1 1615set /a "WINE_foo=1" 1616call :checkenvvars WINE_foo 1 1617set /a WINE_foo=1,WINE_bar=2 1618call :checkenvvars WINE_foo 1 WINE_bar 2 1619set /a "WINE_foo=1,WINE_bar=2" 1620call :checkenvvars WINE_foo 1 WINE_bar 2 1621set /a "WINE_foo=1","WINE_bar=2" 1622call :checkenvvars WINE_foo 1 WINE_bar 2 1623set /a ""WINE_foo=1","WINE_bar=2"" 1624call :checkenvvars WINE_foo 1 WINE_bar 2 1625set /a WINE_foo=1,WINE_bar=2,WINE_baz=3 1626call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1627set /a "WINE_foo=1,WINE_bar=2,WINE_baz=3" 1628call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1629set /a "WINE_foo=1","WINE_bar=2","WINE_baz=3" 1630call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1631set /a ""WINE_foo=1","WINE_bar=2","WINE_baz=3"" 1632call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1633set /a ""WINE_foo=1","WINE_bar=2"","WINE_baz=3" 1634call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3 1635set /a """"""WINE_foo=1"""""" 1636call :checkenvvars WINE_foo 1 1637set /a """"""WINE_foo=1","WINE_bar=5""","WINE_baz=2"" 1638call :checkenvvars WINE_foo 1 WINE_bar 5 WINE_baz 2 1639set /a WINE_foo="3"+"4"+"5+6" 1640call :checkenvvars WINE_foo 18 1641set WINE_foo=3 1642set /a WINE_bar="WINE_""foo"+4 1643call :checkenvvars WINE_foo 3 WINE_bar 7 1644echo --- whitespace are ignored between double char operators 1645set WINE_foo=4 1646set WINE_bar=5 1647set /a WINE_foo + = 6 1648set /a WINE_bar * = WINE_foo 1649call :checkenvvars WINE_foo 10 WINE_bar 50 1650set WINE_foo=4 1651set WINE_bar=5 1652set /a WINE_foo + = "6 < < 7" 1653set /a WINE_bar * = WINE_foo + WINE_foo 1654call :checkenvvars WINE_foo 772 WINE_bar 7720 1655set /a WINE_foo=6 7 1656set /a WINE_ var1=8 1657set WINE_foo= 1658echo --- invalid operator sequence 1659set WINE_foo=4 1660set /a =4 1661set /a *=4 1662set /a ^>=4" 1663set /a ^<=4" 1664set /a WINE_foo^>^<=4 1665echo %WINE_foo% 1666set /a WINE_foo^>^>^>=4 1667echo %WINE_foo% 1668echo ----- negative prefix 1669set /a WINE_foo=-1 1670call :checkenvvars WINE_foo -1 1671set /a WINE_foo=--1 1672call :checkenvvars WINE_foo 1 1673set /a WINE_foo=3--3 1674call :checkenvvars WINE_foo 6 1675set /a WINE_foo=3---3 1676call :checkenvvars WINE_foo 0 1677set /a WINE_foo=3----3 1678call :checkenvvars WINE_foo 6 1679set /a WINE_foo=-~1 1680call :checkenvvars WINE_foo 2 1681set /a WINE_foo=~-1 1682call :checkenvvars WINE_foo 0 1683set /a WINE_foo=3+-~1 1684call :checkenvvars WINE_foo 5 1685set /a WINE_foo=3+~-1 1686call :checkenvvars WINE_foo 3 1687echo ----- assignment tests involving the end destination 1688set WINE_foo=3 1689set /a WINE_foo+=3+(WINE_foo=4) 1690call :checkenvvars WINE_foo 11 1691set WINE_foo=2 1692set /a WINE_bar=3+(WINE_foo=6) 1693call :checkenvvars WINE_foo 6 WINE_bar 9 1694set WINE_foo=2 1695set /a WINE_bar=3+(WINE_foo=6,WINE_baz=7) 1696call :checkenvvars WINE_foo 6 WINE_bar 10 WINE_baz 7 1697set WINE_foo=2 1698set /a WINE_bar=WINE_foo=7 1699call :checkenvvars WINE_foo 7 WINE_bar 7 1700echo ----- equal precedence on stack 1701rem Unary - don't reduce if precedence is equal 1702set /a WINE_foo=!!1 1703call :checkenvvars WINE_foo 1 1704set /a WINE_foo=!!0 1705call :checkenvvars WINE_foo 0 1706set /a WINE_foo=~~1 1707call :checkenvvars WINE_foo 1 1708set /a WINE_foo=~~0 1709call :checkenvvars WINE_foo 0 1710set /a WINE_foo=--1 1711call :checkenvvars WINE_foo 1 1712set /a WINE_foo=+-1 1713call :checkenvvars WINE_foo -1 1714set /a WINE_foo=-+1 1715call :checkenvvars WINE_foo -1 1716set /a WINE_foo=++1 1717call :checkenvvars WINE_foo 1 1718set /a WINE_foo=!~1 1719call :checkenvvars WINE_foo 0 1720set /a WINE_foo=~!1 1721call :checkenvvars WINE_foo -1 1722set /a WINE_foo=!-1 1723call :checkenvvars WINE_foo 0 1724set /a WINE_foo=-!1 1725call :checkenvvars WINE_foo 0 1726set /a WINE_foo=!-0 1727call :checkenvvars WINE_foo 1 1728set /a WINE_foo=-!0 1729call :checkenvvars WINE_foo -1 1730rem Aritmatic - Reduce if precedence is equal 1731set /a WINE_foo=10*5/2 1732call :checkenvvars WINE_foo 25 1733set /a WINE_foo=5/2*10 1734call :checkenvvars WINE_foo 20 1735set /a WINE_foo=10/5/2 1736call :checkenvvars WINE_foo 1 1737set /a WINE_foo=5%%2*4 1738call :checkenvvars WINE_foo 4 1739set /a WINE_foo=10-5+2 1740call :checkenvvars WINE_foo 7 1741set /a WINE_foo=1^<^<4^>^>1 1742call :checkenvvars WINE_foo 8 1743rem Assignment - don't reduce if precedence is equal 1744set /a WINE_foo=5 1745set /a WINE_bar=WINE_foo=6 1746call :checkenvvars WINE_foo 6 WINE_bar 6 1747 1748echo --- for /F 1749mkdir foobar & cd foobar 1750echo ------ string argument 1751rem NT4 does not support usebackq 1752for /F %%i in ("a b c") do echo %%i 1753for /F %%i in ( "a b c" ) do echo X%%iX 1754for /f usebackq %%i in ('a b c') do echo %%i>output_file 1755if not exist output_file (echo no output) else (type output_file & del output_file) 1756for /f usebackq %%i in ( 'a b c' ) do echo X%%iX>output_file 1757if not exist output_file (echo no output) else (type output_file & del output_file) 1758for /f %%i in ("a ") do echo %%i 1759for /f usebackq %%i in ('a ') do echo %%i>output_file 1760if not exist output_file (echo no output) else (type output_file & del output_file) 1761for /f %%i in ("a") do echo %%i 1762for /f usebackq %%i in ('a') do echo %%i>output_file 1763if not exist output_file (echo no output) else (type output_file & del output_file) 1764fOr /f %%i in (" a") do echo %%i 1765for /f usebackq %%i in (' a') do echo %%i>output_file 1766if not exist output_file (echo no output) else (type output_file & del output_file) 1767for /f %%i in (" a ") do echo %%i 1768for /f usebackq %%i in (' a ') do echo %%i>output_file 1769if not exist output_file (echo no output) else (type output_file & del output_file) 1770echo ------ fileset argument 1771echo --------- basic blank handling 1772echo a b c>foo 1773for /f %%i in (foo) do echo %%i 1774echo a >foo 1775for /f %%i in (foo) do echo %%i 1776echo a>foo 1777for /f %%i in (foo) do echo %%i 1778echo a>foo 1779for /f %%i in (foo) do echo %%i 1780echo a >foo 1781for /f %%i in (foo) do echo %%i 1782echo. > foo 1783for /f %%i in (foo) do echo %%i 1784echo. >> foo 1785echo b > foo 1786for /f %%i in (foo) do echo %%i 1787echo --------- multi-line with empty lines 1788echo a Z f> foo 1789echo. >> foo 1790echo.>> foo 1791echo b bC>> foo 1792echo c>> foo 1793echo. >> foo 1794for /f %%b in (foo) do echo %%b 1795echo --------- multiple files 1796echo q w > bar 1797echo.>> bar 1798echo kkk>>bar 1799for /f %%k in (foo bar) do echo %%k 1800for /f %%k in (bar foo) do echo %%k 1801echo ------ command argument 1802rem Not implemented on NT4, need to skip it as no way to get output otherwise 1803if "%CD%"=="" goto :SkipFORFcmdNT4 1804for /f %%i in ('echo.Passed1') do echo %%i 1805for /f "usebackq" %%i in (`echo.Passed2`) do echo %%i 1806for /f usebackq %%i in (`echo.Passed3`) do echo %%i 1807for /f "usebackq" %%i in (`"c:\windows\system32\cmd.exe" /C echo Passed4`) do echo %%i 1808for /f "usebackq" %%i in (`""c:\windows\system32\cmd.exe" /C echo Passed5"`) do echo %%i 1809for /f %%i in ( 'echo.Passed6' ) do echo %%i 1810for /f "usebackq" %%i in ( `echo.Passed7` ) do echo %%i 1811goto :ContinueFORF 1812:SkipFORFcmdNT4 1813for /l %%i in (1,1,7) do echo Missing functionality - Broken%%i 1814:ContinueFORF 1815rem FIXME: Rest not testable right now in wine: not implemented and would need 1816rem preliminary grep-like program implementation (e.g. like findstr or fc) even 1817rem for a simple todo_wine test 1818rem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supported 1819rem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supported 1820echo ------ eol option 1821if "%CD%"=="" goto :SkipFORFeolNT4 1822echo Line one>foo 1823echo and Line two>>foo 1824echo Line three>>foo 1825for /f "eol=L" %%i in (foo) do echo %%i 1826for /f "eol=a" %%i in (foo) do echo %%i 1827del foo 1828goto :ContinueFORFeol 1829:SkipFORFeolNT4 1830for /l %%i in (1,1,3) do echo Broken NT4 functionality%%i 1831:ContinueFORFeol 1832for /f "eol=@" %%i in (" ad") do echo %%i 1833for /f "eol=@" %%i in (" z@y") do echo %%i 1834for /f "eol=|" %%i in ("a|d") do echo %%i 1835for /f "eol=@" %%i in ("@y") do echo %%i > output_file 1836if not exist output_file (echo no output) else (del output_file) 1837for /f "eol==" %%i in ("=y") do echo %%i > output_file 1838if not exist output_file (echo no output) else (del output_file) 1839echo ------ delims option 1840for /f "delims=|" %%i in ("a|d") do echo %%i 1841for /f "delims=|" %%i in ("a |d") do echo %%i 1842for /f "delims=|" %%i in ("a d|") do echo %%i 1843for /f "delims=| " %%i in ("a d|") do echo %%i 1844for /f "delims==" %%i in ("C r=d|") do echo %%i 1845for /f "delims=" %%i in ("foo bar baz") do echo %%i 1846for /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fi 1847echo ------ skip option 1848echo a > foo 1849echo b >> foo 1850echo c >> foo 1851for /f "skip=2" %%i in (foo) do echo %%i 1852for /f "skip=3" %%i in (foo) do echo %%i > output_file 1853if not exist output_file (echo no output) else (del output_file) 1854for /f "skip=4" %%i in (foo) do echo %%i > output_file 1855if not exist output_file (echo no output) else (del output_file) 1856for /f "skip=02" %%i in (foo) do echo %%i 1857for /f "skip=0x2" %%i in (foo) do echo %%i 1858for /f "skip=1" %%i in ("skipme") do echo %%i > output_file 1859if not exist output_file (echo no output) else (del output_file) 1860echo ------ tokens= option 1861rem Basic 1862for /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 1863for /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 1864for /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 1865rem Show * means the rest 1866for /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 1867for /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 1868rem Show * means the rest (not tokenized and rebuilt) 1869for /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 1870rem Order is irrelevant 1871for /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 1872for /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 1873rem Duplicates are ignored 1874for /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 1875rem Large tokens are allowed 1876for /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 1877rem Show tokens blanked in advance regardless of uniqueness of requested tokens 1878for /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 1879for /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 1880rem Show No wrapping from z to A BUT wrapping sort of occurs Z to a occurs 1881for /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 1882for /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 1883rem Show negative ranges have no effect 1884for /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 1885for /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 1886rem Show duplicates stop * from working 1887for /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 1888for /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 1889for /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 1890for /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 1891rem Special case tokens=* or tokens=n,* 1892echo 3.14>testfile 1893FOR /F "tokens=*" %%A IN (testfile) DO @echo 1:%%A,%%B 1894FOR /F "tokens=1*" %%A IN (testfile) DO @echo 2:%%A,%%B 1895FOR /F "tokens=2*" %%A IN (testfile) DO @echo 3:%%A,%%B 1896FOR /F "tokens=1,* delims=." %%A IN (testfile) DO @echo 4:%%A,%%B 1897del testfile 1898cd .. 1899rd /s/q foobar 1900echo ------ parameter splitting 1901echo forFParameterSplittingFunc "myparam1=myvalue1 myparam2=myparam2" mytest> foo 1902for /f "tokens=1 delims=;" %%i in (foo) do (call :%%i) 1903del foo 1904for /f "tokens=1 delims=;" %%i in ("forFParameterSplittingFunc "myparam1^=myvalue1 myparam2^=myparam2" mytest") do (call :%%i) 1905goto :forFParameterSplittingEnd 1906:forFParameterSplittingFunc 1907echo %~0 %~1 %~2 %~3 %~4 %~5 1908goto :eof 1909:forFParameterSplittingEnd 1910echo 3.14>testfile 1911FOR /F "delims=. tokens=*" %%A IN (testfile) DO @echo 4:%%A,%%B 1912FOR /F "delims=. tokens=1*" %%A IN (testfile) DO @echo 5:%%A,%%B 1913FOR /F "delims=. tokens=2*" %%A IN (testfile) DO @echo 6:%%A,%%B 1914FOR /F "delims=. tokens=3*" %%A IN (testfile) DO @echo 7:%%A,%%B 1915del testfile 1916 1917echo ------------ Testing del ------------ 1918echo abc > file 1919echo deleting 'file' 1920del file 1921if errorlevel 0 ( 1922 echo errorlevel is 0, good 1923) else ( 1924 echo unexpected errorlevel, got %errorlevel% 1925) 1926if not exist file ( 1927 echo successfully deleted 'file' 1928) else ( 1929 echo error deleting 'file' 1930) 1931echo attempting to delete 'file', even though it is not present 1932del file 1933if errorlevel 0 ( 1934 echo errorlevel is 0, good 1935) else ( 1936 echo unexpected errorlevel, got %errorlevel% 1937) 1938 1939echo ------------ Testing del /a ------------ 1940del /f/q *.test > nul 1941echo r > r.test 1942attrib +r r.test 1943echo not-r > not-r.test 1944 1945if not exist not-r.test echo not-r.test not found before delete, bad 1946del /a:-r *.test 1947if not exist not-r.test echo not-r.test not found after delete, good 1948 1949if not exist r.test echo r.test not found before delete, bad 1950if exist r.test echo r.test found before delete, good 1951del /a:r *.test 1952if not exist r.test echo r.test not found after delete, good 1953if exist r.test echo r.test found after delete, bad 1954 1955echo ------------ Testing del /q ------------ 1956mkdir del_q_dir 1957cd del_q_dir 1958echo abc > file1 1959echo abc > file2.dat 1960rem If /q doesn't work, cmd will prompt and the test case should hang 1961del /q * > nul 1962for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a 1963for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a 1964cd .. 1965rmdir del_q_dir 1966 1967echo ------------ Testing del /s ------------ 1968mkdir "foo bar" 1969cd "foo bar" 1970mkdir "foo:" 1971echo hi > file1.dat 1972echo there > file2.dat 1973echo bub > file3.dat 1974echo bye > "file with spaces.dat" 1975cd .. 1976del /s file1.dat > nul 1977del file2.dat /s > nul 1978del "file3.dat" /s > nul 1979del "file with spaces.dat" /s > nul 1980cd "foo bar" 1981for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f 1982for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat 1983if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat" 1984if exist "file with spaces.dat" del "file with spaces.dat" 1985rmdir "foo:" 1986cd .. 1987rmdir "foo bar" 1988 1989echo ------------ Testing rename ------------ 1990mkdir foobar & cd foobar 1991echo --- ren and rename are synonymous 1992echo > foo 1993rename foo bar 1994if exist foo echo foo should be renamed! 1995if exist bar echo foo renamed to bar 1996ren bar foo 1997if exist bar echo bar should be renamed! 1998if exist foo echo bar renamed to foo 1999echo --- name collision 2000echo foo>foo 2001echo bar>bar 2002ren foo bar 2> nul 2003type foo 2004type bar 2005rem no-op 2006ren foo foo 2007mkdir baz 2008ren foo baz\abc 2009echo --- rename read-only files 2010echo > file1 2011attrib +r file1 2012ren file1 file2 2013if not exist file1 ( 2014 if exist file2 ( 2015 echo read-only file renamed 2016 ) 2017) else ( 2018 echo read-only file not renamed! 2019) 2020echo --- rename directories 2021mkdir rep1 2022ren rep1 rep2 2023if not exist rep1 ( 2024 if exist rep2 ( 2025 echo dir renamed 2026 ) 2027) 2028attrib +r rep2 2029ren rep2 rep1 2030if not exist rep2 ( 2031 if exist rep1 ( 2032 echo read-only dir renamed 2033 ) 2034) 2035echo --- rename in other directory 2036if not exist baz\abc ( 2037 echo rename impossible in other directory 2038 if exist foo echo original file still present 2039) else ( 2040 echo shouldn't rename in other directory! 2041 if not exist foo echo original file not present anymore 2042) 2043cd .. & rd /s/q foobar 2044 2045echo ------------ Testing move ------------ 2046mkdir foobar & cd foobar 2047echo --- file move 2048echo >foo 2049move foo bar > nul 2>&1 2050if not exist foo ( 2051 if exist bar ( 2052 echo file move succeeded 2053 ) 2054) 2055echo bar>bar 2056echo baz> baz 2057move /Y bar baz > nul 2>&1 2058if not exist bar ( 2059 if exist baz ( 2060 echo file move with overwrite succeeded 2061 ) 2062) else ( 2063 echo file overwrite impossible! 2064 del bar 2065) 2066type baz 2067 2068attrib +r baz 2069move baz bazro > nul 2>&1 2070if not exist baz ( 2071 if exist bazro ( 2072 echo read-only files are moveable 2073 move bazro baz > nul 2>&1 2074 ) 2075) else ( 2076 echo read-only file not moved! 2077) 2078attrib -r baz 2079mkdir rep 2080move baz rep > nul 2>&1 2081if not exist baz ( 2082 if exist rep\baz ( 2083 echo file moved in subdirectory 2084 ) 2085) 2086call :setError 0 2087move rep\baz . > nul 2>&1 2088move /Y baz baz > nul 2>&1 2089if errorlevel 1 ( 2090 echo moving a file to itself should be a no-op! 2091) else ( 2092 echo moving a file to itself is a no-op 2093) 2094echo ErrorLevel: %ErrorLevel% 2095call :setError 0 2096del baz 2097echo --- directory move 2098mkdir foo\bar 2099mkdir baz 2100echo baz2>baz\baz2 2101move baz foo\bar > nul 2>&1 2102if not exist baz ( 2103 if exist foo\bar\baz\baz2 ( 2104 echo simple directory move succeeded 2105 ) 2106) 2107call :setError 0 2108mkdir baz 2109move baz baz > nul 2>&1 2110echo moving a directory to itself gives error; errlevel %ErrorLevel% 2111echo ------ dir in dir move 2112rd /s/q foo 2113mkdir foo bar 2114echo foo2>foo\foo2 2115echo bar2>bar\bar2 2116move foo bar > nul 2>&1 2117if not exist foo ( 2118 if exist bar ( 2119 dir /b /ad bar 2120 dir /b /a-d bar 2121 dir /b bar\foo 2122 ) 2123) 2124cd .. & rd /s/q foobar 2125 2126echo ------------ Testing mkdir ------------ 2127call :setError 0 2128echo --- md and mkdir are synonymous 2129mkdir foobar 2130echo %ErrorLevel% 2131rmdir foobar 2132md foobar 2133echo %ErrorLevel% 2134rmdir foobar 2135echo --- creating an already existing directory/file must fail 2136mkdir foobar 2137md foobar 2138echo %ErrorLevel% 2139rmdir foobar 2140echo > foobar 2141mkdir foobar 2142echo %ErrorLevel% 2143del foobar 2144echo --- multilevel path creation 2145mkdir foo 2146echo %ErrorLevel% 2147mkdir foo\bar\baz 2148echo %ErrorLevel% 2149cd foo 2150echo %ErrorLevel% 2151cd bar 2152echo %ErrorLevel% 2153cd baz 2154echo %ErrorLevel% 2155echo > ..\..\bar2 2156mkdir ..\..\..\foo\bar2 2157echo %ErrorLevel% 2158del ..\..\bar2 2159mkdir ..\..\..\foo\bar2 2160echo %ErrorLevel% 2161rmdir ..\..\..\foo\bar2 2162cd .. 2163rmdir baz 2164cd .. 2165rmdir bar 2166cd .. 2167rmdir foo 2168echo %ErrorLevel% 2169echo --- trailing backslashes 2170mkdir foo\\\\ 2171echo %ErrorLevel% 2172if exist foo (rmdir foo & echo dir created 2173) else ( echo dir not created ) 2174echo %ErrorLevel% 2175echo --- invalid chars 2176mkdir ? 2177echo mkdir ? gives errorlevel %ErrorLevel% 2178call :setError 0 2179mkdir ?\foo 2180echo mkdir ?\foo gives errorlevel %ErrorLevel% 2181call :setError 0 2182mkdir foo\? 2183echo mkdir foo\? gives errorlevel %ErrorLevel% 2184if exist foo (rmdir foo & echo ok, foo created 2185) else ( echo foo not created ) 2186call :setError 0 2187mkdir foo\bar\? 2188echo mkdir foo\bar\? gives errorlevel %ErrorLevel% 2189call :setError 0 2190if not exist foo ( 2191 echo bad, foo not created 2192) else ( 2193 cd foo 2194 if exist bar ( 2195 echo ok, foo\bar created 2196 rmdir bar 2197 ) 2198 cd .. 2199 rmdir foo 2200) 2201echo --- multiple directories at once 2202mkdir foobaz & cd foobaz 2203mkdir foo bar\baz foobar "bazbaz" .\"zabzab" 2204if exist foo (echo foo created) else echo foo not created! 2205if exist bar (echo bar created) else echo bar not created! 2206if exist foobar (echo foobar created) else echo foobar not created! 2207if exist bar\baz (echo bar\baz created) else echo bar\baz not created! 2208if exist bazbaz (echo bazbaz created) else echo bazbaz not created! 2209if exist zabzab (echo zabzab created) else echo zabzab not created! 2210cd .. & rd /s/q foobaz 2211call :setError 0 2212mkdir foo\* 2213echo mkdir foo\* errorlevel %ErrorLevel% 2214if exist foo (rmdir foo & echo ok, foo created 2215) else ( echo bad, foo not created ) 2216 2217echo ------------ Testing rmdir ------------ 2218call :setError 0 2219rem rd and rmdir are synonymous 2220mkdir foobar 2221rmdir foobar 2222echo %ErrorLevel% 2223if not exist foobar echo dir removed 2224mkdir foobar 2225rd foobar 2226echo %ErrorLevel% 2227if not exist foobar echo dir removed 2228rem Removing nonexistent directory 2229rmdir foobar 2230echo %ErrorLevel% 2231rem Removing single-level directories 2232echo > foo 2233rmdir foo 2234echo %ErrorLevel% 2235if exist foo echo file not removed 2236del foo 2237mkdir foo 2238echo > foo\bar 2239rmdir foo 2240echo %ErrorLevel% 2241if exist foo echo non-empty dir not removed 2242del foo\bar 2243mkdir foo\bar 2244rmdir foo 2245echo %ErrorLevel% 2246if exist foo echo non-empty dir not removed 2247rmdir foo\bar 2248rmdir foo 2249rem Recursive rmdir 2250mkdir foo\bar\baz 2251rmdir /s /Q foo 2252if not exist foo ( 2253 echo recursive rmdir succeeded 2254) else ( 2255 rd foo\bar\baz 2256 rd foo\bar 2257 rd foo 2258) 2259mkdir foo\bar\baz 2260echo foo > foo\bar\brol 2261rmdir /s /Q foo 2>&1 2262if not exist foo ( 2263 echo recursive rmdir succeeded 2264) else ( 2265 rd foo\bar\baz 2266 del foo\bar\brol 2267 rd foo\bar 2268 rd foo 2269) 2270rem multiples directories at once 2271mkdir foobaz & cd foobaz 2272mkdir foo 2273mkdir bar\baz 2274mkdir foobar 2275rd /s/q foo bar foobar 2276if not exist foo (echo foo removed) else echo foo not removed! 2277if not exist bar (echo bar removed) else echo bar not removed! 2278if not exist foobar (echo foobar removed) else echo foobar not removed! 2279if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed! 2280cd .. & rd /s/q foobaz 2281 2282echo ------------ Testing pushd/popd ------------ 2283cd 2284echo --- popd is no-op when dir stack is empty 2285popd 2286cd 2287echo --- pushing non-existing dir 2288pushd foobar 2289cd 2290echo --- basic behaviour 2291mkdir foobar\baz 2292pushd foobar 2293cd 2294popd 2295cd 2296pushd foobar 2297pushd baz 2298cd 2299popd 2300cd 2301pushd baz 2302popd 2303cd 2304popd 2305cd 2306pushd . 2307cd foobar\baz 2308pushd .. 2309cd 2310popd 2311popd 2312cd 2313rd /s/q foobar 2314 2315echo ------------ Testing attrib ------------ 2316rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modifications 2317mkdir foobar & cd foobar 2318echo foo original contents> foo 2319attrib foo 2320echo > bar 2321echo --- read-only attribute 2322rem Read-only files cannot be altered or deleted, unless forced 2323attrib +R foo 2324attrib foo 2325dir /Ar /B 2326echo bar>> foo 2327type foo 2328del foo > NUL 2>&1 2329if exist foo ( 2330 echo Read-only file not deleted 2331) else ( 2332 echo Should not delete read-only file! 2333) 2334del /F foo 2335if not exist foo ( 2336 echo Read-only file forcibly deleted 2337) else ( 2338 echo Should delete read-only file with del /F! 2339 attrib -r foo 2340 del foo 2341) 2342cd .. & rd /s/q foobar 2343echo --- recursive behaviour 2344mkdir foobar\baz & cd foobar 2345echo > level1 2346echo > whatever 2347echo > baz\level2 2348attrib baz\level2 2349cd .. 2350attrib +R l*vel? /S > nul 2>&1 2351cd foobar 2352attrib level1 2353attrib baz\level2 2354echo > bar 2355attrib bar 2356cd .. & rd /s/q foobar 2357echo --- folders processing 2358mkdir foobar 2359attrib foobar 2360cd foobar 2361mkdir baz 2362echo toto> baz\toto 2363attrib +r baz /s /d > nul 2>&1 2364attrib baz 2365attrib baz\toto 2366echo lulu>>baz\toto 2367type baz\toto 2368echo > baz\lala 2369rem Oddly windows allows file creation in a read-only directory... 2370if exist baz\lala (echo file created in read-only dir) else echo file not created 2371cd .. & rd /s/q foobar 2372 2373echo ------------ Testing assoc ------------ 2374rem Modifying associations requires some privileges... 2375net session >nul 2>&1 2376if errorlevel 1 goto :SkipAssoc 2377 2378rem FIXME Can't test error messages in the current test system, so we have to use some kludges 2379rem FIXME Revise once || conditional execution is fixed 2380mkdir foobar & cd foobar 2381echo --- setting association 2382assoc .foo > baz 2383type baz 2384echo --- 2385 2386assoc .foo=bar 2387assoc .foo 2388 2389rem association set system-wide 2390echo @echo off> tmp.cmd 2391echo echo +++>> tmp.cmd 2392echo assoc .foo>> tmp.cmd 2393cmd /c tmp.cmd 2394 2395echo --- resetting association 2396assoc .foo= 2397assoc .foo > baz 2398type baz 2399echo --- 2400 2401rem association removal set system-wide 2402cmd /c tmp.cmd > baz 2403type baz 2404echo --- 2405cd .. & rd /s/q foobar 2406goto ContinueFType 2407:SkipAssoc 2408echo --- setting association 2409echo --- 2410echo .foo=bar 2411echo .foo=bar 2412echo +++ 2413echo .foo=bar 2414echo --- resetting association 2415echo --- 2416echo +++ 2417echo --- 2418 2419 2420:ContinueFType 2421echo ------------ Testing ftype ------------ 2422rem Modifying associations requires some privileges... 2423net session >nul 2>&1 2424if errorlevel 1 goto :SkipFType 2425rem FIXME Can't test error messages in the current test system, so we have to use some kludges 2426rem FIXME Revise once || conditional execution is fixed 2427mkdir foobar & cd foobar 2428echo --- setting association 2429ftype footype> baz 2430type baz 2431echo --- 2432 2433ftype footype=foo_opencmd 2434assoc .foo=footype 2435ftype footype 2436 2437rem association set system-wide 2438echo @echo off> tmp.cmd 2439echo echo +++>> tmp.cmd 2440echo ftype footype>> tmp.cmd 2441cmd /c tmp.cmd 2442 2443echo --- resetting association 2444assoc .foo= 2445 2446rem Removing a file type association doesn't work on XP due to a bug, so a workaround is needed 2447setlocal EnableDelayedExpansion 2448set WINE_FOO=original value 2449ftype footype= 2450ftype footype > baz 2451for /F %%i in ('type baz') do (set WINE_FOO=buggyXP) 2452rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion) 2453rem FIXME Revisit once a grep-like program like ftype is implemented 2454rem (e.g. to check baz's size using dir /b instead) 2455echo !WINE_FOO! 2456 2457rem cleanup registry 2458echo REGEDIT4> regCleanup.reg 2459echo.>> regCleanup.reg 2460echo [-HKEY_CLASSES_ROOT\footype]>> regCleanup.reg 2461regedit /s regCleanup.reg 2462set WINE_FOO= 2463endlocal 2464cd .. & rd /s/q foobar 2465goto ContinueCall 2466:SkipFType 2467echo --- setting association 2468echo --- 2469echo footype=foo_opencmd 2470echo .foo=footype 2471echo footype=foo_opencmd 2472echo +++ 2473echo footype=foo_opencmd 2474echo --- resetting association 2475echo original value 2476 2477:ContinueCall 2478echo ------------ Testing CALL ------------ 2479mkdir foobar & cd foobar 2480echo --- external script 2481echo echo foo %%1> foo.cmd 2482call foo 2483call foo.cmd 8 2484echo echo %%1 %%2 > foo.cmd 2485call foo.cmd foo 2486call foo.cmd foo bar 2487call foo.cmd foo "" 2488call foo.cmd "" bar 2489call foo.cmd foo '' 2490call foo.cmd '' bar 2491del foo.cmd 2492 2493echo --- internal routines 2494call :testRoutine :testRoutine 2495goto :endTestRoutine 2496:testRoutine 2497echo bar %1 2498goto :eof 2499:endTestRoutine 2500 2501call :testRoutineArgs foo 2502call :testRoutineArgs foo bar 2503call :testRoutineArgs foo "" 2504call :testRoutineArgs "" bar 2505call :testRoutineArgs foo '' 2506call :testRoutineArgs '' bar 2507goto :endTestRoutineArgs 2508:testRoutineArgs 2509echo %1 %2 2510goto :eof 2511:endTestRoutineArgs 2512 2513echo --- with builtins 2514call mkdir foo 2515echo %ErrorLevel% 2516if exist foo (echo foo created) else echo foo should exist! 2517rmdir foo 2518set WINE_FOOBAZ_VAR=foobaz 2519call echo Should expand %WINE_FOOBAZ_VAR% 2520set WINE_FOOBAZ_VAR= 2521echo>batfile 2522call dir /b 2523echo>robinfile 2524if 1==1 call del batfile 2525dir /b 2526if exist batfile echo batfile shouldn't exist 2527rem ... but not for 'if' or 'for' 2528call if 1==1 echo bar 2> nul 2529echo %ErrorLevel% 2530call :setError 0 2531call for %%i in (foo bar baz) do echo %%i 2> nul 2532echo %ErrorLevel% 2533rem First look for programs in the path before trying a builtin 2534echo echo non-builtin dir> dir.cmd 2535call dir /b 2536del dir.cmd 2537rem The below line equates to call (, which does nothing, then the 2538rem subsequent lines are executed. 2539call ( 2540 echo Line one 2541 echo Line two 2542) 2543rem The below line equates to call if, which always fails, then the 2544rem subsequent lines are executed. Note cmd.exe swallows all lines 2545rem starting with ) 2546call if 1==1 ( 2547 echo Get if 2548) else ( 2549 echo ... and else! 2550) 2551call call call echo passed 2552cd .. & rd /s/q foobar 2553 2554echo ------------ Testing SHIFT ------------ 2555 2556call :shiftFun p1 p2 p3 p4 p5 2557goto :endShiftFun 2558 2559:shiftFun 2560echo '%1' '%2' '%3' '%4' '%5' 2561shift 2562echo '%1' '%2' '%3' '%4' '%5' 2563shift@tab@ /1 2564echo '%1' '%2' '%3' '%4' '%5' 2565shift /2 2566echo '%1' '%2' '%3' '%4' '%5' 2567shift /-1 2568echo '%1' '%2' '%3' '%4' '%5' 2569shift /0 2570echo '%1' '%2' '%3' '%4' '%5' 2571goto :eof 2572:endShiftFun 2573 2574echo ------------ Testing cmd invocation ------------ 2575rem FIXME: only a stub ATM 2576echo --- a batch file can delete itself 2577echo del foo.cmd>foo.cmd 2578cmd /q /c foo.cmd 2579if not exist foo.cmd ( 2580 echo file correctly deleted 2581) else ( 2582 echo file should be deleted! 2583 del foo.cmd 2584) 2585echo --- a batch file can alter itself 2586echo echo bar^>foo.cmd>foo.cmd 2587cmd /q /c foo.cmd > NUL 2>&1 2588if exist foo.cmd ( 2589 type foo.cmd 2590 del foo.cmd 2591) else ( 2592 echo file not created! 2593) 2594 2595echo ---------- Testing copy 2596md foobar2 2597cd foobar2 2598rem Note echo adds 0x0d 0x0a on the end of the line in the file 2599echo AAA> file1 2600echo BBBBBB> file2 2601echo CCCCCCCCC> file3 2602md dir1 2603goto :testcopy 2604 2605:CheckExist 2606if exist "%1" ( 2607 echo Passed: Found expected %1 2608) else ( 2609 echo Failed: Did not find expected %1 2610) 2611del /q "%1" >nul 2>&1 2612shift 2613if not "%1"=="" goto :CheckExist 2614goto :eof 2615 2616:CheckNotExist 2617if not exist "%1" ( 2618 echo Passed: Did not find %1 2619) else ( 2620 echo Failed: Unexpectedly found %1 2621 del /q "%1" >nul 2>&1 2622) 2623shift 2624if not "%1"=="" goto :CheckNotExist 2625goto :eof 2626 2627rem Note: No way to check file size on NT4 so skip the test 2628:CheckFileSize 2629if not exist "%1" ( 2630 echo Failed: File missing when requested filesize check [%2] 2631 goto :ContinueFileSizeChecks 2632) 2633for %%i in (%1) do set WINE_filesize=%%~zi 2634if "%WINE_filesize%"=="%2" ( 2635 echo Passed: file size check on %1 [%WINE_filesize%] 2636) else ( 2637 if "%WINE_filesize%"=="%%~zi" ( 2638 echo Skipping file size check on NT4 2639 ) else ( 2640 echo Failed: file size check on %1 [%WINE_filesize% != %2] 2641 ) 2642) 2643:ContinueFileSizeChecks 2644shift 2645shift 2646if not "%1"=="" goto :CheckFileSize 2647goto :eof 2648 2649:testcopy 2650 2651rem ----------------------- 2652rem Simple single file copy 2653rem ----------------------- 2654rem Simple single file copy, normally used syntax 2655copy file1 dummy.file >nul 2>&1 2656if errorlevel 1 echo Incorrect errorlevel 2657call :CheckExist dummy.file 2658 2659rem Simple single file copy, destination supplied as two forms of directory 2660copy file1 dir1 >nul 2>&1 2661if errorlevel 1 echo Incorrect errorlevel 2662call :CheckExist dir1\file1 2663 2664copy file1 dir1\ >nul 2>&1 2665if errorlevel 1 echo Incorrect errorlevel 2666call :CheckExist dir1\file1 2667 2668rem Simple single file copy, destination supplied as fully qualified destination 2669copy file1 dir1\file99 >nul 2>&1 2670if errorlevel 1 echo Incorrect errorlevel 2671call :CheckExist dir1\file99 2672 2673rem Simple single file copy, destination not supplied 2674cd dir1 2675copy ..\file1 >nul 2>&1 2676if errorlevel 1 echo Incorrect errorlevel 2677call :CheckExist file1 2678cd .. 2679 2680rem Simple single file copy, destination supplied as nonexistent directory 2681copy file1 dir2\ >nul 2>&1 2682if not errorlevel 1 echo Incorrect errorlevel 2683call :CheckNotExist dir2 dir2\file1 2684 2685rem ----------------------- 2686rem Wildcarded copy 2687rem ----------------------- 2688rem Simple single file copy, destination supplied as two forms of directory 2689copy file? dir1 >nul 2>&1 2690if errorlevel 1 echo Incorrect errorlevel 2691call :CheckExist dir1\file1 dir1\file2 dir1\file3 2692 2693copy file* dir1\ >nul 2>&1 2694if errorlevel 1 echo Incorrect errorlevel 2695call :CheckExist dir1\file1 dir1\file2 dir1\file3 2696 2697rem Simple single file copy, destination not supplied 2698cd dir1 2699copy ..\file*.* >nul 2>&1 2700if errorlevel 1 echo Incorrect errorlevel 2701call :CheckExist file1 file2 file3 2702cd .. 2703 2704rem Simple wildcarded file copy, destination supplied as nonexistent directory 2705copy file? dir2\ >nul 2>&1 2706if not errorlevel 1 echo Incorrect errorlevel 2707call :CheckNotExist dir2 dir2\file1 dir2\file2 dir2\file3 2708 2709rem ------------------------------------------------ 2710rem Confirm overwrite works (cannot test prompting!) 2711rem ------------------------------------------------ 2712copy file1 testfile >nul 2>&1 2713copy /y file2 testfile >nul 2>&1 2714call :CheckExist testfile 2715 2716rem ------------------------------------------------ 2717rem Test concatenation 2718rem ------------------------------------------------ 2719rem simple case, no wildcards 2720copy file1+file2 testfile >nul 2>&1 2721if errorlevel 1 echo Incorrect errorlevel 2722call :CheckExist testfile 2723 2724rem simple case, wildcards, no concatenation 2725copy file* testfile >nul 2>&1 2726if errorlevel 1 echo Incorrect errorlevel 2727call :CheckExist testfile 2728 2729rem simple case, wildcards, and concatenation 2730echo ddddd > fred 2731copy file*+fred testfile >nul 2>&1 2732if errorlevel 1 echo Incorrect errorlevel 2733call :CheckExist testfile 2734 2735rem simple case, wildcards, and concatenation 2736copy fred+file* testfile >nul 2>&1 2737if errorlevel 1 echo Incorrect errorlevel 2738call :CheckExist testfile 2739 2740rem Calculate destination name 2741copy fred+file* dir1 >nul 2>&1 2742if errorlevel 1 echo Incorrect errorlevel 2743call :CheckExist dir1\fred 2744 2745rem Calculate destination name 2746copy fred+file* dir1\ >nul 2>&1 2747if errorlevel 1 echo Incorrect errorlevel 2748call :CheckExist dir1\fred 2749 2750rem Calculate destination name (none supplied) 2751cd dir1 2752copy ..\fred+..\file* >nul 2>&1 2753if errorlevel 1 echo Incorrect errorlevel 2754call :CheckExist fred 2755 2756copy ..\fr*+..\file1 >nul 2>&1 2757if errorlevel 1 echo Incorrect errorlevel 2758call :CheckExist fred 2759cd .. 2760 2761rem ****************************************************************** 2762rem ASCII and BINARY tests 2763rem Note: hard coded numbers deliberate because need to ensure whether 2764rem an additional EOF has been added or not. There is no way to handle 2765rem EOFs in batch, so assume if a single byte appears, it's an EOF! 2766rem ****************************************************************** 2767 2768rem Confirm original sizes of file1,2,3 2769call :CheckFileSize file1 5 file2 8 file3 11 2770 2771cd dir1 2772 2773rem ---------------------------------------------- 2774rem Show concatenation defaults copy to ascii mode 2775rem ---------------------------------------------- 2776rem Simple default copy source to destination (should not append EOF 5) 2777copy ..\file1 file1_default >nul 2>&1 2778call :CheckFileSize file1_default 5 2779 2780rem Simple binary copy source to destination (should not append EOF 5) 2781copy /b ..\file1 file1_default2 >nul 2>&1 2782call :CheckFileSize file1_default2 5 2783 2784rem Simple ascii copy source to destination (should append EOF 5+1, 8+1, 11+1) 2785copy /a ..\file1 file1_plus_eof >nul 2>&1 2786call :CheckFileSize file1_plus_eof 6 2787copy /a ..\file2 file2_plus_eof >nul 2>&1 2788call :CheckFileSize file2_plus_eof 9 2789copy /a ..\file3 file3_plus_eof >nul 2>&1 2790call :CheckFileSize file3_plus_eof 12 2791 2792rem Concat 2 files, ascii mode - (only one EOF on the end 5+8+1) 2793copy /a ..\file1+..\file2 file12_plus_eof >nul 2>&1 2794call :CheckFileSize file12_plus_eof 14 2795 2796rem Concat 2 files, binary mode - (no EOF on the end 5+8) 2797copy /b ..\file1+..\file2 file12_no_eof >nul 2>&1 2798call :CheckFileSize file12_no_eof 13 2799 2800rem Concat 2 files, default mode - (one EOF on the end 5+8+1) 2801copy ..\file1+..\file2 file12_eof2 >nul 2>&1 2802call :CheckFileSize file12_eof2 14 2803 2804rem Test copying when destination is one of the sources. 2805rem Concat file1+file2+file3 into file1, should produce file1+file2+file3 = 24 2806copy /y ..\file? .\ >nul 2>&1 2807copy /y /b file1+file2+file3 file1 >nul 2>&1 2808call :CheckFileSize file1 24 2809 2810rem Concat file1+file2+file3 into file2, should produce file1+file3 = 16 2811copy /y ..\file? .\ >nul 2>&1 2812copy /y /b file1+file2+file3 file2 >nul 2>&1 2813call :CheckFileSize file2 16 2814 2815rem Concat file1+file2+file3 into file3, should produce file1+file2 = 13 2816copy /y ..\file? .\ >nul 2>&1 2817copy /y /b file1+file2+file3 file3 >nul 2>&1 2818call :CheckFileSize file3 13 2819 2820rem -------------------------------------------------------------- 2821rem Show ascii source copy stops at first EOF, binary does the lot 2822rem -------------------------------------------------------------- 2823copy file1_plus_eof /b file1_binary_srccopy /b >nul 2>&1 2824call :CheckFileSize file1_binary_srccopy 6 2825 2826copy file1_plus_eof /a file1_ascii_srccopy /b >nul 2>&1 2827call :CheckFileSize file1_ascii_srccopy 5 2828 2829rem -------------------------------------------------------------- 2830rem Show results of concatenating files (ending in EOFs) and /a /b 2831rem -------------------------------------------------------------- 2832 2833rem Default and ascii copy reads as ascii, stripping EOFs, so 6-1 + 9-1 + 12-1 + 1 2834copy file1_plus_eof+file2_plus_eof+file3_plus_eof file123_default_copy >nul 2>&1 2835call :CheckFileSize file123_default_copy 25 2836copy /a file1_plus_eof+file2_plus_eof+file3_plus_eof file123_ascii_copy >nul 2>&1 2837call :CheckFileSize file123_ascii_copy 25 2838 2839rem In binary mode, we get 3 eofs, so 6 + 9 + 12 = 27 2840copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_binary_copy >nul 2>&1 2841call :CheckFileSize file123_binary_copy 27 2842 2843rem We can select which we want the eofs from by postfixing it with /a or /b 2844rem so here have first and third with eof, second as ascii 6 + 9-1 + 12 2845copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy1 >nul 2>&1 2846call :CheckFileSize file123_mixed_copy1 26 2847 2848rem By postfixing the destination with /a, we ask for an ascii destination which appends EOF 2849rem so here have first and third with eof, second as ascii 6 + 9-1 + 12 + extra EOF 2850rem Note the delta between this and the previous one also shows that the destination 2851rem ascii/binary is inherited from the last /a or /b on the line 2852copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy2 /a >nul 2>&1 2853call :CheckFileSize file123_mixed_copy2 27 2854 2855rem so here have second with eof, first and third as ascii 6-1 + 9 + 12-1 2856rem Note the delta between the next two also shows that the destination ascii/binary is 2857rem inherited from the last /a or /b on the line, so the first has an extra EOF 2858copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy3 >nul 2>&1 2859call :CheckFileSize file123_mixed_copy3 26 2860copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy4 /b >nul 2>&1 2861call :CheckFileSize file123_mixed_copy4 25 2862 2863rem ------------------------------------------------------------------------------------------- 2864rem This shows when concatenating, an ascii destination always adds on an EOF but when we 2865rem are not concatenating, it's a direct copy regardless of destination if being read as binary 2866rem ------------------------------------------------------------------------------------------- 2867 2868rem All 3 have eof's, plus an extra = 6 + 9 + 12 + eof 2869copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_mixed_copy5 /a >nul 2>&1 2870call :CheckFileSize file123_mixed_copy5 28 2871 2872rem All 2 have eof's, plus an extra = 6 + 12 + eof 2873copy /b file1_plus_eof + file3_plus_eof file123_mixed_copy6 /a >nul 2>&1 2874call :CheckFileSize file123_mixed_copy6 19 2875 2876rem One file has EOF, but doesn't get an extra one, i.e. 6 2877copy /b file1_plus_eof file123_mixed_copy7 /a >nul 2>&1 2878call :CheckFileSize file123_mixed_copy7 6 2879 2880rem Syntax means concatenate so ascii destination kicks in 2881copy /b file1_plus_eof* file123_mixed_copy8 /a >nul 2>&1 2882call :CheckFileSize file123_mixed_copy8 7 2883 2884del *.* /q 2885cd .. 2886 2887rem --------------------------------------- 2888rem Error combinations 2889rem --------------------------------------- 2890rem Specify source directory but name is a file 2891call :setError 0 2892copy file1\ dir1\ >NUL 2>&1 2893if errorlevel 1 echo Passed: errorlevel invalid check 1 2894if not errorlevel 1 echo Failed: errorlevel invalid check 1 2895call :CheckNotExist dir1\file1 2896 2897rem Overwrite same file 2898call :setError 0 2899copy file1 file1 >NUL 2>&1 2900if errorlevel 1 echo Passed: errorlevel invalid check 2 2901if not errorlevel 1 echo Failed: errorlevel invalid check 2 2902 2903rem Supply same file identified as a directory 2904call :setError 0 2905copy file1 file1\ >NUL 2>&1 2906if errorlevel 1 echo Passed: errorlevel invalid check 3 2907if not errorlevel 1 echo Failed: errorlevel invalid check 3 2908 2909cd .. 2910rd foobar2 /s /q 2911 2912echo ------------ Testing setlocal/endlocal ------------ 2913call :setError 0 2914rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test section 2915mkdir foobar & cd foobar 2916echo --- enable/disable extensions 2917setlocal DisableEXTensions 2918echo ErrLev: %ErrorLevel% 2919endlocal 2920echo ErrLev: %ErrorLevel% 2921echo @echo off> tmp.cmd 2922echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd 2923rem Enabled by default 2924cmd /C tmp.cmd 2925cmd /E:OfF /C tmp.cmd 2926cmd /e:oN /C tmp.cmd 2927 2928rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet) 2929echo --- setlocal with corresponding endlocal 2930rem %CD% does not work on NT4 so use the following workaround 2931for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi 2932echo @echo off> test.cmd 2933echo echo %%WINE_VAR%%>> test.cmd 2934echo setlocal>> test.cmd 2935echo set WINE_VAR=localval>> test.cmd 2936echo md foobar2>> test.cmd 2937echo cd foobar2>> test.cmd 2938echo echo %%WINE_VAR%%>> test.cmd 2939echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd 2940echo endlocal>> test.cmd 2941echo echo %%WINE_VAR%%>> test.cmd 2942echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd 2943set WINE_VAR=globalval 2944call test.cmd 2945echo %WINE_VAR% 2946for /d %%i in (.) do echo %%~dpnxi 2947cd /d %WINE_CURDIR% 2948rd foobar2 2949set WINE_VAR= 2950echo --- setlocal with no corresponding endlocal 2951echo @echo off> test.cmd 2952echo echo %%WINE_VAR%%>> test.cmd 2953echo setlocal>> test.cmd 2954echo set WINE_VAR=localval>> test.cmd 2955echo md foobar2>> test.cmd 2956echo cd foobar2>> test.cmd 2957echo echo %%WINE_VAR%%>> test.cmd 2958echo for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmd 2959set WINE_VAR=globalval 2960rem %CD% does not work on NT4 so use the following workaround 2961for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi 2962call test.cmd 2963echo %WINE_VAR% 2964for /d %%i in (.) do echo %%~dpnxi 2965cd /d %WINE_CURDIR% 2966rd foobar2 2967set WINE_VAR= 2968echo --- setlocal within same batch program 2969set WINE_var1=one 2970set WINE_var2= 2971set WINE_var3= 2972rem %CD% does not work on NT4 so use the following workaround 2973for /d %%i in (.) do set WINE_CURDIR=%%~dpnxi 2974setlocal 2975set WINE_var2=two 2976mkdir foobar2 2977cd foobar2 2978setlocal 2979set WINE_var3=three 2980if "%WINE_var1%"=="one" echo Var1 ok 1 2981if "%WINE_var2%"=="two" echo Var2 ok 2 2982if "%WINE_var3%"=="three" echo Var3 ok 3 2983for /d %%i in (.) do set WINE_curdir2=%%~dpnxi 2984if "%WINE_curdir2%"=="%WINE_CURDIR%\foobar2" echo Directory is ok 1 2985endlocal 2986if "%WINE_var1%"=="one" echo Var1 ok 1 2987if "%WINE_var2%"=="two" echo Var2 ok 2 2988if "%WINE_var3%"=="" echo Var3 ok 3 2989for /d %%i in (.) do set WINE_curdir2=%%~dpnxi 2990if "%WINE_curdir2%"=="%WINE_CURDIR%\foobar2" echo Directory is ok 2 2991endlocal 2992if "%WINE_var1%"=="one" echo Var1 ok 1 2993if "%WINE_var2%"=="" echo Var2 ok 2 2994if "%WINE_var3%"=="" echo Var3 ok 3 2995for /d %%i in (.) do set WINE_curdir2=%%~dpnxi 2996if "%WINE_curdir2%"=="%WINE_CURDIR%" echo Directory is ok 3 2997rd foobar2 /s /q 2998set WINE_var1= 2999 3000echo --- Mismatched set and end locals 3001mkdir foodir2 2>nul 3002mkdir foodir3 2>nul 3003mkdir foodir4 2>nul 3004rem %CD% does not work on NT4 so use the following workaround 3005for /d %%i in (.) do set WINE_curdir=%%~dpnxi 3006 3007echo @echo off> 2set1end.cmd 3008echo echo %%WINE_var%%>> 2set1end.cmd 3009echo setlocal>> 2set1end.cmd 3010echo set WINE_VAR=2set1endvalue1>> 2set1end.cmd 3011echo cd ..\foodir3>> 2set1end.cmd 3012echo setlocal>> 2set1end.cmd 3013echo set WINE_VAR=2set1endvalue2>> 2set1end.cmd 3014echo cd ..\foodir4>> 2set1end.cmd 3015echo endlocal>> 2set1end.cmd 3016echo echo %%WINE_var%%>> 2set1end.cmd 3017echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 2set1end.cmd 3018 3019echo @echo off> 1set2end.cmd 3020echo echo %%WINE_var%%>> 1set2end.cmd 3021echo setlocal>> 1set2end.cmd 3022echo set WINE_VAR=1set2endvalue1>> 1set2end.cmd 3023echo cd ..\foodir3>> 1set2end.cmd 3024echo endlocal>> 1set2end.cmd 3025echo echo %%WINE_var%%>> 1set2end.cmd 3026echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd 3027echo endlocal>> 1set2end.cmd 3028echo echo %%WINE_var%%>> 1set2end.cmd 3029echo for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd 3030 3031echo --- Extra setlocal in called batch 3032set WINE_VAR=value1 3033rem -- setlocal1 == this batch, should never be used inside a called routine 3034setlocal 3035set WINE_var=value2 3036cd foodir2 3037call "%WINE_CURDIR%\2set1end.cmd" 3038echo Finished: 3039echo %WINE_VAR% 3040for /d %%i in (.) do echo %%~dpnxi 3041endlocal 3042echo %WINE_VAR% 3043for /d %%i in (.) do echo %%~dpnxi 3044cd /d %WINE_CURDIR% 3045 3046echo --- Extra endlocal in called batch 3047set WINE_VAR=value1 3048rem -- setlocal1 == this batch, should never be used inside a called routine 3049setlocal 3050set WINE_var=value2 3051cd foodir2 3052call "%WINE_CURDIR%\1set2end.cmd" 3053echo Finished: 3054echo %WINE_VAR% 3055for /d %%i in (.) do echo %%~dpnxi 3056endlocal 3057echo %WINE_VAR% 3058for /d %%i in (.) do echo %%~dpnxi 3059cd /d %WINE_CURDIR% 3060 3061echo --- endlocal in called function rather than batch pgm is ineffective 3062@echo off 3063set WINE_var=1 3064set WINE_var2=1 3065setlocal 3066set WINE_var=2 3067call :endlocalroutine 3068echo %WINE_var% 3069endlocal 3070echo %WINE_var% 3071goto :endlocalfinished 3072:endlocalroutine 3073echo %WINE_var% 3074endlocal 3075echo %WINE_var% 3076setlocal 3077set WINE_var2=2 3078endlocal 3079echo %WINE_var2% 3080endlocal 3081echo %WINE_var% 3082echo %WINE_var2% 3083goto :eof 3084:endlocalfinished 3085echo %WINE_var% 3086 3087set WINE_var= 3088set WINE_var2= 3089cd .. & rd /q/s foobar 3090 3091echo ------------ Testing Errorlevel ------------ 3092rem WARNING: Do *not* add tests using ErrorLevel after this section 3093should_not_exist 2> nul > nul 3094echo %ErrorLevel% 3095rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak 3096rem See http://www.robvanderwoude.com/exit.php 3097call :setError 1 3098echo %ErrorLevel% 3099if errorlevel 2 echo errorlevel too high, bad 3100if errorlevel 1 echo errorlevel just right, good 3101if errorlevel 01 echo errorlevel with leading zero just right, good 3102if errorlevel -1 echo errorlevel with negative number OK 3103if errorlevel 0x1 echo hexa should not be recognized! 3104if errorlevel 1a echo invalid error level recognized! 3105call :setError 0 3106echo abc%ErrorLevel%def 3107if errorlevel 1 echo errorlevel nonzero, bad 3108if not errorlevel 1 echo errorlevel zero, good 3109if not errorlevel 0x1 echo hexa should not be recognized! 3110if not errorlevel 1a echo invalid error level recognized! 3111rem Now verify that setting a real variable hides its magic variable 3112set errorlevel=7 3113echo %ErrorLevel% should be 7 3114if errorlevel 7 echo setting var worked too well, bad 3115call :setError 3 3116echo %ErrorLevel% should still be 7 3117 3118echo ------------ Testing GOTO ------------ 3119if a==a goto dest1 3120echo FAILURE at dest 1 3121:dest1 3122echo goto with no leading space worked 3123if a==a goto :dest1b 3124echo FAILURE at dest 1b 3125:dest1b 3126echo goto with colon and no leading space worked 3127if b==b goto dest2 3128echo FAILURE at dest 2 3129 :dest2 3130echo goto with a leading space worked 3131if c==c goto dest3 3132echo FAILURE at dest 3 3133 :dest3 3134echo goto with a leading tab worked 3135if d==d goto dest4 3136echo FAILURE at dest 4 3137:dest4@space@ 3138echo goto with a following space worked 3139if e==e goto dest5 3140echo FAILURE at dest 5 3141:dest5&& echo FAILURE 3142echo goto with following amphersands worked 3143 3144del failure.txt >nul 2>&1 3145if f==f goto dest6 3146echo FAILURE at dest 6 3147:dest6>FAILURE.TXT 3148if exist FAILURE.TXT echo FAILURE at dest 6 as file exists 3149echo goto with redirections worked 3150del FAILURE.TXT >nul 2>&1 3151 3152:: some text that is ignored | dir >cmd_output | another test 3153if exist cmd_output echo FAILURE at dest 6 as file exists 3154echo Ignoring double colons worked 3155del cmd_output >nul 2>&1 3156 3157rem goto a label which does not exist issues an error message and 3158rem acts the same as goto :EOF, and ensure ::label is never matched 3159del testgoto.bat >nul 2>&1 3160echo goto :dest7 ^>nul 2^>^&1 >> testgoto.bat 3161echo echo FAILURE at dest 7 - Should have not found label and issued an error plus ended the batch>> testgoto.bat 3162echo ::dest7>> testgoto.bat 3163echo echo FAILURE at dest 7 - Incorrectly went to label >> testgoto.bat 3164call testgoto.bat 3165del testgoto.bat >nul 2>&1 3166 3167del testgoto.bat >nul 2>&1 3168echo goto ::dest8 ^>nul 2^>^&1 >> testgoto.bat 3169echo echo FAILURE at dest 8 - Should have not found label and issued an error plus ended the batch>> testgoto.bat 3170echo ::dest8>> testgoto.bat 3171echo echo FAILURE at dest 8 - Incorrectly went to label >> testgoto.bat 3172call testgoto.bat 3173del testgoto.bat >nul 2>&1 3174 3175if g==g goto dest9 3176echo FAILURE at dest 9 3177:dest91 3178echo FAILURE at dest 91 3179@ : dest9>rubbish 3180echo label with mixed whitespace and no echo worked 3181 3182if h==h goto :dest10:this is ignored 3183echo FAILURE at dest 10 3184:dest10:this is also ignored 3185echo Correctly ignored trailing information 3186 3187rem Testing which label is reached when there are many options 3188echo Begin: 3189set nextlabel= 3190call :sub 3191set nextlabel=middle 3192goto :sub 3193 3194:sub 3195echo ..First sub 3196if not "%nextlabel%"=="" goto :%nextlabel% 3197goto :EOF 3198 3199:sub 3200echo ..Second sub 3201if not "%nextlabel%"=="" goto :%nextlabel% 3202goto :EOF 3203 3204:middle 3205echo Middle: 3206set nextlabel= 3207call :sub 3208set nextlabel=nearend 3209goto :sub 3210 3211:sub 3212echo ..Third sub 3213if not "%nextlabel%"=="" goto :%nextlabel% 3214goto :EOF 3215 3216:nearend 3217echo Near end: 3218set nextlabel= 3219call :sub 3220set nextlabel=end 3221goto :sub 3222 3223:sub 3224echo ..Fourth sub 3225if not "%nextlabel%"=="" goto :%nextlabel% 3226goto :EOF 3227 3228:end 3229echo At end: 3230set nextlabel= 3231call :sub 3232set nextlabel=done 3233goto :sub 3234 3235:done 3236echo Finished 3237 3238echo ------------ Testing PATH ------------ 3239set WINE_backup_path=%path% 3240set path=original 3241path 3242path try2 3243path 3244path=try3 3245path 3246set path=%WINE_backup_path% 3247set WINE_backup_path= 3248 3249echo ------------ Testing start /W ------------ 3250echo start /W failed to wait>foobar.txt 3251start /W "" cmd /C "ping -n1 & echo start /W seems to really wait>foobar.txt"& type foobar.txt& del foobar.txt 3252 3253echo ------------ Testing changing the drive letter ---------- 3254pushd C:\ 3255 3256echo Normal: 3257call :setError 0 3258C: 3259if errorlevel 1 echo Normal drive change failed 3260 3261echo Normal+space 3262call :setError 0 3263C:@space@ 3264if errorlevel 1 echo Normal+space drive change failed 3265 3266echo Normal+space+garbage 3267call :setError 0 3268C: garbage 3269if errorlevel 1 echo Normal+space+garbage drive change failed 3270 3271call :setError 0 3272echo Quoted should fail 3273"C:" 3274if not errorlevel 1 echo quoted drive change unexpectedly worked 3275 3276echo Normal+tab 3277call :setError 0 3278C:@tab@ 3279if errorlevel 1 echo Normal+tab drive change failed 3280 3281echo Normal+tab+garbage 3282call :setError 0 3283C:@tab@garbagetab 3284if errorlevel 1 echo Normal+tab+garbage drive change failed 3285 3286popd 3287 3288echo ------------ Testing combined CALLs/GOTOs ------------ 3289echo @echo off>foo.cmd 3290echo goto :eof>>foot.cmd 3291echo :eof>>foot.cmd 3292echo echo world>>foo.cmd 3293 3294echo @echo off>foot.cmd 3295echo echo cheball>>foot.cmd 3296echo.>>foot.cmd 3297echo call :bar>>foot.cmd 3298echo if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmd 3299echo goto :eof>>foot.cmd 3300echo.>>foot.cmd 3301echo :bar>>foot.cmd 3302echo echo barbare>>foot.cmd 3303echo goto :eof>>foot.cmd 3304 3305call foo.cmd 3306call foot 3307call :bar 3308del foo.cmd 3309rem Script execution stops after the following line 3310foot deleteMe 3311call :foo 3312call :foot 3313goto :endFuns 3314 3315:foot 3316echo foot 3317 3318:foo 3319echo foo 3320goto :eof 3321 3322:endFuns 3323 3324:bar 3325echo bar 3326call :foo 3327 3328:baz 3329echo baz 3330goto :eof 3331 3332echo Final message is not output since earlier 'foot' processing stops script execution 3333echo Do NOT add any tests below this line 3334 3335echo ------------ Done, jumping to EOF ----------- 3336goto :eof 3337rem Subroutine to set errorlevel and return 3338rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported 3339:setError 3340exit /B %1 3341rem This line runs under cmd in windows NT 4, but not in more modern versions. 3342