Przeglądaj źródła

configure: fixed checks for tsearch() and related

New check works correctly with new compilers.
Added known problematic implementations.
Added more checks for correct behaviour.
Removed some m4 macros.
Evgeny Grin (Karlson2k) 2 lat temu
rodzic
commit
677e6e431a
6 zmienionych plików z 122 dodań i 142 usunięć
  1. 117 7
      configure.ac
  2. 0 66
      m4/search_h.m4
  3. 0 64
      m4/tsearch.m4
  4. 1 1
      src/lib/Makefile.am
  5. 1 1
      src/microhttpd/Makefile.am
  6. 3 3
      src/microhttpd/daemon.c

+ 117 - 7
configure.ac

@@ -525,14 +525,124 @@ AC_CHECK_HEADERS([sys/msg.h sys/mman.h signal.h], [], [], [AC_INCLUDES_DEFAULT])
 
 
 AC_CHECK_HEADER([[search.h]],
 AC_CHECK_HEADER([[search.h]],
   [
   [
-   gl_FUNC_TSEARCH
-   AS_IF([[test "x$HAVE_TSEARCH" = "x1" && test "x$REPLACE_TSEARCH" != "x1"]],
-     [AC_DEFINE([[HAVE_SEARCH_H]], [[1]],
-       [Define to 1 if you have the <search.h> header file and your system have properly functioning tsearch(), tfind() and tdelete() functions])])
-  ],
-  [], [AC_INCLUDES_DEFAULT])
+    MHD_CHECK_LINK_RUN([[for proper tsearch(), tfind() and tdelete()]],[[mhd_cv_sys_tsearch_usable]],
+	  [
+	    AS_CASE([$host_os],
+	      [openbsd*],
+	      [[ # Some OpenBSD versions have wrong return value for tdelete()
+	        mhd_cv_sys_tsearch_usable='assuming no'
+	      ]],
+	      [netbsd*],
+	      [[ # NetBSD had leaked root node for years
+	        mhd_cv_sys_tsearch_usable='assuming no'
+	      ]],
+	      [[mhd_cv_sys_tsearch_usable='assuming yes']]
+	    )
+	  ],
+	  [
+	    AC_LANG_SOURCE(
+	      [[
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif /* HAVE_STDDEF_H */
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+#include <search.h>
 
 
-AM_CONDITIONAL([MHD_HAVE_TSEARCH], [[test "x$ac_cv_header_search_h" = xyes && test "x$HAVE_TSEARCH" = "x1" && test "x$REPLACE_TSEARCH" != "x1"]])
+static int cmp_func(const void *p1, const void *p2)
+{
+  return (*((const int *)p1)) - (*((const int *)p2));
+}
+
+int main(void)
+{
+  int ret = 0; 
+  void *root_ptr = NULL;
+  int element1 = 1;
+  int **element_ptr_ptr1;
+  int **element_ptr_ptr2;
+  
+  element_ptr_ptr1 =
+    (int **) tsearch ((void*) &element1, &root_ptr, &cmp_func);
+  if (NULL == element_ptr_ptr1)
+  {
+    fprintf (stderr, "NULL pointer has been returned when tsearch() called for the first time.\n");
+    return ++ret;
+  }
+  if (*element_ptr_ptr1 != &element1)
+  {
+    fprintf (stderr, "Wrong pointer has been returned when tsearch() called for the first time.\n");
+    return ++ret;
+  }
+  if (NULL == root_ptr)
+  {
+    fprintf (stderr, "Root pointer has not been set by tsearch().\n");
+    return ++ret;
+  }
+  
+  element_ptr_ptr2 =
+    (int **) tsearch ((void*) &element1, &root_ptr, &cmp_func);
+  if (NULL == element_ptr_ptr2)
+  {
+    fprintf (stderr, "NULL pointer has been returned when tsearch() called for the second time.\n");
+    return ++ret;
+  }
+  if (*element_ptr_ptr2 != &element1)
+  {
+    fprintf (stderr, "Wrong pointer has been returned when tsearch() called for the second time.\n");
+    ++ret;
+  }
+  if (element_ptr_ptr2 != element_ptr_ptr1)
+  {
+    fprintf (stderr, "Wrong element has been returned when tsearch() called for the second time.\n");
+    ++ret;
+  }
+  
+  element_ptr_ptr2 =
+    (int **) tfind ((void*) &element1, &root_ptr, &cmp_func);
+  if (NULL == element_ptr_ptr2)
+  {
+    fprintf (stderr, "NULL pointer has been returned by tfind().\n");
+    ++ret;
+  }
+  if (*element_ptr_ptr2 != &element1)
+  {
+    fprintf (stderr, "Wrong pointer has been returned when by tfind().\n");
+    ++ret;
+  }
+  if (element_ptr_ptr2 != element_ptr_ptr1)
+  {
+    fprintf (stderr, "Wrong element has been returned when tsearch() called for the second time.\n");
+    ++ret;
+  }
+  
+  element_ptr_ptr1 =
+    (int **) tdelete ((void*) &element1, &root_ptr, &cmp_func);
+  if (NULL == element_ptr_ptr1)
+  {
+    fprintf (stderr, "NULL pointer has been returned by tdelete().\n");
+    ++ret;
+  }
+  if (NULL != root_ptr)
+  {
+    fprintf (stderr, "Root pointer has not been set to NULL by tdelete().\n");
+    ++ret;
+  }
+  
+  return ret;
+}
+	      ]]
+	    )
+	  ],
+	  [AC_DEFINE([[MHD_USE_SYS_TSEARCH]], [[1]], [Define to 1 if you have properly working tsearch(), tfind() and tdelete() functions.])]
+	)
+  ],
+  [], [AC_INCLUDES_DEFAULT]
+)
+AM_CONDITIONAL([MHD_USE_SYS_TSEARCH], [[test "x$mhd_cv_sys_tsearch_usable" = "xyes" || test "x$mhd_cv_sys_tsearch_usable" = "xassuming yes"]])
 
 
 # Optional headers used for tests
 # Optional headers used for tests
 AC_CHECK_HEADERS([sys/sysctl.h netinet/ip_icmp.h netinet/icmp_var.h], [], [],
 AC_CHECK_HEADERS([sys/sysctl.h netinet/ip_icmp.h netinet/icmp_var.h], [], [],

+ 0 - 66
m4/search_h.m4

@@ -1,66 +0,0 @@
-# search_h.m4 serial 12
-dnl Copyright (C) 2007-2021 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.
-
-AC_DEFUN([gl_SEARCH_H],
-[
-  AC_REQUIRE([gl_SEARCH_H_DEFAULTS])
-  gl_CHECK_NEXT_HEADERS([search.h])
-  if test $ac_cv_header_search_h = yes; then
-    HAVE_SEARCH_H=1
-  else
-    HAVE_SEARCH_H=0
-  fi
-  AC_SUBST([HAVE_SEARCH_H])
-
-  if test $HAVE_SEARCH_H = 1; then
-    AC_CACHE_CHECK([for type VISIT], [gl_cv_type_VISIT],
-      [AC_COMPILE_IFELSE(
-         [AC_LANG_PROGRAM(
-            [[#if HAVE_SEARCH_H
-               #include <search.h>
-              #endif
-            ]],
-            [[static VISIT x; x = postorder;]])],
-         [gl_cv_type_VISIT=yes],
-         [gl_cv_type_VISIT=no])])
-  else
-    gl_cv_type_VISIT=no
-  fi
-  if test $gl_cv_type_VISIT = yes; then
-    HAVE_TYPE_VISIT=1
-  else
-    HAVE_TYPE_VISIT=0
-  fi
-  AC_SUBST([HAVE_TYPE_VISIT])
-
-  dnl Check for declarations of anything we want to poison if the
-  dnl corresponding gnulib module is not in use.
-  gl_WARN_ON_USE_PREPARE([[#include <search.h>
-    ]], [tdelete tfind tsearch twalk])
-
-  AC_REQUIRE([AC_C_RESTRICT])
-])
-
-AC_DEFUN([gl_SEARCH_MODULE_INDICATOR],
-[
-  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
-  AC_REQUIRE([gl_SEARCH_H_DEFAULTS])
-  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
-  dnl Define it also as a C macro, for the benefit of the unit tests.
-  gl_MODULE_INDICATOR_FOR_TESTS([$1])
-])
-
-AC_DEFUN([gl_SEARCH_H_DEFAULTS],
-[
-  GNULIB_TSEARCH=0; AC_SUBST([GNULIB_TSEARCH])
-  dnl Support Microsoft deprecated alias function names by default.
-  GNULIB_MDA_LFIND=1;   AC_SUBST([GNULIB_MDA_LFIND])
-  GNULIB_MDA_LSEARCH=1; AC_SUBST([GNULIB_MDA_LSEARCH])
-  dnl Assume proper GNU behavior unless another module says otherwise.
-  HAVE_TSEARCH=1;    AC_SUBST([HAVE_TSEARCH])
-  HAVE_TWALK=1;      AC_SUBST([HAVE_TWALK])
-  REPLACE_TSEARCH=0; AC_SUBST([REPLACE_TSEARCH])
-])

+ 0 - 64
m4/tsearch.m4

@@ -1,64 +0,0 @@
-# tsearch.m4 serial 8
-dnl Copyright (C) 2006-2021 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.
-
-AC_DEFUN([gl_FUNC_TSEARCH],
-[
-  AC_REQUIRE([gl_SEARCH_H_DEFAULTS])
-  AC_CHECK_FUNCS([tsearch twalk])
-  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_RUN_IFELSE([AC_LANG_SOURCE([[
-#include <stddef.h>
-#include <search.h>
-static int
-cmp_fn (const void *a, const void *b)
-{
-  return *(const int *) a - *(const int *) b;
-}
-int
-main ()
-{
-  int result = 0;
-  int x = 0;
-  void *root = NULL;
-  if (!(tfind (&x, &root, cmp_fn) == NULL))
-    result |= 1;
-  tsearch (&x, &root, cmp_fn);
-  if (!(tfind (&x, &root, cmp_fn) != NULL))
-    result |= 2;
-  if (!(tdelete (&x, &root, cmp_fn) != NULL))
-    result |= 4;
-  return result;
-}]])], [gl_cv_func_tdelete_works=yes], [gl_cv_func_tdelete_works=no],
-            [case "$host_os" in
-               openbsd*) gl_cv_func_tdelete_works="guessing no" ;;
-                         # Guess yes on native Windows.
-               mingw*)   gl_cv_func_tdelete_works="guessing yes" ;;
-               *)        gl_cv_func_tdelete_works="guessing yes" ;;
-             esac
-            ])
-      ])
-    case "$gl_cv_func_tdelete_works" in
-      *no)
-        REPLACE_TSEARCH=1
-        ;;
-    esac
-  else
-    HAVE_TSEARCH=0
-  fi
-  if test $ac_cv_func_twalk != yes; then
-    HAVE_TWALK=0
-  fi
-])
-
-# Prerequisites of lib/tsearch.c.
-AC_DEFUN([gl_PREREQ_TSEARCH], [
-  :
-])

