+2024-01-02 Bruno Haible <bruno@clisp.org>
+
+ strverscmp: Work around bug in musl libc 1.2.3 and in Cygwin.
+ Reported by Dmitry Bogatov <KAction@gnu.org> via Simon Josefsson in
+ <https://lists.gnu.org/archive/html/bug-gnulib/2024-01/msg00002.html>.
+ * m4/string_h.m4 (gl_STRING_H_DEFAULTS): Initialize REPLACE_STRVERSCMP.
+ * m4/strverscmp.m4 (gl_FUNC_STRVERSCMP): Test whether strverscmp works
+ and set REPLACE_STRVERSCMP if not.
+ * lib/string.in.h (strverscmp): Consider REPLACE_STRVERSCMP.
+ * modules/strverscmp (Depends-on, configure.ac): Likewise.
+ * modules/string (Makefile.am): Substitute REPLACE_STRVERSCMP.
+ * tests/test-strverscmp.c (main): Add test cases suggested by Dmitry
+ Bogatov and by Simon Josefsson.
+ * doc/glibc-functions/strverscmp.texi: Mention the musl and Cygwin bug.
+ Update version info regarding FreeBSD.
+
2024-01-01 Paul Eggert <eggert@cs.ucla.edu>
update-copyright-tests: immunize against self
Portability problems fixed by Gnulib:
@itemize
@item
-This function is missing on all non-glibc platforms:
-macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 1.7.x, mingw, MSVC 14, Android 9.0.
+This function is missing on many platforms:
+macOS 11.1, FreeBSD 13.1, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 1.7.x, mingw, MSVC 14, Android 9.0.
+@item
+This function treats ASCII letters as smaller than a digit sequence
+on some platforms:
+@c https://git.musl-libc.org/cgit/musl/commit/src/string/strverscmp.c?id=b50eb8c36c20f967bd0ed70c0b0db38a450886ba
+musl libc 1.2.3, Cygwin 3.4.6.
@end itemize
Portability problems not fixed by Gnulib:
#endif
#if @GNULIB_STRVERSCMP@
-# if !@HAVE_STRVERSCMP@
+# if @REPLACE_STRVERSCMP@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strverscmp rpl_strverscmp
+# endif
+_GL_FUNCDECL_RPL (strverscmp, int, (const char *, const char *)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (strverscmp, int, (const char *, const char *));
+# else
+# if !@HAVE_STRVERSCMP@
_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *)
_GL_ATTRIBUTE_PURE
_GL_ARG_NONNULL ((1, 2)));
-# endif
+# endif
_GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *));
+# endif
_GL_CXXALIASWARN (strverscmp);
#elif defined GNULIB_POSIXCHECK
# undef strverscmp
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 37
+# serial 38
# Written by Paul Eggert.
REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R])
REPLACE_STRERRORNAME_NP=0; AC_SUBST([REPLACE_STRERRORNAME_NP])
REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL])
+ REPLACE_STRVERSCMP=0; AC_SUBST([REPLACE_STRVERSCMP])
UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R])
])
-# strverscmp.m4 serial 9
+# strverscmp.m4 serial 10
dnl Copyright (C) 2002, 2005-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
AC_CHECK_FUNCS([strverscmp])
if test $ac_cv_func_strverscmp = no; then
HAVE_STRVERSCMP=0
+ else
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether strverscmp works],
+ [gl_cv_func_strverscmp_works],
+ [dnl Detect musl-1.2.3 and Cygwin 3.4.6 bug.
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <string.h>
+int main ()
+{
+ return strverscmp ("UNKNOWN", "2.2.0") <= 0;
+}
+ ]])],
+ [gl_cv_func_strverscmp_works=yes],
+ [gl_cv_func_strverscmp_works=no],
+ [case "$host_os" in
+ # Guess yes on glibc systems.
+ *-gnu* | gnu*) gl_cv_func_strverscmp_works="guessing yes" ;;
+ # Guess no on musl systems.
+ *-musl* | midipix*) gl_cv_func_strverscmp_works="guessing no" ;;
+ # Guess no on Cygwin.
+ cygwin*) gl_cv_func_strverscmp_works="guessing no" ;;
+ # If we don't know, obey --enable-cross-guesses.
+ *) gl_cv_func_strverscmp_works="$gl_cross_guess_normal" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_strverscmp_works" in
+ *yes) ;;
+ *) REPLACE_STRVERSCMP=1 ;;
+ esac
fi
])
-e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \
-e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \
-e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \
+ -e 's|@''REPLACE_STRVERSCMP''@|$(REPLACE_STRVERSCMP)|g' \
-e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
Depends-on:
extensions
-libc-config [test $HAVE_STRVERSCMP = 0]
-stdint [test $HAVE_STRVERSCMP = 0]
+libc-config [test $HAVE_STRVERSCMP = 0 || test $REPLACE_STRVERSCMP = 1]
+stdint [test $HAVE_STRVERSCMP = 0 || test $REPLACE_STRVERSCMP = 1]
string
configure.ac:
gl_FUNC_STRVERSCMP
-gl_CONDITIONAL([GL_COND_OBJ_STRVERSCMP], [test $HAVE_STRVERSCMP = 0])
+gl_CONDITIONAL([GL_COND_OBJ_STRVERSCMP],
+ [test $HAVE_STRVERSCMP = 0 || test $REPLACE_STRVERSCMP = 1])
AM_COND_IF([GL_COND_OBJ_STRVERSCMP], [
gl_PREREQ_STRVERSCMP
])
{
ASSERT (strverscmp ("", "") == 0);
ASSERT (strverscmp ("a", "a") == 0);
+ ASSERT (strverscmp ("1.7", "1.7") == 0);
ASSERT (strverscmp ("a", "b") < 0);
ASSERT (strverscmp ("b", "a") > 0);
ASSERT (strverscmp ("000", "00") < 0);
ASSERT (strverscmp (c, a) > 0);
}
+ /* From Dmitry Bogatov. */
+ {
+ static char const a[] = "UNKNOWN";
+ static char const b[] = "2.2.0";
+ ASSERT (strverscmp (a, b) > 0);
+ ASSERT (strverscmp (b, a) < 0);
+ }
+
return 0;
}