From 2aa729ac6af316bc30111144684a51c4650d5c44 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 15 Apr 2011 13:53:50 -0600 Subject: [PATCH] strchrnul: work around cygwin bug A misplaced * means that cygwin 1.7.9 dereferences NULL rather than returning the location of the trailing NUL byte. * doc/glibc-functions/strchrnul.texi (strchrnul): Document bug. * m4/strchrnul.m4 (gl_FUNC_STRCHRNUL): Detect it. * m4/string_h.m4 (gl_HEADER_STRING_H_DEFAULTS): New witness. * modules/string (Makefile.am): Substitute it. * lib/string.in.h (strchrnul): Use it. Signed-off-by: Eric Blake --- ChangeLog | 9 +++++++++ doc/glibc-functions/strchrnul.texi | 9 +++++++-- lib/string.in.h | 16 ++++++++++++++-- m4/strchrnul.m4 | 32 +++++++++++++++++++++++++++++++- m4/string_h.m4 | 3 ++- modules/string | 1 + 6 files changed, 64 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 580cfa34e..5a70916e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-04-15 Eric Blake + + strchrnul: work around cygwin bug + * doc/glibc-functions/strchrnul.texi (strchrnul): Document bug. + * m4/strchrnul.m4 (gl_FUNC_STRCHRNUL): Detect it. + * m4/string_h.m4 (gl_HEADER_STRING_H_DEFAULTS): New witness. + * modules/string (Makefile.am): Substitute it. + * lib/string.in.h (strchrnul): Use it. + 2011-04-15 Bruno Haible Don't require lib/stdio-write.c when only module 'stdio' is used. diff --git a/doc/glibc-functions/strchrnul.texi b/doc/glibc-functions/strchrnul.texi index fcb461ea8..610e935cd 100644 --- a/doc/glibc-functions/strchrnul.texi +++ b/doc/glibc-functions/strchrnul.texi @@ -7,8 +7,13 @@ Gnulib module: strchrnul Portability problems fixed by Gnulib: @itemize @item -This function is missing on all non-glibc platforms: -MacOS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin, mingw, Interix 3.5, BeOS. +This function is missing on many non-glibc platforms: +MacOS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, +IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.7.8, mingw, Interix 3.5, +BeOS. +@item +This function is broken on some platforms: +Cygwin 1.7.9. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/string.in.h b/lib/string.in.h index 652c9407b..7f156aa45 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -277,17 +277,29 @@ _GL_WARN_ON_USE (strchr, "strchr cannot work correctly on character strings " /* Find the first occurrence of C in S or the final NUL byte. */ #if @GNULIB_STRCHRNUL@ -# if ! @HAVE_STRCHRNUL@ +# if @REPLACE_STRCHRNUL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strchrnul rpl_strchrnul +# endif +_GL_FUNCDECL_RPL (strchrnul, char *, + (const char *str, int ch) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strchrnul, char *, + (const char *str, int ch)); +# else +# if ! @HAVE_STRCHRNUL@ _GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1))); -# endif +# endif /* On some systems, this function is defined as an overloaded function: extern "C++" { const char * std::strchrnul (const char *, int); } extern "C++" { char * std::strchrnul (char *, int); } */ _GL_CXXALIAS_SYS_CAST2 (strchrnul, char *, (char const *__s, int __c_in), char const *, (char const *__s, int __c_in)); +# endif # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) _GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in)); diff --git a/m4/strchrnul.m4 b/m4/strchrnul.m4 index a64e805bd..52e50a121 100644 --- a/m4/strchrnul.m4 +++ b/m4/strchrnul.m4 @@ -1,4 +1,4 @@ -# strchrnul.m4 serial 7 +# strchrnul.m4 serial 8 dnl Copyright (C) 2003, 2007, 2009-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -14,6 +14,36 @@ AC_DEFUN([gl_FUNC_STRCHRNUL], if test $ac_cv_func_strchrnul = no; then HAVE_STRCHRNUL=0 gl_PREREQ_STRCHRNUL + else + AC_CACHE_CHECK([whether strchrnul works], + [gl_cv_func_strchrnul_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include /* for strchrnul */ +]], [[const char *buf = "a"; + return strchrnul(buf, 'b') != buf + 1; + ]])], + [gl_cv_func_strchrnul_works=yes], + [gl_cv_func_strchrnul_works=no], + [dnl Cygwin 1.7.9 introduced strchrnul, but it was broken until 1.7.10 + AC_EGREP_CPP([Lucky user], + [ +#if defined __CYGWIN__ + #include + #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 9) + Lucky user + #endif +#else + Lucky user +#endif + ], + [gl_cv_func_strchrnul_works=yes], + [gl_cv_func_strchrnul_works="guessing no"]) + ]) + ]) + if test "$gl_cv_func_strchrnul_works" != yes; then + REPLACE_STRCHRNUL=1 + AC_LIBOBJ([strchrnul]) + fi fi ]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 index 30ddfbc3a..df8c40353 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -5,7 +5,7 @@ # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 19 +# serial 20 # Written by Paul Eggert. @@ -104,6 +104,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR]) + REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL]) REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R]) REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) diff --git a/modules/string b/modules/string index 9b3e9f0fb..a88bdce00 100644 --- a/modules/string +++ b/modules/string @@ -87,6 +87,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ + -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ -- 2.11.0