cmParseCoberturaCoverage.cxx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include "cmParseCoberturaCoverage.h"
  2. #include "cmSystemTools.h"
  3. #include "cmXMLParser.h"
  4. #include <cmsys/Directory.hxx>
  5. #include <cmsys/FStream.hxx>
  6. class cmParseCoberturaCoverage::XMLParser : public cmXMLParser
  7. {
  8. public:
  9. XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
  10. : CTest(ctest)
  11. , Coverage(cont)
  12. {
  13. this->InSources = false;
  14. this->InSource = false;
  15. this->SkipThisClass = false;
  16. this->FilePaths.push_back(this->Coverage.SourceDir);
  17. this->FilePaths.push_back(this->Coverage.BinaryDir);
  18. this->CurFileName = "";
  19. }
  20. virtual ~XMLParser() {}
  21. protected:
  22. void EndElement(const std::string& name) CM_OVERRIDE
  23. {
  24. if (name == "source") {
  25. this->InSource = false;
  26. } else if (name == "sources") {
  27. this->InSources = false;
  28. } else if (name == "class") {
  29. this->SkipThisClass = false;
  30. }
  31. }
  32. void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
  33. {
  34. std::string tmp;
  35. tmp.insert(0, data, length);
  36. if (this->InSources && this->InSource) {
  37. this->FilePaths.push_back(tmp);
  38. cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  39. "Adding Source: " << tmp << std::endl,
  40. this->Coverage.Quiet);
  41. }
  42. }
  43. void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
  44. {
  45. std::string FoundSource;
  46. std::string finalpath = "";
  47. if (name == "source") {
  48. this->InSource = true;
  49. } else if (name == "sources") {
  50. this->InSources = true;
  51. } else if (name == "class") {
  52. int tagCount = 0;
  53. while (true) {
  54. if (strcmp(atts[tagCount], "filename") == 0) {
  55. cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  56. "Reading file: " << atts[tagCount + 1]
  57. << std::endl,
  58. this->Coverage.Quiet);
  59. std::string filename = atts[tagCount + 1];
  60. this->CurFileName = "";
  61. // Check if this is an absolute path that falls within our
  62. // source or binary directories.
  63. for (size_t i = 0; i < FilePaths.size(); i++) {
  64. if (filename.find(FilePaths[i]) == 0) {
  65. this->CurFileName = filename;
  66. break;
  67. }
  68. }
  69. if (this->CurFileName == "") {
  70. // Check if this is a path that is relative to our source or
  71. // binary directories.
  72. for (size_t i = 0; i < FilePaths.size(); i++) {
  73. finalpath = FilePaths[i] + "/" + filename;
  74. if (cmSystemTools::FileExists(finalpath.c_str())) {
  75. this->CurFileName = finalpath;
  76. break;
  77. }
  78. }
  79. }
  80. cmsys::ifstream fin(this->CurFileName.c_str());
  81. if (this->CurFileName == "" || !fin) {
  82. this->CurFileName =
  83. this->Coverage.BinaryDir + "/" + atts[tagCount + 1];
  84. fin.open(this->CurFileName.c_str());
  85. if (!fin) {
  86. cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  87. "Skipping system file " << filename
  88. << std::endl,
  89. this->Coverage.Quiet);
  90. this->SkipThisClass = true;
  91. break;
  92. }
  93. }
  94. std::string line;
  95. FileLinesType& curFileLines =
  96. this->Coverage.TotalCoverage[this->CurFileName];
  97. while (cmSystemTools::GetLineFromStream(fin, line)) {
  98. curFileLines.push_back(-1);
  99. }
  100. break;
  101. }
  102. ++tagCount;
  103. }
  104. } else if (name == "line") {
  105. int tagCount = 0;
  106. int curNumber = -1;
  107. int curHits = -1;
  108. while (true) {
  109. if (this->SkipThisClass) {
  110. break;
  111. }
  112. if (strcmp(atts[tagCount], "hits") == 0) {
  113. curHits = atoi(atts[tagCount + 1]);
  114. } else if (strcmp(atts[tagCount], "number") == 0) {
  115. curNumber = atoi(atts[tagCount + 1]);
  116. }
  117. if (curHits > -1 && curNumber > 0) {
  118. FileLinesType& curFileLines =
  119. this->Coverage.TotalCoverage[this->CurFileName];
  120. {
  121. curFileLines[curNumber - 1] = curHits;
  122. }
  123. break;
  124. }
  125. ++tagCount;
  126. }
  127. }
  128. }
  129. private:
  130. bool InSources;
  131. bool InSource;
  132. bool SkipThisClass;
  133. std::vector<std::string> FilePaths;
  134. typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
  135. FileLinesType;
  136. cmCTest* CTest;
  137. cmCTestCoverageHandlerContainer& Coverage;
  138. std::string CurFileName;
  139. };
  140. cmParseCoberturaCoverage::cmParseCoberturaCoverage(
  141. cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
  142. : Coverage(cont)
  143. , CTest(ctest)
  144. {
  145. }
  146. bool cmParseCoberturaCoverage::ReadCoverageXML(const char* xmlFile)
  147. {
  148. cmParseCoberturaCoverage::XMLParser parser(this->CTest, this->Coverage);
  149. parser.ParseFile(xmlFile);
  150. return true;
  151. }