diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2012-05-01 17:35:07 (GMT) |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2012-05-01 17:35:07 (GMT) |
commit | 319eeb0247f51bb2d380261ce7d63c7ce5020ed0 (patch) | |
tree | 6885326a833ee4cca3416ed518601f47ca6c986e /Source | |
parent | 72210c266238607e12c12ed7e983efed557fa784 (diff) | |
download | CMake-319eeb0247f51bb2d380261ce7d63c7ce5020ed0.zip CMake-319eeb0247f51bb2d380261ce7d63c7ce5020ed0.tar.gz CMake-319eeb0247f51bb2d380261ce7d63c7ce5020ed0.tar.bz2 |
Add test for mumps coverage. Also refactor code to prepare for cache coverage.
Add a simple test to make sure the GTM mumps coverage is working.
Also refactor the code so that cache coverage can be added.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/CTest/cmCTestCoverageHandler.cxx | 8 | ||||
-rw-r--r-- | Source/CTest/cmParseGTMCoverage.cxx | 324 | ||||
-rw-r--r-- | Source/CTest/cmParseGTMCoverage.h | 31 | ||||
-rw-r--r-- | Source/CTest/cmParseMumpsCoverage.cxx | 125 | ||||
-rw-r--r-- | Source/CTest/cmParseMumpsCoverage.h | 48 |
6 files changed, 309 insertions, 228 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 1ef67da..081cf65 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -423,6 +423,7 @@ SET(CTEST_SRCS cmCTest.cxx CTest/cmCTestConfigureHandler.cxx CTest/cmCTestCoverageCommand.cxx CTest/cmCTestCoverageHandler.cxx + CTest/cmParseMumpsCoverage.cxx CTest/cmParseGTMCoverage.cxx CTest/cmParsePHPCoverage.cxx CTest/cmCTestEmptyBinaryDirectoryCommand.cxx diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 099bcb6..e7fa2f1 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -769,7 +769,13 @@ int cmCTestCoverageHandler::HandleGTMCoverage( "/gtm_coverage.mcov"; if(cmSystemTools::FileExists(coverageFile.c_str())) { - cov.ReadGTMCoverage(coverageFile.c_str()); + cov.ReadCoverageFile(coverageFile.c_str()); + } + else + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Cannot find GTM coverage file: " << coverageFile + << std::endl); } return static_cast<int>(cont->TotalCoverage.size()); } diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index 130e40e..90d047b 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -8,156 +8,152 @@ cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont, - cmCTest* ctest) - :Coverage(cont), CTest(ctest) + cmCTest* ctest) + :cmParseMumpsCoverage(cont, ctest) { } -bool cmParseGTMCoverage::ReadGTMCoverage(const char* file) + +bool cmParseGTMCoverage::LoadCoverageData(const char* d) { - // Read the gtm_coverage.mcov file, that has two lines of data: - // packages:/full/path/to/Vista/Packages - // coverage_dir:/full/path/to/dir/with/*.mcov - std::ifstream in(file); - if(!in) + // load all the .mcov files in the specified directory + cmsys::Directory dir; + if(!dir.Load(d)) { return false; } - std::string line; - cmSystemTools::GetLineFromStream(in, line); - std::string::size_type pos = line.find(':', 0); - std::string packages; - if(pos != std::string::npos) - { - packages = line.substr(pos+1); - } - cmSystemTools::GetLineFromStream(in, line); - pos = line.find(':', 0); - std::string coverage_dir; - if(pos != std::string::npos) + size_t numf; + unsigned int i; + numf = dir.GetNumberOfFiles(); + for (i = 0; i < numf; i++) { - coverage_dir = line.substr(pos+1); + 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) == ".mcov") + { + if(!this->ReadMCovFile(path.c_str())) + { + return false; + } + } + } } - // load the mumps files from the packages directory - this->LoadPackages(packages.c_str()); - // now load the *.mcov files from the coverage directory - this->LoadCoverageData(coverage_dir.c_str()); return true; } -void cmParseGTMCoverage::InitializeFile(std::string& file) +bool cmParseGTMCoverage::ReadMCovFile(const char* file) { - // initialize the coverage information for a given mumps file - std::ifstream in(file.c_str()); + std::ifstream in(file); if(!in) { - return; + return false; } std::string line; - cmCTestCoverageHandlerContainer::SingleFileCoverageVector& - coverageVector = this->Coverage.TotalCoverage[file]; - if(!cmSystemTools::GetLineFromStream(in, line)) - { - return; - } - // first line of a .m file can never be run - coverageVector.push_back(-1); - while( cmSystemTools::GetLineFromStream(in, line) ) + std::string lastfunction; + std::string lastroutine; + std::string lastpath; + int lastoffset = 0; + while( cmSystemTools::GetLineFromStream(in, line)) { - // putting in a 0 for a line means it is executable code - // putting in a -1 for a line means it is not executable code - int val = -1; // assume line is not executable - bool found = false; - std::string::size_type i = 0; - // (1) Search for the first whitespace or semicolon character on a line. - //This will skip over labels if the line starts with one, or will simply - //be the first character on the line for non-label lines. - for(; i < line.size(); ++i) + // only look at lines that have coverage data + if(line.find("^COVERAGE") == line.npos) + { + continue; + } + std::string filepath; + std::string function; + std::string routine; + int linenumber = 0; + int count = 0; + this->ParseMCOVLine(line, routine, function, linenumber, count); + // skip this one + if(routine == "RSEL") + { + continue; + } + // no need to search the file if we just did it + if(function == lastfunction && lastroutine == routine) { - if(line[i] == ' ' || line[i] == '\t' || line[i] == ';') + if(lastpath.size()) + { + this->Coverage.TotalCoverage[lastpath][lastoffset + linenumber] + += count; + } + else { - found = true; - break; + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Can not find mumps file : " + << lastroutine << " referenced in this line of mcov data:\n" + "[" << line << "]\n"); } + continue; } - if(found) + // Find the full path to the file + std::map<cmStdString, cmStdString>::iterator i = + this->RoutineToDirectory.find(routine); + bool found = false; + if(i != this->RoutineToDirectory.end()) + { + filepath = i->second; + found = true; + } + else { - // (2) If the first character found above is whitespace then continue the - // search for the first following non-whitespace character. - if(line[i] == ' ' || line[i] == '\t') + // try some alternate names + const char* tryname[] = {"GUX", "GTM", "ONT", 0}; + for(int k=0; tryname[k] != 0; k++) { - while(i < line.size() && (line[i] == ' ' || line[i] == '\t')) + std::string routine2 = routine + tryname[k]; + i = this->RoutineToDirectory.find(routine2); + if(i != this->RoutineToDirectory.end()) { - i++; + found = true; + filepath = i->second; + break; // break out of tryname loop if found } } - // (3) If the character found is not a semicolon then the line counts for - // coverage. - if(i < line.size() && line[i] != ';') - { - val = 0; - } } - coverageVector.push_back(val); - } -} - -bool cmParseGTMCoverage::LoadPackages(const char* d) -{ - cmsys::Glob glob; - glob.RecurseOn(); - std::string pat = d; - pat += "/*.m"; - glob.FindFiles(pat.c_str()); - std::vector<std::string>& files = glob.GetFiles(); - std::vector<std::string>::iterator fileIt; - for ( fileIt = files.begin(); fileIt != files.end(); - ++ fileIt ) - { - std::string name = cmSystemTools::GetFilenameName(*fileIt); - this->RoutineToDirectory[name.substr(0, name.size()-2)] = *fileIt; - // initialze each file, this is left out until CDash is fixed - // to handle large numbers of files -// this->InitializeFile(*fileIt); - } - return true; -} - -bool cmParseGTMCoverage::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())) + if(found) { - std::string path = d; - path += "/"; - path += file; - if(cmSystemTools::GetFilenameLastExtension(path) == ".mcov") + int lineoffset; + if(this->FindFunctionInMumpsFile(filepath, + function, + lineoffset)) { - if(!this->ReadMCovFile(path.c_str())) + // hack, this should be done on every file, but for now + // just do it on the ones that have coverage at all + if( this->Coverage.TotalCoverage[filepath].size() == 0) { - return false; + this->InitializeMumpsFile(filepath); } + cmCTestCoverageHandlerContainer::SingleFileCoverageVector& + coverageVector = this->Coverage.TotalCoverage[filepath]; + coverageVector[lineoffset + linenumber] += count; } + lastoffset = lineoffset; + } + else + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Can not find mumps file : " + << routine << " referenced in this line of mcov data:\n" + "[" << line << "]\n"); } + lastfunction = function; + lastroutine = routine; + lastpath = filepath; } return true; } -bool cmParseGTMCoverage::ParseFile(std::string& filepath, - std::string& function, - int& lineoffset) +bool cmParseGTMCoverage::FindFunctionInMumpsFile(std::string const& filepath, + std::string const& function, + int& lineoffset) { std::ifstream in(filepath.c_str()); if(!in) @@ -197,11 +193,11 @@ bool cmParseGTMCoverage::ParseFile(std::string& filepath, return false; } -bool cmParseGTMCoverage::ParseLine(std::string const& line, - std::string& routine, - std::string& function, - int& linenumber, - int& count) +bool cmParseGTMCoverage::ParseMCOVLine(std::string const& line, + std::string& routine, + std::string& function, + int& linenumber, + int& count) { // this method parses lines from the .mcov file // each line has ^COVERAGE(...) in it, and there @@ -302,97 +298,3 @@ bool cmParseGTMCoverage::ParseLine(std::string const& line, } return true; } - -bool cmParseGTMCoverage::ReadMCovFile(const char* file) -{ - std::ifstream in(file); - if(!in) - { - return false; - } - std::string line; - std::string lastfunction; - std::string lastroutine; - std::string lastpath; - int lastoffset = 0; - while( cmSystemTools::GetLineFromStream(in, line)) - { - // only look at lines that have coverage data - if(line.find("^COVERAGE") == line.npos) - { - continue; - } - std::string filepath; - std::string function; - std::string routine; - int linenumber = 0; - int count = 0; - this->ParseLine(line, routine, function, linenumber, count); - // skip this one - if(routine == "RSEL") - { - continue; - } - // no need to search the file if we just did it - if(function == lastfunction && lastroutine == routine) - { - this->Coverage.TotalCoverage[lastpath][lastoffset + linenumber] += count; - continue; - } - // Find the full path to the file - std::map<cmStdString, cmStdString>::iterator i = - this->RoutineToDirectory.find(routine); - bool found = false; - if(i != this->RoutineToDirectory.end()) - { - filepath = i->second; - found = true; - } - else - { - // try some alternate names - const char* tryname[] = {"GUX", "GTM", "ONT", 0}; - for(int k=0; tryname[k] != 0; k++) - { - std::string routine2 = routine + tryname[k]; - i = this->RoutineToDirectory.find(routine2); - if(i != this->RoutineToDirectory.end()) - { - found = true; - filepath = i->second; - break; // break out of tryname loop if found - } - } - } - if(found) - { - int lineoffset; - if(this->ParseFile(filepath, - function, - lineoffset)) - { - // hack, this should be done on every file, but for now - // just do it on the ones that have coverage at all - if( this->Coverage.TotalCoverage[filepath].size() == 0) - { - this->InitializeFile(filepath); - } - cmCTestCoverageHandlerContainer::SingleFileCoverageVector& - coverageVector = this->Coverage.TotalCoverage[filepath]; - coverageVector[lineoffset + linenumber] += count; - } - lastoffset = lineoffset; - } - else - { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Can not find mumps file : " - << routine << " referenced in this line of mcov data:\n" - "[" << line << "]\n"); - } - lastfunction = function; - lastroutine = routine; - lastpath = filepath; - } - return true; -} diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h index d4e901d..c6d7ef9 100644 --- a/Source/CTest/cmParseGTMCoverage.h +++ b/Source/CTest/cmParseGTMCoverage.h @@ -13,8 +13,7 @@ #ifndef cmParseGTMCoverage_h #define cmParseGTMCoverage_h -#include "cmStandardIncludes.h" -#include "cmCTestCoverageHandler.h" +#include "cmParseMumpsCoverage.h" /** \class cmParseGTMCoverage * \brief Parse GTM coverage information @@ -22,28 +21,28 @@ * This class is used to parse GTM coverage information for * mumps. */ -class cmParseGTMCoverage +class cmParseGTMCoverage : public cmParseMumpsCoverage { public: cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont, cmCTest* ctest); - bool ReadGTMCoverage(const char* file); -private: - bool ParseFile(std::string& filepath, - std::string& function, - int& lineoffset); - bool ParseLine(std::string const& line, +protected: + // implement virtual from parent + bool LoadCoverageData(const char* dir); + // Read a single mcov file + bool ReadMCovFile(const char* f); + // find out what line in a mumps file (filepath) the given entry point + // or function is. lineoffset is set by this method. + bool FindFunctionInMumpsFile(std::string const& filepath, + std::string const& function, + int& lineoffset); + // parse a line from a .mcov file, and fill in the + // routine, function, linenumber and coverage count + bool ParseMCOVLine(std::string const& line, std::string& routine, std::string& function, int& linenumber, int& count); - bool LoadPackages(const char* dir); - bool LoadCoverageData(const char* dir); - bool ReadMCovFile(const char* f); - void InitializeFile(std::string& file); - std::map<cmStdString, cmStdString> RoutineToDirectory; - cmCTestCoverageHandlerContainer& Coverage; - cmCTest* CTest; }; diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx new file mode 100644 index 0000000..359b5ac --- /dev/null +++ b/Source/CTest/cmParseMumpsCoverage.cxx @@ -0,0 +1,125 @@ +#include "cmStandardIncludes.h" +#include <stdio.h> +#include <stdlib.h> +#include "cmSystemTools.h" +#include "cmParseGTMCoverage.h" +#include <cmsys/Directory.hxx> +#include <cmsys/Glob.hxx> + + +cmParseMumpsCoverage::cmParseMumpsCoverage( + cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest) + :Coverage(cont), CTest(ctest) +{ +} + +bool cmParseMumpsCoverage::ReadCoverageFile(const char* file) +{ + // Read the gtm_coverage.mcov file, that has two lines of data: + // packages:/full/path/to/Vista/Packages + // coverage_dir:/full/path/to/dir/with/*.mcov + std::ifstream in(file); + if(!in) + { + return false; + } + std::string line; + cmSystemTools::GetLineFromStream(in, line); + std::string::size_type pos = line.find(':', 0); + std::string packages; + if(pos != std::string::npos) + { + packages = line.substr(pos+1); + } + cmSystemTools::GetLineFromStream(in, line); + pos = line.find(':', 0); + std::string coverage_dir; + if(pos != std::string::npos) + { + coverage_dir = line.substr(pos+1); + } + // load the mumps files from the packages directory + this->LoadPackages(packages.c_str()); + // now load the *.mcov files from the coverage directory + this->LoadCoverageData(coverage_dir.c_str()); + return true; +} + +void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file) +{ + // initialize the coverage information for a given mumps file + std::ifstream in(file.c_str()); + if(!in) + { + return; + } + std::string line; + cmCTestCoverageHandlerContainer::SingleFileCoverageVector& + coverageVector = this->Coverage.TotalCoverage[file]; + if(!cmSystemTools::GetLineFromStream(in, line)) + { + return; + } + // first line of a .m file can never be run + coverageVector.push_back(-1); + while( cmSystemTools::GetLineFromStream(in, line) ) + { + // putting in a 0 for a line means it is executable code + // putting in a -1 for a line means it is not executable code + int val = -1; // assume line is not executable + bool found = false; + std::string::size_type i = 0; + // (1) Search for the first whitespace or semicolon character on a line. + //This will skip over labels if the line starts with one, or will simply + //be the first character on the line for non-label lines. + for(; i < line.size(); ++i) + { + if(line[i] == ' ' || line[i] == '\t' || line[i] == ';') + { + found = true; + break; + } + } + if(found) + { + // (2) If the first character found above is whitespace then continue the + // search for the first following non-whitespace character. + if(line[i] == ' ' || line[i] == '\t') + { + while(i < line.size() && (line[i] == ' ' || line[i] == '\t')) + { + i++; + } + } + // (3) If the character found is not a semicolon then the line counts for + // coverage. + if(i < line.size() && line[i] != ';') + { + val = 0; + } + } + coverageVector.push_back(val); + } +} + +bool cmParseMumpsCoverage::LoadPackages(const char* d) +{ + cmsys::Glob glob; + glob.RecurseOn(); + std::string pat = d; + pat += "/*.m"; + glob.FindFiles(pat.c_str()); + std::vector<std::string>& files = glob.GetFiles(); + std::vector<std::string>::iterator fileIt; + for ( fileIt = files.begin(); fileIt != files.end(); + ++ fileIt ) + { + std::string name = cmSystemTools::GetFilenameName(*fileIt); + this->RoutineToDirectory[name.substr(0, name.size()-2)] = *fileIt; + // initialze each file, this is left out until CDash is fixed + // to handle large numbers of files +// this->InitializeMumpsFile(*fileIt); + } + return true; +} diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h new file mode 100644 index 0000000..63883de --- /dev/null +++ b/Source/CTest/cmParseMumpsCoverage.h @@ -0,0 +1,48 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmParseMumpsCoverage_h +#define cmParseMumpsCoverage_h + +#include "cmStandardIncludes.h" +#include "cmCTestCoverageHandler.h" + +/** \class cmParseMumpsCoverage + * \brief Parse Mumps coverage information + * + * This class is used as the base class for Mumps coverage + * parsing. + */ +class cmParseMumpsCoverage +{ +public: + cmParseMumpsCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest); + // This is the toplevel coverage file locating the coverage files + // and the mumps source code package tree. + bool ReadCoverageFile(const char* file); +protected: + // sub classes will use this to + // load all coverage files found in the given directory + virtual bool LoadCoverageData(const char* d) = 0; + // search the package directory for mumps files and fill + // in the RoutineToDirectory map + bool LoadPackages(const char* dir); + // initialize the coverage information for a single mumps file + void InitializeMumpsFile(std::string& file); +protected: + std::map<cmStdString, cmStdString> RoutineToDirectory; + cmCTestCoverageHandlerContainer& Coverage; + cmCTest* CTest; +}; + +#endif |