diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-07-28 17:45:15 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-07-28 17:45:15 +0000 |
commit | eac4282fa6325e5633bdfee7a6afd9f943b34b1a (patch) | |
tree | 05ea52c568ad29879831e555bcf4dfa05d478d9b /sysdeps/generic/strtol.c | |
parent | dab46544a261b41876829905c634a5f5558ceacf (diff) | |
download | glibc-eac4282fa6325e5633bdfee7a6afd9f943b34b1a.tar.gz glibc-eac4282fa6325e5633bdfee7a6afd9f943b34b1a.tar.xz glibc-eac4282fa6325e5633bdfee7a6afd9f943b34b1a.zip |
Update.
2000-07-27 Jakub Jelinek <jakub@redhat.com> * locale/indigits.h (indigit_value): Correct. * locale/indigitswc.h (indigitwc_value): Correct. * stdio-common/vfscanf.c (__vfscanf): Fix I18N number conversion, add GROUP checking for it, fix GROUP number conversion with strlen(thousands) > 1. Honour width correctly in the presence of floating decimal points and thousands separators. * stdio-common/tst-sscanf.c: New test. * stdio-common/Makefile: Add it to tests. * sysdeps/generic/strtol.c (strtol): Fix conversion if there are thousands separators and group argument is non-zero. Reported by Andi Kleen <ak@suse.de>.
Diffstat (limited to 'sysdeps/generic/strtol.c')
-rw-r--r-- | sysdeps/generic/strtol.c | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/sysdeps/generic/strtol.c b/sysdeps/generic/strtol.c index 44e2104e18..de6f276131 100644 --- a/sysdeps/generic/strtol.c +++ b/sysdeps/generic/strtol.c @@ -256,6 +256,7 @@ INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM) wchar_t thousands = L'\0'; # else const char *thousands = NULL; + size_t thousands_len = 0; # endif /* The numeric grouping specification of the current locale, in the format described in <locale.h>. */ @@ -338,18 +339,25 @@ INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM) save = s; #ifdef USE_NUMBER_GROUPING - if (group) + if (base != 10) + grouping = NULL; + + if (grouping) { +# ifndef USE_WIDE_CHAR + thousands_len = strlen (thousands); +# endif + /* Find the end of the digit string and check its grouping. */ end = s; if ( # ifdef USE_WIDE_CHAR *s != thousands # else - ({ for (cnt = 0; thousands[cnt] != '\0'; ++cnt) + ({ for (cnt = 0; cnt < thousands_len; ++cnt) if (thousands[cnt] != end[cnt]) break; - thousands[cnt] != '\0'; }) + cnt < thousands_len; }) # endif ) { @@ -358,10 +366,10 @@ INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM) # ifdef USE_WIDE_CHAR && c != thousands # else - && ({ for (cnt = 0; thousands[cnt] != '\0'; ++cnt) + && ({ for (cnt = 0; cnt < thousands_len; ++cnt) if (thousands[cnt] != end[cnt]) break; - thousands[cnt] != '\0'; }) + cnt < thousands_len; }) # endif && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base)) @@ -391,6 +399,28 @@ INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM) break; if (c >= L_('0') && c <= L_('9')) c -= L_('0'); +#ifdef USE_NUMBER_GROUPING +# ifdef USE_WIDE_CHAR + else if (grouping && c == thousands) + continue; +# else + else if (thousands_len) + { + for (cnt = 0; cnt < thousands_len; ++cnt) + if (thousands[cnt] != s[cnt]) + break; + if (cnt == thousands_len) + { + s += thousands_len - 1; + continue; + } + if (ISALPHA (c)) + c = TOUPPER (c) - L_('A') + 10; + else + break; + } +# endif +#endif else if (ISALPHA (c)) c = TOUPPER (c) - L_('A') + 10; else @@ -417,6 +447,28 @@ INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM) break; if (c >= L_('0') && c <= L_('9')) c -= L_('0'); +#ifdef USE_NUMBER_GROUPING +# ifdef USE_WIDE_CHAR + else if (grouping && c == thousands) + continue; +# else + else if (thousands_len) + { + for (cnt = 0; cnt < thousands_len; ++cnt) + if (thousands[cnt] != s[cnt]) + break; + if (cnt == thousands_len) + { + s += thousands_len - 1; + continue; + } + if (ISALPHA (c)) + c = TOUPPER (c) - L_('A') + 10; + else + break; + } +# endif +#endif else if (ISALPHA (c)) c = TOUPPER (c) - L_('A') + 10; else |