summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2009-03-02 20:33:18 (GMT)
committerBrad King <brad.king@kitware.com>2009-03-02 20:33:18 (GMT)
commit91a8569648aba920a4b168eb25e946ca012a93ba (patch)
tree722c768d8d402479d1c44ee205cd3a63f2d0faad
parent3078fef81c9f6d00aceba5ca16435ba37f1cdf03 (diff)
downloadCMake-91a8569648aba920a4b168eb25e946ca012a93ba.zip
CMake-91a8569648aba920a4b168eb25e946ca012a93ba.tar.gz
CMake-91a8569648aba920a4b168eb25e946ca012a93ba.tar.bz2
ENH: Teach ctest_coverage to filter with LABELS
This teaches ctest_coverage() to report only coverage of files labeled with at least one label given by a new LABELS option.
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx39
-rw-r--r--Source/CTest/cmCTestCoverageCommand.h18
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx45
-rw-r--r--Source/CTest/cmCTestCoverageHandler.h7
4 files changed, 105 insertions, 4 deletions
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index bf64afc..067a4e9 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -17,22 +17,55 @@
#include "cmCTestCoverageCommand.h"
#include "cmCTest.h"
-#include "cmCTestGenericHandler.h"
+#include "cmCTestCoverageHandler.h"
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
{
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
"CoverageCommand", "CTEST_COVERAGE_COMMAND");
- cmCTestGenericHandler* handler
- = this->CTest->GetInitializedHandler("coverage");
+ cmCTestCoverageHandler* handler = static_cast<cmCTestCoverageHandler*>(
+ this->CTest->GetInitializedHandler("coverage"));
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate test handler");
return 0;
}
+
+ // If a LABELS option was given, select only files with the labels.
+ if(this->LabelsMentioned)
+ {
+ handler->SetLabelFilter(this->Labels);
+ }
+
return handler;
}
+//----------------------------------------------------------------------------
+bool cmCTestCoverageCommand::CheckArgumentKeyword(std::string const& arg)
+{
+ // Look for arguments specific to this command.
+ if(arg == "LABELS")
+ {
+ this->ArgumentDoing = ArgumentDoingLabels;
+ this->LabelsMentioned = true;
+ return true;
+ }
+ // Look for other arguments.
+ return this->Superclass::CheckArgumentKeyword(arg);
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestCoverageCommand::CheckArgumentValue(std::string const& arg)
+{
+ // Handle states specific to this command.
+ if(this->ArgumentDoing == ArgumentDoingLabels)
+ {
+ this->Labels.insert(arg);
+ return true;
+ }
+ // Look for other arguments.
+ return this->Superclass::CheckArgumentValue(arg);
+}
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
index 3796392..c2062cd 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -60,11 +60,15 @@ public:
virtual const char* GetFullDocumentation()
{
return
- " ctest_coverage([BUILD build_dir] [RETURN_VALUE res] [APPEND])\n"
+ " ctest_coverage([BUILD build_dir] [RETURN_VALUE res] [APPEND]\n"
+ " [LABELS label1 [label2 [...]]])\n"
"Perform the coverage of the given build directory and stores results "
"in Coverage.xml. The second argument is a variable that will hold "
"value."
"\n"
+ "The LABELS option filters the coverage report to include only "
+ "source files labeled with at least one of the labels specified."
+ "\n"
CTEST_COMMAND_APPEND_OPTION_DOCS;
}
@@ -72,6 +76,18 @@ public:
protected:
cmCTestGenericHandler* InitializeHandler();
+
+ virtual bool CheckArgumentKeyword(std::string const& arg);
+ virtual bool CheckArgumentValue(std::string const& arg);
+
+ enum
+ {
+ ArgumentDoingLabels = Superclass::ArgumentDoingLast1,
+ ArgumentDoingLast2
+ };
+
+ bool LabelsMentioned;
+ std::set<cmStdString> Labels;
};
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index f39b7e1..1faf05a 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -17,6 +17,7 @@
#include "cmCTestCoverageHandler.h"
#include "cmCTest.h"
#include "cmake.h"
+#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmGeneratedFileStream.h"
#include "cmXMLSafe.h"
@@ -24,6 +25,8 @@
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Glob.hxx>
+#include <cmsys/stl/iterator>
+#include <cmsys/stl/algorithm>
#include <stdlib.h>
#include <math.h>
@@ -156,6 +159,7 @@ void cmCTestCoverageHandler::Initialize()
this->SourceLabels.clear();
this->LabelIdMap.clear();
this->Labels.clear();
+ this->LabelFilter.clear();
}
//----------------------------------------------------------------------
@@ -207,6 +211,11 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
const char* srcDir,
const char* binDir)
{
+ if(this->IsFilteredOut(file))
+ {
+ return false;
+ }
+
std::vector<cmsys::RegularExpression>::iterator sit;
for ( sit = this->CustomCoverageExcludeRegex.begin();
sit != this->CustomCoverageExcludeRegex.end(); ++ sit )
@@ -1817,3 +1826,39 @@ void cmCTestCoverageHandler::WriteXMLLabels(std::ofstream& os,
os << "\t\t</Labels>\n";
}
}
+
+//----------------------------------------------------------------------------
+void
+cmCTestCoverageHandler::SetLabelFilter(std::set<cmStdString> const& labels)
+{
+ this->LabelFilter.clear();
+ for(std::set<cmStdString>::const_iterator li = labels.begin();
+ li != labels.end(); ++li)
+ {
+ this->LabelFilter.insert(this->GetLabelId(*li));
+ }
+}
+
+//----------------------------------------------------------------------
+bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source)
+{
+ // If there is no label filter then nothing is filtered out.
+ if(this->LabelFilter.empty())
+ {
+ return false;
+ }
+
+ // The source is filtered out if it does not have any labels in
+ // common with the filter set.
+ std::vector<int> ids;
+ std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
+ LabelMapType::const_iterator li = this->SourceLabels.find(shortSrc);
+ if(li != this->SourceLabels.end() && !li->second.empty())
+ {
+ cmsys_stl::set_intersection
+ (li->second.begin(), li->second.end(),
+ this->LabelFilter.begin(), this->LabelFilter.end(),
+ cmsys_stl::back_inserter(ids));
+ }
+ return ids.empty();
+}
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index b391b87..48894fb 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -50,6 +50,9 @@ public:
*/
void PopulateCustomVectors(cmMakefile *mf);
+ /** Report coverage only for sources with these labels. */
+ void SetLabelFilter(std::set<cmStdString> const& labels);
+
private:
bool ShouldIDoCoverage(const char* file, const char* srcDir,
const char* binDir);
@@ -153,6 +156,10 @@ private:
void LoadLabels();
void LoadLabels(const char* fname);
void WriteXMLLabels(std::ofstream& os, std::string const& source);
+
+ // Label-based filtering.
+ std::set<int> LabelFilter;
+ bool IsFilteredOut(std::string const& source);
};
#endif