diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 26b098afc..6bfabd60f 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -20,6 +20,7 @@ #include "cmAuxSourceDirectoryCommand.cxx" #include "cmBuildNameCommand.cxx" #include "cmCreateTestSourceList.cxx" +#include "cmElseIfCommand.cxx" #include "cmEnableLanguageCommand.cxx" #include "cmEndWhileCommand.cxx" #include "cmExecuteProcessCommand.cxx" @@ -73,6 +74,7 @@ void GetPredefinedCommands(std::list& commands.push_back(new cmAuxSourceDirectoryCommand); commands.push_back(new cmBuildNameCommand); commands.push_back(new cmCreateTestSourceList); + commands.push_back(new cmElseIfCommand); commands.push_back(new cmEnableLanguageCommand); commands.push_back(new cmEndWhileCommand); commands.push_back(new cmExecuteProcessCommand); diff --git a/Source/cmElseIfCommand.cxx b/Source/cmElseIfCommand.cxx new file mode 100644 index 000000000..41b55b2c8 --- /dev/null +++ b/Source/cmElseIfCommand.cxx @@ -0,0 +1,24 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmElseIfCommand.h" + +bool cmElseIfCommand::InitialPass(std::vector const&) +{ + this->SetError("An ELSEIF command was found outside of a proper " + "IF ENDIF structure."); + return false; +} diff --git a/Source/cmElseIfCommand.h b/Source/cmElseIfCommand.h new file mode 100644 index 000000000..ca6b1f4da --- /dev/null +++ b/Source/cmElseIfCommand.h @@ -0,0 +1,76 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmElseIfCommand_h +#define cmElseIfCommand_h + +#include "cmIfCommand.h" + +/** \class cmElseIfCommand + * \brief ends an if block + * + * cmElseIfCommand ends an if block + */ +class cmElseIfCommand : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmElseIfCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector const& args); + + /** + * This determines if the command is invoked when in script mode. + */ + virtual bool IsScriptable() { return true; } + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() { return "ELSEIF";} + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() + { + return "Starts the ELSEIF portion of an IF block."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() + { + return + " ELSEIF(expression)\n" + "See the IF command."; + } + + cmTypeMacro(cmElseIfCommand, cmCommand); +}; + + +#endif diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 3297022ff..722cc78cc 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -29,22 +29,65 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) } // watch for our ELSE or ENDIF - if (!cmSystemTools::Strucmp(lff.Name.c_str(),"else") || + if (!cmSystemTools::Strucmp(lff.Name.c_str(),"else") || + !cmSystemTools::Strucmp(lff.Name.c_str(),"elseif") || !cmSystemTools::Strucmp(lff.Name.c_str(),"endif")) { // if it was an else statement then we should change state // and block this Else Command if (!cmSystemTools::Strucmp(lff.Name.c_str(),"else")) + { + this->IsBlocking = this->HasRun; + return true; + } + // if it was an elseif statement then we should check state + // and possibly block this Else Command + if (!cmSystemTools::Strucmp(lff.Name.c_str(),"elseif")) + { + if (!this->HasRun) { - this->IsBlocking = !this->IsBlocking; - return true; + char* errorString = 0; + + std::vector expandedArguments; + mf.ExpandArguments(lff.Arguments, expandedArguments); + bool isTrue = + cmIfCommand::IsTrue(expandedArguments,&errorString,&mf); + + if (errorString) + { + std::string err = "had incorrect arguments: "; + unsigned int i; + for(i =0; i < lff.Arguments.size(); ++i) + { + err += (lff.Arguments[i].Quoted?"\"":""); + err += lff.Arguments[i].Value; + err += (lff.Arguments[i].Quoted?"\"":""); + err += " "; + } + err += "("; + err += errorString; + err += ")."; + cmSystemTools::Error(err.c_str()); + delete [] errorString; + return false; + } + + if (isTrue) + { + this->IsBlocking = false; + this->HasRun = true; + return true; + } } - // otherwise it must be an ENDIF statement, in that case remove the - // function blocker - mf.RemoveFunctionBlocker(lff); - return true; - } - + this->IsBlocking = true; + return true; + } + // otherwise it must be an ENDIF statement, in that case remove the + // function blocker + mf.RemoveFunctionBlocker(lff); + return true; + } + return this->IsBlocking; } @@ -113,6 +156,10 @@ bool cmIfCommand cmIfFunctionBlocker *f = new cmIfFunctionBlocker(); // if is isn't true block the commands f->IsBlocking = !isTrue; + if (isTrue) + { + f->HasRun = true; + } f->Args = args; this->Makefile->AddFunctionBlocker(f); diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index 90cf1a0a1..1d0724852 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -28,7 +28,7 @@ class cmIfFunctionBlocker : public cmFunctionBlocker { public: - cmIfFunctionBlocker() {} + cmIfFunctionBlocker() {this->HasRun = false;} virtual ~cmIfFunctionBlocker() {} virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf); @@ -38,6 +38,7 @@ public: std::vector Args; bool IsBlocking; + bool HasRun; }; /** \class cmIfCommand