/*============================================================================ CMake - Cross Platform Makefile Generator Copyright 2000-2009 Kitware, Inc., Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ #include "cmCTestHandlerCommand.h" #include "cmCTest.h" #include "cmCTestGenericHandler.h" 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(0); } this->Arguments[ct_RETURN_VALUE] = "RETURN_VALUE"; this->Arguments[ct_SOURCE] = "SOURCE"; this->Arguments[ct_BUILD] = "BUILD"; this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX"; this->Last = ct_LAST; this->AppendXML = false; } bool cmCTestHandlerCommand ::InitialPass(std::vector const& args, cmExecutionStatus &) { // 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) { // 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; } } // Set the config type of this ctest to the current value of the // CTEST_CONFIGURATION_TYPE script variable if it is defined. // The current script value trumps the -C argument on the command // line. const char* ctestConfigType = this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE"); if (ctestConfigType) { this->CTest->SetConfigType(ctestConfigType); } cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;); cmCTestGenericHandler* handler = this->InitializeHandler(); if ( !handler ) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot instantiate test handler " << this->GetName() << std::endl); return false; } handler->SetAppendXML(this->AppendXML); handler->PopulateCustomVectors(this->Makefile); if ( this->Values[ct_BUILD] ) { this->CTest->SetCTestConfiguration("BuildDirectory", cmSystemTools::CollapseFullPath( this->Values[ct_BUILD]).c_str()); } else { const char* bdir = this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY"); if(bdir) { this-> CTest->SetCTestConfiguration("BuildDirectory", cmSystemTools::CollapseFullPath(bdir).c_str()); } else { cmCTestLog(this->CTest, ERROR_MESSAGE, "CTEST_BINARY_DIRECTORY not set" << std::endl;); } } if ( this->Values[ct_SOURCE] ) { cmCTestLog(this->CTest, DEBUG, "Set source directory to: " << this->Values[ct_SOURCE] << std::endl); this->CTest->SetCTestConfiguration("SourceDirectory", cmSystemTools::CollapseFullPath( this->Values[ct_SOURCE]).c_str()); } else { this->CTest->SetCTestConfiguration("SourceDirectory", cmSystemTools::CollapseFullPath( this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")).c_str()); } if ( this->Values[ct_SUBMIT_INDEX] ) { if ( this->CTest->GetDartVersion() <= 1 ) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Dart before version 2.0 does not support collecting submissions." << std::endl << "Please upgrade the server to Dart 2 or higher, or do not use " "SUBMIT_INDEX." << std::endl); } else { handler->SetSubmitIndex(atoi(this->Values[ct_SUBMIT_INDEX])); } } std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory(); cmSystemTools::ChangeDirectory( this->CTest->GetCTestConfiguration("BuildDirectory").c_str()); int res = handler->ProcessHandler(); if ( this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) { cmOStringStream str; str << res; this->Makefile->AddDefinition( this->Values[ct_RETURN_VALUE], str.str().c_str()); } cmSystemTools::ChangeDirectory(current_dir.c_str()); return true; } //---------------------------------------------------------------------------- bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg) { // Look for non-value arguments common to all commands. if(arg == "APPEND") { this->ArgumentDoing = ArgumentDoingNone; this->AppendXML = 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; } //---------------------------------------------------------------------------- bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg) { if(this->ArgumentDoing == ArgumentDoingKeyword) { this->ArgumentDoing = ArgumentDoingNone; unsigned int k = this->ArgumentIndex; if(this->Values[k]) { 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 false; }