+ 1 - 1
src/lib/Makefile.am

@@ -156,7 +156,7 @@ if USE_COVERAGE
   AM_CFLAGS += --coverage
   AM_CFLAGS += --coverage
 endif
 endif
 
 
-if !MHD_HAVE_TSEARCH
+if !MHD_USE_SYS_TSEARCH
 libmicrohttpd2_la_SOURCES += \
 libmicrohttpd2_la_SOURCES += \
   tsearch.c tsearch.h
   tsearch.c tsearch.h
 endif
 endif

+ 1 - 1
src/microhttpd/Makefile.am

@@ -153,7 +153,7 @@ if USE_COVERAGE
   AM_CFLAGS += --coverage
   AM_CFLAGS += --coverage
 endif
 endif
 
 
-if !MHD_HAVE_TSEARCH
+if !MHD_USE_SYS_TSEARCH
 libmicrohttpd_la_SOURCES += \
 libmicrohttpd_la_SOURCES += \
   tsearch.c tsearch.h
   tsearch.c tsearch.h
 endif
 endif

+ 3 - 3
src/microhttpd/daemon.c

@@ -47,11 +47,11 @@
 #include "mhd_align.h"
 #include "mhd_align.h"
 #include "mhd_str.h"
 #include "mhd_str.h"
 
 
-#ifdef HAVE_SEARCH_H
+#ifdef MHD_USE_SYS_TSEARCH
 #include <search.h>
 #include <search.h>
-#else
+#else  /* ! MHD_USE_SYS_TSEARCH */
 #include "tsearch.h"
 #include "tsearch.h"
-#endif
+#endif /* ! MHD_USE_SYS_TSEARCH */
 
 
 #ifdef HTTPS_SUPPORT
 #ifdef HTTPS_SUPPORT
 #include "connection_https.h"
 #include "connection_https.h"