1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 * Glenn Fowler & Phong Vo
26 * common header and implementation for
28 * strtof strtod strtold _sfdscan
29 * strntof strntod strntold
31 * define these macros to instantiate an implementation:
33 * S2F_function the function name
34 * S2F_static <0:export =0:extern >0:static
35 * S2F_type 0:float 1:double 2:long.double
36 * S2F_qualifier 1 for optional [fFlL] qualifier suffix
37 * S2F_size 1 for interface with size_t second arg
38 * S2F_scan 1 for alternate interface with these arguments:
40 * int (*getchar)(void* handle, int flag)
41 * exactly one extra (*getchar)() is done, i.e.,
42 * the caller must do the pushback
43 * flag==0 get next char
44 * flag==1 no number seen
45 * return 0 on error or EOF
49 #include "FEATURE/float"
52 * the default is _sfdscan for standalone sfio compatibility
55 #if !defined(S2F_function)
56 #define S2F_function _sfdscan
61 #define elementsof(a) (sizeof(a)/sizeof(a[0]))
65 #if S2F_type == 2 && _ast_fltmax_double
71 #define S2F_number float
72 #define S2F_ldexp ldexp
73 #define S2F_pow10 _Sffpow10
74 #define S2F_inf _Sffinf
75 #define S2F_nan _Sffnan
76 #define S2F_min (FLT_MIN)
77 #define S2F_max (FLT_MAX)
78 #define S2F_exp_10_min (FLT_MIN_10_EXP)
79 #define S2F_exp_10_max (FLT_MAX_10_EXP)
80 #define S2F_exp_2_min (FLT_MIN_EXP)
81 #define S2F_exp_2_max (FLT_MAX_EXP)
84 #define S2F_number double
85 #define S2F_ldexp ldexp
86 #define S2F_pow10 _Sfdpow10
87 #define S2F_inf _Sfdinf
88 #define S2F_nan _Sfdnan
89 #define S2F_min (DBL_MIN)
90 #define S2F_max (DBL_MAX)
91 #define S2F_exp_10_min (DBL_MIN_10_EXP)
92 #define S2F_exp_10_max (DBL_MAX_10_EXP)
93 #define S2F_exp_2_min (DBL_MIN_EXP)
94 #define S2F_exp_2_max (DBL_MAX_EXP)
97 #define S2F_number long double
98 #define S2F_ldexp ldexpl
99 #define S2F_pow10 _Sflpow10
100 #define S2F_inf _Sflinf
101 #define S2F_nan _Sflnan
102 #define S2F_min (LDBL_MIN)
103 #define S2F_max (LDBL_MAX)
104 #define S2F_exp_10_min (LDBL_MIN_10_EXP)
105 #define S2F_exp_10_max (LDBL_MAX_10_EXP)
106 #define S2F_exp_2_min (LDBL_MIN_EXP)
107 #define S2F_exp_2_max (LDBL_MAX_EXP)
110 #if -S2F_exp_10_min < S2F_exp_10_max
111 #define S2F_exp_10_abs (-S2F_exp_10_min)
113 #define S2F_exp_10_abs S2F_exp_10_max
116 #define S2F_batch _ast_flt_unsigned_max_t
118 #undef ERR /* who co-opted this namespace? */
122 typedef int (*S2F_get_f
)_ARG_((void*, int));
125 #define GET(p) (*get)(p,0)
126 #define NON(p) (*get)(p,1)
133 #define ERR(e) (errno=(e))
137 #define GET(p) (((p)<(z))?(*p++):(back=0))
138 #define PUT(p) (end?(*end=(char*)p-back):(char*)0)
139 #define REV(p,t,b) (p=t,back=b)
140 #define SET(p,t,b) (t=p,b=back)
142 #define GET(p) (*p++)
143 #define PUT(p) (end?(*end=(char*)p-1):(char*)0)
144 #define REV(p,t,b) (p=t)
145 #define SET(p,t,b) (t=p)
150 typedef struct S2F_part_s
157 #define ERANGE EINVAL
163 #if S2F_static < 0 || !defined(S2F_static)
164 #if defined(__EXPORT__)
165 #define extern __EXPORT__
174 S2F_function(void* s
, S2F_get_f get
)
176 S2F_function(s
, get
) void* s
; S2F_get_f get
;
181 S2F_function(const char* str
, size_t size
, char** end
)
183 S2F_function(str
, size
, end
) char* str
; size_t size
; char** end
;
187 S2F_function(const char* str
, char** end
)
189 S2F_function(str
, end
) char* str
; char** end
;
195 register unsigned char* s
= (unsigned char*)str
;
197 register unsigned char* z
= s
+ size
;
203 register S2F_batch n
;
207 register unsigned char* cv
;
216 S2F_part_t parts
[16];
219 * radix char and thousands separator are locale specific
222 SFSETLOCALE(&decimal
, &thousand
);
226 * skip initial blanks
229 do c
= GET(s
); while (isspace(c
));
236 if ((negative
= (c
== '-')) || c
== '+')
248 if (c
== 'x' || c
== 'X')
251 * hex floating point -- easy
259 if ((part
= cv
[c
]) < 16)
265 else if (c
== decimal
)
274 if (c
== 'p' || c
== 'P')
277 if ((enegative
= c
== '-') || c
== '+')
279 while (c
>= '0' && c
<= '9')
281 m
= (m
<< 3) + (m
<< 1) + (c
- '0');
291 * consume the optional suffix
306 return negative
? -v
: v
;
308 m
-= 4 * (digits
- fraction
);
309 if (m
< S2F_exp_2_min
)
311 if ((m
-= S2F_exp_2_min
) < S2F_exp_2_min
)
316 v
= S2F_ldexp(v
, S2F_exp_2_min
);
318 else if (m
> S2F_exp_2_max
)
321 return negative
? -S2F_inf
: S2F_inf
;
329 else if (c
== decimal
)
341 else if (c
== 'i' || c
== 'I')
343 if ((c
= GET(s
)) != 'n' && c
!= 'N' ||
344 (c
= GET(s
)) != 'f' && c
!= 'F')
352 if (((c
) == 'i' || c
== 'I') &&
353 ((c
= GET(s
)) == 'n' || c
== 'N') &&
354 ((c
= GET(s
)) == 'i' || c
== 'I') &&
355 ((c
= GET(s
)) == 't' || c
== 'T') &&
356 ((c
= GET(s
)) == 'y' || c
== 'Y'))
363 return negative
? -S2F_inf
: S2F_inf
;
365 else if (c
== 'n' || c
== 'N')
367 if ((c
= GET(s
)) != 'a' && c
!= 'A' ||
368 (c
= GET(s
)) != 'n' && c
!= 'N')
374 do c
= GET(s
); while (c
&& !isspace(c
));
376 return negative
? -S2F_nan
: S2F_nan
;
378 else if (c
< '1' || c
> '9')
387 * consume the integral and fractional parts
394 if (c
>= '0' && c
<= '9')
397 n
= (n
<< 3) + (n
<< 1) + (c
- '0');
398 if (n
>= ((~((S2F_batch
)0)) / 10) && part
< elementsof(parts
))
400 parts
[part
].batch
= n
;
402 parts
[part
].digits
= digits
;
406 else if (m
&& (digits
- m
) != 3)
408 else if (c
== decimal
)
415 else if (c
!= thousand
)
417 else if (!(m
= digits
))
423 * don't forget the last part
426 if (n
&& part
< elementsof(parts
))
428 parts
[part
].batch
= n
;
429 parts
[part
].digits
= digits
;
434 * consume the exponent
439 if (c
== 'e' || c
== 'E')
442 if ((enegative
= (c
== '-')) || c
== '+')
445 while (c
>= '0' && c
<= '9')
447 n
= (n
<< 3) + (n
<< 1) + (c
- '0');
459 * consume the optional suffix
475 * adjust for at most one multiply per part
476 * and at most one divide overall
481 return negative
? -v
: v
;
482 else if ((m
= parts
[part
-1].digits
- digits
) > 0)
493 p
= parts
[part
].batch
;
494 c
= digits
- parts
[part
].digits
;
495 if (c
> S2F_exp_10_max
)
498 return negative
? -S2F_inf
: S2F_inf
;
502 #if _ast_mpy_overflow_fpe
503 if ((S2F_max
/ p
) < S2F_pow10
[c
])
506 return negative
? -S2F_inf
: S2F_inf
;
515 while (m
> S2F_exp_10_max
)
518 v
/= S2F_pow10
[S2F_exp_10_max
];
520 #if _ast_div_underflow_fpe
521 if ((S2F_min
* p
) > S2F_pow10
[c
])
524 return negative
? -S2F_inf
: S2F_inf
;
540 else if (v
> S2F_max
)
550 return negative
? -v
: v
;