summaryrefslogtreecommitdiffstats
path: root/Source/CTest
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2012-05-01 21:00:43 (GMT)
committerBill Hoffman <bill.hoffman@kitware.com>2012-05-01 21:00:43 (GMT)
commit7955e995ec400fb063529064b6232ca0eedfe5e0 (patch)
treebc3d928ad0b31dd93634794b83b425dfc8cdd8f7 /Source/CTest
parenta86cd33cdd497acdb6b77a44c146a9779730675e (diff)
downloadCMake-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.cxx25
-rw-r--r--Source/CTest/cmCTestCoverageHandler.h4
-rw-r--r--Source/CTest/cmParseCacheCoverage.cxx187
-rw-r--r--Source/CTest/cmParseCacheCoverage.h40
-rw-r--r--Source/CTest/cmParseGTMCoverage.cxx28
-rw-r--r--Source/CTest/cmParseMumpsCoverage.cxx28
-rw-r--r--Source/CTest/cmParseMumpsCoverage.h3
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;