From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_LOW,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 31173 invoked from network); 30 May 2023 06:58:59 -0000 Received: from second.openwall.net (193.110.157.125) by inbox.vuxu.org with ESMTPUTF8; 30 May 2023 06:58:59 -0000 Received: (qmail 18179 invoked by uid 550); 30 May 2023 06:58:45 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 18123 invoked from network); 30 May 2023 06:58:44 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=inria.fr; s=dc; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=ZKOU38B5Icy35LBS2y2RsDsJYZ111cubp6cwE9Wp27w=; b=TdW7BRYfAXO4x9BBLub7rLhFF8S+WNkeLuYmK4ubhT1aM5/k70o/lJFw QrtlsZHXp8Eai0r61KszFaqrrWsi7m1ZAPHAa3zHoXnmkO2MUw6bkPKvq M1DfMP+pofhUonE2yVvwbRRuOtTVD9nlTTd11BpCGa7UDJybiLCEbd8lu E=; Authentication-Results: mail2-relais-roc.national.inria.fr; dkim=none (message not signed) header.i=none; spf=SoftFail smtp.mailfrom=Jens.Gustedt@inria.fr; dmarc=fail (p=none dis=none) d=inria.fr X-IronPort-AV: E=Sophos;i="6.00,203,1681164000"; d="scan'208";a="110181273" From: Jens Gustedt To: musl@lists.openwall.com, jens.gustedt@posteo.eu Date: Tue, 30 May 2023 08:55:27 +0200 Message-Id: <5a2c0731967330e9a3832d531ea4212e223aaead.1685429467.git.Jens.Gustedt@inria.fr> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [musl] [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 | 28 +++++++++++++++++++++++++--- src/stdio/vfwprintf.c | 28 +++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index cbc79783..265fb7ad 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, @@ -101,6 +101,12 @@ static const unsigned char states[]['z'-'A'+1] = { S('o') = UMAX, S('u') = UMAX, S('x') = UMAX, S('X') = UMAX, S('n') = PTR, + }, { /* 8: w-prefixed */ + S('b') = UINT, S('B') = UINT, + S('d') = INT, S('i') = INT, + S('o') = UINT, S('u') = UINT, + S('x') = UINT, S('X') = UINT, + S('n') = PTR, } }; @@ -447,7 +453,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int w, p, xp; union arg arg; int argpos; - unsigned st, ps; + unsigned st, ps, width=0; int cnt=0, l=0; size_t i; char buf[sizeof(uintmax_t)*CHAR_BIT+3+LDBL_MANT_DIG/4]; @@ -527,9 +533,25 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, if (OOB(*s)) goto inval; ps=st; st=states[st]S(*s++); + if (st == WPRE) { + if (*s == '0') goto inval; + width = getint(&s); + } } while (st-1= UINT64_MAX + case 64: ps = LPRE; st = (st == UINT) ? ULONG : ((st == INT) ? LONG : PTR); break; +#else + case 64: ps = LLPRE; st = (st == UINT) ? ULLONG : ((st == INT) ? LLONG : PTR); break; +#endif + default: goto inval; + } + /* Check validity of argument type (nl/normal) */ if (st==NOARG) { if (argpos>=0) goto inval; diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c index dbc93f74..c3e81d2a 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, @@ -94,6 +94,12 @@ static const unsigned char states[]['z'-'A'+1] = { S('o') = UMAX, S('u') = UMAX, S('x') = UMAX, S('X') = UMAX, S('n') = PTR, + }, { /* 8: w-prefixed */ + S('b') = UINT, S('B') = UINT, + S('d') = INT, S('i') = INT, + S('o') = UINT, S('u') = UINT, + S('x') = UINT, S('X') = UINT, + S('n') = PTR, } }; @@ -163,7 +169,7 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ int w, p, xp; union arg arg; int argpos; - unsigned st, ps; + unsigned st, ps, width=0; int cnt=0, l=0; int i; int t; @@ -242,9 +248,25 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ if (OOB(*s)) goto inval; ps=st; st=states[st]S(*s++); + if (st == WPRE) { + if (*s == L'0') goto inval; + width = getint(&s); + } } while (st-1= UINT64_MAX + case 64: ps = LPRE; st = (st == UINT) ? ULONG : ((st == INT) ? LONG : PTR); break; +#else + case 64: ps = LLPRE; st = (st == UINT) ? ULLONG : ((st == INT) ? LLONG : PTR); break; +#endif + default: goto inval; + } + /* Check validity of argument type (nl/normal) */ if (st==NOARG) { if (argpos>=0) goto inval; -- 2.34.1