diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2013-12-18 19:23:33 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2013-12-18 19:23:33 +0000 |
commit | 576b7804d63caaae29b7a6ae007f10c0d2c0e58a (patch) | |
tree | c5ae72f229ffe0b57fd5b2c3edf9489a5b927d91 /newlib/libc/stdio/vfscanf.c | |
parent | 5730605d5597ef0fb24a7626d1c2da4fc8529eaa (diff) | |
download | cygnal-576b7804d63caaae29b7a6ae007f10c0d2c0e58a.tar.gz cygnal-576b7804d63caaae29b7a6ae007f10c0d2c0e58a.tar.bz2 cygnal-576b7804d63caaae29b7a6ae007f10c0d2c0e58a.zip |
* vfscanf.c (BUF): Change definition to take multibyte decimal point
into account.
(__SVFSCANF_R): Handle radix char language-dependent
per POSIX.
(__SVFWSCANF_R): Ditto.
Diffstat (limited to 'newlib/libc/stdio/vfscanf.c')
-rw-r--r-- | newlib/libc/stdio/vfscanf.c | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/newlib/libc/stdio/vfscanf.c b/newlib/libc/stdio/vfscanf.c index ae94cea3f..5fd153de6 100644 --- a/newlib/libc/stdio/vfscanf.c +++ b/newlib/libc/stdio/vfscanf.c @@ -162,6 +162,7 @@ Supporting OS subroutines required: #ifdef FLOATING_POINT #include <math.h> #include <float.h> +#include <locale.h> /* Currently a test is made to see if long double processing is warranted. This could be changed in the future should the _ldtoa_r code be @@ -174,11 +175,7 @@ extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr)); #include "floatio.h" -#if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX) -# define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */ -#else -# define BUF MB_LEN_MAX -#endif +#define BUF (MAXEXP+MAXFRACT+MB_LEN_MAX+2) /* decimal point + sign + NUL */ /* An upper bound for how long a long prints in decimal. 4 / 13 approximates log (2). Add one char for roundoff compensation and one for the sign. */ @@ -1288,6 +1285,10 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), unsigned width_left = 0; char nancount = 0; char infcount = 0; + const char *decpt = _localeconv_r (rptr)->decimal_point; +#ifdef _MB_CAPABLE + int decptpos = 0; +#endif #ifdef hardway if (width == 0 || width > sizeof (buf) - 1) #else @@ -1416,14 +1417,6 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), goto fok; } break; - case '.': - if (flags & DPTOK) - { - flags &= ~(SIGNOK | DPTOK); - leading_zeroes = zeroes; - goto fok; - } - break; case 'e': case 'E': /* no exponent without some digits */ @@ -1442,6 +1435,53 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), goto fok; } break; + default: +#ifndef _MB_CAPABLE + if ((unsigned char) c == (unsigned char) decpt[0] + && (flags & DPTOK)) + { + flags &= ~(SIGNOK | DPTOK); + leading_zeroes = zeroes; + goto fok; + } + break; +#else + if (flags & DPTOK) + { + while ((unsigned char) c + == (unsigned char) decpt[decptpos]) + { + if (decpt[++decptpos] == '\0') + { + /* We read the complete decpt seq. */ + flags &= ~(SIGNOK | DPTOK); + leading_zeroes = zeroes; + p = stpncpy (p, decpt, decptpos); + decptpos = 0; + goto fskip; + } + ++nread; + if (--fp->_r > 0) + fp->_p++; + else if (__srefill_r (rptr, fp)) + break; /* EOF */ + c = *fp->_p; + } + if (decptpos > 0) + { + /* We read part of a multibyte decimal point, + but the rest is invalid or we're at EOF, + so back off. */ + while (decptpos-- > 0) + { + _ungetc_r (rptr, (unsigned char) decpt[decptpos], + fp); + --nread; + } + } + } + break; +#endif } break; fok: |