summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2018-04-29 19:18:58 +0100
committerRichard Hughes <richard@hughsie.com>2018-04-29 19:21:45 +0100
commite49872433921fdf6b22deef70f9532310a640114 (patch)
tree55eb5858d037ca36ec7fd49f70cd8fcfca812299
parent261a84db24e28b26a3a5907c5a5c585a666d7c65 (diff)
downloadappstream-glib-wip/hughsie/tilde-all-powerful.tar.gz
Follow the Debian tilde usage when ordering versionswip/hughsie/tilde-all-powerful
Debian requires a custom version of strcmp for the version comparison where tilde is apparently the worst-of-the-worst when checking version segments. Fixes https://github.com/hughsie/appstream-glib/issues/234
-rw-r--r--libappstream-glib/as-self-test.c6
-rw-r--r--libappstream-glib/as-utils.c26
2 files changed, 31 insertions, 1 deletions
diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c
index 3c85a12..c7b4832 100644
--- a/libappstream-glib/as-self-test.c
+++ b/libappstream-glib/as-self-test.c
@@ -5102,6 +5102,12 @@ as_test_utils_vercmp_func (void)
g_assert_cmpint (as_utils_vercmp ("1.2a.3", "1.2b.3"), <, 0);
g_assert_cmpint (as_utils_vercmp ("1.2b.3", "1.2a.3"), >, 0);
+ /* tilde is all-powerful */
+ g_assert_cmpint (as_utils_vercmp ("1.2.3~rc1", "1.2.3~rc1"), ==, 0);
+ g_assert_cmpint (as_utils_vercmp ("1.2.3~rc1", "1.2.3"), <, 0);
+ g_assert_cmpint (as_utils_vercmp ("1.2.3", "1.2.3~rc1"), >, 0);
+ g_assert_cmpint (as_utils_vercmp ("1.2.3~rc2", "1.2.3~rc1"), >, 0);
+
/* invalid */
g_assert_cmpint (as_utils_vercmp ("1", NULL), ==, G_MAXINT);
g_assert_cmpint (as_utils_vercmp (NULL, "1"), ==, G_MAXINT);
diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c
index c605cd1..83af4a4 100644
--- a/libappstream-glib/as-utils.c
+++ b/libappstream-glib/as-utils.c
@@ -1353,6 +1353,30 @@ as_utils_search_tokenize (const gchar *search)
return values;
}
+static gint8
+as_utils_vercmp_char (gchar chr1, gchar chr2)
+{
+ if (chr1 == chr2)
+ return 0;
+ if (chr1 == '~')
+ return -127;
+ if (chr2 == '~')
+ return 127;
+ return chr1 - chr2;
+}
+
+static gint
+as_utils_vercmp_chunk (const gchar *str1, const gchar *str2)
+{
+ guint i;
+ for (i = 0; str1[i] != '\0' && str2[i] != '\0'; i++) {
+ gint rc = as_utils_vercmp_char (str1[i], str2[i]);
+ if (rc != 0)
+ return rc;
+ }
+ return as_utils_vercmp_char (str1[i], str2[i]);
+}
+
/**
* as_utils_vercmp:
* @version_a: the release version, e.g. 1.2.3
@@ -1411,7 +1435,7 @@ as_utils_vercmp (const gchar *version_a, const gchar *version_b)
/* compare strings */
if ((endptr_a != NULL && endptr_a[0] != '\0') ||
(endptr_b != NULL && endptr_b[0] != '\0')) {
- gint rc = g_strcmp0 (endptr_a, endptr_b);
+ gint rc = as_utils_vercmp_chunk (endptr_a, endptr_b);
if (rc < 0)
return -1;
if (rc > 0)