aboutsummaryrefslogtreecommitdiff
path: root/stdio-common/printf-parsemb.c
diff options
context:
space:
mode:
Diffstat (limited to 'stdio-common/printf-parsemb.c')
-rw-r--r--stdio-common/printf-parsemb.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/stdio-common/printf-parsemb.c b/stdio-common/printf-parsemb.c
index c5d2704b02..414cbc7223 100644
--- a/stdio-common/printf-parsemb.c
+++ b/stdio-common/printf-parsemb.c
@@ -56,14 +56,17 @@ size_t
attribute_hidden
#ifdef COMPILE_WPRINTF
__parse_one_specwc (const UCHAR_T *format, size_t posn,
- struct printf_spec *spec, size_t *max_ref_arg)
+ struct printf_spec *spec, size_t *max_ref_arg,
+ bool *failed)
#else
__parse_one_specmb (const UCHAR_T *format, size_t posn,
- struct printf_spec *spec, size_t *max_ref_arg)
+ struct printf_spec *spec, size_t *max_ref_arg,
+ bool *failed)
#endif
{
unsigned int n;
size_t nargs = 0;
+ bool is_fast;
/* Skip the '%'. */
++format;
@@ -81,6 +84,8 @@ __parse_one_specmb (const UCHAR_T *format, size_t posn,
spec->info.wide = sizeof (UCHAR_T) > 1;
spec->info.is_binary128 = 0;
+ *failed = false;
+
/* Test for positional argument. */
if (ISDIGIT (*format))
{
@@ -298,6 +303,53 @@ __parse_one_specmb (const UCHAR_T *format, size_t posn,
#endif
spec->info.is_long = sizeof (uintmax_t) > sizeof (unsigned int);
break;
+ case L_('w'):
+ is_fast = false;
+ if (*format == L_('f'))
+ {
+ ++format;
+ is_fast = true;
+ }
+ int bitwidth = 0;
+ if (ISDIGIT (*format))
+ bitwidth = read_int (&format);
+ if (is_fast)
+ switch (bitwidth)
+ {
+ case 8:
+ bitwidth = INT_FAST8_WIDTH;
+ break;
+ case 16:
+ bitwidth = INT_FAST16_WIDTH;
+ break;
+ case 32:
+ bitwidth = INT_FAST32_WIDTH;
+ break;
+ case 64:
+ bitwidth = INT_FAST64_WIDTH;
+ break;
+ }
+ switch (bitwidth)
+ {
+ case 8:
+ spec->info.is_char = 1;
+ break;
+ case 16:
+ spec->info.is_short = 1;
+ break;
+ case 32:
+ break;
+ case 64:
+ spec->info.is_long_double = 1;
+ spec->info.is_long = 1;
+ break;
+ default:
+ /* ISO C requires this error to be detected. */
+ __set_errno (EINVAL);
+ *failed = true;
+ break;
+ }
+ break;
default:
/* Not a recognized modifier. Backup. */
--format;