]> Savannah Git Hosting - gnulib.git/commitdiff
c-strtod, c-strtold: Use the bug fixes for strtod, strtold.
authorBruno Haible <bruno@clisp.org>
Fri, 1 Feb 2019 03:34:37 +0000 (04:34 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 2 Feb 2019 01:03:02 +0000 (02:03 +0100)
* lib/stdlib.in.h (GNULIB_defined_strtod_function,
GNULIB_defined_strtold_function): New macros.
* lib/c-strtod.c (HAVE_GOOD_STRTOD_L): New macro.
(STRTOD): Ignore HAVE_C99_STRTOLD.
(c_locale): Don't define it on platforms where strtod_l/strtold_l is
deemed buggy. But do use it on platforms where uselocale exists and is
usable.
(C_STRTOD): Don't use STRTOD_L on platforms where strtod_l/strtold_l is
deemed buggy. On platforms where uselocale exists and is usable, use
uselocale and strtod/strtold.
* m4/c-strtod.m4 (gl_C99_STRTOLD): Remove macro.
(gl_C_STRTOD): Require gt_FUNC_USELOCALE.
(gl_C_STRTOLD): Likewise. Define HAVE_C99_STRTOLD unconditionally.
* modules/c-strtod (Files): Add m4/intl-thread-locale.m4.
(Depends-on): Add strtod.
* modules/c-strtold (Files): Add m4/intl-thread-locale.m4.
(Depends-on): Add strtold.

ChangeLog
lib/c-strtod.c
lib/stdlib.in.h
m4/c-strtod.m4
modules/c-strtod
modules/c-strtold

index 3dbab7af443089cf7dfd2b1e1e33e9139a99490f..963dedd66463a19dd08979f37cb902e2d32ba376 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2019-01-31  Bruno Haible  <bruno@clisp.org>
+
+       c-strtod, c-strtold: Use the bug fixes for strtod, strtold.
+       * lib/stdlib.in.h (GNULIB_defined_strtod_function,
+       GNULIB_defined_strtold_function): New macros.
+       * lib/c-strtod.c (HAVE_GOOD_STRTOD_L): New macro.
+       (STRTOD): Ignore HAVE_C99_STRTOLD.
+       (c_locale): Don't define it on platforms where strtod_l/strtold_l is
+       deemed buggy. But do use it on platforms where uselocale exists and is
+       usable.
+       (C_STRTOD): Don't use STRTOD_L on platforms where strtod_l/strtold_l is
+       deemed buggy. On platforms where uselocale exists and is usable, use
+       uselocale and strtod/strtold.
+       * m4/c-strtod.m4 (gl_C99_STRTOLD): Remove macro.
+       (gl_C_STRTOD): Require gt_FUNC_USELOCALE.
+       (gl_C_STRTOLD): Likewise. Define HAVE_C99_STRTOLD unconditionally.
+       * modules/c-strtod (Files): Add m4/intl-thread-locale.m4.
+       (Depends-on): Add strtod.
+       * modules/c-strtold (Files): Add m4/intl-thread-locale.m4.
+       (Depends-on): Add strtold.
+
 2019-01-31  Bruno Haible  <bruno@clisp.org>
 
        strtod, strtold: Use the locale's decimal point.
index b5f88bc007a8f28c4166299f14a977508d8d578e..53ae189d2894f737aa93178656762bbd0b646fa0 100644 (file)
 # define C_STRTOD c_strtold
 # define DOUBLE long double
 # define STRTOD_L strtold_l
+# define HAVE_GOOD_STRTOD_L (HAVE_STRTOLD_L && !GNULIB_defined_strtold_function)
+# define STRTOD strtold
 #else
 # define C_STRTOD c_strtod
 # define DOUBLE double
 # define STRTOD_L strtod_l
-#endif
-
-/* c_strtold falls back on strtod if strtold doesn't conform to C99.  */
-#if LONG && HAVE_C99_STRTOLD
-# define STRTOD strtold
-#else
+# define HAVE_GOOD_STRTOD_L (HAVE_STRTOD_L && !GNULIB_defined_strtod_function)
 # define STRTOD strtod
 #endif
 
-#if defined LC_ALL_MASK && (LONG ? HAVE_STRTOLD_L : HAVE_STRTOD_L)
+#if defined LC_ALL_MASK \
+    && ((LONG ? HAVE_GOOD_STRTOLD_L : HAVE_GOOD_STRTOD_L) \
+        || HAVE_WORKING_USELOCALE)
 
 /* Cache for the C locale object.
    Marked volatile so that different threads see the same value
@@ -67,7 +66,9 @@ C_STRTOD (char const *nptr, char **endptr)
 {
   DOUBLE r;
 
-#if defined LC_ALL_MASK && (LONG ? HAVE_STRTOLD_L : HAVE_STRTOD_L)
+#if defined LC_ALL_MASK \
+    && ((LONG ? HAVE_GOOD_STRTOLD_L : HAVE_GOOD_STRTOD_L) \
+        || HAVE_WORKING_USELOCALE)
 
   locale_t locale = c_locale ();
   if (!locale)
@@ -77,8 +78,30 @@ C_STRTOD (char const *nptr, char **endptr)
       return 0; /* errno is set here */
     }
 
