From 06cd74c141f523c2997cf5a13243ef68b6a2ae81 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 10 Jan 2008 02:46:55 +0100 Subject: [PATCH] Work around OpenBSD 4.0 tdelete() bug. --- ChangeLog | 10 ++++++++++ doc/functions/tdelete.texi | 4 ++++ lib/search.in.h | 12 ++++++++++-- m4/search_h.m4 | 7 ++++--- m4/tsearch.m4 | 44 +++++++++++++++++++++++++++++++++++++++++--- modules/search | 1 + 6 files changed, 70 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc68f9d7d..606e4e46e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2008-01-09 Bruno Haible + Work around OpenBSD 4.0 tdelete() bug. + * m4/tsearch.m4 (gl_FUNC_TSEARCH): Also check tdelete's return value. + * lib/search.in.h: If REPLACE_TSEARCH is 1, define tsearch etc. as + macros and don't redefine the enum values. + * m4/search_h.m4 (gl_SEARCH_H_DEFAULTS): Initialize REPLACE_TSEARCH. + * modules/search (Makefile.am): Also substitute REPLACE_TSEARCH. + * doc/functions/tdelete.texi: Document the OpenBSD 4.0 bug. + +2008-01-09 Bruno Haible + * tests/test-wcwidth.c: Include and localcharset.h. (main): Don't perform the tests if setlocale did not install a UTF-8 locale. Needed on OpenBSD 4.0. diff --git a/doc/functions/tdelete.texi b/doc/functions/tdelete.texi index ac34a889f..8398359de 100644 --- a/doc/functions/tdelete.texi +++ b/doc/functions/tdelete.texi @@ -11,6 +11,10 @@ Portability problems fixed by Gnulib: @item This function is missing on some platforms: mingw, BeOS. +@item +@code{tdelete} returns @code{NULL} when removing the last element of a tree +on some platforms: +OpenBSD 4.0. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/search.in.h b/lib/search.in.h index de94d367f..6ab763dac 100644 --- a/lib/search.in.h +++ b/lib/search.in.h @@ -1,6 +1,6 @@ /* A GNU-like . - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,12 +35,19 @@ extern "C" { #if @GNULIB_TSEARCH@ -# if !@HAVE_TSEARCH@ +# if @REPLACE_TSEARCH@ +# define tsearch rpl_tsearch +# define tfind rpl_tfind +# define tdelete rpl_tdelete +# define twalk rpl_twalk +# endif +# if !@HAVE_TSEARCH@ || @REPLACE_TSEARCH@ /* See , for details. */ +# if !@HAVE_TSEARCH@ typedef enum { preorder, @@ -49,6 +56,7 @@ typedef enum leaf } VISIT; +# endif /* Searches an element in the tree *VROOTP that compares equal to KEY. If one is found, it is returned. Otherwise, a new element equal to KEY diff --git a/m4/search_h.m4 b/m4/search_h.m4 index 333d1b24c..a537e339b 100644 --- a/m4/search_h.m4 +++ b/m4/search_h.m4 @@ -1,5 +1,5 @@ -# search_h.m4 serial 2 -dnl Copyright (C) 2007 Free Software Foundation, Inc. +# search_h.m4 serial 3 +dnl Copyright (C) 2007-2008 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 with or without modifications, as long as this notice is preserved. @@ -27,5 +27,6 @@ AC_DEFUN([gl_SEARCH_H_DEFAULTS], [ GNULIB_TSEARCH=0; AC_SUBST([GNULIB_TSEARCH]) dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_TSEARCH=1; AC_SUBST([HAVE_TSEARCH]) + HAVE_TSEARCH=1; AC_SUBST([HAVE_TSEARCH]) + REPLACE_TSEARCH=0; AC_SUBST([REPLACE_TSEARCH]) ]) diff --git a/m4/tsearch.m4 b/m4/tsearch.m4 index 2a458f875..0281fb918 100644 --- a/m4/tsearch.m4 +++ b/m4/tsearch.m4 @@ -1,5 +1,5 @@ -# tsearch.m4 serial 2 -dnl Copyright (C) 2006-2007 Free Software Foundation, Inc. +# tsearch.m4 serial 3 +dnl Copyright (C) 2006-2008 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 with or without modifications, as long as this notice is preserved. @@ -8,7 +8,45 @@ AC_DEFUN([gl_FUNC_TSEARCH], [ AC_REQUIRE([gl_SEARCH_H_DEFAULTS]) AC_CHECK_FUNCS([tsearch]) - if test $ac_cv_func_tsearch = no; then + if test $ac_cv_func_tsearch = yes; then + dnl On OpenBSD 4.0, the return value of tdelete() is incorrect. + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether tdelete works], [gl_cv_func_tdelete_works], + [ + AC_TRY_RUN([ +#include +#include +static int +cmp_fn (const void *a, const void *b) +{ + return *(const int *) a - *(const int *) b; +} +int +main () +{ + int x = 0; + void *root = NULL; + if (!(tfind (&x, &root, cmp_fn) == NULL)) return 1; + tsearch (&x, &root, cmp_fn); + if (!(tfind (&x, &root, cmp_fn) != NULL)) return 1; + if (!(tdelete (&x, &root, cmp_fn) != NULL)) return 1; + return 0; +}], [gl_cv_func_tdelete_works=yes], [gl_cv_func_tdelete_works=no], + [case "$host_os" in + openbsd*) gl_cv_func_tdelete_works="guessing no";; + *) gl_cv_func_tdelete_works="guessing yes";; + esac + ]) + ]) + case "$gl_cv_func_tdelete_works" in + *no) + REPLACE_TSEARCH=1 + AC_LIBOBJ([tsearch]) + gl_PREREQ_TSEARCH + ;; + esac + else HAVE_TSEARCH=0 AC_LIBOBJ([tsearch]) gl_PREREQ_TSEARCH diff --git a/modules/search b/modules/search index 0796bd7f4..186688443 100644 --- a/modules/search +++ b/modules/search @@ -25,6 +25,7 @@ search.h: search.in.h -e 's|@''NEXT_SEARCH_H''@|$(NEXT_SEARCH_H)|g' \ -e 's|@''GNULIB_TSEARCH''@|$(GNULIB_TSEARCH)|g' \ -e 's|@''HAVE_TSEARCH''@|$(HAVE_TSEARCH)|g' \ + -e 's|@''REPLACE_TSEARCH''@|$(REPLACE_TSEARCH)|g' \ -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ < $(srcdir)/search.in.h; \ } > $@-t -- 2.11.0