diff options
Diffstat (limited to 'stdio-common')
-rw-r--r-- | stdio-common/vfprintf.c | 20 | ||||
-rw-r--r-- | stdio-common/vfscanf.c | 56 |
2 files changed, 47 insertions, 29 deletions
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index dfaf4191c7..e544c6518c 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -189,6 +189,14 @@ extern void __funlockfile (FILE *); # define is_longlong is_long_double #endif +/* If `long' and `int' is effectively the same type we don't have to + handle `long separately. */ +#if INT_MAX == LONG_MAX +# define is_long_num 0 +#else +# define is_long_num is_long +#endif + /* Global variables. */ static const char null[] = "(null)"; @@ -524,13 +532,13 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) \ if (fspec == NULL) \ { \ - if (is_long) \ + if (is_long_num) \ signed_number = va_arg (ap, long int); \ else /* `char' and `short int' will be promoted to `int'. */ \ signed_number = va_arg (ap, int); \ } \ else \ - if (is_long) \ + if (is_long_num) \ signed_number = args_value[fspec->data_arg].pa_long_int; \ else \ signed_number = args_value[fspec->data_arg].pa_int; \ @@ -608,7 +616,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) { \ if (fspec == NULL) \ { \ - if (is_long) \ + if (is_long_num) \ number.word = va_arg (ap, unsigned long int); \ else if (!is_short) \ number.word = va_arg (ap, unsigned int); \ @@ -616,7 +624,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) number.word = (unsigned short int) va_arg (ap, unsigned int); \ } \ else \ - if (is_long) \ + if (is_long_num) \ number.word = args_value[fspec->data_arg].pa_u_long_int; \ else if (is_char) \ number.word = (unsigned char) \ @@ -987,7 +995,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) { \ if (is_longlong) \ *(long long int *) va_arg (ap, void *) = done; \ - else if (is_long) \ + else if (is_long_num) \ *(long int *) va_arg (ap, void *) = done; \ else if (!is_short) \ *(int *) va_arg (ap, void *) = done; \ @@ -997,7 +1005,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) else \ if (is_longlong) \ *(long long int *) args_value[fspec->data_arg].pa_pointer = done; \ - else if (is_long) \ + else if (is_long_num) \ *(long int *) args_value[fspec->data_arg].pa_pointer = done; \ else if (!is_short) \ *(int *) args_value[fspec->data_arg].pa_pointer = done; \ diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index a5f6f4e4b0..0339edbeca 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -43,17 +43,24 @@ # define need_longlong 1 #endif +/* Determine whether we have to handle `long'. */ +#if INT_MAX == LONG_MAX +# define need_long 0 +#else +# define need_long 1 +#endif + /* Those are flags in the conversion format. */ -# define LONG 0x001 /* l: long or double */ -# define LONGDBL 0x002 /* L: long long or long double */ -# define SHORT 0x004 /* h: short */ -# define SUPPRESS 0x008 /* *: suppress assignment */ -# define POINTER 0x010 /* weird %p pointer (`fake hex') */ -# define NOSKIP 0x020 /* do not skip blanks */ -# define WIDTH 0x040 /* width was given */ -# define GROUP 0x080 /* ': group numbers */ -# define MALLOC 0x100 /* a: malloc strings */ -# define CHAR 0x200 /* hh: char */ +#define LONG 0x001 /* l: long or double */ +#define LONGDBL 0x002 /* L: long long or long double */ +#define SHORT 0x004 /* h: short */ +#define SUPPRESS 0x008 /* *: suppress assignment */ +#define POINTER 0x010 /* weird %p pointer (`fake hex') */ +#define NOSKIP 0x020 /* do not skip blanks */ +#define WIDTH 0x040 /* width was given */ +#define GROUP 0x080 /* ': group numbers */ +#define MALLOC 0x100 /* a: malloc strings */ +#define CHAR 0x200 /* hh: char */ #ifdef USE_IN_LIBIO @@ -446,7 +453,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) { /* A double `l' is equivalent to an `L'. */ ++f; - flags |= need_longlong ? LONGDBL : LONG; + flags |= LONGDBL | LONG; } else /* ints are long ints. */ @@ -455,7 +462,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) case 'q': case 'L': /* doubles are long doubles, and ints are long long ints. */ - flags |= need_longlong ? LONGDBL : LONG; + flags |= LONGDBL | LONG; break; case 'a': /* The `a' is used as a flag only if followed by `s', `S' or @@ -534,12 +541,14 @@ __vfscanf (FILE *s, const char *format, va_list argptr) /* Don't count the read-ahead. */ if (need_longlong && (flags & LONGDBL)) *ARG (long long int *) = read_in; - else if (flags & LONG) + else if (need_long && (flags & LONG)) *ARG (long int *) = read_in; else if (flags & SHORT) *ARG (short int *) = read_in; - else + else if (!(flags & CHAR)) *ARG (int *) = read_in; + else + *ARG (char *) = read_in; #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1 /* We have a severe problem here. The ISO C standard @@ -946,28 +955,28 @@ __vfscanf (FILE *s, const char *format, va_list argptr) { if (need_longlong && (flags & LONGDBL)) *ARG (unsigned LONGLONG int *) = num.uq; - else if (flags & LONG) + else if (need_long && (flags & LONG)) *ARG (unsigned long int *) = num.ul; else if (flags & SHORT) *ARG (unsigned short int *) = (unsigned short int) num.ul; - else if (flags & CHAR) - *ARG (unsigned char *) = (unsigned char) num.ul; - else + else if (!(flags & CHAR)) *ARG (unsigned int *) = (unsigned int) num.ul; + else + *ARG (unsigned char *) = (unsigned char) num.ul; } else { if (need_longlong && (flags & LONGDBL)) *ARG (LONGLONG int *) = num.q; - else if (flags & LONG) + 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 (signed char *) = (signed char) num.ul; - else + else if (!(flags & CHAR)) *ARG (int *) = (int) num.l; + else + *ARG (signed char *) = (signed char) num.ul; } ++done; } @@ -1267,7 +1276,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr) base = 16; /* A PTR must be the same size as a `long int'. */ flags &= ~(SHORT|LONGDBL); - flags |= LONG; + if (need_long) + flags |= LONG; number_signed = 0; read_pointer = 1; goto number; |