Browse Source

if: Implement new IN_LIST operator

Nils Gladitz 10 years ago
parent
commit
aed6239e40

+ 3 - 0
Help/command/if.rst

@@ -134,6 +134,9 @@ Possible expressions are:
  Component-wise integer version number comparison (version format is
  Component-wise integer version number comparison (version format is
  ``major[.minor[.patch[.tweak]]]``).
  ``major[.minor[.patch[.tweak]]]``).
 
 
+``if(<variable|string> IN_LIST <variable>)``
+ True if the given element is contained in the named list variable.
+
 ``if(DEFINED <variable>)``
 ``if(DEFINED <variable>)``
  True if the given variable is defined.  It does not matter if the
  True if the given variable is defined.  It does not matter if the
  variable is true or false just if it has been set.  (Note macro
  variable is true or false just if it has been set.  (Note macro

+ 11 - 1
Help/policy/CMP0057.rst

@@ -1,4 +1,14 @@
 CMP0057
 CMP0057
 -------
 -------
 
 
-This policy is reserved for future use.
+Support new :command:`if` IN_LIST operator.
+
+CMake 3.3 adds support for the new IN_LIST operator.
+
+The ``OLD`` behavior for this policy is to ignore the IN_LIST operator.
+The ``NEW`` behavior is to interpret the IN_LIST operator.
+
+This policy was introduced in CMake version 3.3.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior.  Use the :command:`cmake_policy` command to set
+it to ``OLD`` or ``NEW`` explicitly.

+ 5 - 0
Help/release/dev/if-IN_LIST.rst

@@ -0,0 +1,5 @@
+if-IN_LIST
+----------
+
+* Add a new IN_LIST operator to if() that evaluates true
+  if a given element is contained in a named list.

+ 37 - 1
Source/cmConditionEvaluator.cxx

@@ -15,7 +15,8 @@
 cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile):
 cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile):
   Makefile(makefile),
   Makefile(makefile),
   Policy12Status(makefile.GetPolicyStatus(cmPolicies::CMP0012)),
   Policy12Status(makefile.GetPolicyStatus(cmPolicies::CMP0012)),
-  Policy54Status(makefile.GetPolicyStatus(cmPolicies::CMP0054))
+  Policy54Status(makefile.GetPolicyStatus(cmPolicies::CMP0054)),
+  Policy57Status(makefile.GetPolicyStatus(cmPolicies::CMP0057))
 {
 {
 
 
 }
 }
@@ -676,6 +677,41 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs,
           reducible, arg, newArgs, argP1, argP2);
           reducible, arg, newArgs, argP1, argP2);
         }
         }
 
 
+      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+          this->IsKeyword("IN_LIST", *argP1))
+        {
+        if(this->Policy57Status != cmPolicies::OLD &&
+          this->Policy57Status != cmPolicies::WARN)
+          {
+          bool result = false;
+
+          def = this->GetVariableOrString(*arg);
+          def2 = this->Makefile.GetDefinition(argP2->GetValue());
+
+          if(def2)
+            {
+            std::vector<std::string> list;
+            cmSystemTools::ExpandListArgument(def2, list, true);
+
+            result = std::find(list.begin(), list.end(), def) != list.end();
+            }
+
+          this->HandleBinaryOp(result,
+            reducible, arg, newArgs, argP1, argP2);
+          }
+          else if(this->Policy57Status == cmPolicies::WARN)
+            {
+            std::ostringstream e;
+            e << (this->Makefile.GetPolicies()->GetPolicyWarning(
+              cmPolicies::CMP0057)) << "\n";
+            e << "IN_LIST will be interpreted as an operator "
+              "when the policy is set to NEW.  "
+              "Since the policy is not set the OLD behavior will be used.";
+
+            this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+            }
+        }
+
       ++arg;
       ++arg;
       }
       }
     }
     }

+ 1 - 0
Source/cmConditionEvaluator.h

@@ -93,6 +93,7 @@ private:
   cmMakefile& Makefile;
   cmMakefile& Makefile;
   cmPolicies::PolicyStatus Policy12Status;
   cmPolicies::PolicyStatus Policy12Status;
   cmPolicies::PolicyStatus Policy54Status;
   cmPolicies::PolicyStatus Policy54Status;
+  cmPolicies::PolicyStatus Policy57Status;
 };
 };
 
 
 #endif
 #endif

+ 5 - 0
Source/cmPolicies.cxx

@@ -390,6 +390,11 @@ cmPolicies::cmPolicies()
     CMP0060, "CMP0060",
     CMP0060, "CMP0060",
     "Link libraries by full path even in implicit directories.",
     "Link libraries by full path even in implicit directories.",
     3,3,0, cmPolicies::WARN);
     3,3,0, cmPolicies::WARN);
