cmCTest.cxx 159 KB

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