summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2019-09-26 13:22:00 (GMT)
committerKitware Robot <kwrobot@kitware.com>2019-09-26 13:22:13 (GMT)
commit67e6b55c5885c445b5b78b41a66529553dcab069 (patch)
treeb81531ae84bc02bfe7abe2e3c93fcaf4eb705dfb
parentb42cb1ff80dc056da4036c7b65109d1a77d84bf4 (diff)
parent0aa8a2ab8b00c0889df3d0fa1be47ad5a0b9db22 (diff)
downloadCMake-67e6b55c5885c445b5b78b41a66529553dcab069.zip
CMake-67e6b55c5885c445b5b78b41a66529553dcab069.tar.gz
CMake-67e6b55c5885c445b5b78b41a66529553dcab069.tar.bz2
Merge topic 'ctest-argument-parser'
0aa8a2ab8b cmCTest*Command: Port to cmArgumentParser d5a6a13368 cmArgumentParser: Record parsed keywords Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !3835
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx45
-rw-r--r--Source/CTest/cmCTestBuildCommand.h23
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx12
-rw-r--r--Source/CTest/cmCTestConfigureCommand.h10
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx44
-rw-r--r--Source/CTest/cmCTestCoverageCommand.h19
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx147
-rw-r--r--Source/CTest/cmCTestHandlerCommand.h48
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx15
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.h11
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx155
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h48
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx104
-rw-r--r--Source/CTest/cmCTestTestCommand.h37
-rw-r--r--Source/CTest/cmCTestUpdateCommand.cxx7
-rw-r--r--Source/CTest/cmCTestUpdateCommand.h2
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx64
-rw-r--r--Source/CTest/cmCTestUploadCommand.h18
-rw-r--r--Source/cmArgumentParser.cxx6
-rw-r--r--Source/cmArgumentParser.h21
20 files changed, 289 insertions, 547 deletions
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 02b00e3..ce690f9 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -9,6 +9,7 @@
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cm_static_string_view.hxx"
#include "cmake.h"
#include <cstring>
@@ -16,17 +17,15 @@
class cmExecutionStatus;
-cmCTestBuildCommand::cmCTestBuildCommand()
+void cmCTestBuildCommand::BindArguments()
{
- this->GlobalGenerator = nullptr;
- this->Arguments[ctb_NUMBER_ERRORS] = "NUMBER_ERRORS";
- this->Arguments[ctb_NUMBER_WARNINGS] = "NUMBER_WARNINGS";
- this->Arguments[ctb_TARGET] = "TARGET";
- this->Arguments[ctb_CONFIGURATION] = "CONFIGURATION";
- this->Arguments[ctb_FLAGS] = "FLAGS";
- this->Arguments[ctb_PROJECT_NAME] = "PROJECT_NAME";
- this->Arguments[ctb_LAST] = nullptr;
- this->Last = ctb_LAST;
+ this->cmCTestHandlerCommand::BindArguments();
+ this->Bind("NUMBER_ERRORS"_s, this->NumberErrors);
+ this->Bind("NUMBER_WARNINGS"_s, this->NumberWarnings);
+ this->Bind("TARGET"_s, this->Target);
+ this->Bind("CONFIGURATION"_s, this->Configuration);
+ this->Bind("FLAGS"_s, this->Flags);
+ this->Bind("PROJECT_NAME"_s, this->ProjectName);
}
cmCTestBuildCommand::~cmCTestBuildCommand()
@@ -60,20 +59,17 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
//
const char* ctestBuildConfiguration =
this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
- const char* cmakeBuildConfiguration =
- (this->Values[ctb_CONFIGURATION] && *this->Values[ctb_CONFIGURATION])
- ? this->Values[ctb_CONFIGURATION]
+ const char* cmakeBuildConfiguration = !this->Configuration.empty()
+ ? this->Configuration.c_str()
: ((ctestBuildConfiguration && *ctestBuildConfiguration)
? ctestBuildConfiguration
: this->CTest->GetConfigType().c_str());
- const char* cmakeBuildAdditionalFlags =
- (this->Values[ctb_FLAGS] && *this->Values[ctb_FLAGS])
- ? this->Values[ctb_FLAGS]
+ const char* cmakeBuildAdditionalFlags = !this->Flags.empty()
+ ? this->Flags.c_str()
: this->Makefile->GetDefinition("CTEST_BUILD_FLAGS");
- const char* cmakeBuildTarget =
- (this->Values[ctb_TARGET] && *this->Values[ctb_TARGET])
- ? this->Values[ctb_TARGET]
+ const char* cmakeBuildTarget = !this->Target.empty()
+ ? this->Target.c_str()
: this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
if (cmakeGeneratorName && *cmakeGeneratorName) {
@@ -153,16 +149,13 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
bool ret = cmCTestHandlerCommand::InitialPass(args, status);
- if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) {
+ if (!this->NumberErrors.empty()) {
this->Makefile->AddDefinition(
- this->Values[ctb_NUMBER_ERRORS],
- std::to_string(this->Handler->GetTotalErrors()));
+ this->NumberErrors, std::to_string(this->Handler->GetTotalErrors()));
}
- if (this->Values[ctb_NUMBER_WARNINGS] &&
- *this->Values[ctb_NUMBER_WARNINGS]) {
+ if (!this->NumberWarnings.empty()) {
this->Makefile->AddDefinition(
- this->Values[ctb_NUMBER_WARNINGS],
- std::to_string(this->Handler->GetTotalWarnings()));
+ this->NumberWarnings, std::to_string(this->Handler->GetTotalWarnings()));
}
return ret;
}
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index 14f70bf..791e1f0 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -27,7 +27,6 @@ class cmGlobalGenerator;
class cmCTestBuildCommand : public cmCTestHandlerCommand
{
public:
- cmCTestBuildCommand();
~cmCTestBuildCommand() override;
/**
@@ -49,23 +48,19 @@ public:
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status) override;
- cmGlobalGenerator* GlobalGenerator;
+ cmGlobalGenerator* GlobalGenerator = nullptr;
protected:
cmCTestBuildHandler* Handler;
- enum
- {
- ctb_BUILD = ct_LAST,
- ctb_NUMBER_ERRORS,
- ctb_NUMBER_WARNINGS,
- ctb_TARGET,
- ctb_CONFIGURATION,
- ctb_FLAGS,
- ctb_PROJECT_NAME,
- ctb_LAST
- };
-
+ void BindArguments() override;
cmCTestGenericHandler* InitializeHandler() override;
+
+ std::string NumberErrors;
+ std::string NumberWarnings;
+ std::string Target;
+ std::string Configuration;
+ std::string Flags;
+ std::string ProjectName;
};
#endif
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 8a56f3d..948b9fb 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -8,25 +8,25 @@
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cm_static_string_view.hxx"
#include "cmake.h"
#include <cstring>
#include <sstream>
#include <vector>
-cmCTestConfigureCommand::cmCTestConfigureCommand()
+void cmCTestConfigureCommand::BindArguments()
{
- this->Arguments[ctc_OPTIONS] = "OPTIONS";
- this->Arguments[ctc_LAST] = nullptr;
- this->Last = ctc_LAST;
+ this->cmCTestHandlerCommand::BindArguments();
+ this->Bind("OPTIONS"_s, this->Options);
}
cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
{
std::vector<std::string> options;
- if (this->Values[ctc_OPTIONS]) {
- cmExpandList(this->Values[ctc_OPTIONS], options);
+ if (!this->Options.empty()) {
+ cmExpandList(this->Options, options);
}
if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) {
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h
index 36ca7d5..0bc7848 100644
--- a/Source/CTest/cmCTestConfigureCommand.h
+++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -23,8 +23,6 @@ class cmCTestGenericHandler;
class cmCTestConfigureCommand : public cmCTestHandlerCommand
{
public:
- cmCTestConfigureCommand();
-
/**
* This is a virtual constructor for the command.
*/
@@ -42,14 +40,10 @@ public:
std::string GetName() const override { return "ctest_configure"; }
protected:
+ void BindArguments() override;
cmCTestGenericHandler* InitializeHandler() override;
- enum
- {
- ctc_FIRST = ct_LAST,
- ctc_OPTIONS,
- ctc_LAST
- };
+ std::string Options;
};
#endif
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index 07aae76..b66bba7 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -2,14 +2,26 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestCoverageCommand.h"
+#include <set>
+
+#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
+#include "cm_static_string_view.hxx"
class cmCTestGenericHandler;
-cmCTestCoverageCommand::cmCTestCoverageCommand()
+void cmCTestCoverageCommand::BindArguments()
+{
+ this->cmCTestHandlerCommand::BindArguments();
+ this->Bind("LABELS"_s, this->Labels);
+}
+
+void cmCTestCoverageCommand::CheckArguments(
+ std::vector<std::string> const& keywords)
{
- this->LabelsMentioned = false;
+ this->LabelsMentioned =
+ !this->Labels.empty() || cmContains(keywords, "LABELS");
}
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
@@ -24,34 +36,10 @@ cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
// If a LABELS option was given, select only files with the labels.
if (this->LabelsMentioned) {
- handler->SetLabelFilter(this->Labels);
+ handler->SetLabelFilter(
+ std::set<std::string>(this->Labels.begin(), this->Labels.end()));
}
handler->SetQuiet(this->Quiet);
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 75aefdf..fcffa75 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -8,9 +8,9 @@
#include "cmCTestHandlerCommand.h"
#include "cmCommand.h"
-#include <set>
#include <string>
#include <utility>
+#include <vector>
#include <cm/memory>
@@ -24,8 +24,6 @@ class cmCTestGenericHandler;
class cmCTestCoverageCommand : public cmCTestHandlerCommand
{
public:
- cmCTestCoverageCommand();
-
/**
* This is a virtual constructor for the command.
*/
@@ -42,22 +40,13 @@ public:
*/
std::string GetName() const override { return "ctest_coverage"; }
- using Superclass = cmCTestHandlerCommand;
-
protected:
+ void BindArguments() override;
+ void CheckArguments(std::vector<std::string> const& keywords) override;
cmCTestGenericHandler* InitializeHandler() override;
- bool CheckArgumentKeyword(std::string const& arg) override;
- bool CheckArgumentValue(std::string const& arg) override;
-
- enum
- {
- ArgumentDoingLabels = Superclass::ArgumentDoingLast1,
- ArgumentDoingLast2
- };
-
bool LabelsMentioned;
- std::set<std::string> Labels;
+ std::vector<std::string> Labels;
};
#endif
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index 9c5425d..3f9ce4e 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -7,31 +7,16 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
+#include "cm_static_string_view.hxx"
+#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <sstream>
-cmCTestHandlerCommand::cmCTestHandlerCommand()
-{
- const size_t INIT_SIZE = 100;
- size_t cc;
- this->Arguments.reserve(INIT_SIZE);
- for (cc = 0; cc < INIT_SIZE; ++cc) {
- this->Arguments.push_back(nullptr);
- }
- this->Arguments[ct_RETURN_VALUE] = "RETURN_VALUE";
- this->Arguments[ct_CAPTURE_CMAKE_ERROR] = "CAPTURE_CMAKE_ERROR";
- this->Arguments[ct_SOURCE] = "SOURCE";
- this->Arguments[ct_BUILD] = "BUILD";
- this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX";
- this->Last = ct_LAST;
- this->AppendXML = false;
- this->Quiet = false;
-}
-
namespace {
// class to save and restore the error state for ctest_* commands
// if a ctest_* command has a CAPTURE_CMAKE_ERROR then put the error
@@ -90,30 +75,30 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
// save error state and restore it if needed
SaveRestoreErrorState errorState;
// Allocate space for argument values.
- this->Values.clear();
- this->Values.resize(this->Last, nullptr);
+ this->BindArguments();
// Process input arguments.
- this->ArgumentDoing = ArgumentDoingNone;
- // look at all arguments and do not short circuit on the first
- // bad one so that CAPTURE_CMAKE_ERROR can override setting the
- // global error state
- bool foundBadArgument = false;
- for (std::string const& arg : args) {
- // Check this argument.
- if (!this->CheckArgumentKeyword(arg) && !this->CheckArgumentValue(arg)) {
- std::ostringstream e;
- e << "called with unknown argument \"" << arg << "\".";
- this->SetError(e.str());
- foundBadArgument = true;
- }
- // note bad argument
- if (this->ArgumentDoing == ArgumentDoingError) {
- foundBadArgument = true;
- }
+ std::vector<std::string> unparsedArguments;
+ std::vector<std::string> keywordsMissingValue;
+ std::vector<std::string> parsedKeywords;
+ this->Parse(args, &unparsedArguments, &keywordsMissingValue,
+ &parsedKeywords);
+ this->CheckArguments(keywordsMissingValue);
+
+ std::sort(parsedKeywords.begin(), parsedKeywords.end());
+ auto it = std::adjacent_find(parsedKeywords.begin(), parsedKeywords.end());
+ if (it != parsedKeywords.end()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Called with more than one value for ", *it));
+ }
+
+ bool const foundBadArgument = !unparsedArguments.empty();
+ if (foundBadArgument) {
+ this->SetError(cmStrCat("called with unknown argument \"",
+ unparsedArguments.front(), "\"."));
}
- bool captureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] &&
- *this->Values[ct_CAPTURE_CMAKE_ERROR]);
+ bool const captureCMakeError = !this->CaptureCMakeError.empty();
// now that arguments are parsed check to see if there is a
// CAPTURE_CMAKE_ERROR specified let the errorState object know.
if (captureCMakeError) {
@@ -123,8 +108,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
if (foundBadArgument) {
// store the cmake error
if (captureCMakeError) {
- this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
- "-1");
+ this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
std::string const err = this->GetName() + " " + status.GetError();
if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
@@ -146,10 +130,9 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->CTest->SetConfigType(ctestConfigType);
}
- if (this->Values[ct_BUILD]) {
+ if (!this->Build.empty()) {
this->CTest->SetCTestConfiguration(
- "BuildDirectory",
- cmSystemTools::CollapseFullPath(this->Values[ct_BUILD]).c_str(),
+ "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build).c_str(),
this->Quiet);
} else {
std::string const& bdir =
@@ -163,13 +146,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
"CTEST_BINARY_DIRECTORY not set" << std::endl;);
}
}
- if (this->Values[ct_SOURCE]) {
+ if (!this->Source.empty()) {
cmCTestLog(this->CTest, DEBUG,
- "Set source directory to: " << this->Values[ct_SOURCE]
- << std::endl);
+ "Set source directory to: " << this->Source << std::endl);
this->CTest->SetCTestConfiguration(
- "SourceDirectory",
- cmSystemTools::CollapseFullPath(this->Values[ct_SOURCE]).c_str(),
+ "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
this->Quiet);
} else {
this->CTest->SetCTestConfiguration(
@@ -192,8 +173,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
"Cannot instantiate test handler " << this->GetName()
<< std::endl);
if (captureCMakeError) {
- this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
- "-1");
+ this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
std::string const& err = status.GetError();
if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
@@ -203,11 +183,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
return false;
}
- handler->SetAppendXML(this->AppendXML);
+ handler->SetAppendXML(this->Append);
handler->PopulateCustomVectors(this->Makefile);
- if (this->Values[ct_SUBMIT_INDEX]) {
- handler->SetSubmitIndex(atoi(this->Values[ct_SUBMIT_INDEX]));
+ if (!this->SubmitIndex.empty()) {
+ handler->SetSubmitIndex(atoi(this->SubmitIndex.c_str()));
}
cmWorkingDirectory workdir(
this->CTest->GetCTestConfiguration("BuildDirectory"));
@@ -216,8 +196,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->CTest->GetCTestConfiguration("BuildDirectory") +
" : " + std::strerror(workdir.GetLastResult()));
if (captureCMakeError) {
- this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
- "-1");
+ this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
cmCTestLog(this->CTest, ERROR_MESSAGE,
this->GetName() << " " << status.GetError() << "\n");
// return success because failure is recorded in CAPTURE_CMAKE_ERROR
@@ -227,9 +206,8 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
}
int res = handler->ProcessHandler();
- if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) {
- this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE],
- std::to_string(res));
+ if (!this->ReturnValue.empty()) {
+ this->Makefile->AddDefinition(this->ReturnValue, std::to_string(res));
}
this->ProcessAdditionalValues(handler);
// log the error message if there was an error
@@ -245,8 +223,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
}
}
// store the captured cmake error state 0 or -1
- this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
- returnString);
+ this->Makefile->AddDefinition(this->CaptureCMakeError, returnString);
}
return true;
}
@@ -255,47 +232,17 @@ void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*)
{
}
-bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
+void cmCTestHandlerCommand::BindArguments()
{
- // Look for non-value arguments common to all commands.
- if (arg == "APPEND") {
- this->ArgumentDoing = ArgumentDoingNone;
- this->AppendXML = true;
- return true;
- }
- if (arg == "QUIET") {
- this->ArgumentDoing = ArgumentDoingNone;
- this->Quiet = true;
- return true;
- }
-
- // Check for a keyword in our argument/value table.
- for (unsigned int k = 0; k < this->Arguments.size(); ++k) {
- if (this->Arguments[k] && arg == this->Arguments[k]) {
- this->ArgumentDoing = ArgumentDoingKeyword;
- this->ArgumentIndex = k;
- return true;
- }
- }
- return false;
+ this->Bind("APPEND"_s, this->Append);
+ this->Bind("QUIET"_s, this->Quiet);
+ this->Bind("RETURN_VALUE"_s, this->ReturnValue);
+ this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError);
+ this->Bind("SOURCE"_s, this->Source);
+ this->Bind("BUILD"_s, this->Build);
+ this->Bind("SUBMIT_INDEX"_s, this->SubmitIndex);
}
-bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg)
+void cmCTestHandlerCommand::CheckArguments(std::vector<std::string> const&)
{
- if (this->ArgumentDoing == ArgumentDoingKeyword) {
- this->ArgumentDoing = ArgumentDoingNone;
- unsigned int k = this->ArgumentIndex;
- if (this->Values[k]) {
- std::ostringstream e;
- e << "Called with more than one value for " << this->Arguments[k];
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- this->ArgumentDoing = ArgumentDoingError;
- return true;
- }
- this->Values[k] = arg.c_str();
- cmCTestLog(this->CTest, DEBUG,
- "Set " << this->Arguments[k] << " to " << arg << "\n");
- return true;
- }
- return false;
}
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
index 79d61f3..5bbc569 100644
--- a/Source/CTest/cmCTestHandlerCommand.h
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -5,9 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cmArgumentParser.h"
#include "cmCTestCommand.h"
-#include <stddef.h>
#include <string>
#include <vector>
@@ -19,11 +19,11 @@ class cmExecutionStatus;
*
* cmCTestHandlerCommand defineds the command to test the project.
*/
-class cmCTestHandlerCommand : public cmCTestCommand
+class cmCTestHandlerCommand
+ : public cmCTestCommand
+ , public cmArgumentParser<void>
{
public:
- cmCTestHandlerCommand();
-
/**
* The name of the command as specified in CMakeList.txt.
*/
@@ -36,42 +36,22 @@ public:
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status) override;
- enum
- {
- ct_NONE,
- ct_RETURN_VALUE,
- ct_CAPTURE_CMAKE_ERROR,
- ct_BUILD,
- ct_SOURCE,
- ct_SUBMIT_INDEX,
- ct_LAST
- };
-
protected:
virtual cmCTestGenericHandler* InitializeHandler() = 0;
virtual void ProcessAdditionalValues(cmCTestGenericHandler* handler);
// Command argument handling.
- virtual bool CheckArgumentKeyword(std::string const& arg);
- virtual bool CheckArgumentValue(std::string const& arg);
- enum
- {
- ArgumentDoingNone,
- ArgumentDoingError,
- ArgumentDoingKeyword,
- ArgumentDoingLast1
- };
- int ArgumentDoing;
- unsigned int ArgumentIndex;
-
- bool AppendXML;
- bool Quiet;
-
- std::string ReturnVariable;
- std::vector<const char*> Arguments;
- std::vector<const char*> Values;
- size_t Last;
+ virtual void BindArguments();
+ virtual void CheckArguments(std::vector<std::string> const& keywords);
+
+ bool Append = false;
+ bool Quiet = false;
+ std::string CaptureCMakeError;
+ std::string ReturnValue;
+ std::string Build;
+ std::string Source;
+ std::string SubmitIndex;
};
#define CTEST_COMMAND_APPEND_OPTION_DOCS \
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 804efa5..abad5fc 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -2,18 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckCommand.h"
-#include <string>
-#include <vector>
-
#include "cmCTest.h"
#include "cmCTestMemCheckHandler.h"
#include "cmMakefile.h"
+#include "cm_static_string_view.hxx"
-cmCTestMemCheckCommand::cmCTestMemCheckCommand()
+void cmCTestMemCheckCommand::BindArguments()
{
- this->Arguments[ctm_DEFECT_COUNT] = "DEFECT_COUNT";
- this->Arguments[ctm_LAST] = nullptr;
- this->Last = ctm_LAST;
+ this->cmCTestTestCommand::BindArguments();
+ this->Bind("DEFECT_COUNT"_s, this->DefectCount);
}
cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
@@ -43,9 +40,9 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
void cmCTestMemCheckCommand::ProcessAdditionalValues(
cmCTestGenericHandler* handler)
{
- if (this->Values[ctm_DEFECT_COUNT] && *this->Values[ctm_DEFECT_COUNT]) {
+ if (!this->DefectCount.empty()) {
this->Makefile->AddDefinition(
- this->Values[ctm_DEFECT_COUNT],
+ this->DefectCount,
std::to_string(
static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount()));
}
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index 5dad4e7..8f4ffb8 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
#include <utility>
#include <cm/memory>
@@ -22,8 +23,6 @@ class cmCTestGenericHandler;
class cmCTestMemCheckCommand : public cmCTestTestCommand
{
public:
- cmCTestMemCheckCommand();
-
/**
* This is a virtual constructor for the command.
*/
@@ -36,15 +35,13 @@ public:
}
protected:
+ void BindArguments() override;
+
cmCTestGenericHandler* InitializeActualHandler() override;
void ProcessAdditionalValues(cmCTestGenericHandler* handler) override;
- enum
- {
- ctm_DEFECT_COUNT = ctt_LAST,
- ctm_LAST
- };
+ std::string DefectCount;
};
#endif
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 2e2cf1a..706b45a 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -2,14 +2,18 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestSubmitCommand.h"
+#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
#include "cmCommand.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cm_static_string_view.hxx"
+#include <set>
#include <sstream>
#include <utility>
@@ -17,18 +21,6 @@
class cmExecutionStatus;
-cmCTestSubmitCommand::cmCTestSubmitCommand()
-{
- this->PartsMentioned = false;
- this->FilesMentioned = false;
- this->InternalTest = false;
- this->RetryCount = "";
- this->RetryDelay = "";
- this->CDashUpload = false;
- this->Arguments[cts_BUILD_ID] = "BUILD_ID";
- this->Last = cts_LAST;
-}
-
/**
* This is a virtual constructor for the command.
*/
@@ -106,13 +98,18 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
// without any of the default parts.
//
handler->SelectParts(std::set<cmCTest::Part>());
- handler->SelectFiles(this->Files);
+ handler->SelectFiles(
+ std::set<std::string>(this->Files.begin(), this->Files.end()));
}
// If a PARTS option was given, select only the named parts for submission.
//
if (this->PartsMentioned) {
- handler->SelectParts(this->Parts);
+ auto parts =
+ cmMakeRange(this->Parts).transform([this](std::string const& arg) {
+ return this->CTest->GetPartFromName(arg.c_str());
+ });
+ handler->SelectParts(std::set<cmCTest::Part>(parts.begin(), parts.end()));
}
// Pass along any HTTPHEADER to the handler if this option was given.
@@ -140,133 +137,61 @@ bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args,
bool ret = this->cmCTestHandlerCommand::InitialPass(args, status);
- if (this->Values[cts_BUILD_ID] && *this->Values[cts_BUILD_ID]) {
- this->Makefile->AddDefinition(this->Values[cts_BUILD_ID],
- this->CTest->GetBuildID());
+ if (!this->BuildID.empty()) {
+ this->Makefile->AddDefinition(this->BuildID, this->CTest->GetBuildID());
}
return ret;
}
-bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
+void cmCTestSubmitCommand::BindArguments()
{
if (this->CDashUpload) {
// Arguments specific to the CDASH_UPLOAD signature.
- if (arg == "CDASH_UPLOAD") {
- this->ArgumentDoing = ArgumentDoingCDashUpload;
- return true;
- }
-
- if (arg == "CDASH_UPLOAD_TYPE") {
- this->ArgumentDoing = ArgumentDoingCDashUploadType;
- return true;
- }
+ this->Bind("CDASH_UPLOAD", this->CDashUploadFile);
+ this->Bind("CDASH_UPLOAD_TYPE", this->CDashUploadType);
} else {
// Arguments that cannot be used with CDASH_UPLOAD.
- if (arg == "PARTS") {
- this->ArgumentDoing = ArgumentDoingParts;
- this->PartsMentioned = true;
- return true;
- }
-
- if (arg == "FILES") {
- this->ArgumentDoing = ArgumentDoingFiles;
- this->FilesMentioned = true;
- return true;
- }
+ this->Bind("PARTS"_s, this->Parts);
+ this->Bind("FILES"_s, this->Files);
}
// Arguments used by both modes.
- if (arg == "HTTPHEADER") {
- this->ArgumentDoing = ArgumentDoingHttpHeader;
- return true;
- }
-
- if (arg == "RETRY_COUNT") {
- this->ArgumentDoing = ArgumentDoingRetryCount;
- return true;
- }
-
- if (arg == "RETRY_DELAY") {
- this->ArgumentDoing = ArgumentDoingRetryDelay;
- return true;
- }
-
- if (arg == "SUBMIT_URL") {
- this->ArgumentDoing = ArgumentDoingSubmitURL;
- return true;
- }
-
- if (arg == "INTERNAL_TEST_CHECKSUM") {
- this->InternalTest = true;
- return true;
- }
+ this->Bind("BUILD_ID"_s, this->BuildID);
+ this->Bind("HTTPHEADER"_s, this->HttpHeaders);
+ this->Bind("RETRY_COUNT"_s, this->RetryCount);
+ this->Bind("RETRY_DELAY"_s, this->RetryDelay);
+ this->Bind("SUBMIT_URL"_s, this->SubmitURL);
+ this->Bind("INTERNAL_TEST_CHECKSUM", this->InternalTest);
// Look for other arguments.
- return this->Superclass::CheckArgumentKeyword(arg);
+ this->cmCTestHandlerCommand::BindArguments();
}
-bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
+void cmCTestSubmitCommand::CheckArguments(
+ std::vector<std::string> const& keywords)
{
- // Handle states specific to this command.
- if (this->ArgumentDoing == ArgumentDoingParts) {
+ this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS");
+ this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES");
+
+ cmEraseIf(this->Parts, [this](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
- if (p != cmCTest::PartCount) {
- this->Parts.insert(p);
- } else {
+ if (p == cmCTest::PartCount) {
std::ostringstream e;
e << "Part name \"" << arg << "\" is invalid.";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- this->ArgumentDoing = ArgumentDoingError;
+ return true;
}
- return true;
- }
+ return false;
+ });
- if (this->ArgumentDoing == ArgumentDoingFiles) {
- if (cmSystemTools::FileExists(arg)) {
- this->Files.insert(arg);
- } else {
+ cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
+ if (!cmSystemTools::FileExists(arg)) {
std::ostringstream e;
e << "File \"" << arg << "\" does not exist. Cannot submit "
<< "a non-existent file.";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- this->ArgumentDoing = ArgumentDoingError;
+ return true;
}
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingHttpHeader) {
- this->HttpHeaders.push_back(arg);
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingRetryCount) {
- this->RetryCount = arg;
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingRetryDelay) {
- this->RetryDelay = arg;
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingCDashUpload) {
- this->ArgumentDoing = ArgumentDoingNone;
- this->CDashUploadFile = arg;
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingCDashUploadType) {
- this->ArgumentDoing = ArgumentDoingNone;
- this->CDashUploadType = arg;
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingSubmitURL) {
- this->ArgumentDoing = ArgumentDoingNone;
- this->SubmitURL = arg;
- return true;
- }
-
- // Look for other arguments.
- return this->Superclass::CheckArgumentValue(arg);
+ return false;
+ });
}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index 8562207..249f844 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -5,11 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTest.h"
#include "cmCTestHandlerCommand.h"
#include <memory>
-#include <set>
#include <string>
#include <vector>
@@ -26,7 +24,6 @@ class cmExecutionStatus;
class cmCTestSubmitCommand : public cmCTestHandlerCommand
{
public:
- cmCTestSubmitCommand();
std::unique_ptr<cmCommand> Clone() override;
bool InitialPass(std::vector<std::string> const& args,
@@ -37,45 +34,26 @@ public:
*/
std::string GetName() const override { return "ctest_submit"; }
- using Superclass = cmCTestHandlerCommand;
-
protected:
+ void BindArguments() override;
+ void CheckArguments(std::vector<std::string> const& keywords) override;
cmCTestGenericHandler* InitializeHandler() override;
- bool CheckArgumentKeyword(std::string const& arg) override;
- bool CheckArgumentValue(std::string const& arg) override;
-
- enum
- {
- ArgumentDoingParts = Superclass::ArgumentDoingLast1,
- ArgumentDoingFiles,
- ArgumentDoingRetryDelay,
- ArgumentDoingRetryCount,
- ArgumentDoingCDashUpload,
- ArgumentDoingCDashUploadType,
- ArgumentDoingHttpHeader,
- ArgumentDoingSubmitURL,
- ArgumentDoingLast2
- };
-
- enum
- {
- cts_BUILD_ID = ct_LAST,
- cts_LAST
- };
+ bool CDashUpload = false;
+ bool FilesMentioned = false;
+ bool InternalTest = false;
+ bool PartsMentioned = false;
- bool PartsMentioned;
- std::set<cmCTest::Part> Parts;
- bool FilesMentioned;
- bool InternalTest;
- std::set<std::string> Files;
- std::string RetryCount;
- std::string RetryDelay;
- bool CDashUpload;
+ std::string BuildID;
std::string CDashUploadFile;
std::string CDashUploadType;
- std::vector<std::string> HttpHeaders;
+ std::string RetryCount;
+ std::string RetryDelay;
std::string SubmitURL;
+
+ std::vector<std::string> Files;
+ std::vector<std::string> HttpHeaders;
+ std::vector<std::string> Parts;
};
#endif
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 3a29ad3..c277db8 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -8,30 +8,29 @@
#include "cmDuration.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
+#include "cm_static_string_view.hxx"
#include <chrono>
#include <cstdlib>
#include <sstream>
-#include <vector>
-cmCTestTestCommand::cmCTestTestCommand()
+void cmCTestTestCommand::BindArguments()
{
- this->Arguments[ctt_START] = "START";
- this->Arguments[ctt_END] = "END";
- this->Arguments[ctt_STRIDE] = "STRIDE";
- this->Arguments[ctt_EXCLUDE] = "EXCLUDE";
- this->Arguments[ctt_INCLUDE] = "INCLUDE";
- this->Arguments[ctt_EXCLUDE_LABEL] = "EXCLUDE_LABEL";
- this->Arguments[ctt_INCLUDE_LABEL] = "INCLUDE_LABEL";
- this->Arguments[ctt_EXCLUDE_FIXTURE] = "EXCLUDE_FIXTURE";
- this->Arguments[ctt_EXCLUDE_FIXTURE_SETUP] = "EXCLUDE_FIXTURE_SETUP";
- this->Arguments[ctt_EXCLUDE_FIXTURE_CLEANUP] = "EXCLUDE_FIXTURE_CLEANUP";
- this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL";
- this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM";
- this->Arguments[ctt_STOP_TIME] = "STOP_TIME";
- this->Arguments[ctt_TEST_LOAD] = "TEST_LOAD";
- this->Arguments[ctt_LAST] = nullptr;
- this->Last = ctt_LAST;
+ this->cmCTestHandlerCommand::BindArguments();
+ this->Bind("START"_s, this->Start);
+ this->Bind("END"_s, this->End);
+ this->Bind("STRIDE"_s, this->Stride);
+ this->Bind("EXCLUDE"_s, this->Exclude);
+ this->Bind("INCLUDE"_s, this->Include);
+ this->Bind("EXCLUDE_LABEL"_s, this->ExcludeLabel);
+ this->Bind("INCLUDE_LABEL"_s, this->IncludeLabel);
+ this->Bind("EXCLUDE_FIXTURE"_s, this->ExcludeFixture);
+ this->Bind("EXCLUDE_FIXTURE_SETUP"_s, this->ExcludeFixtureSetup);
+ this->Bind("EXCLUDE_FIXTURE_CLEANUP"_s, this->ExcludeFixtureCleanup);
+ this->Bind("PARALLEL_LEVEL"_s, this->ParallelLevel);
+ this->Bind("SCHEDULE_RANDOM"_s, this->ScheduleRandom);
+ this->Bind("STOP_TIME"_s, this->StopTime);
+ this->Bind("TEST_LOAD"_s, this->TestLoad);
}
cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
@@ -51,57 +50,44 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
}
this->CTest->SetTimeOut(timeout);
cmCTestGenericHandler* handler = this->InitializeActualHandler();
- if (this->Values[ctt_START] || this->Values[ctt_END] ||
- this->Values[ctt_STRIDE]) {
- std::ostringstream testsToRunString;
- if (this->Values[ctt_START]) {
- testsToRunString << this->Values[ctt_START];
- }
- testsToRunString << ",";
- if (this->Values[ctt_END]) {
- testsToRunString << this->Values[ctt_END];
- }
- testsToRunString << ",";
- if (this->Values[ctt_STRIDE]) {
- testsToRunString << this->Values[ctt_STRIDE];
- }
- handler->SetOption("TestsToRunInformation",
- testsToRunString.str().c_str());
+ if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) {
+ handler->SetOption(
+ "TestsToRunInformation",
+ cmStrCat(this->Start, ',', this->End, ',', this->Stride).c_str());
}
- if (this->Values[ctt_EXCLUDE]) {
- handler->SetOption("ExcludeRegularExpression", this->Values[ctt_EXCLUDE]);
+ if (!this->Exclude.empty()) {
+ handler->SetOption("ExcludeRegularExpression", this->Exclude.c_str());
}
- if (this->Values[ctt_INCLUDE]) {
- handler->SetOption("IncludeRegularExpression", this->Values[ctt_INCLUDE]);
+ if (!this->Include.empty()) {
+ handler->SetOption("IncludeRegularExpression", this->Include.c_str());
}
- if (this->Values[ctt_EXCLUDE_LABEL]) {
+ if (!this->ExcludeLabel.empty()) {
handler->SetOption("ExcludeLabelRegularExpression",
- this->Values[ctt_EXCLUDE_LABEL]);
+ this->ExcludeLabel.c_str());
}
- if (this->Values[ctt_INCLUDE_LABEL]) {
- handler->SetOption("LabelRegularExpression",
- this->Values[ctt_INCLUDE_LABEL]);
+ if (!this->IncludeLabel.empty()) {
+ handler->SetOption("LabelRegularExpression", this->IncludeLabel.c_str());
}
- if (this->Values[ctt_EXCLUDE_FIXTURE]) {
+ if (!this->ExcludeFixture.empty()) {
handler->SetOption("ExcludeFixtureRegularExpression",
- this->Values[ctt_EXCLUDE_FIXTURE]);
+ this->ExcludeFixture.c_str());
}
- if (this->Values[ctt_EXCLUDE_FIXTURE_SETUP]) {
+ if (!this->ExcludeFixtureSetup.empty()) {
handler->SetOption("ExcludeFixtureSetupRegularExpression",
- this->Values[ctt_EXCLUDE_FIXTURE_SETUP]);
+ this->ExcludeFixtureSetup.c_str());
}
- if (this->Values[ctt_EXCLUDE_FIXTURE_CLEANUP]) {
+ if (!this->ExcludeFixtureCleanup.empty()) {
handler->SetOption("ExcludeFixtureCleanupRegularExpression",
- this->Values[ctt_EXCLUDE_FIXTURE_CLEANUP]);
+ this->ExcludeFixtureCleanup.c_str());
}
- if (this->Values[ctt_PARALLEL_LEVEL]) {
- handler->SetOption("ParallelLevel", this->Values[ctt_PARALLEL_LEVEL]);
+ if (!this->ParallelLevel.empty()) {
+ handler->SetOption("ParallelLevel", this->ParallelLevel.c_str());
}
- if (this->Values[ctt_SCHEDULE_RANDOM]) {
- handler->SetOption("ScheduleRandom", this->Values[ctt_SCHEDULE_RANDOM]);
+ if (!this->ScheduleRandom.empty()) {
+ handler->SetOption("ScheduleRandom", this->ScheduleRandom.c_str());
}
- if (this->Values[ctt_STOP_TIME]) {
- this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]);
+ if (!this->StopTime.empty()) {
+ this->CTest->SetStopTime(this->StopTime);
}
// Test load is determined by: TEST_LOAD argument,
@@ -109,12 +95,12 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
// command line argument... in that order.
unsigned long testLoad;
const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
- if (this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD]) {
- if (!cmStrToULong(this->Values[ctt_TEST_LOAD], &testLoad)) {
+ if (!this->TestLoad.empty()) {
+ if (!cmStrToULong(this->TestLoad.c_str(), &testLoad)) {
testLoad = 0;
cmCTestLog(this->CTest, WARNING,
- "Invalid value for 'TEST_LOAD' : "
- << this->Values[ctt_TEST_LOAD] << std::endl);
+ "Invalid value for 'TEST_LOAD' : " << this->TestLoad
+ << std::endl);
}
} else if (ctestTestLoad && *ctestTestLoad) {
if (!cmStrToULong(ctestTestLoad, &testLoad)) {
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index a9ba3ab..edd21b7 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -23,8 +23,6 @@ class cmCTestGenericHandler;
class cmCTestTestCommand : public cmCTestHandlerCommand
{
public:
- cmCTestTestCommand();
-
/**
* This is a virtual constructor for the command.
*/
@@ -42,29 +40,24 @@ public:
std::string GetName() const override { return "ctest_test"; }
protected:
+ void BindArguments() override;
virtual cmCTestGenericHandler* InitializeActualHandler();
cmCTestGenericHandler* InitializeHandler() override;
- enum
- {
- ctt_BUILD = ct_LAST,
- ctt_RETURN_VALUE,
- ctt_START,
- ctt_END,
- ctt_STRIDE,
- ctt_EXCLUDE,
- ctt_INCLUDE,
- ctt_EXCLUDE_LABEL,
- ctt_INCLUDE_LABEL,
- ctt_EXCLUDE_FIXTURE,
- ctt_EXCLUDE_FIXTURE_SETUP,
- ctt_EXCLUDE_FIXTURE_CLEANUP,
- ctt_PARALLEL_LEVEL,
- ctt_SCHEDULE_RANDOM,
- ctt_STOP_TIME,
- ctt_TEST_LOAD,
- ctt_LAST
- };
+ std::string Start;
+ std::string End;
+ std::string Stride;
+ std::string Exclude;
+ std::string Include;
+ std::string ExcludeLabel;
+ std::string IncludeLabel;
+ std::string ExcludeFixture;
+ std::string ExcludeFixtureSetup;
+ std::string ExcludeFixtureCleanup;
+ std::string ParallelLevel;
+ std::string ScheduleRandom;
+ std::string StopTime;
+ std::string TestLoad;
};
#endif
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 65dc921..673eb9a 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -7,14 +7,11 @@
#include "cmMakefile.h"
#include "cmSystemTools.h"
-#include <vector>
-
cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
{
- if (this->Values[ct_SOURCE]) {
+ if (!this->Source.empty()) {
this->CTest->SetCTestConfiguration(
- "SourceDirectory",
- cmSystemTools::CollapseFullPath(this->Values[ct_SOURCE]).c_str(),
+ "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
this->Quiet);
} else {
this->CTest->SetCTestConfiguration(
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h
index 5b0e07e..a4798a5 100644
--- a/Source/CTest/cmCTestUpdateCommand.h
+++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -23,8 +23,6 @@ class cmCTestGenericHandler;
class cmCTestUpdateCommand : public cmCTestHandlerCommand
{
public:
- cmCTestUpdateCommand() {}
-
/**
* This is a virtual constructor for the command.
*/
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index 59fbf37..9180821 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -2,61 +2,45 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestUploadCommand.h"
+#include <set>
#include <sstream>
#include <vector>
+#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestUploadHandler.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
+#include "cm_static_string_view.hxx"
-cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
-{
- cmCTestUploadHandler* handler = this->CTest->GetUploadHandler();
- handler->Initialize();
- handler->SetFiles(this->Files);
- handler->SetQuiet(this->Quiet);
- return handler;
-}
-
-bool cmCTestUploadCommand::CheckArgumentKeyword(std::string const& arg)
+void cmCTestUploadCommand::BindArguments()
{
- if (arg == "FILES") {
- this->ArgumentDoing = ArgumentDoingFiles;
- return true;
- }
- if (arg == "QUIET") {
- this->ArgumentDoing = ArgumentDoingNone;
- this->Quiet = true;
- return true;
- }
- if (arg == "CAPTURE_CMAKE_ERROR") {
- this->ArgumentDoing = ArgumentDoingCaptureCMakeError;
- return true;
- }
- return false;
+ this->Bind("FILES"_s, this->Files);
+ this->Bind("QUIET"_s, this->Quiet);
+ this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError);
}
-bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg)
+void cmCTestUploadCommand::CheckArguments(std::vector<std::string> const&)
{
- if (this->ArgumentDoing == ArgumentDoingCaptureCMakeError) {
- this->Values[ct_CAPTURE_CMAKE_ERROR] = arg.c_str();
- return true;
- }
- if (this->ArgumentDoing == ArgumentDoingFiles) {
- if (cmSystemTools::FileExists(arg)) {
- this->Files.insert(arg);
+ cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
+ if (!cmSystemTools::FileExists(arg)) {
+ std::ostringstream e;
+ e << "File \"" << arg << "\" does not exist. Cannot submit "
+ << "a non-existent file.";
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return true;
}
- std::ostringstream e;
- e << "File \"" << arg << "\" does not exist. Cannot submit "
- << "a non-existent file.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- this->ArgumentDoing = ArgumentDoingError;
return false;
- }
+ });
+}
- // Look for other arguments.
- return this->Superclass::CheckArgumentValue(arg);
+cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
+{
+ cmCTestUploadHandler* handler = this->CTest->GetUploadHandler();
+ handler->Initialize();
+ handler->SetFiles(
+ std::set<std::string>(this->Files.begin(), this->Files.end()));
+ handler->SetQuiet(this->Quiet);
+ return handler;
}
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
index 39314f2..f78f0ec 100644
--- a/Source/CTest/cmCTestUploadCommand.h
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -8,9 +8,9 @@
#include "cmCTestHandlerCommand.h"
#include "cmCommand.h"
-#include <set>
#include <string>
#include <utility>
+#include <vector>
#include <cm/memory>
@@ -41,22 +41,12 @@ public:
*/
std::string GetName() const override { return "ctest_upload"; }
- using Superclass = cmCTestHandlerCommand;
-
protected:
+ void BindArguments() override;
+ void CheckArguments(std::vector<std::string> const&) override;
cmCTestGenericHandler* InitializeHandler() override;
- bool CheckArgumentKeyword(std::string const& arg) override;
- bool CheckArgumentValue(std::string const& arg) override;
-
- enum
- {
- ArgumentDoingFiles = Superclass::ArgumentDoingLast1,
- ArgumentDoingCaptureCMakeError,
- ArgumentDoingLast2
- };
-
- std::set<std::string> Files;
+ std::vector<std::string> Files;
};
#endif
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index 751d117..4c87177 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -61,10 +61,14 @@ void Instance::Bind(MultiStringList& val)
void Instance::Consume(cm::string_view arg, void* result,
std::vector<std::string>* unparsedArguments,
- std::vector<std::string>* keywordsMissingValue)
+ std::vector<std::string>* keywordsMissingValue,
+ std::vector<std::string>* parsedKeywords)
{
auto const it = this->Bindings.Find(arg);
if (it != this->Bindings.end()) {
+ if (parsedKeywords != nullptr) {
+ parsedKeywords->emplace_back(arg);
+ }
it->second(*this, result);
if (this->ExpectValue && keywordsMissingValue != nullptr) {
keywordsMissingValue->emplace_back(arg);
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index b6798bc..9be2488 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -45,7 +45,8 @@ public:
void Consume(cm::string_view arg, void* result,
std::vector<std::string>* unparsedArguments,
- std::vector<std::string>* keywordsMissingValue);
+ std::vector<std::string>* keywordsMissingValue,
+ std::vector<std::string>* parsedKeywords);
private:
ActionMap const& Bindings;
@@ -79,21 +80,25 @@ public:
template <typename Range>
void Parse(Result& result, Range const& args,
std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr) const
+ std::vector<std::string>* keywordsMissingValue = nullptr,
+ std::vector<std::string>* parsedKeywords = nullptr) const
{
ArgumentParser::Instance instance(this->Bindings);
for (cm::string_view arg : args) {
- instance.Consume(arg, &result, unparsedArguments, keywordsMissingValue);
+ instance.Consume(arg, &result, unparsedArguments, keywordsMissingValue,
+ parsedKeywords);
}
}
template <typename Range>
Result Parse(Range const& args,
std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr) const
+ std::vector<std::string>* keywordsMissingValue = nullptr,
+ std::vector<std::string>* parsedKeywords = nullptr) const
{
Result result;
- this->Parse(result, args, unparsedArguments, keywordsMissingValue);
+ this->Parse(result, args, unparsedArguments, keywordsMissingValue,
+ parsedKeywords);
return result;
}
@@ -116,11 +121,13 @@ public:
template <typename Range>
void Parse(Range const& args,
std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr) const
+ std::vector<std::string>* keywordsMissingValue = nullptr,
+ std::vector<std::string>* parsedKeywords = nullptr) const
{
ArgumentParser::Instance instance(this->Bindings);
for (cm::string_view arg : args) {
- instance.Consume(arg, nullptr, unparsedArguments, keywordsMissingValue);
+ instance.Consume(arg, nullptr, unparsedArguments, keywordsMissingValue,
+ parsedKeywords);
}
}