* stdio-common/vfscanf.c: Small cleanups throughout.

This commit is contained in:
Ulrich Drepper 2007-02-19 21:20:09 +00:00
parent 2484468be1
commit 3979024a8c
2 changed files with 46 additions and 54 deletions

View File

@ -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> 2007-02-18 Ulrich Drepper <drepper@redhat.com>
[BZ #3325] [BZ #3325]

View File

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