CMake/Source/CTest/cmParseJacocoCoverage.cxx

172 lines
4.6 KiB
C++

#include "cmStandardIncludes.h"
#include <stdio.h>
#include <stdlib.h>
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmParseJacocoCoverage.h"
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
#include <cmsys/FStream.hxx>
class cmParseJacocoCoverage::XMLParser: public cmXMLParser
{
public:
XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
: CTest(ctest), Coverage(cont)
{
this->PackageName = "";
this->ModuleName = "";
this->FileName = "";
this->CurFileName = "";
this->FilePaths.push_back(this->Coverage.SourceDir);
}
virtual ~XMLParser()
{
}
protected:
virtual void EndElement(const std::string&)
{
}
virtual void StartElement(const std::string& name,
const char** atts)
{
if(name == "package")
{
this->PackageName = atts[1];
std::string FilePath = this->Coverage.SourceDir +
"/" + this->ModuleName + "/src/main/java/" +
this->PackageName;
this->FilePaths.push_back(FilePath);
FilePath = this->Coverage.SourceDir +
"/src/main/java/" + this->PackageName;
this->FilePaths.push_back(FilePath);
}
else if(name == "sourcefile")
{
this->FileName = atts[1];
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Reading file: " << this->FileName << std::endl,
this->Coverage.Quiet);
for(size_t i=0;i < FilePaths.size();i++)
{
std::string finalpath = FilePaths[i] + "/" + this->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 + "/" +
this->FileName;
fin.open(this->CurFileName.c_str());
if (!fin)
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Jacoco Coverage: Error opening " << this->CurFileName
<< std::endl);
this->Coverage.Error++;
}
}
std::string line;
FileLinesType& curFileLines =
this->Coverage.TotalCoverage[this->CurFileName];
curFileLines.push_back(-1);
while(cmSystemTools::GetLineFromStream(fin, line))
{
curFileLines.push_back(-1);
}
}
else if(name == "report")
{
this->ModuleName=atts[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->CurFileName];
if(!curFileLines.empty())
{
curFileLines[nr-1] = ci;
}
break;
}
++tagCount;
}
}
}
private:
std::string PackageName;
std::string FileName;
std::string ModuleName;
std::string CurFileName;
std::vector<std::string> FilePaths;
typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
FileLinesType;
cmCTest* CTest;
cmCTestCoverageHandlerContainer& Coverage;
};
cmParseJacocoCoverage::cmParseJacocoCoverage(
cmCTestCoverageHandlerContainer& cont,
cmCTest* ctest)
:Coverage(cont), CTest(ctest)
{
}
bool cmParseJacocoCoverage::LoadCoverageData(
const std::vector<std::string> 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;
}