cmParseCoberturaCoverage.cxx 5.0 KB

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