cmParseMumpsCoverage.cxx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "cmParseMumpsCoverage.h"
  2. #include "cmCTest.h"
  3. #include "cmCTestCoverageHandler.h"
  4. #include "cmSystemTools.h"
  5. #include "cmConfigure.h"
  6. #include "cmsys/FStream.hxx"
  7. #include "cmsys/Glob.hxx"
  8. #include <map>
  9. #include <string>
  10. #include <utility>
  11. #include <vector>
  12. cmParseMumpsCoverage::cmParseMumpsCoverage(
  13. cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
  14. : Coverage(cont)
  15. , CTest(ctest)
  16. {
  17. }
  18. cmParseMumpsCoverage::~cmParseMumpsCoverage()
  19. {
  20. }
  21. bool cmParseMumpsCoverage::ReadCoverageFile(const char* file)
  22. {
  23. // Read the gtm_coverage.mcov file, that has two lines of data:
  24. // packages:/full/path/to/Vista/Packages
  25. // coverage_dir:/full/path/to/dir/with/*.mcov
  26. cmsys::ifstream in(file);
  27. if (!in) {
  28. return false;
  29. }
  30. std::string line;
  31. while (cmSystemTools::GetLineFromStream(in, line)) {
  32. std::string::size_type pos = line.find(':', 0);
  33. std::string packages;
  34. if (pos != std::string::npos) {
  35. std::string type = line.substr(0, pos);
  36. std::string path = line.substr(pos + 1);
  37. if (type == "packages") {
  38. this->LoadPackages(path.c_str());
  39. } else if (type == "coverage_dir") {
  40. this->LoadCoverageData(path.c_str());
  41. } else {
  42. cmCTestLog(this->CTest, ERROR_MESSAGE,
  43. "Parse Error in Mumps coverage file :\n"
  44. << file << "\ntype: [" << type << "]\npath:[" << path
  45. << "]\n"
  46. "input line: ["
  47. << line << "]\n");
  48. }
  49. }
  50. }
  51. return true;
  52. }
  53. void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
  54. {
  55. // initialize the coverage information for a given mumps file
  56. cmsys::ifstream in(file.c_str());
  57. if (!in) {
  58. return;
  59. }
  60. std::string line;
  61. cmCTestCoverageHandlerContainer::SingleFileCoverageVector& coverageVector =
  62. this->Coverage.TotalCoverage[file];
  63. if (!cmSystemTools::GetLineFromStream(in, line)) {
  64. return;
  65. }
  66. // first line of a .m file can never be run
  67. coverageVector.push_back(-1);
  68. while (cmSystemTools::GetLineFromStream(in, line)) {
  69. // putting in a 0 for a line means it is executable code
  70. // putting in a -1 for a line means it is not executable code
  71. int val = -1; // assume line is not executable
  72. bool found = false;
  73. std::string::size_type i = 0;
  74. // (1) Search for the first whitespace or semicolon character on a line.
  75. // This will skip over labels if the line starts with one, or will simply
  76. // be the first character on the line for non-label lines.
  77. for (; i < line.size(); ++i) {
  78. if (line[i] == ' ' || line[i] == '\t' || line[i] == ';') {
  79. found = true;
  80. break;
  81. }
  82. }
  83. if (found) {
  84. // (2) If the first character found above is whitespace or a period
  85. // then continue the search for the first following non-whitespace
  86. // character.
  87. if (line[i] == ' ' || line[i] == '\t') {
  88. while (i < line.size() &&
  89. (line[i] == ' ' || line[i] == '\t' || line[i] == '.')) {
  90. i++;
  91. }
  92. }
  93. // (3) If the character found is not a semicolon then the line counts for
  94. // coverage.
  95. if (i < line.size() && line[i] != ';') {
  96. val = 0;
  97. }
  98. }
  99. coverageVector.push_back(val);
  100. }
  101. }
  102. bool cmParseMumpsCoverage::LoadPackages(const char* d)
  103. {
  104. cmsys::Glob glob;
  105. glob.RecurseOn();
  106. std::string pat = d;
  107. pat += "/*.m";
  108. glob.FindFiles(pat);
  109. std::vector<std::string>& files = glob.GetFiles();
  110. std::vector<std::string>::iterator fileIt;
  111. for (fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
  112. std::string name = cmSystemTools::GetFilenameName(*fileIt);
  113. this->RoutineToDirectory[name.substr(0, name.size() - 2)] = *fileIt;
  114. // initialze each file, this is left out until CDash is fixed
  115. // to handle large numbers of files
  116. this->InitializeMumpsFile(*fileIt);
  117. }
  118. return true;
  119. }
  120. bool cmParseMumpsCoverage::FindMumpsFile(std::string const& routine,
  121. std::string& filepath)
  122. {
  123. std::map<std::string, std::string>::iterator i =
  124. this->RoutineToDirectory.find(routine);
  125. if (i != this->RoutineToDirectory.end()) {
  126. filepath = i->second;
  127. return true;
  128. }
  129. // try some alternate names
  130. const char* tryname[] = { "GUX", "GTM", "ONT", nullptr };
  131. for (int k = 0; tryname[k] != nullptr; k++) {
  132. std::string routine2 = routine + tryname[k];
  133. i = this->RoutineToDirectory.find(routine2);
  134. if (i != this->RoutineToDirectory.end()) {
  135. filepath = i->second;
  136. return true;
  137. }
  138. }
  139. return false;
  140. }