summaryrefslogtreecommitdiff
path: root/comphelper
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2014-11-11 18:50:11 +0200
committerTor Lillqvist <tml@collabora.com>2014-11-11 19:01:58 +0200
commitca2fefb8796559b592d1ffd50c8346dcbcb33402 (patch)
treea991ba779dd0cef2820971552e7c12c3683e2c32 /comphelper
parent6914b17246f73595c1061502e432d55d9b47d744 (diff)
Add a function to compare version number strings
Change-Id: I88d3d9040f70e84752ade19001a699f60e9e7636
Diffstat (limited to 'comphelper')
-rw-r--r--comphelper/Library_comphelper.mk1
-rw-r--r--comphelper/qa/string/test_string.cxx40
-rw-r--r--comphelper/source/misc/compareversionstrings.cxx70
3 files changed, 111 insertions, 0 deletions
diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index 84bf6988ffb4..271a95bc5a6e 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 78137a1052fa..5e9f23ffb087 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 000000000000..cc8cb440733e
--- /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: */