+2025-02-16 Bruno Haible <bruno@clisp.org>
+
+ 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 <bruno@clisp.org>
strcasecmp: Add tests.
@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:
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:
# 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 "
# 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,
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])
])
# 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,
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
-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)' \
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
])