|
|
|
#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];
|
|
|
|
if(fin)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|