tools/gnulib: make tdestroy() fully portable
The tdestroy() function, which is a GNU extension to the standard C library, is defined in gnulib in tsearch.c but is missing it's corresponding declaration in search.in.h by being completely missing... This patch is large but upstreamable, including all of the macros and conditionals and configure checks that upstream GNU would expect for portable support, like using the @@ placeholder/substitution method to determine whether or not to have declarations based on whether or not tdestroy() is already declared within the standard headers of the default include paths. There were also some typedefs and aliases missing, along with the warnings and preprocessor exceptions that need to be added for consistency with the usage of the rest of the functions in the files. Tested-by: Georgi Valkov <gvalkov@gmail.com> # MacOS Signed-off-by: Michael Pratt <mcpratt@pm.me> Signed-off-by: Tony Ambardar <itugrok@yahoo.com>
This commit is contained in:
parent
5ade7ee60e
commit
eb726c90be
|
@ -0,0 +1,193 @@
|
|||
--- a/lib/search.in.h
|
||||
+++ b/lib/search.in.h
|
||||
@@ -112,6 +112,11 @@ _GL_CXXALIASWARN (lsearch);
|
||||
# define twalk rpl_twalk
|
||||
# endif
|
||||
# endif
|
||||
+# if @REPLACE_TDESTROY@
|
||||
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
+# define tdestroy rpl_tdestroy
|
||||
+# endif
|
||||
+# endif
|
||||
|
||||
/* See <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/search.h.html>
|
||||
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/tsearch.html>
|
||||
@@ -137,6 +142,7 @@ extern "C" {
|
||||
# if !GNULIB_defined_search_fn_types
|
||||
typedef int (*_gl_search_compar_fn) (const void *, const void *);
|
||||
typedef void (*_gl_search_action_fn) (const void *, VISIT, int);
|
||||
+typedef void (*_gl_search_free_fn) (void *);
|
||||
# define GNULIB_defined_search_fn_types 1
|
||||
# endif
|
||||
# ifdef __cplusplus
|
||||
@@ -252,9 +258,36 @@ _GL_CXXALIAS_SYS (twalk, void,
|
||||
_GL_CXXALIASWARN (twalk);
|
||||
# endif
|
||||
|
||||
+/* Removes the whole tree pointed to by root,
|
||||
+ freeing all resources allocated by the tsearch() function.
|
||||
+ The FREE_NODE function is called:
|
||||
+ - For the data in each tree node.
|
||||
+ - Even when no such work is necessary, to a function doing nothing
|
||||
+ The arguments passed to FREE_NODE are:
|
||||
+ 1. The pointer to the data. */
|
||||
+# if @REPLACE_TDESTROY@
|
||||
+_GL_FUNCDECL_RPL (tdestroy, void,
|
||||
+ (void *vroot, _gl_search_free_fn freefct)
|
||||
+ _GL_ARG_NONNULL ((2)));
|
||||
+_GL_CXXALIAS_RPL (tdestroy, void,
|
||||
+ (void *vroot, _gl_search_free_fn freefct));
|
||||
+# else
|
||||
+# if !@HAVE_TDESTROY@
|
||||
+_GL_FUNCDECL_SYS (tdestroy, void,
|
||||
+ (void *vroot, _gl_search_free_fn freefct)
|
||||
+ _GL_ARG_NONNULL ((2)));
|
||||
+# endif
|
||||
+_GL_CXXALIAS_SYS (tdestroy, void,
|
||||
+ (void *vroot, _gl_search_free_fn freefct));
|
||||
+# endif
|
||||
+# if __GLIBC__ >= 2
|
||||
+_GL_CXXALIASWARN (tdestroy);
|
||||
+# endif
|
||||
+
|
||||
/* Flags used by tsearch.c. */
|
||||
# define GNULIB_defined_tsearch (@REPLACE_TSEARCH@ || !@HAVE_TSEARCH@)
|
||||
# define GNULIB_defined_twalk (@REPLACE_TWALK@ || !@HAVE_TWALK@)
|
||||
+# define GNULIB_defined_tdestroy (@REPLACE_TDESTROY@ || !@HAVE_TDESTROY@)
|
||||
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef tsearch
|
||||
@@ -277,6 +310,11 @@ _GL_WARN_ON_USE (tdelete, "tdelete is un
|
||||
_GL_WARN_ON_USE (twalk, "twalk is unportable - "
|
||||
"use gnulib module tsearch for portability");
|
||||
# endif
|
||||
+# undef tdestroy
|
||||
+# if HAVE_RAW_DECL_TDESTROY
|
||||
+_GL_WARN_ON_USE (tdestroy, "tdestroy is unportable - "
|
||||
+ "use gnulib module tsearch for portability");
|
||||
+# endif
|
||||
#endif
|
||||
|
||||
|
||||
--- a/lib/tsearch.c
|
||||
+++ b/lib/tsearch.c
|
||||
@@ -98,12 +98,14 @@
|
||||
|
||||
typedef int (*__compar_fn_t) (const void *, const void *);
|
||||
typedef void (*__action_fn_t) (const void *, VISIT, int);
|
||||
+typedef void (*__free_fn_t) (void *);
|
||||
|
||||
#ifndef weak_alias
|
||||
# define __tsearch tsearch
|
||||
# define __tfind tfind
|
||||
# define __tdelete tdelete
|
||||
# define __twalk twalk
|
||||
+# define __tdestroy tdestroy
|
||||
#endif
|
||||
|
||||
#ifndef internal_function
|
||||
@@ -656,7 +658,7 @@ weak_alias (__twalk, twalk)
|
||||
#endif /* GNULIB_defined_twalk */
|
||||
|
||||
|
||||
-#ifdef _LIBC
|
||||
+#if defined(_LIBC) || GNULIB_defined_tdestroy
|
||||
|
||||
/* The standardized functions miss an important functionality: the
|
||||
tree cannot be removed easily. We provide a function to do this. */
|
||||
@@ -683,6 +685,8 @@ __tdestroy (void *vroot, __free_fn_t fre
|
||||
if (root != NULL)
|
||||
tdestroy_recurse (root, freefct);
|
||||
}
|
||||
+#ifdef weak_alias
|
||||
weak_alias (__tdestroy, tdestroy)
|
||||
+#endif
|
||||
|
||||
-#endif /* _LIBC */
|
||||
+#endif /* defined(_LIBC) || GNULIB_defined_tdestroy */
|
||||
--- a/m4/search_h.m4
|
||||
+++ b/m4/search_h.m4
|
||||
@@ -39,7 +39,7 @@ AC_DEFUN_ONCE([gl_SEARCH_H],
|
||||
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])
|
||||
+ ]], [tdelete tfind tsearch twalk tdestroy])
|
||||
|
||||
AC_REQUIRE([AC_C_RESTRICT])
|
||||
])
|
||||
@@ -75,8 +75,10 @@ AC_DEFUN([gl_SEARCH_H_DEFAULTS],
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LFIND], [1])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LSEARCH], [1])
|
||||
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])
|
||||
- REPLACE_TWALK=0; AC_SUBST([REPLACE_TWALK])
|
||||
+ HAVE_TSEARCH=1; AC_SUBST([HAVE_TSEARCH])
|
||||
+ HAVE_TWALK=1; AC_SUBST([HAVE_TWALK])
|
||||
+ HAVE_TDESTROY=1; AC_SUBST([HAVE_TDESTROY])
|
||||
+ REPLACE_TSEARCH=0; AC_SUBST([REPLACE_TSEARCH])
|
||||
+ REPLACE_TWALK=0; AC_SUBST([REPLACE_TWALK])
|
||||
+ REPLACE_TDESTROY=0; AC_SUBST([REPLACE_TDESTROY])
|
||||
])
|
||||
--- a/m4/tsearch.m4
|
||||
+++ b/m4/tsearch.m4
|
||||
@@ -9,6 +9,7 @@ AC_DEFUN([gl_FUNC_TSEARCH],
|
||||
AC_REQUIRE([gl_SEARCH_H_DEFAULTS])
|
||||
gl_CHECK_FUNCS_ANDROID([tsearch], [[#include <search.h>]])
|
||||
gl_CHECK_FUNCS_ANDROID([twalk], [[#include <search.h>]])
|
||||
+ gl_CHECK_FUNCS_ANDROID([tdestroy], [[#include <search.h>]])
|
||||
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])
|
||||
@@ -50,6 +51,7 @@ main ()
|
||||
*no)
|
||||
REPLACE_TSEARCH=1
|
||||
REPLACE_TWALK=1
|
||||
+ REPLACE_TDESTROY=1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
@@ -64,6 +66,12 @@ main ()
|
||||
future*) REPLACE_TWALK=1 ;;
|
||||
esac
|
||||
fi
|
||||
+ if test $ac_cv_func_tdestroy != yes; then
|
||||
+ HAVE_TDESTROY=0
|
||||
+ case "$gl_cv_onwards_func_tdestroy" in
|
||||
+ future*) REPLACE_TDESTROY=1 ;;
|
||||
+ esac
|
||||
+ fi
|
||||
])
|
||||
|
||||
# Prerequisites of lib/tsearch.c.
|
||||
--- a/modules/search
|
||||
+++ b/modules/search
|
||||
@@ -37,8 +37,10 @@ search.h: search.in.h $(top_builddir)/co
|
||||
-e 's/@''GNULIB_MDA_LSEARCH''@/$(GNULIB_MDA_LSEARCH)/g' \
|
||||
-e 's|@''HAVE_TSEARCH''@|$(HAVE_TSEARCH)|g' \
|
||||
-e 's|@''HAVE_TWALK''@|$(HAVE_TWALK)|g' \
|
||||
+ -e 's|@''HAVE_TDESTROY''@|$(HAVE_TDESTROY)|g' \
|
||||
-e 's|@''REPLACE_TSEARCH''@|$(REPLACE_TSEARCH)|g' \
|
||||
-e 's|@''REPLACE_TWALK''@|$(REPLACE_TWALK)|g' \
|
||||
+ -e 's|@''REPLACE_TDESTROY''@|$(REPLACE_TDESTROY)|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)' \
|
||||
--- a/modules/tsearch
|
||||
+++ b/modules/tsearch
|
||||
@@ -11,7 +11,12 @@ search
|
||||
configure.ac:
|
||||
gl_FUNC_TSEARCH
|
||||
gl_CONDITIONAL([GL_COND_OBJ_TSEARCH],
|
||||
- [test $HAVE_TSEARCH = 0 || test $HAVE_TWALK = 0 || test $REPLACE_TSEARCH = 1 || test $REPLACE_TWALK = 1])
|
||||
+ [test $HAVE_TSEARCH = 0 ||
|
||||
+ test $HAVE_TWALK = 0 ||
|
||||
+ test $HAVE_TDESTROY = 0 ||
|
||||
+ test $REPLACE_TSEARCH = 1 ||
|
||||
+ test $REPLACE_TWALK = 1 ||
|
||||
+ test $REPLACE_TDESTROY = 1])
|
||||
AM_COND_IF([GL_COND_OBJ_TSEARCH], [
|
||||
gl_PREREQ_TSEARCH
|
||||
])
|
Loading…
Reference in New Issue