diff options
author | Brad King <brad.king@kitware.com> | 2008-09-10 15:58:40 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2008-09-10 15:58:40 (GMT) |
commit | 4fa96dbf95bb3689fb1c3283c38713ec5275f262 (patch) | |
tree | fdf7858be3ec641926a37794ed4e8d906f2e3b52 /Source | |
parent | 4ed4f5a7d4e399b9ac247aff7fec7cda61bfb5d1 (diff) | |
download | CMake-4fa96dbf95bb3689fb1c3283c38713ec5275f262.zip CMake-4fa96dbf95bb3689fb1c3283c38713ec5275f262.tar.gz CMake-4fa96dbf95bb3689fb1c3283c38713ec5275f262.tar.bz2 |
ENH: Add version comparison to if() command
Provide VERSION_LESS, VERSION_EQUAL, and VERSION_GREATER operators in
the if() command. This simplifies component-wise comparison of version
numbers in the form "major[.minor[.patch[.tweak]]]".
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmIfCommand.cxx | 48 | ||||
-rw-r--r-- | Source/cmIfCommand.h | 5 |
2 files changed, 53 insertions, 0 deletions
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index e82a8fb..8c22602 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -285,6 +285,34 @@ namespace } //========================================================================= + enum Op { OpLess, OpEqual, OpGreater }; + bool HandleVersionCompare(Op op, const char* lhs_str, const char* rhs_str) + { + // Parse out up to 4 components. + unsigned int lhs[4] = {0,0,0,0}; + unsigned int rhs[4] = {0,0,0,0}; + sscanf(lhs_str, "%u.%u.%u.%u", &lhs[0], &lhs[1], &lhs[2], &lhs[3]); + sscanf(rhs_str, "%u.%u.%u.%u", &rhs[0], &rhs[1], &rhs[2], &rhs[3]); + + // Do component-wise comparison. + for(unsigned int i=0; i < 4; ++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<std::string> &newArgs, cmMakefile *makefile, @@ -552,6 +580,26 @@ namespace reducible, arg, newArgs, argP1, argP2); } + if (argP1 != newArgs.end() && argP2 != newArgs.end() && + (*(argP1) == "VERSION_LESS" || *(argP1) == "VERSION_GREATER" || + *(argP1) == "VERSION_EQUAL")) + { + def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile); + def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile); + Op op = OpEqual; + if(*argP1 == "VERSION_LESS") + { + op = OpLess; + } + else if(*argP1 == "VERSION_GREATER") + { + op = OpGreater; + } + bool result = HandleVersionCompare(op, def, def2); + HandleBinaryOp(result, + reducible, arg, newArgs, argP1, argP2); + } + // is file A newer than file B if (argP1 != newArgs.end() && argP2 != newArgs.end() && *(argP1) == "IS_NEWER_THAN") diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index 6c23aa0..bc84e56 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -177,6 +177,11 @@ public: " if(string STREQUAL string)\n" "True if the given string or variable's value is lexicographically " "less (or greater, or equal) than the string on the right.\n" + " if(version1 VERSION_LESS version2)\n" + " if(version1 VERSION_EQUAL version2)\n" + " if(version1 VERSION_GREATER version2)\n" + "Component-wise integer version number comparison (version format is " + "major[.minor[.patch[.tweak]]]).\n" " if(DEFINED variable)\n" "True if the given variable is defined. It does not matter if the " "variable is true or false just if it has been set."; |