diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index abe1b42a1..b0486b46b 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -66,3 +66,8 @@ SET(CTEST_CUSTOM_COVERAGE_EXCLUDE # Exclude Qt source files from coverage results: "[A-Za-z]./[Qq]t/qt-.+-opensource-src" ) + +SET(CTEST_EXTRA_COVERAGE_GLOB + *.txx + *.cxx +) diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 10768866e..172e1c443 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -380,7 +380,6 @@ int cmCTestCoverageHandler::ProcessHandler() cmsys::RegularExpression(rexIt->c_str())); } - if(this->HandleBullseyeCoverage(&cont)) { return cont.Error; @@ -398,6 +397,7 @@ int cmCTestCoverageHandler::ProcessHandler() } error = cont.Error; + std::set uncovered = this->FindUncoveredFiles(&cont); if ( file_count == 0 ) { @@ -577,6 +577,49 @@ int cmCTestCoverageHandler::ProcessHandler() this->WriteXMLLabels(covSumFile, shortFileName); covSumFile << "\t" << std::endl; } + + //Handle all the files in the extra coverage globs that have no cov data + for(std::set::iterator i = uncovered.begin(); + i != uncovered.end(); ++i) + { + std::string shortFileName = this->CTest->GetShortPathToFile(i->c_str()); + covLogFile << "\tc_str()) + << "\" FullPath=\"" << cmXMLSafe(shortFileName) << "\">\n" + << "\t\t" << std::endl; + + std::ifstream ifs(i->c_str()); + if (!ifs) + { + cmOStringStream ostr; + ostr << "Cannot open source file: " << i->c_str(); + errorsWhileAccumulating.push_back(ostr.str()); + error ++; + continue; + } + int untested = 0; + std::string line; + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Actually perfoming coverage for: " << i->c_str() << std::endl); + while (cmSystemTools::GetLineFromStream(ifs, line)) + { + covLogFile << "\t\t" + << cmXMLSafe(line) << "" << std::endl; + untested ++; + } + covLogFile << "\t\t\n\t" << std::endl; + + total_untested += untested; + covSumFile << "\tc_str()) + << "\" FullPath=\"" << cmXMLSafe(shortFileName.c_str()) + << "\" Covered=\"true\">\n" + << "\t\t0\n" + << "\t\t" << untested << "\n" + << "\t\t0\n" + << "\t\t0\n"; + this->WriteXMLLabels(covSumFile, shortFileName); + covSumFile << "\t" << std::endl; + } + this->EndCoverageLogFile(covLogFile, logFileCount); if ( errorsWhileAccumulating.size() > 0 ) @@ -654,6 +697,8 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf) " Add coverage exclude regular expressions." << std::endl); this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_COVERAGE_EXCLUDE", this->CustomCoverageExclude); + this->CTest->PopulateCustomVector(mf, "CTEST_EXTRA_COVERAGE_GLOB", + this->ExtraCoverageGlobs); std::vector::iterator it; for ( it = this->CustomCoverageExclude.begin(); it != this->CustomCoverageExclude.end(); @@ -662,6 +707,12 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf) cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage exclude: " << it->c_str() << std::endl); } + for ( it = this->ExtraCoverageGlobs.begin(); + it != this->ExtraCoverageGlobs.end(); ++it) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage glob: " + << it->c_str() << std::endl); + } } //---------------------------------------------------------------------- @@ -1703,6 +1754,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( << "" << "" << std::endl; this->CTest->EndXML(covSumFile); + // Now create the coverage information for each file return this->RunBullseyeCoverageBranch(cont, coveredFileNames, @@ -1961,3 +2013,32 @@ bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source) } return true; } + +//---------------------------------------------------------------------- +std::set cmCTestCoverageHandler::FindUncoveredFiles( + cmCTestCoverageHandlerContainer* cont) +{ + std::set extraMatches; + + for(std::vector::iterator i = this->ExtraCoverageGlobs.begin(); + i != this->ExtraCoverageGlobs.end(); ++i) + { + cmsys::Glob gl; + gl.RecurseOn(); + gl.RecurseThroughSymlinksOff(); + std::string glob = cont->BinaryDir + "/" + *i; + gl.FindFiles(glob); + std::vector files = gl.GetFiles(); + extraMatches.insert(files.begin(), files.end()); + } + + if(extraMatches.size()) + { + for(cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator i = + cont->TotalCoverage.begin(); i != cont->TotalCoverage.end(); ++i) + { + extraMatches.erase(i->first); + } + } + return extraMatches; +} diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index b3e4db693..f0564e81e 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h @@ -66,6 +66,7 @@ private: std::set& coveredFileNames, std::vector& files, std::vector& filesFullPath); + int RunBullseyeCommand( cmCTestCoverageHandlerContainer* cont, const char* cmd, @@ -91,6 +92,9 @@ private: std::string FindFile(cmCTestCoverageHandlerContainer* cont, std::string fileName); + std::set FindUncoveredFiles( + cmCTestCoverageHandlerContainer* cont); + struct cmCTestCoverage { cmCTestCoverage() @@ -135,6 +139,7 @@ private: std::vector CustomCoverageExclude; std::vector CustomCoverageExcludeRegex; + std::vector ExtraCoverageGlobs; typedef std::map CoverageMap;