cmParseBlanketJSCoverage.cxx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmParseBlanketJSCoverage.h"
  4. #include "cmCTest.h"
  5. #include "cmCTestCoverageHandler.h"
  6. #include "cmSystemTools.h"
  7. #include "cmsys/FStream.hxx"
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. class cmParseBlanketJSCoverage::JSONParser
  11. {
  12. public:
  13. typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
  14. FileLinesType;
  15. JSONParser(cmCTestCoverageHandlerContainer& cont)
  16. : Coverage(cont)
  17. {
  18. }
  19. virtual ~JSONParser() {}
  20. std::string getValue(std::string const& line, int type)
  21. {
  22. size_t begIndex;
  23. size_t endIndex;
  24. endIndex = line.rfind(',');
  25. begIndex = line.find_first_of(':');
  26. if (type == 0) {
  27. // A unique substring to remove the extra characters
  28. // around the files name in the JSON (extra " and ,)
  29. std::string foundFileName =
  30. line.substr(begIndex + 3, endIndex - (begIndex + 4));
  31. return foundFileName;
  32. }
  33. return line.substr(begIndex);
  34. }
  35. bool ParseFile(std::string const& file)
  36. {
  37. FileLinesType localCoverageVector;
  38. std::string filename;
  39. bool foundFile = false;
  40. bool inSource = false;
  41. std::string covResult;
  42. std::string line;
  43. cmsys::ifstream in(file.c_str());
  44. if (!in) {
  45. return false;
  46. }
  47. while (cmSystemTools::GetLineFromStream(in, line)) {
  48. if (line.find("filename") != std::string::npos) {
  49. if (foundFile) {
  50. /*
  51. * Upon finding a second file name, generate a
  52. * vector within the total coverage to capture the
  53. * information in the local vector
  54. */
  55. FileLinesType& CoverageVector =
  56. this->Coverage.TotalCoverage[filename];
  57. CoverageVector = localCoverageVector;
  58. localCoverageVector.clear();
  59. }
  60. foundFile = true;
  61. inSource = false;
  62. filename = getValue(line, 0);
  63. } else if ((line.find("coverage") != std::string::npos) && foundFile &&
  64. inSource) {
  65. /*
  66. * two types of "coverage" in the JSON structure
  67. *
  68. * The coverage result over the file or set of files
  69. * and the coverage for each individual line
  70. *
  71. * FoundFile and foundSource ensure that
  72. * only the value of the line coverage is captured
  73. */
  74. std::string result = getValue(line, 1);
  75. result = result.substr(2);
  76. if (result == "\"\"") {
  77. // Empty quotation marks indicate that the
  78. // line is not executable
  79. localCoverageVector.push_back(-1);
  80. } else {
  81. // Else, it contains the number of time executed
  82. localCoverageVector.push_back(atoi(result.c_str()));
  83. }
  84. } else if (line.find("source") != std::string::npos) {
  85. inSource = true;
  86. }
  87. }
  88. // On exit, capture end of last file covered.
  89. FileLinesType& CoverageVector = this->Coverage.TotalCoverage[filename];
  90. CoverageVector = localCoverageVector;
  91. localCoverageVector.clear();
  92. return true;
  93. }
  94. private:
  95. cmCTestCoverageHandlerContainer& Coverage;
  96. };
  97. cmParseBlanketJSCoverage::cmParseBlanketJSCoverage(
  98. cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
  99. : Coverage(cont)
  100. , CTest(ctest)
  101. {
  102. }
  103. bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files)
  104. {
  105. cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  106. "Found " << files.size() << " Files" << std::endl,
  107. this->Coverage.Quiet);
  108. for (std::string const& file : files) {
  109. cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  110. "Reading JSON File " << file << std::endl,
  111. this->Coverage.Quiet);
  112. if (!this->ReadJSONFile(file)) {
  113. return false;
  114. }
  115. }
  116. return true;
  117. }
  118. bool cmParseBlanketJSCoverage::ReadJSONFile(std::string const& file)
  119. {
  120. cmParseBlanketJSCoverage::JSONParser parser(this->Coverage);
  121. cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  122. "Parsing " << file << std::endl, this->Coverage.Quiet);
  123. parser.ParseFile(file);
  124. return true;
  125. }