Ticket #4374: fix file sort by version.

filevercmp: don't treat entire filename as suffix.

Sync with gnulib 1ba2b66ea45f9bc43cdc0f6f93efa59157d2b2ba.

(file_prefixlen): When stripping (\.[A-Za-z~][A-Za-z0-9~]*)*$ suffixes,
do not strip the entire file name.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2022-06-04 08:51:04 +03:00
parent 34d3726b79
commit dc67246c27
3 changed files with 17 additions and 9 deletions

View File

@ -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 (\.[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 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. 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); int filevercmp (const char *a, const char *b);

View File

@ -39,6 +39,9 @@
/* Return the length of a prefix of @s that corresponds to the suffix defined by this extended /* 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~]*)*$ * 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. * 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. * 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) file_prefixlen (const char *s, ssize_t * len)
{ {
size_t n = (size_t) (*len); /* SIZE_MAX if N == -1 */ 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; 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) if (*len < 0)
done = s[i] == '\0'; done = s[i] == '\0';
else else
@ -67,6 +66,13 @@ file_prefixlen (const char *s, ssize_t * len)
*len = (ssize_t) i; *len = (ssize_t) i;
return (ssize_t) prefixlen; 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++)
;
} }
} }

View File

@ -139,6 +139,8 @@ static const char *filevercmp_test_ds2[] = {
"", "",
".", ".",
"..", "..",
".0",
".9",
".A", ".A",
".Z", ".Z",
".a~", ".a~",
@ -149,8 +151,6 @@ static const char *filevercmp_test_ds2[] = {
".zz~", ".zz~",
".zz", ".zz",
".zz.~1~", ".zz.~1~",
".0",
".9",
".zz.0", ".zz.0",
".\1", ".\1",
".\1.txt", ".\1.txt",