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