From 557f0e4958ca54ce1e660d611d8f4a872e2a981f Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 16 Feb 2025 18:22:31 +0100 Subject: [PATCH] strncasecmp: Work around Solaris, Cygwin bug. * lib/strings.in.h (strncasecmp): Consider REPLACE_STRNCASECMP. Use the usual idioms. * m4/strings_h.m4 (gl_STRINGS_H_DEFAULTS): Initialize HAVE_STRNCASECMP, REPLACE_STRNCASECMP. * m4/strncasecmp.m4 (gl_FUNC_STRNCASECMP): Invoke gl_STRNCASECMP_WORKS. Set REPLACE_STRNCASECMP. Assume that HAVE_STRNCASECMP is initialized. * modules/strncasecmp (Files): Add m4/strcasecmp.m4. (configure.ac): Consider REPLACE_STRNCASECMP. * modules/strings-h (Makefile.am): Substitute HAVE_STRNCASECMP, REPLACE_STRNCASECMP. * doc/posix-functions/strncasecmp.texi: Mention the Solaris, Cygwin bug. --- ChangeLog | 15 +++++++++++++++ doc/posix-functions/strncasecmp.texi | 5 +++++ lib/strings.in.h | 24 ++++++++++++------------ m4/strings_h.m4 | 4 +++- m4/strncasecmp.m4 | 9 +++++++-- modules/strings-h | 2 ++ modules/strncasecmp | 4 +++- 7 files changed, 47 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 052ec74b9d..e73bdd7804 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2025-02-16 Bruno Haible + + strncasecmp: Work around Solaris, Cygwin bug. + * lib/strings.in.h (strncasecmp): Consider REPLACE_STRNCASECMP. Use the + usual idioms. + * m4/strings_h.m4 (gl_STRINGS_H_DEFAULTS): Initialize HAVE_STRNCASECMP, + REPLACE_STRNCASECMP. + * m4/strncasecmp.m4 (gl_FUNC_STRNCASECMP): Invoke gl_STRNCASECMP_WORKS. + Set REPLACE_STRNCASECMP. Assume that HAVE_STRNCASECMP is initialized. + * modules/strncasecmp (Files): Add m4/strcasecmp.m4. + (configure.ac): Consider REPLACE_STRNCASECMP. + * modules/strings-h (Makefile.am): Substitute HAVE_STRNCASECMP, + REPLACE_STRNCASECMP. + * doc/posix-functions/strncasecmp.texi: Mention the Solaris, Cygwin bug. + 2025-02-16 Bruno Haible strcasecmp: Add tests. diff --git a/doc/posix-functions/strncasecmp.texi b/doc/posix-functions/strncasecmp.texi index 1fc9e0307a..b52cedb4f3 100644 --- a/doc/posix-functions/strncasecmp.texi +++ b/doc/posix-functions/strncasecmp.texi @@ -12,6 +12,11 @@ Portability problems fixed by Gnulib: @item This function is missing on some platforms: 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 Portability problems not fixed by Gnulib: diff --git a/lib/strings.in.h b/lib/strings.in.h index b356115181..12a9c40a7d 100644 --- a/lib/strings.in.h +++ b/lib/strings.in.h @@ -77,23 +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 than S2. Note: This function does not work in multibyte locales. */ -# if @REPLACE_STRCASECMP@ +# if @REPLACE_STRNCASECMP@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef strcasecmp -# define strcasecmp rpl_strcasecmp +# undef strncasecmp +# define strncasecmp rpl_strncasecmp # endif -_GL_FUNCDECL_RPL (strcasecmp, int, (const char *, const char *), - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (strcasecmp, int, (const char *, const char *)); +_GL_FUNCDECL_RPL (strncasecmp, int, (const char *, const char *, size_t), + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (strncasecmp, int, (const char *, const char *, size_t)); # else -# if !@HAVE_STRCASECMP@ -_GL_FUNCDECL_SYS (strcasecmp, int, (const char *, const char *), - _GL_ARG_NONNULL ((1, 2))); +# if !@HAVE_STRNCASECMP@ +_GL_FUNCDECL_SYS (strncasecmp, int, (const char *, const char *, size_t), + _GL_ARG_NONNULL ((1, 2))); # endif -_GL_CXXALIAS_SYS (strcasecmp, int, (const char *, const char *)); +_GL_CXXALIAS_SYS (strncasecmp, int, (const char *, const char *, size_t)); # endif # if __GLIBC__ >= 2 -_GL_CXXALIASWARN (strcasecmp); +_GL_CXXALIASWARN (strncasecmp); # endif #elif defined GNULIB_POSIXCHECK /* strcasecmp() does not work with multibyte strings: @@ -126,7 +126,7 @@ extern int strncasecmp (char const *s1, char const *s2, size_t n) # undef strncasecmp # if HAVE_RAW_DECL_STRNCASECMP _GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character " - "strings in multibyte locales - " + "strings in multibyte locales and is unportable - " "use mbsncasecmp or mbspcasecmp if you care about " "internationalization, or use c_strncasecmp " "(gnulib module c-strncasecmp) if you want a locale " diff --git a/m4/strings_h.m4 b/m4/strings_h.m4 index b88e1105fb..f635575012 100644 --- a/m4/strings_h.m4 +++ b/m4/strings_h.m4 @@ -1,5 +1,5 @@ # strings_h.m4 -# serial 11 +# serial 12 dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -62,6 +62,8 @@ AC_DEFUN([gl_STRINGS_H_DEFAULTS], dnl Assume proper GNU behavior unless another module says otherwise. HAVE_FFS=1; AC_SUBST([HAVE_FFS]) HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) + HAVE_STRNCASECMP=1; AC_SUBST([HAVE_STRNCASECMP]) HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP]) REPLACE_STRCASECMP=1; AC_SUBST([REPLACE_STRCASECMP]) + REPLACE_STRNCASECMP=1; AC_SUBST([REPLACE_STRNCASECMP]) ]) diff --git a/m4/strncasecmp.m4 b/m4/strncasecmp.m4 index d27a4a0c5e..c7c8b24036 100644 --- a/m4/strncasecmp.m4 +++ b/m4/strncasecmp.m4 @@ -1,5 +1,5 @@ # strncasecmp.m4 -# serial 1 +# serial 2 dnl Copyright (C) 2002-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,7 +11,12 @@ AC_DEFUN([gl_FUNC_STRNCASECMP], AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) AC_CHECK_FUNCS([strncasecmp]) if test $ac_cv_func_strncasecmp = yes; then - HAVE_STRNCASECMP=1 + dnl Assume that strncasecmp and strcasecmp share the same bugs. + gl_STRCASECMP_WORKS + case "$gl_cv_func_strcasecmp_works" in + *yes) ;; + *) REPLACE_STRNCASECMP=1 ;; + esac else HAVE_STRNCASECMP=0 fi diff --git a/modules/strings-h b/modules/strings-h index 5c6c6736c2..2e0f0c1012 100644 --- a/modules/strings-h +++ b/modules/strings-h @@ -37,8 +37,10 @@ strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE -e 's/@''GNULIB_STRNCASECMP''@/$(GNULIB_STRNCASECMP)/g' \ -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ + -e 's|@''HAVE_STRNCASECMP''@|$(HAVE_STRNCASECMP)|g' \ -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ -e 's|@''REPLACE_STRCASECMP''@|$(REPLACE_STRCASECMP)|g' \ + -e 's|@''REPLACE_STRNCASECMP''@|$(REPLACE_STRNCASECMP)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ diff --git a/modules/strncasecmp b/modules/strncasecmp index 5fca265bad..816cd0fae6 100644 --- a/modules/strncasecmp +++ b/modules/strncasecmp @@ -4,13 +4,15 @@ Case-insensitive string comparison function for unibyte locales. Files: lib/strncasecmp.c m4/strncasecmp.m4 +m4/strcasecmp.m4 Depends-on: strings-h configure.ac: gl_FUNC_STRNCASECMP -gl_CONDITIONAL([GL_COND_OBJ_STRNCASECMP], [test $HAVE_STRNCASECMP = 0]) +gl_CONDITIONAL([GL_COND_OBJ_STRNCASECMP], + [test $HAVE_STRNCASECMP = 0 || test $REPLACE_STRNCASECMP = 1]) AM_COND_IF([GL_COND_OBJ_STRNCASECMP], [ gl_PREREQ_STRNCASECMP ])