1
0
mirror of https://git.savannah.gnu.org/git/gnulib.git synced 2025-08-08 17:22:05 +03:00

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.
This commit is contained in:
Bruno Haible
2024-01-02 11:37:05 +01:00
parent d57daa5979
commit dee279cf2a
8 changed files with 83 additions and 9 deletions

View File

@@ -1,3 +1,19 @@
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> 2024-01-01 Paul Eggert <eggert@cs.ucla.edu>
update-copyright-tests: immunize against self update-copyright-tests: immunize against self

View File

@@ -20,8 +20,13 @@ Gnulib module: strverscmp
Portability problems fixed by Gnulib: Portability problems fixed by Gnulib:
@itemize @itemize
@item @item
This function is missing on all non-glibc platforms: This function is missing on many 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. 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 @end itemize
Portability problems not fixed by Gnulib: Portability problems not fixed by Gnulib:

View File

@@ -1419,12 +1419,22 @@ _GL_WARN_ON_USE (strsignal, "strsignal is unportable - "
#endif #endif
#if @GNULIB_STRVERSCMP@ #if @GNULIB_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@ # if !@HAVE_STRVERSCMP@
_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *) _GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *)
_GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE
_GL_ARG_NONNULL ((1, 2))); _GL_ARG_NONNULL ((1, 2)));
# endif # endif
_GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *)); _GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *));
# endif
_GL_CXXALIASWARN (strverscmp); _GL_CXXALIASWARN (strverscmp);
#elif defined GNULIB_POSIXCHECK #elif defined GNULIB_POSIXCHECK
# undef strverscmp # undef strverscmp

View File

@@ -5,7 +5,7 @@
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved. # with or without modifications, as long as this notice is preserved.
# serial 37 # serial 38
# Written by Paul Eggert. # Written by Paul Eggert.
@@ -146,5 +146,6 @@ AC_DEFUN([gl_STRING_H_DEFAULTS],
REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R]) REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R])
REPLACE_STRERRORNAME_NP=0; AC_SUBST([REPLACE_STRERRORNAME_NP]) REPLACE_STRERRORNAME_NP=0; AC_SUBST([REPLACE_STRERRORNAME_NP])
REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL]) REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL])
REPLACE_STRVERSCMP=0; AC_SUBST([REPLACE_STRVERSCMP])
UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R]) UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R])
]) ])

View File

@@ -1,4 +1,4 @@
# strverscmp.m4 serial 9 # strverscmp.m4 serial 10
dnl Copyright (C) 2002, 2005-2024 Free Software Foundation, Inc. dnl Copyright (C) 2002, 2005-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@@ -13,6 +13,37 @@ AC_DEFUN([gl_FUNC_STRVERSCMP],
AC_CHECK_FUNCS([strverscmp]) AC_CHECK_FUNCS([strverscmp])
if test $ac_cv_func_strverscmp = no; then if test $ac_cv_func_strverscmp = no; then
HAVE_STRVERSCMP=0 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 fi
]) ])

View File

@@ -125,6 +125,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \
-e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \ -e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \
-e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|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 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \

View File

@@ -7,13 +7,14 @@ m4/strverscmp.m4
Depends-on: Depends-on:
extensions extensions
libc-config [test $HAVE_STRVERSCMP = 0] libc-config [test $HAVE_STRVERSCMP = 0 || test $REPLACE_STRVERSCMP = 1]
stdint [test $HAVE_STRVERSCMP = 0] stdint [test $HAVE_STRVERSCMP = 0 || test $REPLACE_STRVERSCMP = 1]
string string
configure.ac: configure.ac:
gl_FUNC_STRVERSCMP 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], [ AM_COND_IF([GL_COND_OBJ_STRVERSCMP], [
gl_PREREQ_STRVERSCMP gl_PREREQ_STRVERSCMP
]) ])

View File

@@ -30,6 +30,7 @@ main (void)
{ {
ASSERT (strverscmp ("", "") == 0); ASSERT (strverscmp ("", "") == 0);
ASSERT (strverscmp ("a", "a") == 0); ASSERT (strverscmp ("a", "a") == 0);
ASSERT (strverscmp ("1.7", "1.7") == 0);
ASSERT (strverscmp ("a", "b") < 0); ASSERT (strverscmp ("a", "b") < 0);
ASSERT (strverscmp ("b", "a") > 0); ASSERT (strverscmp ("b", "a") > 0);
ASSERT (strverscmp ("000", "00") < 0); ASSERT (strverscmp ("000", "00") < 0);
@@ -55,5 +56,13 @@ main (void)
ASSERT (strverscmp (c, a) > 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; return 0;
} }