summaryrefslogtreecommitdiffstats
path: root/Source/CTest/cmParseCoberturaCoverage.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest/cmParseCoberturaCoverage.cxx')
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.cxx200
1 files changed, 200 insertions, 0 deletions
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
new file mode 100644
index 0000000..3ed5cb0
--- /dev/null
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -0,0 +1,200 @@
+#include "cmStandardIncludes.h"
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+#include "cmParseCoberturaCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/FStream.hxx>
+
+//----------------------------------------------------------------------------
+class cmParseCoberturaCoverage::XMLParser: public cmXMLParser
+{
+public:
+ XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
+ : CTest(ctest), Coverage(cont)
+ {
+ this->InSources = false;
+ this->InSource = false;
+ this->SkipThisClass = false;
+ this->FilePaths.push_back(this->Coverage.SourceDir);
+ this->FilePaths.push_back(this->Coverage.BinaryDir);
+ this->CurFileName = "";
+ }
+
+ virtual ~XMLParser()
+ {
+ }
+
+protected:
+
+
+ virtual void EndElement(const std::string& name)
+ {
+ if(name == "source")
+ {
+ this->InSource=false;
+ }
+ else if (name == "sources")
+ {
+ this->InSources=false;
+ }
+ else if(name == "class")
+ {
+ this->SkipThisClass = false;
+ }
+ }
+
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ std::string tmp;
+ tmp.insert(0,data,length);
+ if (this->InSources && this->InSource)
+ {
+ this->FilePaths.push_back(tmp);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Adding Source: " << tmp << std::endl, this->Coverage.Quiet);
+ }
+ }
+
+ virtual void StartElement(const std::string& name, const char** atts)
+ {
+ std::string FoundSource;
+ std::string finalpath = "";
+ if(name == "source")
+ {
+ this->InSource = true;
+ }
+ else if(name == "sources")
+ {
+ this->InSources = true;
+ }
+ else if(name == "class")
+ {
+ int tagCount = 0;
+ while(true)
+ {
+ if(strcmp(atts[tagCount], "filename") == 0)
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Reading file: " << atts[tagCount+1]<< std::endl,
+ this->Coverage.Quiet);
+ std::string filename = atts[tagCount+1];
+ this->CurFileName = "";
+
+ // Check if this is an absolute path that falls within our
+ // source or binary directories.
+ for(size_t i=0;i < FilePaths.size();i++)
+ {
+ if (filename.find(FilePaths[i]) == 0)
+ {
+ this->CurFileName = filename;
+ break;
+ }
+ }
+
+ if (this->CurFileName == "")
+ {
+ // Check if this is a path that is relative to our source or
+ // binary directories.
+ for(size_t i=0;i < FilePaths.size();i++)
+ {
+ finalpath = FilePaths[i] + "/" + filename;
+ if(cmSystemTools::FileExists(finalpath.c_str()))
+ {
+ this->CurFileName = finalpath;
+ break;
+ }
+ }
+ }
+
+ cmsys::ifstream fin(this->CurFileName.c_str());
+ if(this->CurFileName == "" || !fin )
+ {
+ this->CurFileName = this->Coverage.BinaryDir + "/" +
+ atts[tagCount+1];
+ fin.open(this->CurFileName.c_str());
+ if (!fin)
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Skipping system file " << filename << std::endl,
+ this->Coverage.Quiet);
+
+ this->SkipThisClass = true;
+ break;
+ }
+ }
+ std::string line;
+ FileLinesType& curFileLines =
+ this->Coverage.TotalCoverage[this->CurFileName];
+ curFileLines.push_back(-1);
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ curFileLines.push_back(-1);
+ }
+
+ break;
+ }
+ ++tagCount;
+ }
+ }
+ else if(name == "line")
+ {
+ int tagCount = 0;
+ int curNumber = -1;
+ int curHits = -1;
+ while(true)
+ {
+ if(this->SkipThisClass)
+ {
+ break;
+ }
+ if(strcmp(atts[tagCount], "hits") == 0)
+ {
+ curHits = atoi(atts[tagCount+1]);
+ }
+ else if(strcmp(atts[tagCount], "number") == 0)
+ {
+ curNumber = atoi(atts[tagCount+1]);
+ }
+
+ if(curHits > -1 && curNumber > 0)
+ {
+ FileLinesType& curFileLines =
+ this->Coverage.TotalCoverage[this->CurFileName];
+ {
+ curFileLines[curNumber-1] = curHits;
+ }
+ break;
+ }
+ ++tagCount;
+ }
+ }
+ }
+
+private:
+
+ bool InSources;
+ bool InSource;
+ bool SkipThisClass;
+ std::vector<std::string> FilePaths;
+ typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
+ FileLinesType;
+ cmCTest* CTest;
+ cmCTestCoverageHandlerContainer& Coverage;
+ std::string CurFileName;
+
+};
+
+
+cmParseCoberturaCoverage::cmParseCoberturaCoverage(
+ cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest)
+ :Coverage(cont), CTest(ctest)
+{
+}
+
+bool cmParseCoberturaCoverage::ReadCoverageXML(const char* xmlFile)
+{
+ cmParseCoberturaCoverage::XMLParser parser(this->CTest, this->Coverage);
+ parser.ParseFile(xmlFile);
+ return true;
+}