summaryrefslogtreecommitdiff
path: root/libappstream-glib/as-utils.c
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2017-05-01 19:16:44 +0100
committerRichard Hughes <richard@hughsie.com>2017-05-02 07:59:47 +0100
commitccec0538498cf1f8171efea92c9eaa43d4875894 (patch)
treed54bb8b983febee5b6a3059e6e15ba6191cf8675 /libappstream-glib/as-utils.c
parentd54e56034feb0c2f51cbb37cf506788f680cc53c (diff)
downloadappstream-glib-ccec0538498cf1f8171efea92c9eaa43d4875894.tar.gz
Support non-numeric version numbers correctly
Fall back to strcmp when both sections are non-numeric. Also add a 'vercmp' command to appstream-util to allow us to use this on the command line.
Diffstat (limited to 'libappstream-glib/as-utils.c')
-rw-r--r--libappstream-glib/as-utils.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c
index 76e4dd6..6303ac3 100644
--- a/libappstream-glib/as-utils.c
+++ b/libappstream-glib/as-utils.c
@@ -1378,6 +1378,8 @@ as_utils_vercmp (const gchar *version_a, const gchar *version_b)
split_b = g_strsplit (str_b, ".", -1);
longest_split = MAX (g_strv_length (split_a), g_strv_length (split_b));
for (i = 0; i < longest_split; i++) {
+ gboolean isnum_a = TRUE;
+ gboolean isnum_b = TRUE;
/* we lost or gained a dot */
if (split_a[i] == NULL)
@@ -1388,18 +1390,32 @@ as_utils_vercmp (const gchar *version_a, const gchar *version_b)
/* compare integers */
ver_a = g_ascii_strtoll (split_a[i], &endptr, 10);
if (endptr != NULL && endptr[0] != '\0')
- return G_MAXINT;
+ isnum_a = FALSE;
if (ver_a < 0)
- return G_MAXINT;
+ isnum_a = FALSE;
ver_b = g_ascii_strtoll (split_b[i], &endptr, 10);
if (endptr != NULL && endptr[0] != '\0')
- return G_MAXINT;
+ isnum_b = FALSE;
if (ver_b < 0)
+ isnum_b = FALSE;
+
+ /* can't compare integer with string */
+ if (isnum_a != isnum_b)
return G_MAXINT;
- if (ver_a < ver_b)
- return -1;
- if (ver_a > ver_b)
- return 1;
+
+ /* compare strings */
+ if (!isnum_a) {
+ gint rc = g_strcmp0 (split_a[i], split_b[i]);
+ if (rc != 0)
+ return rc;
+
+ /* compare integers */
+ } else {
+ if (ver_a < ver_b)
+ return -1;
+ if (ver_a > ver_b)
+ return 1;
+ }
}
/* we really shouldn't get here */