diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | stdio-common/vfscanf.c | 92 |
2 files changed, 44 insertions, 52 deletions
@@ -1,3 +1,7 @@ +2007-02-19 Ulrich Drepper <drepper@redhat.com> + + * stdio-common/vfscanf.c: Small cleanups throughout. + 2007-02-18 Ulrich Drepper <drepper@redhat.com> [BZ #3325] diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index cdb610dc0c..c7d8a07e9e 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -58,10 +58,12 @@ #define SUPPRESS 0x008 /* *: suppress assignment */ #define POINTER 0x010 /* weird %p pointer (`fake hex') */ #define NOSKIP 0x020 /* do not skip blanks */ +#define NUMBER_SIGNED 0x040 /* signed integer */ #define GROUP 0x080 /* ': group numbers */ #define MALLOC 0x100 /* a: malloc strings */ #define CHAR 0x200 /* hh: char */ #define I18N 0x400 /* I: use locale's digits */ +#define HEXA_FLOAT 0x800 /* hexadecimal float */ #include <locale/localeinfo.h> @@ -203,9 +205,6 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, #define exp_char not_in /* Base for integral numbers. */ int base; - /* Signedness for integral numbers. */ - int number_signed; -#define is_hexa number_signed /* Decimal point character. */ #ifdef COMPILE_WSCANF wint_t decimal; @@ -436,7 +435,12 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, flags |= SUPPRESS; break; case L_('\''): - flags |= GROUP; +#ifdef COMPILE_WSCANF + if (thousands != L'\0') +#else + if (thousands != NULL) +#endif + flags |= GROUP; break; case L_('I'): flags |= I18N; @@ -1076,27 +1080,24 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, case L_('x'): /* Hexadecimal integer. */ case L_('X'): /* Ditto. */ base = 16; - number_signed = 0; goto number; case L_('o'): /* Octal integer. */ base = 8; - number_signed = 0; goto number; case L_('u'): /* Unsigned decimal integer. */ base = 10; - number_signed = 0; goto number; case L_('d'): /* Signed decimal integer. */ base = 10; - number_signed = 1; + flags |= NUMBER_SIGNED; goto number; case L_('i'): /* Generic number. */ base = 0; - number_signed = 1; + flags |= NUMBER_SIGNED; number: c = inchar (); @@ -1361,13 +1362,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (n < 10) c = L_('0') + n; - else if ((flags & GROUP) -#ifdef COMPILE_WSCANF - && thousands != L'\0' -#else - && thousands != NULL -#endif - ) + else if (flags & GROUP) { /* Try matching against the thousands separator. */ #ifdef COMPILE_WSCANF @@ -1433,13 +1428,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, } else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base) { - if (base == 10 && (flags & GROUP) -#ifdef COMPILE_WSCANF - && thousands != L'\0' -#else - && thousands != NULL -#endif - ) + if (base == 10 && (flags & GROUP)) { /* Try matching against the thousands separator. */ #ifdef COMPILE_WSCANF @@ -1527,14 +1516,14 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, ADDW (L_('\0')); if (need_longlong && (flags & LONGDBL)) { - if (number_signed) + if (flags & NUMBER_SIGNED) num.q = __strtoll_internal (wp, &tw, base, flags & GROUP); else num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP); } else { - if (number_signed) + if (flags & NUMBER_SIGNED) num.l = __strtol_internal (wp, &tw, base, flags & GROUP); else num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP); @@ -1544,32 +1533,32 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (!(flags & SUPPRESS)) { - if (! number_signed) + if (flags & NUMBER_SIGNED) { if (need_longlong && (flags & LONGDBL)) - *ARG (unsigned LONGLONG int *) = num.uq; + *ARG (LONGLONG int *) = num.q; else if (need_long && (flags & LONG)) - *ARG (unsigned long int *) = num.ul; + *ARG (long int *) = num.l; else if (flags & SHORT) - *ARG (unsigned short int *) - = (unsigned short int) num.ul; + *ARG (short int *) = (short int) num.l; else if (!(flags & CHAR)) - *ARG (unsigned int *) = (unsigned int) num.ul; + *ARG (int *) = (int) num.l; else - *ARG (unsigned char *) = (unsigned char) num.ul; + *ARG (signed char *) = (signed char) num.ul; } else { if (need_longlong && (flags & LONGDBL)) - *ARG (LONGLONG int *) = num.q; + *ARG (unsigned LONGLONG int *) = num.uq; else if (need_long && (flags & LONG)) - *ARG (long int *) = num.l; + *ARG (unsigned long int *) = num.ul; else if (flags & SHORT) - *ARG (short int *) = (short int) num.l; + *ARG (unsigned short int *) + = (unsigned short int) num.ul; else if (!(flags & CHAR)) - *ARG (int *) = (int) num.l; + *ARG (unsigned int *) = (unsigned int) num.ul; else - *ARG (signed char *) = (signed char) num.ul; + *ARG (unsigned char *) = (unsigned char) num.ul; } ++done; } @@ -1689,7 +1678,6 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, goto scan_float; } - is_hexa = 0; exp_char = L_('e'); if (width != 0 && c == L_('0')) { @@ -1702,7 +1690,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, /* It is a number in hexadecimal format. */ ADDW (c); - is_hexa = 1; + flags |= HEXA_FLOAT; exp_char = L_('p'); /* Grouping is not allowed. */ @@ -1717,7 +1705,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, { if (ISDIGIT (c)) ADDW (c); - else if (!got_e && is_hexa && ISXDIGIT (c)) + else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c)) ADDW (c); else if (got_e && wp[wpsize - 1] == exp_char && (c == L_('-') || c == L_('+'))) @@ -1736,8 +1724,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, ADDW (c); got_dot = 1; } - else if ((flags & GROUP) != 0 && thousands != L'\0' - && ! got_dot && c == thousands) + else if ((flags & GROUP) != 0 && ! got_dot && c == thousands) ADDW (c); else { @@ -1781,8 +1768,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, we can compare against it. */ const char *cmp2p = thousands; - if ((flags & GROUP) != 0 && thousands != NULL - && ! got_dot) + if ((flags & GROUP) != 0 && ! got_dot) { while (cmp2p - thousands < cmpp - decimal && *cmp2p == decimal[cmp2p - thousands]) @@ -1831,7 +1817,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (__builtin_expect ((flags & I18N) != 0, 0) /* Hexadecimal floats make no sense, fixing localized digits with ASCII letters. */ - && !is_hexa + && !(flags & HEXA_FLOAT) /* Minimum requirement. */ && (wpsize == 0 || got_dot) && (map = __wctrans ("to_inpunct")) != NULL) @@ -1884,14 +1870,18 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (match_so_far) #endif { - int have_locthousands = true; + bool have_locthousands = (flags & GROUP) != 0; + /* Now get the digits and the thousands-sep equivalents. */ for (int n = 0; n < 11; ++n) { if (n < 10) wcdigits[n] = __towctrans (L'0' + n, map); else if (n == 10) - wcdigits[10] = __towctrans (L',', map); + { + wcdigits[10] = __towctrans (L',', map); + have_locthousands &= wcdigits[10] != L'\0'; + } #ifndef COMPILE_WSCANF memset (&state, '\0', sizeof (state)); @@ -1902,9 +1892,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, { if (n == 10) { - if (thousands == NULL || (flags & GROUP) == 0) - have_locthousands = false; - else + if (have_locthousands) { size_t thousands_len = strlen (thousands); if (thousands_len <= MB_LEN_MAX) @@ -2046,7 +2034,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, in hexadecimal notation and we have read only the `0x' prefix or no exponent this is an error. */ if (__builtin_expect (wpsize == 0 - || (is_hexa && (wpsize == 2 || ! got_e)), 0)) + || ((flags & HEXA_FLOAT) + && (wpsize == 2 || ! got_e)), 0)) conv_error (); scan_float: @@ -2585,7 +2574,6 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, flags &= ~(SHORT|LONGDBL); if (need_long) flags |= LONG; - number_signed = 0; read_pointer = 1; goto number; |