|
Message-Id: <c2a62c90d2715b454f672778b8b2a193ca0fcaaf.1685129854.git.Jens.Gustedt@inria.fr> Date: Fri, 26 May 2023 21:41:03 +0200 From: Jens Gustedt <Jens.Gustedt@...ia.fr> To: musl@...ts.openwall.com Subject: [C23 printf 2/3] C23: implement the wN length specifiers for printf These are mandatory for C23 and concern all types for which the platform has `int_leastN_t` and `uint_leastN_t`. For musl these types always coincide with `intN_t` and `uintN_t` and are always present for N equal 8, 16, 32 and 64. They can be added for general use since all lowercase letters were previously reserved. Nevertheless, users that use these modifiers will see a lot of warnings from compilers in the beginning. This is because the compilers have not yet integrated this form of a specifier into their correponding extensions (gcc attributes). So unfortunately also testing this feature may be a bit noisy for the moment. The only architecture dependend choice is the type for N == 64, which may be `long` or `long long`. We just mimick the test that is done in other places to compare `UINTPTR_MAX` and `UINT64_MAX` to determine that. --- src/stdio/vfprintf.c | 18 ++++++++++++++++-- src/stdio/vfwprintf.c | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index cbc79783..1a516663 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -33,7 +33,7 @@ enum { BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE, - ZTPRE, JPRE, + ZTPRE, JPRE, WPRE, STOP, PTR, INT, UINT, ULLONG, LONG, ULONG, @@ -57,7 +57,7 @@ static const unsigned char states[]['z'-'A'+1] = { S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, S('m') = NOARG, S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, - S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, + S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, S('w') = WPRE, }, { /* 1: l-prefixed */ S('b') = ULONG, S('B') = ULONG, S('d') = LONG, S('i') = LONG, @@ -525,8 +525,22 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, st=0; do { if (OOB(*s)) goto inval; + wpre: ps=st; st=states[st]S(*s++); + if (st == WPRE) { + switch (getint(&s)) { + case 8: st = HHPRE; goto wpre; + case 16: st = HPRE; goto wpre; + case 32: st = BARE; goto wpre; +#if UINTPTR_MAX >= UINT64_MAX + case 64: st = LPRE; goto wpre; +#else + case 64: st = LLPRE; goto wpre; +#endif + default: goto inval; + } + } } while (st-1<STOP); if (!st) goto inval; diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c index dbc93f74..4320761a 100644 --- a/src/stdio/vfwprintf.c +++ b/src/stdio/vfwprintf.c @@ -26,7 +26,7 @@ enum { BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE, - ZTPRE, JPRE, + ZTPRE, JPRE, WPRE, STOP, PTR, INT, UINT, ULLONG, LONG, ULONG, @@ -50,7 +50,7 @@ static const unsigned char states[]['z'-'A'+1] = { S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, S('m') = NOARG, S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, - S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, + S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, S('w') = WPRE, }, { /* 1: l-prefixed */ S('b') = ULONG, S('B') = ULONG, S('d') = LONG, S('i') = LONG, @@ -240,8 +240,22 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ st=0; do { if (OOB(*s)) goto inval; + wpre: ps=st; st=states[st]S(*s++); + if (st == WPRE) { + switch (getint(&s)) { + case 8: st = HHPRE; goto wpre; + case 16: st = HPRE; goto wpre; + case 32: st = BARE; goto wpre; +#if UINTPTR_MAX >= UINT64_MAX + case 64: st = LPRE; goto wpre; +#else + case 64: st = LLPRE; goto wpre; +#endif + default: goto inval; + } + } } while (st-1<STOP); if (!st) goto inval; -- 2.34.1
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.