summaryrefslogtreecommitdiffstats
path: root/Source/CTest/cmCTestHandlerCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest/cmCTestHandlerCommand.cxx')
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx147
1 files changed, 47 insertions, 100 deletions
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;
}