From d49ef18f8a9ebe4e512d67d3fb88958c655beb69 Mon Sep 17 00:00:00 2001
From: Ken Martin <ken.martin@kitware.com>
Date: Sat, 1 Mar 2008 15:20:35 -0500
Subject: ENH: add first cut and policies still need to add the doc support

---
 CMakeLists.txt                       |  11 +--
 Source/CMakeLists.txt                |   2 +
 Source/cmAddCustomTargetCommand.cxx  |  44 ++++++-----
 Source/cmBootstrapCommands.cxx       |   2 +
 Source/cmCommand.h                   |   8 --
 Source/cmIncludeDirectoryCommand.cxx |   2 +-
 Source/cmMakefile.cxx                | 148 ++++++++++++++++++++++++++++++-----
 Source/cmMakefile.h                  |  25 +++++-
 Source/cmake.cxx                     |   5 +-
 Source/cmake.h                       |   4 +
 bootstrap                            |   1 +
 11 files changed, 194 insertions(+), 58 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2f9a655..ac6b835 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -134,9 +134,7 @@ ENDMACRO(CMAKE_TEST_FOR_MFC)
 # for testing. Simply to improve readability of the main script.
 #-----------------------------------------------------------------------
 MACRO(CMAKE_SETUP_TESTING)
-  IF (NOT DART_ROOT)
-    SET(MAKEPROGRAM ${CMAKE_MAKE_PROGRAM})
-  ENDIF (NOT DART_ROOT)
+  SET(MAKEPROGRAM ${CMAKE_MAKE_PROGRAM})
   
   IF(BUILD_TESTING)
     SET(CMAKE_TEST_GENERATOR "" CACHE STRING 
@@ -190,11 +188,6 @@ MACRO(CMAKE_SETUP_TESTING)
     ${CMake_BINARY_DIR}/CTestCustom.cmake @ONLY)
   CONFIGURE_FILE(${CMake_SOURCE_DIR}/CTestCustom.ctest.in
     ${CMake_BINARY_DIR}/CTestCustom.ctest @ONLY)
-  IF(BUILD_TESTING AND DART_ROOT)
-    CONFIGURE_FILE(${CMake_SOURCE_DIR}/CMakeLogo.gif 
-      ${CMake_BINARY_DIR}/Testing/HTML/TestingResults/Icons/Logo.gif COPYONLY)
-  ENDIF(BUILD_TESTING AND DART_ROOT)
-  MARK_AS_ADVANCED(DART_ROOT)
   MARK_AS_ADVANCED(CURL_TESTING)
 ENDMACRO(CMAKE_SETUP_TESTING)
 
@@ -365,7 +358,7 @@ SET(CMake_VERSION_FULL "${CMake_VERSION}.${CMake_VERSION_PATCH}")
 
 # Include the standard Dart testing module
 ENABLE_TESTING()
