diff options
Diffstat (limited to 'newlib/libc/stdio/nano-vfscanf_float.c')
-rw-r--r-- | newlib/libc/stdio/nano-vfscanf_float.c | 342 |
1 files changed, 0 insertions, 342 deletions
diff --git a/newlib/libc/stdio/nano-vfscanf_float.c b/newlib/libc/stdio/nano-vfscanf_float.c deleted file mode 100644 index a81fe7f70..000000000 --- a/newlib/libc/stdio/nano-vfscanf_float.c +++ /dev/null @@ -1,342 +0,0 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include <_ansi.h> -#include <reent.h> -#include <newlib.h> -#include <ctype.h> -#include <wctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <limits.h> -#include <wchar.h> -#include <string.h> -#include <stdarg.h> -#include <errno.h> -#include "local.h" -#include "../stdlib/local.h" -#include "nano-vfscanf_local.h" - -#ifdef FLOATING_POINT -int -_scanf_float (struct _reent *rptr, - struct _scan_data_t *pdata, - FILE *fp, va_list *ap) -{ - int c; - char *p; - float *flp; - _LONG_DOUBLE *ldp; - - /* Scan a floating point number as if by strtod. */ - /* This code used to assume that the number of digits is reasonable. - However, ANSI / ISO C makes no such stipulation; we have to get - exact results even when there is an unreasonable amount of leading - zeroes. */ - long leading_zeroes = 0; - long zeroes, exp_adjust; - char *exp_start = NULL; - unsigned width_left = 0; - char nancount = 0; - char infcount = 0; -#ifdef hardway - if (pdata->width == 0 || pdata->width > BUF - 1) -#else - /* size_t is unsigned, hence this optimisation. */ - if (pdata->width - 1 > BUF - 2) -#endif - { - width_left = pdata->width - (BUF - 1); - pdata->width = BUF - 1; - } - pdata->flags |= SIGNOK | NDIGITS | DPTOK | EXPOK; - zeroes = 0; - exp_adjust = 0; - for (p = pdata->buf; pdata->width; ) - { - c = *fp->_p; - /* This code mimicks the integer conversion code, - but is much simpler. */ - switch (c) - { - case '0': - if (pdata->flags & NDIGITS) - { - pdata->flags &= ~SIGNOK; - zeroes++; - if (width_left) - { - width_left--; - pdata->width++; - } - goto fskip; - } - /* Fall through. */ - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (nancount + infcount == 0) - { - pdata->flags &= ~(SIGNOK | NDIGITS); - goto fok; - } - break; - - case '+': - case '-': - if (pdata->flags & SIGNOK) - { - pdata->flags &= ~SIGNOK; - goto fok; - } - break; - case 'n': - case 'N': - if (nancount == 0 && zeroes == 0 - && (pdata->flags & (NDIGITS | DPTOK | EXPOK)) == - (NDIGITS | DPTOK | EXPOK)) - { - pdata->flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS); - nancount = 1; - goto fok; - } - if (nancount == 2) - { - nancount = 3; - goto fok; - } - if (infcount == 1 || infcount == 4) - { - infcount++; - goto fok; - } - break; - case 'a': - case 'A': - if (nancount == 1) - { - nancount = 2; - goto fok; - } - break; - case 'i': - case 'I': - if (infcount == 0 && zeroes == 0 - && (pdata->flags & (NDIGITS | DPTOK | EXPOK)) == - (NDIGITS | DPTOK | EXPOK)) - { - pdata->flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS); - infcount = 1; - goto fok; - } - if (infcount == 3 || infcount == 5) - { - infcount++; - goto fok; - } - break; - case 'f': - case 'F': - if (infcount == 2) - { - infcount = 3; - goto fok; - } - break; - case 't': - case 'T': - if (infcount == 6) - { - infcount = 7; - goto fok; - } - break; - case 'y': - case 'Y': - if (infcount == 7) - { - infcount = 8; - goto fok; - } - break; - case '.': - if (pdata->flags & DPTOK) - { - pdata->flags &= ~(SIGNOK | DPTOK); - leading_zeroes = zeroes; - goto fok; - } - break; - case 'e': - case 'E': - /* No exponent without some digits. */ - if ((pdata->flags & (NDIGITS | EXPOK)) == EXPOK - || ((pdata->flags & EXPOK) && zeroes)) - { - if (! (pdata->flags & DPTOK)) - { - exp_adjust = zeroes - leading_zeroes; - exp_start = p; - } - pdata->flags = - (pdata->flags & ~(EXPOK | DPTOK)) | SIGNOK | NDIGITS; - zeroes = 0; - goto fok; - } - break; - } - break; -fok: - *p++ = c; -fskip: - pdata->width--; - ++pdata->nread; - if (--fp->_r > 0) - fp->_p++; - else if (pdata->pfn_refill (rptr, fp)) - /* "EOF". */ - break; - } - if (zeroes) - pdata->flags &= ~NDIGITS; - /* We may have a 'N' or possibly even [sign] 'N' 'a' as the - start of 'NaN', only to run out of chars before it was - complete (or having encountered a non-matching char). So - check here if we have an outstanding nancount, and if so - put back the chars we did swallow and treat as a failed - match. - - FIXME - we still don't handle NAN([0xdigits]). */ - if (nancount - 1U < 2U) - { - /* "nancount && nancount < 3". */ - /* Newlib's ungetc works even if we called __srefill in - the middle of a partial parse, but POSIX does not - guarantee that in all implementations of ungetc. */ - while (p > pdata->buf) - { - pdata->pfn_ungetc (rptr, *--p, fp); /* "[-+nNaA]". */ - --pdata->nread; - } - return MATCH_FAILURE; - } - /* Likewise for 'inf' and 'infinity'. But be careful that - 'infinite' consumes only 3 characters, leaving the stream - at the second 'i'. */ - if (infcount - 1U < 7U) - { - /* "infcount && infcount < 8". */ - if (infcount >= 3) /* valid 'inf', but short of 'infinity'. */ - while (infcount-- > 3) - { - pdata->pfn_ungetc (rptr, *--p, fp); /* "[iInNtT]". */ - --pdata->nread; - } - else - { - while (p > pdata->buf) - { - pdata->pfn_ungetc (rptr, *--p, fp); /* "[-+iInN]". */ - --pdata->nread; - } - return MATCH_FAILURE; - } - } - /* If no digits, might be missing exponent digits - (just give back the exponent) or might be missing - regular digits, but had sign and/or decimal point. */ - if (pdata->flags & NDIGITS) - { - if (pdata->flags & EXPOK) - { - /* No digits at all. */ - while (p > pdata->buf) - { - pdata->pfn_ungetc (rptr, *--p, fp); /* "[-+.]". */ - --pdata->nread; - } - return MATCH_FAILURE; - } - /* Just a bad exponent (e and maybe sign). */ - c = *--p; - --pdata->nread; - if (c != 'e' && c != 'E') - { - pdata->pfn_ungetc (rptr, c, fp); /* "[-+]". */ - c = *--p; - --pdata->nread; - } - pdata->pfn_ungetc (rptr, c, fp); /* "[eE]". */ - } - if ((pdata->flags & SUPPRESS) == 0) - { - double fp; - long new_exp = 0; - - *p = 0; - if ((pdata->flags & (DPTOK | EXPOK)) == EXPOK) - { - exp_adjust = zeroes - leading_zeroes; - new_exp = -exp_adjust; - exp_start = p; - } - else if (exp_adjust) - new_exp = _strtol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust; - - if (exp_adjust) - { - /* If there might not be enough space for the new exponent, - truncate some trailing digits to make room. */ - if (exp_start >= pdata->buf + BUF - MAX_LONG_LEN) - exp_start = pdata->buf + BUF - MAX_LONG_LEN - 1; - sprintf (exp_start, "e%ld", new_exp); - } - - /* Current _strtold routine is markedly slower than - _strtod_r. Only use it if we have a long double - result. */ - fp = _strtod_r (rptr, pdata->buf, NULL); - - /* Do not support long double. */ - if (pdata->flags & LONG) - *GET_ARG (N, *ap, double *) = fp; - else if (pdata->flags & LONGDBL) - { - ldp = GET_ARG (N, *ap, _LONG_DOUBLE *); - *ldp = fp; - } - else - { - flp = GET_ARG (N, *ap, float *); - if (isnan (fp)) - *flp = nanf (NULL); - else - *flp = fp; - } - pdata->nassigned++; - } - return 0; -} -#endif - |