md5, sha1, sha256, sha512: add gl_SET_CRYPTO_CHECK_DEFAULT
[gnulib.git] / m4 / strtod.m4
index 6b2d731..06ba60f 100644 (file)
@@ -1,5 +1,5 @@
-# strtod.m4 serial 13
-dnl Copyright (C) 2002-2003, 2006-2010 Free Software Foundation, Inc.
+# strtod.m4 serial 22
+dnl Copyright (C) 2002-2003, 2006-2013 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.
@@ -7,13 +7,18 @@ dnl with or without modifications, as long as this notice is preserved.
 AC_DEFUN([gl_FUNC_STRTOD],
 [
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
-  AC_FUNC_STRTOD
-  dnl Note: AC_FUNC_STRTOD does AC_LIBOBJ([strtod]).
-  if test $ac_cv_func_strtod = no; then
-    HAVE_STRTOD=0
-    REPLACE_STRTOD=1
-    gl_PREREQ_STRTOD
-  else
+  m4_ifdef([gl_FUNC_STRTOD_OBSOLETE], [
+    dnl Test whether strtod is declared.
+    dnl Don't call AC_FUNC_STRTOD, because it does not have the right guess
+    dnl when cross-compiling.
+    dnl Don't call AC_CHECK_FUNCS([strtod]) because it would collide with the
+    dnl ac_cv_func_strtod variable set by the AC_FUNC_STRTOD macro.
+    AC_CHECK_DECLS_ONCE([strtod])
+    if test $ac_cv_have_decl_strtod != yes; then
+      HAVE_STRTOD=0
+    fi
+  ])
+  if test $HAVE_STRTOD = 1; then
     AC_CACHE_CHECK([whether strtod obeys C99], [gl_cv_func_strtod_works],
       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
 #include <stdlib.h>
@@ -28,6 +33,25 @@ numeric_equal (double x, double y)
   return x == y;
 }
 ]], [[
+  int result = 0;
+  {
+    /* In some old versions of Linux (2000 or before), strtod mis-parses
+       strings with leading '+'.  */
+    const char *string = " +69";
+    char *term;
+    double value = strtod (string, &term);
+    if (value != 69 || term != (string + 4))
+      result |= 1;
+  }
+  {
+    /* Under Solaris 2.4, strtod returns the wrong value for the
+       terminating character under some conditions.  */
+    const char *string = "NaN";
+    char *term;
+    strtod (string, &term);
+    if (term != string && *(term - 1) == 0)
+      result |= 2;
+  }
   {
     /* Older glibc and Cygwin mis-parse "-0x".  */
     const char *string = "-0x";
@@ -35,7 +59,7 @@ numeric_equal (double x, double y)
     double value = strtod (string, &term);
     double zero = 0.0;
     if (1.0 / value != -1.0 / zero || term != (string + 2))
-      return 1;
+      result |= 4;
   }
   {
     /* Many platforms do not parse hex floats.  */
@@ -43,7 +67,7 @@ numeric_equal (double x, double y)
     char *term;
     double value = strtod (string, &term);
     if (value != 20.0 || term != (string + 6))
-      return 1;
+      result |= 8;
   }
   {
     /* Many platforms do not parse infinities.  HP-UX 11.31 parses inf,
@@ -54,7 +78,7 @@ numeric_equal (double x, double y)
     errno = 0;
     value = strtod (string, &term);
     if (value != HUGE_VAL || term != (string + 3) || errno)
-      return 1;
+      result |= 16;
   }
   {
     /* glibc 2.7 and cygwin 1.5.24 misparse "nan()".  */
@@ -62,7 +86,7 @@ numeric_equal (double x, double y)
     char *term;
     double value = strtod (string, &term);
     if (numeric_equal (value, value) || term != (string + 5))
-      return 1;
+      result |= 32;
   }
   {
     /* darwin 10.6.1 misparses "nan(".  */
@@ -70,21 +94,40 @@ numeric_equal (double x, double y)
     char *term;
     double value = strtod (string, &term);
     if (numeric_equal (value, value) || term != (string + 3))
-      return 1;
+      result |= 64;
   }
+  return result;
 ]])],
         [gl_cv_func_strtod_works=yes],
         [gl_cv_func_strtod_works=no],
-        [gl_cv_func_strtod_works="guessing no"])])
-    if test "$gl_cv_func_strtod_works" != yes; then
-      REPLACE_STRTOD=1
-      gl_PREREQ_STRTOD
-      dnl Use undocumented macro to set POW_LIB correctly.
-      _AC_LIBOBJ_STRTOD
-    fi
+        [dnl The last known bugs in glibc strtod(), as of this writing,
+         dnl were fixed in version 2.8
+         AC_EGREP_CPP([Lucky user],
+           [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) || (__GLIBC__ > 2)) \
+     && !defined __UCLIBC__
+  Lucky user
+ #endif
+#endif
+           ],
+           [gl_cv_func_strtod_works="guessing yes"],
+           [gl_cv_func_strtod_works="guessing no"])])])
+    case "$gl_cv_func_strtod_works" in
+      *yes) ;;
+      *)
+        REPLACE_STRTOD=1
+        ;;
+    esac
   fi
 ])
 
 # Prerequisites of lib/strtod.c.
-# The need for pow() is already handled by AC_FUNC_STRTOD.
-AC_DEFUN([gl_PREREQ_STRTOD], [:])
+AC_DEFUN([gl_PREREQ_STRTOD], [
+  AC_REQUIRE([gl_CHECK_LDEXP_NO_LIBM])
+  if test $gl_cv_func_ldexp_no_libm = yes; then
+    AC_DEFINE([HAVE_LDEXP_IN_LIBC], [1],
+      [Define if the ldexp function is available in libc.])
+  fi
+])