Genex: Add IF generator expression

This allows a single condition to be used to choose between two
alternatives.  Without this the condition must be duplicated with
one surrounded by `NOT`.

Closes: #15585
This commit is contained in:
Colby Pike
2017-01-23 20:14:03 -07:00
committed by Brad King
parent 8ea12a8b80
commit 895f7f16a7
9 changed files with 62 additions and 0 deletions

View File

@@ -51,6 +51,8 @@ Available logical expressions are:
``0`` if all ``?`` are ``0``, else ``1``
``$<NOT:?>``
``0`` if ``?`` is ``1``, else ``1``
``$<IF:?,true-value...,false-value...>```
``true-value...`` if ``?`` is ``1``, ``false-value...`` if ``?`` is ``0``
``$<STREQUAL:a,b>``
``1`` if ``a`` is STREQUAL ``b``, else ``0``
``$<EQUAL:a,b>``

View File

@@ -0,0 +1,7 @@
genex-if
--------
* A new logical generator expression for immediate-if was added:
``$<IF:cond,true-value,false-value>``. It takes three arguments: One
condition, a true-value, and a false-value. Resolves to the true-value if the
condition is ``1``, and resolves to the false-value if the condition is ``0``.

View File

@@ -162,6 +162,27 @@ static const struct BoolNode : public cmGeneratorExpressionNode
}
} boolNode;
static const struct IfNode : public cmGeneratorExpressionNode
{
IfNode() {}
int NumExpectedParameters() const CM_OVERRIDE { return 3; }
std::string Evaluate(const std::vector<std::string>& parameters,
cmGeneratorExpressionContext* context,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker*) const CM_OVERRIDE
{
if (parameters[0] != "1" && parameters[0] != "0") {
reportError(context, content->GetOriginalExpression(),
"First parameter to $<IF> must resolve to exactly one '0' "
"or '1' value.");
return std::string();
}
return parameters[0] == "1" ? parameters[1] : parameters[2];
}
} ifNode;
static const struct StrEqualNode : public cmGeneratorExpressionNode
{
StrEqualNode() {}
@@ -1757,6 +1778,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
nodeMap["UPPER_CASE"] = &upperCaseNode;
nodeMap["MAKE_C_IDENTIFIER"] = &makeCIdentifierNode;
nodeMap["BOOL"] = &boolNode;
nodeMap["IF"] = &ifNode;
nodeMap["ANGLE-R"] = &angle_rNode;
nodeMap["COMMA"] = &commaNode;
nodeMap["SEMICOLON"] = &semicolonNode;

View File

@@ -246,6 +246,10 @@ add_custom_target(check-part4 ALL
# CMake as command-line argument
-Dtest_shell_path=${path_prefix}$<SHELL_PATH:${test_shell_path}>
-Dpath_prefix=${path_prefix}
-Dif_1=$<IF:1,a,b>
-Dif_2=$<IF:0,a,b>
-Dif_3=$<IF:$<EQUAL:10,30>,a,b>
-Dif_4=$<IF:$<EQUAL:30,30>,a,b>
-DWIN32=${WIN32}
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part4.cmake

View File

@@ -13,3 +13,8 @@ if(WIN32)
else()
check(test_shell_path [[/shell/path]])
endif()
check(if_1 "a")
check(if_2 "b")
check(if_3 "b")
check(if_4 "a")

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,15 @@
CMake Error at BadIF.cmake:2 \(add_custom_target\):
Error evaluating generator expression:
\$<IF:asdf,a,b>
First parameter to \$<IF> must resolve to exactly one '0' or '1' value.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at BadIF.cmake:2 \(add_custom_target\):
Error evaluating generator expression:
\$<IF:asdf,a>
\$<IF> expression requires 3 comma separated parameters, but got 2 instead.

View File

@@ -0,0 +1,5 @@
add_custom_target(check ALL COMMAND check
$<IF:asdf,a,b>
$<IF:asdf,a>
)

View File

@@ -1,5 +1,6 @@
include(RunCMake)
run_cmake(BadIF)
run_cmake(BadCONFIG)
run_cmake(BadOR)
run_cmake(BadAND)