+
+  this->DefinePolicy(
+    CMP0057, "CMP0057",
+    "Support new IN_LIST if() operator.",
+    3,3,0, cmPolicies::WARN);
 }
 }
 
 
 cmPolicies::~cmPolicies()
 cmPolicies::~cmPolicies()

+ 1 - 0
Source/cmPolicies.h

@@ -117,6 +117,7 @@ public:
     CMP0059, ///< Do not treat ``DEFINITIONS`` as a built-in directory
     CMP0059, ///< Do not treat ``DEFINITIONS`` as a built-in directory
     /// property.
     /// property.
     CMP0060, ///< Link libraries by full path even in implicit directories.
     CMP0060, ///< Link libraries by full path even in implicit directories.
+    CMP0057, ///< Support new IN_LIST if() operator.
 
 
     /** \brief Always the last entry.
     /** \brief Always the last entry.
      *
      *

+ 31 - 0
Tests/RunCMake/CMP0057/CMP0057-NEW.cmake

@@ -0,0 +1,31 @@
+cmake_policy(SET CMP0057 NEW)
+
+set(MY_NON_EXISTENT_LIST)
+
+set(MY_EMPTY_LIST "")
+
+set(MY_LIST foo bar)
+
+if(NOT "foo" IN_LIST MY_LIST)
+  message(FATAL_ERROR "expected item 'foo' not found in list MY_LIST")
+endif()
+
+if("baz" IN_LIST MY_LIST)
+  message(FATAL_ERROR "unexpected item 'baz' found in list MY_LIST")
+endif()
+
+if("foo" IN_LIST MY_NON_EXISTENT_LIST)
+  message(FATAL_ERROR
+    "unexpected item 'baz' found in non existent list MY_NON_EXISTENT_LIST")
+endif()
+
+if("foo" IN_LIST MY_EMPTY_LIST)
+  message(FATAL_ERROR
+    "unexpected item 'baz' found in empty list MY_EMPTY_LIST")
+endif()
+
+set(VAR "foo")
+
+if(NOT VAR IN_LIST MY_LIST)
+  message(FATAL_ERROR "expected item VAR not found in list MY_LIST")
+endif()

+ 1 - 0
Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt

@@ -0,0 +1 @@
+1

+ 8 - 0
Tests/RunCMake/CMP0057/CMP0057-OLD-stderr.txt

@@ -0,0 +1,8 @@
+CMake Error at CMP0057-OLD.cmake:5 \(if\):
+  if given arguments:
+
+    "foo" "IN_LIST" "MY_LIST"
+
+  Unknown arguments specified
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 7 - 0
Tests/RunCMake/CMP0057/CMP0057-OLD.cmake

@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0057 OLD)
+
+set(MY_LIST foo bar)
+
+if("foo" IN_LIST MY_LIST)
+  message("foo is in MY_LIST")
+endif()

+ 1 - 0
Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt

@@ -0,0 +1 @@
+1

+ 19 - 0
Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt

@@ -0,0 +1,19 @@
+CMake Warning \(dev\) at CMP0057-WARN.cmake:3 \(if\):
+  Policy CMP0057 is not set: Support new IN_LIST if\(\) operator.  Run "cmake
+  --help-policy CMP0057" for policy details.  Use the cmake_policy command to
+  set the policy and suppress this warning.
+
+  IN_LIST will be interpreted as an operator when the policy is set to NEW.
+  Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Error at CMP0057-WARN.cmake:3 \(if\):
+  if given arguments:
+
+    "foo" "IN_LIST" "MY_LIST"
+
+  Unknown arguments specified
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 5 - 0
Tests/RunCMake/CMP0057/CMP0057-WARN.cmake

@@ -0,0 +1,5 @@
+set(MY_LIST foo bar)
+
+if("foo" IN_LIST MY_LIST)
+  message("foo is in MY_LIST")
+endif()

+ 3 - 0
Tests/RunCMake/CMP0057/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 5 - 0
Tests/RunCMake/CMP0057/RunCMakeTest.cmake

@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0057-OLD)
+run_cmake(CMP0057-WARN)
+run_cmake(CMP0057-NEW)

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -63,6 +63,7 @@ add_RunCMake_test(CMP0051)
 add_RunCMake_test(CMP0053)
 add_RunCMake_test(CMP0053)
 add_RunCMake_test(CMP0054)
 add_RunCMake_test(CMP0054)
 add_RunCMake_test(CMP0055)
 add_RunCMake_test(CMP0055)
+add_RunCMake_test(CMP0057)
 add_RunCMake_test(CMP0059)
 add_RunCMake_test(CMP0059)
 add_RunCMake_test(CMP0060)
 add_RunCMake_test(CMP0060)
 if(CMAKE_GENERATOR STREQUAL "Ninja")
 if(CMAKE_GENERATOR STREQUAL "Ninja")