summaryrefslogtreecommitdiff
path: root/m4/ilogbl.m4
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2017-10-29 12:57:35 +0100
committerBruno Haible <bruno@clisp.org>2017-10-29 21:27:51 +0100
commit625f7aea332a6b43fd9be4ce91d805182a5feb0c (patch)
tree320a535d47d2207ff1f4b8550ce78a8ddd38c8aa /m4/ilogbl.m4
parent6065f427d616ccc578b38d92a5ef27bc4b6286ea (diff)
downloadgnulib-625f7aea332a6b43fd9be4ce91d805182a5feb0c.tar.gz
ilogbl: Ensure replacement on Haiku.
* m4/ilogbl.m4 (gl_FUNC_ILOGBL): Invoke gl_FUNC_ILOGBL_WORKS and set REPLACE_ILOGBL if ilogbl does not work. (gl_FUNC_ILOGBL_WORKS): New macro. * lib/math.in.h (ilogbl): Replace if REPLACE_ILOGBL is 1. * m4/math_h.m4 (gl_MATH_H_DEFAULTS): Initialize REPLACE_ILOGBL. * modules/math (Makefile.am): Substitute REPLACE_ILOGBL. * modules/ilogbl (Depends-on, configure.ac): Consider REPLACE_ILOGBL. * doc/posix-functions/ilogbl.texi: Mention the Haiku problem.
Diffstat (limited to 'm4/ilogbl.m4')
-rw-r--r--m4/ilogbl.m475
1 files changed, 74 insertions, 1 deletions
diff --git a/m4/ilogbl.m4 b/m4/ilogbl.m4
index 44556a9d1c..60cb14118e 100644
--- a/m4/ilogbl.m4
+++ b/m4/ilogbl.m4
@@ -1,4 +1,4 @@
-# ilogbl.m4 serial 1
+# ilogbl.m4 serial 2
dnl Copyright (C) 2010-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -36,8 +36,18 @@ AC_DEFUN([gl_FUNC_ILOGBL],
LIBS="$save_LIBS"
if test $gl_cv_func_ilogbl = yes; then
ILOGBL_LIBM="$ILOGB_LIBM"
+ save_LIBS="$LIBS"
+ LIBS="$LIBS $ILOGBL_LIBM"
+ gl_FUNC_ILOGBL_WORKS
+ LIBS="$save_LIBS"
+ case "$gl_cv_func_ilogbl_works" in
+ *yes) ;;
+ *) REPLACE_ILOGBL=1 ;;
+ esac
else
HAVE_ILOGBL=0
+ fi
+ if test $HAVE_ILOGBL = 0 || test $REPLACE_ILOGBL = 1; then
dnl Find libraries needed to link lib/ilogbl.c.
if test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 1; then
ILOGBL_LIBM="$ILOGB_LIBM"
@@ -59,3 +69,66 @@ AC_DEFUN([gl_FUNC_ILOGBL],
fi
AC_SUBST([ILOGBL_LIBM])
])
+
+dnl Test whether ilogbl() works.
+dnl On Haiku 2017, it returns i-2 instead of i-1 for values between
+dnl ca. 2^-16444 and ca. 2^-16382.
+AC_DEFUN([gl_FUNC_ILOGBL_WORKS],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether ilogbl works], [gl_cv_func_ilogbl_works],
+ [
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <float.h>
+#include <math.h>
+/* Override the values of <float.h>, like done in float.in.h. */
+#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__)
+# undef LDBL_MIN_EXP
+# define LDBL_MIN_EXP (-16381)
+#endif
+#if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__)
+# undef LDBL_MIN_EXP
+# define LDBL_MIN_EXP (-16381)
+#endif
+#if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__
+# undef LDBL_MIN_EXP
+# define LDBL_MIN_EXP DBL_MIN_EXP
+#endif
+#if defined __sgi && (LDBL_MANT_DIG >= 106)
+# if defined __GNUC__
+# undef LDBL_MIN_EXP
+# define LDBL_MIN_EXP DBL_MIN_EXP
+# endif
+#endif
+volatile long double x;
+static int dummy (long double x) { return 0; }
+int main (int argc, char *argv[])
+{
+ int (*my_ilogbl) (long double) = argc ? ilogbl : dummy;
+ int result = 0;
+ /* This test fails on Haiku 2017. */
+ {
+ int i;
+ for (i = 1, x = (long double)1.0; i >= LDBL_MIN_EXP-100 && x > (long double)0.0; i--, x *= (long double)0.5)
+ if (my_ilogbl (x) != i - 1)
+ {
+ result |= 1;
+ break;
+ }
+ }
+ return result;
+}
+]])],
+ [gl_cv_func_ilogbl_works=yes],
+ [gl_cv_func_ilogbl_works=no],
+ [case "$host_os" in
+ haiku*) gl_cv_func_ilogbl_works="guessing no" ;;
+ # Guess yes on native Windows.
+ mingw*) gl_cv_func_ilogbl_works="guessing yes" ;;
+ *) gl_cv_func_ilogbl_works="guessing yes" ;;
+ esac
+ ])
+ ])
+])