[Cmake-commits] CMake branch, next, updated. v3.6.2-1998-g154dcb8

Brad King brad.king at kitware.com
Tue Sep 13 16:42:00 EDT 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  154dcb8a6ecea90335d13f7671b005ca520a63a1 (commit)
       via  b07862c453ad0ea7308e2841316631886620a668 (commit)
       via  07f69bd5cc9b6b4bc040327f315620c736ec15ba (commit)
      from  375be98a45b2f56c60724bf79518534b3ab5088f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=154dcb8a6ecea90335d13f7671b005ca520a63a1
commit 154dcb8a6ecea90335d13f7671b005ca520a63a1
Merge: 375be98 b07862c
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 13 16:41:58 2016 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Sep 13 16:41:58 2016 -0400

    Merge topic 'add-strverscmp' into next
    
    b07862c4 Tests: Add test for our strverscmp implementation
    07f69bd5 cmSystemTools: Add strverscmp


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b07862c453ad0ea7308e2841316631886620a668
commit b07862c453ad0ea7308e2841316631886620a668
Author:     Pierluigi Taddei <pierluigi.taddei at gmail.com>
AuthorDate: Mon Sep 12 23:13:13 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Sep 13 11:52:29 2016 -0400

    Tests: Add test for our strverscmp implementation
    
    Cover typical examples and the ordering defined by the `strverscmp(3)`
    man page.

diff --git a/Tests/CMakeLib/testSystemTools.cxx b/Tests/CMakeLib/testSystemTools.cxx
index e834b93..4ac06d7 100644
--- a/Tests/CMakeLib/testSystemTools.cxx
+++ b/Tests/CMakeLib/testSystemTools.cxx
@@ -31,5 +31,101 @@ int testSystemTools(int /*unused*/, char* /*unused*/ [])
   } else {
     cmFailed("cmSystemTools::UpperCase is working");
   }
+
+  // ----------------------------------------------------------------------
+  // Test cmSystemTools::strverscmp
+  if (cmSystemTools::strverscmp("", "") != 0) {
+    // empty string
+    cmFailed("cmSystemTools::strverscmp error empty string");
+  }
+  if (cmSystemTools::strverscmp("lib_1.1.0", "") < 0) {
+    // empty string goes first
+    cmFailed("cmSystemTools::strverscmp error empty string goes first");
+  }
+  if (cmSystemTools::strverscmp("abc", "ab") < 0) {
+    // shortest goes first
+    cmFailed("cmSystemTools::strverscmp shortest non digit");
+  }
+  if (cmSystemTools::strverscmp("12345", "123") < 0) {
+    // only numbers
+    cmFailed("cmSystemTools::strverscmp error only numbers");
+  }
+  if (cmSystemTools::strverscmp("12345", "00345") <
+      0) { // only numbers, same length
+    cmFailed("cmSystemTools::strverscmp error only numbers, same length");
+  }
+  if (cmSystemTools::strverscmp("12abcde", "12abcc") <= 0) {
+    cmFailed("cmSystemTools::strverscmp  standard order");
+  }
+  if (cmSystemTools::strverscmp("lib_1.10.0", "lib_1.1.0") < 0) {
+    // symmetric
+    cmFailed("cmSystemTools::strverscmp error /symmetric");
+  }
+  if (cmSystemTools::strverscmp("lib_1.1.0", "lib_1.001.000") <
+      0) { // multiple zeros
+    cmFailed("cmSystemTools::strverscmp error multiple zeros");
+  }
+  if (cmSystemTools::strverscmp("lib_1.2_2", "lib_1.2_10") >=
+      0) { // last number
+    cmFailed("cmSystemTools::strverscmp error last number");
+  }
+  if (cmSystemTools::strverscmp("lib", "lib") != 0) {
+    // same string
+    cmFailed("cmSystemTools::strverscmp error same string");
+  }
+  if (cmSystemTools::strverscmp("2lib", "21lib") >= 0) {
+    // suffix letter
+    cmFailed("cmSystemTools::strverscmp suffix letter");
+  }
+  if (cmSystemTools::strverscmp("002lib", "02lib") >= 0) {
+    // suffix letter decimal
+    cmFailed("cmSystemTools::strverscmp suffix letter decimal");
+  }
+  if (cmSystemTools::strverscmp("9a", "10") >= 0) {
+    // letter filler
+    cmFailed("cmSystemTools::strverscmp error letter filler");
+  }
+  if (cmSystemTools::strverscmp("01", "010") >= 0) {
+    // decimal comparison
+    cmFailed("cmSystemTools::strverscmp errordecimal comparison");
+  }
+  if (cmSystemTools::strverscmp("01", "0") >= 0) {
+    // zero and decimal
+    cmFailed("cmSystemTools::strverscmp error zero and decimal");
+  }
+  if (cmSystemTools::strverscmp("000", "00") >= 0) {
+    // zero and decimal
+    cmFailed("cmSystemTools::strverscmp error zero and decimal");
+  }
+  if (cmSystemTools::strverscmp("000", "0001") < 0) {
+    // zero and decimal
+    cmFailed("cmSystemTools::strverscmp leading zeros");
+  }
+
+  // test sorting using standard strvercmp input
+  std::vector<std::string> testString;
+  testString.push_back("000");
+  testString.push_back("00");
+  testString.push_back("01");
+  testString.push_back("010");
+  testString.push_back("09");
+  testString.push_back("0");
+  testString.push_back("1");
+  testString.push_back("9");
+  testString.push_back("10");
+
+  // test global ordering of input strings
+  for (size_t i = 0; i < testString.size() - 1; i++) {
+    for (size_t j = i + 1; j < testString.size(); j++) {
+      if (cmSystemTools::strverscmp(testString[i], testString[j]) >= 0) {
+        cmFailed("cmSystemTools::strverscmp error in comparing strings " +
+                 testString[i] + " " + testString[j]);
+      }
+    }
+  }
+
+  if (!failed) {
+    cmPassed("cmSystemTools::strverscmp working");
+  }
   return failed;
 }

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=07f69bd5cc9b6b4bc040327f315620c736ec15ba
commit 07f69bd5cc9b6b4bc040327f315620c736ec15ba
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 13 08:37:00 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Sep 13 11:52:28 2016 -0400

    cmSystemTools: Add strverscmp
    
    Add support for natural string order by comparing non-numerical
    character directly and numerical number by firstly collecting contiguous
    digits.  The order is defined by the `strverscmp(3)` manual [1].
    
    [1] http://man7.org/linux/man-pages/man3/strverscmp.3.html
    
    Inspired-by: Pierluigi Taddei <pierluigi.taddei at gmail.com>

diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 7da9975..a0a9c50 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2426,6 +2426,83 @@ bool cmSystemTools::VersionCompareGreaterEq(std::string const& lhs,
                                        lhs.c_str(), rhs.c_str());
 }
 
+static size_t cm_strverscmp_find_first_difference_or_end(const char* lhs,
+                                                         const char* rhs)
+{
+  size_t i = 0;
+  /* Step forward until we find a difference or both strings end together.
+     The difference may lie on the null-terminator of one string.  */
+  while (lhs[i] == rhs[i] && lhs[i] != 0) {
+    ++i;
+  }
+  return i;
+}
+
+static size_t cm_strverscmp_find_digits_begin(const char* s, size_t i)
+{
+  /* Step back until we are not preceded by a digit.  */
+  while (i > 0 && isdigit(s[i - 1])) {
+    --i;
+  }
+  return i;
+}
+
+static size_t cm_strverscmp_find_digits_end(const char* s, size_t i)
+{
+  /* Step forward over digits.  */
+  while (isdigit(s[i])) {
+    ++i;
+  }
+  return i;
+}
+
+static size_t cm_strverscmp_count_leading_zeros(const char* s, size_t b)
+{
+  size_t i = b;
+  /* Step forward over zeros that are followed by another digit.  */
+  while (s[i] == '0' && isdigit(s[i + 1])) {
+    ++i;
+  }
+  return i - b;
+}
+
+static int cm_strverscmp(const char* lhs, const char* rhs)
+{
+  size_t const i = cm_strverscmp_find_first_difference_or_end(lhs, rhs);
+  if (lhs[i] != rhs[i]) {
+    /* The strings differ starting at 'i'.  Check for a digit sequence.  */
+    size_t const b = cm_strverscmp_find_digits_begin(lhs, i);
+    if (b != i || (isdigit(lhs[i]) && isdigit(rhs[i]))) {
+      /* A digit sequence starts at 'b', preceding or at 'i'.  */
+
+      /* Look for leading zeros, implying a leading decimal point.  */
+      size_t const lhs_zeros = cm_strverscmp_count_leading_zeros(lhs, b);
+      size_t const rhs_zeros = cm_strverscmp_count_leading_zeros(rhs, b);
+      if (lhs_zeros != rhs_zeros) {
+        /* The side with more leading zeros orders first.  */
+        return rhs_zeros > lhs_zeros ? 1 : -1;
+      }
+      if (lhs_zeros == 0) {
+        /* No leading zeros; compare digit sequence lengths.  */
+        size_t const lhs_end = cm_strverscmp_find_digits_end(lhs, i);
+        size_t const rhs_end = cm_strverscmp_find_digits_end(rhs, i);
+        if (lhs_end != rhs_end) {
+          /* The side with fewer digits orders first.  */
+          return lhs_end > rhs_end ? 1 : -1;
+        }
+      }
+    }
+  }
+
+  /* Ordering was not decided by digit sequence lengths; compare bytes.  */
+  return lhs[i] - rhs[i];
+}
+
+int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs)
+{
+  return cm_strverscmp(lhs.c_str(), rhs.c_str());
+}
+
 bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
                                 bool* removed)
 {
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 3c1a9f4..aecf40e 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -306,6 +306,16 @@ public:
                                       std::string const& rhs);
 
   /**
+   * Compare two ASCII strings using natural versioning order.
+   * Non-numerical characters are compared directly.
+   * Numerical characters are first globbed such that, e.g.
+   * `test000 < test01 < test0 < test1 < test10`.
+   * Return a value less than, equal to, or greater than zero if lhs
+   * precedes, equals, or succeeds rhs in the defined ordering.
+   */
+  static int strverscmp(std::string const& lhs, std::string const& rhs);
+
+  /**
    * Determine the file type based on the extension
    */
   static FileFormat GetFileFormat(const char* ext);

-----------------------------------------------------------------------

Summary of changes:
 Source/cmSystemTools.cxx           |   77 +++++++++++++++++++++++++++++
 Source/cmSystemTools.h             |   10 ++++
 Tests/CMakeLib/testSystemTools.cxx |   96 ++++++++++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list