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 #define FLT_CONTEXT int
65
scanf_getc(const char * s,int * lenp)66 static inline int scanf_getc(const char *s, int *lenp)
67 {
68 int l = *lenp;
69 int c = s[l];
70 *lenp = l + 1;
71 return c;
72 }
73
scanf_ungetc(int c,FLT_STREAM * s,int * lenp)74 static inline void scanf_ungetc(int c, FLT_STREAM *s, int *lenp)
75 {
76 (void) c;
77 (void) s;
78 --(*lenp);
79 }
80
81 #undef EOF
82 #define EOF -1
83
84 #else
85
86 # define CHECK_WIDTH() (--width != 0)
87 # define CHECK_RANGE(flt)
88
89 # ifdef _NEED_IO_FLOAT
90
91 # define CHECK_LONG() 0
92 # define CHECK_LONG_LONG() 0
93
94 # elif defined(_NEED_IO_DOUBLE)
95
96 # ifdef _NEED_IO_LONG_DOUBLE
97 # define CHECK_LONG() (flags & FL_LONG)
98 # define CHECK_LONG_LONG() (flags & FL_LONGLONG)
99 # else
100 # define CHECK_LONG() (flags & (FL_LONG|FL_LONGLONG))
101 # define CHECK_LONG_LONG() 0
102 # endif
103 # else
104 # define CHECK_LONG() 0
105 # define CHECK_LONG_LONG() 0
106 # endif
107
108 #define FLT_STREAM FILE
109 #define FLT_CONTEXT scanf_context_t
110
111 #endif
112
113 #include "scanf_private.h"
114
115 #include "dtoa.h"
116
117 #ifdef _NEED_IO_LONG_DOUBLE
118 # define FLOAT long double
119 # define FLOAT_MIN __LDBL_MIN__
120 # define FLOAT_MANT_DIG __LDBL_MANT_DIG__
121 # define FLOAT_MAX_EXP __LDBL_MAX_EXP__
122 # define FLOAT_MIN_EXP __LDBL_MIN_EXP__
123 # define ASFLOAT(x) aslongdouble(x)
124 # if __SIZEOF_LONG_DOUBLE__ > 8
125 # define TOFLOAT(x) _u128_to_ld(x)
126 # define UINTFLOAT _u128
127 # elif __SIZEOF_LONG_DOUBLE__ == 8
128 # define TOFLOAT(x) ((long double) (x))
129 # define UINTFLOAT uint64_t
130 # elif __SIZEOF_LONG_DOUBLE__ == 4
131 # define TOFLOAT(x) ((long double) (x))
132 # define UINTFLOAT uint32_t
133 # endif
134 #elif defined(_NEED_IO_DOUBLE)
135 # define FLOAT double
136 # define FLOAT_MIN __DBL_MIN__
137 # define FLOAT_MANT_DIG __DBL_MANT_DIG__
138 # define FLOAT_MAX_EXP __DBL_MAX_EXP__
139 # define FLOAT_MIN_EXP __DBL_MIN_EXP__
140 # define ASFLOAT(x) _asdouble(x)
141 # define TOFLOAT(x) ((double) (x))
142 # if __SIZEOF_DOUBLE__ == 4
143 # define UINTFLOAT uint32_t
144 # elif __SIZEOF_DOUBLE__ == 8
145 # define UINTFLOAT uint64_t
146 # endif
147 #elif defined(_NEED_IO_FLOAT)
148 # define FLOAT float
149 # define FLOAT_MIN __FLT_MIN__
150 # define FLOAT_MANT_DIG __FLT_MANT_DIG__
151 # define FLOAT_MAX_EXP __FLT_MAX_EXP__
152 # define FLOAT_MIN_EXP __FLT_MIN_EXP__
153 # define ASFLOAT(x) _asfloat(x)
154 # define TOFLOAT(x) ((float) (x))
155 # define UINTFLOAT uint32_t
156 #endif
157
158 #if FLOAT_MANT_DIG > 53
159 #define U32_TO_UF(x) to_u128(x)
160 #define U64_TO_UF(x) to_u128(x)
161 #define U128_TO_UF(x) (x)
162 #define UF_TO_U32(x) from_u128(x)
163 #define UF_TO_U64(x) from_u128(x)
164 #define UF_TO_U128(x) (x)
165 #define UF_IS_ZERO(x) _u128_is_zero(x)
166 #define UF_TIMES_BASE(a,b) _u128_times_base(a,b)
167 #define UF_PLUS_DIGIT(a,b) _u128_plus_64(a,b)
168 #define UF_RSHIFT(a,b) _u128_rshift(a,b)
169 #define UF_LSHIFT(a,b) _u128_lshift(a,b)
170 #define UF_LSHIFT_64(a,b) _u128_lshift_64(a,b)
171 #define UF_LT(a,b) _u128_lt(a,b)
172 #define UF_GE(a,b) _u128_ge(a,b)
173 #define UF_OR_64(a,b) _u128_or_64(a,b)
174 #define UF_AND_64(a,b) _u128_and_64(a,b)
175 #define UF_AND(a,b) _u128_and(a,b)
176 #define UF_NOT(a) _u128_not(a)
177 #define UF_OR(a,b) _u128_or(a,b)
178 #else
179 #define U32_TO_UF(x) (x)
180 #define U64_TO_UF(x) (x)
181 #define U128_TO_UF(x) from_u128(x)
182 #define UF_TO_U32(x) (x)
183 #define UF_TO_U64(x) (x)
184 #define UF_TO_U128(x) to_u128(x)
185 #define UF_IS_ZERO(x) ((x) == 0)
186 #define UF_TIMES_BASE(a,b) ((a) * (b))
187 #define UF_PLUS_DIGIT(a,b) ((a) + (b))
188 #define UF_RSHIFT(a,b) ((a) >> (b))
189 #define UF_LSHIFT(a,b) ((a) << (b))
190 #define UF_LSHIFT_64(a,b) ((UINTFLOAT) (a) << (b))
191 #define UF_LT(a,b) ((a) < (b))
192 #define UF_GE(a,b) ((a) >= (b))
193 #define UF_OR_64(a,b) ((a) | (b))
194 #define UF_AND_64(a,b) ((a) & (b))
195 #define UF_AND(a,b) ((a) & (b))
196 #define UF_NOT(a) (~(a))
197 #define UF_OR(a,b) ((a) | (b))
198 #endif
199
200 static unsigned char
conv_flt(FLT_STREAM * stream,FLT_CONTEXT * context,width_t width,void * addr,uint16_t flags)201 conv_flt (FLT_STREAM *stream, FLT_CONTEXT *context, width_t width, void *addr, uint16_t flags)
202 {
203 UINTFLOAT uint;
204 unsigned int overflow = 0;
205 int uintdigits = 0;
206 FLOAT flt;
207 int i;
208 const char *p;
209 int exp;
210
211 i = scanf_getc (stream, context); /* after scanf_ungetc() */
212
213 switch ((unsigned char)i) {
214 case '-':
215 flags |= FL_MINUS;
216 __PICOLIBC_FALLTHROUGH;
217 case '+':
218 if (!CHECK_WIDTH() || (i = scanf_getc (stream, context)) < 0)
219 return 0;
220 }
221
222 switch (TOLOWER (i)) {
223 case 'n':
224 p = pstr_an;
225 flt = (FLOAT) NAN;
226 goto operate_pstr;
227
228 case 'i':
229 p = pstr_nfinity;
230 flt = (FLOAT) INFINITY;
231 operate_pstr:
232 {
233 unsigned char c;
234
235 while ((c = *p++) != 0) {
236 if (CHECK_WIDTH()) {
237 if ((i = scanf_getc (stream, context)) >= 0) {
238 if (TOLOWER(i) == c)
239 continue;
240 scanf_ungetc (i, stream, context);
241 }
242 }
243 if (p == pstr_nfinity + 3)
244 break;
245 return 0;
246 }
247 if (flt != flt) {
248 if (CHECK_WIDTH()) {
249 if ((i = scanf_getc (stream, context)) == '(') {
250 while (CHECK_WIDTH() && (i = scanf_getc (stream, context)) != ')') {
251 if (isalnum(i) || i == '_' )
252 continue;
253 else
254 break;
255 }
256 if (i != ')')
257 return 0;
258 } else {
259 scanf_ungetc (i, stream, context);
260 }
261 }
262 }
263 }
264 break;
265
266 default:
267 exp = 0;
268 uint = U32_TO_UF(0);
269 #define uintdigitsmax_10_float 8
270 #define uintdigitsmax_16_float 7
271 #if __SIZEOF_DOUBLE__ == 8
272 #define uintdigitsmax_10_double 16
273 #define uintdigitsmax_16_double 15
274 #elif __SIZEOF_DOUBLE__ ==4
275 #define uintdigitsmax_10_double 8
276 #define uintdigitsmax_16_double 7
277 #endif
278 #if __SIZEOF_LONG_DOUBLE__ > 8
279 #define uintdigitsmax_10_long_double 32
280 #define uintdigitsmax_16_long_double 30
281 #elif __SIZEOF_LONG_DOUBLE__ == 8
282 #define uintdigitsmax_10_long_double 16
283 #define uintdigitsmax_16_long_double 15
284 #elif __SIZEOF_LONG_DOUBLE__ == 4
285 #define uintdigitsmax_10_long_double 8
286 #define uintdigitsmax_16_long_double 7
287 #endif
288
289 #ifdef _NEED_IO_C99_FORMATS
290 int base = 10;
291 #else
292 #define base 10
293 #endif
294
295 #define uintdigitsmax \
296 ((base) == 10 ? \
297 (CHECK_LONG_LONG() ? uintdigitsmax_10_long_double : \
298 (CHECK_LONG() ? \
299 uintdigitsmax_10_double : \
300 uintdigitsmax_10_float)) : \
301 (CHECK_LONG_LONG() ? uintdigitsmax_16_long_double : \
302 (CHECK_LONG() ? \
303 uintdigitsmax_16_double : \
304 uintdigitsmax_16_float)))
305
306 do {
307
308 unsigned char c;
309
310 #ifdef _NEED_IO_C99_FORMATS
311 if ((flags & FL_FHEX) && (c = TOLOWER(i) - 'a') <= 5)
312 c += 10;
313 else
314 #endif
315 c = i - '0';
316
317 if (c < base) {
318 flags |= FL_ANY;
319 if (!(flags & FL_OVFL) && uintdigits > uintdigitsmax) {
320 flags |= FL_OVFL;
321 if (base == 10) {
322 /* Check if overflow is >= 0.5 */
323 if (c >= 5) {
324 overflow = 2;
325 /* Check if overflow might be == 0.5 */
326 if (c == 5)
327 c = 0;
328 }
329 }
330 }
331 if (flags & FL_OVFL) {
332 overflow |= (c != 0);
333 if (!(flags & FL_DOT))
334 exp += 1;
335 } else {
336 if (flags & FL_DOT)
337 exp -= 1;
338 uint = UF_PLUS_DIGIT(UF_TIMES_BASE(uint, base), c);
339 if (!UF_IS_ZERO(uint))
340 uintdigits++;
341 }
342
343 } else if (c == (('.'-'0') & 0xff) && !(flags & FL_DOT)) {
344 flags |= FL_DOT;
345 #ifdef _NEED_IO_C99_FORMATS
346 } else if (TOLOWER(i) == 'x' && (flags & FL_ANY) && UF_IS_ZERO(uint)) {
347 flags |= FL_FHEX;
348 base = 16;
349 #endif
350 } else {
351 break;
352 }
353 } while (CHECK_WIDTH() && (i = scanf_getc (stream, context)) >= 0);
354
355 if (!(flags & FL_ANY))
356 return 0;
357
358 #ifdef _NEED_IO_C99_FORMATS
359 int exp_match = 'e';
360 if (flags & FL_FHEX) {
361 exp_match = 'p';
362 exp *= 4;
363 }
364 #else
365 #define exp_match 'e'
366 #endif
367 if (TOLOWER(i) == exp_match)
368 {
369 int esign, edig;
370 int expacc;
371
372 if (!CHECK_WIDTH())
373 goto no_exp;
374
375 esign = scanf_getc (stream, context);
376
377 switch ((unsigned char)esign) {
378 case '-':
379 flags |= FL_MEXP;
380 __PICOLIBC_FALLTHROUGH;
381 case '+':
382 if (!CHECK_WIDTH()) {
383 scanf_ungetc(esign, stream, context);
384 goto no_exp;
385 }
386 edig = scanf_getc (stream, context); /* test EOF will below */
387 break;
388 default:
389 edig = esign;
390 esign = EOF;
391 break;
392 }
393
394 if (!isdigit (edig))
395 {
396 scanf_ungetc(edig, stream, context);
397 if (esign != EOF)
398 scanf_ungetc(esign, stream, context);
399 goto no_exp;
400 }
401
402 i = edig;
403 expacc = 0;
404 #define MAX_POSSIBLE_EXP (FLOAT_MAX_EXP + FLOAT_MANT_DIG * 4)
405 do {
406 if (expacc < MAX_POSSIBLE_EXP)
407 expacc = expacc * 10 + (i - '0');
408 } while (CHECK_WIDTH() && isdigit (i = scanf_getc(stream, context)));
409 if (flags & FL_MEXP)
410 expacc = -expacc;
411 exp += expacc;
412 }
413
414 no_exp:
415 if (width)
416 scanf_ungetc (i, stream, context);
417
418 if (UF_IS_ZERO(uint)) {
419 flt = (FLOAT) 0;
420 break;
421 }
422
423 #ifdef _NEED_IO_C99_FORMATS
424 if (flags & FL_FHEX)
425 {
426 int sig_bits;
427 int min_exp;
428
429 if (CHECK_LONG_LONG()) {
430 sig_bits = __LDBL_MANT_DIG__;
431 min_exp = __LDBL_MIN_EXP__ - 1;
432 } else if (CHECK_LONG()) {
433 sig_bits = __DBL_MANT_DIG__;
434 min_exp = __DBL_MIN_EXP__ - 1;
435 } else {
436 sig_bits = __FLT_MANT_DIG__;
437 min_exp = __FLT_MIN_EXP__ - 1;
438 }
439
440 /* We're using two guard bits, one for the
441 * 'half' value and the second to indicate whether
442 * there is any non-zero value beyond that
443 */
444 exp += (sig_bits + 2 - 1);
445
446 /* Make significand larger than 1.0 */
447 while (UF_LT(uint, UF_LSHIFT_64(1, (sig_bits + 2 - 1)))) {
448 uint = UF_LSHIFT(uint, 1);
449 exp--;
450 }
451
452 /* Now shift right until the exponent is in range and the
453 * value is less than 2.0. Capture any value > 0.5 in the
454 * LSB of uint. This may generate a denorm.
455 */
456 while (UF_GE(uint, UF_LSHIFT_64(1, (sig_bits + 2))) || exp < min_exp) {
457 /* squash extra bits into the second guard bit */
458 uint = UF_OR_64(UF_RSHIFT(uint, 1), UF_AND_64(uint, 1));
459 exp++;
460 }
461
462 /* Mix in the overflow bit computed while scanning the
463 * string
464 */
465 uint = UF_OR_64(uint, overflow);
466
467 /* Round even */
468 if (UF_AND_64(uint, 3) == 3 || UF_AND_64(uint, 6) == 6) {
469 uint = UF_PLUS_DIGIT(uint, 4);
470 if (UF_GE(uint, UF_LSHIFT_64(1, FLOAT_MANT_DIG + 2))) {
471 uint = UF_RSHIFT(uint, 1);
472 exp++;
473 }
474 }
475
476 /* remove guard bits */
477 uint = UF_RSHIFT(uint, 2);
478
479 /* align from target to FLOAT */
480 uint = UF_LSHIFT(uint, FLOAT_MANT_DIG - sig_bits);
481
482 if (min_exp != (FLOAT_MIN_EXP - 1)) {
483
484 /* Convert from target denorm to FLOAT value */
485 while (UF_LT(uint, UF_LSHIFT_64(1, (FLOAT_MANT_DIG - 1))) && exp > FLOAT_MIN_EXP) {
486 uint = UF_LSHIFT(uint, 1);
487 exp--;
488 }
489 }
490
491 if (exp >= FLOAT_MAX_EXP) {
492 flt = (FLOAT) INFINITY;
493 } else {
494 #if FLOAT_MANT_DIG <= 53 || __LDBL_IS_IEC_60559__ != 0 || defined(__m68k__)
495 if (UF_LT(uint, UF_LSHIFT_64(1, (FLOAT_MANT_DIG-1)))) {
496 exp = 0;
497 } else {
498 exp += (FLOAT_MAX_EXP - 1);
499 #if FLOAT_MANT_DIG > 53 && (defined(__x86_64__) || defined(__i386__))
500 /*
501 * Intel 80-bit format is weird -- there's an
502 * integer bit so denorms can have the 'real'
503 * exponent value. That means we don't mask off
504 * the integer bit
505 */
506 #define EXP_SHIFT FLOAT_MANT_DIG
507 #elif FLOAT_MANT_DIG > 53 && defined(__m68k__)
508 #define EXP_SHIFT FLOAT_MANT_DIG + 16
509 #else
510 uint = UF_AND(uint, UF_NOT(UF_LSHIFT_64(1, (FLOAT_MANT_DIG-1))));
511 #define EXP_SHIFT (FLOAT_MANT_DIG-1)
512 #endif
513 }
514 uint = UF_OR(uint, UF_LSHIFT_64(exp, EXP_SHIFT));
515 flt = ASFLOAT(uint);
516 #else /* FLOAT_MANT_DIG <= 53 || __LDBL_IS_IEC_60559__ != 0 */
517 flt = scalbnl(TOFLOAT(uint), exp - (FLOAT_MANT_DIG-1));
518 #endif
519 CHECK_RANGE(flt);
520 }
521 }
522 else
523 #endif
524 {
525 /*
526 * Mix in overflow. Overflow has four possible values:
527 *
528 * 0: overflow == 0
529 * 1: overflow < 0.5
530 * 2: overflow == 0.5
531 * 3: overflow > 0.5
532 *
533 * We want to increment in case 2 if uint is odd
534 * and always in case 3.
535 */
536 overflow |= UF_AND_64(uint, 1);
537 uint = UF_PLUS_DIGIT(uint, (overflow + 1) >> 2);
538
539 #ifdef _NEED_IO_FLOAT_LARGE
540 if (CHECK_LONG_LONG() && __SIZEOF_LONG_DOUBLE__ > 8)
541 {
542 flt = (FLOAT) __atold_engine(UF_TO_U128(uint), exp);
543 }
544 else
545 #endif
546 #ifdef _NEED_IO_FLOAT64
547 if ((CHECK_LONG() && __SIZEOF_DOUBLE__ == 8) ||
548 (CHECK_LONG_LONG() && __SIZEOF_LONG_DOUBLE__ == 8))
549 {
550 if (uintdigits + exp <= -324) {
551 // Number is less than 1e-324, which should be rounded down to 0; return +/-0.0.
552 flt = (FLOAT) 0.0;
553 } else if (uintdigits + exp >= 310) {
554 // Number is larger than 1e+309, which should be rounded to +/-Infinity.
555 flt = (FLOAT) INFINITY;
556 } else {
557 flt = (FLOAT) __atod_engine(UF_TO_U64(uint), exp);
558 }
559 }
560 else
561 #endif
562 {
563 if (uintdigits + exp <= -46) {
564 // Number is less than 1e-46, which should be rounded down to 0; return 0.0.
565 flt = (FLOAT) 0.0f;
566 } else if (uintdigits + exp >= 40) {
567 // Number is larger than 1e+39, which should be rounded to +/-Infinity.
568 flt = (FLOAT) INFINITY;
569 } else {
570 flt = (FLOAT) __atof_engine(UF_TO_U32(uint), exp);
571 }
572 }
573 }
574 CHECK_RANGE(flt)
575 break;
576 } /* switch */
577
578 #if defined(__riscv) || defined(__ARC64__) || defined(__mips)
579 /*
580 * Some processors don't preserve the sign of NAN across
581 * conversions, so we have to negate after the cast
582 */
583 if (addr) {
584 if (CHECK_LONG_LONG()) {
585 long double ld = (long double) flt;
586 if (flags & FL_MINUS)
587 ld = -ld;
588 *((long double *) addr) = ld;
589 } else if (CHECK_LONG()) {
590 double d = (double) flt;
591 if (flags & FL_MINUS)
592 d = -d;
593 *((double *) addr) = d;
594 } else {
595 float f = (float) flt;
596 if (flags & FL_MINUS)
597 f = -f;
598 *((float *) addr) = f;
599 }
600 }
601 #else
602 if (flags & FL_MINUS)
603 flt = -flt;
604 if (addr) {
605 if (CHECK_LONG_LONG())
606 *((long double *) addr) = (long double) flt;
607 else if (CHECK_LONG())
608 *((double *) addr) = (double) flt;
609 else
610 *((float *) addr) = (float) flt;
611 }
612 #endif
613 return 1;
614 }
615
616 #undef base
617