diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2022-06-03 17:27:44 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2022-06-03 17:30:39 -0700 |
commit | 1ba2b66ea45f9bc43cdc0f6f93efa59157d2b2ba (patch) | |
tree | 9a040418bd7f1291fc0202a516421313991bc5a5 | |
parent | ff24917703530849f3b109905d437337cdeeab14 (diff) | |
download | gnulib-1ba2b66ea45f9bc43cdc0f6f93efa59157d2b2ba.tar.gz |
filevercmp: don’t treat entire filename as suffix
Problem reported by Artém S. Tashkinóv in:
https://lists.gnu.org/r/bug-gnulib/2022-06/msg00012.html
* lib/filevercmp.c (file_prefixlen): When stripping
(\.[A-Za-z~][A-Za-z0-9~]*)*$ suffixes, do not strip
the entire file name.
* tests/test-filevercmp.c (examples): Adjust to match new behavior.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | lib/filevercmp.c | 18 | ||||
-rw-r--r-- | lib/filevercmp.h | 4 | ||||
-rw-r--r-- | tests/test-filevercmp.c | 4 |
4 files changed, 26 insertions, 10 deletions
@@ -1,3 +1,13 @@ +2022-06-03 Paul Eggert <eggert@cs.ucla.edu> + + filevercmp: don’t treat entire filename as suffix + Problem reported by Artém S. Tashkinóv in: + https://lists.gnu.org/r/bug-gnulib/2022-06/msg00012.html + * lib/filevercmp.c (file_prefixlen): When stripping + (\.[A-Za-z~][A-Za-z0-9~]*)*$ suffixes, do not strip + the entire file name. + * tests/test-filevercmp.c (examples): Adjust to match new behavior. + 2022-06-03 Bruno Haible <bruno@clisp.org> setlocale: Update after Turkey changed its name. diff --git a/lib/filevercmp.c b/lib/filevercmp.c index d546e79054..7e54793e61 100644 --- a/lib/filevercmp.c +++ b/lib/filevercmp.c @@ -29,6 +29,8 @@ /* 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 *LEN to S's length. Otherwise, *LEN should be nonnegative, S is a char array, and *LEN does not change. */ @@ -36,20 +38,22 @@ static idx_t file_prefixlen (char const *s, ptrdiff_t *len) { size_t n = *len; /* SIZE_MAX if N == -1. */ + idx_t prefixlen = 0; - for (idx_t i = 0; ; i++) + for (idx_t i = 0; ; ) { - idx_t prefixlen = i; - while (i + 1 < n && s[i] == '.' && (c_isalpha (s[i + 1]) - || s[i + 1] == '~')) - for (i += 2; i < n && (c_isalnum (s[i]) || s[i] == '~'); i++) - continue; - if (*len < 0 ? !s[i] : i == n) { *len = i; return prefixlen; } + + i++; + prefixlen = i; + while (i + 1 < n && s[i] == '.' && (c_isalpha (s[i + 1]) + || s[i + 1] == '~')) + for (i += 2; i < n && (c_isalnum (s[i]) || s[i] == '~'); i++) + continue; } } diff --git a/lib/filevercmp.h b/lib/filevercmp.h index 5a33677671..57949760b2 100644 --- a/lib/filevercmp.h +++ b/lib/filevercmp.h @@ -61,7 +61,9 @@ 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. + 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. This function is intended to be a replacement for strverscmp. */ int filevercmp (char const *a, char const *b) _GL_ATTRIBUTE_PURE; diff --git a/tests/test-filevercmp.c b/tests/test-filevercmp.c index b2a7e90f3f..998250990d 100644 --- a/tests/test-filevercmp.c +++ b/tests/test-filevercmp.c @@ -29,6 +29,8 @@ static const char *const examples[] = "", ".", "..", + ".0", + ".9", ".A", ".Z", ".a~", @@ -39,8 +41,6 @@ static const char *const examples[] = ".zz~", ".zz", ".zz.~1~", - ".0", - ".9", ".zz.0", ".\1", ".\1.txt", |