From 48bb48e114b7141b63e9c905f0258531c6b78cb1 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 11 Jun 2013 09:56:02 +0200 Subject: De-duplicate version comparison code. Extend the VersionCompare in cmSystemTools to handle 8 components, and port the if command to use that. --- Source/cmIfCommand.cxx | 40 ++++------------------------------------ Source/cmSystemTools.cxx | 15 ++++++++++----- 2 files changed, 14 insertions(+), 41 deletions(-) diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 56d7170..57cec5b 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -406,38 +406,6 @@ namespace } //========================================================================= - enum Op { OpLess, OpEqual, OpGreater }; - bool HandleVersionCompare(Op op, const char* lhs_str, const char* rhs_str) - { - // Parse out up to 8 components. - unsigned int lhs[8] = {0,0,0,0,0,0,0,0}; - unsigned int rhs[8] = {0,0,0,0,0,0,0,0}; - sscanf(lhs_str, "%u.%u.%u.%u.%u.%u.%u.%u", - &lhs[0], &lhs[1], &lhs[2], &lhs[3], - &lhs[4], &lhs[5], &lhs[6], &lhs[7]); - sscanf(rhs_str, "%u.%u.%u.%u.%u.%u.%u.%u", - &rhs[0], &rhs[1], &rhs[2], &rhs[3], - &rhs[4], &rhs[5], &rhs[6], &rhs[7]); - - // Do component-wise comparison. - for(unsigned int i=0; i < 8; ++i) - { - if(lhs[i] < rhs[i]) - { - // lhs < rhs, so true if operation is LESS - return op == OpLess; - } - else if(lhs[i] > rhs[i]) - { - // lhs > rhs, so true if operation is GREATER - return op == OpGreater; - } - } - // lhs == rhs, so true if operation is EQUAL - return op == OpEqual; - } - - //========================================================================= // level 0 processes parenthetical expressions bool HandleLevel0(std::list &newArgs, cmMakefile *makefile, @@ -723,16 +691,16 @@ namespace { def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile); def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile); - Op op = OpEqual; + cmSystemTools::CompareOp op = cmSystemTools::OP_EQUAL; if(*argP1 == "VERSION_LESS") { - op = OpLess; + op = cmSystemTools::OP_LESS; } else if(*argP1 == "VERSION_GREATER") { - op = OpGreater; + op = cmSystemTools::OP_GREATER; } - bool result = HandleVersionCompare(op, def, def2); + bool result = cmSystemTools::VersionCompare(op, def, def2); HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2); } diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 803d0da..66b34ab 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2680,13 +2680,18 @@ bool cmSystemTools::ChangeRPath(std::string const& file, bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op, const char* lhss, const char* rhss) { - unsigned int lhs[4] = {0,0,0,0}; - unsigned int rhs[4] = {0,0,0,0}; - sscanf(lhss, "%u.%u.%u.%u", &lhs[0], &lhs[1], &lhs[2], &lhs[3]); - sscanf(rhss, "%u.%u.%u.%u", &rhs[0], &rhs[1], &rhs[2], &rhs[3]); + // Parse out up to 8 components. + unsigned int lhs[8] = {0,0,0,0,0,0,0,0}; + unsigned int rhs[8] = {0,0,0,0,0,0,0,0}; + sscanf(lhss, "%u.%u.%u.%u.%u.%u.%u.%u", + &lhs[0], &lhs[1], &lhs[2], &lhs[3], + &lhs[4], &lhs[5], &lhs[6], &lhs[7]); + sscanf(rhss, "%u.%u.%u.%u.%u.%u.%u.%u", + &rhs[0], &rhs[1], &rhs[2], &rhs[3], + &rhs[4], &rhs[5], &rhs[6], &rhs[7]); // Do component-wise comparison. - for(unsigned int i=0; i < 4; ++i) + for(unsigned int i=0; i < 8; ++i) { if(lhs[i] < rhs[i]) { -- cgit v0.12 From e6055284b347775ae1396725704778af0bfb56c7 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 11 Jun 2013 09:53:10 +0200 Subject: Add generator expressions for version comparision. --- Source/cmDocumentGeneratorExpressions.h | 6 +++ Source/cmGeneratorExpressionEvaluator.cxx | 60 +++++++++++++++++++++++++++++ Tests/GeneratorExpression/CMakeLists.txt | 6 +++ Tests/GeneratorExpression/check-part2.cmake | 6 +++ 4 files changed, 78 insertions(+) diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index a8b3847..84f4af5 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -48,6 +48,12 @@ "used.\n" \ " $ = '1' if the CMake-id of the CXX " \ "compiler matches comp, otherwise '0'.\n" \ + " $ = '1' if v1 is a version greater than " \ + "v2, else '0'.\n" \ + " $ = '1' if v1 is a version less than v2, " \ + "else '0'.\n" \ + " $ = '1' if v1 is the same version as v2, " \ + "else '0'.\n" \ " $ = main file (.exe, .so.1.2, .a)\n" \ " $ = file used to link (.a, .lib, .so)\n" \ " $ = file with soname (.so.3)\n" \ diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 28f749d..1804691 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -345,6 +345,60 @@ static const struct CXXCompilerIdNode : public CompilerIdNode } cxxCompilerIdNode; //---------------------------------------------------------------------------- +static const struct VersionGreaterNode : public cmGeneratorExpressionNode +{ + VersionGreaterNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER, + parameters.front().c_str(), + parameters[1].c_str()) ? "1" : "0"; + } +} versionGreaterNode; + +//---------------------------------------------------------------------------- +static const struct VersionLessNode : public cmGeneratorExpressionNode +{ + VersionLessNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, + parameters.front().c_str(), + parameters[1].c_str()) ? "1" : "0"; + } +} versionLessNode; + +//---------------------------------------------------------------------------- +static const struct VersionEqualNode : public cmGeneratorExpressionNode +{ + VersionEqualNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, + parameters.front().c_str(), + parameters[1].c_str()) ? "1" : "0"; + } +} versionEqualNode; + +//---------------------------------------------------------------------------- static const struct ConfigurationNode : public cmGeneratorExpressionNode { ConfigurationNode() {} @@ -1169,6 +1223,12 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &cCompilerIdNode; else if (identifier == "CXX_COMPILER_ID") return &cxxCompilerIdNode; + else if (identifier == "VERSION_GREATER") + return &versionGreaterNode; + else if (identifier == "VERSION_LESS") + return &versionLessNode; + else if (identifier == "VERSION_EQUAL") + return &versionEqualNode; else if (identifier == "CONFIGURATION") return &configurationNode; else if (identifier == "CONFIG") diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 9cd8a7f..e2fc353 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -130,6 +130,12 @@ add_custom_target(check-part2 ALL -Dtest_arbitrary_content_comma_8=$<1:a,,b> -Dtest_arbitrary_content_comma_9=$<1:a,,b,,> -Dtest_arbitrary_content_comma_10=$<1:,,a,,b,,> + -Dtest_version_greater_1=$ + -Dtest_version_greater_2=$ + -Dtest_version_less_1=$ + -Dtest_version_less_2=$ + -Dtest_version_equal_1=$ + -Dtest_version_equal_2=$ -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 2)" VERBATIM diff --git a/Tests/GeneratorExpression/check-part2.cmake b/Tests/GeneratorExpression/check-part2.cmake index a1db5f6..f9b33b3 100644 --- a/Tests/GeneratorExpression/check-part2.cmake +++ b/Tests/GeneratorExpression/check-part2.cmake @@ -44,3 +44,9 @@ check(test_arbitrary_content_comma_7 ",,a") check(test_arbitrary_content_comma_8 "a,,b") check(test_arbitrary_content_comma_9 "a,,b,,") check(test_arbitrary_content_comma_10 ",,a,,b,,") +check(test_version_greater_1 "0") +check(test_version_greater_2 "1") +check(test_version_less_1 "0") +check(test_version_less_2 "1") +check(test_version_equal_1 "0") +check(test_version_equal_2 "1") -- cgit v0.12