[Libreoffice-commits] core.git: comphelper/Library_comphelper.mk comphelper/qa comphelper/source include/comphelper

Tor Lillqvist tml at collabora.com
Tue Nov 11 09:03:20 PST 2014


 comphelper/Library_comphelper.mk                 |    1 
 comphelper/qa/string/test_string.cxx             |   40 +++++++++++++
 comphelper/source/misc/compareversionstrings.cxx |   70 +++++++++++++++++++++++
 include/comphelper/string.hxx                    |    9 ++
 4 files changed, 120 insertions(+)

New commits:
commit ca2fefb8796559b592d1ffd50c8346dcbcb33402
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Nov 11 18:50:11 2014 +0200

    Add a function to compare version number strings
    
    Change-Id: I88d3d9040f70e84752ade19001a699f60e9e7636

diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index 84bf698..271a95b 100644
--- a/comphelper/Library_comphelper.mk
+++ b/comphelper/Library_comphelper.mk
@@ -75,6 +75,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
     comphelper/source/misc/accimplaccess \
     comphelper/source/misc/anytostring \
     comphelper/source/misc/asyncnotification \
+    comphelper/source/misc/compareversionstrings \
     comphelper/source/misc/comphelper_module \
     comphelper/source/misc/comphelper_services \
     comphelper/source/misc/componentbase \
diff --git a/comphelper/qa/string/test_string.cxx b/comphelper/qa/string/test_string.cxx
index 78137a1..5e9f23f 100644
--- a/comphelper/qa/string/test_string.cxx
+++ b/comphelper/qa/string/test_string.cxx
@@ -44,6 +44,7 @@ public:
     void testIsdigitAsciiString();
     void testReverseString();
     void testEqualsString();
+    void testCompareVersionStrings();
 
     CPPUNIT_TEST_SUITE(TestString);
     CPPUNIT_TEST(testNatural);
@@ -57,6 +58,7 @@ public:
     CPPUNIT_TEST(testIsdigitAsciiString);
     CPPUNIT_TEST(testReverseString);
     CPPUNIT_TEST(testEqualsString);
+    CPPUNIT_TEST(testCompareVersionStrings);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -407,6 +409,44 @@ void TestString::testEqualsString()
     CPPUNIT_ASSERT(!::comphelper::string::equals(aIn, 'A'));
 }
 
+int sign(int n)
+{
+    if (n == 0)
+        return 0;
+    if (n < 0)
+        return -1;
+    else
+        return 1;
+}
+
+void TestString::testCompareVersionStrings()
+{
+#ifdef TEST
+#error TEST already defined
+#endif
+#define TEST(a,b,result) \
+    CPPUNIT_ASSERT(sign(::comphelper::string::compareVersionStrings(a, b)) == result); \
+    if ( result != 0 ) \
+        CPPUNIT_ASSERT(sign(::comphelper::string::compareVersionStrings(b, a)) == -(result))
+
+    TEST("", "", 0);
+    TEST("", "0", -1);
+    TEST("", "a", -1);
+    TEST("0", "1", -1);
+    TEST("1", "2", -1);
+    TEST("2", "10", -1);
+    TEST("01", "1", -1);
+    TEST("01", "001", 1);
+    TEST("1.00", "1", 1);
+    TEST("1.2", "1", 1);
+    TEST("1.01", "1.1", -1);
+    TEST("1.001", "1.1", -1);
+    TEST("1.001", "1.010", -1);
+    TEST("1.2.a", "1.2.b", -1);
+
+#undef TEST
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(TestString);
 
 }
diff --git a/comphelper/source/misc/compareversionstrings.cxx b/comphelper/source/misc/compareversionstrings.cxx
new file mode 100644
index 0000000..cc8cb44
--- /dev/null
+++ b/comphelper/source/misc/compareversionstrings.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <ctype.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <comphelper/string.hxx>
+#include <rtl/ustring.hxx>
+
+namespace comphelper { namespace string {
+
+namespace {
+
+// BSD licensed, from http://git.musl-libc.org/cgit/musl/plain/src/string/strverscmp.c
+
+int strverscmp(const char *l, const char *r)
+{
+    int haszero=1;
+    while (*l==*r) {
+        if (!*l) return 0;
+
+        if (*l=='0') {
+            if (haszero==1) {
+                haszero=0;
+            }
+        } else if (isdigit(*l)) {
+            if (haszero==1) {
+                haszero=2;
+            }
+        } else {
+            haszero=1;
+        }
+        l++; r++;
+    }
+    if (haszero==1 && (*l=='0' || *r=='0')) {
+        haszero=0;
+    }
+    if ((isdigit(*l) && isdigit(*r) ) && haszero) {
+        size_t lenl=0, lenr=0;
+        while (isdigit(l[lenl]) ) lenl++;
+        while (isdigit(r[lenr]) ) lenr++;
+        if (lenl==lenr) {
+            return (*l -  *r);
+        } else if (lenl>lenr) {
+            return 1;
+        } else {
+            return -1;
+        }
+    } else {
+        return (*l -  *r);
+    }
+}
+
+} // anonymous namespace
+
+int compareVersionStrings(const OUString& a, const OUString& b)
+{
+    return strverscmp(OUStringToOString(a, RTL_TEXTENCODING_UTF8).getStr(), OUStringToOString(b, RTL_TEXTENCODING_UTF8).getStr());
+}
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/string.hxx b/include/comphelper/string.hxx
index 74bc6a1..b062d7c 100644
--- a/include/comphelper/string.hxx
+++ b/include/comphelper/string.hxx
@@ -463,6 +463,15 @@ inline bool isalnumAscii(sal_Unicode c)
     return isalphaAscii(c) || isdigitAscii(c);
 }
 
+/** Compare two strings containing software version numbers
+
+    Inspired by the GNU strverscmp(), but there is no guarantee that the exact
+    same semantics are used, or that the semantics are stable between LibreOffice versions.
+
+    @return -1, 0 or 1
+*/
+COMPHELPER_DLLPUBLIC int compareVersionStrings(const OUString& a, const OUString& b);
+
 } }
 
 #endif


More information about the Libreoffice-commits mailing list