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

strcasecmp: Work around Solaris, Cygwin bug.

* lib/strings.in.h (strcasecmp): Consider REPLACE_STRCASECMP. Use the
usual idioms.
* m4/strings_h.m4 (gl_STRINGS_H_DEFAULTS): Initialize
REPLACE_STRCASECMP.
* m4/strcasecmp.m4 (gl_STRCASECMP_WORKS): New macro.
(gl_FUNC_STRCASECMP): Invoke it. Set REPLACE_STRCASECMP.
* modules/strcasecmp (configure.ac): Consider REPLACE_STRCASECMP.
* modules/strings-h (Makefile.am): Substitute REPLACE_STRCASECMP.
* doc/posix-functions/strcasecmp.texi: Mention the Solaris, Cygwin bug.
This commit is contained in:
Bruno Haible
2025-02-16 17:59:48 +01:00
parent 6abed08f2c
commit 9980b9e526
7 changed files with 89 additions and 8 deletions

View File

@@ -1,3 +1,16 @@
2025-02-16 Bruno Haible <bruno@clisp.org>
strcasecmp: Work around Solaris, Cygwin bug.
* lib/strings.in.h (strcasecmp): Consider REPLACE_STRCASECMP. Use the
usual idioms.
* m4/strings_h.m4 (gl_STRINGS_H_DEFAULTS): Initialize
REPLACE_STRCASECMP.
* m4/strcasecmp.m4 (gl_STRCASECMP_WORKS): New macro.
(gl_FUNC_STRCASECMP): Invoke it. Set REPLACE_STRCASECMP.
* modules/strcasecmp (configure.ac): Consider REPLACE_STRCASECMP.
* modules/strings-h (Makefile.am): Substitute REPLACE_STRCASECMP.
* doc/posix-functions/strcasecmp.texi: Mention the Solaris, Cygwin bug.
2025-02-16 Bruno Haible <bruno@clisp.org> 2025-02-16 Bruno Haible <bruno@clisp.org>
strcasecmp, strncasecmp: Fix header reference. strcasecmp, strncasecmp: Fix header reference.

View File

@@ -12,6 +12,11 @@ Portability problems fixed by Gnulib:
@item @item
This function is missing on some platforms: This function is missing on some platforms:
MSVC 14. MSVC 14.
@item
This function uses the case mappings of a wrong locale on some platforms:
Solaris 11.4,
@c https://sourceware.org/pipermail/cygwin/2025-February/257347.html
Cygwin 3.5.6.
@end itemize @end itemize
Portability problems not fixed by Gnulib: Portability problems not fixed by Gnulib:

View File