-INCLUDE (${CMAKE_ROOT}/Modules/Dart.cmake)
+INCLUDE (${CMAKE_ROOT}/Modules/CTest.cmake)
 
 # where to write the resulting executables and libraries
 SET(BUILD_SHARED_LIBS OFF)
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 39c0731..3e0eca6 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -184,6 +184,8 @@ SET(SRCS
   cmMakefileUtilityTargetGenerator.cxx
   cmOrderDirectories.cxx
   cmOrderDirectories.h
+  cmPolicies.h
+  cmPolicies.cxx
   cmProperty.cxx
   cmProperty.h
   cmPropertyDefinition.cxx
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 06998c6..aaa2af0 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -28,27 +28,33 @@ bool cmAddCustomTargetCommand
 
   // Check the target name.
   if(args[0].find_first_of("/\\") != args[0].npos)
+  {
+    // slashes are not allowed anymore in taret names CMP_0001
+    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP_0001))
     {
-    int major = 0;
-    int minor = 0;
-    if(const char* versionValue =
-       this->Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY"))
-      {
-      sscanf(versionValue, "%d.%d", &major, &minor);
-      }
-    if(!major || major > 3 || (major == 2 && minor > 2))
-      {
-      cmOStringStream e;
-      e << "called with invalid target name \"" << args[0]
-        << "\".  Target names may not contain a slash.  "
-        << "Use ADD_CUSTOM_COMMAND to generate files.  "
-        << "Set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 "
-        << "or lower to skip this check.";
-      this->SetError(e.str().c_str());
-      return false;
-      }
+      case cmPolicies::WARN:
+        cmSystemTools::Message(
+          this->Makefile->GetPolicies()->GetPolicyWarning
+            (cmPolicies::CMP_0001).c_str(),"Warning");
+      case cmPolicies::OLD:
+//        if (this->Makefile->IsBWCompatibilityLessThan(2,2))
+//        {
+//          break;
+//        }
+      case cmPolicies::NEW:
+        this->SetError("You included a / or \\ in your target name and "
+          "this is not allowed according to policy CMP_0001. Run "
+          "cmake --help-policy CMP_0001 for more information.");
+        return false;
+        break;
+      case cmPolicies::REQUIRED_IF_USED:
+        this->SetError(
+          this->Makefile->GetPolicies()->GetRequiredPolicyError
+            (cmPolicies::CMP_0001).c_str());
+        return false;      
     }
-
+  }
+    
   // Accumulate one command line at a time.
   cmCustomCommandLine currentLine;
 
diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands.cxx
index e7c0d2e..bdc9e3b 100644
--- a/Source/cmBootstrapCommands.cxx
+++ b/Source/cmBootstrapCommands.cxx
@@ -30,6 +30,7 @@
 #include "cmBreakCommand.cxx"
 #include "cmBuildCommand.cxx"
 #include "cmCMakeMinimumRequired.cxx"
+#include "cmCMakePolicyCommand.cxx"
 #include "cmCommandArgumentsHelper.cxx"
 #include "cmConfigureFileCommand.cxx"
 #include "cmCoreTryCompile.cxx"
@@ -105,6 +106,7 @@ void GetBootstrapCommands(std::list<cmCommand*>& commands)
   commands.push_back(new cmBreakCommand);
   commands.push_back(new cmBuildCommand);
   commands.push_back(new cmCMakeMinimumRequired);
+  commands.push_back(new cmCMakePolicyCommand);
   commands.push_back(new cmConfigureFileCommand);
   commands.push_back(new cmCreateTestSourceList);
   commands.push_back(new cmDefinePropertyCommand);
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index e7c0fc6..96699ac 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -97,14 +97,6 @@ public:
     }
 
   /**
-   * This determines if the method is deprecated or not. 
-   */
-  virtual bool IsDeprecated(int /*major*/, int /*minor*/)
-    {
-    return false;
-    }
-
-  /**
    * This determines if usage of the method is discouraged or not.
    * This is currently only used for generating the documentation.
    */
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index 2d3271e..e51116d 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -61,7 +61,7 @@ bool cmIncludeDirectoryCommand
       else
         {
         this->SetError(errorMessage);
-        return 0;
+        return false;
         }
       }
 
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index c87a4dd..18348c1 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -291,24 +291,14 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
     this->GetCMakeInstance()->GetCommand(name.c_str());
   if(rm)
     {
-    const char* versionValue
-      = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
-    int major = 0;
-    int minor = 0;
-    if ( versionValue )
-      {
-      sscanf(versionValue, "%d.%d", &major, &minor);
-      }
-    if ( rm->IsDeprecated(major, minor) )
-      {
-      cmOStringStream error;
-      error << "Error in cmake code at\n"
-            << lff.FilePath << ":" << lff.Line << ":\n"
-            << rm->GetError() << std::endl
-            << "   Called from: " << this->GetListFileStack().c_str();
-      cmSystemTools::Error(error.str().c_str());
-      return false;
-      }
+    // const char* versionValue
+      // = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
+    // int major = 0;
+    // int minor = 0;
+    // if ( versionValue )
+      // {
+      // sscanf(versionValue, "%d.%d", &major, &minor);
+      // }
     cmCommand* usedCommand = rm->Clone();
     usedCommand->SetMakefile(this);
     bool keepCommand = false;
@@ -3148,8 +3138,24 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
       msg = e.str();
       return false;
       }
-    else if(!this->NeedBackwardsCompatibility(2, 4))
+    else 
       {
+      // target names must be globally unique
+      switch (this->GetPolicyStatus(cmPolicies::CMP_0002))
+        {
+        case cmPolicies::WARN:
+          msg = this->GetPolicies()->
+            GetPolicyWarning(cmPolicies::CMP_0002);
+        case cmPolicies::OLD:
+          return true;
+        case cmPolicies::REQUIRED_IF_USED:
+          msg = this->GetPolicies()->
+            GetRequiredPolicyError(cmPolicies::CMP_0002);
+          return false;
+        case cmPolicies::NEW:
+          break;
+        }
+      
       // The conflict is with a non-imported target.
       // Allow this if the user has requested support.
       cmake* cm =
@@ -3225,3 +3231,107 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
     }
   return true;
 }
+
+cmPolicies::PolicyStatus cmMakefile
+::GetPolicyStatus(cmPolicies::PolicyID id)
+{
+  cmPolicies::PolicyStatus status;
+  PolicyMap::iterator mappos;
+  unsigned int vecpos;
+  bool done = false;
+  // check our policy stack first
+  for (vecpos = this->PolicyStack.size(); vecpos >= 0 && !done; vecpos--)
+  {
+    mappos = this->PolicyStack[vecpos].find(id);
+    if (mappos != this->PolicyStack[vecpos].end())
+    {
+      status = mappos->second;
+      done = true;
+    }
+  }
+  
+  // if not found then 
+  if (!done)
+  {
+    // pass the buck to our parent if we have one
+    if (this->LocalGenerator->GetParent())
+    {
+      cmMakefile *parent = 
+        this->LocalGenerator->GetParent()->GetMakefile();
+      return parent->GetPolicyStatus(id);
+    }
+    // otherwise use the default
+    else
+    {
+      status = this->GetPolicies()->GetPolicyStatus(id);
+    }
+  }
+  
+  // warn if we see a REQUIRED_IF_USED above a OLD or WARN
+  if (!this->GetPolicies()->IsValidUsedPolicyStatus(id,status))
+  {
+    return cmPolicies::REQUIRED_IF_USED;
+  }
+  
+  return status;
+}
+
+bool cmMakefile::SetPolicy(const char *id, 
+                           cmPolicies::PolicyStatus status)
+{
+  cmPolicies::PolicyID pid;
+  if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid))
+  {
+    cmSystemTools::Error("Invalid policy string used. Invalid string was "
+      , id);
+    return false;
+  }
+  return this->SetPolicy(pid,status);
+}
+
+bool cmMakefile::SetPolicy(cmPolicies::PolicyID id, 
+                           cmPolicies::PolicyStatus status)
+{
+  // setting a REQUIRED_ALWAYS policy to WARN or OLD is an insta error
+  if (this->GetPolicies()->
+      IsValidPolicyStatus(id,status))
+  {
+    this->PolicyStack.back()[id] = status;
+    return true;
+  }
+  return false;
+}
+
+bool cmMakefile::PushPolicy()
+{
+  // Allocate a new stack entry.
+  this->PolicyStack.push_back(PolicyMap());
+  return true;
+}
+
+bool cmMakefile::PopPolicy()
+{
+  if (PolicyStack.size() == 0)
+  {
+    cmSystemTools::Error("Attempt to pop the policy stack past "
+      "it's beginning.");
+    return false;
+  }
+  this->PolicyStack.pop_back();
+  return true;
+}
+
+bool cmMakefile::SetPolicyVersion(const char *version)
+{
+  return this->GetCMakeInstance()->GetPolicies()->
+    ApplyPolicyVersion(this,version);
+}
+
+cmPolicies *cmMakefile::GetPolicies()
+{ 
+  if (!this->GetCMakeInstance())
+  {
+    return 0;
+  }
+  return this->GetCMakeInstance()->GetPolicies();
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 4c99df1..819de0d 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -21,6 +21,7 @@
 #include "cmData.h"
 #include "cmExecutionStatus.h"
 #include "cmListFileCache.h"
+#include "cmPolicies.h"
 #include "cmPropertyMap.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
@@ -322,7 +323,24 @@ public:
                       const char* regex=0);
 
 #endif
