diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2012-05-01 21:00:43 (GMT) |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2012-05-01 21:00:43 (GMT) |
commit | 7955e995ec400fb063529064b6232ca0eedfe5e0 (patch) | |
tree | bc3d928ad0b31dd93634794b83b425dfc8cdd8f7 /Source/CTest | |
parent | a86cd33cdd497acdb6b77a44c146a9779730675e (diff) | |
download | CMake-7955e995ec400fb063529064b6232ca0eedfe5e0.zip CMake-7955e995ec400fb063529064b6232ca0eedfe5e0.tar.gz CMake-7955e995ec400fb063529064b6232ca0eedfe5e0.tar.bz2 |
Add support for Cache coverage.
This adds support for Cache coverage parsing. A test is added
that does a basic run of the coverage on a small bit of data.
Diffstat (limited to 'Source/CTest')
-rw-r--r-- | Source/CTest/cmCTestCoverageHandler.cxx | 25 | ||||
-rw-r--r-- | Source/CTest/cmCTestCoverageHandler.h | 4 | ||||
-rw-r--r-- | Source/CTest/cmParseCacheCoverage.cxx | 187 | ||||
-rw-r--r-- | Source/CTest/cmParseCacheCoverage.h | 40 | ||||
-rw-r--r-- | Source/CTest/cmParseGTMCoverage.cxx | 28 | ||||
-rw-r--r-- | Source/CTest/cmParseMumpsCoverage.cxx | 28 | ||||
-rw-r--r-- | Source/CTest/cmParseMumpsCoverage.h | 3 |
7 files changed, 285 insertions, 30 deletions
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index e7fa2f1..48bea64 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -12,6 +12,7 @@ #include "cmCTestCoverageHandler.h" #include "cmParsePHPCoverage.h" #include "cmParseGTMCoverage.h" +#include "cmParseCacheCoverage.h" #include "cmCTest.h" #include "cmake.h" #include "cmMakefile.h" @@ -391,7 +392,7 @@ int cmCTestCoverageHandler::ProcessHandler() { return error; } - file_count += this->HandleGTMCoverage(&cont); + file_count += this->HandleMumpsCoverage(&cont); error = cont.Error; if ( file_count < 0 ) { @@ -761,20 +762,38 @@ int cmCTestCoverageHandler::HandlePHPCoverage( return static_cast<int>(cont->TotalCoverage.size()); } //---------------------------------------------------------------------- -int cmCTestCoverageHandler::HandleGTMCoverage( +int cmCTestCoverageHandler::HandleMumpsCoverage( cmCTestCoverageHandlerContainer* cont) { + // try gtm coverage cmParseGTMCoverage cov(*cont, this->CTest); std::string coverageFile = this->CTest->GetBinaryDir() + "/gtm_coverage.mcov"; if(cmSystemTools::FileExists(coverageFile.c_str())) { cov.ReadCoverageFile(coverageFile.c_str()); + return static_cast<int>(cont->TotalCoverage.size()); } else { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " Cannot find GTM coverage file: " << coverageFile + " Cannot find foobar GTM coverage file: " << coverageFile + << std::endl); + } + cmParseCacheCoverage ccov(*cont, this->CTest); + coverageFile = this->CTest->GetBinaryDir() + + "/cache_coverage.cmcov"; + if(cmSystemTools::FileExists(coverageFile.c_str())) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Parsing Cache Coverage: " << coverageFile + << std::endl); + ccov.ReadCoverageFile(coverageFile.c_str()); + } + else + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Cannot find Cache coverage file: " << coverageFile << std::endl); } return static_cast<int>(cont->TotalCoverage.size()); diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index f4c275f..92b0b22 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h @@ -70,8 +70,8 @@ private: //! Handle coverage using xdebug php coverage int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont); - //! Handle coverage using GTM - int HandleGTMCoverage(cmCTestCoverageHandlerContainer* cont); + //! Handle coverage for mumps + int HandleMumpsCoverage(cmCTestCoverageHandlerContainer* cont); //! Handle coverage using Bullseye int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont); diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx new file mode 100644 index 0000000..d2ff404 --- /dev/null +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -0,0 +1,187 @@ +#include "cmStandardIncludes.h" +#include <stdio.h> +#include <stdlib.h> +#include "cmSystemTools.h" +#include "cmParseCacheCoverage.h" +#include <cmsys/Directory.hxx> +#include <cmsys/Glob.hxx> + + +cmParseCacheCoverage::cmParseCacheCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest) + :cmParseMumpsCoverage(cont, ctest) +{ +} + + +bool cmParseCacheCoverage::LoadCoverageData(const char* d) +{ + // load all the .mcov files in the specified directory + cmsys::Directory dir; + if(!dir.Load(d)) + { + return false; + } + size_t numf; + unsigned int i; + numf = dir.GetNumberOfFiles(); + for (i = 0; i < numf; i++) + { + std::string file = dir.GetFile(i); + if(file != "." && file != ".." + && !cmSystemTools::FileIsDirectory(file.c_str())) + { + std::string path = d; + path += "/"; + path += file; + if(cmSystemTools::GetFilenameLastExtension(path) == ".cmcov") + { + if(!this->ReadCMCovFile(path.c_str())) + { + return false; + } + } + } + } + return true; +} + +bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args, + std::string const& line) +{ + std::string::size_type pos1 = 0; + std::string::size_type pos2 = line.find(',', 0); + if(pos2 == std::string::npos) + { + return false; + } + std::string arg; + while(pos2 != std::string::npos) + { + arg = line.substr(pos1, pos2-pos1); + args.push_back(arg); + pos1 = pos2+1; + pos2 = line.find(',',pos1); + } + arg = line.substr(pos1); + args.push_back(arg); + return true; +} + +bool cmParseCacheCoverage::ReadCMCovFile(const char* file) +{ + std::ifstream in(file); + if(!in) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Can not open : " + << file << "\n"); + return false; + } + std::string line; + std::vector<std::string> separateLine; + if(!cmSystemTools::GetLineFromStream(in, line)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Empty file : " + << file << " referenced in this line of cmcov data:\n" + "[" << line << "]\n"); + return false; + } + separateLine.clear(); + this->SplitString(separateLine, line); + if(separateLine.size() !=4 || separateLine[0] != "Routine" + || separateLine[1] != "Line" || separateLine[2] != "RtnLine" + || separateLine[3] != "Code") + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Bad first line of cmcov file : " + << file << " line:\n" + "[" << line << "]\n"); + } + std::string routine; + std::string filepath; + bool foundFile = false; + while(cmSystemTools::GetLineFromStream(in, line)) + { + // clear out line argument vector + separateLine.clear(); + // parse the comma separated line + this->SplitString(separateLine, line); + // might have more because code could have a quoted , in it + // but we only care about the first 3 args anyway + if(separateLine.size() < 4) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Bad line of cmcov file expected at least 4 found: " + << separateLine.size() << " " + << file << " line:\n" + "[" << line << "]\n"); + for(std::string::size_type i = 0; i < separateLine.size(); ++i) + { + cmCTestLog(this->CTest, ERROR_MESSAGE,"" + << separateLine[1] << " "); + } + cmCTestLog(this->CTest, ERROR_MESSAGE, "\n"); + return false; + } + // if we do not have a routine yet, then it should be + // the first argument in the vector + if(routine.size() == 0) + { + routine = separateLine[0]; + // Find the full path to the file + if(!this->FindMumpsFile(routine, filepath)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Could not find mumps file for routine: " + << routine << "\n"); + filepath = ""; + continue; // move to next line + } + } + // if we have a routine name, check for end of routine + else + { + // Totals in arg 0 marks the end of a routine + if(separateLine[0].substr(0, 6) == "Totals") + { + routine = ""; // at the end of this routine + filepath = ""; + continue; // move to next line + } + } + // if the file path was not found for the routine + // move to next line. We should have already warned + // after the call to FindMumpsFile that we did not find + // it, so don't report again to cut down on output + if(filepath.size() == 0) + { + continue; + } + // routine and filepath should be set at this point. + // see if we have visited this file before, and if not + // call InitializeMumpsFile + if( this->Coverage.TotalCoverage[filepath].size() == 0) + { + // hack, this should be done on every file, but for now + // just do it on the ones that have coverage at all + this->InitializeMumpsFile(filepath); + } + // now we are ready to set the coverage from the line of data + cmCTestCoverageHandlerContainer::SingleFileCoverageVector& + coverageVector = this->Coverage.TotalCoverage[filepath]; + std::string::size_type linenumber = atoi(separateLine[1].c_str()) -1; + int count = atoi(separateLine[2].c_str()); + if(linenumber > coverageVector.size()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Parse error line is greater than number of lines in file: " + << linenumber << " " << filepath << "\n"); + continue; // skip setting count to avoid crash + } + // now add to count for linenumber + coverageVector[linenumber] += count; + } + return true; +} diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h new file mode 100644 index 0000000..f377567 --- /dev/null +++ b/Source/CTest/cmParseCacheCoverage.h @@ -0,0 +1,40 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmParseCacheCoverage_h +#define cmParseCacheCoverage_h + +#include "cmParseMumpsCoverage.h" + +/** \class cmParseCacheCoverage + * \brief Parse Cache coverage information + * + * This class is used to parse Cache coverage information for + * mumps. + */ +class cmParseCacheCoverage : public cmParseMumpsCoverage +{ +public: + cmParseCacheCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest); +protected: + // implement virtual from parent + bool LoadCoverageData(const char* dir); + // Read a single mcov file + bool ReadCMCovFile(const char* f); + // split a string based on , + bool SplitString(std::vector<std::string>& args, + std::string const& line); +}; + + +#endif diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index 90d047b..f850c3c 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -88,36 +88,14 @@ bool cmParseGTMCoverage::ReadMCovFile(const char* file) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Can not find mumps file : " - << lastroutine << " referenced in this line of mcov data:\n" + << lastroutine << + " referenced in this line of mcov data:\n" "[" << line << "]\n"); } continue; } // Find the full path to the file - std::map<cmStdString, cmStdString>::iterator i = - this->RoutineToDirectory.find(routine); - bool found = false; - if(i != this->RoutineToDirectory.end()) - { - filepath = i->second; - found = true; - } - else - { - // try some alternate names - const char* tryname[] = {"GUX", "GTM", "ONT", 0}; - for(int k=0; tryname[k] != 0; k++) - { - std::string routine2 = routine + tryname[k]; - i = this->RoutineToDirectory.find(routine2); - if(i != this->RoutineToDirectory.end()) - { - found = true; - filepath = i->second; - break; // break out of tryname loop if found - } - } - } + bool found = this->FindMumpsFile(routine, filepath); if(found) { int lineoffset; diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx index 761139f..ed263a4 100644 --- a/Source/CTest/cmParseMumpsCoverage.cxx +++ b/Source/CTest/cmParseMumpsCoverage.cxx @@ -127,3 +127,31 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d) } return true; } + +bool cmParseMumpsCoverage::FindMumpsFile(std::string const& routine, + std::string& filepath) +{ + std::map<cmStdString, cmStdString>::iterator i = + this->RoutineToDirectory.find(routine); + if(i != this->RoutineToDirectory.end()) + { + filepath = i->second; + return true; + } + else + { + // try some alternate names + const char* tryname[] = {"GUX", "GTM", "ONT", 0}; + for(int k=0; tryname[k] != 0; k++) + { + std::string routine2 = routine + tryname[k]; + i = this->RoutineToDirectory.find(routine2); + if(i != this->RoutineToDirectory.end()) + { + filepath = i->second; + return true; + } + } + } + return false; +} diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h index 81180ee..c1effa7 100644 --- a/Source/CTest/cmParseMumpsCoverage.h +++ b/Source/CTest/cmParseMumpsCoverage.h @@ -40,6 +40,9 @@ protected: bool LoadPackages(const char* dir); // initialize the coverage information for a single mumps file void InitializeMumpsFile(std::string& file); + // Find mumps file for routine + bool FindMumpsFile(std::string const& routine, + std::string& filepath); protected: std::map<cmStdString, cmStdString> RoutineToDirectory; cmCTestCoverageHandlerContainer& Coverage; |