| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | #include "cmParseCoberturaCoverage.h"#include "cmCTest.h"#include "cmCTestCoverageHandler.h"#include "cmSystemTools.h"#include "cmXMLParser.h"#include "cmsys/FStream.hxx"#include <stdlib.h>#include <string.h>class cmParseCoberturaCoverage::XMLParser : public cmXMLParser{public:  XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)    : CTest(ctest)    , Coverage(cont)  {    this->InSources = false;    this->InSource = false;    this->SkipThisClass = false;    this->FilePaths.push_back(this->Coverage.SourceDir);    this->FilePaths.push_back(this->Coverage.BinaryDir);    this->CurFileName.clear();  }  ~XMLParser() override {}protected:  void EndElement(const std::string& name) override  {    if (name == "source") {      this->InSource = false;    } else if (name == "sources") {      this->InSources = false;    } else if (name == "class") {      this->SkipThisClass = false;    }  }  void CharacterDataHandler(const char* data, int length) override  {    std::string tmp;    tmp.insert(0, data, length);    if (this->InSources && this->InSource) {      this->FilePaths.push_back(tmp);      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,                         "Adding Source: " << tmp << std::endl,                         this->Coverage.Quiet);    }  }  void StartElement(const std::string& name, const char** atts) override  {    std::string FoundSource;    std::string finalpath;    if (name == "source") {      this->InSource = true;    } else if (name == "sources") {      this->InSources = true;    } else if (name == "class") {      int tagCount = 0;      while (true) {        if (strcmp(atts[tagCount], "filename") == 0) {          cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,                             "Reading file: " << atts[tagCount + 1]                                              << std::endl,                             this->Coverage.Quiet);          std::string filename = atts[tagCount + 1];          this->CurFileName.clear();          // Check if this is an absolute path that falls within our          // source or binary directories.          for (std::string const& filePath : FilePaths) {            if (filename.find(filePath) == 0) {              this->CurFileName = filename;              break;            }          }          if (this->CurFileName.empty()) {            // Check if this is a path that is relative to our source or            // binary directories.            for (std::string const& filePath : FilePaths) {              finalpath = filePath + "/" + filename;              if (cmSystemTools::FileExists(finalpath)) {                this->CurFileName = finalpath;                break;              }            }          }          cmsys::ifstream fin(this->CurFileName.c_str());          if (this->CurFileName.empty() || !fin) {            this->CurFileName =              this->Coverage.BinaryDir + "/" + atts[tagCount + 1];            fin.open(this->CurFileName.c_str());            if (!fin) {              cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,                                 "Skipping system file " << filename                                                         << std::endl,                                 this->Coverage.Quiet);              this->SkipThisClass = true;              break;            }          }          std::string line;          FileLinesType& curFileLines =            this->Coverage.TotalCoverage[this->CurFileName];          while (cmSystemTools::GetLineFromStream(fin, line)) {            curFileLines.push_back(-1);          }          break;        }        ++tagCount;      }    } else if (name == "line") {      int tagCount = 0;      int curNumber = -1;      int curHits = -1;      while (true) {        if (this->SkipThisClass) {          break;        }        if (strcmp(atts[tagCount], "hits") == 0) {          curHits = atoi(atts[tagCount + 1]);        } else if (strcmp(atts[tagCount], "number") == 0) {          curNumber = atoi(atts[tagCount + 1]);        }        if (curHits > -1 && curNumber > 0) {          FileLinesType& curFileLines =            this->Coverage.TotalCoverage[this->CurFileName];          {            curFileLines[curNumber - 1] = curHits;          }          break;        }        ++tagCount;      }    }  }private:  bool InSources;  bool InSource;  bool SkipThisClass;  std::vector<std::string> FilePaths;  typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector    FileLinesType;  cmCTest* CTest;  cmCTestCoverageHandlerContainer& Coverage;  std::string CurFileName;};cmParseCoberturaCoverage::cmParseCoberturaCoverage(  cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)  : Coverage(cont)  , CTest(ctest){}bool cmParseCoberturaCoverage::ReadCoverageXML(const char* xmlFile){  cmParseCoberturaCoverage::XMLParser parser(this->CTest, this->Coverage);  parser.ParseFile(xmlFile);  return true;}
 |