cmParseMumpsCoverage.cxx 4.3 KB

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