diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index 535901397..5d6553d46 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -16,6 +16,8 @@ "Generator expressions are evaluted during build system generation " \ "to produce information specific to each build configuration. " \ "Valid expressions are:\n" \ + " $<0:...> = empty string (ignores \"...\")\n" \ + " $<1:...> = content of \"...\"\n" \ " $ = configuration name\n" \ " $ = main file (.exe, .so.1.2, .a)\n" \ " $ = file used to link (.a, .lib, .so)\n" \ @@ -25,6 +27,12 @@ "versions can produce the directory and file name components:\n" \ " $/$\n" \ " $/$\n" \ - " $/$\n" + " $/$\n" \ + "Boolean expressions:\n" \ + " $ = '1' if all '?' are '1', else '0'\n" \ + " $ = '0' if all '?' are '0', else '1'\n" \ + " $ = '0' if '?' is '1', else '1'\n" \ + "where '?' is always either '0' or '1'.\n" \ + "" #endif diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index f88ab0b71..ed33c7e68 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -102,6 +102,26 @@ bool cmGeneratorExpression::Evaluate() return true; } +//---------------------------------------------------------------------------- +static bool cmGeneratorExpressionBool(const char* c, std::string& result, + const char* name, + const char* a, const char* b) +{ + result = a; + while((c[0] == '0' || c[0] == '1') && (c[1] == ',' || c[1] == '>')) + { + if(c[0] == b[0]) { result = b; } + c += 2; + } + if(c[0]) + { + result = name; + result += " requires one or more comma-separated '0' or '1' values."; + return false; + } + return true; +} + //---------------------------------------------------------------------------- bool cmGeneratorExpression::Evaluate(const char* expr, std::string& result) { @@ -116,6 +136,32 @@ bool cmGeneratorExpression::Evaluate(const char* expr, std::string& result) { result = this->Config? this->Config : ""; } + else if(strncmp(expr, "$<0:",4) == 0) + { + result = ""; + } + else if(strncmp(expr, "$<1:",4) == 0) + { + result = std::string(expr+4, strlen(expr)-5); + } + else if(strncmp(expr, "$ + -Dtest_1=$<1:content> + -Dconfig=$ + -Dtest_and_0=$ + -Dtest_and_0_0=$ + -Dtest_and_0_1=$ + -Dtest_and_1=$ + -Dtest_and_1_0=$ + -Dtest_and_1_1=$ + -Dtest_not_0=$ + -Dtest_not_1=$ + -Dtest_or_0=$ + -Dtest_or_0_0=$ + -Dtest_or_0_1=$ + -Dtest_or_1=$ + -Dtest_or_1_0=$ + -Dtest_or_1_1=$ + -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake + COMMAND ${CMAKE_COMMAND} -E echo "check done" + VERBATIM + ) diff --git a/Tests/GeneratorExpression/check.cmake b/Tests/GeneratorExpression/check.cmake new file mode 100644 index 000000000..c40b847c9 --- /dev/null +++ b/Tests/GeneratorExpression/check.cmake @@ -0,0 +1,23 @@ +macro(check var val) + if(NOT "${${var}}" STREQUAL "${val}") + message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"") + endif() +endmacro() + +message(STATUS "config=[${config}]") +check(test_0 "") +check(test_1 "content") +check(test_and_0 "0") +check(test_and_0_0 "0") +check(test_and_0_1 "0") +check(test_and_1 "1") +check(test_and_1_0 "0") +check(test_and_1_1 "1") +check(test_not_0 "1") +check(test_not_1 "0") +check(test_or_0 "0") +check(test_or_0_0 "0") +check(test_or_0_1 "1") +check(test_or_1 "1") +check(test_or_1_0 "1") +check(test_or_1_1 "1") diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index eca96f907..3ea54f169 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -45,6 +45,7 @@ macro(add_RunCMake_test test) ) endmacro() +add_RunCMake_test(GeneratorExpression) add_RunCMake_test(Languages) add_RunCMake_test(ObjectLibrary) diff --git a/Tests/RunCMake/GeneratorExpression/BadAND-result.txt b/Tests/RunCMake/GeneratorExpression/BadAND-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadAND-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt new file mode 100644 index 000000000..ced21d806 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt @@ -0,0 +1,17 @@ +CMake Error at BadAND.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + AND requires one or more comma-separated '0' or '1' values. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadAND.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + AND requires one or more comma-separated '0' or '1' values. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/GeneratorExpression/BadAND.cmake b/Tests/RunCMake/GeneratorExpression/BadAND.cmake new file mode 100644 index 000000000..792654046 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadAND.cmake @@ -0,0 +1,4 @@ +add_custom_target(check ALL COMMAND check + $ + $ + VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/BadNOT-result.txt b/Tests/RunCMake/GeneratorExpression/BadNOT-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadNOT-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt new file mode 100644 index 000000000..5721f5fe1 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt @@ -0,0 +1,26 @@ +CMake Error at BadNOT.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + NOT requires exactly one '0' or '1' value. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadNOT.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + NOT requires exactly one '0' or '1' value. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadNOT.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + NOT requires exactly one '0' or '1' value. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/GeneratorExpression/BadNOT.cmake b/Tests/RunCMake/GeneratorExpression/BadNOT.cmake new file mode 100644 index 000000000..452293b8d --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadNOT.cmake @@ -0,0 +1,5 @@ +add_custom_target(check ALL COMMAND check + $ + $ + $ + VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/BadOR-result.txt b/Tests/RunCMake/GeneratorExpression/BadOR-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadOR-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt new file mode 100644 index 000000000..72ef2dd3c --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt @@ -0,0 +1,17 @@ +CMake Error at BadOR.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + OR requires one or more comma-separated '0' or '1' values. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadOR.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + OR requires one or more comma-separated '0' or '1' values. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/GeneratorExpression/BadOR.cmake b/Tests/RunCMake/GeneratorExpression/BadOR.cmake new file mode 100644 index 000000000..f16f56a3c --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadOR.cmake @@ -0,0 +1,4 @@ +add_custom_target(check ALL COMMAND check + $ + $ + VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/CMakeLists.txt b/Tests/RunCMake/GeneratorExpression/CMakeLists.txt new file mode 100644 index 000000000..e8db6b05b --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake new file mode 100644 index 000000000..95b16b35c --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(BadOR) +run_cmake(BadAND) +run_cmake(BadNOT)