1 /* Copyright (c) 2002,2004,2005 Joerg Wunsch
2 Copyright (c) 2008 Dmitry Xmelkov
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the
14 distribution.
15
16 * Neither the name of the copyright holders nor the names of
17 contributors may be used to endorse or promote products derived
18 from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 static const char pstr_nfinity[] = "nfinity";
34 static const char pstr_an[] = "an";
35
36 #if defined(STRTOD) || defined(STRTOF) || defined(STRTOLD)
37 # define CHECK_WIDTH() 1
38 # define CHECK_RANGE(flt) do { \
39 int __class = fpclassify(flt); \
40 if (__class == FP_INFINITE || __class == FP_SUBNORMAL || __class == FP_ZERO) \
41 errno = ERANGE; \
42 } while (0);
43 # ifdef _WANT_IO_C99_FORMATS
44 # define _NEED_IO_C99_FORMATS
45 # endif
46 # if defined(STRTOD)
47 # define _NEED_IO_DOUBLE
48 # define SCANF_LEVEL SCANF_DBL
49 # define CHECK_LONG() 1
50 # define CHECK_LONG_LONG() 0
51 # elif defined(STRTOLD)
52 # define _NEED_IO_LONG_DOUBLE
53 # define SCANF_LEVEL SCANF_DBL
54 # define CHECK_LONG() 0
55 # define CHECK_LONG_LONG() 1
56 # elif defined(STRTOF)
57 # define _NEED_IO_FLOAT
58 # define SCANF_LEVEL SCANF_FLT
59 # define CHECK_LONG() 0
60 # define CHECK_LONG_LONG() 0
61 # endif
62
63 #define FLT_STREAM const char
64
scanf_getc(const char * s,int * lenp)65 static inline int scanf_getc(const char *s, int *lenp)
66 {
67 int l = *lenp;
68 int c = s[l];
69 *lenp = l + 1;
70 return c;
71 }
72
scanf_ungetc(int c,const char * s,int * lenp)73 static inline void scanf_ungetc(int c, const char *s, int *lenp)
74 {
75 (void) c;
76 (void) s;
77 *lenp = *lenp - 1;
78 }
79
80 #undef EOF
81 #define EOF -1
82
83 #else
84
85 # define CHECK_WIDTH() (--width != 0)
86 # define CHECK_RANGE(flt)
87
88 # ifdef _NEED_IO_FLOAT
89
90 # define CHECK_LONG() 0
91 # define CHECK_LONG_LONG() 0
92
93 # elif defined(_NEED_IO_DOUBLE)
94
95 # ifdef _NEED_IO_LONG_DOUBLE
96 # define CHECK_LONG() (flags & FL_LONG)
97 # define CHECK_LONG_LONG() (flags & FL_LONGLONG)
98 # else
99 # define CHECK_LONG() (flags & (FL_LONG|FL_LONGLONG))
100 # define CHECK_LONG_LONG() 0
101 # endif
102 # else
103 # define CHECK_LONG() 0
104 # define CHECK_LONG_LONG() 0
105 # endif
106 #endif
107
108 #include "scanf_private.h"
109
110 #include "dtoa.h"
111
112 #ifdef _NEED_IO_LONG_DOUBLE
113 # define FLOAT long double
114 # define FLOAT_MIN __LDBL_MIN__
115 # define FLOAT_MANT_DIG __LDBL_MANT_DIG__
116 # define FLOAT_MAX_EXP __LDBL_MAX_EXP__
117 # define FLOAT_MIN_EXP __LDBL_MIN_EXP__
118 # define ASFLOAT(x) aslongdouble(x)
119 # if __SIZEOF_LONG_DOUBLE__ > 8
120 # define TOFLOAT(x) _u128_to_ld(x)
121 # define UINTFLOAT _u128
122 # elif __SIZEOF_LONG_DOUBLE__ == 8
123 # define TOFLOAT(x) ((long double) (x))
124 # define UINTFLOAT uint64_t
125 # elif __SIZEOF_LONG_DOUBLE__ == 4
126 # define TOFLOAT(x) ((long double) (x))
127 # define UINTFLOAT uint32_t
128 # endif
129 #elif defined(_NEED_IO_DOUBLE)
130 # define FLOAT double
131 # define FLOAT_MIN __DBL_MIN__
132 # define FLOAT_MANT_DIG __DBL_MANT_DIG__
133 # define FLOAT_MAX_EXP __DBL_MAX_EXP__
134 # define FLOAT_MIN_EXP __DBL_MIN_EXP__
135 # define ASFLOAT(x) _asdouble(x)
136 # define TOFLOAT(x) ((double) (x))
137 # if __SIZEOF_DOUBLE__ == 4
138 # define UINTFLOAT uint32_t
139 # elif __SIZEOF_DOUBLE__ == 8
140 # define UINTFLOAT uint64_t
141 # endif
142 #elif defined(_NEED_IO_FLOAT)
143 # define FLOAT float
144 # define FLOAT_MIN __FLT_MIN__
145 # define FLOAT_MANT_DIG __FLT_MANT_DIG__
146 # define FLOAT_MAX_EXP __FLT_MAX_EXP__
147 # define FLOAT_MIN_EXP __FLT_MIN_EXP__
148 # define ASFLOAT(x) _asfloat(x)
149 # define TOFLOAT(x) ((float) (x))
150 # define UINTFLOAT uint32_t
151 #endif
152
153 #if FLOAT_MANT_DIG > 53
154 #define U32_TO_UF(x) to_u128(x)
155 #define U64_TO_UF(x) to_u128(x)
156 #define U128_TO_UF(x) (x)
157 #define UF_TO_U32(x) from_u128(x)
158 #define UF_TO_U64(x) from_u128(x)
159 #define UF_TO_U128(x) (x)
160 #define UF_IS_ZERO(x) _u128_is_zero(x)
161 #define UF_TIMES_BASE(a,b) _u128_times_base(a,b)
162 #define UF_PLUS_DIGIT(a,b) _u128_plus_64(a,b)
163 #define UF_RSHIFT(a,b) _u128_rshift(a,b)
164 #define UF_LSHIFT(a,b) _u128_lshift(a,b)
165 #define UF_LSHIFT_64(a,b) _u128_lshift_64(a,b)
166 #define UF_LT(a,b) _u128_lt(a,b)
167 #define UF_GE(a,b) _u128_ge(a,b)
168 #define UF_OR_64(a,b) _u128_or_64(a,b)
169 #define UF_AND_64(a,b) _u128_and_64(a,b)
170 #define UF_AND(a,b) _u128_and(a,b)
171 #define UF_NOT(a) _u128_not(a)
172 #define UF_OR(a,b) _u128_or(a,b)
173 #else
174 #define U32_TO_UF(x) (x)
175 #define U64_TO_UF(x) (x)
176 #define U128_TO_UF(x) from_u128(x)
177 #define UF_TO_U32(x) (x)
178 #define UF_TO_U64(x) (x)
179 #define UF_TO_U128(x) to_u128(x)
180 #define UF_IS_ZERO(x) ((x) == 0)
181 #define UF_TIMES_BASE(a,b) ((a) * (b))
182 #define UF_PLUS_DIGIT(a,b) ((a) + (b))
183 #define UF_RSHIFT(a,b) ((a) >> (b))
184 #define UF_LSHIFT(a,b) ((a) << (b))
185 #define UF_LSHIFT_64(a,b) ((UINTFLOAT) (a) << (b))
186 #define UF_LT(a,b) ((a) < (b))
187 #define UF_GE(a,b) ((a) >= (b))
188 #define UF_OR_64(a,b) ((a) | (b))
189 #define UF_AND_64(a,b) ((a) & (b))
190 #define UF_AND(a,b) ((a) & (b))
191 #define UF_NOT(a) (~(a))
192 #define UF_OR(a,b) ((a) | (b))
193 #endif
194
195 static unsigned char
conv_flt(FLT_STREAM * stream,int * lenp,width_t width,void * addr,uint16_t flags)196 conv_flt (FLT_STREAM *stream, int *lenp, width_t width, void *addr, uint16_t flags)
197 {
198 UINTFLOAT uint;
199 unsigned int overflow = 0;
200 int uintdigits = 0;
201 FLOAT flt;
202 int i;
203 const char *p;
204 int exp;
205
206 i = scanf_getc (stream, lenp); /* after scanf_ungetc() */
207
208 switch ((unsigned char)i) {
209 case '-':
210 flags |= FL_MINUS;
211 __PICOLIBC_FALLTHROUGH;
212 case '+':
213 if (!CHECK_WIDTH() || (i = scanf_getc (stream, lenp)) < 0)
214 return 0;
215 }
216
217 switch (TOLOWER (i)) {
218 case 'n':
219 p = pstr_an;
220 flt = (FLOAT) NAN;
221 goto operate_pstr;
222
223 case 'i':
224 p = pstr_nfinity;
225 flt = (FLOAT) INFINITY;
226 operate_pstr:
227 {
228 unsigned char c;
229
230 while ((c = *p++) != 0) {
231 if (CHECK_WIDTH()) {
232 if ((i = scanf_getc (stream, lenp)) >= 0) {
233 if (TOLOWER(i) == c)
234 continue;
235 scanf_ungetc (i, stream, lenp);
236 }
237 if (p == pstr_nfinity + 3)
238 break;
239 return 0;
240 }
241 }
242 }
243 break;
244
245 default:
246 exp = 0;
247 uint = U32_TO_UF(0);
248 #define uintdigitsmax_10_float 8
249 #define uintdigitsmax_16_float 7
250 #if __SIZEOF_DOUBLE__ == 8
251 #define uintdigitsmax_10_double 16
252 #define uintdigitsmax_16_double 15
253 #elif __SIZEOF_DOUBLE__ ==4
254 #define uintdigitsmax_10_double 8
255 #define uintdigitsmax_16_double 7
256 #endif
257 #if __SIZEOF_LONG_DOUBLE__ > 8
258 #define uintdigitsmax_10_long_double 32
259 #define uintdigitsmax_16_long_double 30
260 #elif __SIZEOF_LONG_DOUBLE__ == 8
261 #define uintdigitsmax_10_long_double 16
262 #define uintdigitsmax_16_long_double 15
263 #elif __SIZEOF_LONG_DOUBLE__ == 4
264 #define uintdigitsmax_10_long_double 8
265 #define uintdigitsmax_16_long_double 7
266 #endif
267
268 #ifdef _NEED_IO_C99_FORMATS
269 int base = 10;
270 #else
271 #define base 10
272 #endif
273
274 #define uintdigitsmax \
275 ((base) == 10 ? \
276 (CHECK_LONG_LONG() ? uintdigitsmax_10_long_double : \
277 (CHECK_LONG() ? \
278 uintdigitsmax_10_double : \
279 uintdigitsmax_10_float)) : \
280 (CHECK_LONG_LONG() ? uintdigitsmax_16_long_double : \
281 (CHECK_LONG() ? \
282 uintdigitsmax_16_double : \
283 uintdigitsmax_16_float)))
284
285 do {
286
287 unsigned char c;
288
289 #ifdef _NEED_IO_C99_FORMATS
290 if ((flags & FL_FHEX) && (c = TOLOWER(i) - 'a') <= 5)
291 c += 10;
292 else
293 #endif
294 c = i - '0';
295
296 if (c < base) {
297 flags |= FL_ANY;
298 if (flags & FL_OVFL) {
299 overflow |= (c != 0);
300 if (!(flags & FL_DOT))
301 exp += 1;
302 } else {
303 if (flags & FL_DOT)
304 exp -= 1;
305 uint = UF_PLUS_DIGIT(UF_TIMES_BASE(uint, base), c);
306 if (!UF_IS_ZERO(uint)) {
307 uintdigits++;
308 if (uintdigits > uintdigitsmax)
309 flags |= FL_OVFL;
310 }
311 }
312
313 } else if (c == (('.'-'0') & 0xff) && !(flags & FL_DOT)) {
314 flags |= FL_DOT;
315 #ifdef _NEED_IO_C99_FORMATS
316 } else if (TOLOWER(i) == 'x' && (flags & FL_ANY) && UF_IS_ZERO(uint)) {
317 flags |= FL_FHEX;
318 base = 16;
319 #endif
320 } else {
321 break;
322 }
323 } while (CHECK_WIDTH() && (i = scanf_getc (stream, lenp)) >= 0);
324
325 if (!(flags & FL_ANY))
326 return 0;
327
328 #ifdef _NEED_IO_C99_FORMATS
329 int exp_match = (flags & FL_FHEX) ? 'p' : 'e';
330 #else
331 #define exp_match 'e'
332 #endif
333 if (TOLOWER(i) == exp_match)
334 {
335 int esign, edig;
336 int expacc;
337
338 if (!CHECK_WIDTH())
339 goto no_exp;
340
341 esign = scanf_getc (stream, lenp);
342
343 switch ((unsigned char)esign) {
344 case '-':
345 flags |= FL_MEXP;
346 __PICOLIBC_FALLTHROUGH;
347 case '+':
348 if (!CHECK_WIDTH()) {
349 scanf_ungetc(esign, stream, lenp);
350 goto no_exp;
351 }
352 edig = scanf_getc (stream, lenp); /* test EOF will below */
353 break;
354 default:
355 edig = esign;
356 esign = EOF;
357 break;
358 }
359
360 if (!isdigit (edig))
361 {
362 scanf_ungetc(edig, stream, lenp);
363 if (esign != EOF)
364 scanf_ungetc(esign, stream, lenp);
365 goto no_exp;
366 }
367
368 i = edig;
369 expacc = 0;
370 #define MAX_POSSIBLE_EXP (FLOAT_MAX_EXP + FLOAT_MANT_DIG * 4)
371 do {
372 if (expacc < MAX_POSSIBLE_EXP)
373 expacc = expacc * 10 + (i - '0');
374 } while (CHECK_WIDTH() && isdigit (i = scanf_getc(stream, lenp)));
375 if (flags & FL_MEXP)
376 expacc = -expacc;
377 #ifdef _NEED_IO_C99_FORMATS
378 if (flags & FL_FHEX)
379 exp *= 4;
380 #endif
381 exp += expacc;
382 }
383
384 no_exp:
385 if (width)
386 scanf_ungetc (i, stream, lenp);
387
388 if (UF_IS_ZERO(uint)) {
389 flt = (FLOAT) 0;
390 break;
391 }
392
393 #ifdef _NEED_IO_C99_FORMATS
394 if (flags & FL_FHEX)
395 {
396 int sig_bits;
397 int min_exp;
398
399 if (CHECK_LONG_LONG()) {
400 sig_bits = __LDBL_MANT_DIG__;
401 min_exp = __LDBL_MIN_EXP__ - 1;
402 } else if (CHECK_LONG()) {
403 sig_bits = __DBL_MANT_DIG__;
404 min_exp = __DBL_MIN_EXP__ - 1;
405 } else {
406 sig_bits = __FLT_MANT_DIG__;
407 min_exp = __FLT_MIN_EXP__ - 1;
408 }
409
410 /* We're using two guard bits, one for the
411 * 'half' value and the second to indicate whether
412 * there is any non-zero value beyond that
413 */
414 exp += (sig_bits + 2 - 1);
415
416 /* Make significand larger than 1.0 */
417 while (UF_LT(uint, UF_LSHIFT_64(1, (sig_bits + 2 - 1)))) {
418 uint = UF_LSHIFT(uint, 1);
419 exp--;
420 }
421
422 /* Now shift right until the exponent is in range and the
423 * value is less than 2.0. Capture any value > 0.5 in the
424 * LSB of uint. This may generate a denorm.
425 */
426 while (UF_GE(uint, UF_LSHIFT_64(1, (sig_bits + 2))) || exp < min_exp) {
427 /* squash extra bits into the second guard bit */
428 uint = UF_OR_64(UF_RSHIFT(uint, 1), UF_AND_64(uint, 1));
429 exp++;
430 }
431
432 /* Mix in the overflow bit computed while scanning the
433 * string
434 */
435 uint = UF_OR_64(uint, overflow);
436
437 /* Round even */
438 if (UF_AND_64(uint, 3) == 3 || UF_AND_64(uint, 6) == 6) {
439 uint = UF_PLUS_DIGIT(uint, 4);
440 if (UF_GE(uint, UF_LSHIFT_64(1, FLOAT_MANT_DIG + 2))) {
441 uint = UF_RSHIFT(uint, 1);
442 exp++;
443 }
444 }
445
446 /* remove guard bits */
447 uint = UF_RSHIFT(uint, 2);
448
449 /* align from target to FLOAT */
450 uint = UF_LSHIFT(uint, FLOAT_MANT_DIG - sig_bits);
451
452 if (min_exp != (FLOAT_MIN_EXP - 1)) {
453
454 /* Convert from target denorm to FLOAT value */
455 while (UF_LT(uint, UF_LSHIFT_64(1, (FLOAT_MANT_DIG - 1))) && exp > FLOAT_MIN_EXP) {
456 uint = UF_LSHIFT(uint, 1);
457 exp--;
458 }
459 }
460
461 if (exp >= FLOAT_MAX_EXP) {
462 flt = (FLOAT) INFINITY;
463 } else {
464 #if FLOAT_MANT_DIG <= 53 || __LDBL_IS_IEC_60559__ != 0 || defined(__m68k__)
465 if (UF_LT(uint, UF_LSHIFT_64(1, (FLOAT_MANT_DIG-1)))) {
466 exp = 0;
467 } else {
468 exp += (FLOAT_MAX_EXP - 1);
469 #if FLOAT_MANT_DIG > 53 && (defined(__x86_64__) || defined(__i386__))
470 /*
471 * Intel 80-bit format is weird -- there's an
472 * integer bit so denorms can have the 'real'
473 * exponent value. That means we don't mask off
474 * the integer bit
475 */
476 #define EXP_SHIFT FLOAT_MANT_DIG
477 #elif FLOAT_MANT_DIG > 53 && defined(__m68k__)
478 #define EXP_SHIFT FLOAT_MANT_DIG + 16
479 #else
480 uint = UF_AND(uint, UF_NOT(UF_LSHIFT_64(1, (FLOAT_MANT_DIG-1))));
481 #define EXP_SHIFT (FLOAT_MANT_DIG-1)
482 #endif
483 }
484 uint = UF_OR(uint, UF_LSHIFT_64(exp, EXP_SHIFT));
485 flt = ASFLOAT(uint);
486 #else /* FLOAT_MANT_DIG <= 53 || __LDBL_IS_IEC_60559__ != 0 */
487 flt = scalbnl(TOFLOAT(uint), exp - (FLOAT_MANT_DIG-1));
488 #endif
489 CHECK_RANGE(flt);
490 }
491 }
492 else
493 #endif
494 {
495 #ifdef _NEED_IO_FLOAT_LARGE
496 if (CHECK_LONG_LONG() && __SIZEOF_LONG_DOUBLE__ > 8)
497 {
498 flt = (FLOAT) __atold_engine(UF_TO_U128(uint), exp);
499 }
500 else
501 #endif
502 #ifdef _NEED_IO_FLOAT64
503 if ((CHECK_LONG() && __SIZEOF_DOUBLE__ == 8) ||
504 (CHECK_LONG_LONG() && __SIZEOF_LONG_DOUBLE__ == 8))
505 {
506 if (uintdigits + exp <= -324) {
507 // Number is less than 1e-324, which should be rounded down to 0; return +/-0.0.
508 flt = (FLOAT) 0.0;
509 } else if (uintdigits + exp >= 310) {
510 // Number is larger than 1e+309, which should be rounded to +/-Infinity.
511 flt = (FLOAT) INFINITY;
512 } else {
513 flt = (FLOAT) __atod_engine(UF_TO_U64(uint), exp);
514 }
515 }
516 else
517 #endif
518 {
519 if (uintdigits + exp <= -46) {
520 // Number is less than 1e-46, which should be rounded down to 0; return 0.0.
521 flt = (FLOAT) 0.0f;
522 } else if (uintdigits + exp >= 40) {
523 // Number is larger than 1e+39, which should be rounded to +/-Infinity.
524 flt = (FLOAT) INFINITY;
525 } else {
526 flt = (FLOAT) __atof_engine(UF_TO_U32(uint), exp);
527 }
528 }
529 }
530 CHECK_RANGE(flt)
531 break;
532 } /* switch */
533
534 if (flags & FL_MINUS)
535 flt = -flt;
536 if (addr) {
537 if (CHECK_LONG_LONG())
538 *((long double *) addr) = (long double) flt;
539 else if (CHECK_LONG())
540 *((double *) addr) = (double) flt;
541 else
542 *((float *) addr) = (float) flt;
543 }
544 return 1;
545 }
546
547 #undef base
548