+# if (LONG ? HAVE_GOOD_STRTOLD_L : HAVE_GOOD_STRTOD_L)
+
   r = STRTOD_L (nptr, endptr, locale);
 
+# else /* HAVE_WORKING_USELOCALE */
+
+  locale_t old_locale = uselocale (locale);
+  if (old_locale == (locale_t)0)
+    {
+      if (endptr)
+        *endptr = (char *) nptr;
+      return 0; /* errno is set here */
+    }
+
+  r = STRTOD (nptr, endptr);
+
+  int saved_errno = errno;
+  if (uselocale (old_locale) == (locale_t)0)
+    /* We can't switch back to the old locale.  The thread is hosed.  */
+    abort ();
+  errno = saved_errno;
+
+# endif
+
 #else
 
   char *saved_locale = setlocale (LC_NUMERIC, NULL);
index b70444d08331209bf274a27dce17cf06312de6d0..f829525c104f9cc19f9a9c403e84152f709704a1 100644 (file)
@@ -929,6 +929,7 @@ _GL_WARN_ON_USE (setenv, "setenv is unportable - "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define strtod rpl_strtod
 #  endif
+#  define GNULIB_defined_strtod_function 1
 _GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp)
                                   _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp));
@@ -954,6 +955,7 @@ _GL_WARN_ON_USE (strtod, "strtod is unportable - "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define strtold rpl_strtold
 #  endif
+#  define GNULIB_defined_strtold_function 1
 _GL_FUNCDECL_RPL (strtold, long double, (const char *str, char **endp)
                                         _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (strtold, long double, (const char *str, char **endp));
index 1694a2396c5b024ccf62f8c3613ef59a5e53e6be..1d4b7f860c929d9a7d4d650e7cba44fce656af60 100644 (file)
@@ -1,4 +1,4 @@
-# c-strtod.m4 serial 16
+# c-strtod.m4 serial 17
 
 # Copyright (C) 2004-2006, 2009-2019 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -7,36 +7,11 @@
 
 # Written by Paul Eggert.
 
-AC_DEFUN([gl_C99_STRTOLD],
-[
-  AC_CACHE_CHECK([whether strtold conforms to C99],
-    [gl_cv_func_c99_strtold],
-    [AC_LINK_IFELSE(
-       [AC_LANG_PROGRAM(
-          [[/* On HP-UX before 11.23, strtold returns a struct instead of
-                long double.  Reject implementations like that, by requiring
-                compatibility with the C99 prototype.  */
-             #include <stdlib.h>
-             static long double (*p) (char const *, char **) = strtold;
-             static long double
-             test (char const *nptr, char **endptr)
-             {
-               long double r;
-               r = strtold (nptr, endptr);
-               return r;
-             }]],
-           [[return test ("1.0", NULL) != 1 || p ("1.0", NULL) != 1;]])],
-       [gl_cv_func_c99_strtold=yes],
-       [gl_cv_func_c99_strtold=no])])
-  if test $gl_cv_func_c99_strtold = yes; then
-    AC_DEFINE([HAVE_C99_STRTOLD], [1], [Define to 1 if strtold conforms to C99.])
-  fi
-])
-
 dnl Prerequisites of lib/c-strtod.c.
 AC_DEFUN([gl_C_STRTOD],
 [
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_REQUIRE([gt_FUNC_USELOCALE])
 
   AC_CHECK_HEADERS_ONCE([xlocale.h])
   dnl We can't use AC_CHECK_FUNC here, because strtod_l() is defined as a
@@ -71,6 +46,8 @@ dnl Prerequisites of lib/c-strtold.c.
 AC_DEFUN([gl_C_STRTOLD],
 [
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
-  AC_REQUIRE([gl_C99_STRTOLD])
+  AC_REQUIRE([gt_FUNC_USELOCALE])
+  AC_DEFINE([HAVE_C99_STRTOLD], [1],
+    [Define to 1 because the gnulib 'strtold' module provides a C99-conforming strtold function.])
   AC_CHECK_FUNCS([strtold_l])
 ])
index 7999d45ee4133e029fa1599386c483dfe628f4b2..71b292ee7f8c177a6c2db3ab3bb219357052d774 100644 (file)
@@ -5,11 +5,13 @@ Files:
 lib/c-strtod.c
 lib/c-strtod.h
 m4/c-strtod.m4
+m4/intl-thread-locale.m4
 
 Depends-on:
 extensions
 locale
 strdup-posix
+strtod
 
 configure.ac:
 gl_C_STRTOD
index 72ff21dd18a26cf00b761bd9070de71ddf24ec7b..c7f31dba11a5bd46990b19ae15f2e209d795a72a 100644 (file)
@@ -6,11 +6,13 @@ lib/c-strtod.h
 lib/c-strtod.c
 lib/c-strtold.c
 m4/c-strtod.m4
+m4/intl-thread-locale.m4
 
 Depends-on:
 extensions
 locale
 strdup-posix
+strtold
 
 configure.ac:
 gl_C_STRTOLD