diff options
Diffstat (limited to 'Source/CTest/cmCTestHandlerCommand.cxx')
-rw-r--r-- | Source/CTest/cmCTestHandlerCommand.cxx | 147 |
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; } |