Ver Fonte

ENH: added elseif

Ken Martin há 19 anos atrás
pai
commit
5e46232ad8

+ 2 - 0
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<cmCommand*>&
   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);

+ 24 - 0
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<std::string> const&)
+{
+  this->SetError("An ELSEIF command was found outside of a proper "
+                 "IF ENDIF structure.");
+  return false;
+}

+ 76 - 0
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<std::string> 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

+ 56 - 9
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<std::string> 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);
   

+ 2 - 1
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<cmListFileArgument> Args;
   bool IsBlocking;
+  bool HasRun;
 };
 
 /** \class cmIfCommand