diff options
author | Joseph Myers <joseph@codesourcery.com> | 2023-09-28 17:27:58 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2023-09-28 17:28:15 +0000 |
commit | cdbf8229bb1438998b211e4760a97d94a13674d4 (patch) | |
tree | c3253d92a5c54051f664dcee3c64372df858f741 /stdio-common/vfscanf-internal.c | |
parent | aea4ddb87168d0475777e605f3bb576b0f62b3a2 (diff) | |
download | glibc-cdbf8229bb1438998b211e4760a97d94a13674d4.zip glibc-cdbf8229bb1438998b211e4760a97d94a13674d4.tar.gz glibc-cdbf8229bb1438998b211e4760a97d94a13674d4.tar.bz2 |
C2x scanf %wN, %wfN support
ISO C2x defines scanf length modifiers wN (for intN_t / int_leastN_t /
uintN_t / uint_leastN_t) and wfN (for int_fastN_t / uint_fastN_t).
Add support for those length modifiers, similar to the printf support
previously added.
Tested for x86_64 and x86.
Diffstat (limited to 'stdio-common/vfscanf-internal.c')
-rw-r--r-- | stdio-common/vfscanf-internal.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c index 9b1197d..cacb966 100644 --- a/stdio-common/vfscanf-internal.c +++ b/stdio-common/vfscanf-internal.c @@ -381,6 +381,7 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, while (*f != '\0') { unsigned int argpos; + bool is_fast; /* Extract the next argument, which is of type TYPE. For a %N$... spec, this is the Nth argument from the beginning; otherwise it is the next argument after the state now in ARG. */ @@ -602,6 +603,53 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, else if (sizeof (ptrdiff_t) > sizeof (int)) flags |= LONG; break; + case L_('w'): + { + is_fast = false; + if (*f == L_('f')) + { + ++f; + is_fast = true; + } + int bitwidth = 0; + if (ISDIGIT (*f)) + bitwidth = read_int (&f); + 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: + flags |= CHAR; + break; + case 16: + flags |= SHORT; + break; + case 32: + break; + case 64: + flags |= LONGDBL | LONG; + break; + default: + /* ISO C requires this error to be detected. */ + __set_errno (EINVAL); + goto errout; + } + } + break; default: /* Not a recognized modifier. Backup. */ --f; |