File: strtold.m4

package info (click to toggle)
coreutils 9.7-3
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 67,780 kB
  • sloc: ansic: 243,477; sh: 29,063; perl: 7,908; yacc: 1,858; makefile: 196; python: 47; sed: 16
file content (185 lines) | stat: -rw-r--r-- 6,005 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# strtold.m4
# serial 10
dnl Copyright (C) 2002-2003, 2006-2025 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.
dnl This file is offered as-is, without any warranty.

AC_DEFUN([gl_FUNC_STRTOLD],
[
  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
  AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  AC_CHECK_FUNCS_ONCE([strtold])
  if test $ac_cv_func_strtold != yes; then
    HAVE_STRTOLD=0
  else
    AC_CACHE_CHECK([whether strtold obeys POSIX], [gl_cv_func_strtold_works],
      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <errno.h>
#include <string.h>
/* Compare two numbers with ==.
   This is a separate function because IRIX 6.5 "cc -O" miscompiles an
   'x == x' test.  */
static int
numeric_equal (long double x, long double y)
{
  return x == y;
}
]], [[
  int result = 0;
  {
    /* Under Solaris 2.4, strtod returns the wrong value for the
       terminating character under some conditions.  */
    const char *string = "NaN";
    char *term;
    strtold (string, &term);
    if (term != string && *(term - 1) == 0)
      result |= 1;
  }
  {
    /* Older glibc and Cygwin mis-parse "-0x".  */
    const char *string = "-0x";
    char *term;
    long double value = strtold (string, &term);
    long double zero = 0.0L;
    if (1.0L / value != -1.0L / zero || term != (string + 2))
      result |= 2;
  }
  {
    /* IRIX 6.5, mingw do not parse hex floats.  */
    const char *string = "0XaP+1";
    char *term;
    long double value = strtold (string, &term);
    if (value != 20.0L || term != (string + 6))
      result |= 4;
  }
  {
    /* IRIX 6.5 does not parse infinities.  HP-UX 11.31/ia64 parses inf,
       but mistakenly sets errno.  */
    const char *string = "inf";
    char *term;
    long double value;
    errno = 0;
    value = strtold (string, &term);
    if (value != HUGE_VAL || term != (string + 3) || errno)
      result |= 8;
  }
  {
    /* glibc-2.3.2, IRIX 6.5, mingw, Haiku misparse "nan()".  */
    const char *string = "nan()";
    char *term;
    long double value = strtold (string, &term);
    if (numeric_equal (value, value) || term != (string + 5))
      result |= 16;
  }
  {
    /* Mac OS X 10.5, IRIX 6.5 misparse "nan(".  */
    const char *string = "nan(";
    char *term;
    long double value = strtold (string, &term);
    if (numeric_equal (value, value) || term != (string + 3))
      result |= 16;
  }
#ifndef _MSC_VER /* On MSVC, this is expected behaviour.  */
  {
    /* In Cygwin 2.9 and mingw 5.0, strtold does not set errno upon
       gradual underflow.  */
# if LDBL_MAX_EXP > 10000
    const char *string = "1e-4950";
# else
    const char *string = "1e-320";
# endif
    char *term;
    long double value;
    errno = 0;
    value = strtold (string, &term);
    if (term != (string + strlen (string))
        || (value > 0.0L && value <= LDBL_MIN && errno != ERANGE))
      result |= 32;
  }
#endif
  {
    /* In Cygwin 2.9, strtold does not set errno upon
       flush-to-zero underflow.  */
    const char *string = "1E-100000";
    char *term;
    long double value;
    errno = 0;
    value = strtold (string, &term);
    if (term != (string + 9) || (value == 0.0L && errno != ERANGE))
      result |= 64;
  }
  return result;
]])],
        [gl_cv_func_strtold_works=yes],
        [result=$?
         if expr $result '>=' 64 >/dev/null; then
           gl_cv_func_strtold_works="no (underflow problem)"
         else
           if expr $result '>=' 32 >/dev/null; then
             gl_cv_func_strtold_works="no (gradual underflow problem)"
           else
             gl_cv_func_strtold_works=no
           fi
         fi
        ],
        [dnl The last known bugs in glibc strtold(), 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_strtold_works="guessing yes"],
           [case "$host_os" in
                                  # Guess yes on musl systems.
              *-musl* | midipix*) gl_cv_func_strtold_works="guessing yes" ;;
                                  # Guess 'no (underflow problem)' on Cygwin.
              cygwin*)            gl_cv_func_strtold_works="guessing no (underflow problem)" ;;
                                  # Guess 'no (gradual underflow problem)' on mingw.
                                  # (Although the results may vary depending on
                                  # __USE_MINGW_ANSI_STDIO.)
              mingw* | windows*)  gl_cv_func_strtold_works="guessing no (gradual underflow problem)" ;;
              *)                  gl_cv_func_strtold_works="$gl_cross_guess_normal" ;;
            esac
           ])
        ])
      ])
    case "$gl_cv_func_strtold_works" in
      *yes) ;;
      *)
        REPLACE_STRTOLD=1
        case "$gl_cv_func_strtold_works" in
          *"no (underflow problem)")
            AC_DEFINE([STRTOLD_HAS_UNDERFLOW_BUG], [1],
              [Define to 1 if strtold does not set errno upon flush-to-zero underflow.])
            ;;
          *"no (gradual underflow problem)")
            AC_DEFINE([STRTOLD_HAS_GRADUAL_UNDERFLOW_PROBLEM], [1],
              [Define to 1 if strtold does not set errno upon gradual underflow.])
            ;;
        esac
        ;;
    esac
  fi
])

# Prerequisites of lib/strtold.c.
AC_DEFUN([gl_PREREQ_STRTOLD], [
  AC_REQUIRE([gl_CHECK_LDEXPL_NO_LIBM])
  if test $gl_cv_func_ldexpl_no_libm = yes; then
    AC_DEFINE([HAVE_LDEXPL_IN_LIBC], [1],
      [Define if the ldexpl function is available in libc.])
  fi
  gl_CHECK_FUNCS_ANDROID([nl_langinfo], [[#include <langinfo.h>]])
])