@@ -77,9 +77,23 @@ _GL_WARN_ON_USE (ffs, "ffs is not portable - use the ffs module");
greater than zero if S1 is lexicographically less than, equal to or greater greater than zero if S1 is lexicographically less than, equal to or greater
than S2. than S2.
Note: This function does not work in multibyte locales. */ Note: This function does not work in multibyte locales. */
# if ! @HAVE_STRCASECMP@ # if @REPLACE_STRCASECMP@
extern int strcasecmp (char const *s1, char const *s2) # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
_GL_ARG_NONNULL ((1, 2)); # undef strcasecmp
# define strcasecmp rpl_strcasecmp
# endif
_GL_FUNCDECL_RPL (strcasecmp, int, (const char *, const char *),
_GL_ARG_NONNULL ((1, 2)));
_GL_CXXALIAS_RPL (strcasecmp, int, (const char *, const char *));
# else
# if !@HAVE_STRCASECMP@
_GL_FUNCDECL_SYS (strcasecmp, int, (const char *, const char *),
_GL_ARG_NONNULL ((1, 2)));
# endif
_GL_CXXALIAS_SYS (strcasecmp, int, (const char *, const char *));
# endif
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (strcasecmp);
# endif # endif
#elif defined GNULIB_POSIXCHECK #elif defined GNULIB_POSIXCHECK
/* strcasecmp() does not work with multibyte strings: /* strcasecmp() does not work with multibyte strings:
@@ -88,7 +102,7 @@ extern int strcasecmp (char const *s1, char const *s2)
# undef strcasecmp # undef strcasecmp
# if HAVE_RAW_DECL_STRCASECMP # if HAVE_RAW_DECL_STRCASECMP
_GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character " _GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character "
"strings in multibyte locales - " "strings in multibyte locales and is unportable - "
"use mbscasecmp if you care about " "use mbscasecmp if you care about "
"internationalization, or use c_strcasecmp " "internationalization, or use c_strcasecmp "
"(gnulib module c-strcasecmp) if you want a locale " "(gnulib module c-strcasecmp) if you want a locale "

View File

@@ -1,5 +1,5 @@
# strcasecmp.m4 # strcasecmp.m4
# serial 1 # serial 2
dnl Copyright (C) 2002-2025 Free Software Foundation, Inc. dnl Copyright (C) 2002-2025 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,
@@ -10,11 +10,57 @@ AC_DEFUN([gl_FUNC_STRCASECMP],
[ [
AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) AC_REQUIRE([gl_STRINGS_H_DEFAULTS])
AC_CHECK_FUNCS([strcasecmp]) AC_CHECK_FUNCS([strcasecmp])
if test $ac_cv_func_strcasecmp = no; then if test $ac_cv_func_strcasecmp = yes; then
gl_STRCASECMP_WORKS
case "$gl_cv_func_strcasecmp_works" in
*yes) ;;
*) REPLACE_STRCASECMP=1 ;;
esac
else
HAVE_STRCASECMP=0 HAVE_STRCASECMP=0
fi fi
]) ])
AC_DEFUN([gl_STRCASECMP_WORKS],
[
AC_REQUIRE([AC_CANONICAL_HOST])
AC_CACHE_CHECK([whether strcasecmp works],
[gl_cv_func_strcasecmp_works],
[dnl Prepare a guess, used when cross-compiling or when specific locales
dnl are not available.
case "$host_os" in
solaris* | cygwin*)
gl_cv_func_strcasecmp_works="guessing no" ;;
*)
gl_cv_func_strcasecmp_works="guessing yes" ;;
esac
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdio.h>
#include <ctype.h>
#include <locale.h>
#include <strings.h>
int main ()
{
if (setlocale (LC_ALL, "fr_FR.ISO-8859-1") != NULL
|| setlocale (LC_ALL, "fr_FR.ISO8859-1") != NULL)
{
int c1 = (unsigned char) '\311';
int c2 = (unsigned char) '\351';
if (tolower (c1) == c2 && toupper (c2) == c1)
return strcasecmp ("Fej\311r", "Fej\351r") != 0;
}
return 2;
}]])],
[gl_cv_func_strcasecmp_works=yes],
[if test $? = 1; then
gl_cv_func_strcasecmp_works=no
fi
],
[])
])
])
# Prerequisites of lib/strcasecmp.c. # Prerequisites of lib/strcasecmp.c.
AC_DEFUN([gl_PREREQ_STRCASECMP], [ AC_DEFUN([gl_PREREQ_STRCASECMP], [
: :

View File

@@ -1,5 +1,5 @@
# strings_h.m4 # strings_h.m4
# serial 10 # serial 11
dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. dnl Copyright (C) 2007, 2009-2025 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,
@@ -63,4 +63,5 @@ AC_DEFUN([gl_STRINGS_H_DEFAULTS],
HAVE_FFS=1; AC_SUBST([HAVE_FFS]) HAVE_FFS=1; AC_SUBST([HAVE_FFS])
HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP])
HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP]) HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP])
REPLACE_STRCASECMP=1; AC_SUBST([REPLACE_STRCASECMP])
]) ])

View File

@@ -10,7 +10,8 @@ strings-h
configure.ac: configure.ac:
gl_FUNC_STRCASECMP gl_FUNC_STRCASECMP
gl_CONDITIONAL([GL_COND_OBJ_STRCASECMP], [test $HAVE_STRCASECMP = 0]) gl_CONDITIONAL([GL_COND_OBJ_STRCASECMP],
[test $HAVE_STRCASECMP = 0 || test $REPLACE_STRCASECMP = 1])
AM_COND_IF([GL_COND_OBJ_STRCASECMP], [ AM_COND_IF([GL_COND_OBJ_STRCASECMP], [
gl_PREREQ_STRCASECMP gl_PREREQ_STRCASECMP
]) ])

View File

@@ -38,6 +38,7 @@ strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE
-e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \
-e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \
-e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \
-e 's|@''REPLACE_STRCASECMP''@|$(REPLACE_STRCASECMP)|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)' \
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \