diff options
Diffstat (limited to 'Source/CTest/cmParseBlanketJSCoverage.cxx')
-rw-r--r-- | Source/CTest/cmParseBlanketJSCoverage.cxx | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx new file mode 100644 index 0000000..63d6a15 --- /dev/null +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -0,0 +1,137 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmParseBlanketJSCoverage.h" + +#include "cmCTest.h" +#include "cmCTestCoverageHandler.h" +#include "cmSystemTools.h" + +#include "cmsys/FStream.hxx" +#include <stdio.h> +#include <stdlib.h> + +class cmParseBlanketJSCoverage::JSONParser +{ +public: + typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector + FileLinesType; + JSONParser(cmCTestCoverageHandlerContainer& cont) + : Coverage(cont) + { + } + + virtual ~JSONParser() = default; + + std::string getValue(std::string const& line, int type) + { + size_t begIndex; + size_t endIndex; + endIndex = line.rfind(','); + begIndex = line.find_first_of(':'); + if (type == 0) { + // A unique substring to remove the extra characters + // around the files name in the JSON (extra " and ,) + std::string foundFileName = + line.substr(begIndex + 3, endIndex - (begIndex + 4)); + return foundFileName; + } + return line.substr(begIndex); + } + bool ParseFile(std::string const& file) + { + FileLinesType localCoverageVector; + std::string filename; + bool foundFile = false; + bool inSource = false; + std::string covResult; + std::string line; + + cmsys::ifstream in(file.c_str()); + if (!in) { + return false; + } + while (cmSystemTools::GetLineFromStream(in, line)) { + if (line.find("filename") != std::string::npos) { + if (foundFile) { + /* + * Upon finding a second file name, generate a + * vector within the total coverage to capture the + * information in the local vector + */ + FileLinesType& CoverageVector = + this->Coverage.TotalCoverage[filename]; + CoverageVector = localCoverageVector; + localCoverageVector.clear(); + } + foundFile = true; + inSource = false; + filename = getValue(line, 0); + } else if ((line.find("coverage") != std::string::npos) && foundFile && + inSource) { + /* + * two types of "coverage" in the JSON structure + * + * The coverage result over the file or set of files + * and the coverage for each individual line + * + * FoundFile and foundSource ensure that + * only the value of the line coverage is captured + */ + std::string result = getValue(line, 1); + result = result.substr(2); + if (result == "\"\"") { + // Empty quotation marks indicate that the + // line is not executable + localCoverageVector.push_back(-1); + } else { + // Else, it contains the number of time executed + localCoverageVector.push_back(atoi(result.c_str())); + } + } else if (line.find("source") != std::string::npos) { + inSource = true; + } + } + + // On exit, capture end of last file covered. + FileLinesType& CoverageVector = this->Coverage.TotalCoverage[filename]; + CoverageVector = localCoverageVector; + localCoverageVector.clear(); + return true; + } + +private: + cmCTestCoverageHandlerContainer& Coverage; +}; + +cmParseBlanketJSCoverage::cmParseBlanketJSCoverage( + cmCTestCoverageHandlerContainer& cont, cmCTest* ctest) + : Coverage(cont) + , CTest(ctest) +{ +} + +bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files) +{ + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Found " << files.size() << " Files" << std::endl, + this->Coverage.Quiet); + for (std::string const& file : files) { + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Reading JSON File " << file << std::endl, + this->Coverage.Quiet); + + if (!this->ReadJSONFile(file)) { + return false; + } + } + return true; +} + +bool cmParseBlanketJSCoverage::ReadJSONFile(std::string const& file) +{ + cmParseBlanketJSCoverage::JSONParser parser(this->Coverage); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Parsing " << file << std::endl, this->Coverage.Quiet); + parser.ParseFile(file); + return true; +} |