cmParseMumpsCoverage.cxx 4.6 KB

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