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.
This commit is contained in:
Evgeny Grin (Karlson2k)
2023-03-03 13:23:01 +03:00
parent 29311f4097
commit 677e6e431a
6 changed files with 122 additions and 142 deletions
+117 -7
View File
@@ -525,14 +525,124 @@ AC_CHECK_HEADERS([sys/msg.h sys/mman.h signal.h], [], [], [AC_INCLUDES_DEFAULT])
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 */
AM_CONDITIONAL([MHD_HAVE_TSEARCH], [[test "x$ac_cv_header_search_h" = xyes && test "x$HAVE_TSEARCH" = "x1" && test "x$REPLACE_TSEARCH" != "x1"]])
#include <stdio.h>
#include <search.h>
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
AC_CHECK_HEADERS([sys/sysctl.h netinet/ip_icmp.h netinet/icmp_var.h], [], [],
-66
View File
@@ -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])
])
-64
View File
@@ -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
View File
@@ -156,7 +156,7 @@ if USE_COVERAGE
AM_CFLAGS += --coverage
endif
if !MHD_HAVE_TSEARCH
if !MHD_USE_SYS_TSEARCH
libmicrohttpd2_la_SOURCES += \
tsearch.c tsearch.h
endif
+1 -1
View File
@@ -153,7 +153,7 @@ if USE_COVERAGE
AM_CFLAGS += --coverage
endif
if !MHD_HAVE_TSEARCH
if !MHD_USE_SYS_TSEARCH
libmicrohttpd_la_SOURCES += \
tsearch.c tsearch.h
endif
+3 -3
View File
@@ -47,11 +47,11 @@
#include "mhd_align.h"
#include "mhd_str.h"
#ifdef HAVE_SEARCH_H
#ifdef MHD_USE_SYS_TSEARCH
#include <search.h>
#else
#else /* ! MHD_USE_SYS_TSEARCH */
#include "tsearch.h"
#endif
#endif /* ! MHD_USE_SYS_TSEARCH */
#ifdef HTTPS_SUPPORT
#include "connection_https.h"