summaryrefslogtreecommitdiffstats
path: root/Source/CTest/cmParseBlanketJSCoverage.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest/cmParseBlanketJSCoverage.cxx')
-rw-r--r--Source/CTest/cmParseBlanketJSCoverage.cxx137
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;
+}