2016-04-29 16:40:20 +03:00
|
|
|
#include "cmParseCoberturaCoverage.h"
|
|
|
|
|
2016-08-24 23:01:40 +03:00
|
|
|
#include "cmCTest.h"
|
|
|
|
#include "cmCTestCoverageHandler.h"
|
2013-09-27 18:42:39 +04:00
|
|
|
#include "cmSystemTools.h"
|
|
|
|
#include "cmXMLParser.h"
|
2016-08-24 23:01:40 +03:00
|
|
|
|
|
|
|
#include <cmConfigure.h>
|
2014-01-04 09:47:13 +04:00
|
|
|
#include <cmsys/FStream.hxx>
|
2016-08-24 23:01:40 +03:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2013-09-27 18:42:39 +04:00
|
|
|
|
2016-05-16 17:34:04 +03:00
|
|
|
class cmParseCoberturaCoverage::XMLParser : public cmXMLParser
|
2013-09-27 18:42:39 +04:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
|
2016-05-16 17:34:04 +03:00
|
|
|
: CTest(ctest)
|
|
|
|
, Coverage(cont)
|
2013-09-27 18:42:39 +04:00
|
|
|
{
|
2016-05-16 17:34:04 +03:00
|
|
|
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 = "";
|
2013-09-27 18:42:39 +04:00
|
|
|
}
|
|
|
|
|
2016-06-27 22:25:27 +03:00
|
|
|
~XMLParser() CM_OVERRIDE {}
|
2013-09-27 18:42:39 +04:00
|
|
|
|
|
|
|
protected:
|
2016-06-23 02:02:39 +03:00
|
|
|
void EndElement(const std::string& name) CM_OVERRIDE
|
2014-05-29 21:47:31 +04:00
|
|
|
{
|
2016-05-16 17:34:04 +03:00
|
|
|
if (name == "source") {
|
|
|
|
this->InSource = false;
|
|
|
|
} else if (name == "sources") {
|
|
|
|
this->InSources = false;
|
|
|
|
} else if (name == "class") {
|
2014-12-19 18:12:25 +03:00
|
|
|
this->SkipThisClass = false;
|
2016-05-16 17:34:04 +03:00
|
|
|
}
|
2014-05-29 21:47:31 +04:00
|
|
|
}
|
|
|
|
|
2016-06-23 02:02:39 +03:00
|
|
|
void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
|
2014-05-29 21:47:31 +04:00
|
|
|
{
|
2016-05-16 17:34:04 +03:00
|
|
|
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);
|
|
|
|
}
|
2014-05-29 21:47:31 +04:00
|
|
|
}
|
|
|
|
|
2016-06-23 02:02:39 +03:00
|
|
|
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
|
2013-09-27 18:42:39 +04:00
|
|
|
{
|
2014-05-29 21:47:31 +04:00
|
|
|
std::string FoundSource;
|
|
|
|
std::string finalpath = "";
|
2016-05-16 17:34:04 +03:00
|
|
|
if (name == "source") {
|
2014-05-29 21:47:31 +04:00
|
|
|
this->InSource = true;
|
2016-05-16 17:34:04 +03:00
|
|
|
} else if (name == "sources") {
|
2014-05-29 21:47:31 +04:00
|
|
|
this->InSources = true;
|
2016-05-16 17:34:04 +03:00
|
|
|
} else if (name == "class") {
|
2013-09-27 18:42:39 +04:00
|
|
|
int tagCount = 0;
|
2016-05-16 17:34:04 +03:00
|
|
|
while (true) {
|
|
|
|
if (strcmp(atts[tagCount], "filename") == 0) {
|
2015-02-17 23:57:26 +03:00
|
|
|
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
2016-05-16 17:34:04 +03:00
|
|
|
"Reading file: " << atts[tagCount + 1]
|
|
|
|
<< std::endl,
|
|
|
|
this->Coverage.Quiet);
|
|
|
|
std::string filename = atts[tagCount + 1];
|
2014-10-03 21:51:14 +04:00
|
|
|
this->CurFileName = "";
|
2014-12-19 18:12:25 +03:00
|
|
|
|
|
|
|
// Check if this is an absolute path that falls within our
|
|
|
|
// source or binary directories.
|
2016-05-16 17:34:04 +03:00
|
|
|
for (size_t i = 0; i < FilePaths.size(); i++) {
|
|
|
|
if (filename.find(FilePaths[i]) == 0) {
|
2014-12-19 18:12:25 +03:00
|
|
|
this->CurFileName = filename;
|
2014-05-29 21:47:31 +04:00
|
|
|
break;
|
|
|
|
}
|
2016-05-16 17:34:04 +03:00
|
|
|
}
|
2014-12-19 18:12:25 +03:00
|
|
|
|
2016-05-16 17:34:04 +03:00
|
|
|
if (this->CurFileName == "") {
|
2014-12-19 18:12:25 +03:00
|
|
|
// Check if this is a path that is relative to our source or
|
|
|
|
// binary directories.
|
2016-05-16 17:34:04 +03:00
|
|
|
for (size_t i = 0; i < FilePaths.size(); i++) {
|
2014-12-19 18:12:25 +03:00
|
|
|
finalpath = FilePaths[i] + "/" + filename;
|
2016-05-16 17:34:04 +03:00
|
|
|
if (cmSystemTools::FileExists(finalpath.c_str())) {
|
2014-12-19 18:12:25 +03:00
|
|
|
this->CurFileName = finalpath;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-05-16 17:34:04 +03:00
|
|
|
}
|
2014-12-19 18:12:25 +03:00
|
|
|
|
2014-01-04 09:47:13 +04:00
|
|
|
cmsys::ifstream fin(this->CurFileName.c_str());
|
2016-05-16 17:34:04 +03:00
|
|
|
if (this->CurFileName == "" || !fin) {
|
|
|
|
this->CurFileName =
|
|
|
|
this->Coverage.BinaryDir + "/" + atts[tagCount + 1];
|
2014-05-24 19:42:08 +04:00
|
|
|
fin.open(this->CurFileName.c_str());
|
2016-05-16 17:34:04 +03:00
|
|
|
if (!fin) {
|
2015-02-17 23:57:26 +03:00
|
|
|
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
2016-05-16 17:34:04 +03:00
|
|
|
"Skipping system file " << filename
|
|
|
|
<< std::endl,
|
|
|
|
this->Coverage.Quiet);
|
2014-12-19 18:12:25 +03:00
|
|
|
|
|
|
|
this->SkipThisClass = true;
|
2014-05-24 19:42:08 +04:00
|
|
|
break;
|
|
|
|
}
|
2013-09-27 18:42:39 +04:00
|
|
|
}
|
|
|
|
std::string line;
|
2014-05-24 19:42:08 +04:00
|
|
|
FileLinesType& curFileLines =
|
|
|
|
this->Coverage.TotalCoverage[this->CurFileName];
|
2016-05-16 17:34:04 +03:00
|
|
|
while (cmSystemTools::GetLineFromStream(fin, line)) {
|
2013-09-27 18:42:39 +04:00
|
|
|
curFileLines.push_back(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++tagCount;
|
|
|
|
}
|
2016-05-16 17:34:04 +03:00
|
|
|
} else if (name == "line") {
|
2013-09-27 18:42:39 +04:00
|
|
|
int tagCount = 0;
|
|
|
|
int curNumber = -1;
|
|
|
|
int curHits = -1;
|
2016-05-16 17:34:04 +03:00
|
|
|
while (true) {
|
|
|
|
if (this->SkipThisClass) {
|
2014-12-19 18:12:25 +03:00
|
|
|
break;
|
2013-09-27 18:42:39 +04:00
|
|
|
}
|
2016-05-16 17:34:04 +03:00
|
|
|
if (strcmp(atts[tagCount], "hits") == 0) {
|
|
|
|
curHits = atoi(atts[tagCount + 1]);
|
|
|
|
} else if (strcmp(atts[tagCount], "number") == 0) {
|
|
|
|
curNumber = atoi(atts[tagCount + 1]);
|
2013-09-27 18:42:39 +04:00
|
|
|
}
|
|
|
|
|
2016-05-16 17:34:04 +03:00
|
|
|
if (curHits > -1 && curNumber > 0) {
|
2013-09-27 18:42:39 +04:00
|
|
|
FileLinesType& curFileLines =
|
|
|
|
this->Coverage.TotalCoverage[this->CurFileName];
|
2016-05-16 17:34:04 +03:00
|
|
|
{
|
|
|
|
curFileLines[curNumber - 1] = curHits;
|
|
|
|
}
|
2013-09-27 18:42:39 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
++tagCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2014-05-29 21:47:31 +04:00
|
|
|
bool InSources;
|
|
|
|
bool InSource;
|
2014-12-19 18:12:25 +03:00
|
|
|
bool SkipThisClass;
|
2014-05-29 21:47:31 +04:00
|
|
|
std::vector<std::string> FilePaths;
|
2013-09-27 18:42:39 +04:00
|
|
|
typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
|
2016-05-16 17:34:04 +03:00
|
|
|
FileLinesType;
|
2013-09-27 18:42:39 +04:00
|
|
|
cmCTest* CTest;
|
|
|
|
cmCTestCoverageHandlerContainer& Coverage;
|
|
|
|
std::string CurFileName;
|
|
|
|
};
|
|
|
|
|
2014-06-03 22:30:46 +04:00
|
|
|
cmParseCoberturaCoverage::cmParseCoberturaCoverage(
|
2016-05-16 17:34:04 +03:00
|
|
|
cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
|
|
|
|
: Coverage(cont)
|
|
|
|
, CTest(ctest)
|
2013-09-27 18:42:39 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-06-03 22:30:46 +04:00
|
|
|
bool cmParseCoberturaCoverage::ReadCoverageXML(const char* xmlFile)
|
2013-09-27 18:42:39 +04:00
|
|
|
{
|
2014-06-03 22:30:46 +04:00
|
|
|
cmParseCoberturaCoverage::XMLParser parser(this->CTest, this->Coverage);
|
2013-09-27 18:42:39 +04:00
|
|
|
parser.ParseFile(xmlFile);
|
|
|
|
return true;
|
|
|
|
}
|