diff options
author | David Cole <david.cole@kitware.com> | 2012-05-17 18:58:54 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2012-05-17 18:58:54 (GMT) |
commit | 8e9101a0cb81374a619686ee820c86d0531d6372 (patch) | |
tree | 7b1d077d46d1c76acbc6d1f80565c5b954d78918 /Source/CTest/cmParseCacheCoverage.cxx | |
parent | 8f635d0268be899286669f1a8be5da6c97671470 (diff) | |
parent | c806b23cfe08259efed1ed310613f65c16a60680 (diff) | |
download | CMake-8e9101a0cb81374a619686ee820c86d0531d6372.zip CMake-8e9101a0cb81374a619686ee820c86d0531d6372.tar.gz CMake-8e9101a0cb81374a619686ee820c86d0531d6372.tar.bz2 |
Merge topic 'mumps_coverage'
c806b23 CDash now supports lots of files in coverage. So, show all files.
761d931 Do not try to run bullseye coverage if COVFILE env is empty.
5b69ce4 Update test data to match new coverage format.
1b418f1 Change GT.M Coverage Parser global
b0c07a1 Disable bullseye coverage for mumps coverage test.
0a169e6 Remove uncovered files from cache coverage data.
a7abf5e Add ability to specify more than one package directory or coverage directory.
220afca Use <TARGET_FILE> expression to run ctest so it works with Xcode and VS IDE.
62f6bce Use a script to run the test because WORKING_DIRECTORY is not in 2.8.2.
f5c5db0 Fix some warnings and a bug where it went past the length of a vector.
7955e99 Add support for Cache coverage.
a86cd33 Add virutal destructor to silence warning.
319eeb0 Add test for mumps coverage. Also refactor code to prepare for cache coverage.
72210c2 Fix line length.
dd07161 Fix warning about char* instead of const char*.
e6412e0 Add support to ctest for GTM mumps coverage.
Diffstat (limited to 'Source/CTest/cmParseCacheCoverage.cxx')
-rw-r--r-- | Source/CTest/cmParseCacheCoverage.cxx | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx new file mode 100644 index 0000000..137f344 --- /dev/null +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -0,0 +1,220 @@ +#include "cmStandardIncludes.h" +#include <stdio.h> +#include <stdlib.h> +#include "cmSystemTools.h" +#include "cmParseCacheCoverage.h" +#include <cmsys/Directory.hxx> +#include <cmsys/Glob.hxx> + + +cmParseCacheCoverage::cmParseCacheCoverage( + cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest) + :cmParseMumpsCoverage(cont, ctest) +{ +} + + +bool cmParseCacheCoverage::LoadCoverageData(const char* d) +{ + // load all the .mcov files in the specified directory + cmsys::Directory dir; + if(!dir.Load(d)) + { + return false; + } + size_t numf; + unsigned int i; + numf = dir.GetNumberOfFiles(); + for (i = 0; i < numf; i++) + { + std::string file = dir.GetFile(i); + if(file != "." && file != ".." + && !cmSystemTools::FileIsDirectory(file.c_str())) + { + std::string path = d; + path += "/"; + path += file; + if(cmSystemTools::GetFilenameLastExtension(path) == ".cmcov") + { + if(!this->ReadCMCovFile(path.c_str())) + { + return false; + } + } + } + } + return true; +} + +// not currently used, but leave it in case we want it in the future +void cmParseCacheCoverage::RemoveUnCoveredFiles() +{ + // loop over the coverage data computed and remove all files + // that only have -1 or 0 for the lines. + cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator ci = + this->Coverage.TotalCoverage.begin(); + while(ci != this->Coverage.TotalCoverage.end()) + { + cmCTestCoverageHandlerContainer::SingleFileCoverageVector& v = + ci->second; + bool nothing = true; + for(cmCTestCoverageHandlerContainer::SingleFileCoverageVector::iterator i= + v.begin(); i != v.end(); ++i) + { + if(*i > 0) + { + nothing = false; + break; + } + } + if(nothing) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "No coverage found in: " << ci->first + << std::endl); + this->Coverage.TotalCoverage.erase(ci++); + } + else + { + ++ci; + } + } +} + +bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args, + std::string const& line) +{ + std::string::size_type pos1 = 0; + std::string::size_type pos2 = line.find(',', 0); + if(pos2 == std::string::npos) + { + return false; + } + std::string arg; + while(pos2 != std::string::npos) + { + arg = line.substr(pos1, pos2-pos1); + args.push_back(arg); + pos1 = pos2+1; + pos2 = line.find(',',pos1); + } + arg = line.substr(pos1); + args.push_back(arg); + return true; +} + +bool cmParseCacheCoverage::ReadCMCovFile(const char* file) +{ + std::ifstream in(file); + if(!in) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Can not open : " + << file << "\n"); + return false; + } + std::string line; + std::vector<std::string> separateLine; + if(!cmSystemTools::GetLineFromStream(in, line)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Empty file : " + << file << " referenced in this line of cmcov data:\n" + "[" << line << "]\n"); + return false; + } + separateLine.clear(); + this->SplitString(separateLine, line); + if(separateLine.size() !=4 || separateLine[0] != "Routine" + || separateLine[1] != "Line" || separateLine[2] != "RtnLine" + || separateLine[3] != "Code") + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Bad first line of cmcov file : " + << file << " line:\n" + "[" << line << "]\n"); + } + std::string routine; + std::string filepath; + while(cmSystemTools::GetLineFromStream(in, line)) + { + // clear out line argument vector + separateLine.clear(); + // parse the comma separated line + this->SplitString(separateLine, line); + // might have more because code could have a quoted , in it + // but we only care about the first 3 args anyway + if(separateLine.size() < 4) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Bad line of cmcov file expected at least 4 found: " + << separateLine.size() << " " + << file << " line:\n" + "[" << line << "]\n"); + for(std::string::size_type i = 0; i < separateLine.size(); ++i) + { + cmCTestLog(this->CTest, ERROR_MESSAGE,"" + << separateLine[1] << " "); + } + cmCTestLog(this->CTest, ERROR_MESSAGE, "\n"); + return false; + } + // if we do not have a routine yet, then it should be + // the first argument in the vector + if(routine.size() == 0) + { + routine = separateLine[0]; + // Find the full path to the file + if(!this->FindMumpsFile(routine, filepath)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Could not find mumps file for routine: " + << routine << "\n"); + filepath = ""; + continue; // move to next line + } + } + // if we have a routine name, check for end of routine + else + { + // Totals in arg 0 marks the end of a routine + if(separateLine[0].substr(0, 6) == "Totals") + { + routine = ""; // at the end of this routine + filepath = ""; + continue; // move to next line + } + } + // if the file path was not found for the routine + // move to next line. We should have already warned + // after the call to FindMumpsFile that we did not find + // it, so don't report again to cut down on output + if(filepath.size() == 0) + { + continue; + } + // now we are ready to set the coverage from the line of data + cmCTestCoverageHandlerContainer::SingleFileCoverageVector& + coverageVector = this->Coverage.TotalCoverage[filepath]; + std::string::size_type linenumber = atoi(separateLine[1].c_str()) -1; + int count = atoi(separateLine[2].c_str()); + if(linenumber > coverageVector.size()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Parse error line is greater than number of lines in file: " + << linenumber << " " << filepath << "\n"); + continue; // skip setting count to avoid crash + } + // now add to count for linenumber + // for some reason the cache coverage adds extra lines to the + // end of the file in some cases. Since they do not exist, we will + // mark them as non executable + while(linenumber >= coverageVector.size()) + { + coverageVector.push_back(-1); + } + coverageVector[linenumber] += count; + } + return true; +} |