-  
+
+  //@{
+  /**
+     * Set, Push, Pop policy values for CMake.   
+     */
+  bool SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
+  bool SetPolicy(const char *id, cmPolicies::PolicyStatus status);
+  cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
+  bool PushPolicy();
+  bool PopPolicy();
+  bool SetPolicyVersion(const char *version);
+  //@}
+
+  /**
+    * Get the Policies Instance
+    */
+ cmPolicies *GetPolicies();
+   
   /**
    * Add an auxiliary directory to the build.
    */
@@ -861,6 +879,11 @@ private:
   cmTarget* FindBasicTarget(const char* name);
   std::vector<cmTarget*> ImportedTargetsOwned;
   std::map<cmStdString, cmTarget*> ImportedTargets;
+  
+  // stack of policy settings
+  typedef std::map<cmPolicies::PolicyID,
+                   cmPolicies::PolicyStatus> PolicyMap;
+  std::vector<PolicyMap> PolicyStack;
 };
 
 
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index af13d3a..80b0dfe 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -143,6 +143,8 @@ cmake::cmake()
   this->ClearBuildSystem = false;
   this->FileComparison = new cmFileTimeComparison;
 
+  this->Policies = new cmPolicies();
+
   this->Properties.SetCMakeInstance(this);
 
   // initialize properties
@@ -181,7 +183,7 @@ cmake::cmake()
   this->ProgressCallback = 0;
   this->ProgressCallbackClientData = 0;
   this->ScriptMode = false;
-
+  
 #ifdef CMAKE_BUILD_WITH_CMAKE
   this->VariableWatch = new cmVariableWatch;
   this->VariableWatch->AddWatch("CMAKE_WORDS_BIGENDIAN",
@@ -203,6 +205,7 @@ cmake::cmake()
 cmake::~cmake()
 {
   delete this->CacheManager;
+  delete this->Policies;
   if (this->GlobalGenerator)
     {
     delete this->GlobalGenerator;
diff --git a/Source/cmake.h b/Source/cmake.h
index e1eda4a..9ed4ddc 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -53,6 +53,7 @@ class cmVariableWatch;
 class cmFileTimeComparison;
 class cmExternalMakefileProjectGenerator;
 class cmDocumentationSection;
+class cmPolicies;
 
 class cmake
 {
@@ -238,6 +239,8 @@ class cmake
   ///! this is called by generators to update the progress
   void UpdateProgress(const char *msg, float prog);
 
+  ///!  get the cmake policies instance
+  cmPolicies *GetPolicies() {return this->Policies;} ;
 
   ///! Get the variable watch object
   cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
@@ -358,6 +361,7 @@ protected:
   void AddExtraGenerator(const char* name, 
                          CreateExtraGeneratorFunctionType newFunction);
 
+  cmPolicies *Policies;                       
   cmGlobalGenerator *GlobalGenerator;
   cmCacheManager *CacheManager;
   std::string cmHomeDirectory; 
diff --git a/bootstrap b/bootstrap
index 40199ad..dfc151e 100755
--- a/bootstrap
+++ b/bootstrap
@@ -137,6 +137,7 @@ CMAKE_CXX_SOURCES="\
   cmCommandArgumentParserHelper \
   cmDepends \
   cmDependsC \
+  cmPolicies \
   cmProperty \
   cmPropertyMap \
   cmPropertyDefinition \
-- 
cgit v0.12