diff options
-rw-r--r-- | Help/command/if.rst | 3 | ||||
-rw-r--r-- | Help/policy/CMP0057.rst | 12 | ||||
-rw-r--r-- | Help/release/dev/if-IN_LIST.rst | 5 | ||||
-rw-r--r-- | Source/cmConditionEvaluator.cxx | 38 | ||||
-rw-r--r-- | Source/cmConditionEvaluator.h | 1 | ||||
-rw-r--r-- | Source/cmPolicies.cxx | 5 | ||||
-rw-r--r-- | Source/cmPolicies.h | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/CMP0057-NEW.cmake | 31 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/CMP0057-OLD-stderr.txt | 8 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/CMP0057-OLD.cmake | 7 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt | 19 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/CMP0057-WARN.cmake | 5 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0057/RunCMakeTest.cmake | 5 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 1 |
17 files changed, 144 insertions, 2 deletions
diff --git a/Help/command/if.rst b/Help/command/if.rst index d50b14c..396becf 100644 --- a/Help/command/if.rst +++ b/Help/command/if.rst @@ -134,6 +134,9 @@ Possible expressions are: Component-wise integer version number comparison (version format is ``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>)`` 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 diff --git a/Help/policy/CMP0057.rst b/Help/policy/CMP0057.rst index 377f22d..1298a16 100644 --- a/Help/policy/CMP0057.rst +++ b/Help/policy/CMP0057.rst @@ -1,4 +1,14 @@ 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. diff --git a/Help/release/dev/if-IN_LIST.rst b/Help/release/dev/if-IN_LIST.rst new file mode 100644 index 0000000..9dd0725 --- /dev/null +++ b/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. diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 0a71c60..1f9b9d4 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -15,7 +15,8 @@ cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile): Makefile(makefile), 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); } + 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; } } diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h index fcef234..c923d76 100644 --- a/Source/cmConditionEvaluator.h +++ b/Source/cmConditionEvaluator.h @@ -93,6 +93,7 @@ private: cmMakefile& Makefile; cmPolicies::PolicyStatus Policy12Status; cmPolicies::PolicyStatus Policy54Status; + cmPolicies::PolicyStatus Policy57Status; }; #endif diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index ab60f93..76990f0 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -390,6 +390,11 @@ cmPolicies::cmPolicies() CMP0060, "CMP0060", "Link libraries by full path even in implicit directories.", 3,3,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0057, "CMP0057", + "Support new IN_LIST if() operator.", + 3,3,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 90acf8e..ca82264 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -117,6 +117,7 @@ public: CMP0059, ///< Do not treat ``DEFINITIONS`` as a built-in directory /// property. CMP0060, ///< Link libraries by full path even in implicit directories. + CMP0057, ///< Support new IN_LIST if() operator. /** \brief Always the last entry. * diff --git a/Tests/RunCMake/CMP0057/CMP0057-NEW.cmake b/Tests/RunCMake/CMP0057/CMP0057-NEW.cmake new file mode 100644 index 0000000..ebd7ba5 --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt b/Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0057/CMP0057-OLD-stderr.txt b/Tests/RunCMake/CMP0057/CMP0057-OLD-stderr.txt new file mode 100644 index 0000000..f3fad8d --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/CMP0057/CMP0057-OLD.cmake b/Tests/RunCMake/CMP0057/CMP0057-OLD.cmake new file mode 100644 index 0000000..cf9ec89 --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt b/Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt b/Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt new file mode 100644 index 0000000..b1c9b63 --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/CMP0057/CMP0057-WARN.cmake b/Tests/RunCMake/CMP0057/CMP0057-WARN.cmake new file mode 100644 index 0000000..45f53a5 --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/CMP0057/CMakeLists.txt b/Tests/RunCMake/CMP0057/CMakeLists.txt new file mode 100644 index 0000000..18dfd26 --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.2) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0057/RunCMakeTest.cmake b/Tests/RunCMake/CMP0057/RunCMakeTest.cmake new file mode 100644 index 0000000..719e054 --- /dev/null +++ b/Tests/RunCMake/CMP0057/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0057-OLD) +run_cmake(CMP0057-WARN) +run_cmake(CMP0057-NEW) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index dc18764..d5f1d22 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -63,6 +63,7 @@ add_RunCMake_test(CMP0051) add_RunCMake_test(CMP0053) add_RunCMake_test(CMP0054) add_RunCMake_test(CMP0055) +add_RunCMake_test(CMP0057) add_RunCMake_test(CMP0059) add_RunCMake_test(CMP0060) if(CMAKE_GENERATOR STREQUAL "Ninja") |