Преглед изворни кода

Extend the generator expression language with more logic.

Generator expressions for comparing strings, evaluating
strings as booleans, and for creating literal right-angle-brackets
and commas are added. Those may be needed in some cases
where they appear in literals.
Stephen Kelly пре 13 година
родитељ
комит
e028381bf1

+ 6 - 0
Source/cmDocumentGeneratorExpressions.h

@@ -20,6 +20,12 @@
   "  $<1:...>                  = content of \"...\"\n"                  \
   "  $<CONFIG:cfg>             = '1' if config is \"cfg\", else '0'\n"  \
   "  $<CONFIGURATION>          = configuration name\n"                  \
+  "  $<BOOL:...>               = '1' if the '...' is true, else '0'\n"  \
+  "  $<STREQUAL:a,b>           = '1' if a is STREQUAL b, else '0'\n"    \
+  "  $<ANGLE-R>                = A literal '>'. Used to compare "       \
+  "strings which contain a '>' for example.\n"                          \
+  "  $<COMMA>                  = A literal ','. Used to compare "       \
+  "strings which contain a ',' for example.\n"                          \
   "  $<TARGET_FILE:tgt>        = main file (.exe, .so.1.2, .a)\n"       \
   "  $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n"   \
   "  $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n"            \

+ 68 - 0
Source/cmGeneratorExpressionEvaluator.cxx

@@ -137,6 +137,66 @@ static const struct NotNode : public cmGeneratorExpressionNode
   }
 } notNode;
 
+//----------------------------------------------------------------------------
+static const struct BoolNode : public cmGeneratorExpressionNode
+{
+  BoolNode() {}
+
+  virtual int NumExpectedParameters() const { return 1; }
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *,
+                       const GeneratorExpressionContent *) const
+  {
+    return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0";
+  }
+} boolNode;
+
+//----------------------------------------------------------------------------
+static const struct StrEqualNode : public cmGeneratorExpressionNode
+{
+  StrEqualNode() {}
+
+  virtual int NumExpectedParameters() const { return 2; }
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *,
+                       const GeneratorExpressionContent *) const
+  {
+    return *parameters.begin() == parameters.at(1) ? "1" : "0";
+  }
+} strEqualNode;
+
+//----------------------------------------------------------------------------
+static const struct Angle_RNode : public cmGeneratorExpressionNode
+{
+  Angle_RNode() {}
+
+  virtual int NumExpectedParameters() const { return 0; }
+
+  std::string Evaluate(const std::vector<std::string> &,
+                       cmGeneratorExpressionContext *,
+                       const GeneratorExpressionContent *) const
+  {
+    return ">";
+  }
+} angle_rNode;
+
+//----------------------------------------------------------------------------
+static const struct CommaNode : public cmGeneratorExpressionNode
+{
+  CommaNode() {}
+
+  virtual int NumExpectedParameters() const { return 0; }
+
+  std::string Evaluate(const std::vector<std::string> &,
+                       cmGeneratorExpressionContext *,
+                       const GeneratorExpressionContent *) const
+  {
+    return ",";
+  }
+} commaNode;
+
 //----------------------------------------------------------------------------
 static const struct ConfigurationNode : public cmGeneratorExpressionNode
 {
@@ -392,6 +452,14 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
     return &targetLinkerFileDirNode;
   else if (identifier == "TARGET_SONAME_FILE_DIR")
     return &targetSoNameFileDirNode;
+  else if (identifier == "STREQUAL")
+    return &strEqualNode;
+  else if (identifier == "BOOL")
+    return &boolNode;
+  else if (identifier == "ANGLE-R")
+    return &angle_rNode;
+  else if (identifier == "COMMA")
+    return &commaNode;
   return 0;
 }
 

+ 17 - 0
Tests/GeneratorExpression/CMakeLists.txt

@@ -22,6 +22,23 @@ add_custom_target(check ALL
     -Dtest_or_1=$<OR:1>
     -Dtest_or_1_0=$<OR:1,0>
     -Dtest_or_1_1=$<OR:1,1>
+    -Dtest_bool_notfound=$<BOOL:NOTFOUND>
+    -Dtest_bool_foo_notfound=$<BOOL:Foo-NOTFOUND>
+    -Dtest_bool_true=$<BOOL:True>
+    -Dtest_bool_false=$<BOOL:False>
+    -Dtest_bool_on=$<BOOL:On>
+    -Dtest_bool_off=$<BOOL:Off>
+    -Dtest_bool_no=$<BOOL:No>
+    -Dtest_bool_n=$<BOOL:N>
+    -Dtest_strequal_yes_yes=$<STREQUAL:Yes,Yes>
+    -Dtest_strequal_yes_yes_cs=$<STREQUAL:Yes,yes>
+    -Dtest_strequal_yes_no=$<STREQUAL:Yes,No>
+    -Dtest_strequal_no_yes=$<STREQUAL:No,Yes>
+    -Dtest_strequal_angle_r=$<STREQUAL:$<ANGLE-R>,$<ANGLE-R>>
+    -Dtest_strequal_comma=$<STREQUAL:$<COMMA>,$<COMMA>>
+    -Dtest_strequal_angle_r_comma=$<STREQUAL:$<ANGLE-R>,$<COMMA>>
+    -Dtest_angle_r=$<ANGLE-R>
+    -Dtest_comma=$<COMMA>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
   COMMAND ${CMAKE_COMMAND} -E echo "check done"
   VERBATIM

+ 17 - 0
Tests/GeneratorExpression/check.cmake

@@ -23,3 +23,20 @@ check(test_or_0_1 "1")
 check(test_or_1 "1")
 check(test_or_1_0 "1")
 check(test_or_1_1 "1")
+check(test_bool_notfound "0")
+check(test_bool_foo_notfound "0")
+check(test_bool_true "1")
+check(test_bool_false "0")
+check(test_bool_on "1")
+check(test_bool_off "0")
+check(test_bool_no "0")
+check(test_bool_n "0")
+check(test_strequal_yes_yes "1")
+check(test_strequal_yes_yes_cs "0")
+check(test_strequal_yes_no "0")
+check(test_strequal_no_yes "0")
+check(test_strequal_angle_r "1")
+check(test_strequal_comma "1")
+check(test_strequal_angle_r_comma "0")
+check(test_angle_r ">")
+check(test_comma ",")