cmCTest.cxx 148 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmCTest.h"
  14. #include "cmake.h"
  15. #include "cmMakefile.h"
  16. #include "cmLocalGenerator.h"
  17. #include "cmGlobalGenerator.h"
  18. #include <cmsys/Directory.hxx>
  19. #include "cmGlob.h"
  20. #include "cmDynamicLoader.h"
  21. #include "cmCTestSubmit.h"
  22. #include "curl/curl.h"
  23. #include <cmsys/RegularExpression.hxx>
  24. #include <cmsys/Process.h>
  25. #include <cmsys/Base64.h>
  26. #include <stdlib.h>
  27. #include <time.h>
  28. #include <math.h>
  29. #include <float.h>
  30. // needed for sleep
  31. #if !defined(_WIN32)
  32. # include <unistd.h>
  33. #endif
  34. #include <memory> // auto_ptr
  35. #define SAFEDIV(x,y) (((y)!=0)?((x)/(y)):(0))
  36. #define DEBUGOUT std::cout << __LINE__ << " "; std::cout
  37. #define DEBUGERR std::cerr << __LINE__ << " "; std::cerr
  38. // provide some more detailed info on the return code for ctest
  39. #define CTEST_UPDATE_ERRORS 0x01
  40. #define CTEST_CONFIGURE_ERRORS 0x02
  41. #define CTEST_BUILD_ERRORS 0x04
  42. #define CTEST_TEST_ERRORS 0x08
  43. #define CTEST_MEMORY_ERRORS 0x10
  44. static struct tm* GetNightlyTime(std::string str, bool tomorrowtag)
  45. {
  46. struct tm* lctime;
  47. time_t tctime = time(0);
  48. //Convert the nightly start time to seconds. Since we are
  49. //providing only a time and a timezone, the current date of
  50. //the local machine is assumed. Consequently, nightlySeconds
  51. //is the time at which the nightly dashboard was opened or
  52. //will be opened on the date of the current client machine.
  53. //As such, this time may be in the past or in the future.
  54. time_t ntime = curl_getdate(str.c_str(), &tctime);
  55. tctime = time(0);
  56. //std::cout << "Seconds: " << tctime << std::endl;
  57. if ( ntime > tctime )
  58. {
  59. // If nightlySeconds is in the past, this is the current
  60. // open dashboard, then return nightlySeconds. If
  61. // nightlySeconds is in the future, this is the next
  62. // dashboard to be opened, so subtract 24 hours to get the
  63. // time of the current open dashboard
  64. ntime -= ( 24 * 60 * 60 );
  65. //std::cout << "Pick yesterday" << std::endl;
  66. }
  67. //std::cout << "nightlySeconds: " << ntime << std::endl;
  68. if ( tomorrowtag )
  69. {
  70. std::cout << "Add a day" << std::endl;
  71. ntime += ( 24 * 60 * 60 );
  72. }
  73. lctime = gmtime(&ntime);
  74. return lctime;
  75. }
  76. static std::string CleanString(const std::string& str)
  77. {
  78. std::string::size_type spos = str.find_first_not_of(" \n\t\r\f\v");
  79. std::string::size_type epos = str.find_last_not_of(" \n\t\r\f\v");
  80. if ( spos == str.npos )
  81. {
  82. return std::string();
  83. }
  84. if ( epos != str.npos )
  85. {
  86. epos = epos - spos + 1;
  87. }
  88. return str.substr(spos, epos);
  89. }
  90. static std::string CurrentTime()
  91. {
  92. time_t currenttime = time(0);
  93. struct tm* t = localtime(&currenttime);
  94. //return ::CleanString(ctime(&currenttime));
  95. char current_time[1024];
  96. strftime(current_time, 1000, "%a %b %d %H:%M:%S %Z %Y", t);
  97. //std::cout << "Current_Time: " << current_time << std::endl;
  98. return ::CleanString(current_time);
  99. }
  100. static const char* cmCTestErrorMatches[] = {
  101. "^[Bb]us [Ee]rror",
  102. "^[Ss]egmentation [Vv]iolation",
  103. "^[Ss]egmentation [Ff]ault",
  104. "([^ :]+):([0-9]+): ([^ \\t])",
  105. "([^:]+): error[ \\t]*[0-9]+[ \\t]*:",
  106. "^Error ([0-9]+):",
  107. "^Fatal",
  108. "^Error: ",
  109. "^Error ",
  110. "[0-9] ERROR: ",
  111. "^\"[^\"]+\", line [0-9]+: [^Ww]",
  112. "^cc[^C]*CC: ERROR File = ([^,]+), Line = ([0-9]+)",
  113. "^ld([^:])*:([ \\t])*ERROR([^:])*:",
  114. "^ild:([ \\t])*\\(undefined symbol\\)",
  115. "([^ :]+) : (error|fatal error|catastrophic error)",
  116. "([^:]+): (Error:|error|undefined reference|multiply defined)",
  117. "([^:]+)\\(([^\\)]+)\\) : (error|fatal error|catastrophic error)",
  118. "^fatal error C[0-9]+:",
  119. ": syntax error ",
  120. "^collect2: ld returned 1 exit status",
  121. "Unsatisfied symbols:",
  122. "Undefined symbols:",
  123. "^Undefined[ \\t]+first referenced",
  124. "^CMake Error:",
  125. ":[ \\t]cannot find",
  126. ":[ \\t]can't find",
  127. ": \\*\\*\\* No rule to make target \\`.*\\'. Stop",
  128. ": Invalid loader fixup for symbol",
  129. ": internal link edit command failed",
  130. ": Unrecognized option \\`.*\\'",
  131. "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\([^W]\\)",
  132. "ld: 0706-006 Cannot find or open library file: -l ",
  133. "ild: \\(argument error\\) can't find library argument ::",
  134. "^could not be found and will not be loaded.",
  135. "make: Fatal error: ",
  136. 0
  137. };
  138. static const char* cmCTestErrorExceptions[] = {
  139. "instantiated from ",
  140. "candidates are:",
  141. ": warning",
  142. "makefile:",
  143. "Makefile:",
  144. ":[ \\t]+Where:",
  145. 0
  146. };
  147. static const char* cmCTestWarningMatches[] = {
  148. "([^ :]+):([0-9]+): warning:",
  149. "^cc[^C]*CC: WARNING File = ([^,]+), Line = ([0-9]+)",
  150. "^ld([^:])*:([ \\t])*WARNING([^:])*:",
  151. "([^:]+): warning ([0-9]+):",
  152. "^\"[^\"]+\", line [0-9]+: [Ww]arning",
  153. "([^:]+): warning[ \\t]*[0-9]+[ \\t]*:",
  154. "^Warning ([0-9]+):",
  155. "^Warning ",
  156. "WARNING: ",
  157. "([^ :]+) : warning",
  158. "([^:]+): warning",
  159. "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\(W\\)",
  160. 0
  161. };
  162. static const char* cmCTestWarningExceptions[] = {
  163. "/usr/openwin/include/X11/Xlib\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  164. "/usr/openwin/include/X11/Xutil\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  165. "/usr/openwin/include/X11/XResource\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  166. "WARNING 84 :",
  167. "WARNING 47 :",
  168. "makefile:",
  169. "Makefile:",
  170. "warning: Clock skew detected. Your build may be incomplete.",
  171. "/usr/openwin/include/GL/[^:]+:",
  172. "bind_at_load",
  173. "XrmQGetResource",
  174. "IceFlush",
  175. "warning LNK4089: all references to [^ \\t]+ discarded by .OPT:REF",
  176. "ld32: WARNING 85: definition of dataKey in",
  177. "cc: warning 422: Unknown option \"\\+b",
  178. "_with_warning_C",
  179. 0
  180. };
  181. static const char* cmCTestMemCheckResultStrings[] = {
  182. "ABR",
  183. "ABW",
  184. "ABWL",
  185. "COR",
  186. "EXU",
  187. "FFM",
  188. "FIM",
  189. "FMM",
  190. "FMR",
  191. "FMW",
  192. "FUM",
  193. "IPR",
  194. "IPW",
  195. "MAF",
  196. "MLK",
  197. "MPK",
  198. "NPR",
  199. "ODS",
  200. "PAR",
  201. "PLK",
  202. "UMC",
  203. "UMR",
  204. 0
  205. };
  206. static const char* cmCTestMemCheckResultLongStrings[] = {
  207. "ABR",
  208. "ABW",
  209. "ABWL",
  210. "COR",
  211. "EXU",
  212. "FFM",
  213. "FIM",
  214. "Mismatched deallocation",
  215. "FMR",
  216. "FMW",
  217. "FUM",
  218. "IPR",
  219. "IPW",
  220. "MAF",
  221. "Memory Leak",
  222. "Potential Memory Leak",
  223. "NPR",
  224. "ODS",
  225. "Invalid syscall param",
  226. "PLK",
  227. "Uninitialized Memory Conditional",
  228. "Uninitialized Memory Read",
  229. 0
  230. };
  231. std::string cmCTest::MakeXMLSafe(const std::string& str)
  232. {
  233. cmOStringStream ost;
  234. // By uncommenting the lcnt code, it will put newline every 120 characters
  235. //int lcnt = 0;
  236. for (std::string::size_type pos = 0; pos < str.size(); pos ++ )
  237. {
  238. unsigned char ch = str[pos];
  239. if ( (ch > 126 || ch < 32) && ch != 9 && ch != 10 && ch != 13 )
  240. {
  241. char buffer[33];
  242. sprintf(buffer, "&lt;%d&gt;", (int)ch);
  243. //sprintf(buffer, "&#x%0x;", (unsigned int)ch);
  244. ost << buffer;
  245. //lcnt += 4;
  246. }
  247. else
  248. {
  249. switch ( ch )
  250. {
  251. case '&': ost << "&amp;"; break;
  252. case '<': ost << "&lt;"; break;
  253. case '>': ost << "&gt;"; break;
  254. case '\n': ost << "\n";
  255. //lcnt = 0;
  256. break;
  257. default: ost << ch;
  258. }
  259. //lcnt ++;
  260. }
  261. //if ( lcnt > 120 )
  262. // {
  263. // ost << "\n";
  264. // lcnt = 0;
  265. // }
  266. }
  267. return ost.str();
  268. }
  269. std::string cmCTest::MakeURLSafe(const std::string& str)
  270. {
  271. cmOStringStream ost;
  272. char buffer[10];
  273. for ( std::string::size_type pos = 0; pos < str.size(); pos ++ )
  274. {
  275. unsigned char ch = str[pos];
  276. if ( ( ch > 126 || ch < 32 ||
  277. ch == '&' ||
  278. ch == '%' ||
  279. ch == '+' ||
  280. ch == '=' ||
  281. ch == '@'
  282. ) && ch != 9 )
  283. {
  284. sprintf(buffer, "%02x;", (unsigned int)ch);
  285. ost << buffer;
  286. }
  287. else
  288. {
  289. ost << ch;
  290. }
  291. }
  292. return ost.str();
  293. }
  294. bool TryExecutable(const char *dir, const char *file,
  295. std::string *fullPath, const char *subdir)
  296. {
  297. // try current directory
  298. std::string tryPath;
  299. if (dir && strcmp(dir,""))
  300. {
  301. tryPath = dir;
  302. tryPath += "/";
  303. }
  304. if (subdir && strcmp(subdir,""))
  305. {
  306. tryPath += subdir;
  307. tryPath += "/";
  308. }
  309. tryPath += file;
  310. if(cmSystemTools::FileExists(tryPath.c_str()))
  311. {
  312. *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
  313. return true;
  314. }
  315. tryPath += cmSystemTools::GetExecutableExtension();
  316. if(cmSystemTools::FileExists(tryPath.c_str()))
  317. {
  318. *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
  319. return true;
  320. }
  321. return false;
  322. }
  323. cmCTest::cmCTest()
  324. {
  325. m_ForceNewCTestProcess = false;
  326. m_TomorrowTag = false;
  327. m_BuildNoCMake = false;
  328. m_BuildNoClean = false;
  329. m_BuildTwoConfig = false;
  330. m_UseIncludeRegExp = false;
  331. m_UseExcludeRegExp = false;
  332. m_UseExcludeRegExpFirst = false;
  333. m_Verbose = false;
  334. m_DartMode = false;
  335. m_ShowOnly = false;
  336. m_RunConfigurationScript = false;
  337. m_TestModel = cmCTest::EXPERIMENTAL;
  338. m_InteractiveDebugMode = true;
  339. m_TimeOut = 0;
  340. m_CompatibilityMode = 0;
  341. int cc;
  342. for ( cc=0; cc < cmCTest::LAST_TEST; cc ++ )
  343. {
  344. m_Tests[cc] = 0;
  345. }
  346. }
  347. int cmCTest::Initialize()
  348. {
  349. if(!m_InteractiveDebugMode)
  350. {
  351. this->BlockTestErrorDiagnostics();
  352. }
  353. m_ToplevelPath = cmSystemTools::GetCurrentWorkingDirectory();
  354. cmSystemTools::ConvertToUnixSlashes(m_ToplevelPath);
  355. if ( !this->ReadCustomConfigurationFileTree(m_ToplevelPath.c_str()) )
  356. {
  357. return 0;
  358. }
  359. this->UpdateCTestConfiguration();
  360. if ( m_DartMode )
  361. {
  362. std::string testingDir = m_ToplevelPath + "/Testing";
  363. if ( cmSystemTools::FileExists(testingDir.c_str()) )
  364. {
  365. if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
  366. {
  367. std::cerr << "File " << testingDir << " is in the place of the testing directory"
  368. << std::endl;
  369. return 0;
  370. }
  371. }
  372. else
  373. {
  374. if ( !cmSystemTools::MakeDirectory(testingDir.c_str()) )
  375. {
  376. std::cerr << "Cannot create directory " << testingDir
  377. << std::endl;
  378. return 0;
  379. }
  380. }
  381. std::string tagfile = testingDir + "/TAG";
  382. std::ifstream tfin(tagfile.c_str());
  383. std::string tag;
  384. time_t tctime = time(0);
  385. if ( m_TomorrowTag )
  386. {
  387. tctime += ( 24 * 60 * 60 );
  388. }
  389. struct tm *lctime = gmtime(&tctime);
  390. if ( tfin && cmSystemTools::GetLineFromStream(tfin, tag) )
  391. {
  392. int year = 0;
  393. int mon = 0;
  394. int day = 0;
  395. int hour = 0;
  396. int min = 0;
  397. sscanf(tag.c_str(), "%04d%02d%02d-%02d%02d",
  398. &year, &mon, &day, &hour, &min);
  399. if ( year != lctime->tm_year + 1900 ||
  400. mon != lctime->tm_mon+1 ||
  401. day != lctime->tm_mday )
  402. {
  403. tag = "";
  404. }
  405. std::string tagmode;
  406. if ( cmSystemTools::GetLineFromStream(tfin, tagmode) )
  407. {
  408. if ( tagmode.size() > 4 && !( m_Tests[cmCTest::START_TEST] || m_Tests[ALL_TEST] ))
  409. {
  410. m_TestModel = cmCTest::GetTestModelFromString(tagmode.c_str());
  411. }
  412. }
  413. tfin.close();
  414. }
  415. if ( tag.size() == 0 || m_Tests[cmCTest::START_TEST] || m_Tests[ALL_TEST])
  416. {
  417. //std::cout << "TestModel: " << this->GetTestModelString() << std::endl;
  418. //std::cout << "TestModel: " << m_TestModel << std::endl;
  419. if ( m_TestModel == cmCTest::NIGHTLY )
  420. {
  421. lctime = ::GetNightlyTime(m_DartConfiguration["NightlyStartTime"],
  422. m_TomorrowTag);
  423. }
  424. char datestring[100];
  425. sprintf(datestring, "%04d%02d%02d-%02d%02d",
  426. lctime->tm_year + 1900,
  427. lctime->tm_mon+1,
  428. lctime->tm_mday,
  429. lctime->tm_hour,
  430. lctime->tm_min);
  431. tag = datestring;
  432. std::ofstream ofs(tagfile.c_str());
  433. if ( ofs )
  434. {
  435. ofs << tag << std::endl;
  436. ofs << this->GetTestModelString() << std::endl;
  437. }
  438. ofs.close();
  439. std::cout << "Create new tag: " << tag << " - "
  440. << this->GetTestModelString() << std::endl;
  441. }
  442. m_CurrentTag = tag;
  443. }
  444. return 1;
  445. }
  446. void cmCTest::UpdateCTestConfiguration()
  447. {
  448. // parse the dart test file
  449. std::ifstream fin("DartConfiguration.tcl");
  450. if(!fin)
  451. {
  452. return;
  453. }
  454. char buffer[1024];
  455. while ( fin )
  456. {
  457. buffer[0] = 0;
  458. fin.getline(buffer, 1023);
  459. buffer[1023] = 0;
  460. std::string line = ::CleanString(buffer);
  461. if(line.size() == 0)
  462. {
  463. continue;
  464. }
  465. while ( fin && (line[line.size()-1] == '\\') )
  466. {
  467. line = line.substr(0, line.size()-1);
  468. buffer[0] = 0;
  469. fin.getline(buffer, 1023);
  470. buffer[1023] = 0;
  471. line += ::CleanString(buffer);
  472. }
  473. if ( line[0] == '#' )
  474. {
  475. continue;
  476. }
  477. std::string::size_type cpos = line.find_first_of(":");
  478. if ( cpos == line.npos )
  479. {
  480. continue;
  481. }
  482. std::string key = line.substr(0, cpos);
  483. std::string value = ::CleanString(line.substr(cpos+1, line.npos));
  484. m_DartConfiguration[key] = value;
  485. }
  486. fin.close();
  487. if ( m_DartMode )
  488. {
  489. m_TimeOut = atoi(m_DartConfiguration["TimeOut"].c_str());
  490. }
  491. }
  492. void cmCTest::BlockTestErrorDiagnostics()
  493. {
  494. cmSystemTools::PutEnv("DART_TEST_FROM_DART=1");
  495. cmSystemTools::PutEnv("DASHBOARD_TEST_FROM_CTEST=1");
  496. #if defined(_WIN32)
  497. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  498. #endif
  499. }
  500. void cmCTest::SetTestModel(int mode)
  501. {
  502. m_InteractiveDebugMode = false;
  503. m_TestModel = mode;
  504. }
  505. bool cmCTest::SetTest(const char* ttype)
  506. {
  507. if ( cmSystemTools::LowerCase(ttype) == "all" )
  508. {
  509. m_Tests[cmCTest::ALL_TEST] = 1;
  510. }
  511. else if ( cmSystemTools::LowerCase(ttype) == "start" )
  512. {
  513. m_Tests[cmCTest::START_TEST] = 1;
  514. }
  515. else if ( cmSystemTools::LowerCase(ttype) == "update" )
  516. {
  517. m_Tests[cmCTest::UPDATE_TEST] = 1;
  518. }
  519. else if ( cmSystemTools::LowerCase(ttype) == "configure" )
  520. {
  521. m_Tests[cmCTest::CONFIGURE_TEST] = 1;
  522. }
  523. else if ( cmSystemTools::LowerCase(ttype) == "build" )
  524. {
  525. m_Tests[cmCTest::BUILD_TEST] = 1;
  526. }
  527. else if ( cmSystemTools::LowerCase(ttype) == "test" )
  528. {
  529. m_Tests[cmCTest::TEST_TEST] = 1;
  530. }
  531. else if ( cmSystemTools::LowerCase(ttype) == "coverage" )
  532. {
  533. m_Tests[cmCTest::COVERAGE_TEST] = 1;
  534. }
  535. else if ( cmSystemTools::LowerCase(ttype) == "memcheck" )
  536. {
  537. m_Tests[cmCTest::MEMCHECK_TEST] = 1;
  538. }
  539. else if ( cmSystemTools::LowerCase(ttype) == "notes" )
  540. {
  541. m_Tests[cmCTest::NOTES_TEST] = 1;
  542. }
  543. else if ( cmSystemTools::LowerCase(ttype) == "submit" )
  544. {
  545. m_Tests[cmCTest::SUBMIT_TEST] = 1;
  546. }
  547. else
  548. {
  549. std::cerr << "Don't know about test \"" << ttype << "\" yet..." << std::endl;
  550. return false;
  551. }
  552. return true;
  553. }
  554. void cmCTest::Finalize()
  555. {
  556. }
  557. std::string cmCTest::FindTheExecutable(const char *exe)
  558. {
  559. std::string fullPath = "";
  560. std::string dir;
  561. std::string file;
  562. cmSystemTools::SplitProgramPath(exe, dir, file);
  563. if(m_ConfigType != "" &&
  564. ::TryExecutable(dir.c_str(), file.c_str(), &fullPath,
  565. m_ConfigType.c_str()))
  566. {
  567. return fullPath;
  568. }
  569. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"."))
  570. {
  571. return fullPath;
  572. }
  573. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,""))
  574. {
  575. return fullPath;
  576. }
  577. if ( m_ConfigType == "" )
  578. {
  579. // No config type, so try to guess it
  580. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Release"))
  581. {
  582. return fullPath;
  583. }
  584. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Debug"))
  585. {
  586. return fullPath;
  587. }
  588. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"MinSizeRel"))
  589. {
  590. return fullPath;
  591. }
  592. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"RelWithDebInfo"))
  593. {
  594. return fullPath;
  595. }
  596. }
  597. // if everything else failed, check the users path
  598. if (dir != "")
  599. {
  600. std::string path = cmSystemTools::FindProgram(file.c_str());
  601. if (path != "")
  602. {
  603. return path;
  604. }
  605. }
  606. if ( m_ConfigType != "" )
  607. {
  608. dir += "/";
  609. dir += m_ConfigType;
  610. dir += "/";
  611. dir += file;
  612. cmSystemTools::Error("config type specified on the command line, but test executable not found.",
  613. dir.c_str());
  614. return "";
  615. }
  616. return fullPath;
  617. }
  618. int cmCTest::UpdateDirectory()
  619. {
  620. int count = 0;
  621. std::string::size_type cc, kk;
  622. std::string cvsCommand = m_DartConfiguration["CVSCommand"];
  623. if ( cvsCommand.size() == 0 )
  624. {
  625. std::cerr << "Cannot find CVSCommand key in the DartConfiguration.tcl" << std::endl;
  626. return -1;
  627. }
  628. std::string cvsOptions = m_DartConfiguration["CVSUpdateOptions"];
  629. if ( cvsOptions.size() == 0 )
  630. {
  631. std::cerr << "Cannot find CVSUpdateOptions key in the DartConfiguration.tcl" << std::endl;
  632. return -1;
  633. }
  634. std::string sourceDirectory = m_DartConfiguration["SourceDirectory"];
  635. if ( sourceDirectory.size() == 0 )
  636. {
  637. std::cerr << "Cannot find SourceDirectory key in the DartConfiguration.tcl" << std::endl;
  638. return -1;
  639. }
  640. std::string extra_update_opts;
  641. if ( m_TestModel == cmCTest::NIGHTLY )
  642. {
  643. struct tm* t = ::GetNightlyTime(m_DartConfiguration["NightlyStartTime"],
  644. m_TomorrowTag);
  645. char current_time[1024];
  646. sprintf(current_time, "%04d-%02d-%02d %02d:%02d:%02d UTC",
  647. t->tm_year + 1900,
  648. t->tm_mon + 1,
  649. t->tm_mday,
  650. t->tm_hour,
  651. t->tm_min,
  652. t->tm_sec);
  653. std::string today_update_date = current_time;
  654. extra_update_opts += "-D \"" + today_update_date +"\"";
  655. //std::cout << "Update: " << extra_update_opts << std::endl;
  656. }
  657. std::string command = cvsCommand + " -z3 update " + cvsOptions +
  658. " " + extra_update_opts;
  659. std::ofstream os;
  660. if ( !this->OpenOutputFile(m_CurrentTag, "Update.xml", os) )
  661. {
  662. std::cerr << "Cannot open log file" << std::endl;
  663. }
  664. std::string start_time = ::CurrentTime();
  665. std::string goutput;
  666. int retVal = 0;
  667. bool res = true;
  668. std::ofstream ofs;
  669. if ( !m_ShowOnly )
  670. {
  671. res = cmSystemTools::RunSingleCommand(command.c_str(), &goutput,
  672. &retVal, sourceDirectory.c_str(),
  673. m_Verbose, 0 /*m_TimeOut*/);
  674. if ( this->OpenOutputFile("Temporary", "LastUpdate.log", ofs) )
  675. {
  676. ofs << goutput << std::endl;;
  677. }
  678. }
  679. else
  680. {
  681. std::cout << "Update with command: " << command << std::endl;
  682. }
  683. os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  684. << "<Update mode=\"Client\" Generator=\"ctest\">\n"
  685. << "\t<Site>" <<m_DartConfiguration["Site"] << "</Site>\n"
  686. << "\t<BuildName>" << m_DartConfiguration["BuildName"]
  687. << "</BuildName>\n"
  688. << "\t<BuildStamp>" << m_CurrentTag << "-"
  689. << this->GetTestModelString() << "</BuildStamp>" << std::endl;
  690. os << "\t<StartDateTime>" << start_time << "</StartDateTime>\n"
  691. << "\t<UpdateCommand>" << command << "</UpdateCommand>\n"
  692. << "\t<UpdateReturnStatus>";
  693. int failed = 0;
  694. if ( !res || retVal )
  695. {
  696. os << "Update error: ";
  697. os << goutput;
  698. std::cerr << "Update with command: " << command << " failed" << std::endl;
  699. failed = 1;
  700. }
  701. os << "</UpdateReturnStatus>" << std::endl;
  702. if ( !failed )
  703. {
  704. std::vector<cmStdString> lines;
  705. cmSystemTools::Split(goutput.c_str(), lines);
  706. std::cout << "Updated; gathering version information" << std::endl;
  707. cmsys::RegularExpression date_author("^date: +([^;]+); +author: +([^;]+); +state: +[^;]+;");
  708. cmsys::RegularExpression revision("^revision +([^ ]*) *$");
  709. cmsys::RegularExpression end_of_file("^=============================================================================$");
  710. cmsys::RegularExpression end_of_comment("^----------------------------$");
  711. std::string current_path = "";
  712. bool first_file = true;
  713. cmCTest::AuthorsToUpdatesMap authors_files_map;
  714. int num_updated = 0;
  715. int num_modified = 0;
  716. int num_conflicting = 0;
  717. for ( cc= 0 ; cc < lines.size(); cc ++ )
  718. {
  719. const char* line = lines[cc].c_str();
  720. char mod = line[0];
  721. if ( line[1] == ' ' && mod != '?' )
  722. {
  723. count ++;
  724. const char* file = line + 2;
  725. //std::cout << "Line" << cc << ": " << mod << " - " << file << std::endl;
  726. std::string logcommand = cvsCommand + " -z3 log -N " + file;
  727. //std::cout << "Do log: " << logcommand << std::endl;
  728. std::string output;
  729. res = cmSystemTools::RunSingleCommand(logcommand.c_str(), &output,
  730. &retVal, sourceDirectory.c_str(),
  731. m_Verbose, 0 /*m_TimeOut*/);
  732. if ( ofs )
  733. {
  734. ofs << output << std::endl;
  735. }
  736. if ( res && retVal == 0)
  737. {
  738. //std::cout << output << std::endl;
  739. std::vector<cmStdString> ulines;
  740. cmSystemTools::Split(output.c_str(), ulines);
  741. std::string::size_type sline = 0;
  742. std::string srevision1 = "Unknown";
  743. std::string sdate1 = "Unknown";
  744. std::string sauthor1 = "Unknown";
  745. std::string semail1 = "Unknown";
  746. std::string comment1 = "";
  747. std::string srevision2 = "Unknown";
  748. std::string sdate2 = "Unknown";
  749. std::string sauthor2 = "Unknown";
  750. std::string comment2 = "";
  751. std::string semail2 = "Unknown";
  752. bool have_first = false;
  753. bool have_second = false;
  754. for ( kk = 0; kk < ulines.size(); kk ++ )
  755. {
  756. const char* clp = ulines[kk].c_str();
  757. if ( !have_second && !sline && revision.find(clp) )
  758. {
  759. if ( !have_first )
  760. {
  761. srevision1 = revision.match(1);
  762. }
  763. else
  764. {
  765. srevision2 = revision.match(1);
  766. }
  767. }
  768. else if ( !have_second && !sline && date_author.find(clp) )
  769. {
  770. sline = kk + 1;
  771. if ( !have_first )
  772. {
  773. sdate1 = date_author.match(1);
  774. sauthor1 = date_author.match(2);
  775. }
  776. else
  777. {
  778. sdate2 = date_author.match(1);
  779. sauthor2 = date_author.match(2);
  780. }
  781. }
  782. else if ( sline && end_of_comment.find(clp) || end_of_file.find(clp))
  783. {
  784. if ( !have_first )
  785. {
  786. have_first = true;
  787. }
  788. else if ( !have_second )
  789. {
  790. have_second = true;
  791. }
  792. sline = 0;
  793. }
  794. else if ( sline )
  795. {
  796. if ( !have_first )
  797. {
  798. comment1 += clp;
  799. comment1 += "\n";
  800. }
  801. else
  802. {
  803. comment2 += clp;
  804. comment2 += "\n";
  805. }
  806. }
  807. }
  808. if ( mod == 'M' )
  809. {
  810. comment1 = "Locally modified file\n";
  811. }
  812. if ( mod == 'C' )
  813. {
  814. comment1 = "Conflict while updating\n";
  815. }
  816. std::string path = cmSystemTools::GetFilenamePath(file);
  817. std::string fname = cmSystemTools::GetFilenameName(file);
  818. if ( path != current_path )
  819. {
  820. if ( !first_file )
  821. {
  822. os << "\t</Directory>" << std::endl;
  823. }
  824. else
  825. {
  826. first_file = false;
  827. }
  828. os << "\t<Directory>\n"
  829. << "\t\t<Name>" << path << "</Name>" << std::endl;
  830. }
  831. if ( mod == 'C' )
  832. {
  833. num_conflicting ++;
  834. os << "\t<Conflicting>" << std::endl;
  835. }
  836. else if ( mod == 'M' )
  837. {
  838. num_modified ++;
  839. os << "\t<Modified>" << std::endl;
  840. }
  841. else
  842. {
  843. num_updated ++;
  844. os << "\t<Updated>" << std::endl;
  845. }
  846. if ( srevision2 == "Unknown" )
  847. {
  848. srevision2 = srevision1;
  849. }
  850. os << "\t\t<File Directory=\"" << path << "\">" << fname
  851. << "</File>\n"
  852. << "\t\t<Directory>" << path << "</Directory>\n"
  853. << "\t\t<FullName>" << file << "</FullName>\n"
  854. << "\t\t<CheckinDate>" << sdate1 << "</CheckinDate>\n"
  855. << "\t\t<Author>" << sauthor1 << "</Author>\n"
  856. << "\t\t<Email>" << semail1 << "</Email>\n"
  857. << "\t\t<Log>" << this->MakeXMLSafe(comment1) << "</Log>\n"
  858. << "\t\t<Revision>" << srevision1 << "</Revision>\n"
  859. << "\t\t<PriorRevision>" << srevision2 << "</PriorRevision>"
  860. << std::endl;
  861. if ( srevision2 != srevision1 )
  862. {
  863. os
  864. << "\t\t<Revisions>\n"
  865. << "\t\t\t<Revision>" << srevision1 << "</Revision>\n"
  866. << "\t\t\t<PreviousRevision>" << srevision2 << "</PreviousRevision>\n"
  867. << "\t\t\t<Author>" << sauthor1<< "</Author>\n"
  868. << "\t\t\t<Date>" << sdate1 << "</Date>\n"
  869. << "\t\t\t<Comment>" << this->MakeXMLSafe(comment1) << "</Comment>\n"
  870. << "\t\t\t<Email>" << semail1 << "</Email>\n"
  871. << "\t\t</Revisions>\n"
  872. << "\t\t<Revisions>\n"
  873. << "\t\t\t<Revision>" << srevision2 << "</Revision>\n"
  874. << "\t\t\t<PreviousRevision>" << srevision2 << "</PreviousRevision>\n"
  875. << "\t\t\t<Author>" << sauthor2<< "</Author>\n"
  876. << "\t\t\t<Date>" << sdate2 << "</Date>\n"
  877. << "\t\t\t<Comment>" << this->MakeXMLSafe(comment2) << "</Comment>\n"
  878. << "\t\t\t<Email>" << semail2 << "</Email>\n"
  879. << "\t\t</Revisions>" << std::endl;
  880. }
  881. if ( mod == 'C' )
  882. {
  883. os << "\t</Conflicting>" << std::endl;
  884. }
  885. else if ( mod == 'M' )
  886. {
  887. os << "\t</Modified>" << std::endl;
  888. }
  889. else
  890. {
  891. os << "\t</Updated>" << std::endl;
  892. }
  893. cmCTest::UpdateFiles *u = &authors_files_map[sauthor1];
  894. cmCTest::StringPair p;
  895. p.first = path;
  896. p.second = fname;
  897. u->push_back(p);
  898. current_path = path;
  899. }
  900. }
  901. }
  902. if ( num_updated )
  903. {
  904. std::cout << "Found " << num_updated << " updated files" << std::endl;
  905. }
  906. if ( num_modified )
  907. {
  908. std::cout << "Found " << num_modified << " locally modified files"
  909. << std::endl;
  910. }
  911. if ( num_conflicting )
  912. {
  913. std::cout << "Found " << num_conflicting << " conflicting files"
  914. << std::endl;
  915. }
  916. if ( !first_file )
  917. {
  918. os << "\t</Directory>" << std::endl;
  919. }
  920. cmCTest::AuthorsToUpdatesMap::iterator it;
  921. for ( it = authors_files_map.begin();
  922. it != authors_files_map.end();
  923. it ++ )
  924. {
  925. os << "\t<Author>\n"
  926. << "\t\t<Name>" << it->first << "</Name>" << std::endl;
  927. cmCTest::UpdateFiles *u = &(it->second);
  928. for ( cc = 0; cc < u->size(); cc ++ )
  929. {
  930. os << "\t\t<File Directory=\"" << (*u)[cc].first << "\">"
  931. << (*u)[cc].second << "</File>" << std::endl;
  932. }
  933. os << "\t</Author>" << std::endl;
  934. }
  935. //std::cout << "End" << std::endl;
  936. std::string end_time = ::CurrentTime();
  937. os << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
  938. << "</Update>" << std::endl;
  939. if ( ofs )
  940. {
  941. ofs.close();
  942. }
  943. }
  944. if (! res || retVal )
  945. {
  946. std::cerr << "Error(s) when updating the project" << std::endl;
  947. std::cerr << "Output: " << goutput << std::endl;
  948. return -1;
  949. }
  950. return count;
  951. }
  952. int cmCTest::ConfigureDirectory()
  953. {
  954. std::cout << "Configure project" << std::endl;
  955. std::string cCommand = m_DartConfiguration["ConfigureCommand"];
  956. if ( cCommand.size() == 0 )
  957. {
  958. std::cerr << "Cannot find ConfigureCommand key in the DartConfiguration.tcl"
  959. << std::endl;
  960. return 1;
  961. }
  962. std::string buildDirectory = m_DartConfiguration["BuildDirectory"];
  963. if ( buildDirectory.size() == 0 )
  964. {
  965. std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
  966. return 1;
  967. }
  968. std::string output;
  969. int retVal = 0;
  970. int res = 0;
  971. if ( !m_ShowOnly )
  972. {
  973. std::ofstream os;
  974. if ( !this->OpenOutputFile(m_CurrentTag, "Configure.xml", os) )
  975. {
  976. std::cerr << "Cannot open configure file" << std::endl;
  977. return 1;
  978. }
  979. std::string start_time = ::CurrentTime();
  980. std::ofstream ofs;
  981. this->OpenOutputFile("Temporary", "LastConfigure.log", ofs);
  982. res = this->RunMakeCommand(cCommand.c_str(), &output,
  983. &retVal, buildDirectory.c_str(),
  984. m_Verbose, 0, ofs);
  985. if ( ofs )
  986. {
  987. ofs.close();
  988. }
  989. if ( os )
  990. {
  991. this->StartXML(os);
  992. os << "<Configure>\n"
  993. << "\t<StartDateTime>" << start_time << "</StartDateTime>" << std::endl;
  994. if ( res == cmsysProcess_State_Exited && retVal )
  995. {
  996. os << retVal;
  997. }
  998. os << "<ConfigureCommand>" << cCommand.c_str() << "</ConfigureCommand>" << std::endl;
  999. //std::cout << "End" << std::endl;
  1000. os << "<Log>" << this->MakeXMLSafe(output) << "</Log>" << std::endl;
  1001. std::string end_time = ::CurrentTime();
  1002. os << "\t<ConfigureStatus>" << retVal << "</ConfigureStatus>\n"
  1003. << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
  1004. << "</Configure>" << std::endl;
  1005. this->EndXML(os);
  1006. }
  1007. }
  1008. else
  1009. {
  1010. std::cout << "Configure with command: " << cCommand << std::endl;
  1011. }
  1012. if (! res || retVal )
  1013. {
  1014. std::cerr << "Error(s) when updating the project" << std::endl;
  1015. return 1;
  1016. }
  1017. return 0;
  1018. }
  1019. int cmCTest::BuildDirectory()
  1020. {
  1021. std::cout << "Build project" << std::endl;
  1022. std::string makeCommand = m_DartConfiguration["MakeCommand"];
  1023. if ( makeCommand.size() == 0 )
  1024. {
  1025. std::cerr << "Cannot find MakeCommand key in the DartConfiguration.tcl" << std::endl;
  1026. return 1;
  1027. }
  1028. std::string buildDirectory = m_DartConfiguration["BuildDirectory"];
  1029. if ( buildDirectory.size() == 0 )
  1030. {
  1031. std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
  1032. return 1;
  1033. }
  1034. std::ofstream ofs;
  1035. if ( !this->OpenOutputFile("Temporary", "LastBuild.log", ofs) )
  1036. {
  1037. std::cerr << "Cannot create LastBuild.log file" << std::endl;
  1038. }
  1039. m_StartBuild = ::CurrentTime();
  1040. std::string output;
  1041. int retVal = 0;
  1042. int res = cmsysProcess_State_Exited;
  1043. if ( !m_ShowOnly )
  1044. {
  1045. res = this->RunMakeCommand(makeCommand.c_str(), &output,
  1046. &retVal, buildDirectory.c_str(),
  1047. m_Verbose, 0, ofs);
  1048. }
  1049. else
  1050. {
  1051. std::cout << "Build with command: " << makeCommand << std::endl;
  1052. }
  1053. m_EndBuild = ::CurrentTime();
  1054. if (res != cmsysProcess_State_Exited || retVal )
  1055. {
  1056. std::cerr << "Error(s) when building project" << std::endl;
  1057. }
  1058. if ( ofs )
  1059. {
  1060. ofs.close();
  1061. }
  1062. tm_VectorOfStrings::size_type cc;
  1063. if ( m_DartConfiguration["SourceDirectory"].size() > 20 ||
  1064. m_DartConfiguration["BuildDirectory"].size() > 20 )
  1065. {
  1066. std::string srcdir = m_DartConfiguration["SourceDirectory"] + "/";
  1067. std::string bindir = m_DartConfiguration["BuildDirectory"] + "/";
  1068. std::string srcdirrep;
  1069. std::string bindirrep;
  1070. for ( cc = srcdir.size()-2; cc > 0; cc -- )
  1071. {
  1072. if ( srcdir[cc] == '/' )
  1073. {
  1074. srcdirrep = srcdir.c_str() + cc;
  1075. srcdirrep = "/..." + srcdirrep;
  1076. srcdir = srcdir.substr(0, cc+1);
  1077. break;
  1078. }
  1079. }
  1080. for ( cc = bindir.size()-2; cc > 0; cc -- )
  1081. {
  1082. if ( bindir[cc] == '/' )
  1083. {
  1084. bindirrep = bindir.c_str() + cc;
  1085. bindirrep = "/..." + bindirrep;
  1086. bindir = bindir.substr(0, cc+1);
  1087. break;
  1088. }
  1089. }
  1090. cmSystemTools::ReplaceString(output, srcdir.c_str(), "/.../"); //srcdirrep.c_str());
  1091. cmSystemTools::ReplaceString(output, bindir.c_str(), "/.../"); //bindirrep.c_str());
  1092. }
  1093. // Parsing of output for errors and warnings.
  1094. std::vector<cmStdString> lines;
  1095. cmSystemTools::Split(output.c_str(), lines);
  1096. // Lines are marked:
  1097. // 0 - nothing
  1098. // 1 - error
  1099. // > 1 - warning
  1100. std::vector<int> markedLines(lines.size(), 0);
  1101. // Errors
  1102. for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ )
  1103. {
  1104. m_CustomErrorMatches.push_back(cmCTestErrorMatches[cc]);
  1105. }
  1106. for ( cc = 0; cmCTestErrorExceptions[cc]; cc ++ )
  1107. {
  1108. m_CustomErrorExceptions.push_back(cmCTestErrorExceptions[cc]);
  1109. }
  1110. for ( cc = 0; cmCTestWarningMatches[cc]; cc ++ )
  1111. {
  1112. m_CustomWarningMatches.push_back(cmCTestWarningMatches[cc]);
  1113. }
  1114. for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ )
  1115. {
  1116. m_CustomWarningExceptions.push_back(cmCTestWarningExceptions[cc]);
  1117. }
  1118. for ( cc = 0; cc < m_CustomErrorMatches.size(); cc ++ )
  1119. {
  1120. cmsys::RegularExpression re(m_CustomErrorMatches[cc].c_str());
  1121. cmCTest::tm_VectorOfStrings::size_type kk;
  1122. for ( kk = 0; kk < lines.size(); kk ++ )
  1123. {
  1124. if ( re.find(lines[kk]) )
  1125. {
  1126. markedLines[kk] = 1;
  1127. }
  1128. }
  1129. }
  1130. // Warnings
  1131. for ( cc = 0; cc < m_CustomWarningMatches.size(); cc ++ )
  1132. {
  1133. cmsys::RegularExpression re(m_CustomWarningMatches[cc].c_str());
  1134. cmCTest::tm_VectorOfStrings::size_type kk;
  1135. for ( kk = 0; kk < lines.size(); kk ++ )
  1136. {
  1137. if ( re.find(lines[kk]) )
  1138. {
  1139. markedLines[kk] += 2;
  1140. }
  1141. }
  1142. }
  1143. // Errors exceptions
  1144. for ( cc = 0; cc < m_CustomErrorExceptions.size(); cc ++ )
  1145. {
  1146. cmsys::RegularExpression re(m_CustomErrorExceptions[cc].c_str());
  1147. std::vector<int>::size_type kk;
  1148. for ( kk =0; kk < markedLines.size(); kk ++ )
  1149. {
  1150. if ( markedLines[kk] == 1 )
  1151. {
  1152. if ( re.find(lines[kk]) )
  1153. {
  1154. markedLines[kk] = 0;
  1155. }
  1156. }
  1157. }
  1158. }
  1159. // Warning exceptions
  1160. for ( cc = 0; cc < m_CustomWarningExceptions.size(); cc ++ )
  1161. {
  1162. cmsys::RegularExpression re(m_CustomWarningExceptions[cc].c_str());
  1163. std::vector<int>::size_type kk;
  1164. for ( kk =0; kk < markedLines.size(); kk ++ )
  1165. {
  1166. if ( markedLines[kk] > 1 )
  1167. {
  1168. if ( re.find(lines[kk]) )
  1169. {
  1170. markedLines[kk] = 0;
  1171. }
  1172. }
  1173. }
  1174. }
  1175. std::vector<cmCTestBuildErrorWarning> errorsWarnings;
  1176. int errors = 0;
  1177. int warnings = 0;
  1178. std::vector<int>::size_type kk;
  1179. cmCTestBuildErrorWarning errorwarning;
  1180. for ( kk =0; kk < markedLines.size(); kk ++ )
  1181. {
  1182. errorwarning.m_LineNumber = -1;
  1183. bool found = false;
  1184. if ( markedLines[kk] == 1 )
  1185. {
  1186. //std::cout << "Error: " << lines[kk] << std::endl;
  1187. errorwarning.m_Error = true;
  1188. found = true;
  1189. }
  1190. else if ( markedLines[kk] > 1 )
  1191. {
  1192. //std::cout << "Warning: " << lines[kk] << std::endl;
  1193. errorwarning.m_Error = false;
  1194. found = true;
  1195. }
  1196. if ( found )
  1197. {
  1198. errorwarning.m_LogLine = static_cast<int>(kk+1);
  1199. errorwarning.m_Text = lines[kk];
  1200. errorwarning.m_PreContext = "";
  1201. errorwarning.m_PostContext = "";
  1202. std::vector<int>::size_type jj;
  1203. std::vector<int>::size_type ll = 0;
  1204. if ( kk > 6 )
  1205. {
  1206. ll = kk - 6;
  1207. }
  1208. for ( jj = kk-1;
  1209. jj > 0 && jj > ll && markedLines[jj] != markedLines[kk];
  1210. jj -- );
  1211. while ( markedLines[jj] == markedLines[kk] && jj < kk )
  1212. {
  1213. jj ++;
  1214. }
  1215. for (; jj < kk; jj ++ )
  1216. {
  1217. errorwarning.m_PreContext += lines[jj] + "\n";
  1218. }
  1219. for ( jj = kk+1;
  1220. jj < lines.size() && jj < kk + 7 && markedLines[jj] != markedLines[kk];
  1221. jj ++ )
  1222. {
  1223. errorwarning.m_PostContext += lines[jj] + "\n";
  1224. }
  1225. errorsWarnings.push_back(errorwarning);
  1226. if ( errorwarning.m_Error )
  1227. {
  1228. errors ++;
  1229. }
  1230. else
  1231. {
  1232. warnings ++;
  1233. }
  1234. }
  1235. }
  1236. std::cout << " " << errors << " Compiler errors" << std::endl;
  1237. std::cout << " " << warnings << " Compiler warnings" << std::endl;
  1238. if( !this->OpenOutputFile(m_CurrentTag, "Build.xml", ofs) )
  1239. {
  1240. std::cerr << "Cannot create build XML file" << std::endl;
  1241. return 1;
  1242. }
  1243. this->GenerateDartBuildOutput(ofs, errorsWarnings);
  1244. return 0;
  1245. }
  1246. int cmCTest::CoverageDirectory()
  1247. {
  1248. std::cout << "Performing coverage" << std::endl;
  1249. cmCTest::tm_VectorOfStrings files;
  1250. cmCTest::tm_VectorOfStrings cfiles;
  1251. cmCTest::tm_VectorOfStrings cdirs;
  1252. bool done = false;
  1253. std::string::size_type cc;
  1254. std::string glob;
  1255. std::map<std::string, std::string> allsourcefiles;
  1256. std::map<std::string, std::string> allbinaryfiles;
  1257. std::string start_time = ::CurrentTime();
  1258. // Find all source files.
  1259. std::string sourceDirectory = m_DartConfiguration["SourceDirectory"];
  1260. if ( sourceDirectory.size() == 0 )
  1261. {
  1262. std::cerr << "Cannot find SourceDirectory key in the DartConfiguration.tcl" << std::endl;
  1263. return 1;
  1264. }
  1265. std::string coverageCommand = m_DartConfiguration["CoverageCommand"];
  1266. if ( coverageCommand.size() == 0 )
  1267. {
  1268. std::cerr << "Coverage command not defined in DartConfiguration.tcl" << std::endl;
  1269. return 1;
  1270. }
  1271. cdirs.push_back(sourceDirectory);
  1272. while ( !done )
  1273. {
  1274. if ( cdirs.size() <= 0 )
  1275. {
  1276. break;
  1277. }
  1278. glob = cdirs[cdirs.size()-1] + "/*";
  1279. //std::cout << "Glob: " << glob << std::endl;
  1280. cdirs.pop_back();
  1281. if ( cmSystemTools::SimpleGlob(glob, cfiles, 1) )
  1282. {
  1283. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1284. {
  1285. allsourcefiles[cmSystemTools::GetFilenameName(cfiles[cc])] = cfiles[cc];
  1286. }
  1287. }
  1288. if ( cmSystemTools::SimpleGlob(glob, cfiles, -1) )
  1289. {
  1290. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1291. {
  1292. if ( cfiles[cc] != "." && cfiles[cc] != ".." )
  1293. {
  1294. cdirs.push_back(cfiles[cc]);
  1295. }
  1296. }
  1297. }
  1298. }
  1299. // find all binary files
  1300. cdirs.push_back(cmSystemTools::GetCurrentWorkingDirectory());
  1301. while ( !done )
  1302. {
  1303. if ( cdirs.size() <= 0 )
  1304. {
  1305. break;
  1306. }
  1307. glob = cdirs[cdirs.size()-1] + "/*";
  1308. //std::cout << "Glob: " << glob << std::endl;
  1309. cdirs.pop_back();
  1310. if ( cmSystemTools::SimpleGlob(glob, cfiles, 1) )
  1311. {
  1312. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1313. {
  1314. allbinaryfiles[cmSystemTools::GetFilenameName(cfiles[cc])] = cfiles[cc];
  1315. }
  1316. }
  1317. if ( cmSystemTools::SimpleGlob(glob, cfiles, -1) )
  1318. {
  1319. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1320. {
  1321. if ( cfiles[cc] != "." && cfiles[cc] != ".." )
  1322. {
  1323. cdirs.push_back(cfiles[cc]);
  1324. }
  1325. }
  1326. }
  1327. }
  1328. std::map<std::string, std::string>::iterator sit;
  1329. for ( sit = allbinaryfiles.begin(); sit != allbinaryfiles.end(); sit ++ )
  1330. {
  1331. const std::string& fname = sit->second;
  1332. //std::cout << "File: " << fname << std::endl;
  1333. if ( strcmp(fname.substr(fname.size()-3, 3).c_str(), ".da") == 0 )
  1334. {
  1335. files.push_back(fname);
  1336. }
  1337. }
  1338. if ( files.size() == 0 )
  1339. {
  1340. std::cerr << "Cannot find any coverage information files (.da)" << std::endl;
  1341. return 1;
  1342. }
  1343. std::ofstream log;
  1344. if (!this->OpenOutputFile("Temporary", "Coverage.log", log))
  1345. {
  1346. std::cerr << "Cannot open log file" << std::endl;
  1347. return 1;
  1348. }
  1349. log.close();
  1350. if (!this->OpenOutputFile(m_CurrentTag, "Coverage.xml", log))
  1351. {
  1352. std::cerr << "Cannot open log file" << std::endl;
  1353. return 1;
  1354. }
  1355. std::string opath = m_ToplevelPath + "/Testing/Temporary/Coverage";
  1356. cmSystemTools::MakeDirectory(opath.c_str());
  1357. cfiles.clear();
  1358. cmCTest::tm_VectorOfStrings ncfiles;
  1359. cmCTest::tm_VectorOfStrings missing_files;
  1360. for ( cc = 0; cc < files.size(); cc ++ )
  1361. {
  1362. std::string currPath = cmSystemTools::GetFilenamePath(files[cc]);
  1363. std::string command = coverageCommand + " -o \"" + currPath + "\" -l \"" + files[cc] + "\"";
  1364. std::string output;
  1365. int retVal = 0;
  1366. if ( m_Verbose )
  1367. {
  1368. std::cerr << "Run gcov on " << files[cc] << " in directory: " << currPath.c_str() << std::endl;
  1369. }
  1370. //std::cout << " --- Run [" << command << "]" << std::endl;
  1371. bool res = true;
  1372. if ( !m_ShowOnly )
  1373. {
  1374. res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
  1375. &retVal, currPath.c_str(),
  1376. m_Verbose, 0 /*m_TimeOut*/);
  1377. }
  1378. if ( res && retVal == 0 )
  1379. {
  1380. //std::cout << " - done" << std::endl;
  1381. glob = currPath + "/*";
  1382. if ( !cmSystemTools::SimpleGlob(glob, ncfiles, 1) )
  1383. {
  1384. std::cerr << "Cannot found any coverage files" << std::endl;
  1385. return 1;
  1386. }
  1387. cfiles.insert(cfiles.end(), ncfiles.begin(), ncfiles.end());
  1388. std::vector<cmStdString> gcovlines;
  1389. cmSystemTools::Split(output.c_str(), gcovlines);
  1390. std::vector<cmStdString>::iterator git;
  1391. const char* message = "Could not open source file";
  1392. for ( git = gcovlines.begin(); git != gcovlines.end(); ++git )
  1393. {
  1394. if ( strncmp(git->c_str(), message, strlen(message) ) == 0 )
  1395. {
  1396. std::cerr << "Problem: " << git->c_str() << std::endl;
  1397. missing_files.push_back(git->c_str() + strlen(message));
  1398. }
  1399. }
  1400. }
  1401. else
  1402. {
  1403. std::cerr << "Run gcov on " << files[cc] << std::flush;
  1404. std::cerr << " [" << command << "]" << std::endl;
  1405. std::cerr << " - fail" << std::endl;
  1406. }
  1407. }
  1408. files.clear();
  1409. std::map<std::string, cmCTest::tm_VectorOfStrings > sourcefiles;
  1410. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1411. {
  1412. std::string& fname = cfiles[cc];
  1413. // std::cout << "File: " << fname << std::endl;
  1414. if ( strcmp(fname.substr(fname.size()-5, 5).c_str(), ".gcov") == 0 )
  1415. {
  1416. files.push_back(fname);
  1417. std::string::size_type pos = fname.find(".da.");
  1418. std::string::size_type pos2 = fname.find(".da##");
  1419. if(pos2 != fname.npos)
  1420. {
  1421. pos = pos2+1;
  1422. }
  1423. if ( pos != fname.npos )
  1424. {
  1425. pos += 4;
  1426. std::string::size_type epos = fname.size() - pos - strlen(".gcov");
  1427. std::string nf = fname.substr(pos, epos);
  1428. //std::cout << "Substring: " << nf << std::endl;
  1429. if ( allsourcefiles.find(nf) != allsourcefiles.end() ||
  1430. allbinaryfiles.find(nf) != allbinaryfiles.end() )
  1431. {
  1432. cmCTest::tm_VectorOfStrings &cvec = sourcefiles[nf];
  1433. cvec.push_back(fname);
  1434. }
  1435. }
  1436. }
  1437. }
  1438. // for ( cc = 0; cc < files.size(); cc ++ )
  1439. // {
  1440. // std::cout << "File: " << files[cc] << std::endl;
  1441. // }
  1442. if ( missing_files.size() > 0 )
  1443. {
  1444. std::cout << "---------------------------------------------------------------" << std::endl;
  1445. std::cout << "The following files were missing:" << std::endl;
  1446. for ( cc = 0; cc < missing_files.size(); cc ++ )
  1447. {
  1448. std::cout << "File: " << missing_files[cc] << std::endl;
  1449. }
  1450. std::cout << "---------------------------------------------------------------" << std::endl;
  1451. }
  1452. std::map<std::string, cmCTest::tm_VectorOfStrings >::iterator it;
  1453. cmCTest::tm_CoverageMap coverageresults;
  1454. this->StartXML(log);
  1455. log << "<Coverage>\n"
  1456. << "\t<StartDateTime>" << start_time << "</StartDateTime>" << std::endl;
  1457. int total_tested = 0;
  1458. int total_untested = 0;
  1459. for ( it = sourcefiles.begin(); it != sourcefiles.end(); it ++ )
  1460. {
  1461. //std::cerr << "Source file: " << it->first << std::endl;
  1462. cmCTest::tm_VectorOfStrings &gfiles = it->second;
  1463. for ( cc = 0; cc < gfiles.size(); cc ++ )
  1464. {
  1465. int do_coverage = 1;
  1466. std::string coverage_dir = cmSystemTools::GetFilenamePath(gfiles[cc].c_str());
  1467. std::string builDir = m_DartConfiguration["BuildDirectory"];
  1468. do
  1469. {
  1470. std::string coverage_file = coverage_dir + "/.NoDartCoverage";
  1471. if ( cmSystemTools::FileExists(coverage_file.c_str()) )
  1472. {
  1473. do_coverage = 0;
  1474. break;
  1475. }
  1476. // is there a parent directory we can check
  1477. std::string::size_type pos = coverage_dir.rfind('/');
  1478. // if we could not find the directory return 0
  1479. if(pos == std::string::npos)
  1480. {
  1481. break;
  1482. }
  1483. coverage_dir = coverage_dir.substr(0, pos);
  1484. }
  1485. while (coverage_dir.size() >= builDir.size());
  1486. if ( !do_coverage )
  1487. {
  1488. continue;
  1489. }
  1490. //std::cout << "\t" << gfiles[cc] << std::endl;
  1491. std::ifstream ifile(gfiles[cc].c_str());
  1492. if ( !ifile )
  1493. {
  1494. std::cerr << "Cannot open file: " << gfiles[cc].c_str() << std::endl;
  1495. }
  1496. ifile.seekg (0, std::ios::end);
  1497. int length = ifile.tellg();
  1498. ifile.seekg (0, std::ios::beg);
  1499. char *buffer = new char [ length + 1 ];
  1500. ifile.read(buffer, length);
  1501. buffer [length] = 0;
  1502. //std::cout << "Read: " << buffer << std::endl;
  1503. std::vector<cmStdString> lines;
  1504. cmSystemTools::Split(buffer, lines);
  1505. delete [] buffer;
  1506. cmCTest::cmCTestCoverage& cov = coverageresults[it->first];
  1507. std::vector<int>& covlines = cov.m_Lines;
  1508. if ( cov.m_FullPath == "" )
  1509. {
  1510. covlines.insert(covlines.begin(), lines.size(), -1);
  1511. if ( allsourcefiles.find(it->first) != allsourcefiles.end() )
  1512. {
  1513. cov.m_FullPath = allsourcefiles[it->first];
  1514. }
  1515. else if ( allbinaryfiles.find(it->first) != allbinaryfiles.end() )
  1516. {
  1517. cov.m_FullPath = allbinaryfiles[it->first];
  1518. }
  1519. cov.m_AbsolutePath = cov.m_FullPath;
  1520. std::string src_dir = m_DartConfiguration["SourceDirectory"];
  1521. if ( src_dir[src_dir.size()-1] != '/' )
  1522. {
  1523. src_dir = src_dir + "/";
  1524. }
  1525. std::string::size_type spos = cov.m_FullPath.find(src_dir);
  1526. if ( spos == 0 )
  1527. {
  1528. cov.m_FullPath = std::string("./") + cov.m_FullPath.substr(src_dir.size());
  1529. }
  1530. else
  1531. {
  1532. //std::cerr << "Compare -- " << cov.m_FullPath << std::endl;
  1533. //std::cerr << " -- " << src_dir << std::endl;
  1534. cov.m_Show = false;
  1535. continue;
  1536. }
  1537. cov.m_Show = true;
  1538. }
  1539. std::string::size_type kk;
  1540. // std::cerr << "number of lines " << lines.size() << "\n";
  1541. for ( kk = 0; kk < lines.size(); kk ++ )
  1542. {
  1543. std::string& line = lines[kk];
  1544. //std::cerr << line << "\n";
  1545. std::string sub1 = line.substr(0, strlen(" #####"));
  1546. std::string sub2 = line.substr(0, strlen(" ######"));
  1547. int count = atoi(sub2.c_str());
  1548. if ( sub1.compare(" #####") == 0 ||
  1549. sub2.compare(" ######") == 0 )
  1550. {
  1551. if ( covlines[kk] == -1 )
  1552. {
  1553. covlines[kk] = 0;
  1554. }
  1555. cov.m_UnTested ++;
  1556. //std::cout << "Untested - ";
  1557. }
  1558. else if ( count > 0 )
  1559. {
  1560. if ( covlines[kk] == -1 )
  1561. {
  1562. covlines[kk] = 0;
  1563. }
  1564. cov.m_Tested ++;
  1565. covlines[kk] ++;
  1566. //std::cout << "Tested[" << count << "] - ";
  1567. }
  1568. //std::cout << line << std::endl;
  1569. }
  1570. }
  1571. }
  1572. //std::cerr << "Finalizing" << std::endl;
  1573. cmCTest::tm_CoverageMap::iterator cit;
  1574. int ccount = 0;
  1575. std::ofstream cfileoutput;
  1576. int cfileoutputcount = 0;
  1577. char cfileoutputname[100];
  1578. std::string local_start_time = ::CurrentTime();
  1579. std::string local_end_time;
  1580. for ( cit = coverageresults.begin(); cit != coverageresults.end(); cit ++ )
  1581. {
  1582. cmCTest::cmCTestCoverage &cov = cit->second;
  1583. if ( !cov.m_Show )
  1584. {
  1585. continue;
  1586. }
  1587. // Check if we should ignore the directory, if we find a NoDartCoverage
  1588. // file in it or any of its parents
  1589. int do_coverage = 1;
  1590. std::string coverage_dir = cmSystemTools::GetFilenamePath(cov.m_AbsolutePath.c_str());
  1591. do
  1592. {
  1593. std::string coverage_file = coverage_dir + "/.NoDartCoverage";
  1594. if ( cmSystemTools::FileExists(coverage_file.c_str()) )
  1595. {
  1596. do_coverage = 0;
  1597. break;
  1598. }
  1599. // is there a parent directory we can check
  1600. std::string::size_type pos = coverage_dir.rfind('/');
  1601. // if we could not find the directory return 0
  1602. if(pos == std::string::npos)
  1603. {
  1604. break;
  1605. }
  1606. coverage_dir = coverage_dir.substr(0, pos);
  1607. }
  1608. while (coverage_dir.size() >= sourceDirectory.size());
  1609. if (!do_coverage)
  1610. {
  1611. if ( m_Verbose )
  1612. {
  1613. std::cout << "Ignore file: " << cov.m_FullPath.c_str() << std::endl;
  1614. }
  1615. continue;
  1616. }
  1617. if ( ccount == 100 )
  1618. {
  1619. local_end_time = ::CurrentTime();
  1620. cfileoutput << "\t<EndDateTime>" << local_end_time << "</EndDateTime>\n"
  1621. << "</CoverageLog>" << std::endl;
  1622. this->EndXML(cfileoutput);
  1623. cfileoutput.close();
  1624. std::cout << "Close file: " << cfileoutputname << std::endl;
  1625. ccount = 0;
  1626. }
  1627. if ( ccount == 0 )
  1628. {
  1629. sprintf(cfileoutputname, "CoverageLog-%d.xml", cfileoutputcount++);
  1630. std::cout << "Open file: " << cfileoutputname << std::endl;
  1631. if (!this->OpenOutputFile(m_CurrentTag, cfileoutputname, cfileoutput))
  1632. {
  1633. std::cerr << "Cannot open log file: " << cfileoutputname << std::endl;
  1634. return 1;
  1635. }
  1636. local_start_time = ::CurrentTime();
  1637. this->StartXML(cfileoutput);
  1638. cfileoutput << "<CoverageLog>\n"
  1639. << "\t<StartDateTime>" << local_start_time << "</StartDateTime>" << std::endl;
  1640. }
  1641. //std::cerr << "Final process of Source file: " << cit->first << std::endl;
  1642. cov.m_UnTested = 0;
  1643. cov.m_Tested = 0;
  1644. for ( cc = 0; cc < cov.m_Lines.size(); cc ++ )
  1645. {
  1646. if ( cov.m_Lines[cc] == 0 )
  1647. {
  1648. cov.m_UnTested ++;
  1649. }
  1650. else if ( cov.m_Lines[cc] > 0 )
  1651. {
  1652. cov.m_Tested ++;
  1653. }
  1654. }
  1655. std::ifstream ifile(cov.m_AbsolutePath.c_str());
  1656. if ( !ifile )
  1657. {
  1658. std::cerr << "Cannot open file: " << cov.m_FullPath.c_str() << std::endl;
  1659. }
  1660. ifile.seekg (0, std::ios::end);
  1661. int length = ifile.tellg();
  1662. ifile.seekg (0, std::ios::beg);
  1663. char *buffer = new char [ length + 1 ];
  1664. ifile.read(buffer, length);
  1665. buffer [length] = 0;
  1666. //std::cout << "Read: " << buffer << std::endl;
  1667. std::vector<cmStdString> lines;
  1668. cmSystemTools::Split(buffer, lines);
  1669. delete [] buffer;
  1670. cfileoutput << "\t<File Name=\"" << cit->first << "\" FullPath=\""
  1671. << cov.m_FullPath << "\">\n"
  1672. << "\t\t<Report>" << std::endl;
  1673. for ( cc = 0; cc < lines.size(); cc ++ )
  1674. {
  1675. cfileoutput << "\t\t<Line Number=\""
  1676. << static_cast<int>(cc) << "\" Count=\""
  1677. << cov.m_Lines[cc] << "\">"
  1678. << cmCTest::MakeXMLSafe(lines[cc]) << "</Line>" << std::endl;
  1679. }
  1680. cfileoutput << "\t\t</Report>\n"
  1681. << "\t</File>" << std::endl;
  1682. total_tested += cov.m_Tested;
  1683. total_untested += cov.m_UnTested;
  1684. float cper = 0;
  1685. float cmet = 0;
  1686. if ( total_tested + total_untested > 0 && (cov.m_Tested + cov.m_UnTested) > 0)
  1687. {
  1688. cper = (100 * SAFEDIV(static_cast<float>(cov.m_Tested),
  1689. static_cast<float>(cov.m_Tested + cov.m_UnTested)));
  1690. cmet = ( SAFEDIV(static_cast<float>(cov.m_Tested + 10),
  1691. static_cast<float>(cov.m_Tested + cov.m_UnTested + 10)));
  1692. }
  1693. log << "\t<File Name=\"" << cit->first << "\" FullPath=\"" << cov.m_FullPath
  1694. << "\" Covered=\"" << (cmet>0?"true":"false") << "\">\n"
  1695. << "\t\t<LOCTested>" << cov.m_Tested << "</LOCTested>\n"
  1696. << "\t\t<LOCUnTested>" << cov.m_UnTested << "</LOCUnTested>\n"
  1697. << "\t\t<PercentCoverage>";
  1698. log.setf(std::ios::fixed, std::ios::floatfield);
  1699. log.precision(2);
  1700. log << (cper) << "</PercentCoverage>\n"
  1701. << "\t\t<CoverageMetric>";
  1702. log.setf(std::ios::fixed, std::ios::floatfield);
  1703. log.precision(2);
  1704. log << (cmet) << "</CoverageMetric>\n"
  1705. << "\t</File>" << std::endl;
  1706. ccount ++;
  1707. }
  1708. if ( ccount > 0 )
  1709. {
  1710. local_end_time = ::CurrentTime();
  1711. cfileoutput << "\t<EndDateTime>" << local_end_time << "</EndDateTime>\n"
  1712. << "</CoverageLog>" << std::endl;
  1713. this->EndXML(cfileoutput);
  1714. cfileoutput.close();
  1715. }
  1716. int total_lines = total_tested + total_untested;
  1717. float percent_coverage = 100 * SAFEDIV(static_cast<float>(total_tested),
  1718. static_cast<float>(total_lines));
  1719. if ( total_lines == 0 )
  1720. {
  1721. percent_coverage = 0;
  1722. }
  1723. std::string end_time = ::CurrentTime();
  1724. log << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
  1725. << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
  1726. << "\t<LOC>" << total_lines << "</LOC>\n"
  1727. << "\t<PercentCoverage>";
  1728. log.setf(std::ios::fixed, std::ios::floatfield);
  1729. log.precision(2);
  1730. log << (percent_coverage)<< "</PercentCoverage>\n"
  1731. << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
  1732. << "</Coverage>" << std::endl;
  1733. this->EndXML(log);
  1734. std::cout << "\tCovered LOC: " << total_tested << std::endl
  1735. << "\tNot covered LOC: " << total_untested << std::endl
  1736. << "\tTotal LOC: " << total_lines << std::endl
  1737. << "\tPercentage Coverage: ";
  1738. std::cout.setf(std::ios::fixed, std::ios::floatfield);
  1739. std::cout.precision(2);
  1740. std::cout << (percent_coverage) << "%" << std::endl;
  1741. return 1;
  1742. }
  1743. bool cmCTest::OpenOutputFile(const std::string& path,
  1744. const std::string& name, std::ofstream& stream)
  1745. {
  1746. std::string testingDir = m_ToplevelPath + "/Testing";
  1747. if ( path.size() > 0 )
  1748. {
  1749. testingDir += "/" + path;
  1750. }
  1751. if ( cmSystemTools::FileExists(testingDir.c_str()) )
  1752. {
  1753. if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
  1754. {
  1755. std::cerr << "File " << testingDir
  1756. << " is in the place of the testing directory"
  1757. << std::endl;
  1758. return false;
  1759. }
  1760. }
  1761. else
  1762. {
  1763. if ( !cmSystemTools::MakeDirectory(testingDir.c_str()) )
  1764. {
  1765. std::cerr << "Cannot create directory " << testingDir
  1766. << std::endl;
  1767. return false;
  1768. }
  1769. }
  1770. std::string filename = testingDir + "/" + name;
  1771. stream.open(filename.c_str());
  1772. if( !stream )
  1773. {
  1774. std::cerr << "Problem opening file: " << filename << std::endl;
  1775. return false;
  1776. }
  1777. return true;
  1778. }
  1779. void cmCTest::GenerateDartBuildOutput(std::ostream& os,
  1780. std::vector<cmCTestBuildErrorWarning> ew)
  1781. {
  1782. this->StartXML(os);
  1783. os << "<Build>\n"
  1784. << "\t<StartDateTime>" << m_StartBuild << "</StartDateTime>\n"
  1785. << "<BuildCommand>"
  1786. << this->MakeXMLSafe(m_DartConfiguration["MakeCommand"])
  1787. << "</BuildCommand>" << std::endl;
  1788. std::vector<cmCTestBuildErrorWarning>::iterator it;
  1789. for ( it = ew.begin(); it != ew.end(); it++ )
  1790. {
  1791. cmCTestBuildErrorWarning *cm = &(*it);
  1792. os << "\t<" << (cm->m_Error ? "Error" : "Warning") << ">\n"
  1793. << "\t\t<BuildLogLine>" << cm->m_LogLine << "</BuildLogLine>\n"
  1794. << "\t\t<Text>" << this->MakeXMLSafe(cm->m_Text)
  1795. << "\n</Text>" << std::endl;
  1796. if ( cm->m_SourceFile.size() > 0 )
  1797. {
  1798. os << "\t\t<SourceFile>" << cm->m_SourceFile << "</SourceFile>"
  1799. << std::endl;
  1800. }
  1801. if ( cm->m_SourceFileTail.size() > 0 )
  1802. {
  1803. os << "\t\t<SourceFileTail>" << cm->m_SourceFileTail
  1804. << "</SourceFileTail>" << std::endl;
  1805. }
  1806. if ( cm->m_LineNumber >= 0 )
  1807. {
  1808. os << "\t\t<SourceLineNumber>" << cm->m_LineNumber
  1809. << "</SourceLineNumber>" << std::endl;
  1810. }
  1811. os << "\t\t<PreContext>" << this->MakeXMLSafe(cm->m_PreContext)
  1812. << "</PreContext>\n"
  1813. << "\t\t<PostContext>" << this->MakeXMLSafe(cm->m_PostContext)
  1814. << "</PostContext>\n"
  1815. << "\t\t<RepeatCount>0</RepeatCount>\n"
  1816. << "</" << (cm->m_Error ? "Error" : "Warning") << ">\n\n"
  1817. << std::endl;
  1818. }
  1819. os << "\t<Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n\t</Log>\n"
  1820. << "\t<EndDateTime>" << m_EndBuild << "</EndDateTime>\n"
  1821. << "</Build>" << std::endl;
  1822. this->EndXML(os);
  1823. }
  1824. void cmCTest::GetListOfTests(tm_ListOfTests* testlist, bool memcheck)
  1825. {
  1826. // does the DartTestfile.txt exist ?
  1827. if(!cmSystemTools::FileExists("DartTestfile.txt"))
  1828. {
  1829. return;
  1830. }
  1831. // parse the file
  1832. std::ifstream fin("DartTestfile.txt");
  1833. if(!fin)
  1834. {
  1835. return;
  1836. }
  1837. cmsys::RegularExpression ireg(this->m_IncludeRegExp.c_str());
  1838. cmsys::RegularExpression ereg(this->m_ExcludeRegExp.c_str());
  1839. cmListFileCache cache;
  1840. cmListFile* listFile = cache.GetFileCache("DartTestfile.txt", false);
  1841. for(std::vector<cmListFileFunction>::const_iterator f =
  1842. listFile->m_Functions.begin(); f != listFile->m_Functions.end(); ++f)
  1843. {
  1844. const cmListFileFunction& lff = *f;
  1845. const std::string& name = lff.m_Name;
  1846. const tm_VectorOfListFileArgs& args = lff.m_Arguments;
  1847. if (name == "SUBDIRS")
  1848. {
  1849. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  1850. for(tm_VectorOfListFileArgs::const_iterator j = args.begin();
  1851. j != args.end(); ++j)
  1852. {
  1853. std::string nwd = cwd + "/";
  1854. nwd += j->Value;
  1855. if (cmSystemTools::FileIsDirectory(nwd.c_str()))
  1856. {
  1857. cmSystemTools::ChangeDirectory(nwd.c_str());
  1858. this->GetListOfTests(testlist, memcheck);
  1859. }
  1860. }
  1861. // return to the original directory
  1862. cmSystemTools::ChangeDirectory(cwd.c_str());
  1863. }
  1864. if (name == "ADD_TEST")
  1865. {
  1866. const std::string& testname = args[0].Value;
  1867. if (this->m_UseExcludeRegExp &&
  1868. this->m_UseExcludeRegExpFirst &&
  1869. ereg.find(testname.c_str()))
  1870. {
  1871. continue;
  1872. }
  1873. if ( memcheck )
  1874. {
  1875. tm_VectorOfStrings::iterator it;
  1876. bool found = false;
  1877. for ( it = m_CustomMemCheckIgnore.begin();
  1878. it != m_CustomMemCheckIgnore.end(); ++ it )
  1879. {
  1880. if ( *it == testname )
  1881. {
  1882. found = true;
  1883. break;
  1884. }
  1885. }
  1886. if ( found )
  1887. {
  1888. if ( m_Verbose )
  1889. {
  1890. std::cout << "Ignore memcheck: " << *it << std::endl;
  1891. }
  1892. continue;
  1893. }
  1894. }
  1895. else
  1896. {
  1897. tm_VectorOfStrings::iterator it;
  1898. bool found = false;
  1899. for ( it = m_CustomTestsIgnore.begin();
  1900. it != m_CustomTestsIgnore.end(); ++ it )
  1901. {
  1902. if ( *it == testname )
  1903. {
  1904. found = true;
  1905. break;
  1906. }
  1907. }
  1908. if ( found )
  1909. {
  1910. if ( m_Verbose )
  1911. {
  1912. std::cout << "Ignore test: " << *it << std::endl;
  1913. }
  1914. continue;
  1915. }
  1916. }
  1917. if (this->m_UseIncludeRegExp && !ireg.find(testname.c_str()))
  1918. {
  1919. continue;
  1920. }
  1921. if (this->m_UseExcludeRegExp &&
  1922. !this->m_UseExcludeRegExpFirst &&
  1923. ereg.find(testname.c_str()))
  1924. {
  1925. continue;
  1926. }
  1927. cmCTestTestProperties test;
  1928. test.m_Name = testname;
  1929. test.m_Args = args;
  1930. test.m_Directory = cmSystemTools::GetCurrentWorkingDirectory();
  1931. testlist->push_back(test);
  1932. }
  1933. }
  1934. }
  1935. void cmCTest::ProcessDirectory(cmCTest::tm_VectorOfStrings &passed,
  1936. cmCTest::tm_VectorOfStrings &failed,
  1937. bool memcheck)
  1938. {
  1939. std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
  1940. cmsys::RegularExpression dartStuff("(<DartMeasurement.*/DartMeasurement[a-zA-Z]*>)");
  1941. tm_ListOfTests testlist;
  1942. this->GetListOfTests(&testlist, memcheck);
  1943. tm_ListOfTests::size_type tmsize = testlist.size();
  1944. std::ofstream ofs;
  1945. std::ofstream *olog = 0;
  1946. if ( !m_ShowOnly && tmsize > 0 &&
  1947. this->OpenOutputFile("Temporary",
  1948. (memcheck?"LastMemCheck.xml":"LastTest.log"), ofs) )
  1949. {
  1950. olog = &ofs;
  1951. }
  1952. m_StartTest = ::CurrentTime();
  1953. if ( olog )
  1954. {
  1955. *olog << "Start testing: " << m_StartTest << std::endl
  1956. << "----------------------------------------------------------"
  1957. << std::endl;
  1958. }
  1959. // expand the test list
  1960. this->ExpandTestsToRunInformation((int)tmsize);
  1961. int cnt = 0;
  1962. tm_ListOfTests::iterator it;
  1963. std::string last_directory = "";
  1964. for ( it = testlist.begin(); it != testlist.end(); it ++ )
  1965. {
  1966. cnt ++;
  1967. const std::string& testname = it->m_Name;
  1968. tm_VectorOfListFileArgs& args = it->m_Args;
  1969. cmCTestTestResult cres;
  1970. cres.m_Status = cmCTest::NOT_RUN;
  1971. cres.m_TestCount = cnt;
  1972. if (!(last_directory == it->m_Directory))
  1973. {
  1974. if ( m_Verbose )
  1975. {
  1976. std::cerr << "Changing directory into "
  1977. << it->m_Directory.c_str() << "\n";
  1978. }
  1979. last_directory = it->m_Directory;
  1980. cmSystemTools::ChangeDirectory(it->m_Directory.c_str());
  1981. }
  1982. cres.m_Name = testname;
  1983. if(m_TestsToRun.size() &&
  1984. std::find(m_TestsToRun.begin(), m_TestsToRun.end(), cnt) == m_TestsToRun.end())
  1985. {
  1986. continue;
  1987. }
  1988. if ( m_ShowOnly )
  1989. {
  1990. fprintf(stderr,"%3d/%3d Testing %-30s\n", cnt, (int)tmsize, testname.c_str());
  1991. }
  1992. else
  1993. {
  1994. fprintf(stderr,"%3d/%3d Testing %-30s ", cnt, (int)tmsize, testname.c_str());
  1995. fflush(stderr);
  1996. }
  1997. //std::cerr << "Testing " << args[0] << " ... ";
  1998. // find the test executable
  1999. std::string actualCommand = this->FindTheExecutable(args[1].Value.c_str());
  2000. std::string testCommand = cmSystemTools::ConvertToOutputPath(actualCommand.c_str());
  2001. std::string memcheckcommand = "";
  2002. // continue if we did not find the executable
  2003. if (testCommand == "")
  2004. {
  2005. std::cerr << "Unable to find executable: " <<
  2006. args[1].Value.c_str() << "\n";
  2007. if ( !m_ShowOnly )
  2008. {
  2009. m_TestResults.push_back( cres );
  2010. failed.push_back(testname);
  2011. continue;
  2012. }
  2013. }
  2014. // add the arguments
  2015. tm_VectorOfListFileArgs::const_iterator j = args.begin();
  2016. ++j;
  2017. ++j;
  2018. std::vector<const char*> arguments;
  2019. if ( memcheck )
  2020. {
  2021. cmCTest::tm_VectorOfStrings::size_type pp;
  2022. arguments.push_back(m_MemoryTester.c_str());
  2023. memcheckcommand = m_MemoryTester;
  2024. for ( pp = 0; pp < m_MemoryTesterOptionsParsed.size(); pp ++ )
  2025. {
  2026. arguments.push_back(m_MemoryTesterOptionsParsed[pp].c_str());
  2027. memcheckcommand += " ";
  2028. memcheckcommand += cmSystemTools::EscapeSpaces(m_MemoryTesterOptionsParsed[pp].c_str());
  2029. }
  2030. }
  2031. arguments.push_back(actualCommand.c_str());
  2032. for(;j != args.end(); ++j)
  2033. {
  2034. testCommand += " ";
  2035. testCommand += cmSystemTools::EscapeSpaces(j->Value.c_str());
  2036. arguments.push_back(j->Value.c_str());
  2037. }
  2038. arguments.push_back(0);
  2039. /**
  2040. * Run an executable command and put the stdout in output.
  2041. */
  2042. std::string output;
  2043. int retVal = 0;
  2044. if ( m_Verbose )
  2045. {
  2046. std::cout << std::endl << (memcheck?"MemCheck":"Test") << " command: " << testCommand << std::endl;
  2047. if ( memcheck )
  2048. {
  2049. std::cout << "Memory check command: " << memcheckcommand << std::endl;
  2050. }
  2051. }
  2052. if ( olog )
  2053. {
  2054. *olog << cnt << "/" << tmsize
  2055. << " Test: " << testname.c_str() << std::endl;
  2056. *olog << "Command: ";
  2057. tm_VectorOfStrings::size_type ll;
  2058. for ( ll = 0; ll < arguments.size()-1; ll ++ )
  2059. {
  2060. *olog << "\"" << arguments[ll] << "\" ";
  2061. }
  2062. *olog
  2063. << std::endl
  2064. << "Directory: " << it->m_Directory << std::endl
  2065. << "\"" << testname.c_str() << "\" start time: "
  2066. << ::CurrentTime() << std::endl
  2067. << "Output:" << std::endl
  2068. << "----------------------------------------------------------"
  2069. << std::endl;
  2070. }
  2071. int res = 0;
  2072. double clock_start, clock_finish;
  2073. clock_start = cmSystemTools::GetTime();
  2074. if ( !m_ShowOnly )
  2075. {
  2076. res = this->RunTest(arguments, &output, &retVal, olog);
  2077. }
  2078. clock_finish = cmSystemTools::GetTime();
  2079. if ( olog )
  2080. {
  2081. double ttime = clock_finish - clock_start;
  2082. int hours = static_cast<int>(ttime / (60 * 60));
  2083. int minutes = static_cast<int>(ttime / 60) % 60;
  2084. int seconds = static_cast<int>(ttime) % 60;
  2085. char buffer[100];
  2086. sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds);
  2087. *olog
  2088. << "----------------------------------------------------------"
  2089. << std::endl
  2090. << "\"" << testname.c_str() << "\" end time: "
  2091. << ::CurrentTime() << std::endl
  2092. << "\"" << testname.c_str() << "\" time elapsed: "
  2093. << buffer << std::endl
  2094. << "----------------------------------------------------------"
  2095. << std::endl << std::endl;
  2096. }
  2097. cres.m_ExecutionTime = (double)(clock_finish - clock_start);
  2098. cres.m_FullCommandLine = testCommand;
  2099. if ( !m_ShowOnly )
  2100. {
  2101. if (res == cmsysProcess_State_Exited && retVal == 0)
  2102. {
  2103. fprintf(stderr," Passed\n");
  2104. passed.push_back(testname);
  2105. cres.m_Status = cmCTest::COMPLETED;
  2106. }
  2107. else
  2108. {
  2109. cres.m_Status = cmCTest::FAILED;
  2110. if ( res == cmsysProcess_State_Expired )
  2111. {
  2112. fprintf(stderr,"***Timeout\n");
  2113. cres.m_Status = cmCTest::TIMEOUT;
  2114. }
  2115. else if ( res == cmsysProcess_State_Exception )
  2116. {
  2117. fprintf(stderr,"***Exception: ");
  2118. switch ( retVal )
  2119. {
  2120. case cmsysProcess_Exception_Fault:
  2121. fprintf(stderr,"SegFault");
  2122. cres.m_Status = cmCTest::SEGFAULT;
  2123. break;
  2124. case cmsysProcess_Exception_Illegal:
  2125. fprintf(stderr,"Illegal");
  2126. cres.m_Status = cmCTest::ILLEGAL;
  2127. break;
  2128. case cmsysProcess_Exception_Interrupt:
  2129. fprintf(stderr,"Interrupt");
  2130. cres.m_Status = cmCTest::INTERRUPT;
  2131. break;
  2132. case cmsysProcess_Exception_Numerical:
  2133. fprintf(stderr,"Numerical");
  2134. cres.m_Status = cmCTest::NUMERICAL;
  2135. break;
  2136. default:
  2137. fprintf(stderr,"Other");
  2138. cres.m_Status = cmCTest::OTHER_FAULT;
  2139. }
  2140. fprintf(stderr,"\n");
  2141. }
  2142. else if ( res == cmsysProcess_State_Error )
  2143. {
  2144. fprintf(stderr,"***Bad command %d\n", res);
  2145. cres.m_Status = cmCTest::BAD_COMMAND;
  2146. }
  2147. else
  2148. {
  2149. fprintf(stderr,"***Failed\n");
  2150. }
  2151. failed.push_back(testname);
  2152. }
  2153. if (output != "")
  2154. {
  2155. if (dartStuff.find(output.c_str()))
  2156. {
  2157. std::string dartString = dartStuff.match(1);
  2158. cmSystemTools::ReplaceString(output, dartString.c_str(),"");
  2159. cres.m_RegressionImages = this->GenerateRegressionImages(dartString);
  2160. }
  2161. }
  2162. }
  2163. cres.m_Output = output;
  2164. cres.m_ReturnValue = retVal;
  2165. std::string nwd = it->m_Directory;
  2166. if ( nwd.size() > m_ToplevelPath.size() )
  2167. {
  2168. nwd = "." + nwd.substr(m_ToplevelPath.size(), nwd.npos);
  2169. }
  2170. cmSystemTools::ReplaceString(nwd, "\\", "/");
  2171. cres.m_Path = nwd;
  2172. cres.m_CompletionStatus = "Completed";
  2173. m_TestResults.push_back( cres );
  2174. }
  2175. m_EndTest = ::CurrentTime();
  2176. if ( olog )
  2177. {
  2178. *olog << "End testing: " << m_EndTest << std::endl;
  2179. }
  2180. cmSystemTools::ChangeDirectory(current_dir.c_str());
  2181. }
  2182. bool cmCTest::InitializeMemoryChecking()
  2183. {
  2184. // Setup the command
  2185. if ( cmSystemTools::FileExists(m_DartConfiguration["MemoryCheckCommand"].c_str()) )
  2186. {
  2187. m_MemoryTester
  2188. = cmSystemTools::ConvertToOutputPath(m_DartConfiguration["MemoryCheckCommand"].c_str());
  2189. }
  2190. else if ( cmSystemTools::FileExists(m_DartConfiguration["PurifyCommand"].c_str()) )
  2191. {
  2192. m_MemoryTester
  2193. = cmSystemTools::ConvertToOutputPath(m_DartConfiguration["PurifyCommand"].c_str());
  2194. }
  2195. else if ( cmSystemTools::FileExists(m_DartConfiguration["ValgrindCommand"].c_str()) )
  2196. {
  2197. m_MemoryTester
  2198. = cmSystemTools::ConvertToOutputPath(m_DartConfiguration["ValgrindCommand"].c_str());
  2199. }
  2200. else
  2201. {
  2202. std::cerr << "Memory checker (MemoryCheckCommand) not set, or cannot find the specified program."
  2203. << std::endl;
  2204. return false;
  2205. }
  2206. if ( m_MemoryTester[0] == '\"' && m_MemoryTester[m_MemoryTester.size()-1] == '\"' )
  2207. {
  2208. m_MemoryTester = m_MemoryTester.substr(1, m_MemoryTester.size()-2);
  2209. }
  2210. // Setup the options
  2211. if ( m_DartConfiguration["MemoryCheckCommandOptions"].size() )
  2212. {
  2213. m_MemoryTesterOptions = m_DartConfiguration["MemoryCheckCommandOptions"];
  2214. }
  2215. else if ( m_DartConfiguration["ValgrindCommandOptions"].size() )
  2216. {
  2217. m_MemoryTesterOptions = m_DartConfiguration["ValgrindCommandOptions"];
  2218. }
  2219. m_MemoryTesterOutputFile = m_ToplevelPath + "/Testing/Temporary/MemoryChecker.log";
  2220. m_MemoryTesterOutputFile = cmSystemTools::EscapeSpaces(m_MemoryTesterOutputFile.c_str());
  2221. if ( m_MemoryTester.find("valgrind") != std::string::npos )
  2222. {
  2223. m_MemoryTesterStyle = cmCTest::VALGRIND;
  2224. if ( !m_MemoryTesterOptions.size() )
  2225. {
  2226. m_MemoryTesterOptions = "-q --skin=memcheck --leak-check=yes --show-reachable=yes --workaround-gcc296-bugs=yes --num-callers=100";
  2227. }
  2228. if ( m_DartConfiguration["MemoryCheckSuppressionFile"].size() )
  2229. {
  2230. if ( !cmSystemTools::FileExists(m_DartConfiguration["MemoryCheckSuppressionFile"].c_str()) )
  2231. {
  2232. std::cerr << "Cannot find memory checker suppression file: "
  2233. << m_DartConfiguration["MemoryCheckSuppressionFile"].c_str() << std::endl;
  2234. return false;
  2235. }
  2236. m_MemoryTesterOptions += " --suppressions=" + cmSystemTools::EscapeSpaces(m_DartConfiguration["MemoryCheckSuppressionFile"].c_str()) + "";
  2237. }
  2238. }
  2239. else if ( m_MemoryTester.find("purify") != std::string::npos )
  2240. {
  2241. m_MemoryTesterStyle = cmCTest::PURIFY;
  2242. #ifdef _WIN32
  2243. m_MemoryTesterOptions += " /SAVETEXTDATA=" + m_MemoryTesterOutputFile;
  2244. #else
  2245. m_MemoryTesterOptions += " -log-file=" + m_MemoryTesterOutputFile;
  2246. #endif
  2247. }
  2248. else if ( m_MemoryTester.find("boundschecker") != std::string::npos )
  2249. {
  2250. m_MemoryTesterStyle = cmCTest::BOUNDS_CHECKER;
  2251. std::cerr << "Bounds checker not yet implemented" << std::endl;
  2252. return false;
  2253. }
  2254. else
  2255. {
  2256. std::cerr << "Do not understand memory checker: " << m_MemoryTester.c_str() << std::endl;
  2257. return false;
  2258. }
  2259. m_MemoryTesterOptionsParsed = cmSystemTools::ParseArguments(m_MemoryTesterOptions.c_str());
  2260. cmCTest::tm_VectorOfStrings::size_type cc;
  2261. for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
  2262. {
  2263. m_MemoryTesterGlobalResults[cc] = 0;
  2264. }
  2265. return true;
  2266. }
  2267. int cmCTest::TestDirectory(bool memcheck)
  2268. {
  2269. m_TestResults.clear();
  2270. std::cout << (memcheck ? "Memory check" : "Test") << " project" << std::endl;
  2271. if ( memcheck )
  2272. {
  2273. if ( !this->InitializeMemoryChecking() )
  2274. {
  2275. return 1;
  2276. }
  2277. }
  2278. if ( memcheck )
  2279. {
  2280. if ( !this->ExecuteCommands(m_CustomPreMemCheck) )
  2281. {
  2282. std::cerr << "Problem executing pre-memcheck command(s)." << std::endl;
  2283. return 1;
  2284. }
  2285. }
  2286. else
  2287. {
  2288. if ( !this->ExecuteCommands(m_CustomPreTest) )
  2289. {
  2290. std::cerr << "Problem executing pre-test command(s)." << std::endl;
  2291. return 1;
  2292. }
  2293. }
  2294. cmCTest::tm_VectorOfStrings passed;
  2295. cmCTest::tm_VectorOfStrings failed;
  2296. int total;
  2297. this->ProcessDirectory(passed, failed, memcheck);
  2298. total = int(passed.size()) + int(failed.size());
  2299. if (total == 0)
  2300. {
  2301. if ( !m_ShowOnly )
  2302. {
  2303. std::cerr << "No tests were found!!!\n";
  2304. }
  2305. }
  2306. else
  2307. {
  2308. if (m_Verbose && passed.size() &&
  2309. (m_UseIncludeRegExp || m_UseExcludeRegExp))
  2310. {
  2311. std::cerr << "\nThe following tests passed:\n";
  2312. for(cmCTest::tm_VectorOfStrings::iterator j = passed.begin();
  2313. j != passed.end(); ++j)
  2314. {
  2315. std::cerr << "\t" << *j << "\n";
  2316. }
  2317. }
  2318. float percent = float(passed.size()) * 100.0f / total;
  2319. if ( failed.size() > 0 && percent > 99)
  2320. {
  2321. percent = 99;
  2322. }
  2323. fprintf(stderr,"\n%.0f%% tests passed, %i tests failed out of %i\n",
  2324. percent, int(failed.size()), total);
  2325. if (failed.size())
  2326. {
  2327. std::ofstream ofs;
  2328. std::cerr << "\nThe following tests FAILED:\n";
  2329. this->OpenOutputFile("Temporary", "LastTestsFailed.log", ofs);
  2330. std::vector<cmCTest::cmCTestTestResult>::iterator ftit;
  2331. for(ftit = m_TestResults.begin();
  2332. ftit != m_TestResults.end(); ++ftit)
  2333. {
  2334. if ( ftit->m_Status != cmCTest::COMPLETED )
  2335. {
  2336. ofs << ftit->m_TestCount << ":" << ftit->m_Name << std::endl;
  2337. fprintf(stderr, "\t%3d - %s (%s)\n", ftit->m_TestCount, ftit->m_Name.c_str(),
  2338. this->GetTestStatus(ftit->m_Status));
  2339. }
  2340. }
  2341. }
  2342. }
  2343. if ( m_DartMode )
  2344. {
  2345. std::ofstream xmlfile;
  2346. if( !this->OpenOutputFile(m_CurrentTag,
  2347. (memcheck ? (m_CompatibilityMode?"Purify.xml":"DynamicAnalysis.xml") : "Test.xml"), xmlfile) )
  2348. {
  2349. std::cerr << "Cannot create " << (memcheck ? "memory check" : "testing")
  2350. << " XML file" << std::endl;
  2351. return 1;
  2352. }
  2353. if ( memcheck )
  2354. {
  2355. this->GenerateDartMemCheckOutput(xmlfile);
  2356. }
  2357. else
  2358. {
  2359. this->GenerateDartTestOutput(xmlfile);
  2360. }
  2361. }
  2362. if ( memcheck )
  2363. {
  2364. if ( !this->ExecuteCommands(m_CustomPostMemCheck) )
  2365. {
  2366. std::cerr << "Problem executing post-memcheck command(s)." << std::endl;
  2367. return 1;
  2368. }
  2369. }
  2370. else
  2371. {
  2372. if ( !this->ExecuteCommands(m_CustomPostTest) )
  2373. {
  2374. std::cerr << "Problem executing post-test command(s)." << std::endl;
  2375. return 1;
  2376. }
  2377. }
  2378. return int(failed.size());
  2379. }
  2380. int cmCTest::SubmitResults()
  2381. {
  2382. std::ofstream ofs;
  2383. this->OpenOutputFile("Temporary", "LastSubmit.log", ofs);
  2384. cmCTest::tm_VectorOfStrings files;
  2385. std::string prefix = this->GetSubmitResultsPrefix();
  2386. // TODO:
  2387. // Check if test is enabled
  2388. if ( this->CTestFileExists("Update.xml") )
  2389. {
  2390. files.push_back("Update.xml");
  2391. }
  2392. if ( this->CTestFileExists("Configure.xml") )
  2393. {
  2394. files.push_back("Configure.xml");
  2395. }
  2396. if ( this->CTestFileExists("Build.xml") )
  2397. {
  2398. files.push_back("Build.xml");
  2399. }
  2400. if ( this->CTestFileExists("Test.xml") )
  2401. {
  2402. files.push_back("Test.xml");
  2403. }
  2404. if ( this->CTestFileExists("Coverage.xml") )
  2405. {
  2406. files.push_back("Coverage.xml");
  2407. cmCTest::tm_VectorOfStrings gfiles;
  2408. std::string gpath = m_ToplevelPath + "/Testing/" + m_CurrentTag;
  2409. std::string::size_type glen = gpath.size() + 1;
  2410. gpath = gpath + "/CoverageLog*";
  2411. //std::cout << "Globbing for: " << gpath.c_str() << std::endl;
  2412. if ( cmSystemTools::SimpleGlob(gpath, gfiles, 1) )
  2413. {
  2414. size_t cc;
  2415. for ( cc = 0; cc < gfiles.size(); cc ++ )
  2416. {
  2417. gfiles[cc] = gfiles[cc].substr(glen);
  2418. //std::cout << "Glob file: " << gfiles[cc].c_str() << std::endl;
  2419. files.push_back(gfiles[cc]);
  2420. }
  2421. }
  2422. else
  2423. {
  2424. std::cerr << "Problem globbing" << std::endl;
  2425. }
  2426. }
  2427. if ( this->CTestFileExists("DynamicAnalysis.xml") )
  2428. {
  2429. files.push_back("DynamicAnalysis.xml");
  2430. }
  2431. if ( this->CTestFileExists("Purify.xml") )
  2432. {
  2433. files.push_back("Purify.xml");
  2434. }
  2435. if ( this->CTestFileExists("Notes.xml") )
  2436. {
  2437. files.push_back("Notes.xml");
  2438. }
  2439. if ( ofs )
  2440. {
  2441. ofs << "Upload files:" << std::endl;
  2442. int cnt = 0;
  2443. cmCTest::tm_VectorOfStrings::iterator it;
  2444. for ( it = files.begin(); it != files.end(); ++ it )
  2445. {
  2446. ofs << cnt << "\t" << it->c_str() << std::endl;
  2447. cnt ++;
  2448. }
  2449. }
  2450. cmCTestSubmit submit;
  2451. submit.SetVerbose(m_Verbose);
  2452. submit.SetLogFile(&ofs);
  2453. if ( m_DartConfiguration["DropMethod"] == "" ||
  2454. m_DartConfiguration["DropMethod"] == "ftp" )
  2455. {
  2456. ofs << "Using drop method: FTP" << std::endl;
  2457. std::cout << " Using FTP submit method" << std::endl;
  2458. std::string url = "ftp://";
  2459. url += cmCTest::MakeURLSafe(m_DartConfiguration["DropSiteUser"]) + ":" +
  2460. cmCTest::MakeURLSafe(m_DartConfiguration["DropSitePassword"]) + "@" +
  2461. m_DartConfiguration["DropSite"] +
  2462. cmCTest::MakeURLSafe(m_DartConfiguration["DropLocation"]);
  2463. if ( !submit.SubmitUsingFTP(m_ToplevelPath+"/Testing/"+m_CurrentTag,
  2464. files, prefix, url) )
  2465. {
  2466. std::cerr << " Problems when submitting via FTP" << std::endl;
  2467. ofs << " Problems when submitting via FTP" << std::endl;
  2468. return 0;
  2469. }
  2470. if ( !submit.TriggerUsingHTTP(files, prefix, m_DartConfiguration["TriggerSite"]) )
  2471. {
  2472. std::cerr << " Problems when triggering via HTTP" << std::endl;
  2473. ofs << " Problems when triggering via HTTP" << std::endl;
  2474. return 0;
  2475. }
  2476. std::cout << " Submission successfull" << std::endl;
  2477. ofs << " Submission succesfull" << std::endl;
  2478. return 1;
  2479. }
  2480. else if ( m_DartConfiguration["DropMethod"] == "http" )
  2481. {
  2482. ofs << "Using drop method: HTTP" << std::endl;
  2483. std::cout << " Using HTTP submit method" << std::endl;
  2484. std::string url = "http://";
  2485. if ( m_DartConfiguration["DropSiteUser"].size() > 0 )
  2486. {
  2487. url += m_DartConfiguration["DropSiteUser"];
  2488. if ( m_DartConfiguration["DropSitePassword"].size() > 0 )
  2489. {
  2490. url += ":" + m_DartConfiguration["DropSitePassword"];
  2491. }
  2492. url += "@";
  2493. }
  2494. url += m_DartConfiguration["DropSite"] + m_DartConfiguration["DropLocation"];
  2495. if ( !submit.SubmitUsingHTTP(m_ToplevelPath+"/Testing/"+m_CurrentTag, files, prefix, url) )
  2496. {
  2497. std::cerr << " Problems when submitting via HTTP" << std::endl;
  2498. ofs << " Problems when submitting via HTTP" << std::endl;
  2499. return 0;
  2500. }
  2501. if ( !submit.TriggerUsingHTTP(files, prefix, m_DartConfiguration["TriggerSite"]) )
  2502. {
  2503. std::cerr << " Problems when triggering via HTTP" << std::endl;
  2504. ofs << " Problems when triggering via HTTP" << std::endl;
  2505. return 0;
  2506. }
  2507. std::cout << " Submission successfull" << std::endl;
  2508. ofs << " Submission succesfull" << std::endl;
  2509. return 1;
  2510. }
  2511. else
  2512. {
  2513. std::cerr << "SCP submit not yet implemented" << std::endl;
  2514. ofs << "SCP submit not yet implemented" << std::endl;
  2515. }
  2516. return 0;
  2517. }
  2518. bool cmCTest::CTestFileExists(const std::string& filename)
  2519. {
  2520. std::string testingDir = m_ToplevelPath + "/Testing/" + m_CurrentTag + "/" +
  2521. filename;
  2522. return cmSystemTools::FileExists(testingDir.c_str());
  2523. }
  2524. std::string cmCTest::GetSubmitResultsPrefix()
  2525. {
  2526. std::string name = m_DartConfiguration["Site"] +
  2527. "___" + m_DartConfiguration["BuildName"] +
  2528. "___" + m_CurrentTag + "-" +
  2529. this->GetTestModelString() + "___XML___";
  2530. return name;
  2531. }
  2532. void cmCTest::GenerateDartMemCheckOutput(std::ostream& os)
  2533. {
  2534. if ( !m_DartMode )
  2535. {
  2536. return;
  2537. }
  2538. this->StartXML(os);
  2539. if ( m_CompatibilityMode )
  2540. {
  2541. os << "<Purify>" << std::endl;
  2542. }
  2543. else
  2544. {
  2545. os << "<DynamicAnalysis Checker=\"";
  2546. switch ( m_MemoryTesterStyle )
  2547. {
  2548. case cmCTest::VALGRIND:
  2549. os << "Valgrind";
  2550. break;
  2551. case cmCTest::PURIFY:
  2552. os << "Purify";
  2553. break;
  2554. case cmCTest::BOUNDS_CHECKER:
  2555. os << "BoundsChecker";
  2556. break;
  2557. default:
  2558. os << "Unknown";
  2559. }
  2560. os << "\">" << std::endl;
  2561. }
  2562. os << "\t<StartDateTime>" << m_StartTest << "</StartDateTime>\n"
  2563. << "\t<TestList>\n";
  2564. tm_TestResultsVector::size_type cc;
  2565. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  2566. {
  2567. cmCTestTestResult *result = &m_TestResults[cc];
  2568. os << "\t\t<Test>" << this->MakeXMLSafe(result->m_Path)
  2569. << "/" << this->MakeXMLSafe(result->m_Name)
  2570. << "</Test>" << std::endl;
  2571. }
  2572. os << "\t</TestList>\n";
  2573. std::cout << "-- Processing memory checking output: ";
  2574. unsigned int total = m_TestResults.size();
  2575. unsigned int step = total / 10;
  2576. unsigned int current = 0;
  2577. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  2578. {
  2579. cmCTestTestResult *result = &m_TestResults[cc];
  2580. std::string memcheckstr;
  2581. int memcheckresults[cmCTest::NO_MEMORY_FAULT];
  2582. int kk;
  2583. bool res = this->ProcessMemCheckOutput(result->m_Output, memcheckstr, memcheckresults);
  2584. if ( res && result->m_Status == cmCTest::COMPLETED )
  2585. {
  2586. continue;
  2587. }
  2588. os << "\t<Test Status=\"";
  2589. if ( result->m_Status == cmCTest::COMPLETED )
  2590. {
  2591. os << "passed";
  2592. }
  2593. else if ( result->m_Status == cmCTest::NOT_RUN )
  2594. {
  2595. os << "notrun";
  2596. }
  2597. else
  2598. {
  2599. os << "failed";
  2600. }
  2601. os << "\">\n"
  2602. << "\t\t<Name>" << this->MakeXMLSafe(result->m_Name) << "</Name>\n"
  2603. << "\t\t<Path>" << this->MakeXMLSafe(result->m_Path) << "</Path>\n"
  2604. << "\t\t<FullName>" << this->MakeXMLSafe(result->m_Path)
  2605. << "/" << this->MakeXMLSafe(result->m_Name) << "</FullName>\n"
  2606. << "\t\t<FullCommandLine>"
  2607. << this->MakeXMLSafe(result->m_FullCommandLine)
  2608. << "</FullCommandLine>\n"
  2609. << "\t\t<Results>" << std::endl;
  2610. if ( m_CompatibilityMode )
  2611. {
  2612. for ( kk = 0; cmCTestMemCheckResultStrings[kk]; kk ++ )
  2613. {
  2614. os << "\t\t\t<" << cmCTestMemCheckResultStrings[kk] << ">"
  2615. << memcheckresults[kk]
  2616. << "</" << cmCTestMemCheckResultStrings[kk] << ">" << std::endl;
  2617. m_MemoryTesterGlobalResults[kk] += memcheckresults[kk];
  2618. }
  2619. }
  2620. else
  2621. {
  2622. for ( kk = 0; cmCTestMemCheckResultLongStrings[kk]; kk ++ )
  2623. {
  2624. if ( memcheckresults[kk] )
  2625. {
  2626. os << "\t\t\t<Defect type=\"" << cmCTestMemCheckResultLongStrings[kk] << "\">"
  2627. << memcheckresults[kk]
  2628. << "</Defect>" << std::endl;
  2629. }
  2630. m_MemoryTesterGlobalResults[kk] += memcheckresults[kk];
  2631. }
  2632. }
  2633. os
  2634. << "\t\t</Results>\n"
  2635. << "\t<Log>\n" << memcheckstr << std::endl
  2636. << "\t</Log>\n"
  2637. << "\t</Test>" << std::endl;
  2638. if ( current < cc )
  2639. {
  2640. std::cout << "#";
  2641. std::cout.flush();
  2642. current += step;
  2643. }
  2644. }
  2645. std::cout << std::endl;
  2646. std::cerr << "Memory checking results:" << std::endl;
  2647. os << "\t<DefectList>" << std::endl;
  2648. for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
  2649. {
  2650. if ( m_MemoryTesterGlobalResults[cc] )
  2651. {
  2652. std::cerr.width(35);
  2653. std::cerr << cmCTestMemCheckResultLongStrings[cc] << " - "
  2654. << m_MemoryTesterGlobalResults[cc] << std::endl;
  2655. if ( !m_CompatibilityMode )
  2656. {
  2657. os << "\t\t<Defect Type=\"" << cmCTestMemCheckResultLongStrings[cc] << "\"/>" << std::endl;
  2658. }
  2659. }
  2660. }
  2661. os << "\t</DefectList>" << std::endl;
  2662. os << "\t<EndDateTime>" << m_EndTest << "</EndDateTime>" << std::endl;
  2663. if ( m_CompatibilityMode )
  2664. {
  2665. os << "</Purify>" << std::endl;
  2666. }
  2667. else
  2668. {
  2669. os << "</DynamicAnalysis>" << std::endl;
  2670. }
  2671. this->EndXML(os);
  2672. }
  2673. void cmCTest::GenerateDartTestOutput(std::ostream& os)
  2674. {
  2675. if ( !m_DartMode )
  2676. {
  2677. return;
  2678. }
  2679. this->StartXML(os);
  2680. os << "<Testing>\n"
  2681. << "\t<StartDateTime>" << m_StartTest << "</StartDateTime>\n"
  2682. << "\t<TestList>\n";
  2683. tm_TestResultsVector::size_type cc;
  2684. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  2685. {
  2686. cmCTestTestResult *result = &m_TestResults[cc];
  2687. os << "\t\t<Test>" << this->MakeXMLSafe(result->m_Path)
  2688. << "/" << this->MakeXMLSafe(result->m_Name)
  2689. << "</Test>" << std::endl;
  2690. }
  2691. os << "\t</TestList>\n";
  2692. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  2693. {
  2694. cmCTestTestResult *result = &m_TestResults[cc];
  2695. os << "\t<Test Status=\"";
  2696. if ( result->m_Status == cmCTest::COMPLETED )
  2697. {
  2698. os << "passed";
  2699. }
  2700. else if ( result->m_Status == cmCTest::NOT_RUN )
  2701. {
  2702. os << "notrun";
  2703. }
  2704. else
  2705. {
  2706. os << "failed";
  2707. }
  2708. os << "\">\n"
  2709. << "\t\t<Name>" << this->MakeXMLSafe(result->m_Name) << "</Name>\n"
  2710. << "\t\t<Path>" << this->MakeXMLSafe(result->m_Path) << "</Path>\n"
  2711. << "\t\t<FullName>" << this->MakeXMLSafe(result->m_Path)
  2712. << "/" << this->MakeXMLSafe(result->m_Name) << "</FullName>\n"
  2713. << "\t\t<FullCommandLine>"
  2714. << this->MakeXMLSafe(result->m_FullCommandLine)
  2715. << "</FullCommandLine>\n"
  2716. << "\t\t<Results>" << std::endl;
  2717. if ( result->m_Status != cmCTest::NOT_RUN )
  2718. {
  2719. if ( result->m_Status != cmCTest::COMPLETED || result->m_ReturnValue )
  2720. {
  2721. os << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Code\"><Value>"
  2722. << this->GetTestStatus(result->m_Status) << "</Value></NamedMeasurement>\n"
  2723. << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Value\"><Value>"
  2724. << result->m_ReturnValue << "</Value></NamedMeasurement>" << std::endl;
  2725. }
  2726. os << result->m_RegressionImages;
  2727. os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
  2728. << "name=\"Execution Time\"><Value>"
  2729. << result->m_ExecutionTime << "</Value></NamedMeasurement>\n";
  2730. os
  2731. << "\t\t\t<NamedMeasurement type=\"text/string\" "
  2732. << "name=\"Completion Status\"><Value>"
  2733. << result->m_CompletionStatus << "</Value></NamedMeasurement>\n";
  2734. }
  2735. os
  2736. << "\t\t\t<Measurement>\n"
  2737. << "\t\t\t\t<Value>" << this->MakeXMLSafe(result->m_Output)
  2738. << "</Value>\n"
  2739. << "\t\t\t</Measurement>\n"
  2740. << "\t\t</Results>\n"
  2741. << "\t</Test>" << std::endl;
  2742. }
  2743. os << "\t<EndDateTime>" << m_EndTest << "</EndDateTime>\n"
  2744. << "</Testing>" << std::endl;
  2745. this->EndXML(os);
  2746. }
  2747. int cmCTest::ProcessTests()
  2748. {
  2749. int res = 0;
  2750. bool notest = true;
  2751. int cc;
  2752. int update_count = 0;
  2753. for ( cc = 0; cc < LAST_TEST; cc ++ )
  2754. {
  2755. if ( m_Tests[cc] )
  2756. {
  2757. notest = false;
  2758. break;
  2759. }
  2760. }
  2761. if ( m_Tests[UPDATE_TEST] || m_Tests[ALL_TEST] )
  2762. {
  2763. update_count = this->UpdateDirectory();
  2764. if ( update_count < 0 )
  2765. {
  2766. res |= CTEST_UPDATE_ERRORS;
  2767. }
  2768. }
  2769. if ( m_TestModel == cmCTest::CONTINUOUS && !update_count )
  2770. {
  2771. return 0;
  2772. }
  2773. if ( m_Tests[CONFIGURE_TEST] || m_Tests[ALL_TEST] )
  2774. {
  2775. if (this->ConfigureDirectory())
  2776. {
  2777. res |= CTEST_CONFIGURE_ERRORS;
  2778. }
  2779. }
  2780. if ( m_Tests[BUILD_TEST] || m_Tests[ALL_TEST] )
  2781. {
  2782. this->UpdateCTestConfiguration();
  2783. if (this->BuildDirectory())
  2784. {
  2785. res |= CTEST_BUILD_ERRORS;
  2786. }
  2787. }
  2788. if ( m_Tests[TEST_TEST] || m_Tests[ALL_TEST] || notest )
  2789. {
  2790. this->UpdateCTestConfiguration();
  2791. if (this->TestDirectory(false))
  2792. {
  2793. res |= CTEST_TEST_ERRORS;
  2794. }
  2795. }
  2796. if ( m_Tests[COVERAGE_TEST] || m_Tests[ALL_TEST] )
  2797. {
  2798. this->UpdateCTestConfiguration();
  2799. this->CoverageDirectory();
  2800. }
  2801. if ( m_Tests[MEMCHECK_TEST] || m_Tests[ALL_TEST] )
  2802. {
  2803. this->UpdateCTestConfiguration();
  2804. if (this->TestDirectory(true))
  2805. {
  2806. res |= CTEST_MEMORY_ERRORS;
  2807. }
  2808. }
  2809. if ( !notest )
  2810. {
  2811. std::string notes_dir = m_ToplevelPath + "/Testing/Notes";
  2812. if ( cmSystemTools::FileIsDirectory(notes_dir.c_str()) )
  2813. {
  2814. cmsys::Directory d;
  2815. d.Load(notes_dir.c_str());
  2816. unsigned long kk;
  2817. for ( kk = 0; kk < d.GetNumberOfFiles(); kk ++ )
  2818. {
  2819. const char* file = d.GetFile(kk);
  2820. std::string fullname = notes_dir + "/" + file;
  2821. if ( cmSystemTools::FileExists(fullname.c_str()) &&
  2822. !cmSystemTools::FileIsDirectory(fullname.c_str()) )
  2823. {
  2824. if ( m_NotesFiles.size() > 0 )
  2825. {
  2826. m_NotesFiles += ";";
  2827. }
  2828. m_NotesFiles += fullname;
  2829. m_Tests[NOTES_TEST] = 1;
  2830. }
  2831. }
  2832. }
  2833. }
  2834. if ( m_Tests[NOTES_TEST] || m_Tests[ALL_TEST] )
  2835. {
  2836. this->UpdateCTestConfiguration();
  2837. if ( m_NotesFiles.size() )
  2838. {
  2839. this->GenerateNotesFile(m_NotesFiles.c_str());
  2840. }
  2841. }
  2842. if ( m_Tests[SUBMIT_TEST] || m_Tests[ALL_TEST] )
  2843. {
  2844. this->UpdateCTestConfiguration();
  2845. this->SubmitResults();
  2846. }
  2847. return res;
  2848. }
  2849. std::string cmCTest::GetTestModelString()
  2850. {
  2851. switch ( m_TestModel )
  2852. {
  2853. case cmCTest::NIGHTLY:
  2854. return "Nightly";
  2855. case cmCTest::CONTINUOUS:
  2856. return "Continuous";
  2857. }
  2858. return "Experimental";
  2859. }
  2860. int cmCTest::GetTestModelFromString(const char* str)
  2861. {
  2862. if ( !str )
  2863. {
  2864. return cmCTest::EXPERIMENTAL;
  2865. }
  2866. std::string rstr = cmSystemTools::LowerCase(str);
  2867. if ( strncmp(rstr.c_str(), "cont", 4) == 0 )
  2868. {
  2869. return cmCTest::CONTINUOUS;
  2870. }
  2871. if ( strncmp(rstr.c_str(), "nigh", 4) == 0 )
  2872. {
  2873. return cmCTest::NIGHTLY;
  2874. }
  2875. return cmCTest::EXPERIMENTAL;
  2876. }
  2877. #define SPACE_REGEX "[ \t\r\n]"
  2878. std::string cmCTest::GenerateRegressionImages(const std::string& xml)
  2879. {
  2880. cmsys::RegularExpression twoattributes(
  2881. "<DartMeasurement"
  2882. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2883. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2884. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  2885. cmsys::RegularExpression threeattributes(
  2886. "<DartMeasurement"
  2887. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2888. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2889. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2890. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  2891. cmsys::RegularExpression fourattributes(
  2892. "<DartMeasurement"
  2893. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2894. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2895. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2896. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2897. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  2898. cmsys::RegularExpression measurementfile(
  2899. "<DartMeasurementFile"
  2900. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2901. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2902. SPACE_REGEX "*>([^<]*)</DartMeasurementFile>");
  2903. cmOStringStream ostr;
  2904. bool done = false;
  2905. std::string cxml = xml;
  2906. while ( ! done )
  2907. {
  2908. if ( twoattributes.find(cxml) )
  2909. {
  2910. ostr
  2911. << "\t\t\t<NamedMeasurement"
  2912. << " " << twoattributes.match(1) << "=\"" << twoattributes.match(2) << "\""
  2913. << " " << twoattributes.match(3) << "=\"" << twoattributes.match(4) << "\""
  2914. << "><Value>" << twoattributes.match(5)
  2915. << "</Value></NamedMeasurement>"
  2916. << std::endl;
  2917. cxml.erase(twoattributes.start(), twoattributes.end() - twoattributes.start());
  2918. }
  2919. else if ( threeattributes.find(cxml) )
  2920. {
  2921. ostr
  2922. << "\t\t\t<NamedMeasurement"
  2923. << " " << threeattributes.match(1) << "=\"" << threeattributes.match(2) << "\""
  2924. << " " << threeattributes.match(3) << "=\"" << threeattributes.match(4) << "\""
  2925. << " " << threeattributes.match(5) << "=\"" << threeattributes.match(6) << "\""
  2926. << "><Value>" << threeattributes.match(7)
  2927. << "</Value></NamedMeasurement>"
  2928. << std::endl;
  2929. cxml.erase(threeattributes.start(), threeattributes.end() - threeattributes.start());
  2930. }
  2931. else if ( fourattributes.find(cxml) )
  2932. {
  2933. ostr
  2934. << "\t\t\t<NamedMeasurement"
  2935. << " " << fourattributes.match(1) << "=\"" << fourattributes.match(2) << "\""
  2936. << " " << fourattributes.match(3) << "=\"" << fourattributes.match(4) << "\""
  2937. << " " << fourattributes.match(5) << "=\"" << fourattributes.match(6) << "\""
  2938. << " " << fourattributes.match(7) << "=\"" << fourattributes.match(8) << "\""
  2939. << "><Value>" << fourattributes.match(9)
  2940. << "</Value></NamedMeasurement>"
  2941. << std::endl;
  2942. cxml.erase(fourattributes.start(), fourattributes.end() - fourattributes.start());
  2943. }
  2944. else if ( measurementfile.find(cxml) )
  2945. {
  2946. const std::string& filename = ::CleanString(measurementfile.match(5));
  2947. if ( cmSystemTools::FileExists(filename.c_str()) )
  2948. {
  2949. long len = cmSystemTools::FileLength(filename.c_str());
  2950. if ( len == 0 )
  2951. {
  2952. std::string k1 = measurementfile.match(1);
  2953. std::string v1 = measurementfile.match(2);
  2954. std::string k2 = measurementfile.match(3);
  2955. std::string v2 = measurementfile.match(4);
  2956. if ( cmSystemTools::LowerCase(k1) == "type" )
  2957. {
  2958. v1 = "text/string";
  2959. }
  2960. if ( cmSystemTools::LowerCase(k2) == "type" )
  2961. {
  2962. v2 = "text/string";
  2963. }
  2964. ostr
  2965. << "\t\t\t<NamedMeasurement"
  2966. << " " << k1 << "=\"" << v1 << "\""
  2967. << " " << k2 << "=\"" << v2 << "\""
  2968. << " encoding=\"none\""
  2969. << "><Value>Image " << filename.c_str()
  2970. << " is empty</Value></NamedMeasurement>";
  2971. }
  2972. else
  2973. {
  2974. std::ifstream ifs(filename.c_str(), std::ios::in
  2975. #ifdef _WIN32
  2976. | std::ios::binary
  2977. #endif
  2978. );
  2979. unsigned char *file_buffer = new unsigned char [ len + 1 ];
  2980. ifs.read(reinterpret_cast<char*>(file_buffer), len);
  2981. unsigned char *encoded_buffer = new unsigned char [ static_cast<int>(len * 1.5 + 5) ];
  2982. unsigned long rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
  2983. unsigned long cc;
  2984. ostr
  2985. << "\t\t\t<NamedMeasurement"
  2986. << " " << measurementfile.match(1) << "=\"" << measurementfile.match(2) << "\""
  2987. << " " << measurementfile.match(3) << "=\"" << measurementfile.match(4) << "\""
  2988. << " encoding=\"base64\""
  2989. << ">" << std::endl << "\t\t\t\t<Value>";
  2990. for ( cc = 0; cc < rlen; cc ++ )
  2991. {
  2992. ostr << encoded_buffer[cc];
  2993. if ( cc % 60 == 0 && cc )
  2994. {
  2995. ostr << std::endl;
  2996. }
  2997. }
  2998. ostr
  2999. << "</Value>" << std::endl << "\t\t\t</NamedMeasurement>"
  3000. << std::endl;
  3001. delete [] file_buffer;
  3002. delete [] encoded_buffer;
  3003. }
  3004. }
  3005. else
  3006. {
  3007. int idx = 4;
  3008. if ( measurementfile.match(1) == "name" )
  3009. {
  3010. idx = 2;
  3011. }
  3012. ostr
  3013. << "\t\t\t<NamedMeasurement"
  3014. << " name=\"" << measurementfile.match(idx) << "\""
  3015. << " text=\"text/string\""
  3016. << "><Value>File " << filename.c_str() << " not found</Value></NamedMeasurement>"
  3017. << std::endl;
  3018. std::cout << "File \"" << filename.c_str() << "\" not found." << std::endl;
  3019. }
  3020. cxml.erase(measurementfile.start(), measurementfile.end() - measurementfile.start());
  3021. }
  3022. else
  3023. {
  3024. done = true;
  3025. }
  3026. }
  3027. return ostr.str();
  3028. }
  3029. int cmCTest::RunMakeCommand(const char* command, std::string* output,
  3030. int* retVal, const char* dir, bool verbose, int timeout, std::ofstream& ofs)
  3031. {
  3032. std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
  3033. if(args.size() < 1)
  3034. {
  3035. return false;
  3036. }
  3037. std::vector<const char*> argv;
  3038. for(std::vector<cmStdString>::const_iterator a = args.begin();
  3039. a != args.end(); ++a)
  3040. {
  3041. argv.push_back(a->c_str());
  3042. }
  3043. argv.push_back(0);
  3044. if ( output )
  3045. {
  3046. *output = "";
  3047. }
  3048. cmsysProcess* cp = cmsysProcess_New();
  3049. cmsysProcess_SetCommand(cp, &*argv.begin());
  3050. cmsysProcess_SetWorkingDirectory(cp, dir);
  3051. cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
  3052. cmsysProcess_SetTimeout(cp, timeout);
  3053. cmsysProcess_Execute(cp);
  3054. std::string::size_type tick = 0;
  3055. std::string::size_type tick_len = 1024;
  3056. std::string::size_type tick_line_len = 50;
  3057. char* data;
  3058. int length;
  3059. if ( !verbose )
  3060. {
  3061. std::cout << " Each . represents " << tick_len << " bytes of output" << std::endl;
  3062. std::cout << " " << std::flush;
  3063. }
  3064. while(cmsysProcess_WaitForData(cp, &data, &length, 0))
  3065. {
  3066. if ( output )
  3067. {
  3068. for(int cc =0; cc < length; ++cc)
  3069. {
  3070. if(data[cc] == 0)
  3071. {
  3072. data[cc] = '\n';
  3073. }
  3074. }
  3075. output->append(data, length);
  3076. if ( !verbose )
  3077. {
  3078. while ( output->size() > (tick * tick_len) )
  3079. {
  3080. tick ++;
  3081. std::cout << "." << std::flush;
  3082. if ( tick % tick_line_len == 0 && tick > 0 )
  3083. {
  3084. std::cout << " Size: ";
  3085. std::cout << int((output->size() / 1024.0) + 1) << "K" << std::endl;
  3086. std::cout << " " << std::flush;
  3087. }
  3088. }
  3089. }
  3090. }
  3091. if(verbose)
  3092. {
  3093. std::cout.write(data, length);
  3094. std::cout.flush();
  3095. }
  3096. if ( ofs )
  3097. {
  3098. ofs.write(data, length);
  3099. ofs.flush();
  3100. }
  3101. }
  3102. std::cout << " Size of output: ";
  3103. std::cout << int(output->size() / 1024.0) << "K" << std::endl;
  3104. cmsysProcess_WaitForExit(cp, 0);
  3105. int result = cmsysProcess_GetState(cp);
  3106. if(result == cmsysProcess_State_Exited)
  3107. {
  3108. *retVal = cmsysProcess_GetExitValue(cp);
  3109. }
  3110. else if(result == cmsysProcess_State_Exception)
  3111. {
  3112. *retVal = cmsysProcess_GetExitException(cp);
  3113. std::cout << "There was an exception: " << *retVal << std::endl;
  3114. }
  3115. else if(result == cmsysProcess_State_Expired)
  3116. {
  3117. std::cout << "There was a timeout" << std::endl;
  3118. }
  3119. else if(result == cmsysProcess_State_Error)
  3120. {
  3121. *output += "\n*** ERROR executing: ";
  3122. *output += cmsysProcess_GetErrorString(cp);
  3123. }
  3124. cmsysProcess_Delete(cp);
  3125. return result;
  3126. }
  3127. int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, int *retVal,
  3128. std::ostream* log)
  3129. {
  3130. if(cmSystemTools::SameFile(argv[0], m_CTestSelf.c_str()) && !m_ForceNewCTestProcess)
  3131. {
  3132. cmCTest inst;
  3133. inst.m_ConfigType = m_ConfigType;
  3134. std::vector<std::string> args;
  3135. for(unsigned int i =0; i < argv.size(); ++i)
  3136. {
  3137. if(argv[i])
  3138. {
  3139. args.push_back(argv[i]);
  3140. }
  3141. }
  3142. if ( *log )
  3143. {
  3144. *log << "* Run internal CTest" << std::endl;
  3145. }
  3146. std::string oldpath = cmSystemTools::GetCurrentWorkingDirectory();
  3147. *retVal = inst.Run(args, output);
  3148. if ( *log )
  3149. {
  3150. *log << output->c_str();
  3151. }
  3152. cmSystemTools::ChangeDirectory(oldpath.c_str());
  3153. if(m_Verbose)
  3154. {
  3155. std::cout << "Internal cmCTest object used to run test.\n";
  3156. std::cout << *output << "\n";
  3157. }
  3158. return cmsysProcess_State_Exited;
  3159. }
  3160. std::vector<char> tempOutput;
  3161. if ( output )
  3162. {
  3163. *output = "";
  3164. }
  3165. cmsysProcess* cp = cmsysProcess_New();
  3166. cmsysProcess_SetCommand(cp, &*argv.begin());
  3167. // std::cout << "Command is: " << argv[0] << std::endl;
  3168. if(cmSystemTools::GetRunCommandHideConsole())
  3169. {
  3170. cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
  3171. }
  3172. cmsysProcess_SetTimeout(cp, m_TimeOut);
  3173. cmsysProcess_Execute(cp);
  3174. char* data;
  3175. int length;
  3176. while(cmsysProcess_WaitForData(cp, &data, &length, 0))
  3177. {
  3178. if ( output )
  3179. {
  3180. tempOutput.insert(tempOutput.end(), data, data+length);
  3181. }
  3182. if ( m_Verbose )
  3183. {
  3184. std::cout.write(data, length);
  3185. std::cout.flush();
  3186. }
  3187. if ( log )
  3188. {
  3189. log->write(data, length);
  3190. log->flush();
  3191. }
  3192. }
  3193. cmsysProcess_WaitForExit(cp, 0);
  3194. if(output)
  3195. {
  3196. output->append(&*tempOutput.begin(), tempOutput.size());
  3197. }
  3198. if ( m_Verbose )
  3199. {
  3200. std::cout << "-- Process completed" << std::endl;
  3201. }
  3202. int result = cmsysProcess_GetState(cp);
  3203. if(result == cmsysProcess_State_Exited)
  3204. {
  3205. *retVal = cmsysProcess_GetExitValue(cp);
  3206. }
  3207. else if(result == cmsysProcess_State_Exception)
  3208. {
  3209. *retVal = cmsysProcess_GetExitException(cp);
  3210. std::string outerr = "\n*** Exception executing: ";
  3211. outerr += cmsysProcess_GetExceptionString(cp);
  3212. *output += outerr;
  3213. if ( m_Verbose )
  3214. {
  3215. std::cout << outerr.c_str() << "\n";
  3216. std::cout.flush();
  3217. }
  3218. }
  3219. else if(result == cmsysProcess_State_Error)
  3220. {
  3221. std::string outerr = "\n*** ERROR executing: ";
  3222. outerr += cmsysProcess_GetErrorString(cp);
  3223. *output += outerr;
  3224. if ( m_Verbose )
  3225. {
  3226. std::cout << outerr.c_str() << "\n";
  3227. std::cout.flush();
  3228. }
  3229. }
  3230. cmsysProcess_Delete(cp);
  3231. return result;
  3232. }
  3233. const char* cmCTest::GetTestStatus(int status)
  3234. {
  3235. static const char statuses[][100] = {
  3236. "Not Run",
  3237. "Timeout",
  3238. "SEGFAULT",
  3239. "ILLEGAL",
  3240. "INTERRUPT",
  3241. "NUMERICAL",
  3242. "OTHER_FAULT",
  3243. "Failed",
  3244. "BAD_COMMAND",
  3245. "Completed"
  3246. };
  3247. if ( status < cmCTest::NOT_RUN || status > cmCTest::COMPLETED )
  3248. {
  3249. return "No Status";
  3250. }
  3251. return statuses[status];
  3252. }
  3253. void cmCTest::RestoreBackupDirectories(bool backup,
  3254. const char *srcDir,
  3255. const char *binDir,
  3256. const char *backupSrcDir,
  3257. const char *backupBinDir)
  3258. {
  3259. // if we backed up the dirs and the build failed, then restore
  3260. // the backed up dirs
  3261. if (backup)
  3262. {
  3263. // if for some reason those directories exist then first delete them
  3264. if (cmSystemTools::FileExists(srcDir))
  3265. {
  3266. cmSystemTools::RemoveADirectory(srcDir);
  3267. }
  3268. if (cmSystemTools::FileExists(binDir))
  3269. {
  3270. cmSystemTools::RemoveADirectory(binDir);
  3271. }
  3272. // rename the src and binary directories
  3273. rename(backupSrcDir, srcDir);
  3274. rename(backupBinDir, binDir);
  3275. }
  3276. }
  3277. int cmCTest::RunConfigurationScript()
  3278. {
  3279. int res = 0;
  3280. cmCTest::tm_VectorOfStrings::iterator it;
  3281. for ( it = m_ConfigurationScripts.begin();
  3282. it != m_ConfigurationScripts.end();
  3283. it ++ )
  3284. {
  3285. res += this->RunConfigurationScript(
  3286. cmSystemTools::CollapseFullPath(it->c_str()));
  3287. }
  3288. return res;
  3289. }
  3290. int cmCTest::RunConfigurationScript(const std::string& total_script_arg)
  3291. {
  3292. // if the argument has a , in it then it needs to be broken into the fist
  3293. // argument (which is the script) and the second argument which will be passed
  3294. // into the scripts as S_ARG
  3295. std::string script = total_script_arg;
  3296. std::string script_arg;
  3297. if (total_script_arg.find(",") != std::string::npos)
  3298. {
  3299. script = total_script_arg.substr(0,total_script_arg.find(","));
  3300. script_arg = total_script_arg.substr(total_script_arg.find(",")+1);
  3301. }
  3302. // make sure the file exists
  3303. if (!cmSystemTools::FileExists(script.c_str()))
  3304. {
  3305. std::cerr << "Cannot find file: " << script.c_str() << std::endl;
  3306. return 1;
  3307. }
  3308. // create a cmake instance to read the configuration script
  3309. cmake cm;
  3310. cmGlobalGenerator gg;
  3311. gg.SetCMakeInstance(&cm);
  3312. // read in the list file to fill the cache
  3313. std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
  3314. lg->SetGlobalGenerator(&gg);
  3315. // set a variable with the path to the current script
  3316. lg->GetMakefile()->AddDefinition("CTEST_SCRIPT_DIRECTORY",
  3317. cmSystemTools::GetFilenamePath(
  3318. script).c_str());
  3319. lg->GetMakefile()->AddDefinition("CTEST_SCRIPT_NAME",
  3320. cmSystemTools::GetFilenameName(
  3321. script).c_str());
  3322. // add the script arg if defined
  3323. if (script_arg.size())
  3324. {
  3325. lg->GetMakefile()->AddDefinition("CTEST_SCRIPT_ARG",
  3326. script_arg.c_str());
  3327. }
  3328. if (!lg->GetMakefile()->ReadListFile(0, script.c_str()))
  3329. {
  3330. return 2;
  3331. }
  3332. // no popup widows
  3333. cmSystemTools::SetRunCommandHideConsole(true);
  3334. // get some info that should be set
  3335. cmMakefile *mf = lg->GetMakefile();
  3336. const char *srcDir = mf->GetDefinition("CTEST_SOURCE_DIRECTORY");
  3337. const char *binDir = mf->GetDefinition("CTEST_BINARY_DIRECTORY");
  3338. const char *ctestCmd = mf->GetDefinition("CTEST_COMMAND");
  3339. bool backup = mf->IsOn("CTEST_BACKUP_AND_RESTORE");
  3340. // in order to back we also must have the cvs root
  3341. const char *cvsCheckOut = mf->GetDefinition("CTEST_CVS_CHECKOUT");
  3342. if (backup && !cvsCheckOut)
  3343. {
  3344. cmSystemTools::Error("Backup was requested without a cvs checkout");
  3345. return 3;
  3346. }
  3347. // make sure the required info is here
  3348. if (!srcDir || !binDir || !ctestCmd)
  3349. {
  3350. cmSystemTools::Error("Some required settings in the configuration file were missing");
  3351. return 4;
  3352. }
  3353. // set any environment variables
  3354. const char *ctestEnv = mf->GetDefinition("CTEST_ENVIRONMENT");
  3355. if (ctestEnv)
  3356. {
  3357. std::vector<std::string> envArgs;
  3358. cmSystemTools::ExpandListArgument(ctestEnv,envArgs);
  3359. // for each variable/argument do a putenv
  3360. for (unsigned i = 0; i < envArgs.size(); ++i)
  3361. {
  3362. cmSystemTools::PutEnv(envArgs[i].c_str());
  3363. }
  3364. }
  3365. // now that we have done most of the error checking finally run the
  3366. // dashboard, we may be asked to repeatedly run this dashboard, such as
  3367. // for a continuous
  3368. if (mf->GetDefinition("CTEST_CONTINUOUS_DURATION"))
  3369. {
  3370. // the *60 is becuase the settings are in minutes but GetTime is seconds
  3371. double minimumInterval = 30*60;
  3372. if (mf->GetDefinition("CTEST_CONTINUOUS_MINIMUM_INTERVAL"))
  3373. {
  3374. minimumInterval =
  3375. 60*atof(mf->GetDefinition("CTEST_CONTINUOUS_MINIMUM_INTERVAL"));
  3376. }
  3377. double duration = 60.0*atof(mf->GetDefinition("CTEST_CONTINUOUS_DURATION"));
  3378. double clock_start = cmSystemTools::GetTime();
  3379. while (cmSystemTools::GetTime() < clock_start + duration)
  3380. {
  3381. double clock_recent_start = cmSystemTools::GetTime();
  3382. this->RunConfigurationDashboard(mf, srcDir, binDir, backup,
  3383. cvsCheckOut, ctestCmd);
  3384. double interval = cmSystemTools::GetTime() - clock_recent_start;
  3385. if (interval < minimumInterval)
  3386. {
  3387. unsigned int secondsToWait =
  3388. static_cast<unsigned int>(minimumInterval - interval);
  3389. #if defined(_WIN32)
  3390. Sleep(1000*secondsToWait);
  3391. #else
  3392. sleep(secondsToWait);
  3393. #endif
  3394. }
  3395. }
  3396. }
  3397. // otherwise just run it once
  3398. else
  3399. {
  3400. return this->RunConfigurationDashboard(mf, srcDir, binDir,
  3401. backup, cvsCheckOut, ctestCmd);
  3402. }
  3403. return 0;
  3404. }
  3405. int cmCTest::RunConfigurationDashboard(cmMakefile *mf,
  3406. const char *srcDir, const char *binDir,
  3407. bool backup, const char *cvsCheckOut,
  3408. const char *ctestCmd)
  3409. {
  3410. const char *ctestRoot = mf->GetDefinition("CTEST_DASHBOARD_ROOT");
  3411. const char *cvsCmd = mf->GetDefinition("CTEST_CVS_COMMAND");
  3412. // local variables
  3413. std::string command;
  3414. std::string output;
  3415. int retVal = 0;
  3416. bool res;
  3417. // compute the backup names
  3418. std::string backupSrcDir = srcDir;
  3419. backupSrcDir += "_CMakeBackup";
  3420. std::string backupBinDir = binDir;
  3421. backupBinDir += "_CMakeBackup";
  3422. // backup the binary and src directories if requested
  3423. if (backup)
  3424. {
  3425. // if for some reason those directories exist then first delete them
  3426. if (cmSystemTools::FileExists(backupSrcDir.c_str()))
  3427. {
  3428. cmSystemTools::RemoveADirectory(backupSrcDir.c_str());
  3429. }
  3430. if (cmSystemTools::FileExists(backupBinDir.c_str()))
  3431. {
  3432. cmSystemTools::RemoveADirectory(backupBinDir.c_str());
  3433. }
  3434. // first rename the src and binary directories
  3435. rename(srcDir, backupSrcDir.c_str());
  3436. rename(binDir, backupBinDir.c_str());
  3437. // we must now checkout the src dir
  3438. output = "";
  3439. if ( m_Verbose )
  3440. {
  3441. std::cerr << "Run cvs: " << cvsCheckOut << std::endl;
  3442. }
  3443. res = cmSystemTools::RunSingleCommand(cvsCheckOut, &output,
  3444. &retVal, ctestRoot,
  3445. m_Verbose, 0 /*m_TimeOut*/);
  3446. if (!res || retVal != 0)
  3447. {
  3448. cmSystemTools::Error("Unable to perform cvs checkout ");
  3449. this->RestoreBackupDirectories(backup, srcDir, binDir,
  3450. backupSrcDir.c_str(),
  3451. backupBinDir.c_str());
  3452. return 6;
  3453. }
  3454. }
  3455. // clear the binary directory?
  3456. if (mf->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY"))
  3457. {
  3458. // try to avoid deleting directories that we shouldn't
  3459. std::string check = binDir;
  3460. check += "/CMakeCache.txt";
  3461. if (cmSystemTools::FileExists(check.c_str()))
  3462. {
  3463. cmSystemTools::RemoveADirectory(binDir);
  3464. }
  3465. }
  3466. // make sure the binary directory exists if it isn;t the srcdir
  3467. if (!cmSystemTools::FileExists(binDir) && strcmp(srcDir, binDir))
  3468. {
  3469. if (!cmSystemTools::MakeDirectory(binDir))
  3470. {
  3471. cmSystemTools::Error("Unable to create the binary directory");
  3472. this->RestoreBackupDirectories(backup, srcDir, binDir,
  3473. backupSrcDir.c_str(),
  3474. backupBinDir.c_str());
  3475. return 7;
  3476. }
  3477. }
  3478. // if the binary directory and the source directory are the same,
  3479. // and we are starting with an empty binary directory, then that means
  3480. // we must check out the source tree
  3481. if (mf->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY") &&
  3482. !strcmp(srcDir, binDir))
  3483. {
  3484. // make sure we have the required info
  3485. if (!cvsCheckOut)
  3486. {
  3487. cmSystemTools::Error("You have specified the source and binary directories to be the same (an in source build). You have also specified that the binary directory is to be erased. This means that the source will have to be checked out from CVS. But you have not specified CTEST_CVS_CHECKOUT");
  3488. return 8;
  3489. }
  3490. // we must now checkout the src dir
  3491. output = "";
  3492. if ( m_Verbose )
  3493. {
  3494. std::cerr << "Run cvs: " << cvsCheckOut << std::endl;
  3495. }
  3496. res = cmSystemTools::RunSingleCommand(cvsCheckOut, &output,
  3497. &retVal, ctestRoot,
  3498. m_Verbose, 0 /*m_TimeOut*/);
  3499. if (!res || retVal != 0)
  3500. {
  3501. cmSystemTools::Error("Unable to perform cvs checkout ");
  3502. this->RestoreBackupDirectories(backup, srcDir, binDir,
  3503. backupSrcDir.c_str(),
  3504. backupBinDir.c_str());
  3505. return 6;
  3506. }
  3507. }
  3508. // do an initial cvs update as required
  3509. if (cvsCmd)
  3510. {
  3511. command = cvsCmd;
  3512. char updateVar[40];
  3513. int i;
  3514. for (i = 1; i < 10; ++i)
  3515. {
  3516. sprintf(updateVar,"CTEST_EXTRA_UPDATES_%i",i);
  3517. const char *updateVal = mf->GetDefinition(updateVar);
  3518. if (updateVal)
  3519. {
  3520. std::vector<std::string> cvsArgs;
  3521. cmSystemTools::ExpandListArgument(updateVal,cvsArgs);
  3522. if (cvsArgs.size() == 2)
  3523. {
  3524. std::string fullCommand = command;
  3525. fullCommand += " update ";
  3526. fullCommand += cvsArgs[1];
  3527. output = "";
  3528. retVal = 0;
  3529. if ( m_Verbose )
  3530. {
  3531. std::cerr << "Run CVS: " << fullCommand.c_str() << std::endl;
  3532. }
  3533. res = cmSystemTools::RunSingleCommand(fullCommand.c_str(), &output,
  3534. &retVal, cvsArgs[0].c_str(),
  3535. m_Verbose, 0 /*m_TimeOut*/);
  3536. if (!res || retVal != 0)
  3537. {
  3538. cmSystemTools::Error("Unable to perform extra cvs updates");
  3539. this->RestoreBackupDirectories(backup, srcDir, binDir,
  3540. backupSrcDir.c_str(),
  3541. backupBinDir.c_str());
  3542. return 8;
  3543. }
  3544. }
  3545. }
  3546. }
  3547. }
  3548. // put the initial cache into the bin dir
  3549. if (mf->GetDefinition("CTEST_INITIAL_CACHE"))
  3550. {
  3551. const char *initCache = mf->GetDefinition("CTEST_INITIAL_CACHE");
  3552. std::string cacheFile = binDir;
  3553. cacheFile += "/CMakeCache.txt";
  3554. std::ofstream fout(cacheFile.c_str());
  3555. if(!fout)
  3556. {
  3557. this->RestoreBackupDirectories(backup, srcDir, binDir,
  3558. backupSrcDir.c_str(),
  3559. backupBinDir.c_str());
  3560. return 9;
  3561. }
  3562. fout.write(initCache, strlen(initCache));
  3563. // Make sure the operating system has finished writing the file
  3564. // before closing it. This will ensure the file is finished before
  3565. // the check below.
  3566. fout.flush();
  3567. fout.close();
  3568. }
  3569. // do an initial cmake to setup the DartConfig file
  3570. const char *cmakeCmd = mf->GetDefinition("CTEST_CMAKE_COMMAND");
  3571. int cmakeFailed = 0;
  3572. if (cmakeCmd)
  3573. {
  3574. command = cmakeCmd;
  3575. command += " \"";
  3576. command += srcDir;
  3577. output = "";
  3578. command += "\"";
  3579. retVal = 0;
  3580. if ( m_Verbose )
  3581. {
  3582. std::cerr << "Run cmake command: " << command.c_str() << std::endl;
  3583. }
  3584. res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
  3585. &retVal, binDir,
  3586. m_Verbose, 0 /*m_TimeOut*/);
  3587. if (!res || retVal != 0)
  3588. {
  3589. // even if this fails continue to the next step
  3590. cmakeFailed = 1;
  3591. }
  3592. }
  3593. // run ctest
  3594. command = ctestCmd;
  3595. output = "";
  3596. retVal = 0;
  3597. if ( m_Verbose )
  3598. {
  3599. std::cerr << "Run ctest command: " << command.c_str() << std::endl;
  3600. }
  3601. res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
  3602. &retVal, binDir,
  3603. m_Verbose, 0 /*m_TimeOut*/);
  3604. // did something critical fail in ctest
  3605. if (!res || cmakeFailed ||
  3606. retVal & CTEST_BUILD_ERRORS)
  3607. {
  3608. this->RestoreBackupDirectories(backup, srcDir, binDir,
  3609. backupSrcDir.c_str(),
  3610. backupBinDir.c_str());
  3611. if (cmakeFailed)
  3612. {
  3613. cmSystemTools::Error("Unable to run cmake");
  3614. return 10;
  3615. }
  3616. cmSystemTools::Error("Unable to run ctest");
  3617. if (!res)
  3618. {
  3619. return 11;
  3620. }
  3621. return retVal * 100;
  3622. }
  3623. // if all was succesful, delete the backup dirs to free up disk space
  3624. if (backup)
  3625. {
  3626. cmSystemTools::RemoveADirectory(backupSrcDir.c_str());
  3627. cmSystemTools::RemoveADirectory(backupBinDir.c_str());
  3628. }
  3629. return 0;
  3630. }
  3631. void cmCTest::StartXML(std::ostream& ostr)
  3632. {
  3633. ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  3634. << "<Site BuildName=\"" << m_DartConfiguration["BuildName"]
  3635. << "\" BuildStamp=\"" << m_CurrentTag << "-"
  3636. << this->GetTestModelString() << "\" Name=\""
  3637. << m_DartConfiguration["Site"] << "\" Generator=\"ctest\">" << std::endl;
  3638. }
  3639. void cmCTest::EndXML(std::ostream& ostr)
  3640. {
  3641. ostr << "</Site>" << std::endl;
  3642. }
  3643. bool cmCTest::ProcessMemCheckPurifyOutput(const std::string&, std::string& log,
  3644. int* results)
  3645. {
  3646. if ( !cmSystemTools::FileExists(m_MemoryTesterOutputFile.c_str()) )
  3647. {
  3648. log = "Cannot find Purify output file: " + m_MemoryTesterOutputFile;
  3649. std::cerr << log.c_str() << std::endl;
  3650. return false;
  3651. }
  3652. std::ifstream ifs(m_MemoryTesterOutputFile.c_str());
  3653. if ( !ifs )
  3654. {
  3655. log = "Cannot read Purify output file: " + m_MemoryTesterOutputFile;
  3656. std::cerr << log.c_str() << std::endl;
  3657. return false;
  3658. }
  3659. cmOStringStream ostr;
  3660. log = "";
  3661. cmsys::RegularExpression pfW("^\\[[WEI]\\] ([A-Z][A-Z][A-Z][A-Z]*): ");
  3662. int defects = 0;
  3663. std::string line;
  3664. while ( cmSystemTools::GetLineFromStream(ifs, line) )
  3665. {
  3666. int failure = cmCTest::NO_MEMORY_FAULT;
  3667. if ( pfW.find(line) )
  3668. {
  3669. int cc;
  3670. for ( cc = 0; cc < cmCTest::NO_MEMORY_FAULT; cc ++ )
  3671. {
  3672. if ( pfW.match(1) == cmCTestMemCheckResultStrings[cc] )
  3673. {
  3674. failure = cc;
  3675. break;
  3676. }
  3677. }
  3678. if ( cc == cmCTest::NO_MEMORY_FAULT )
  3679. {
  3680. std::cerr<< "Unknown Purify memory fault: " << pfW.match(1) << std::endl;
  3681. ostr << "*** Unknown Purify memory fault: " << pfW.match(1) << std::endl;
  3682. }
  3683. }
  3684. if ( failure != NO_MEMORY_FAULT )
  3685. {
  3686. ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
  3687. results[failure] ++;
  3688. defects ++;
  3689. }
  3690. ostr << cmCTest::MakeXMLSafe(line) << std::endl;
  3691. }
  3692. log = ostr.str();
  3693. if ( defects )
  3694. {
  3695. return false;
  3696. }
  3697. return true;
  3698. }
  3699. bool cmCTest::ProcessMemCheckValgrindOutput(const std::string& str, std::string& log,
  3700. int* results)
  3701. {
  3702. std::vector<cmStdString> lines;
  3703. cmSystemTools::Split(str.c_str(), lines);
  3704. std::string::size_type cc;
  3705. cmOStringStream ostr;
  3706. log = "";
  3707. int defects = 0;
  3708. cmsys::RegularExpression valgrindLine("^==[0-9][0-9]*==");
  3709. cmsys::RegularExpression vgFIM(
  3710. "== .*Invalid free\\(\\) / delete / delete\\[\\]");
  3711. cmsys::RegularExpression vgFMM(
  3712. "== .*Mismatched free\\(\\) / delete / delete \\[\\]");
  3713. cmsys::RegularExpression vgMLK(
  3714. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are definitely lost"
  3715. " in loss record [0-9][0-9]* of [0-9]");
  3716. cmsys::RegularExpression vgPAR(
  3717. "== .*Syscall param .* contains unaddressable byte\\(s\\)");
  3718. cmsys::RegularExpression vgMPK1(
  3719. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are possibly lost in"
  3720. " loss record [0-9][0-9]* of [0-9]");
  3721. cmsys::RegularExpression vgMPK2(
  3722. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are still reachable"
  3723. " in loss record [0-9][0-9]* of [0-9]");
  3724. cmsys::RegularExpression vgUMC(
  3725. "== .*Conditional jump or move depends on uninitialised value\\(s\\)");
  3726. cmsys::RegularExpression vgUMR1("== .*Use of uninitialised value of size [0-9][0-9]*");
  3727. cmsys::RegularExpression vgUMR2("== .*Invalid read of size [0-9][0-9]*");
  3728. cmsys::RegularExpression vgUMR3("== .*Jump to the invalid address ");
  3729. cmsys::RegularExpression vgUMR4(
  3730. "== .*Syscall param .* contains uninitialised or unaddressable byte\\(s\\)");
  3731. cmsys::RegularExpression vgIPW("== .*Invalid write of size [0-9]");
  3732. //double sttime = cmSystemTools::GetTime();
  3733. //std::cout << "Start test: " << lines.size() << std::endl;
  3734. for ( cc = 0; cc < lines.size(); cc ++ )
  3735. {
  3736. if ( valgrindLine.find(lines[cc]) )
  3737. {
  3738. int failure = cmCTest::NO_MEMORY_FAULT;
  3739. if ( vgFIM.find(lines[cc]) ) { failure = cmCTest::FIM; }
  3740. else if ( vgFMM.find(lines[cc]) ) { failure = cmCTest::FMM; }
  3741. else if ( vgMLK.find(lines[cc]) ) { failure = cmCTest::MLK; }
  3742. else if ( vgPAR.find(lines[cc]) ) { failure = cmCTest::PAR; }
  3743. else if ( vgMPK1.find(lines[cc]) ){ failure = cmCTest::MPK; }
  3744. else if ( vgMPK2.find(lines[cc]) ){ failure = cmCTest::MPK; }
  3745. else if ( vgUMC.find(lines[cc]) ) { failure = cmCTest::UMC; }
  3746. else if ( vgUMR1.find(lines[cc]) ){ failure = cmCTest::UMR; }
  3747. else if ( vgUMR2.find(lines[cc]) ){ failure = cmCTest::UMR; }
  3748. else if ( vgUMR3.find(lines[cc]) ){ failure = cmCTest::UMR; }
  3749. else if ( vgUMR4.find(lines[cc]) ){ failure = cmCTest::UMR; }
  3750. else if ( vgIPW.find(lines[cc]) ) { failure = cmCTest::IPW; }
  3751. if ( failure != cmCTest::NO_MEMORY_FAULT )
  3752. {
  3753. ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
  3754. results[failure] ++;
  3755. defects ++;
  3756. }
  3757. ostr << cmCTest::MakeXMLSafe(lines[cc]) << std::endl;
  3758. }
  3759. }
  3760. //std::cout << "End test (elapsed: " << (cmSystemTools::GetTime() - sttime) << std::endl;
  3761. log = ostr.str();
  3762. if ( defects )
  3763. {
  3764. return false;
  3765. }
  3766. return true;
  3767. }
  3768. bool cmCTest::ProcessMemCheckOutput(const std::string& str, std::string& log, int* results)
  3769. {
  3770. std::string::size_type cc;
  3771. for ( cc = 0; cc < cmCTest::NO_MEMORY_FAULT; cc ++ )
  3772. {
  3773. results[cc] = 0;
  3774. }
  3775. if ( m_MemoryTesterStyle == cmCTest::VALGRIND )
  3776. {
  3777. return this->ProcessMemCheckValgrindOutput(str, log, results);
  3778. }
  3779. else if ( m_MemoryTesterStyle == cmCTest::PURIFY )
  3780. {
  3781. return this->ProcessMemCheckPurifyOutput(str, log, results);
  3782. }
  3783. else if ( m_MemoryTesterStyle == cmCTest::BOUNDS_CHECKER )
  3784. {
  3785. log.append("\nMemory checking style used was: ");
  3786. log.append("Bounds Checker");
  3787. }
  3788. else
  3789. {
  3790. log.append("\nMemory checking style used was: ");
  3791. log.append("None that I know");
  3792. log = str;
  3793. }
  3794. return true;
  3795. }
  3796. int cmCTest::GenerateDartNotesOutput(std::ostream& os, const cmCTest::tm_VectorOfStrings& files)
  3797. {
  3798. cmCTest::tm_VectorOfStrings::const_iterator it;
  3799. for ( it = files.begin(); it != files.end(); it ++ )
  3800. {
  3801. if ( !cmSystemTools::FileExists(it->c_str()) )
  3802. {
  3803. std::cerr << "Error creating notes. File " << it->c_str() << " does not exists" << std::endl;
  3804. return 0;
  3805. }
  3806. }
  3807. os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  3808. << "<?xml-stylesheet type=\"text/xsl\" href=\"Dart/Source/Server/XSL/Build.xsl <file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
  3809. << "<Site BuildName=\"" << m_DartConfiguration["BuildName"] << "\" BuildStamp=\""
  3810. << m_CurrentTag << "-" << this->GetTestModelString() << "\" Name=\""
  3811. << m_DartConfiguration["Site"] << "\" Generator=\"ctest\">\n"
  3812. << "<Notes>" << std::endl;
  3813. for ( it = files.begin(); it != files.end(); it ++ )
  3814. {
  3815. std::cout << "\tAdd file: " << it->c_str() << std::endl;
  3816. std::string note_time = ::CurrentTime();
  3817. os << "<Note Name=\"" << this->MakeXMLSafe(it->c_str()) << "\">\n"
  3818. << "<DateTime>" << note_time << "</DateTime>\n"
  3819. << "<Text>" << std::endl;
  3820. std::ifstream ifs(it->c_str());
  3821. if ( ifs )
  3822. {
  3823. std::string line;
  3824. while ( cmSystemTools::GetLineFromStream(ifs, line) )
  3825. {
  3826. os << this->MakeXMLSafe(line) << std::endl;
  3827. }
  3828. ifs.close();
  3829. }
  3830. else
  3831. {
  3832. os << "Problem reading file: " << it->c_str() << std::endl;
  3833. std::cerr << "Problem reading file: " << it->c_str() << " while creating notes" << std::endl;
  3834. }
  3835. os << "</Text>\n"
  3836. << "</Note>" << std::endl;
  3837. }
  3838. os << "</Notes>\n"
  3839. << "</Site>" << std::endl;
  3840. return 1;
  3841. }
  3842. int cmCTest::GenerateNotesFile(const char* cfiles)
  3843. {
  3844. if ( !cfiles )
  3845. {
  3846. return 1;
  3847. }
  3848. std::vector<cmStdString> files;
  3849. std::cout << "Create notes file" << std::endl;
  3850. files = cmSystemTools::SplitString(cfiles, ';');
  3851. if ( files.size() == 0 )
  3852. {
  3853. return 1;
  3854. }
  3855. std::ofstream ofs;
  3856. if ( !this->OpenOutputFile(m_CurrentTag, "Notes.xml", ofs) )
  3857. {
  3858. std::cerr << "Cannot open notes file" << std::endl;
  3859. return 1;
  3860. }
  3861. this->GenerateDartNotesOutput(ofs, files);
  3862. return 0;
  3863. }
  3864. int cmCTest::Run(std::vector<std::string>const& args, std::string* output)
  3865. {
  3866. this->FindRunningCMake(args[0].c_str());
  3867. bool cmakeAndTest = false;
  3868. for(unsigned int i=1; i < args.size(); ++i)
  3869. {
  3870. std::string arg = args[i];
  3871. if(arg.find("-C",0) == 0 && i < args.size() - 1)
  3872. {
  3873. i++;
  3874. this->m_ConfigType = args[i];
  3875. }
  3876. if( arg.find("-V",0) == 0 || arg.find("--verbose",0) == 0 )
  3877. {
  3878. this->m_Verbose = true;
  3879. }
  3880. if( arg.find("-N",0) == 0 || arg.find("--show-only",0) == 0 )
  3881. {
  3882. this->m_ShowOnly = true;
  3883. }
  3884. if( arg.find("-S",0) == 0 && i < args.size() - 1 )
  3885. {
  3886. this->m_RunConfigurationScript = true;
  3887. i++;
  3888. this->m_ConfigurationScripts.push_back(args[i]);
  3889. }
  3890. if( arg.find("--tomorrow-tag",0) == 0 )
  3891. {
  3892. m_TomorrowTag = true;
  3893. }
  3894. if( arg.find("--force-new-ctest-process",0) == 0 )
  3895. {
  3896. m_ForceNewCTestProcess = true;
  3897. }
  3898. if( arg.find("--interactive-debug-mode",0) == 0 && i < args.size() - 1 )
  3899. {
  3900. i++;
  3901. m_InteractiveDebugMode = cmSystemTools::IsOn(args[i].c_str());
  3902. }
  3903. if( arg.find("--compatibility-mode",0) == 0 )
  3904. {
  3905. m_CompatibilityMode = true;
  3906. }
  3907. if( arg.find("-D",0) == 0 && i < args.size() - 1 )
  3908. {
  3909. this->m_DartMode = true;
  3910. i++;
  3911. std::string targ = args[i];
  3912. if ( targ == "Experimental" )
  3913. {
  3914. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3915. this->SetTest("Start");
  3916. this->SetTest("Configure");
  3917. this->SetTest("Build");
  3918. this->SetTest("Test");
  3919. this->SetTest("Coverage");
  3920. this->SetTest("Submit");
  3921. }
  3922. else if ( targ == "ExperimentalStart" )
  3923. {
  3924. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3925. this->SetTest("Start");
  3926. }
  3927. else if ( targ == "ExperimentalUpdate" )
  3928. {
  3929. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3930. this->SetTest("Update");
  3931. }
  3932. else if ( targ == "ExperimentalConfigure" )
  3933. {
  3934. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3935. this->SetTest("Configure");
  3936. }
  3937. else if ( targ == "ExperimentalBuild" )
  3938. {
  3939. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3940. this->SetTest("Build");
  3941. }
  3942. else if ( targ == "ExperimentalTest" )
  3943. {
  3944. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3945. this->SetTest("Test");
  3946. }
  3947. else if ( targ == "ExperimentalMemCheck" || targ == "ExperimentalPurify" )
  3948. {
  3949. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3950. this->SetTest("MemCheck");
  3951. }
  3952. else if ( targ == "ExperimentalCoverage" )
  3953. {
  3954. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3955. this->SetTest("Coverage");
  3956. }
  3957. else if ( targ == "ExperimentalSubmit" )
  3958. {
  3959. this->SetTestModel(cmCTest::EXPERIMENTAL);
  3960. this->SetTest("Submit");
  3961. }
  3962. else if ( targ == "Continuous" )
  3963. {
  3964. this->SetTestModel(cmCTest::CONTINUOUS);
  3965. this->SetTest("Start");
  3966. this->SetTest("Update");
  3967. this->SetTest("Configure");
  3968. this->SetTest("Build");
  3969. this->SetTest("Test");
  3970. this->SetTest("Coverage");
  3971. this->SetTest("Submit");
  3972. }
  3973. else if ( targ == "ContinuousStart" )
  3974. {
  3975. this->SetTestModel(cmCTest::CONTINUOUS);
  3976. this->SetTest("Start");
  3977. }
  3978. else if ( targ == "ContinuousUpdate" )
  3979. {
  3980. this->SetTestModel(cmCTest::CONTINUOUS);
  3981. this->SetTest("Update");
  3982. }
  3983. else if ( targ == "ContinuousConfigure" )
  3984. {
  3985. this->SetTestModel(cmCTest::CONTINUOUS);
  3986. this->SetTest("Configure");
  3987. }
  3988. else if ( targ == "ContinuousBuild" )
  3989. {
  3990. this->SetTestModel(cmCTest::CONTINUOUS);
  3991. this->SetTest("Build");
  3992. }
  3993. else if ( targ == "ContinuousTest" )
  3994. {
  3995. this->SetTestModel(cmCTest::CONTINUOUS);
  3996. this->SetTest("Test");
  3997. }
  3998. else if ( targ == "ContinuousMemCheck" || targ == "ContinuousPurify" )
  3999. {
  4000. this->SetTestModel(cmCTest::CONTINUOUS);
  4001. this->SetTest("MemCheck");
  4002. }
  4003. else if ( targ == "ContinuousCoverage" )
  4004. {
  4005. this->SetTestModel(cmCTest::CONTINUOUS);
  4006. this->SetTest("Coverage");
  4007. }
  4008. else if ( targ == "ContinuousSubmit" )
  4009. {
  4010. this->SetTestModel(cmCTest::CONTINUOUS);
  4011. this->SetTest("Submit");
  4012. }
  4013. else if ( targ == "Nightly" )
  4014. {
  4015. this->SetTestModel(cmCTest::NIGHTLY);
  4016. this->SetTest("Start");
  4017. this->SetTest("Update");
  4018. this->SetTest("Configure");
  4019. this->SetTest("Build");
  4020. this->SetTest("Test");
  4021. this->SetTest("Coverage");
  4022. this->SetTest("Submit");
  4023. }
  4024. else if ( targ == "NightlyStart" )
  4025. {
  4026. this->SetTestModel(cmCTest::NIGHTLY);
  4027. this->SetTest("Start");
  4028. }
  4029. else if ( targ == "NightlyUpdate" )
  4030. {
  4031. this->SetTestModel(cmCTest::NIGHTLY);
  4032. this->SetTest("Update");
  4033. }
  4034. else if ( targ == "NightlyConfigure" )
  4035. {
  4036. this->SetTestModel(cmCTest::NIGHTLY);
  4037. this->SetTest("Configure");
  4038. }
  4039. else if ( targ == "NightlyBuild" )
  4040. {
  4041. this->SetTestModel(cmCTest::NIGHTLY);
  4042. this->SetTest("Build");
  4043. }
  4044. else if ( targ == "NightlyTest" )
  4045. {
  4046. this->SetTestModel(cmCTest::NIGHTLY);
  4047. this->SetTest("Test");
  4048. }
  4049. else if ( targ == "NightlyMemCheck" || targ == "NightlyPurify" )
  4050. {
  4051. this->SetTestModel(cmCTest::NIGHTLY);
  4052. this->SetTest("MemCheck");
  4053. }
  4054. else if ( targ == "NightlyCoverage" )
  4055. {
  4056. this->SetTestModel(cmCTest::NIGHTLY);
  4057. this->SetTest("Coverage");
  4058. }
  4059. else if ( targ == "NightlySubmit" )
  4060. {
  4061. this->SetTestModel(cmCTest::NIGHTLY);
  4062. this->SetTest("Submit");
  4063. }
  4064. else if ( targ == "MemoryCheck" )
  4065. {
  4066. this->SetTestModel(cmCTest::EXPERIMENTAL);
  4067. this->SetTest("Start");
  4068. this->SetTest("Configure");
  4069. this->SetTest("Build");
  4070. this->SetTest("MemCheck");
  4071. this->SetTest("Coverage");
  4072. this->SetTest("Submit");
  4073. }
  4074. else if ( targ == "NightlyMemoryCheck" )
  4075. {
  4076. this->SetTestModel(cmCTest::NIGHTLY);
  4077. this->SetTest("Start");
  4078. this->SetTest("Update");
  4079. this->SetTest("Configure");
  4080. this->SetTest("Build");
  4081. this->SetTest("MemCheck");
  4082. this->SetTest("Coverage");
  4083. this->SetTest("Submit");
  4084. }
  4085. }
  4086. if( ( arg.find("-T",0) == 0 ) &&
  4087. (i < args.size() -1) )
  4088. {
  4089. this->m_DartMode = true;
  4090. i++;
  4091. this->SetTest(args[i].c_str());
  4092. }
  4093. if( ( arg.find("-M",0) == 0 || arg.find("--test-model",0) == 0 ) &&
  4094. (i < args.size() -1) )
  4095. {
  4096. i++;
  4097. std::string const& str = args[i];
  4098. if ( str == "NIGHTLY" || str == "nightly" || str == "Nightly" )
  4099. {
  4100. this->SetTestModel(cmCTest::NIGHTLY);
  4101. }
  4102. else if ( str == "CONTINUOUS" || str == "continuous" ||
  4103. str == "Continuous" )
  4104. {
  4105. this->SetTestModel(cmCTest::CONTINUOUS);
  4106. std::cout << "Continuous" << std::endl;
  4107. }
  4108. else
  4109. {
  4110. this->SetTestModel(cmCTest::EXPERIMENTAL);
  4111. }
  4112. }
  4113. if(arg.find("-I",0) == 0 && i < args.size() - 1)
  4114. {
  4115. i++;
  4116. this->SetTestsToRunInformation(args[i].c_str());
  4117. }
  4118. if(arg.find("-R",0) == 0 && i < args.size() - 1)
  4119. {
  4120. this->m_UseIncludeRegExp = true;
  4121. i++;
  4122. this->m_IncludeRegExp = args[i];
  4123. }
  4124. if(arg.find("-E",0) == 0 && i < args.size() - 1)
  4125. {
  4126. this->m_UseExcludeRegExp = true;
  4127. i++;
  4128. this->m_ExcludeRegExp = args[i];
  4129. this->m_UseExcludeRegExpFirst = this->m_UseIncludeRegExp ? false : true;
  4130. }
  4131. if(arg.find("-A",0) == 0 && i < args.size() - 1)
  4132. {
  4133. this->m_DartMode = true;
  4134. this->SetTest("Notes");
  4135. i++;
  4136. this->SetNotesFiles(args[i].c_str());
  4137. }
  4138. // --build-and-test options
  4139. if(arg.find("--build-and-test",0) == 0 && i < args.size() - 1)
  4140. {
  4141. cmakeAndTest = true;
  4142. if(i+2 < args.size())
  4143. {
  4144. i++;
  4145. m_SourceDir = args[i];
  4146. i++;
  4147. m_BinaryDir = args[i];
  4148. // dir must exist before CollapseFullPath is called
  4149. cmSystemTools::MakeDirectory(m_BinaryDir.c_str());
  4150. m_BinaryDir = cmSystemTools::CollapseFullPath(m_BinaryDir.c_str());
  4151. m_SourceDir = cmSystemTools::CollapseFullPath(m_SourceDir.c_str());
  4152. }
  4153. else
  4154. {
  4155. std::cerr << "--build-and-test must have source and binary dir\n";
  4156. }
  4157. }
  4158. if(arg.find("--build-target",0) == 0 && i < args.size() - 1)
  4159. {
  4160. i++;
  4161. m_BuildTarget = args[i];
  4162. }
  4163. if(arg.find("--build-nocmake",0) == 0 && i < args.size() - 1)
  4164. {
  4165. m_BuildNoCMake = true;
  4166. }
  4167. if(arg.find("--build-run-dir",0) == 0 && i < args.size() - 1)
  4168. {
  4169. i++;
  4170. m_BuildRunDir = args[i];
  4171. }
  4172. if(arg.find("--build-two-config",0) == 0 && i < args.size() - 1)
  4173. {
  4174. m_BuildTwoConfig = true;
  4175. }
  4176. if(arg.find("--build-exe-dir",0) == 0 && i < args.size() - 1)
  4177. {
  4178. i++;
  4179. m_ExecutableDirectory = args[i];
  4180. }
  4181. if(arg.find("--build-generator",0) == 0 && i < args.size() - 1)
  4182. {
  4183. i++;
  4184. m_BuildGenerator = args[i];
  4185. }
  4186. if(arg.find("--build-project",0) == 0 && i < args.size() - 1)
  4187. {
  4188. i++;
  4189. m_BuildProject = args[i];
  4190. }
  4191. if(arg.find("--build-makeprogram",0) == 0 && i < args.size() - 1)
  4192. {
  4193. i++;
  4194. m_BuildMakeProgram = args[i];
  4195. }
  4196. if(arg.find("--build-noclean",0) == 0 && i < args.size() - 1)
  4197. {
  4198. m_BuildNoClean = true;
  4199. }
  4200. if(arg.find("--build-options",0) == 0 && i < args.size() - 1)
  4201. {
  4202. ++i;
  4203. bool done = false;
  4204. while(i < args.size() && !done)
  4205. {
  4206. m_BuildOptions.push_back(args[i]);
  4207. if(i+1 < args.size()
  4208. && (args[i+1] == "--build-target" || args[i+1] == "--test-command"))
  4209. {
  4210. done = true;
  4211. }
  4212. else
  4213. {
  4214. ++i;
  4215. }
  4216. }
  4217. }
  4218. if(arg.find("--test-command",0) == 0 && i < args.size() - 1)
  4219. {
  4220. ++i;
  4221. m_TestCommand = args[i];
  4222. while(i+1 < args.size())
  4223. {
  4224. ++i;
  4225. m_TestCommandArgs.push_back(args[i]);
  4226. }
  4227. }
  4228. }
  4229. if(cmakeAndTest)
  4230. {
  4231. cmSystemTools::ResetErrorOccuredFlag();
  4232. cmListFileCache::GetInstance()->ClearCache();
  4233. int retv = this->RunCMakeAndTest(output);
  4234. cmSystemTools::ResetErrorOccuredFlag();
  4235. cmListFileCache::GetInstance()->ClearCache();
  4236. #ifdef CMAKE_BUILD_WITH_CMAKE
  4237. cmDynamicLoader::FlushCache();
  4238. #endif
  4239. return retv;
  4240. }
  4241. int res;
  4242. // call process directory
  4243. if (this->m_RunConfigurationScript)
  4244. {
  4245. res = this->RunConfigurationScript();
  4246. }
  4247. else
  4248. {
  4249. if ( !this->Initialize() )
  4250. {
  4251. res = 12;
  4252. }
  4253. else
  4254. {
  4255. res = this->ProcessTests();
  4256. }
  4257. this->Finalize();
  4258. }
  4259. return res;
  4260. }
  4261. void cmCTest::FindRunningCMake(const char* arg0)
  4262. {
  4263. // Find our own executable.
  4264. std::vector<cmStdString> failures;
  4265. m_CTestSelf = arg0;
  4266. cmSystemTools::ConvertToUnixSlashes(m_CTestSelf);
  4267. failures.push_back(m_CTestSelf);
  4268. m_CTestSelf = cmSystemTools::FindProgram(m_CTestSelf.c_str());
  4269. if(!cmSystemTools::FileExists(m_CTestSelf.c_str()))
  4270. {
  4271. failures.push_back(m_CTestSelf);
  4272. m_CTestSelf = "/usr/local/bin/ctest";
  4273. }
  4274. if(!cmSystemTools::FileExists(m_CTestSelf.c_str()))
  4275. {
  4276. failures.push_back(m_CTestSelf);
  4277. cmOStringStream msg;
  4278. msg << "CTEST can not find the command line program cmake.\n";
  4279. msg << " argv[0] = \"" << arg0 << "\"\n";
  4280. msg << " Attempted paths:\n";
  4281. std::vector<cmStdString>::iterator i;
  4282. for(i=failures.begin(); i != failures.end(); ++i)
  4283. {
  4284. msg << " \"" << i->c_str() << "\"\n";
  4285. }
  4286. cmSystemTools::Error(msg.str().c_str());
  4287. }
  4288. std::string dir;
  4289. std::string file;
  4290. if(cmSystemTools::SplitProgramPath(m_CTestSelf.c_str(),
  4291. dir,
  4292. file,
  4293. true))
  4294. {
  4295. m_CMakeSelf = dir += "/cmake";
  4296. m_CMakeSelf += cmSystemTools::GetExecutableExtension();
  4297. if(!cmSystemTools::FileExists(m_CMakeSelf.c_str()))
  4298. {
  4299. cmOStringStream msg;
  4300. failures.push_back(m_CMakeSelf);
  4301. msg << "CTEST can not find the command line program cmake.\n";
  4302. msg << " argv[0] = \"" << arg0 << "\"\n";
  4303. msg << " Attempted path:\n";
  4304. msg << " \"" << m_CMakeSelf.c_str() << "\"\n";
  4305. cmSystemTools::Error(msg.str().c_str());
  4306. }
  4307. }
  4308. }
  4309. void CMakeMessageCallback(const char* m, const char*, bool&, void* s)
  4310. {
  4311. std::string* out = (std::string*)s;
  4312. *out += m;
  4313. *out += "\n";
  4314. }
  4315. void CMakeStdoutCallback(const char* m, int len, void* s)
  4316. {
  4317. std::string* out = (std::string*)s;
  4318. out->append(m, len);
  4319. }
  4320. int cmCTest::RunCMakeAndTest(std::string* outstring)
  4321. {
  4322. unsigned int k;
  4323. std::string cmakeOutString;
  4324. cmSystemTools::SetErrorCallback(CMakeMessageCallback, &cmakeOutString);
  4325. cmSystemTools::SetStdoutCallback(CMakeStdoutCallback, &cmakeOutString);
  4326. cmOStringStream out;
  4327. cmake cm;
  4328. // default to the build type of ctest itself
  4329. if(m_ConfigType.size() == 0)
  4330. {
  4331. #ifdef CMAKE_INTDIR
  4332. m_ConfigType = CMAKE_INTDIR;
  4333. #endif
  4334. }
  4335. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  4336. out << "Internal cmake changing into directory: " << m_BinaryDir << "\n";
  4337. if (!cmSystemTools::FileIsDirectory(m_BinaryDir.c_str()))
  4338. {
  4339. cmSystemTools::MakeDirectory(m_BinaryDir.c_str());
  4340. }
  4341. cmSystemTools::ChangeDirectory(m_BinaryDir.c_str());
  4342. if(!m_BuildNoCMake)
  4343. {
  4344. std::vector<std::string> args;
  4345. args.push_back(m_CMakeSelf);
  4346. args.push_back(m_SourceDir);
  4347. if(m_BuildGenerator.size())
  4348. {
  4349. std::string generator = "-G";
  4350. generator += m_BuildGenerator;
  4351. args.push_back(generator);
  4352. }
  4353. if ( m_ConfigType.size() > 0 )
  4354. {
  4355. std::string btype = "-DBUILD_TYPE:STRING=" + m_ConfigType;
  4356. args.push_back(btype);
  4357. }
  4358. for(k=0; k < m_BuildOptions.size(); ++k)
  4359. {
  4360. args.push_back(m_BuildOptions[k]);
  4361. }
  4362. if (cm.Run(args) != 0)
  4363. {
  4364. out << "Error: cmake execution failed\n";
  4365. out << cmakeOutString << "\n";
  4366. // return to the original directory
  4367. cmSystemTools::ChangeDirectory(cwd.c_str());
  4368. if(outstring)
  4369. {
  4370. *outstring = out.str();
  4371. }
  4372. else
  4373. {
  4374. std::cerr << out.str() << "\n";
  4375. }
  4376. return 1;
  4377. }
  4378. if(m_BuildTwoConfig)
  4379. {
  4380. if (cm.Run(args) != 0)
  4381. {
  4382. out << "Error: cmake execution failed\n";
  4383. out << cmakeOutString << "\n";
  4384. // return to the original directory
  4385. cmSystemTools::ChangeDirectory(cwd.c_str());
  4386. if(outstring)
  4387. {
  4388. *outstring = out.str();
  4389. }
  4390. else
  4391. {
  4392. std::cerr << out.str() << "\n";
  4393. }
  4394. return 1;
  4395. }
  4396. }
  4397. }
  4398. cmSystemTools::SetErrorCallback(0, 0);
  4399. out << cmakeOutString << "\n";
  4400. if(m_BuildMakeProgram.size() == 0)
  4401. {
  4402. out << "Error: cmake does not have a valid MAKEPROGRAM\n";
  4403. out << "Did you specify a --build-makeprogram and a --build-generator?\n";
  4404. if(outstring)
  4405. {
  4406. *outstring = out.str();
  4407. }
  4408. else
  4409. {
  4410. std::cerr << out.str() << "\n";
  4411. }
  4412. return 1;
  4413. }
  4414. int retVal = 0;
  4415. std::string makeCommand = cmSystemTools::ConvertToOutputPath(m_BuildMakeProgram.c_str());
  4416. std::string lowerCaseCommand = cmSystemTools::LowerCase(makeCommand);
  4417. // if msdev is the make program then do the following
  4418. // MSDEV 6.0
  4419. if(lowerCaseCommand.find("msdev") != std::string::npos)
  4420. {
  4421. // if there are spaces in the makeCommand, assume a full path
  4422. // and convert it to a path with no spaces in it as the
  4423. // RunSingleCommand does not like spaces
  4424. #if defined(_WIN32) && !defined(__CYGWIN__)
  4425. if(makeCommand.find(' ') != std::string::npos)
  4426. {
  4427. cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
  4428. }
  4429. #endif
  4430. makeCommand += " ";
  4431. makeCommand += m_BuildProject;
  4432. makeCommand += ".dsw /MAKE \"ALL_BUILD - ";
  4433. makeCommand += m_ConfigType;
  4434. if(m_BuildNoClean)
  4435. {
  4436. makeCommand += "\" /BUILD";
  4437. }
  4438. else
  4439. {
  4440. makeCommand += "\" /REBUILD";
  4441. }
  4442. }
  4443. // MSDEV 7.0 .NET
  4444. else if (lowerCaseCommand.find("devenv") != std::string::npos)
  4445. {
  4446. #if defined(_WIN32) && !defined(__CYGWIN__)
  4447. if(makeCommand.find(' ') != std::string::npos)
  4448. {
  4449. cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
  4450. }
  4451. #endif
  4452. makeCommand += " ";
  4453. makeCommand += m_BuildProject;
  4454. makeCommand += ".sln ";
  4455. if(m_BuildNoClean)
  4456. {
  4457. makeCommand += "/build ";
  4458. }
  4459. else
  4460. {
  4461. makeCommand += "/rebuild ";
  4462. }
  4463. makeCommand += m_ConfigType + " /project ALL_BUILD";
  4464. }
  4465. else if (lowerCaseCommand.find("make") != std::string::npos)
  4466. {
  4467. // assume a make sytle program
  4468. // clean first
  4469. if(!m_BuildNoClean)
  4470. {
  4471. std::string cleanCommand = makeCommand;
  4472. cleanCommand += " clean";
  4473. out << "Running make clean command: " << cleanCommand.c_str() << " ...\n";
  4474. retVal = 0;
  4475. std::string output;
  4476. if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), &output, &retVal) ||
  4477. retVal)
  4478. {
  4479. out << "Error: " << cleanCommand.c_str() << " execution failed\n";
  4480. out << output.c_str() << "\n";
  4481. // return to the original directory
  4482. cmSystemTools::ChangeDirectory(cwd.c_str());
  4483. out << "Return value: " << retVal << std::endl;
  4484. if(outstring)
  4485. {
  4486. *outstring = out.str();
  4487. }
  4488. else
  4489. {
  4490. std::cerr << out.str() << "\n";
  4491. }
  4492. return 1;
  4493. }
  4494. out << output;
  4495. }
  4496. if(m_BuildTarget.size())
  4497. {
  4498. makeCommand += " ";
  4499. makeCommand += m_BuildTarget;
  4500. }
  4501. }
  4502. // command line make program
  4503. out << "Running make command: " << makeCommand.c_str() << "\n";
  4504. retVal = 0;
  4505. std::string output;
  4506. if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), &output, &retVal, 0, false))
  4507. {
  4508. out << "Error: " << makeCommand.c_str() << " execution failed\n";
  4509. out << output.c_str() << "\n";
  4510. // return to the original directory
  4511. cmSystemTools::ChangeDirectory(cwd.c_str());
  4512. out << "Return value: " << retVal << std::endl;
  4513. if(outstring)
  4514. {
  4515. *outstring = out.str();
  4516. }
  4517. else
  4518. {
  4519. std::cerr << out.str() << "\n";
  4520. }
  4521. return 1;
  4522. }
  4523. if ( retVal )
  4524. {
  4525. if(outstring)
  4526. {
  4527. *outstring = out.str();
  4528. *outstring += "Building of project failed\n";
  4529. *outstring += output;
  4530. *outstring += "\n";
  4531. }
  4532. else
  4533. {
  4534. std::cerr << "Building of project failed\n";
  4535. std::cerr << out.str() << output << "\n";
  4536. }
  4537. // return to the original directory
  4538. cmSystemTools::ChangeDirectory(cwd.c_str());
  4539. return 1;
  4540. }
  4541. out << output;
  4542. if(m_TestCommand.size() == 0)
  4543. {
  4544. if(outstring)
  4545. {
  4546. *outstring = out.str();
  4547. }
  4548. else
  4549. {
  4550. std::cout << out.str() << "\n";
  4551. }
  4552. return retVal;
  4553. }
  4554. // now run the compiled test if we can find it
  4555. std::vector<std::string> attempted;
  4556. std::vector<std::string> failed;
  4557. std::string tempPath;
  4558. std::string filepath =
  4559. cmSystemTools::GetFilenamePath(m_TestCommand);
  4560. std::string filename =
  4561. cmSystemTools::GetFilenameName(m_TestCommand);
  4562. // if full path specified then search that first
  4563. if (filepath.size())
  4564. {
  4565. tempPath = filepath;
  4566. tempPath += "/";
  4567. tempPath += filename;
  4568. attempted.push_back(tempPath);
  4569. if(m_ConfigType.size())
  4570. {
  4571. tempPath = filepath;
  4572. tempPath += "/";
  4573. tempPath += m_ConfigType;
  4574. tempPath += "/";
  4575. tempPath += filename;
  4576. attempted.push_back(tempPath);
  4577. }
  4578. }
  4579. // otherwise search local dirs
  4580. else
  4581. {
  4582. attempted.push_back(filename);
  4583. if(m_ConfigType.size())
  4584. {
  4585. tempPath = m_ConfigType;
  4586. tempPath += "/";
  4587. tempPath += filename;
  4588. attempted.push_back(tempPath);
  4589. }
  4590. }
  4591. // if m_ExecutableDirectory is set try that as well
  4592. if (m_ExecutableDirectory.size())
  4593. {
  4594. tempPath = m_ExecutableDirectory;
  4595. tempPath += "/";
  4596. tempPath += m_TestCommand;
  4597. attempted.push_back(tempPath);
  4598. if(m_ConfigType.size())
  4599. {
  4600. tempPath = m_ExecutableDirectory;
  4601. tempPath += "/";
  4602. tempPath += m_ConfigType;
  4603. tempPath += "/";
  4604. tempPath += filename;
  4605. attempted.push_back(tempPath);
  4606. }
  4607. }
  4608. // store the final location in fullPath
  4609. std::string fullPath;
  4610. // now look in the paths we specified above
  4611. for(unsigned int ai=0;
  4612. ai < attempted.size() && fullPath.size() == 0; ++ai)
  4613. {
  4614. // first check without exe extension
  4615. if(cmSystemTools::FileExists(attempted[ai].c_str())
  4616. && !cmSystemTools::FileIsDirectory(attempted[ai].c_str()))
  4617. {
  4618. fullPath = cmSystemTools::CollapseFullPath(attempted[ai].c_str());
  4619. }
  4620. // then try with the exe extension
  4621. else
  4622. {
  4623. failed.push_back(attempted[ai].c_str());
  4624. tempPath = attempted[ai];
  4625. tempPath += cmSystemTools::GetExecutableExtension();
  4626. if(cmSystemTools::FileExists(tempPath.c_str())
  4627. && !cmSystemTools::FileIsDirectory(tempPath.c_str()))
  4628. {
  4629. fullPath = cmSystemTools::CollapseFullPath(tempPath.c_str());
  4630. }
  4631. else
  4632. {
  4633. failed.push_back(tempPath.c_str());
  4634. }
  4635. }
  4636. }
  4637. if(!cmSystemTools::FileExists(fullPath.c_str()))
  4638. {
  4639. out << "Could not find path to executable, perhaps it was not built: " <<
  4640. m_TestCommand << "\n";
  4641. out << "tried to find it in these places:\n";
  4642. out << fullPath.c_str() << "\n";
  4643. for(unsigned int i=0; i < failed.size(); ++i)
  4644. {
  4645. out << failed[i] << "\n";
  4646. }
  4647. if(outstring)
  4648. {
  4649. *outstring = out.str();
  4650. }
  4651. else
  4652. {
  4653. std::cerr << out.str();
  4654. }
  4655. // return to the original directory
  4656. cmSystemTools::ChangeDirectory(cwd.c_str());
  4657. return 1;
  4658. }
  4659. std::vector<const char*> testCommand;
  4660. testCommand.push_back(fullPath.c_str());
  4661. for(k=0; k < m_TestCommandArgs.size(); ++k)
  4662. {
  4663. testCommand.push_back(m_TestCommandArgs[k].c_str());
  4664. }
  4665. testCommand.push_back(0);
  4666. std::string outs;
  4667. int retval = 0;
  4668. // run the test from the m_BuildRunDir if set
  4669. if(m_BuildRunDir.size())
  4670. {
  4671. out << "Run test in directory: " << m_BuildRunDir << "\n";
  4672. cmSystemTools::ChangeDirectory(m_BuildRunDir.c_str());
  4673. }
  4674. out << "Running test executable: " << fullPath << " ";
  4675. for(k=0; k < m_TestCommandArgs.size(); ++k)
  4676. {
  4677. out << m_TestCommandArgs[k] << " ";
  4678. }
  4679. out << "\n";
  4680. int runTestRes = this->RunTest(testCommand, &outs, &retval, 0);
  4681. if(runTestRes != cmsysProcess_State_Exited || retval != 0)
  4682. {
  4683. out << "Failed to run test command: " << testCommand[0] << "\n";
  4684. retval = 1;
  4685. }
  4686. out << outs << "\n";
  4687. if(outstring)
  4688. {
  4689. *outstring = out.str();
  4690. }
  4691. else
  4692. {
  4693. std::cout << out.str() << "\n";
  4694. }
  4695. return retval;
  4696. }
  4697. void cmCTest::SetNotesFiles(const char* notes)
  4698. {
  4699. if ( !notes )
  4700. {
  4701. return;
  4702. }
  4703. m_NotesFiles = notes;
  4704. }
  4705. int cmCTest::ReadCustomConfigurationFileTree(const char* dir)
  4706. {
  4707. tm_VectorOfStrings dirs;
  4708. tm_VectorOfStrings ndirs;
  4709. dirs.push_back(dir);
  4710. cmake cm;
  4711. cmGlobalGenerator gg;
  4712. gg.SetCMakeInstance(&cm);
  4713. std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
  4714. lg->SetGlobalGenerator(&gg);
  4715. cmMakefile *mf = lg->GetMakefile();
  4716. while ( dirs.size() > 0 )
  4717. {
  4718. tm_VectorOfStrings::iterator cdir = dirs.end()-1;
  4719. std::string rexpr = *cdir + "/*";
  4720. std::string fname = *cdir + "/CTestCustom.ctest";
  4721. if ( cmSystemTools::FileExists(fname.c_str()) &&
  4722. (!lg->GetMakefile()->ReadListFile(0, fname.c_str()) ||
  4723. cmSystemTools::GetErrorOccuredFlag() ) )
  4724. {
  4725. std::cerr << "Problem reading custom configuration" << std::endl;
  4726. }
  4727. dirs.erase(dirs.end()-1, dirs.end());
  4728. cmSystemTools::SimpleGlob(rexpr, ndirs, -1);
  4729. dirs.insert(dirs.end(), ndirs.begin(), ndirs.end());
  4730. }
  4731. this->PopulateCustomVector(mf, "CTEST_CUSTOM_ERROR_MATCH", m_CustomErrorMatches);
  4732. this->PopulateCustomVector(mf, "CTEST_CUSTOM_ERROR_EXCEPTION", m_CustomErrorExceptions);
  4733. this->PopulateCustomVector(mf, "CTEST_CUSTOM_WARNING_MATCH", m_CustomWarningMatches);
  4734. this->PopulateCustomVector(mf, "CTEST_CUSTOM_WARNING_EXCEPTION", m_CustomWarningExceptions);
  4735. this->PopulateCustomVector(mf, "CTEST_CUSTOM_TESTS_IGNORE", m_CustomTestsIgnore);
  4736. this->PopulateCustomVector(mf, "CTEST_CUSTOM_MEMCHECK_IGNORE", m_CustomMemCheckIgnore);
  4737. this->PopulateCustomVector(mf, "CTEST_CUSTOM_PRE_TEST", m_CustomPreTest);
  4738. this->PopulateCustomVector(mf, "CTEST_CUSTOM_POST_TEST", m_CustomPostTest);
  4739. this->PopulateCustomVector(mf, "CTEST_CUSTOM_PRE_MEMCHECK", m_CustomPreMemCheck);
  4740. this->PopulateCustomVector(mf, "CTEST_CUSTOM_POST_MEMCHECK", m_CustomPostMemCheck);
  4741. return 1;
  4742. }
  4743. void cmCTest::PopulateCustomVector(cmMakefile* mf, const char* def, tm_VectorOfStrings& vec)
  4744. {
  4745. if ( !def)
  4746. {
  4747. return;
  4748. }
  4749. const char* dval = mf->GetDefinition(def);
  4750. if ( !dval )
  4751. {
  4752. return;
  4753. }
  4754. std::vector<std::string> slist;
  4755. cmSystemTools::ExpandListArgument(dval, slist);
  4756. std::vector<std::string>::iterator it;
  4757. for ( it = slist.begin(); it != slist.end(); ++it )
  4758. {
  4759. vec.push_back(it->c_str());
  4760. }
  4761. }
  4762. int cmCTest::ExecuteCommands(tm_VectorOfStrings& vec)
  4763. {
  4764. tm_VectorOfStrings::iterator it;
  4765. for ( it = vec.begin(); it != vec.end(); ++it )
  4766. {
  4767. int retVal = 0;
  4768. if ( m_Verbose )
  4769. {
  4770. std::cout << "Run command: " << *it << std::endl;
  4771. }
  4772. if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, &retVal, 0, true /*m_Verbose*/) ||
  4773. retVal != 0 )
  4774. {
  4775. std::cerr << "Problem running command: " << *it << std::endl;
  4776. return 0;
  4777. }
  4778. }
  4779. return 1;
  4780. }
  4781. // get the next number in a string with numbers separated by ,
  4782. // pos is the start of the search and pos2 is the end of the search
  4783. // pos becomes pos2 after a call to GetNextNumber.
  4784. // -1 is returned at the end of the list.
  4785. inline int GetNextNumber(std::string const& in,
  4786. int& val,
  4787. std::string::size_type& pos,
  4788. std::string::size_type& pos2)
  4789. {
  4790. pos2 = in.find(',', pos);
  4791. if(pos2 != in.npos)
  4792. {
  4793. if(pos2-pos == 0)
  4794. {
  4795. val = -1;
  4796. }
  4797. else
  4798. {
  4799. val = atoi(in.substr(pos, pos2-pos).c_str());
  4800. }
  4801. pos = pos2+1;
  4802. return 1;
  4803. }
  4804. else
  4805. {
  4806. if(in.size()-pos == 0)
  4807. {
  4808. val = -1;
  4809. }
  4810. else
  4811. {
  4812. val = atoi(in.substr(pos, in.size()-pos).c_str());
  4813. }
  4814. return 0;
  4815. }
  4816. }
  4817. void cmCTest::SetTestsToRunInformation(const char* in)
  4818. {
  4819. this->TestsToRunString = in;
  4820. // if the argument is a file, then read it and use the contents as the string
  4821. if(cmSystemTools::FileExists(in))
  4822. {
  4823. std::ifstream fin(in);
  4824. unsigned long filelen = cmSystemTools::FileLength(in);
  4825. char* buff = new char[filelen+1];
  4826. fin.getline(buff, filelen);
  4827. buff[fin.gcount()] = 0;
  4828. this->TestsToRunString = buff;
  4829. }
  4830. }
  4831. void cmCTest::ExpandTestsToRunInformation(int numTests)
  4832. {
  4833. if (this->TestsToRunString.empty())
  4834. {
  4835. return;
  4836. }
  4837. int start;
  4838. int end = -1;
  4839. int stride = -1;
  4840. std::string::size_type pos = 0;
  4841. std::string::size_type pos2;
  4842. // read start
  4843. if(GetNextNumber(this->TestsToRunString, start, pos, pos2))
  4844. {
  4845. // read end
  4846. if(GetNextNumber(this->TestsToRunString, end, pos, pos2))
  4847. {
  4848. // read stride
  4849. if(GetNextNumber(this->TestsToRunString, stride, pos, pos2))
  4850. {
  4851. int val =0;
  4852. // now read specific numbers
  4853. while(GetNextNumber(this->TestsToRunString, val, pos, pos2))
  4854. {
  4855. m_TestsToRun.push_back(val);
  4856. }
  4857. m_TestsToRun.push_back(val);
  4858. }
  4859. }
  4860. }
  4861. // if start and specific tests are not specified then we assume we start at
  4862. // 1
  4863. if(start == -1 && !m_TestsToRun.size())
  4864. {
  4865. start = 1;
  4866. }
  4867. // if end and specific tests are not specified then we assume we end with
  4868. // the last test
  4869. if(end == -1 && !m_TestsToRun.size())
  4870. {
  4871. end = numTests;
  4872. }
  4873. // if the stride wasn't specified then it defaults to 1
  4874. if(stride == -1)
  4875. {
  4876. stride = 1;
  4877. }
  4878. // if we have a range then add it
  4879. if(end != -1 && start != -1)
  4880. {
  4881. for(int i =start; i <= end; i+= stride)
  4882. {
  4883. m_TestsToRun.push_back(i);
  4884. }
  4885. }
  4886. // sort the array
  4887. std::sort(m_TestsToRun.begin(), m_TestsToRun.end(), std::less<int>());
  4888. // remove duplicates
  4889. std::vector<int>::iterator new_end =
  4890. std::unique(m_TestsToRun.begin(), m_TestsToRun.end());
  4891. m_TestsToRun.erase(new_end, m_TestsToRun.end());
  4892. std::cout << "Running tests: ";
  4893. for(unsigned int i =0; i < m_TestsToRun.size(); ++i)
  4894. {
  4895. std::cout << m_TestsToRun[i] << " ";
  4896. }
  4897. std::cout << "\n";
  4898. }