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