Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377echo Tests for cmd's builtin commands
@echo onecho ------------ Testing 'echo' [ON] ------------echo wordecho 'singlequotedword'echo "doublequotedword"@echo at-echoed-wordecho "/?"echo.echo .echo.wordecho .wordecho:echo :echo:wordecho :wordecho/echo /echo/wordecho /wordecho off nowecho word@space@echo word@space@@space@ echo wordecho@tab@wordecho@tab@word @tab@echo@tab@word@tab@@space@@tab@echo wordecho @tab@wordecho @tab@wordecho@tab@@tab@wordecho @tab@ on @space@@echo --- @ with chains and brackets(echo the @ character chains until&&@echo we leave the current depth||(echo hidden@echo hidden))&&echo and can hide brackets||(@echo command hidden)||@(echo brackets hidden)@echo ---
@echo offecho off@tab@@space@@echo noecho1 @echo noecho2@@@@@echo echo3echo ------------ Testing 'echo' [OFF] ------------echo wordecho 'singlequotedword'echo "doublequotedword"@echo at-echoed-wordecho "/?"echo.echo .echo.wordecho .wordecho:echo :echo:wordecho :wordecho/echo /echo/wordecho /wordecho on againecho word@space@echo word@space@@space@ echo wordecho@tab@wordecho@tab@word @tab@echo@tab@word@tab@@space@@tab@echo wordecho @tab@wordecho @tab@wordecho@tab@@tab@word
echo ------------ Testing mixed echo modes ------------echo @echo on> mixedEchoModes.cmdecho if 1==1 echo foo>> mixedEchoModes.cmdecho if 1==1 @echo bar>> mixedEchoModes.cmdecho @echo off>> mixedEchoModes.cmdecho if 1==1 echo foo2>> mixedEchoModes.cmdecho if 1==1 @echo bar2>> mixedEchoModes.cmdtype mixedEchoModes.cmdcmd /c mixedEchoModes.cmddel mixedEchoModes.cmd
echo ------------ Testing parameterization ------------call :TestParm a b ccall :TestParm "a b c"call :TestParm "a b"\ccall :TestParm a=~`+,.{}!+bcall :TestParm a;bcall :TestParm "a;b"call :TestParm a^;bcall :TestParm a[b]{c}(d)ecall :TestParm a&echo second linecall :TestParm a b,,,ccall :TestParm a==b;;ccall :TestParm a,,, bgoto :TestRem
:TestParmecho '%1', '%2', '%3'goto :eof
:TestRemecho ------------ Testing rem ------------rem Hellorem Hellorem Hello || foorem echo lolrem echo foo & echo barrem @tab@ Hellorem@tab@ Hellorem@tab@echo foo & echo bar@echo onrem Hellorem Hellorem Hello || foorem echo lolrem echo foo & echo barrem @tab@ Hellorem@tab@ Hellorem@tab@echo foo & echo bar@echo off
echo ------------ Testing redirection operators ------------mkdir foobar & cd foobarecho --- stdout redirectionecho foo>footype fooecho foo 1> footype fooecho foo@tab@1> footype fooecho foo 1>@tab@footype fooecho foo@tab@1>@tab@footype fooecho foo7 7> footype fooecho foo9 9> footype fooecho foo1> footype fooecho foo11> footype fooecho foo12> footype fooecho foo13>"foo"type fooecho foo14>."\foo"type fooecho foo15>."\f"ootype foodel fooecho1>footype fooecho --- stdout appendingecho foo>fooecho foo >>footype foodel fooecho foob >> footype fooecho fooc 1>>footype fooecho food1>>footype fooecho food2>>"foo"type foodel fooecho food21>>footype foodel fooecho foo> fooecho foo7 7>> foo || (echo not supported & del foo)if exist foo (type foo) else echo not supportedecho --- redirections within IF statementsif 1==1 echo foo1>bartype bar & del barif 1==1 echo foo2>>bartype bar & del barecho -----if 1==1 (echo foo2>bar) else echo baz2>bartype bar & del barif 1==1 (echo foo3) else echo baz3>bartype bar || echo file does not exist, okif 1==1 (echo foo4>bar) else echo baz4>bartype bar & del barif 1==0 (echo foo5>bar) else echo baz5>bartype bar & del barif 1==0 (echo foo6) else echo baz6 1>bartype bar & del barif 1==0 (echo foo7 1>bar) else echo baz7>bartype bar & del barif 1==0 (echo foo8 1>bar) else echo baz8>baktype bakif 1==1 (echo foo>bar & echo baz)type barif 1==1 ( echo foo>bar echo baz)type bar(if 1==1 (echo A) else echo B) > Ctype C(if 1==0 (echo A) else echo B) > Ctype C(if 1==0 (echo A > B) else echo C)cd .. & rd /s/q foobar
echo ------------ Testing circumflex escape character ------------rem Using something like "echo foo^" asks for an additional char after a "More?" prompt on the following line; it's not possible to currently test that non-interactivelyecho ^hell^o, worldecho hell^o, worldecho hell^^o, worldecho hell^^^o, worldecho hello^worldecho hello^
worldecho hello^
echo finishedmkdir foobarecho baz> foobar\baztype foobar\baztype foobar^\bazrd /s/q foobarecho foo ^| echo barecho foo ^& echo barcall :setError 0echo bak ^&& echo baz 2> nulecho %ErrorLevel%echo foo ^> fooecho ^<> footype foodel fooset WINE_FOO=oofecho ff^%WINE_FOO%set WINE_FOO=bar ^| bazset WINE_FOOrem FIXME: echoing %WINE_FOO% gives an error (baz not recognized) but prematurelyrem exits the script on windows; redirecting stdout and/or stderr doesn't helpecho %ErrorLevel%call :setError 0set WINE_FOO=bar ^^^| bazset WINE_FOOecho %WINE_FOO%echo %ErrorLevel%set WINE_FOO=
echo ------------ Testing chains ------------rem The chain operators have the following bottom-up precedence:rem 'else' precedes nothing and matches the closest unmatched 'if' in the same bracket depthrem '&' precedes 'else'rem '||' precedes '&' and 'else'rem '&&' precedes '||', '&' and 'else'rem '|' precedes '&&', '||', '&' and 'else'remrem Example: 'if 1==1 if 2==2 if 3==3 a | b && c || d & e else f else g' is interpreted asrem 'if 1==1 (if 2==2 (if 3==3 ((((a | b) && c) || d) & e) else f) else g)'goto :cfailend:cfailecho %1call :setError 1goto :eof:cfailendecho --- chain successecho a1&echo a2echo b1&&echo b2echo c1||echo c2echo ---echo d1&echo d2&echo d3echo e1&echo e2&&echo e3echo f1&echo f2||echo f3echo ---echo g1&&echo g2&echo g3echo h1&&echo h2&&echo h3echo i1&&echo i2||echo i3echo ---echo j1||echo j2&echo j3echo ---echo k1||echo k2&&echo k3echo ---echo l1||echo l2||echo l3echo ---echo --- chain failurecall :cfail a1&call :cfail a2call :cfail b1&&call :cfail b2echo ---call :cfail c1||call :cfail c2call :cfail d1&call :cfail d2&call :cfail d3call :cfail e1&call :cfail e2&&call :cfail e3echo ---call :cfail f1&call :cfail f2||call :cfail f3call :cfail g1&&call :cfail g2&call :cfail g3echo ---call :cfail h1&&call :cfail h2&&call :cfail h3echo ---call :cfail i1&&call :cfail i2||call :cfail i3echo ---call :cfail j1||call :cfail j2&call :cfail j3call :cfail k1||call :cfail k2&&call :cfail k3echo ---call :cfail l1||call :cfail l2||call :cfail l3echo --- chain bracketsrem Brackets are like regular commands, they support redirectionsrem and have the same precedence as regular commands.echo a1&(echo a2&echo a3)echo b1&(echo b2&&echo b3)echo c1&(echo c2||echo c3)echo ---echo d1&&(echo d2&echo d3)echo e1&&(echo e2&&echo e3)echo f1&&(echo f2||echo f3)echo ---echo g1||(echo g2&echo g3)echo ---echo h1||(echo h2&&echo h3)echo ---echo i1||(echo i2||echo i3)echo ---call :cfail j1&(call :cfail j2&call :cfail j3)call :cfail k1&(call :cfail k2&&call :cfail k3)echo ---call :cfail l1&(call :cfail l2||call :cfail l3)call :cfail m1&&(call :cfail m2&call :cfail m3)echo ---call :cfail n1&&(call :cfail n2&&call :cfail n3)echo ---call :cfail o1&&(call :cfail o2||call :cfail o3)echo ---call :cfail p1||(call :cfail p2&call :cfail p3)call :cfail q1||(call :cfail q2&&call :cfail q3)echo ---call :cfail r1||(call :cfail r2||call :cfail r3)echo --- chain piperem Piped commands run at the same time, so the print order varies.rem Additionally, they don't run in the batch script context, as shown byrem 'call :existing_label|echo read the error message'.(echo a 1>&2|echo a 1>&2) 2>&1echo ---echo b1|echo b2echo c1&&echo c2|echo c3echo d1||echo d2|echo d3echo ---echo e1&echo e2|echo e3echo f1|echo f2&&echo f3echo g1|echo g2||echo g3echo ---echo h1|echo h2&echo h3echo i1|echo i2|echo i3echo --- chain pipe inputrem The output data of the left side of a pipe can disappear, probablyrem because it finished too fast and closed the pipe before it could be read,rem which means we can get broken results for the tests of this section.echo @echo off> tmp.cmdecho set IN=X>> tmp.cmdecho set /p IN=%%1:>> tmp.cmdecho setlocal EnableDelayedExpansion>> tmp.cmdecho echo [!IN!,%%1]>> tmp.cmdecho endlocal>> tmp.cmdecho set IN=>> tmp.cmdecho a1|cmd /ctmp.cmd a2echo b1|cmd /ctmp.cmd b2|cmd /ctmp.cmd b3echo c1|cmd /ctmp.cmd c2|cmd /ctmp.cmd c3|cmd /ctmp.cmd c4echo d1|call tmp.cmd d2echo e1|call tmp.cmd e2|call tmp.cmd e3echo f1|call tmp.cmd f2|call tmp.cmd f3|call tmp.cmd f4rem FIXME these 3 tests cause "unexpected end of output"rem test : echo g1|tmp.cmd g2rem result: g2:[g1,g2]rem test : echo h1|tmp.cmd h2|tmp.cmd h3rem result: h3:[h2:[h1,h2],h3]@or_broken@h3:[h2:,h3]rem test : echo i1|tmp.cmd i2|tmp.cmd i3|tmp.cmd i4rem result: i4:[i3:[i2:[i1,i2],i3],i4]@or_broken@i4:[i3:[i2:,i3],i4]@or_broken@i4:[i3:,i4]del tmp.cmdecho --- chain elserem Command arguments are gready and eat up the 'else' unless terminated byrem brackets, which means the 'else' can only be recognized when therem 'if true' command chain ends with brackets.if 1==1 if 2==2 if 3==3 (echo a1) else (echo a2) else echo a3if 1==1 if 2==2 if 3==0 (echo b1) else (echo b2) else echo b3echo ---if 1==1 if 2==0 if 3==3 (echo c1) else (echo c2) else echo c3echo ---if 1==1 if 2==0 if 3==0 (echo d1) else (echo d2) else echo d3echo ---if 1==0 if 2==2 if 3==3 (echo e1) else (echo e2) else echo e3echo ---if 1==0 if 2==2 if 3==0 (echo f1) else (echo f2) else echo f3echo ---if 1==0 if 2==0 if 3==3 (echo g1) else (echo g2) else echo g3echo ---if 1==0 if 2==0 if 3==0 (echo h1) else (echo h2) else echo h3echo ---echo --- chain else (if true)if 1==1 echo a1 else echo a2if 1==1 echo b1|echo b2 else echo b3if 1==1 echo c1&&echo c2 else echo c3if 1==1 echo d1||echo d2 else echo d3echo ---if 1==1 echo e1&echo e2 else echo e3if 1==1 echo f1 else echo f2|echo f3if 1==1 echo g1 else echo g2&&echo g3if 1==1 echo h1 else echo h2||echo h3echo ---if 1==1 echo i1 else echo i2&echo i3if 1==1 echo j1|(echo j2) else echo j3echo ---if 1==1 echo k1&&(echo k2) else echo k3if 1==1 echo l1||(echo l2) else echo l3echo ---if 1==1 echo m1&(echo m2) else echo m3if 1==1 (echo n1) else echo n2|echo n3if 1==1 (echo o1) else echo o2&&echo o3if 1==1 (echo p1) else echo p2||echo p3if 1==1 (echo q1) else echo q2&echo q3echo ---echo --- chain else (if false)if 1==0 echo a1 else echo a2if 1==0 echo b1|echo b2 else echo b3if 1==0 echo c1&&echo c2 else echo c3if 1==0 echo d1||echo d2 else echo d3if 1==0 echo e1&echo e2 else echo e3if 1==0 echo f1 else echo f2|echo f3if 1==0 echo g1 else echo g2&&echo g3if 1==0 echo h1 else echo h2||echo h3if 1==0 echo i1 else echo i2&echo i3if 1==0 echo j1|(echo j2) else echo j3echo ---if 1==0 echo k1&&(echo k2) else echo k3if 1==0 echo l1||(echo l2) else echo l3if 1==0 echo m1&(echo m2) else echo m3if 1==0 (echo n1) else echo n2|echo n3if 1==0 (echo o1) else echo o2&&echo o3if 1==0 (echo p1) else echo p2||echo p3echo ---if 1==0 (echo q1) else echo q2&echo q3echo ------------ Testing 'set' ------------call :setError 0rem Remove any WINE_FOO* WINE_BA* environment variables from shell before proceedingfor /f "delims==" %%i in ('set WINE_ba') do set %%i=for /f "delims==" %%i in ('set WINE_foo') do set %%i=set WINE_FOOBAR 2> nul > nulecho %ErrorLevel%set WINE_FOOBAR = bazecho %ErrorLevel%echo %WINE_FOOBAR%WINE_FOOBAR not definedecho %WINE_FOOBAR %set WINE_FOOBAR 2> nulset WINE_FOOBAR = baz2echo %ErrorLevel%echo %WINE_fOObAr %set WINE_FOOBAR= barecho %ErrorLevel%echo %WINE_FOOBAR%set WINE_FOOset WINE_FOOBAR=set WINE_FOOBecho %WINE_FOOBAR%WINE_FOOBAR not definedset WINE_FOOBAR =set WINE_FOOBA 2> nul > nulecho %ErrorLevel%set WINE_FOO=barecho %WINE_FOO%set WINE_FOO=fooset WINE_BAR=barecho %WINE_FOO%%WINE_BAR%set WINE_BAR=set WINE_FOO=set WINE_FOO=%WINE_FOO%echo %WINE_FOO%WINE_FOO not definedset WINE_BAZ%=bazbazset WINE_BAecho %WINE_BAZ%%set WINE_BAZ%=echo set "WINE_FOO=bar" should not include the quotes in the variable valueset "WINE_FOO=bar"echo %WINE_FOO%set@tab@WINE_FOO=fooecho %WINE_FOO%set@tab@WINE_FOO=echo '%WINE_FOO%'set WINE_FOO=foo@space@echo '%WINE_FOO%'set WINE_FOO=foo@tab@echo '%WINE_FOO%'rem Space symbol must appear in `var`set WINE_FOO=value@space@echo '%WINE_FOO%'rem Space symbol must NOT appear in `var`set "WINE_FOO=value"@space@echo '%WINE_FOO%'rem Mixed examples:set WINE_FOO=jim fredecho '%WINE_FOO%'set WINE_FOO="jim" fredecho '%WINE_FOO%'set "WINE_FOO=jim fred"echo '%WINE_FOO%'set "WINE_FOO=jim" fredecho '%WINE_FOO%'rem Only the final quote ends the stringset "WINE_FOO=apple"banana"grape"orangeecho '%WINE_FOO%'set WINE_FOO=rem set PATH must work with quotesset PATH_BACKUP=%PATH%mkdir foldermkdir "fol;der"echo echo I'm here! > "fol;der\sub1.bat"echo echo I'm here! > folder\sub1.batset PATH=nothing;"fol;der"call sub1set PATH="foldercall sub1set PATH=folder"call sub1del "fol;der\sub1.bat"del folder\sub1.batrmdir "fol;der"rmdir folderPATH=%PATH_BACKUP%
echo ------------ Testing 'choice' ------------
rem Windows XP and Windows 2000 do not come with choicerem echo is used for @or_broken@ formattingchoice /C:ABC /M "Example message" /D A /T:0if %ERRORLEVEL% EQU 9009 ( echo choice unavailable)echo %ERRORLEVEL%choice /C ABC "/M:Example message" /D:B /T 0if %ERRORLEVEL% EQU 9009 ( echo choice unavailable)echo %ERRORLEVEL%choice /C def /D:f /T:0if %ERRORLEVEL% EQU 9009 ( echo choice unavailable)echo %ERRORLEVEL%REM If a pipe fails due to a nonexistent commandREM it will stop the whole program's executionif %ERRORLEVEL% NEQ 9009 ( echo Y | choice /C ABCXYZ /D A /T 2)if %ERRORLEVEL% EQU 9009 ( echo choice unavailable)echo %ERRORLEVEL%choice /C ABC /N /D A /T 0if %ERRORLEVEL% EQU 9009 ( echo choice unavailable)echo %ERRORLEVEL%choice /C abcABC /CS /D:A /T:0if %ERRORLEVEL% EQU 9009 ( echo choice unavailable)echo %ERRORLEVEL%rem intentional errorchoice /C abcABC /D:A /T:0 >NUL 2>NULecho %ERRORLEVEL%
echo ------------ Testing variable expansion ------------call :setError 0echo ~p0 should be path containing batch fileecho %~p0mkdir dummydircd dummydirecho %~p0cd ..rmdir dummydirecho ~dp0 should be directory containing batch fileecho %~dp0mkdir dummydircd dummydirecho %~dp0cd ..rmdir dummydirecho CD value %CD%echo %%echo P%echo %Pecho %WINE_UNKNOWN%Secho P%WINE_UNKNOWN%echo P%WINE_UNKNOWN%Secho %ERRORLEVELecho %ERRORLEVEL%echo %ERRORLEVEL%%ERRORLEVEL%echo %ERRORLEVEL%ERRORLEVEL%echo %ERRORLEVEL%%echo %ERRORLEVEL%%%echo P%ERRORLEVEL%echo %ERRORLEVEL%Secho P%ERRORLEVEL%S
echo ------------ Testing variable substrings ------------set WINE_VAR=qwertyecho %WINE_VAR:~0,1%echo %WINE_VAR:~0,3%echo %WINE_VAR:~2,2%echo '%WINE_VAR:~-2,3%'echo '%WINE_VAR:~-2,1%'echo %WINE_VAR:~2,-1%echo %WINE_VAR:~2,-3%echo '%WINE_VAR:~-2,-4%'echo %WINE_VAR:~-3,-2%set WINE_VAR=
echo ------------ Testing variable substitution ------------echo --- in FOR variablesfor %%i in ("A B" C) do echo %%irem check works when prefix with @@for %%i in ("A B" C) do echo %%irem quotes removalfor %%i in ("A B" C) do echo '%%~i'rem fully qualified pathfor %%f in ("C D" E) do echo %%~ffrem drive letterfor %%i in ("F G" H) do echo %%~direm pathfor %%d in ("I J" K) do echo %%~pdrem filenamefor %%i in ("L M" N) do echo %%~nirem file extensionfor %%i in ("O. P.OOL" Q.TABC hello) do echo '%%~xi'rem path with short path namesfor %%I in ("R S" T ABCDEFGHIJK.LMNOP) do echo '%%~sI'rem file attributefor %%i in ("U V" W) do echo '%%~ai'echo foo> foofor %%i in (foo) do echo '%%~ai'for %%i in (foo) do echo '%%~zi'del foorem file date/timerem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar...for %%i in ("a b" c) do echo '%%~ti'rem file sizerem Similar issues as abovefor %%i in ("a b" c) do echo '%%~zi'rem combined optionsfor %%i in ("d e" f) do echo %%~dpifor %%i in ("g h" i) do echo %%~sdifor %%i in ("g h" i) do echo %%~dsifor %%i in ("j k" l.eh) do echo '%%~xsi'for %%i in ("") do echo '%%~i,%%~fi,%%~di,%%~pi,%%~ni,%%~xi,%%~si,%%~ai,%%~ti,%%~zi'
echo --- in parametersfor %%i in ("A B" C) do call :echoFun %%irem quotes removalfor %%i in ("A B" C) do call :echoFunQ %%irem fully qualified pathfor %%f in ("C D" E) do call :echoFunF %%frem drive letterfor %%i in ("F G" H) do call :echoFunD %%irem pathfor %%d in ("I J" K) do call :echoFunP %%drem filenamefor %%i in ("L M" N) do call :echoFunN %%irem file extensionfor %%i in ("O. P.OOL" Q.TABC hello) do call :echoFunX %%irem path with short path namesfor %%I in ("R S" T ABCDEFGHIJK.LMNOP) do call :echoFunS %%Irem NT4 aborts whole script execution when encountering ~a, ~t and ~z substitutions, preventing full testingrem combined optionsfor %%i in ("d e" f) do call :echoFunDP %%ifor %%i in ("g h" i) do call :echoFunSD %%ifor %%i in ("g h" i) do call :echoFunDS %%ifor %%i in ("j k" l.eh) do call :echoFunXS %%i
goto :endEchoFuns:echoFunecho %1goto :eof
:echoFunQecho '%~1'goto :eof
:echoFunFecho %~f1goto :eof
:echoFunDecho %~d1goto :eof
:echoFunPecho %~p1goto :eof
:echoFunNecho %~n1goto :eof
:echoFunXecho '%~x1'goto :eof
:echoFunSrem some NT4 workaroundset WINE_VAR='%~s1'echo %WINE_VAR%set WINE_VAR=goto :eof
:echoFunDPecho %~dp1goto :eof
:echoFunSDecho %~sd1goto :eof
:echoFunDSecho %~ds1goto :eof
:echoFunXSecho '%~xs1'goto :eof:endEchoFuns
echo ------------ Testing parameter zero ------------call :func parm1 parm2goto :endParm0:funcecho %~0 %~1echo [%0] [%~d0] [%~p0] [%~n0] [%~x0] [%~s0]goto :EOF:endParm0
echo ------------ Testing variable delayed expansion ------------rem NT4 doesn't support thisecho --- default mode (load-time expansion)set WINE_FOO=fooecho %WINE_FOO%echo !WINE_FOO!if %WINE_FOO% == foo ( set WINE_FOO=bar if %WINE_FOO% == bar (echo bar) else echo foo)
set WINE_FOO=fooif %WINE_FOO% == foo ( set WINE_FOO=bar if !WINE_FOO! == bar (echo bar) else echo foo)
echo --- runtime (delayed) expansion modesetlocal EnableDelayedExpansionset WINE_FOO=fooecho %WINE_FOO%echo !WINE_FOO!if %WINE_FOO% == foo ( set WINE_FOO=bar if %WINE_FOO% == bar (echo bar) else echo foo)
set WINE_FOO=fooif %WINE_FOO% == foo ( set WINE_FOO=bar if !WINE_FOO! == bar (echo bar) else echo foo)echo %ErrorLevel%setlocal DisableDelayedExpansionecho %ErrorLevel%set WINE_FOO=fooecho %WINE_FOO%echo !WINE_FOO!set WINE_FOO=echo --- using /V cmd flagecho @echo off> tmp.cmdecho set WINE_FOO=foo>> tmp.cmdecho echo %%WINE_FOO%%>> tmp.cmdecho echo !WINE_FOO!>> tmp.cmdecho set WINE_FOO=>> tmp.cmdcmd /V:ON /C tmp.cmdcmd /V:OfF /C tmp.cmddel tmp.cmd
echo ------------ Testing conditional execution ------------echo --- unconditional ampersandcall :setError 123 & echo foo1echo bar2 & echo foo2mkdir foobar & cd foobarecho > foobazbarcd .. & rd /s/q foobarif exist foobazbar ( echo foobar not deleted! cd .. rd /s/q foobar) else echo foobar deletedecho --- on success conditional andcall :setError 456 && echo foo3 > foo3if exist foo3 ( echo foo3 created del foo3) else echo foo3 not createdecho bar4 && echo foo4echo --- on failure conditional orcall :setError 789 || echo foo5echo foo6 || echo bar6 > bar6if exist bar6 ( echo bar6 created del bar6)
echo ------------ Testing cd ------------mkdir foobarcd foobarecho blabla > singleFiledir /becho Current dir: %CD%cdcd ..cdcd foobar@space@cdcd ..cdcd @space@foobarcdcd..cdcd foobarcd..@space@cdif not exist foobar (cd ..)cd foobarcd@tab@..@tab@@space@@tab@cdif not exist foobar (cd ..)cd foobarmkdir "bar bak"cd "bar bak"cdcd ..cd ".\bar bak"cdcd ..cd .\"bar bak"cdcd ..cd bar bakcdcd "bar bak@space@"@tab@@space@cdcd ..\..cdrd /Q/s foobarmkdir foobarcd /d@tab@foobarcdcd ..rd /q/s foobar
echo ------------ Testing type ------------echo bar> foobaz@echo ontype foobazecho ---@echo offtype foobaz@tab@echo ---1type ."\foobaz"echo ---2type ".\foobaz"echo ---3echo foo> foobayecho ---4type foobaz foobay > foobax 2> foobawecho ---5type foobaxecho ---6type foobawecho ---7del foobaz foobay foobax foobaw
echo ------------ Testing NUL ------------md foobar & cd foobarrem NUL file (non) creation + case insensitivityrem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaroundecho > barecho foo > NULdir /b /a-decho foo > nuldir /b /a-decho foo > NuL@tab@dir /b@tab@/a-ddel barrem NUL not special everywherecall :setError 123echo NUL> fooif not exist foo (echo foo should have been created) else ( type foo del foo)rem Empty file creationcopy nul foo > nulif exist foo ( echo foo created del foo type foo) else ( echo ***)echo 1234 >a.acopy a.a+NUL b.b >nulcall :CheckFileSize a.a 7 b.b 8copy NUL+a.a b.b >nulcall :CheckFileSize a.a 7 b.b 8mkdir subdircopy a.a+NUL subdir\ >nulcall :CheckFileSize a.a 7 subdir\a.a 8del subdir\a.acd subdircopy ..\a.a NUL >nulif exist a.a echo Failedcd ..rd subdir /s /qdel a.a b.bcd .. & rd foobar /s /q
echo ------------ Testing if/else ------------echo --- if/else should work with blocksif 0 == 0 ( echo if seems to work) else ( echo if seems to be broken)if 1 == 0 ( echo else seems to be broken) else ( echo else seems to work)if /c==/c ( echo if seems not to detect /c as parameter) else ( echo parameter detection seems to be broken)SET elseIF=0if 1 == 1 ( SET /a elseIF=%elseIF%+1) else if 1 == 1 ( SET /a elseIF=%elseIF%+2) else ( SET /a elseIF=%elseIF%+2)if %elseIF% == 1 ( echo else if seems to work) else ( echo else if seems to be broken)SET elseIF=0if 1 == 2 ( SET /a elseIF=%elseIF%+2) else if 1 == 1 ( SET /a elseIF=%elseIF%+1) else ( SET /a elseIF=%elseIF%+2)if %elseIF% == 1 ( echo else if seems to work) else ( echo else if seems to be broken)SET elseIF=0if 1 == 2 ( SET /a elseIF=%elseIF%+2) else if 1 == 2 ( SET /a elseIF=%elseIF%+2) else ( SET /a elseIF=%elseIF%+1)if %elseIF% == 1 ( echo else if seems to work) else ( echo else if seems to be broken)if "x" == "a" ( echo broken1) else ( echo expected1 if "y" == "b" echo broken2 echo expected post-embedded if)if ()==() ( echo comparison operators surrounded by brackets seem to work) else ( echo comparison operators surrounded by brackets seem to be broken)if 1(==1( ( echo comparison operators surrounded by brackets seem to work) else ( echo comparison operators surrounded by brackets seem to be broken)if )==) ( echo comparison operators surrounded by brackets seem to work) else ( echo comparison operators surrounded by brackets seem to be broken)if /i not (a)==(b) ( echo comparison operators surrounded by brackets seem to work) else ( echo comparison operators surrounded by brackets seem to be broken)if defined windir echo windir is definedif not defined windir echo windir is definedif not exist %windir% ( echo windir does not exist) else ( echo windir does exist)echo --- case sensitivity with and without /i optionif bar==BAR echo if does not default to case sensitivityif not bar==BAR echo if seems to default to case sensitivityif /i foo==FOO echo if /i seems to workif /i not foo==FOO echo if /i seems to be brokenif /I foo==FOO echo if /I seems to workif /I not foo==FOO echo if /I seems to be broken
echo --- string comparisonsif abc == abc (echo equal) else echo non equalif abc =="abc" (echo equal) else echo non equalif "abc"== abc (echo equal) else echo non equalif "abc"== "abc" (echo equal) else echo non equal
echo --- tabs handlingif@tab@1==1 echo doomif @tab@1==1 echo doomif 1==1 (echo doom) else@tab@echo quakeif@tab@not @tab@1==@tab@0 @tab@echo lolif 1==0@tab@(echo doom) else echo quakeif 1==0 (echo doom)@tab@else echo quakeif 1==0 (echo doom) else@tab@echo quake
echo --- comparison operatorsrem NT4 misevaluates conditionals in for loops so we have to use subroutines as workaroundsecho ------ for stringsrem NT4 stops processing of the whole batch file as soon as it finds arem comparison operator non fully uppercased, such as lss instead of LSS, so werem can't test those here.if LSS LSS LSSfoo (echo LSS string can be used as operand for LSS comparison)if LSS LSS LSS (echo bar)if 1.1 LSS 1.10 (echo floats are handled as strings)if "9" LSS "10" (echo numbers in quotes recognized!) else echo numbers in quotes are handled as stringsif not "-1" LSS "1" (echo negative numbers as well) else echo NT4if /i foo LSS FoOc echo if /i seems to work for LSSif /I not foo LSS FOOb echo if /I seems to be broken for LSSset WINE_STR_PARMS=A B AB BA AAfor %%i in (%WINE_STR_PARMS%) do ( for %%j in (%WINE_STR_PARMS%) do ( call :LSStest %%i %%j))if b LSS B (echo b LSS B) else echo NT4if /I b LSS B echo b LSS B insensitiveif b LSS A echo b LSS Aif /I b LSS A echo b LSS A insensitiveif a LSS B (echo a LSS B) else echo NT4if /I a LSS B echo a LSS B insensitiveif A LSS b echo A LSS bif /I A LSS b echo A LSS b insensitivefor %%i in (%WINE_STR_PARMS%) do ( for %%j in (%WINE_STR_PARMS%) do ( call :LEQtest %%i %%j))if b LEQ B (echo b LEQ B) else echo NT4if /I b LEQ B echo b LEQ B insensitiveif b LEQ A echo b LEQ Aif /I b LEQ A echo b LEQ A insensitiveif a LEQ B (echo a LEQ B) else echo NT4if /I a LEQ B echo a LEQ B insensitiveif A LEQ b echo A LEQ bif /I A LEQ b echo A LEQ b insensitivefor %%i in (%WINE_STR_PARMS%) do ( for %%j in (%WINE_STR_PARMS%) do ( call :EQUtest %%i %%j))if /I A EQU a echo A EQU a insensitivefor %%i in (%WINE_STR_PARMS%) do ( for %%j in (%WINE_STR_PARMS%) do ( call :NEQtest %%i %%j))for %%i in (%WINE_STR_PARMS%) do ( for %%j in (%WINE_STR_PARMS%) do ( call :GEQtest %%i %%j))for %%i in (%WINE_STR_PARMS%) do ( for %%j in (%WINE_STR_PARMS%) do ( call :GTRtest %%i %%j))
echo ------------ Testing if/exist ------------mkdir subdirecho something>subdir\barecho something else>fooif exist foo ( echo exist explicit works) else ( echo ERROR exist explicit broken)if exist bar ( echo ERROR exist explicit unknown file broken) else ( echo exist explicit unknown file works)if exist subdir\bar ( echo exist explicit in subdir works) else ( echo ERROR exist explicit in subdir broken)if exist fo* ( echo exist simple wildcard works) else ( echo ERROR exist simple wildcard broken)if exist subdir\ba* ( echo exist wildcard works) else ( echo ERROR exist wildcard broken)if not exist subdir\ba* ( echo ERROR negate exist wildcard broken) else ( echo negate exist wildcard works)if exist idontexist\ba* ( echo ERROR exist wildcard bad subdir broken) else ( echo exist wildcard bad subdir broken works)if exist subdir ( echo exist subdir ok) else ( echo ERROR exist subdir not working)if exist subdir\. ( echo exist subdir with . ok) else ( echo ERROR exist subdir with . not working)if exist subdir\ ( echo exist subdir with \ ok) else ( echo ERROR exist subdir with \ not working)if exist "subdir\" ( echo exist subdir with \ and quotes ok) else ( echo ERROR exist subdir with \ and quotes not working)del foo subdir\barrd subdir
echo ------ for numbersif -1 LSS 1 (echo negative numbers handled)if not -1 LSS -10 (echo negative numbers handled)if not 9 LSS 010 (echo octal handled)if not -010 LSS -8 (echo also in negative form)if 4 LSS 0x5 (echo hexa handled)if not -1 LSS -0x1A (echo also in negative form)if 11 LSS 101 (echo 11 LSS 101)set WINE_INT_PARMS=0 1 10 9for %%i in (%WINE_INT_PARMS%) do ( for %%j in (%WINE_INT_PARMS%) do ( call :LSStest %%i %%j))for %%i in (%WINE_INT_PARMS%) do ( for %%j in (%WINE_INT_PARMS%) do ( call :LEQtest %%i %%j))for %%i in (%WINE_INT_PARMS%) do ( for %%j in (%WINE_INT_PARMS%) do ( call :EQUtest %%i %%j))if 011 EQU 9 (echo octal ok)if 0xA1 EQU 161 (echo hexa ok)if 0xA1 EQU "161" (echo hexa should be recognized) else (echo string/hexa compare ok)if "0xA1" EQU 161 (echo hexa should be recognized) else (echo string/hexa compare ok)for %%i in (%WINE_INT_PARMS%) do ( for %%j in (%WINE_INT_PARMS%) do ( call :NEQtest %%i %%j))for %%i in (%WINE_INT_PARMS%) do ( for %%j in (%WINE_INT_PARMS%) do ( call :GEQtest %%i %%j))for %%i in (%WINE_INT_PARMS%) do ( for %%j in (%WINE_INT_PARMS%) do ( call :GTRtest %%i %%j))echo ------ for numbers and stringified numbersif not "1" EQU 1 (echo strings and integers not equal) else echo fooif not 1 EQU "1" (echo strings and integers not equal) else echo fooif '1' EQU 1 echo '1' EQU 1if 1 EQU '1' echo 1 EQU '1'if not "1" GEQ 1 (echo foo) else echo barif "10" GEQ "1" echo "10" GEQ "1"if '1' GEQ 1 (echo '1' GEQ 1) else echo NT4if 1 GEQ "1" echo 1 GEQ "1"if "1" GEQ "1" echo "1" GEQ "1"if '1' GEQ "1" echo '1' GEQ "1"if "10" GEQ "1" echo "10" GEQ "1"if not 1 GEQ '1' (echo non NT4) else echo 1 GEQ '1'for %%i in ("1" '1') do call :GEQtest %%i '1'if "10" GEQ '1' (echo "10" GEQ '1') else echo fooif 1 GEQ "10" (echo 1 GEQ "10") else echo fooif "1" GEQ "10" (echo 1 GEQ "10") else echo fooif '1' GEQ "10" (echo '1' GEQ "10") else echo fooif "10" GEQ "10" (echo "10" GEQ "10")echo --- unconditional ampersand after if one lineif "0"=="0" echo 1 & echo 2 & echo 3 else echo 4echo ---echo x & if "0"=="1" echo 1 & echo 2echo ---echo x & if "0"=="1" echo 1 & echo 2 & echo 3echo ---echo x & if "0"=="1" (echo 1 & echo 2 & echo 3)echo ---echo x & if "0"=="1" echo 1 & echo 2 & echo 3 else echo 4echo ---goto :endIfCompOpsSubroutines
rem IF subroutines helpers:LSStestif %1 LSS %2 echo %1 LSS %2goto :eof:LEQtestif %1 LEQ %2 echo %1 LEQ %2goto :eof:EQUtestif %1 EQU %2 echo %1 EQU %2goto :eof:NEQtestif %1 NEQ %2 echo %1 NEQ %2goto :eof:GEQtestif %1 GEQ %2 echo %1 GEQ %2goto :eof:GTRtestif %1 GTR %2 echo %1 GTR %2goto :eof
:endIfCompOpsSubroutinesset WINE_STR_PARMS=set WINE_INT_PARMS=
echo ------------ Testing for ------------echo --- plain FORfor %%i in (A B C) do echo %%ifor %%i in (A B C) do echo %%Ifor %%i in (A B C) do echo %%jfor %%i in (A B C) do call :forTestFun1 %%ifor %%i in (1,4,1) do echo %%ifor %%i in (A, B,C) do echo %%ifor %%i in (X) do echo %%ifor@tab@%%i in (X2) do echo %%ifor %%i in@tab@(X3) do echo %%ifor %%i in (@tab@ foo@tab@) do echo %%ifor@tab@ %%i in@tab@(@tab@M) do echo %%ifor %%i@tab@in (X)@tab@do@tab@echo %%ifor@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%jfor %%i in (`echo A B`) do echo %%ifor %%i in ('echo A B') do echo %%ifor %%i in ("echo A B") do echo %%ifor %%i in ("A B" C) do echo %%igoto :endForTestFun1:forTestFun1echo %1goto :eof:endForTestFun1echo --- imbricated FORsfor %%i in (X) do ( for %%j in (Y) do ( echo %%i %%j))for %%i in (X) do ( for %%I in (Y) do ( echo %%i %%I))for %%i in (A B) do ( for %%j in (C D) do ( echo %%i %%j))for %%i in (A B) do ( for %%j in (C D) do ( call :forTestFun2 %%i %%j ))goto :endForTestFun2:forTestFun2echo %1 %2goto :eof:endForTestFun2mkdir foobar & cd foobarmkdir foomkdir barmkdir bazmkdir popecho > bazbazecho --- basic wildcardsfor %%i in (ba*) do echo %%iecho --- wildcards in subdirsecho something>pop\bar1echo something>pop\bar2.txtecho something>pop\bar3for %%f in (pop\ba*) do ( call echo %%f )rmdir /s/q popecho --- for /dfor /d %%i in (baz foo bar) do echo %%i 2>&1rem Confirm we don't match files:for /d %%i in (bazb*) do echo %%i 2>&1for /d %%i in (bazb2*) do echo %%i 2>&1rem Show we pass through non wildcardsfor /d %%i in (PASSED) do echo %%ifor /d %%i in (xxx) do ( echo %%i - Should be xxx echo Expected second line)rem Show we issue no messages on failuresfor /d %%i in (FAILED?) do echo %%i 2>&1for /d %%i in (FAILED?) do ( echo %%i - Unexpected! echo FAILED Unexpected second line)for /d %%i in (FAILED*) do echo %%i 2>&1for /d %%i in (FAILED*) do ( echo %%i - Unexpected! echo FAILED Unexpected second line)rem FIXME can't test wildcard expansion here since it's listed in directoryrem order, and not in alphabetic order.rem Proper testing would need a currently missing "sort" program implementation.rem for /d %%i in (ba*) do echo %%i>> tmprem sort < tmprem del tmprem for /d %%i in (?a*) do echo %%i>> tmprem sort < tmprem del tmprem for /d %%i in (*) do echo %%i>> tmprem sort < tmprem del tmpecho > baz\bazbazgoto :TestForR
:SetExpecteddel temp.bat 2>nulcall :WriteLine set WINE_found=Nfor /l %%i in (1,1,%WINE_expectedresults%) do ( call :WriteLine if "%%%%WINE_expectedresults.%%i%%%%"=="%%%%~1" set WINE_found=Y call :WriteLine if "%%%%WINE_found%%%%"=="Y" set WINE_expectedresults.%%i= call :WriteLine if "%%%%WINE_found%%%%"=="Y" goto :eof)call :WriteLine echo Got unexpected result: "%%%%~1"goto :eof
:WriteLineecho %*>> temp.batgoto :EOF
:ValidateExpecteddel temp.bat 2>nulfor /l %%i in (1,1,%WINE_expectedresults%) do ( call :WriteLine if not "%%%%WINE_expectedresults.%%i%%%%"=="" echo Found missing result: "%%%%WINE_expectedresults.%%i%%%%")call temp.batdel temp.bat 2>nulgoto :eof
:TestForRrem %CD% does not work on NT4 so use the following workaroundfor /d %%i in (.) do set WINE_CURDIR=%%~dpnxi
echo --- for /Recho Plain directory enumerationset WINE_expectedresults=4set WINE_expectedresults.1=%WINE_CURDIR%\.set WINE_expectedresults.2=%WINE_CURDIR%\bar\.set WINE_expectedresults.3=%WINE_CURDIR%\baz\.set WINE_expectedresults.4=%WINE_CURDIR%\foo\.call :SetExpectedfor /R %%i in (.) do call temp.bat "%%i"call :ValidateExpected
echo Plain directory enumeration from provided rootset WINE_expectedresults=4set WINE_expectedresults.1=%WINE_CURDIR%\.set WINE_expectedresults.2=%WINE_CURDIR%\bar\.set WINE_expectedresults.3=%WINE_CURDIR%\baz\.set WINE_expectedresults.4=%WINE_CURDIR%\foo\.if "%CD%"=="" goto :SkipBrokenNT4call :SetExpectedfor /R "%WINE_CURDIR%" %%i in (.) do call temp.bat "%%i"call :ValidateExpected:SkipBrokenNT4
echo File enumerationset WINE_expectedresults=2set WINE_expectedresults.1=%WINE_CURDIR%\baz\bazbazset WINE_expectedresults.2=%WINE_CURDIR%\bazbazcall :SetExpectedfor /R %%i in (baz*) do call temp.bat "%%i"call :ValidateExpected
echo File enumeration from provided rootset WINE_expectedresults=2set WINE_expectedresults.1=%WINE_CURDIR%\baz\bazbazset WINE_expectedresults.2=%WINE_CURDIR%\bazbazcall :SetExpectedfor /R %%i in (baz*) do call temp.bat "%%i"call :ValidateExpected
echo Mixed enumerationset WINE_expectedresults=6set WINE_expectedresults.1=%WINE_CURDIR%\.set WINE_expectedresults.2=%WINE_CURDIR%\bar\.set WINE_expectedresults.3=%WINE_CURDIR%\baz\.set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbazset WINE_expectedresults.5=%WINE_CURDIR%\bazbazset WINE_expectedresults.6=%WINE_CURDIR%\foo\.call :SetExpectedfor /R %%i in (. baz*) do call temp.bat "%%i"call :ValidateExpected
echo Mixed enumeration from provided rootset WINE_expectedresults=6set WINE_expectedresults.1=%WINE_CURDIR%\.set WINE_expectedresults.2=%WINE_CURDIR%\bar\.set WINE_expectedresults.3=%WINE_CURDIR%\baz\.set WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbazset WINE_expectedresults.5=%WINE_CURDIR%\bazbazset WINE_expectedresults.6=%WINE_CURDIR%\foo\.call :SetExpectedfor /R %%i in (. baz*) do call temp.bat "%%i"call :ValidateExpected
echo With duplicates enumerationset WINE_expectedresults=12set WINE_expectedresults.1=%WINE_CURDIR%\bar\bazbazset WINE_expectedresults.2=%WINE_CURDIR%\bar\fredset WINE_expectedresults.3=%WINE_CURDIR%\baz\bazbazset WINE_expectedresults.4=%WINE_CURDIR%\baz\bazbazset WINE_expectedresults.5=%WINE_CURDIR%\baz\bazbazset WINE_expectedresults.6=%WINE_CURDIR%\baz\fredset WINE_expectedresults.7=%WINE_CURDIR%\bazbazset WINE_expectedresults.8=%WINE_CURDIR%\bazbazset WINE_expectedresults.9=%WINE_CURDIR%\bazbazset WINE_expectedresults.10=%WINE_CURDIR%\foo\bazbazset WINE_expectedresults.11=%WINE_CURDIR%\foo\fredset WINE_expectedresults.12=%WINE_CURDIR%\fredcall :SetExpectedfor /R %%i in (baz* bazbaz fred ba*) do call temp.bat "%%i"call :ValidateExpected
echo Strip missing wildcards, keep unwildcarded namesset WINE_expectedresults=6set WINE_expectedresults.1=%WINE_CURDIR%\bar\jimset WINE_expectedresults.2=%WINE_CURDIR%\baz\bazbazset WINE_expectedresults.3=%WINE_CURDIR%\baz\jimset WINE_expectedresults.4=%WINE_CURDIR%\bazbazset WINE_expectedresults.5=%WINE_CURDIR%\foo\jimset WINE_expectedresults.6=%WINE_CURDIR%\jimcall :SetExpectedfor /R %%i in (baz* fred* jim) do call temp.bat "%%i"call :ValidateExpected
echo for /R passedecho --- Complex wildcards unix and windows slashcd ..echo Windows slashes, valid pathfor %%f in (foobar\baz\bazbaz) do echo ASIS: %%ffor %%f in (foobar\baz\*) do echo WC : %%fecho Windows slashes, invalid pathfor %%f in (foobar\jim\bazbaz) do echo ASIS: %%ffor %%f in (foobar\jim\*) do echo WC : %%fecho Unix slashes, valid pathfor %%f in (foobar/baz/bazbaz) do echo ASIS: %%ffor %%f in (foobar/baz/*) do echo WC : %%fecho Unix slashes, invalid pathfor %%f in (foobar/jim/bazbaz) do echo ASIS: %%ffor %%f in (foobar/jim/*) do echo WC : %%fecho Donerd /s/Q foobarecho --- for /Lrem Some cases loop forever writing 0s, like e.g. (1,0,1), (1,a,3) or (a,b,c); those can't be tested herefor /L %%i in (1,2,0) do echo %%ifor@tab@/L %%i in (1,2,0) do echo %%ifor /L %%i in (1,2,6) do echo %%ifor /l %%i in (1 ,2,6) do echo %%ifor /L %%i in (a,2,3) do echo %%ifor /L %%i in (1,2,-1) do echo %%ifor /L %%i in (-4,-1,-1) do echo %%ifor /L %%i in (1,-2,-2) do echo %%ifor /L %%i in (1,2,a) do echo %%iecho ErrorLevel %ErrorLevel%for /L %%i in (1,a,b) do echo %%iecho ErrorLevel %ErrorLevel%rem Test boundariesfor /l %%i in (1,1,4) do echo %%ifor /l %%i in (1,2,4) do echo %%ifor /l %%i in (4,-1,1) do echo %%ifor /l %%i in (4,-2,1) do echo %%ifor /l %%i in (1,-1,4) do echo %%ifor /l %%i in (4,1,1) do echo %%ifor /L %%i in (a,2,b) do echo %%ifor /L %%i in (1,1,1) do echo %%ifor /L %%i in (1,-2,-1) do echo %%ifor /L %%i in (-1,-1,-1) do echo %%ifor /L %%i in (1,2, 3) do echo %%irem Test zero iteration skips the body of the forfor /L %%i in (2,2,1) do ( echo %%i echo FAILED)echo --- rems inside for loopsfor /f %%i IN ("hello") DO ( REM foo|echo ERROR unexpected execution 1 @REM foo|echo ERROR unexpected execution 2 @ REM foo|echo ERROR unexpected execution 3)echo --- ifs inside for loopsfor %%i in (test) do ( echo a1 if 1==1 ( echo b1 ) else ( echo c1 ) echo d1)for %%i in (test) do ( echo a2 if 1==1 ( echo b2 ) else echo c2 echo d2)for %%i in (test) do ( echo a3 if 1==0 ( echo b3 ) else echo c3 echo d3)for %%i in (test) do ( echo a4 if 1==0 ( echo b4 ) else ( echo c4 ) echo d4)echo --- set /agoto :testseta
Rem Ideally for /f can be used rather than building a command to executerem but that does not work on NT4:checkenvvarsif "%1"=="" goto :eofcall :executecmd set wine_result=%%%1%%if "%wine_result%"=="%2" ( echo %1 correctly %2) else echo ERROR: %1 incorrectly %wine_result% [%2]set %1=shiftshiftrem shiftgoto :checkenvvars:executecmd%*goto :eof
:testsetarem No output when using "set expr" syntax, unless in interactive moderem Need to use "set envvar=expr" to use in a batch scriptecho ------ individual operationsset WINE_foo=0set /a WINE_foo=1 +2 & call :checkenvvars WINE_foo 3set /a WINE_foo=1 +-2 & call :checkenvvars WINE_foo -1set /a WINE_foo=1 --2 & call :checkenvvars WINE_foo 3set /a WINE_foo=2* 3 & call :checkenvvars WINE_foo 6set /a WINE_foo=-2* -5 & call :checkenvvars WINE_foo 10set /a WINE_foo=12/3 & call :checkenvvars WINE_foo 4set /a WINE_foo=13/3 & call :checkenvvars WINE_foo 4set /a WINE_foo=-13/3 & call :checkenvvars WINE_foo -4rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructureset /a WINE_foo=5 %% 5 & call :checkenvvars WINE_foo 0set /a WINE_foo=5 %% 3 & call :checkenvvars WINE_foo 2set /a WINE_foo=5 %% -3 & call :checkenvvars WINE_foo 2set /a WINE_foo=-5 %% -3 & call :checkenvvars WINE_foo -2set /a WINE_foo=1 ^<^< 0 & call :checkenvvars WINE_foo 1set /a WINE_foo=1 ^<^< 2 & call :checkenvvars WINE_foo 4set /a WINE_foo=1 ^<^< -2 & call :checkenvvars WINE_foo 0set /a WINE_foo=-1 ^<^< -2 & call :checkenvvars WINE_foo 0set /a WINE_foo=-1 ^<^< 2 & call :checkenvvars WINE_foo -4set /a WINE_foo=9 ^>^> 0 & call :checkenvvars WINE_foo 9set /a WINE_foo=9 ^>^> 2 & call :checkenvvars WINE_foo 2set /a WINE_foo=9 ^>^> -2 & call :checkenvvars WINE_foo 0set /a WINE_foo=-9 ^>^> -2 & call :checkenvvars WINE_foo -1set /a WINE_foo=-9 ^>^> 2 & call :checkenvvars WINE_foo -3set /a WINE_foo=5 ^& 0 & call :checkenvvars WINE_foo 0set /a WINE_foo=5 ^& 1 & call :checkenvvars WINE_foo 1set /a WINE_foo=5 ^& 3 & call :checkenvvars WINE_foo 1set /a WINE_foo=5 ^& 4 & call :checkenvvars WINE_foo 4set /a WINE_foo=5 ^& 1 & call :checkenvvars WINE_foo 1set /a WINE_foo=5 ^| 0 & call :checkenvvars WINE_foo 5set /a WINE_foo=5 ^| 1 & call :checkenvvars WINE_foo 5set /a WINE_foo=5 ^| 3 & call :checkenvvars WINE_foo 7set /a WINE_foo=5 ^| 4 & call :checkenvvars WINE_foo 5set /a WINE_foo=5 ^| 1 & call :checkenvvars WINE_foo 5set /a WINE_foo=5 ^^ 0 & call :checkenvvars WINE_foo 5set /a WINE_foo=5 ^^ 1 & call :checkenvvars WINE_foo 4set /a WINE_foo=5 ^^ 3 & call :checkenvvars WINE_foo 6set /a WINE_foo=5 ^^ 4 & call :checkenvvars WINE_foo 1set /a WINE_foo=5 ^^ 1 & call :checkenvvars WINE_foo 4echo ------ precedence and groupingset /a WINE_foo=4 + 2*3 & call :checkenvvars WINE_foo 10set /a WINE_foo=(4+2)*3 & call :checkenvvars WINE_foo 18set /a WINE_foo=4 * 3/5 & call :checkenvvars WINE_foo 2set /a WINE_foo=(4 * 3)/5 & call :checkenvvars WINE_foo 2set /a WINE_foo=4 * 5 %% 4 & call :checkenvvars WINE_foo 0set /a WINE_foo=4 * (5 %% 4) & call :checkenvvars WINE_foo 4set /a WINE_foo=3 %% (5 + 8 %% 3 ^^ 2) & call :checkenvvars WINE_foo 3set /a WINE_foo=3 %% (5 + 8 %% 3 ^^ -2) & call :checkenvvars WINE_foo 3echo ------ octal and hexadecimalset /a WINE_foo=0xf + 3 & call :checkenvvars WINE_foo 18set /a WINE_foo=0xF + 3 & call :checkenvvars WINE_foo 18set /a WINE_foo=015 + 2 & call :checkenvvars WINE_foo 15set /a WINE_foo=3, 8+3,0 & call :checkenvvars WINE_foo 3echo ------ variablesset /a WINE_foo=WINE_bar=3, WINE_bar+1 & call :checkenvvars WINE_foo 3 WINE_bar 3set /a WINE_foo=WINE_bar=3, WINE_bar+=1 & call :checkenvvars WINE_foo 3 WINE_bar 4set /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 4set WINE_bar=3set /a WINE_foo=WINE_bar*= WINE_bar & call :checkenvvars WINE_foo 9 WINE_bar 9set /a WINE_foo=WINE_whateverNonExistingVar & call :checkenvvars WINE_foo 0set WINE_bar=4set /a WINE_foo=WINE_whateverNonExistingVar + WINE_bar & call :checkenvvars WINE_foo 4 WINE_bar 4set WINE_bar=4set /a WINE_foo=WINE_bar -= WINE_bar + 7 & call :checkenvvars WINE_foo -7 WINE_bar -7set WINE_bar=-7set /a WINE_foo=WINE_bar /= 3 + 2 & call :checkenvvars WINE_foo -1 WINE_bar -1set /a WINE_foo=WINE_bar=5, WINE_bar %%=2 & call :checkenvvars WINE_foo 5 WINE_bar 1set WINE_bar=1set /a WINE_foo=WINE_bar ^<^<= 2 & call :checkenvvars WINE_foo 4 WINE_bar 4set WINE_bar=4set /a WINE_foo=WINE_bar ^>^>= 2 & call :checkenvvars WINE_foo 1 WINE_bar 1set WINE_bar=1set /a WINE_foo=WINE_bar ^&= 2 & call :checkenvvars WINE_foo 0 WINE_bar 0set /a WINE_foo=WINE_bar=5, WINE_bar ^|= 2 & call :checkenvvars WINE_foo 5 WINE_bar 7set /a WINE_foo=WINE_bar=5, WINE_bar ^^= 2 & call :checkenvvars WINE_foo 5 WINE_bar 7set WINE_baz=4set /a WINE_foo=WINE_bar=19, WINE_bar %%= 4 + (WINE_baz %%= 7) & call :checkenvvars WINE_foo 19 WINE_bar 3 WINE_baz 4echo --- quotesset /a WINE_foo=1call :checkenvvars WINE_foo 1set /a "WINE_foo=1"call :checkenvvars WINE_foo 1set /a WINE_foo=1,WINE_bar=2call :checkenvvars WINE_foo 1 WINE_bar 2set /a "WINE_foo=1,WINE_bar=2"call :checkenvvars WINE_foo 1 WINE_bar 2set /a "WINE_foo=1","WINE_bar=2"call :checkenvvars WINE_foo 1 WINE_bar 2set /a ""WINE_foo=1","WINE_bar=2""call :checkenvvars WINE_foo 1 WINE_bar 2set /a WINE_foo=1,WINE_bar=2,WINE_baz=3call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3set /a "WINE_foo=1,WINE_bar=2,WINE_baz=3"call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3set /a "WINE_foo=1","WINE_bar=2","WINE_baz=3"call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3set /a ""WINE_foo=1","WINE_bar=2","WINE_baz=3""call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3set /a ""WINE_foo=1","WINE_bar=2"","WINE_baz=3"call :checkenvvars WINE_foo 1 WINE_bar 2 WINE_baz 3set /a """"""WINE_foo=1""""""call :checkenvvars WINE_foo 1set /a """"""WINE_foo=1","WINE_bar=5""","WINE_baz=2""call :checkenvvars WINE_foo 1 WINE_bar 5 WINE_baz 2set /a WINE_foo="3"+"4"+"5+6"call :checkenvvars WINE_foo 18set WINE_foo=3set /a WINE_bar="WINE_""foo"+4call :checkenvvars WINE_foo 3 WINE_bar 7echo --- whitespace are ignored between double char operatorsset WINE_foo=4set WINE_bar=5set /a WINE_foo + = 6set /a WINE_bar * = WINE_foocall :checkenvvars WINE_foo 10 WINE_bar 50set WINE_foo=4set WINE_bar=5set /a WINE_foo + = "6 < < 7"set /a WINE_bar * = WINE_foo + WINE_foocall :checkenvvars WINE_foo 772 WINE_bar 7720set /a WINE_foo=6 7set /a WINE_ var1=8set WINE_foo=echo --- invalid operator sequenceset WINE_foo=4set /a =4set /a *=4set /a ^>=4"set /a ^<=4"set /a WINE_foo^>^<=4echo %WINE_foo%set /a WINE_foo^>^>^>=4echo %WINE_foo%echo ----- negative prefixset /a WINE_foo=-1call :checkenvvars WINE_foo -1set /a WINE_foo=--1call :checkenvvars WINE_foo 1set /a WINE_foo=3--3call :checkenvvars WINE_foo 6set /a WINE_foo=3---3call :checkenvvars WINE_foo 0set /a WINE_foo=3----3call :checkenvvars WINE_foo 6set /a WINE_foo=-~1call :checkenvvars WINE_foo 2set /a WINE_foo=~-1call :checkenvvars WINE_foo 0set /a WINE_foo=3+-~1call :checkenvvars WINE_foo 5set /a WINE_foo=3+~-1call :checkenvvars WINE_foo 3echo ----- assignment tests involving the end destinationset WINE_foo=3set /a WINE_foo+=3+(WINE_foo=4)call :checkenvvars WINE_foo 11set WINE_foo=2set /a WINE_bar=3+(WINE_foo=6)call :checkenvvars WINE_foo 6 WINE_bar 9set WINE_foo=2set /a WINE_bar=3+(WINE_foo=6,WINE_baz=7)call :checkenvvars WINE_foo 6 WINE_bar 10 WINE_baz 7set WINE_foo=2set /a WINE_bar=WINE_foo=7call :checkenvvars WINE_foo 7 WINE_bar 7echo ----- equal precedence on stackrem Unary - don't reduce if precedence is equalset /a WINE_foo=!!1call :checkenvvars WINE_foo 1set /a WINE_foo=!!0call :checkenvvars WINE_foo 0set /a WINE_foo=~~1call :checkenvvars WINE_foo 1set /a WINE_foo=~~0call :checkenvvars WINE_foo 0set /a WINE_foo=--1call :checkenvvars WINE_foo 1set /a WINE_foo=+-1call :checkenvvars WINE_foo -1set /a WINE_foo=-+1call :checkenvvars WINE_foo -1set /a WINE_foo=++1call :checkenvvars WINE_foo 1set /a WINE_foo=!~1call :checkenvvars WINE_foo 0set /a WINE_foo=~!1call :checkenvvars WINE_foo -1set /a WINE_foo=!-1call :checkenvvars WINE_foo 0set /a WINE_foo=-!1call :checkenvvars WINE_foo 0set /a WINE_foo=!-0call :checkenvvars WINE_foo 1set /a WINE_foo=-!0call :checkenvvars WINE_foo -1rem Aritmatic - Reduce if precedence is equalset /a WINE_foo=10*5/2call :checkenvvars WINE_foo 25set /a WINE_foo=5/2*10call :checkenvvars WINE_foo 20set /a WINE_foo=10/5/2call :checkenvvars WINE_foo 1set /a WINE_foo=5%%2*4call :checkenvvars WINE_foo 4set /a WINE_foo=10-5+2call :checkenvvars WINE_foo 7set /a WINE_foo=1^<^<4^>^>1call :checkenvvars WINE_foo 8rem Assignment - don't reduce if precedence is equalset /a WINE_foo=5set /a WINE_bar=WINE_foo=6call :checkenvvars WINE_foo 6 WINE_bar 6
echo --- for /Fmkdir foobar & cd foobarecho ------ string argumentrem NT4 does not support usebackqfor /F %%i in ("a b c") do echo %%ifor /F %%i in ( "a b c" ) do echo X%%iXfor /f usebackq %%i in ('a b c') do echo %%i>output_fileif not exist output_file (echo no output) else (type output_file & del output_file)for /f usebackq %%i in ( 'a b c' ) do echo X%%iX>output_fileif not exist output_file (echo no output) else (type output_file & del output_file)for /f %%i in ("a ") do echo %%ifor /f usebackq %%i in ('a ') do echo %%i>output_fileif not exist output_file (echo no output) else (type output_file & del output_file)for /f %%i in ("a") do echo %%ifor /f usebackq %%i in ('a') do echo %%i>output_fileif not exist output_file (echo no output) else (type output_file & del output_file)fOr /f %%i in (" a") do echo %%ifor /f usebackq %%i in (' a') do echo %%i>output_fileif not exist output_file (echo no output) else (type output_file & del output_file)for /f %%i in (" a ") do echo %%ifor /f usebackq %%i in (' a ') do echo %%i>output_fileif not exist output_file (echo no output) else (type output_file & del output_file)echo ------ fileset argumentecho --------- basic blank handlingecho a b c>foofor /f %%i in (foo) do echo %%iecho a >foofor /f %%i in (foo) do echo %%iecho a>foofor /f %%i in (foo) do echo %%iecho a>foofor /f %%i in (foo) do echo %%iecho a >foofor /f %%i in (foo) do echo %%iecho. > foofor /f %%i in (foo) do echo %%iecho. >> fooecho b > foofor /f %%i in (foo) do echo %%iecho --------- multi-line with empty linesecho a Z f> fooecho. >> fooecho.>> fooecho b bC>> fooecho c>> fooecho. >> foofor /f %%b in (foo) do echo %%becho --------- multiple filesecho q w > barecho.>> barecho kkk>>barfor /f %%k in (foo bar) do echo %%kfor /f %%k in (bar foo) do echo %%kecho ------ command argumentrem Not implemented on NT4, need to skip it as no way to get output otherwiseif "%CD%"=="" goto :SkipFORFcmdNT4for /f %%i in ('echo.Passed1') do echo %%ifor /f "usebackq" %%i in (`echo.Passed2`) do echo %%ifor /f usebackq %%i in (`echo.Passed3`) do echo %%ifor /f "usebackq" %%i in (`"c:\windows\system32\cmd.exe" /C echo Passed4`) do echo %%ifor /f "usebackq" %%i in (`""c:\windows\system32\cmd.exe" /C echo Passed5"`) do echo %%ifor /f %%i in ( 'echo.Passed6' ) do echo %%ifor /f "usebackq" %%i in ( `echo.Passed7` ) do echo %%igoto :ContinueFORF:SkipFORFcmdNT4for /l %%i in (1,1,7) do echo Missing functionality - Broken%%i:ContinueFORFrem FIXME: Rest not testable right now in wine: not implemented and would needrem preliminary grep-like program implementation (e.g. like findstr or fc) evenrem for a simple todo_wine testrem (for /f "usebackq" %%i in (`echo z a b`) do echo %%i) || echo not supportedrem (for /f usebackq %%i in (`echo z a b`) do echo %%i) || echo not supportedecho ------ eol optionif "%CD%"=="" goto :SkipFORFeolNT4echo Line one>fooecho and Line two>>fooecho Line three>>foofor /f "eol=L" %%i in (foo) do echo %%ifor /f "eol=a" %%i in (foo) do echo %%idel foogoto :ContinueFORFeol:SkipFORFeolNT4for /l %%i in (1,1,3) do echo Broken NT4 functionality%%i:ContinueFORFeolfor /f "eol=@" %%i in (" ad") do echo %%ifor /f "eol=@" %%i in (" z@y") do echo %%ifor /f "eol=|" %%i in ("a|d") do echo %%ifor /f "eol=@" %%i in ("@y") do echo %%i > output_fileif not exist output_file (echo no output) else (del output_file)for /f "eol==" %%i in ("=y") do echo %%i > output_fileif not exist output_file (echo no output) else (del output_file)echo ------ delims optionfor /f "delims=|" %%i in ("a|d") do echo %%ifor /f "delims=|" %%i in ("a |d") do echo %%ifor /f "delims=|" %%i in ("a d|") do echo %%ifor /f "delims=| " %%i in ("a d|") do echo %%ifor /f "delims==" %%i in ("C r=d|") do echo %%ifor /f "delims=" %%i in ("foo bar baz") do echo %%ifor /f "delims=" %%i in ("c:\foo bar baz\..") do echo %%~fiecho ------ skip optionecho a > fooecho b >> fooecho c >> foofor /f "skip=2" %%i in (foo) do echo %%ifor /f "skip=3" %%i in (foo) do echo %%i > output_fileif not exist output_file (echo no output) else (del output_file)for /f "skip=4" %%i in (foo) do echo %%i > output_fileif not exist output_file (echo no output) else (del output_file)for /f "skip=02" %%i in (foo) do echo %%ifor /f "skip=0x2" %%i in (foo) do echo %%ifor /f "skip=1" %%i in ("skipme") do echo %%i > output_fileif not exist output_file (echo no output) else (del output_file)echo ------ tokens= optionrem Basicfor /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=%%ofor /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=%%ofor /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=%%orem Show * means the restfor /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=%%ofor /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=%%orem Show * means the rest (not tokenized and rebuilt)for /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=%%orem Order is irrelevantfor /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=%%ofor /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=%%orem Duplicates are ignoredfor /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=%%orem Large tokens are allowedfor /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=%%orem Show tokens blanked in advance regardless of uniqueness of requested tokensfor /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=%%ofor /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=%%orem Show No wrapping from z to A BUT wrapping sort of occurs Z to a occursfor /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=%%afor /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=%%arem Show negative ranges have no effectfor /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=%%ofor /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=%%orem Show duplicates stop * from workingfor /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=%%ofor /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=%%ofor /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=%%ofor /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=%%orem Special case tokens=* or tokens=n,*echo 3.14>testfileFOR /F "tokens=*" %%A IN (testfile) DO @echo 1:%%A,%%BFOR /F "tokens=1*" %%A IN (testfile) DO @echo 2:%%A,%%BFOR /F "tokens=2*" %%A IN (testfile) DO @echo 3:%%A,%%BFOR /F "tokens=1,* delims=." %%A IN (testfile) DO @echo 4:%%A,%%Bdel testfilecd ..rd /s/q foobarecho ------ parameter splittingecho forFParameterSplittingFunc "myparam1=myvalue1 myparam2=myparam2" mytest> foofor /f "tokens=1 delims=;" %%i in (foo) do (call :%%i)del foofor /f "tokens=1 delims=;" %%i in ("forFParameterSplittingFunc "myparam1^=myvalue1 myparam2^=myparam2" mytest") do (call :%%i)goto :forFParameterSplittingEnd:forFParameterSplittingFuncecho %~0 %~1 %~2 %~3 %~4 %~5goto :eof:forFParameterSplittingEndecho 3.14>testfileFOR /F "delims=. tokens=*" %%A IN (testfile) DO @echo 4:%%A,%%BFOR /F "delims=. tokens=1*" %%A IN (testfile) DO @echo 5:%%A,%%BFOR /F "delims=. tokens=2*" %%A IN (testfile) DO @echo 6:%%A,%%BFOR /F "delims=. tokens=3*" %%A IN (testfile) DO @echo 7:%%A,%%Bdel testfile
echo ------------ Testing del ------------echo abc > fileecho deleting 'file'del fileif errorlevel 0 ( echo errorlevel is 0, good) else ( echo unexpected errorlevel, got %errorlevel%)if not exist file ( echo successfully deleted 'file') else ( echo error deleting 'file')echo attempting to delete 'file', even though it is not presentdel fileif errorlevel 0 ( echo errorlevel is 0, good) else ( echo unexpected errorlevel, got %errorlevel%)
echo ------------ Testing del /a ------------del /f/q *.test > nulecho r > r.testattrib +r r.testecho not-r > not-r.test
if not exist not-r.test echo not-r.test not found before delete, baddel /a:-r *.testif not exist not-r.test echo not-r.test not found after delete, good
if not exist r.test echo r.test not found before delete, badif exist r.test echo r.test found before delete, gooddel /a:r *.testif not exist r.test echo r.test not found after delete, goodif exist r.test echo r.test found after delete, bad
echo ------------ Testing del /q ------------mkdir del_q_dircd del_q_direcho abc > file1echo abc > file2.datrem If /q doesn't work, cmd will prompt and the test case should hangdel /q * > nulfor %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%afor %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%acd ..rmdir del_q_dir
echo ------------ Testing del /s ------------mkdir "foo bar"cd "foo bar"mkdir "foo:"echo hi > file1.datecho there > file2.datecho bub > file3.datecho bye > "file with spaces.dat"cd ..del /s file1.dat > nuldel file2.dat /s > nuldel "file3.dat" /s > nuldel "file with spaces.dat" /s > nulcd "foo bar"for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%ffor %%f in (1 2 3) do if exist file%%f.dat del file%%f.datif exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"if exist "file with spaces.dat" del "file with spaces.dat"rmdir "foo:"cd ..rmdir "foo bar"
echo ------------ Testing rename ------------mkdir foobar & cd foobarecho --- ren and rename are synonymousecho > foorename foo barif exist foo echo foo should be renamed!if exist bar echo foo renamed to barren bar fooif exist bar echo bar should be renamed!if exist foo echo bar renamed to fooecho --- name collisionecho foo>fooecho bar>barren foo bar 2> nultype footype barrem no-opren foo foomkdir bazren foo baz\abcecho --- rename read-only filesecho > file1attrib +r file1ren file1 file2if not exist file1 ( if exist file2 ( echo read-only file renamed )) else ( echo read-only file not renamed!)echo --- rename directoriesmkdir rep1ren rep1 rep2if not exist rep1 ( if exist rep2 ( echo dir renamed ))attrib +r rep2ren rep2 rep1if not exist rep2 ( if exist rep1 ( echo read-only dir renamed ))echo --- rename in other directoryif not exist baz\abc ( echo rename impossible in other directory if exist foo echo original file still present) else ( echo shouldn't rename in other directory! if not exist foo echo original file not present anymore)cd .. & rd /s/q foobar
echo ------------ Testing move ------------mkdir foobar & cd foobarecho --- file moveecho >foomove foo bar > nul 2>&1if not exist foo ( if exist bar ( echo file move succeeded ))echo bar>barecho baz> bazmove /Y bar baz > nul 2>&1if not exist bar ( if exist baz ( echo file move with overwrite succeeded )) else ( echo file overwrite impossible! del bar)type baz
attrib +r bazmove baz bazro > nul 2>&1if not exist baz ( if exist bazro ( echo read-only files are moveable move bazro baz > nul 2>&1 )) else ( echo read-only file not moved!)attrib -r bazmkdir repmove baz rep > nul 2>&1if not exist baz ( if exist rep\baz ( echo file moved in subdirectory ))call :setError 0move rep\baz . > nul 2>&1move /Y baz baz > nul 2>&1if errorlevel 1 ( echo moving a file to itself should be a no-op!) else ( echo moving a file to itself is a no-op)echo ErrorLevel: %ErrorLevel%call :setError 0del bazecho --- directory movemkdir foo\barmkdir bazecho baz2>baz\baz2move baz foo\bar > nul 2>&1if not exist baz ( if exist foo\bar\baz\baz2 ( echo simple directory move succeeded ))call :setError 0mkdir bazmove baz baz > nul 2>&1echo moving a directory to itself gives error; errlevel %ErrorLevel%echo ------ dir in dir moverd /s/q foomkdir foo barecho foo2>foo\foo2echo bar2>bar\bar2move foo bar > nul 2>&1if not exist foo ( if exist bar ( dir /b /ad bar dir /b /a-d bar dir /b bar\foo ))cd .. & rd /s/q foobar
echo ------------ Testing mkdir ------------call :setError 0echo --- md and mkdir are synonymousmkdir foobarecho %ErrorLevel%rmdir foobarmd foobarecho %ErrorLevel%rmdir foobarecho --- creating an already existing directory/file must failmkdir foobarmd foobarecho %ErrorLevel%rmdir foobarecho > foobarmkdir foobarecho %ErrorLevel%del foobarecho --- multilevel path creationmkdir fooecho %ErrorLevel%mkdir foo\bar\bazecho %ErrorLevel%cd fooecho %ErrorLevel%cd barecho %ErrorLevel%cd bazecho %ErrorLevel%echo > ..\..\bar2mkdir ..\..\..\foo\bar2echo %ErrorLevel%del ..\..\bar2mkdir ..\..\..\foo\bar2echo %ErrorLevel%rmdir ..\..\..\foo\bar2cd ..rmdir bazcd ..rmdir barcd ..rmdir fooecho %ErrorLevel%echo --- trailing backslashesmkdir foo\\\\echo %ErrorLevel%if exist foo (rmdir foo & echo dir created) else ( echo dir not created )echo %ErrorLevel%echo --- invalid charsmkdir ?echo mkdir ? gives errorlevel %ErrorLevel%call :setError 0mkdir ?\fooecho mkdir ?\foo gives errorlevel %ErrorLevel%call :setError 0mkdir foo\?echo mkdir foo\? gives errorlevel %ErrorLevel%if exist foo (rmdir foo & echo ok, foo created) else ( echo foo not created )call :setError 0mkdir foo\bar\?echo mkdir foo\bar\? gives errorlevel %ErrorLevel%call :setError 0if not exist foo ( echo bad, foo not created) else ( cd foo if exist bar ( echo ok, foo\bar created rmdir bar ) cd .. rmdir foo)echo --- multiple directories at oncemkdir foobaz & cd foobazmkdir foo bar\baz foobar "bazbaz" .\"zabzab"if exist foo (echo foo created) else echo foo not created!if exist bar (echo bar created) else echo bar not created!if exist foobar (echo foobar created) else echo foobar not created!if exist bar\baz (echo bar\baz created) else echo bar\baz not created!if exist bazbaz (echo bazbaz created) else echo bazbaz not created!if exist zabzab (echo zabzab created) else echo zabzab not created!cd .. & rd /s/q foobazcall :setError 0mkdir foo\*echo mkdir foo\* errorlevel %ErrorLevel%if exist foo (rmdir foo & echo ok, foo created) else ( echo bad, foo not created )
echo ------------ Testing rmdir ------------call :setError 0rem rd and rmdir are synonymousmkdir foobarrmdir foobarecho %ErrorLevel%if not exist foobar echo dir removedmkdir foobarrd foobarecho %ErrorLevel%if not exist foobar echo dir removedrem Removing nonexistent directoryrmdir foobarecho %ErrorLevel%rem Removing single-level directoriesecho > foormdir fooecho %ErrorLevel%if exist foo echo file not removeddel foomkdir fooecho > foo\barrmdir fooecho %ErrorLevel%if exist foo echo non-empty dir not removeddel foo\barmkdir foo\barrmdir fooecho %ErrorLevel%if exist foo echo non-empty dir not removedrmdir foo\barrmdir foorem Recursive rmdirmkdir foo\bar\bazrmdir /s /Q fooif not exist foo ( echo recursive rmdir succeeded) else ( rd foo\bar\baz rd foo\bar rd foo)mkdir foo\bar\bazecho foo > foo\bar\brolrmdir /s /Q foo 2>&1if not exist foo ( echo recursive rmdir succeeded) else ( rd foo\bar\baz del foo\bar\brol rd foo\bar rd foo)rem multiples directories at oncemkdir foobaz & cd foobazmkdir foomkdir bar\bazmkdir foobarrd /s/q foo bar foobarif not exist foo (echo foo removed) else echo foo not removed!if not exist bar (echo bar removed) else echo bar not removed!if not exist foobar (echo foobar removed) else echo foobar not removed!if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!cd .. & rd /s/q foobaz
echo ------------ Testing pushd/popd ------------cdecho --- popd is no-op when dir stack is emptypopdcdecho --- pushing non-existing dirpushd foobarcdecho --- basic behaviourmkdir foobar\bazpushd foobarcdpopdcdpushd foobarpushd bazcdpopdcdpushd bazpopdcdpopdcdpushd .cd foobar\bazpushd ..cdpopdpopdcdrd /s/q foobar
echo ------------ Testing attrib ------------rem FIXME Add tests for archive, hidden and system attributes + mixed attributes modificationsmkdir foobar & cd foobarecho foo original contents> fooattrib fooecho > barecho --- read-only attributerem Read-only files cannot be altered or deleted, unless forcedattrib +R fooattrib foodir /Ar /Becho bar>> footype foodel foo > NUL 2>&1if exist foo ( echo Read-only file not deleted) else ( echo Should not delete read-only file!)del /F fooif not exist foo ( echo Read-only file forcibly deleted) else ( echo Should delete read-only file with del /F! attrib -r foo del foo)cd .. & rd /s/q foobarecho --- recursive behaviourmkdir foobar\baz & cd foobarecho > level1echo > whateverecho > baz\level2attrib baz\level2cd ..attrib +R l*vel? /S > nul 2>&1cd foobarattrib level1attrib baz\level2echo > barattrib barcd .. & rd /s/q foobarecho --- folders processingmkdir foobarattrib foobarcd foobarmkdir bazecho toto> baz\totoattrib +r baz /s /d > nul 2>&1attrib bazattrib baz\totoecho lulu>>baz\tototype baz\totoecho > baz\lalarem Oddly windows allows file creation in a read-only directory...if exist baz\lala (echo file created in read-only dir) else echo file not createdcd .. & rd /s/q foobar
echo ------------ Testing assoc ------------rem Modifying associations requires some privileges...net session >nul 2>&1if errorlevel 1 goto :SkipAssoc
rem FIXME Can't test error messages in the current test system, so we have to use some kludgesrem FIXME Revise once || conditional execution is fixedmkdir foobar & cd foobarecho --- setting associationassoc .foo > baztype bazecho ---
assoc .foo=barassoc .foo
rem association set system-wideecho @echo off> tmp.cmdecho echo +++>> tmp.cmdecho assoc .foo>> tmp.cmdcmd /c tmp.cmd
echo --- resetting associationassoc .foo=assoc .foo > baztype bazecho ---
rem association removal set system-widecmd /c tmp.cmd > baztype bazecho ---cd .. & rd /s/q foobargoto ContinueFType:SkipAssocecho --- setting associationecho ---echo .foo=barecho .foo=barecho +++echo .foo=barecho --- resetting associationecho ---echo +++echo ---
:ContinueFTypeecho ------------ Testing ftype ------------rem Modifying associations requires some privileges...net session >nul 2>&1if errorlevel 1 goto :SkipFTyperem FIXME Can't test error messages in the current test system, so we have to use some kludgesrem FIXME Revise once || conditional execution is fixedmkdir foobar & cd foobarecho --- setting associationftype footype> baztype bazecho ---
ftype footype=foo_opencmdassoc .foo=footypeftype footype
rem association set system-wideecho @echo off> tmp.cmdecho echo +++>> tmp.cmdecho ftype footype>> tmp.cmdcmd /c tmp.cmd
echo --- resetting associationassoc .foo=
rem Removing a file type association doesn't work on XP due to a bug, so a workaround is neededsetlocal EnableDelayedExpansionset WINE_FOO=original valueftype footype=ftype footype > bazfor /F %%i in ('type baz') do (set WINE_FOO=buggyXP)rem Resetting actually works on wine/NT4, but is reported as failing due to the peculiar test (and non-support for EnabledDelayedExpansion)rem FIXME Revisit once a grep-like program like ftype is implementedrem (e.g. to check baz's size using dir /b instead)echo !WINE_FOO!
rem cleanup registryecho REGEDIT4> regCleanup.regecho.>> regCleanup.regecho [-HKEY_CLASSES_ROOT\footype]>> regCleanup.regregedit /s regCleanup.regset WINE_FOO=endlocalcd .. & rd /s/q foobargoto ContinueCall:SkipFTypeecho --- setting associationecho ---echo footype=foo_opencmdecho .foo=footypeecho footype=foo_opencmdecho +++echo footype=foo_opencmdecho --- resetting associationecho original value
:ContinueCallecho ------------ Testing CALL ------------mkdir foobar & cd foobarecho --- external scriptecho echo foo %%1> foo.cmdcall foocall foo.cmd 8echo echo %%1 %%2 > foo.cmdcall foo.cmd foocall foo.cmd foo barcall foo.cmd foo ""call foo.cmd "" barcall foo.cmd foo ''call foo.cmd '' bardel foo.cmd
echo --- internal routinescall :testRoutine :testRoutinegoto :endTestRoutine:testRoutineecho bar %1goto :eof:endTestRoutine
call :testRoutineArgs foocall :testRoutineArgs foo barcall :testRoutineArgs foo ""call :testRoutineArgs "" barcall :testRoutineArgs foo ''call :testRoutineArgs '' bargoto :endTestRoutineArgs:testRoutineArgsecho %1 %2goto :eof:endTestRoutineArgs
echo --- with builtinscall mkdir fooecho %ErrorLevel%if exist foo (echo foo created) else echo foo should exist!rmdir fooset WINE_FOOBAZ_VAR=foobazcall echo Should expand %WINE_FOOBAZ_VAR%set WINE_FOOBAZ_VAR=echo>batfilecall dir /becho>robinfileif 1==1 call del batfiledir /bif exist batfile echo batfile shouldn't existrem ... but not for 'if' or 'for'call if 1==1 echo bar 2> nulecho %ErrorLevel%call :setError 0call for %%i in (foo bar baz) do echo %%i 2> nulecho %ErrorLevel%rem First look for programs in the path before trying a builtinecho echo non-builtin dir> dir.cmdcall dir /bdel dir.cmdrem The below line equates to call (, which does nothing, then therem subsequent lines are executed.call ( echo Line one echo Line two)rem The below line equates to call if, which always fails, then therem subsequent lines are executed. Note cmd.exe swallows all linesrem starting with )call if 1==1 ( echo Get if) else ( echo ... and else!)call call call echo passedcd .. & rd /s/q foobar
echo ------------ Testing SHIFT ------------
call :shiftFun p1 p2 p3 p4 p5goto :endShiftFun
:shiftFunecho '%1' '%2' '%3' '%4' '%5'shiftecho '%1' '%2' '%3' '%4' '%5'shift@tab@ /1echo '%1' '%2' '%3' '%4' '%5'shift /2echo '%1' '%2' '%3' '%4' '%5'shift /-1echo '%1' '%2' '%3' '%4' '%5'shift /0echo '%1' '%2' '%3' '%4' '%5'goto :eof:endShiftFun
echo ------------ Testing cmd invocation ------------rem FIXME: only a stub ATMecho --- a batch file can delete itselfecho del foo.cmd>foo.cmdcmd /q /c foo.cmdif not exist foo.cmd ( echo file correctly deleted) else ( echo file should be deleted! del foo.cmd)echo --- a batch file can alter itselfecho echo bar^>foo.cmd>foo.cmdcmd /q /c foo.cmd > NUL 2>&1if exist foo.cmd ( type foo.cmd del foo.cmd) else ( echo file not created!)
echo ---------- Testing copymd foobar2cd foobar2rem Note echo adds 0x0d 0x0a on the end of the line in the fileecho AAA> file1echo BBBBBB> file2echo CCCCCCCCC> file3md dir1goto :testcopy
:CheckExistif exist "%1" ( echo Passed: Found expected %1) else ( echo Failed: Did not find expected %1)del /q "%1" >nul 2>&1shiftif not "%1"=="" goto :CheckExistgoto :eof
:CheckNotExistif not exist "%1" ( echo Passed: Did not find %1) else ( echo Failed: Unexpectedly found %1 del /q "%1" >nul 2>&1)shiftif not "%1"=="" goto :CheckNotExistgoto :eof
rem Note: No way to check file size on NT4 so skip the test:CheckFileSizeif not exist "%1" ( echo Failed: File missing when requested filesize check [%2] goto :ContinueFileSizeChecks)for %%i in (%1) do set WINE_filesize=%%~ziif "%WINE_filesize%"=="%2" ( echo Passed: file size check on %1 [%WINE_filesize%]) else ( if "%WINE_filesize%"=="%%~zi" ( echo Skipping file size check on NT4 ) else ( echo Failed: file size check on %1 [%WINE_filesize% != %2] )):ContinueFileSizeChecksshiftshiftif not "%1"=="" goto :CheckFileSizegoto :eof
:testcopy
rem -----------------------rem Simple single file copyrem -----------------------rem Simple single file copy, normally used syntaxcopy file1 dummy.file >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist dummy.file
rem Simple single file copy, destination supplied as two forms of directorycopy file1 dir1 >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist dir1\file1
copy file1 dir1\ >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist dir1\file1
rem Simple single file copy, destination supplied as fully qualified destinationcopy file1 dir1\file99 >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist dir1\file99
rem Simple single file copy, destination not suppliedcd dir1copy ..\file1 >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist file1cd ..
rem Simple single file copy, destination supplied as nonexistent directorycopy file1 dir2\ >nul 2>&1if not errorlevel 1 echo Incorrect errorlevelcall :CheckNotExist dir2 dir2\file1
rem -----------------------rem Wildcarded copyrem -----------------------rem Simple single file copy, destination supplied as two forms of directorycopy file? dir1 >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist dir1\file1 dir1\file2 dir1\file3
copy file* dir1\ >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist dir1\file1 dir1\file2 dir1\file3
rem Simple single file copy, destination not suppliedcd dir1copy ..\file*.* >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist file1 file2 file3cd ..
rem Simple wildcarded file copy, destination supplied as nonexistent directorycopy file? dir2\ >nul 2>&1if not errorlevel 1 echo Incorrect errorlevelcall :CheckNotExist dir2 dir2\file1 dir2\file2 dir2\file3
rem ------------------------------------------------rem Confirm overwrite works (cannot test prompting!)rem ------------------------------------------------copy file1 testfile >nul 2>&1copy /y file2 testfile >nul 2>&1call :CheckExist testfile
rem ------------------------------------------------rem Test concatenationrem ------------------------------------------------rem simple case, no wildcardscopy file1+file2 testfile >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist testfile
rem simple case, wildcards, no concatenationcopy file* testfile >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist testfile
rem simple case, wildcards, and concatenationecho ddddd > fredcopy file*+fred testfile >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist testfile
rem simple case, wildcards, and concatenationcopy fred+file* testfile >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist testfile
rem Calculate destination namecopy fred+file* dir1 >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist dir1\fred
rem Calculate destination namecopy fred+file* dir1\ >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist dir1\fred
rem Calculate destination name (none supplied)cd dir1copy ..\fred+..\file* >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist fred
copy ..\fr*+..\file1 >nul 2>&1if errorlevel 1 echo Incorrect errorlevelcall :CheckExist fredcd ..
rem ******************************************************************rem ASCII and BINARY testsrem Note: hard coded numbers deliberate because need to ensure whetherrem an additional EOF has been added or not. There is no way to handlerem EOFs in batch, so assume if a single byte appears, it's an EOF!rem ******************************************************************
rem Confirm original sizes of file1,2,3call :CheckFileSize file1 5 file2 8 file3 11
cd dir1
rem ----------------------------------------------rem Show concatenation defaults copy to ascii moderem ----------------------------------------------rem Simple default copy source to destination (should not append EOF 5)copy ..\file1 file1_default >nul 2>&1call :CheckFileSize file1_default 5
rem Simple binary copy source to destination (should not append EOF 5)copy /b ..\file1 file1_default2 >nul 2>&1call :CheckFileSize file1_default2 5
rem Simple ascii copy source to destination (should append EOF 5+1, 8+1, 11+1)copy /a ..\file1 file1_plus_eof >nul 2>&1call :CheckFileSize file1_plus_eof 6copy /a ..\file2 file2_plus_eof >nul 2>&1call :CheckFileSize file2_plus_eof 9copy /a ..\file3 file3_plus_eof >nul 2>&1call :CheckFileSize file3_plus_eof 12
rem Concat 2 files, ascii mode - (only one EOF on the end 5+8+1)copy /a ..\file1+..\file2 file12_plus_eof >nul 2>&1call :CheckFileSize file12_plus_eof 14
rem Concat 2 files, binary mode - (no EOF on the end 5+8)copy /b ..\file1+..\file2 file12_no_eof >nul 2>&1call :CheckFileSize file12_no_eof 13
rem Concat 2 files, default mode - (one EOF on the end 5+8+1)copy ..\file1+..\file2 file12_eof2 >nul 2>&1call :CheckFileSize file12_eof2 14
rem Test copying when destination is one of the sources.rem Concat file1+file2+file3 into file1, should produce file1+file2+file3 = 24copy /y ..\file? .\ >nul 2>&1copy /y /b file1+file2+file3 file1 >nul 2>&1call :CheckFileSize file1 24
rem Concat file1+file2+file3 into file2, should produce file1+file3 = 16copy /y ..\file? .\ >nul 2>&1copy /y /b file1+file2+file3 file2 >nul 2>&1call :CheckFileSize file2 16
rem Concat file1+file2+file3 into file3, should produce file1+file2 = 13copy /y ..\file? .\ >nul 2>&1copy /y /b file1+file2+file3 file3 >nul 2>&1call :CheckFileSize file3 13
rem --------------------------------------------------------------rem Show ascii source copy stops at first EOF, binary does the lotrem --------------------------------------------------------------copy file1_plus_eof /b file1_binary_srccopy /b >nul 2>&1call :CheckFileSize file1_binary_srccopy 6
copy file1_plus_eof /a file1_ascii_srccopy /b >nul 2>&1call :CheckFileSize file1_ascii_srccopy 5
rem --------------------------------------------------------------rem Show results of concatenating files (ending in EOFs) and /a /brem --------------------------------------------------------------
rem Default and ascii copy reads as ascii, stripping EOFs, so 6-1 + 9-1 + 12-1 + 1copy file1_plus_eof+file2_plus_eof+file3_plus_eof file123_default_copy >nul 2>&1call :CheckFileSize file123_default_copy 25copy /a file1_plus_eof+file2_plus_eof+file3_plus_eof file123_ascii_copy >nul 2>&1call :CheckFileSize file123_ascii_copy 25
rem In binary mode, we get 3 eofs, so 6 + 9 + 12 = 27copy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_binary_copy >nul 2>&1call :CheckFileSize file123_binary_copy 27
rem We can select which we want the eofs from by postfixing it with /a or /brem so here have first and third with eof, second as ascii 6 + 9-1 + 12copy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy1 >nul 2>&1call :CheckFileSize file123_mixed_copy1 26
rem By postfixing the destination with /a, we ask for an ascii destination which appends EOFrem so here have first and third with eof, second as ascii 6 + 9-1 + 12 + extra EOFrem Note the delta between this and the previous one also shows that the destinationrem ascii/binary is inherited from the last /a or /b on the linecopy file1_plus_eof /b + file2_plus_eof /a + file3_plus_eof /b file123_mixed_copy2 /a >nul 2>&1call :CheckFileSize file123_mixed_copy2 27
rem so here have second with eof, first and third as ascii 6-1 + 9 + 12-1rem Note the delta between the next two also shows that the destination ascii/binary isrem inherited from the last /a or /b on the line, so the first has an extra EOFcopy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy3 >nul 2>&1call :CheckFileSize file123_mixed_copy3 26copy file1_plus_eof /a + file2_plus_eof /b + file3_plus_eof /a file123_mixed_copy4 /b >nul 2>&1call :CheckFileSize file123_mixed_copy4 25
rem -------------------------------------------------------------------------------------------rem This shows when concatenating, an ascii destination always adds on an EOF but when werem are not concatenating, it's a direct copy regardless of destination if being read as binaryrem -------------------------------------------------------------------------------------------
rem All 3 have eof's, plus an extra = 6 + 9 + 12 + eofcopy /b file1_plus_eof + file2_plus_eof + file3_plus_eof file123_mixed_copy5 /a >nul 2>&1call :CheckFileSize file123_mixed_copy5 28
rem All 2 have eof's, plus an extra = 6 + 12 + eofcopy /b file1_plus_eof + file3_plus_eof file123_mixed_copy6 /a >nul 2>&1call :CheckFileSize file123_mixed_copy6 19
rem One file has EOF, but doesn't get an extra one, i.e. 6copy /b file1_plus_eof file123_mixed_copy7 /a >nul 2>&1call :CheckFileSize file123_mixed_copy7 6
rem Syntax means concatenate so ascii destination kicks incopy /b file1_plus_eof* file123_mixed_copy8 /a >nul 2>&1call :CheckFileSize file123_mixed_copy8 7
del *.* /qcd ..
rem ---------------------------------------rem Error combinationsrem ---------------------------------------rem Specify source directory but name is a filecall :setError 0copy file1\ dir1\ >NUL 2>&1if errorlevel 1 echo Passed: errorlevel invalid check 1if not errorlevel 1 echo Failed: errorlevel invalid check 1call :CheckNotExist dir1\file1
rem Overwrite same filecall :setError 0copy file1 file1 >NUL 2>&1if errorlevel 1 echo Passed: errorlevel invalid check 2if not errorlevel 1 echo Failed: errorlevel invalid check 2
rem Supply same file identified as a directorycall :setError 0copy file1 file1\ >NUL 2>&1if errorlevel 1 echo Passed: errorlevel invalid check 3if not errorlevel 1 echo Failed: errorlevel invalid check 3
cd ..rd foobar2 /s /q
echo ------------ Testing setlocal/endlocal ------------call :setError 0rem Note: setlocal EnableDelayedExpansion already tested in the variable delayed expansion test sectionmkdir foobar & cd foobarecho --- enable/disable extensionssetlocal DisableEXTensionsecho ErrLev: %ErrorLevel%endlocalecho ErrLev: %ErrorLevel%echo @echo off> tmp.cmdecho echo ErrLev: %%ErrorLevel%%>> tmp.cmdrem Enabled by defaultcmd /C tmp.cmdcmd /E:OfF /C tmp.cmdcmd /e:oN /C tmp.cmd
rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)echo --- setlocal with corresponding endlocalrem %CD% does not work on NT4 so use the following workaroundfor /d %%i in (.) do set WINE_CURDIR=%%~dpnxiecho @echo off> test.cmdecho echo %%WINE_VAR%%>> test.cmdecho setlocal>> test.cmdecho set WINE_VAR=localval>> test.cmdecho md foobar2>> test.cmdecho cd foobar2>> test.cmdecho echo %%WINE_VAR%%>> test.cmdecho for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmdecho endlocal>> test.cmdecho echo %%WINE_VAR%%>> test.cmdecho for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmdset WINE_VAR=globalvalcall test.cmdecho %WINE_VAR%for /d %%i in (.) do echo %%~dpnxicd /d %WINE_CURDIR%rd foobar2set WINE_VAR=echo --- setlocal with no corresponding endlocalecho @echo off> test.cmdecho echo %%WINE_VAR%%>> test.cmdecho setlocal>> test.cmdecho set WINE_VAR=localval>> test.cmdecho md foobar2>> test.cmdecho cd foobar2>> test.cmdecho echo %%WINE_VAR%%>> test.cmdecho for /d %%%%i in (.) do echo %%%%~dpnxi>> test.cmdset WINE_VAR=globalvalrem %CD% does not work on NT4 so use the following workaroundfor /d %%i in (.) do set WINE_CURDIR=%%~dpnxicall test.cmdecho %WINE_VAR%for /d %%i in (.) do echo %%~dpnxicd /d %WINE_CURDIR%rd foobar2set WINE_VAR=echo --- setlocal within same batch programset WINE_var1=oneset WINE_var2=set WINE_var3=rem %CD% does not work on NT4 so use the following workaroundfor /d %%i in (.) do set WINE_CURDIR=%%~dpnxisetlocalset WINE_var2=twomkdir foobar2cd foobar2setlocalset WINE_var3=threeif "%WINE_var1%"=="one" echo Var1 ok 1if "%WINE_var2%"=="two" echo Var2 ok 2if "%WINE_var3%"=="three" echo Var3 ok 3for /d %%i in (.) do set WINE_curdir2=%%~dpnxiif "%WINE_curdir2%"=="%WINE_CURDIR%\foobar2" echo Directory is ok 1endlocalif "%WINE_var1%"=="one" echo Var1 ok 1if "%WINE_var2%"=="two" echo Var2 ok 2if "%WINE_var3%"=="" echo Var3 ok 3for /d %%i in (.) do set WINE_curdir2=%%~dpnxiif "%WINE_curdir2%"=="%WINE_CURDIR%\foobar2" echo Directory is ok 2endlocalif "%WINE_var1%"=="one" echo Var1 ok 1if "%WINE_var2%"=="" echo Var2 ok 2if "%WINE_var3%"=="" echo Var3 ok 3for /d %%i in (.) do set WINE_curdir2=%%~dpnxiif "%WINE_curdir2%"=="%WINE_CURDIR%" echo Directory is ok 3rd foobar2 /s /qset WINE_var1=
echo --- Mismatched set and end localsmkdir foodir2 2>nulmkdir foodir3 2>nulmkdir foodir4 2>nulrem %CD% does not work on NT4 so use the following workaroundfor /d %%i in (.) do set WINE_curdir=%%~dpnxi
echo @echo off> 2set1end.cmdecho echo %%WINE_var%%>> 2set1end.cmdecho setlocal>> 2set1end.cmdecho set WINE_VAR=2set1endvalue1>> 2set1end.cmdecho cd ..\foodir3>> 2set1end.cmdecho setlocal>> 2set1end.cmdecho set WINE_VAR=2set1endvalue2>> 2set1end.cmdecho cd ..\foodir4>> 2set1end.cmdecho endlocal>> 2set1end.cmdecho echo %%WINE_var%%>> 2set1end.cmdecho for /d %%%%i in (.) do echo %%%%~dpnxi>> 2set1end.cmd
echo @echo off> 1set2end.cmdecho echo %%WINE_var%%>> 1set2end.cmdecho setlocal>> 1set2end.cmdecho set WINE_VAR=1set2endvalue1>> 1set2end.cmdecho cd ..\foodir3>> 1set2end.cmdecho endlocal>> 1set2end.cmdecho echo %%WINE_var%%>> 1set2end.cmdecho for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmdecho endlocal>> 1set2end.cmdecho echo %%WINE_var%%>> 1set2end.cmdecho for /d %%%%i in (.) do echo %%%%~dpnxi>> 1set2end.cmd
echo --- Extra setlocal in called batchset WINE_VAR=value1rem -- setlocal1 == this batch, should never be used inside a called routinesetlocalset WINE_var=value2cd foodir2call "%WINE_CURDIR%\2set1end.cmd"echo Finished:echo %WINE_VAR%for /d %%i in (.) do echo %%~dpnxiendlocalecho %WINE_VAR%for /d %%i in (.) do echo %%~dpnxicd /d %WINE_CURDIR%
echo --- Extra endlocal in called batchset WINE_VAR=value1rem -- setlocal1 == this batch, should never be used inside a called routinesetlocalset WINE_var=value2cd foodir2call "%WINE_CURDIR%\1set2end.cmd"echo Finished:echo %WINE_VAR%for /d %%i in (.) do echo %%~dpnxiendlocalecho %WINE_VAR%for /d %%i in (.) do echo %%~dpnxicd /d %WINE_CURDIR%
echo --- endlocal in called function rather than batch pgm is ineffective@echo offset WINE_var=1set WINE_var2=1setlocalset WINE_var=2call :endlocalroutineecho %WINE_var%endlocalecho %WINE_var%goto :endlocalfinished:endlocalroutineecho %WINE_var%endlocalecho %WINE_var%setlocalset WINE_var2=2endlocalecho %WINE_var2%endlocalecho %WINE_var%echo %WINE_var2%goto :eof:endlocalfinishedecho %WINE_var%
set WINE_var=set WINE_var2=cd .. & rd /q/s foobar
echo ------------ Testing Errorlevel ------------rem WARNING: Do *not* add tests using ErrorLevel after this sectionshould_not_exist 2> nul > nulecho %ErrorLevel%rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weakrem See http://www.robvanderwoude.com/exit.phpcall :setError 1echo %ErrorLevel%if errorlevel 2 echo errorlevel too high, badif errorlevel 1 echo errorlevel just right, goodif errorlevel 01 echo errorlevel with leading zero just right, goodif errorlevel -1 echo errorlevel with negative number OKif errorlevel 0x1 echo hexa should not be recognized!if errorlevel 1a echo invalid error level recognized!call :setError 0echo abc%ErrorLevel%defif errorlevel 1 echo errorlevel nonzero, badif not errorlevel 1 echo errorlevel zero, goodif not errorlevel 0x1 echo hexa should not be recognized!if not errorlevel 1a echo invalid error level recognized!rem Now verify that setting a real variable hides its magic variableset errorlevel=7echo %ErrorLevel% should be 7if errorlevel 7 echo setting var worked too well, badcall :setError 3echo %ErrorLevel% should still be 7
echo ------------ Testing GOTO ------------if a==a goto dest1echo FAILURE at dest 1:dest1echo goto with no leading space workedif a==a goto :dest1becho FAILURE at dest 1b:dest1becho goto with colon and no leading space workedif b==b goto dest2echo FAILURE at dest 2 :dest2echo goto with a leading space workedif c==c goto dest3echo FAILURE at dest 3 :dest3echo goto with a leading tab workedif d==d goto dest4echo FAILURE at dest 4:dest4@space@echo goto with a following space workedif e==e goto dest5echo FAILURE at dest 5:dest5&& echo FAILUREecho goto with following amphersands worked
del failure.txt >nul 2>&1if f==f goto dest6echo FAILURE at dest 6:dest6>FAILURE.TXTif exist FAILURE.TXT echo FAILURE at dest 6 as file existsecho goto with redirections workeddel FAILURE.TXT >nul 2>&1
:: some text that is ignored | dir >cmd_output | another testif exist cmd_output echo FAILURE at dest 6 as file existsecho Ignoring double colons workeddel cmd_output >nul 2>&1
rem goto a label which does not exist issues an error message andrem acts the same as goto :EOF, and ensure ::label is never matcheddel testgoto.bat >nul 2>&1echo goto :dest7 ^>nul 2^>^&1 >> testgoto.batecho echo FAILURE at dest 7 - Should have not found label and issued an error plus ended the batch>> testgoto.batecho ::dest7>> testgoto.batecho echo FAILURE at dest 7 - Incorrectly went to label >> testgoto.batcall testgoto.batdel testgoto.bat >nul 2>&1
del testgoto.bat >nul 2>&1echo goto ::dest8 ^>nul 2^>^&1 >> testgoto.batecho echo FAILURE at dest 8 - Should have not found label and issued an error plus ended the batch>> testgoto.batecho ::dest8>> testgoto.batecho echo FAILURE at dest 8 - Incorrectly went to label >> testgoto.batcall testgoto.batdel testgoto.bat >nul 2>&1
if g==g goto dest9echo FAILURE at dest 9:dest91echo FAILURE at dest 91@ : dest9>rubbishecho label with mixed whitespace and no echo worked
if h==h goto :dest10:this is ignoredecho FAILURE at dest 10:dest10:this is also ignoredecho Correctly ignored trailing information
rem Testing which label is reached when there are many optionsecho Begin:set nextlabel=call :subset nextlabel=middlegoto :sub
:subecho ..First subif not "%nextlabel%"=="" goto :%nextlabel%goto :EOF
:subecho ..Second subif not "%nextlabel%"=="" goto :%nextlabel%goto :EOF
:middleecho Middle:set nextlabel=call :subset nextlabel=nearendgoto :sub
:subecho ..Third subif not "%nextlabel%"=="" goto :%nextlabel%goto :EOF
:nearendecho Near end:set nextlabel=call :subset nextlabel=endgoto :sub
:subecho ..Fourth subif not "%nextlabel%"=="" goto :%nextlabel%goto :EOF
:endecho At end:set nextlabel=call :subset nextlabel=donegoto :sub
:doneecho Finished
echo ------------ Testing PATH ------------set WINE_backup_path=%path%set path=originalpathpath try2pathpath=try3pathset path=%WINE_backup_path%set WINE_backup_path=
echo ------------ Testing start /W ------------echo start /W failed to wait>foobar.txtstart /W "" cmd /C "ping -n1 & echo start /W seems to really wait>foobar.txt"& type foobar.txt& del foobar.txt
echo ------------ Testing changing the drive letter ----------pushd C:\
echo Normal:call :setError 0C:if errorlevel 1 echo Normal drive change failed
echo Normal+spacecall :setError 0C:@space@if errorlevel 1 echo Normal+space drive change failed
echo Normal+space+garbagecall :setError 0C: garbageif errorlevel 1 echo Normal+space+garbage drive change failed
call :setError 0echo Quoted should fail"C:"if not errorlevel 1 echo quoted drive change unexpectedly worked
echo Normal+tabcall :setError 0C:@tab@if errorlevel 1 echo Normal+tab drive change failed
echo Normal+tab+garbagecall :setError 0C:@tab@garbagetabif errorlevel 1 echo Normal+tab+garbage drive change failed
popd
echo ------------ Testing combined CALLs/GOTOs ------------echo @echo off>foo.cmdecho goto :eof>>foot.cmdecho :eof>>foot.cmdecho echo world>>foo.cmd
echo @echo off>foot.cmdecho echo cheball>>foot.cmdecho.>>foot.cmdecho call :bar>>foot.cmdecho if "%%1"=="deleteMe" (del foot.cmd)>>foot.cmdecho goto :eof>>foot.cmdecho.>>foot.cmdecho :bar>>foot.cmdecho echo barbare>>foot.cmdecho goto :eof>>foot.cmd
call foo.cmdcall footcall :bardel foo.cmdrem Script execution stops after the following linefoot deleteMecall :foocall :footgoto :endFuns
:footecho foot
:fooecho foogoto :eof
:endFuns
:barecho barcall :foo
:bazecho bazgoto :eof
echo Final message is not output since earlier 'foot' processing stops script executionecho Do NOT add any tests below this line
echo ------------ Done, jumping to EOF -----------goto :eofrem Subroutine to set errorlevel and returnrem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported:setErrorexit /B %1rem This line runs under cmd in windows NT 4, but not in more modern versions.