cmParseMumpsCoverage.cxx 4.4 KB

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