CMake/Source/CTest/cmParseJacocoCoverage.cxx
Daniel Pfeifer 7647f6afa4 Add CM_OVERRIDE to some functions
Run clang-tidy's modernize-use-override checker.  This checker must have
issues in version 3.8.  It has way too little matches.  And it adds
override to destructors.  Revert the changes on the destructors and
change override to CM_OVERRIDE.
2016-06-27 10:37:41 -04:00

180 lines
5.1 KiB
C++

#include "cmParseJacocoCoverage.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include <cmsys/Directory.hxx>
#include <cmsys/FStream.hxx>
#include <cmsys/Glob.hxx>
#include <stdio.h>
#include <stdlib.h>
class cmParseJacocoCoverage::XMLParser : public cmXMLParser
{
public:
XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
: CTest(ctest)
, Coverage(cont)
{
this->FilePath = "";
this->PackagePath = "";
this->PackageName = "";
}
virtual ~XMLParser() {}
protected:
void EndElement(const std::string&) CM_OVERRIDE {}
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
{
if (name == "package") {
this->PackageName = atts[1];
this->PackagePath = "";
} else if (name == "sourcefile") {
std::string fileName = atts[1];
if (this->PackagePath == "") {
if (!this->FindPackagePath(fileName)) {
cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find file: "
<< this->PackageName << "/" << fileName << std::endl);
this->Coverage.Error++;
return;
}
}
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Reading file: " << fileName << std::endl,
this->Coverage.Quiet);
this->FilePath = this->PackagePath + "/" + fileName;
cmsys::ifstream fin(this->FilePath.c_str());
if (!fin) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Jacoco Coverage: Error opening " << this->FilePath
<< std::endl);
}
std::string line;
FileLinesType& curFileLines =
this->Coverage.TotalCoverage[this->FilePath];
if (fin) {
curFileLines.push_back(-1);
}
while (cmSystemTools::GetLineFromStream(fin, line)) {
curFileLines.push_back(-1);
}
} else if (name == "line") {
int tagCount = 0;
int nr = -1;
int ci = -1;
while (true) {
if (strcmp(atts[tagCount], "ci") == 0) {
ci = atoi(atts[tagCount + 1]);
} else if (strcmp(atts[tagCount], "nr") == 0) {
nr = atoi(atts[tagCount + 1]);
}
if (ci > -1 && nr > 0) {
FileLinesType& curFileLines =
this->Coverage.TotalCoverage[this->FilePath];
if (!curFileLines.empty()) {
curFileLines[nr - 1] = ci;
}
break;
}
++tagCount;
}
}
}
virtual bool FindPackagePath(std::string const& fileName)
{
// Search for the source file in the source directory.
if (this->PackagePathFound(fileName, this->Coverage.SourceDir)) {
return true;
}
// If not found there, check the binary directory.
if (this->PackagePathFound(fileName, this->Coverage.BinaryDir)) {
return true;
}
return false;
}
virtual bool PackagePathFound(std::string const& fileName,
std::string const& baseDir)
{
// Search for the file in the baseDir and its subdirectories.
std::string packageGlob = baseDir;
packageGlob += "/";
packageGlob += fileName;
cmsys::Glob gl;
gl.RecurseOn();
gl.RecurseThroughSymlinksOn();
gl.FindFiles(packageGlob);
std::vector<std::string> const& files = gl.GetFiles();
if (files.empty()) {
return false;
}
// Check if any of the locations found match our package.
for (std::vector<std::string>::const_iterator fi = files.begin();
fi != files.end(); ++fi) {
std::string dir = cmsys::SystemTools::GetParentDirectory(*fi);
if (cmsys::SystemTools::StringEndsWith(dir, this->PackageName.c_str())) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Found package directory for " << fileName << ": "
<< dir << std::endl,
this->Coverage.Quiet);
this->PackagePath = dir;
return true;
}
}
return false;
}
private:
std::string FilePath;
std::string PackagePath;
std::string PackageName;
typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
FileLinesType;
cmCTest* CTest;
cmCTestCoverageHandlerContainer& Coverage;
};
cmParseJacocoCoverage::cmParseJacocoCoverage(
cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
: Coverage(cont)
, CTest(ctest)
{
}
bool cmParseJacocoCoverage::LoadCoverageData(
std::vector<std::string> const& files)
{
// load all the jacoco.xml files in the source directory
cmsys::Directory dir;
size_t i;
std::string path;
size_t numf = files.size();
for (i = 0; i < numf; i++) {
path = files[i];
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Reading XML File " << path << std::endl,
this->Coverage.Quiet);
if (cmSystemTools::GetFilenameLastExtension(path) == ".xml") {
if (!this->ReadJacocoXML(path.c_str())) {
return false;
}
}
}
return true;
}
bool cmParseJacocoCoverage::ReadJacocoXML(const char* file)
{
cmParseJacocoCoverage::XMLParser parser(this->CTest, this->Coverage);
parser.ParseFile(file);
return true;
}