diff --git a/lib/strutil.h b/lib/strutil.h index fe947dea7..e1ac193e7 100644 --- a/lib/strutil.h +++ b/lib/strutil.h @@ -577,6 +577,8 @@ int str_verscmp (const char *s1, const char *s2); (\.[A-Za-z~][A-Za-z0-9~]*)*$ are removed and the strings compared without them, using version sort without special priority; if they do not compare equal, this comparison result is used and the suffixes are effectively ignored. Otherwise, the entire strings are compared using version sort. + When removing a suffix from a nonempty string, remove the maximal-length suffix such that + the remaining string is nonempty. */ int filevercmp (const char *a, const char *b); diff --git a/lib/strutil/filevercmp.c b/lib/strutil/filevercmp.c index 1f5334a2c..a0e55fc9a 100644 --- a/lib/strutil/filevercmp.c +++ b/lib/strutil/filevercmp.c @@ -39,6 +39,9 @@ /* Return the length of a prefix of @s that corresponds to the suffix defined by this extended * regular expression in the C locale: (\.[A-Za-z~][A-Za-z0-9~]*)*$ * + * Use the longest suffix matching this regular expression, except do not use all of s as a suffix + * if s is nonempty. + * * If *len is -1, s is a string; set *lem to s's length. * Otherwise, *len should be nonnegative, s is a char array, and *len does not change. */ @@ -46,17 +49,13 @@ static ssize_t file_prefixlen (const char *s, ssize_t * len) { size_t n = (size_t) (*len); /* SIZE_MAX if N == -1 */ - size_t i; + size_t i = 0; + size_t prefixlen = 0; - for (i = 0;; i++) + while (TRUE) { - size_t prefixlen = i; gboolean done; - while (i + 1 < n && s[i] == '.' && (g_ascii_isalpha (s[i + 1]) || s[i + 1] == '~')) - for (i += 2; i < n && (g_ascii_isalnum (s[i]) || s[i] == '~'); i++) - ; - if (*len < 0) done = s[i] == '\0'; else @@ -67,6 +66,13 @@ file_prefixlen (const char *s, ssize_t * len) *len = (ssize_t) i; return (ssize_t) prefixlen; } + + i++; + prefixlen = i; + + while (i + 1 < n && s[i] == '.' && (g_ascii_isalpha (s[i + 1]) || s[i + 1] == '~')) + for (i += 2; i < n && (g_ascii_isalnum (s[i]) || s[i] == '~'); i++) + ; } } diff --git a/tests/lib/strutil/filevercmp.c b/tests/lib/strutil/filevercmp.c index a8a368a8b..9cb4cdc73 100644 --- a/tests/lib/strutil/filevercmp.c +++ b/tests/lib/strutil/filevercmp.c @@ -139,6 +139,8 @@ static const char *filevercmp_test_ds2[] = { "", ".", "..", + ".0", + ".9", ".A", ".Z", ".a~", @@ -149,8 +151,6 @@ static const char *filevercmp_test_ds2[] = { ".zz~", ".zz", ".zz.~1~", - ".0", - ".9", ".zz.0", ".\1", ".\1.txt",