From ae2c4143d288624b6703085602ecee2289b3ee27 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 12 Jan 2009 09:10:47 -0500 Subject: ENH: Refactor CTest command argument handling The previous approach to handling of arguments to ctest_* commands worked only for keyword/value arguments with a single value. This refactors the approach to allow some commands to define alternative argument forms. --- Source/CTest/cmCTestHandlerCommand.cxx | 99 +++++++++++++++++----------------- Source/CTest/cmCTestHandlerCommand.h | 15 +++++- 2 files changed, 64 insertions(+), 50 deletions(-) diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index dfd55e4..e4ae832 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -38,10 +38,29 @@ cmCTestHandlerCommand::cmCTestHandlerCommand() bool cmCTestHandlerCommand ::InitialPass(std::vector const& args, cmExecutionStatus &) { - if ( !this->ProcessArguments(args, (unsigned int)this->Last, - &*this->Arguments.begin(),this->Values) ) + // Allocate space for argument values. + this->Values.clear(); + this->Values.resize(this->Last, 0); + + // Process input arguments. + this->ArgumentDoing = ArgumentDoingNone; + for(unsigned int i=0; i < args.size(); ++i) { - return false; + // Check this argument. + if(!this->CheckArgumentKeyword(args[i]) && + !this->CheckArgumentValue(args[i])) + { + cmOStringStream e; + e << "called with unknown argument \"" << args[i] << "\"."; + this->SetError(e.str().c_str()); + return false; + } + + // Quit if an argument is invalid. + if(this->ArgumentDoing == ArgumentDoingError) + { + return false; + } } cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;); @@ -121,57 +140,41 @@ bool cmCTestHandlerCommand return true; } -bool cmCTestHandlerCommand::ProcessArguments( - std::vector const& args, int last, const char** strings, - std::vector& values) +//---------------------------------------------------------------------------- +bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg) { - int state = 0; - int cc; - values.resize(last); - for ( cc = 0; cc < last; ++ cc ) + // Check for a keyword in our argument/value table. + for(unsigned int k=0; k < this->Arguments.size(); ++k) { - values[cc] = 0; + if(this->Arguments[k] && arg == this->Arguments[k]) + { + this->ArgumentDoing = ArgumentDoingKeyword; + this->ArgumentIndex = k; + return true; + } } + return false; +} - for(size_t i=0; i < args.size(); ++i) +//---------------------------------------------------------------------------- +bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg) +{ + if(this->ArgumentDoing == ArgumentDoingKeyword) { - if ( state > 0 && state < last ) + this->ArgumentDoing = ArgumentDoingNone; + unsigned int k = this->ArgumentIndex; + if(this->Values[k]) { - values[state] = args[i].c_str(); - cmCTestLog(this->CTest, DEBUG, "Set " << strings[state] << " to " - << args[i].c_str() << std::endl); - state = 0; - } - else - { - bool found = false; - for ( cc = 0; cc < last; ++ cc ) - { - if ( strings[cc] && args[i] == strings[cc] ) - { - state = cc; - if ( values[state] ) - { - cmOStringStream ostr; - ostr << "called with incorrect number of arguments. " - << strings[state] << " specified twice."; - this->SetError(ostr.str().c_str()); - return false; - } - found = true; - break; - } - } - if ( !found ) - { - cmOStringStream str; - str - << "called with incorrect number of arguments. Extra argument is: " - << args[i].c_str() << "."; - this->SetError(str.str().c_str()); - return false; - } + cmOStringStream e; + e << "Called with more than one value for " << this->Arguments[k]; + this->Makefile->IssueMessage(cmake::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 true; + return false; } diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h index 727437b..8c2e651 100644 --- a/Source/CTest/cmCTestHandlerCommand.h +++ b/Source/CTest/cmCTestHandlerCommand.h @@ -52,8 +52,19 @@ public: protected: virtual cmCTestGenericHandler* InitializeHandler() = 0; - bool ProcessArguments(std::vector const& args, - int last, const char** strings, std::vector& values); + + // 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; std::string ReturnVariable; std::vector Arguments; -- cgit v0.12