xstrtol: Improve documentation.
[gnulib.git] / m4 / strtold.m4
blob4439b602661d74b775aea1774512153411f6cceb
1 # strtold.m4
2 # serial 9
3 dnl Copyright (C) 2002-2003, 2006-2024 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
8 AC_DEFUN([gl_FUNC_STRTOLD],
10   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
11   AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
12   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
13   AC_CHECK_FUNCS_ONCE([strtold])
14   if test $ac_cv_func_strtold != yes; then
15     HAVE_STRTOLD=0
16   else
17     AC_CACHE_CHECK([whether strtold obeys POSIX], [gl_cv_func_strtold_works],
18       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
19 #include <stdlib.h>
20 #include <math.h>
21 #include <errno.h>
22 /* Compare two numbers with ==.
23    This is a separate function because IRIX 6.5 "cc -O" miscompiles an
24    'x == x' test.  */
25 static int
26 numeric_equal (long double x, long double y)
28   return x == y;
30 ]], [[
31   int result = 0;
32   {
33     /* Under Solaris 2.4, strtod returns the wrong value for the
34        terminating character under some conditions.  */
35     const char *string = "NaN";
36     char *term;
37     strtold (string, &term);
38     if (term != string && *(term - 1) == 0)
39       result |= 1;
40   }
41   {
42     /* Older glibc and Cygwin mis-parse "-0x".  */
43     const char *string = "-0x";
44     char *term;
45     long double value = strtold (string, &term);
46     long double zero = 0.0L;
47     if (1.0L / value != -1.0L / zero || term != (string + 2))
48       result |= 2;
49   }
50   {
51     /* IRIX 6.5, mingw do not parse hex floats.  */
52     const char *string = "0XaP+1";
53     char *term;
54     long double value = strtold (string, &term);
55     if (value != 20.0L || term != (string + 6))
56       result |= 4;
57   }
58   {
59     /* IRIX 6.5 does not parse infinities.  HP-UX 11.31/ia64 parses inf,
60        but mistakenly sets errno.  */
61     const char *string = "inf";
62     char *term;
63     long double value;
64     errno = 0;
65     value = strtold (string, &term);
66     if (value != HUGE_VAL || term != (string + 3) || errno)
67       result |= 8;
68   }
69   {
70     /* glibc-2.3.2, IRIX 6.5, mingw, Haiku misparse "nan()".  */
71     const char *string = "nan()";
72     char *term;
73     long double value = strtold (string, &term);
74     if (numeric_equal (value, value) || term != (string + 5))
75       result |= 16;
76   }
77   {
78     /* Mac OS X 10.5, IRIX 6.5 misparse "nan(".  */
79     const char *string = "nan(";
80     char *term;
81     long double value = strtold (string, &term);
82     if (numeric_equal (value, value) || term != (string + 3))
83       result |= 32;
84   }
85   {
86     /* In Cygwin 2.9, strtold does not set errno upon underflow.  */
87     const char *string = "1E-100000";
88     char *term;
89     long double value;
90     errno = 0;
91     value = strtold (string, &term);
92     if (term != (string + 9) || (value == 0.0L && errno != ERANGE))
93       result |= 64;
94   }
95   return result;
96 ]])],
97         [gl_cv_func_strtold_works=yes],
98         [if expr $? '>=' 64 >/dev/null; then
99            gl_cv_func_strtold_works="no (underflow problem)"
100          else
101            gl_cv_func_strtold_works=no
102          fi
103         ],
104         [dnl The last known bugs in glibc strtold(), as of this writing,
105          dnl were fixed in version 2.8
106          AC_EGREP_CPP([Lucky user],
107            [
108 #include <features.h>
109 #ifdef __GNU_LIBRARY__
110  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) || (__GLIBC__ > 2)) \
111      && !defined __UCLIBC__
112   Lucky user
113  #endif
114 #endif
115            ],
116            [gl_cv_func_strtold_works="guessing yes"],
117            [case "$host_os" in
118                                   # Guess yes on musl systems.
119               *-musl* | midipix*) gl_cv_func_strtold_works="guessing yes" ;;
120                                   # Guess 'no (underflow problem)' on Cygwin.
121               cygwin*)            gl_cv_func_strtold_works="guessing no (underflow problem)" ;;
122               *)                  gl_cv_func_strtold_works="$gl_cross_guess_normal" ;;
123             esac
124            ])
125         ])
126       ])
127     case "$gl_cv_func_strtold_works" in
128       *yes) ;;
129       *)
130         REPLACE_STRTOLD=1
131         case "$gl_cv_func_strtold_works" in
132           *"no (underflow problem)")
133             AC_DEFINE([STRTOLD_HAS_UNDERFLOW_BUG], [1],
134               [Define to 1 if strtold does not set errno upon underflow.])
135             ;;
136         esac
137         ;;
138     esac
139   fi
142 # Prerequisites of lib/strtold.c.
143 AC_DEFUN([gl_PREREQ_STRTOLD], [
144   AC_REQUIRE([gl_CHECK_LDEXPL_NO_LIBM])
145   if test $gl_cv_func_ldexpl_no_libm = yes; then
146     AC_DEFINE([HAVE_LDEXPL_IN_LIBC], [1],
147       [Define if the ldexpl function is available in libc.])
148   fi
149   gl_CHECK_FUNCS_ANDROID([nl_langinfo], [[#include <langinfo.h>]])