From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by sourceware.org (Postfix) with ESMTPS id 32294385828D for ; Wed, 27 Sep 2023 20:26:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 32294385828D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-69101d33315so10104361b3a.3 for ; Wed, 27 Sep 2023 13:26:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1695846409; x=1696451209; darn=sourceware.org; h=content-transfer-encoding:in-reply-to:organization:from:references :to:content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=c7tv+RcPEIgPb7po9jdcjKm54J5RgVfSFGr8rsVxOm8=; b=ypCrcaPJyTREkGc+hsilix2divhF+FBNkDsidvpvuDHMtdN6KiGeshqMuutR0p4H5W 06QkjLPCEdE5hFltKV/DqdJU0r7ROpvPSiIWyIpc2nPjF1vMz+RPhpY88t8ebVw5xw56 ySKSDwhByHUQtbd9eKSWi3pzUOtbgI+hjlNYF/NSycc85yHrT5I6VIbjuAC5MUiFFkQP vN4r8bRwlwka6HlzbMFV/RfZjsPmhPLX8UEGw8ieB1RbyTb7TgF+qNo1kg8v66K1Pj63 0Javs5RiBhO5s/jfL0VfainTY973LzLzit32Avbt9A1vG1VM7Z0LuABuk+JIYwtVjuxz E4yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695846409; x=1696451209; h=content-transfer-encoding:in-reply-to:organization:from:references :to:content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=c7tv+RcPEIgPb7po9jdcjKm54J5RgVfSFGr8rsVxOm8=; b=JgmM3YDArRsXgpheyd6oLoDWEbhX7uD4Rz0+kVM3K9Mb0r95Lb6y6CPyQx4VrZJIcT afKWuLMrDM6nie/KucjYuqrsXRPw/aeS2/bxs+XiLqkhGSoNzkDzqjun7FOSlOc1NQJT I3Ptoku1YqyG7YoP/C68N6x1LYt5JbZBJQIpPRJzRlUQF/Ca6EkGFV+XIe/L5XjvAMFG mEesZX7SsIKoetKiW9lF4XO4Kw3w+E5jI0qk6STtu9nic/EESWh9Bt76S61FCc+rksj8 3se0w13flu3VOTnZ2bSWwXPs7+uIBsUl1IJYCFTdNGjeZP3x2CTnKerRY+iaOMPFbukO wWOA== X-Gm-Message-State: AOJu0YyuOGav8IGO9kxDJM5kz528XVU62Mr4qSuqkXaU2JPiUqd2/Hlr HGp91t6EUeN/a9KjNOBRkHK3g7zFEZzsH32rrcnhMQ== X-Google-Smtp-Source: AGHT+IH0O62gLuwzmJgD7/s+zJZoL1SjNeD6aBJiTP4hzOFU/W+g7KFEm/xkkeqUcGv7eOgTGnvhFQ== X-Received: by 2002:a05:6a21:7895:b0:137:23f1:4281 with SMTP id bf21-20020a056a21789500b0013723f14281mr3822839pzc.12.1695846408941; Wed, 27 Sep 2023 13:26:48 -0700 (PDT) Received: from ?IPV6:2804:1b3:a7c1:6eb0:6d4f:92fe:5e4e:27d3? ([2804:1b3:a7c1:6eb0:6d4f:92fe:5e4e:27d3]) by smtp.gmail.com with ESMTPSA id ff11-20020a056a002f4b00b0068790c41ca2sm755200pfb.27.2023.09.27.13.26.46 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 27 Sep 2023 13:26:47 -0700 (PDT) Message-ID: <2d9f1077-b2fd-42ef-b415-e2219f9392ed@linaro.org> Date: Wed, 27 Sep 2023 17:26:44 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: C2x scanf %wN, %wfN support Content-Language: en-US To: libc-alpha@sourceware.org, Joseph Myers References: <611ae3f4-969-441e-8a51-68dbdf45f62a@codesourcery.com> From: Adhemerval Zanella Netto Organization: Linaro In-Reply-To: <611ae3f4-969-441e-8a51-68dbdf45f62a@codesourcery.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_LOTSOFHASH,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 14/09/23 16:03, Joseph Myers wrote: > 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. > Patch looks good, some minor remarks below. > diff --git a/NEWS b/NEWS > index a48c32e76f..d2ae239895 100644 > --- a/NEWS > +++ b/NEWS > @@ -31,6 +31,13 @@ Major new features: > the process ID associated with the process file descriptor created by > pid_spawn, fork_np, or pidfd_open. > > +* scanf-family functions now support the wN format length modifiers for > + arguments pointing to types intN_t, int_leastN_t, uintN_t or > + uint_leastN_t (for example, %w32d to read int32_t or int_least32_t in > + decimal, or %w32x to read uint32_t or uint_least32_t in hexadecimal) > + and the wfN format length modifiers for arguments pointing to types > + int_fastN_t or uint_fastN_t, as specified in draft ISO C2X. > + > Deprecated and removed features, and other changes affecting compatibility: > > [Add deprecations, removals and changes affecting compatibility here] Ok. > diff --git a/manual/stdio.texi b/manual/stdio.texi > index 9cf622403f..002fce7a10 100644 > --- a/manual/stdio.texi > +++ b/manual/stdio.texi > @@ -3714,6 +3714,20 @@ Specifies that the argument is a @code{ptrdiff_t *}. > > This modifier was introduced in @w{ISO C99}. > > +@item w@var{n} > +Specifies that the argument is an @code{int@var{n}_t *} or > +@code{int_least@var{n}_t *} (which are the same type), or > +@code{uint@var{n}_t *} or @code{uint_least@var{n}_t *} (which are the > +same type). > + > +This modifier was introduced in @w{ISO C2X}. > + > +@item wf@var{n} > +Specifies that the argument is an @code{int_fast@var{n}_t *} or > +@code{uint_fast@var{n}_t *}. > + > +This modifier was introduced in @w{ISO C2X}. > + > @item z > Specifies that the argument is a @code{size_t *}. > Ok. > diff --git a/stdio-common/Makefile b/stdio-common/Makefile > index 3866362bae..bacb795fed 100644 > --- a/stdio-common/Makefile > +++ b/stdio-common/Makefile > @@ -243,6 +243,7 @@ tests := \ > tst-scanf-binary-c2x \ > tst-scanf-binary-gnu11 \ > tst-scanf-binary-gnu89 \ > + tst-scanf-intn \ > tst-scanf-round \ > tst-scanf-to_inpunct \ > tst-setvbuf1 \ Ok. > diff --git a/stdio-common/tst-scanf-intn-main.c b/stdio-common/tst-scanf-intn-main.c > new file mode 100644 > index 0000000000..fa0462a8de > --- /dev/null > +++ b/stdio-common/tst-scanf-intn-main.c > @@ -0,0 +1,479 @@ > +/* Test scanf formats for intN_t, int_leastN_t and int_fastN_t types. > + Copyright (C) 2023 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +/* GCC does not know the %wN or %wfN length modifiers before GCC 13. */ > +DIAG_PUSH_NEEDS_COMMENT; > +#if !__GNUC_PREREQ (13, 0) > +DIAG_IGNORE_NEEDS_COMMENT (12, "-Wformat"); > +DIAG_IGNORE_NEEDS_COMMENT (12, "-Wformat-extra-args"); > +#endif > + > +#define CHECK_SCANF1(EXPECTED, STR, FMT) \ > + do \ > + { \ > + var = ((typeof (var)) 0xabababab); \ > + int ret = SSCANF (L_(STR), L_(FMT), &var); \ > + TEST_COMPARE (var, (EXPECTED)); \ > + TEST_COMPARE (ret, 1); \ > + } \ > + while (0) > + > +#define CHECK_SCANF1N(EXPECTED, STR, FMT) \ > + do \ > + { \ > + var = ((typeof (var)) 0xabababab); \ > + n = 123; \ > + int ret = SSCANF (L_(STR), L_(FMT), &var, &n); \ > + TEST_COMPARE (var, (EXPECTED)); \ > + TEST_COMPARE (n, STRLEN (L_(STR))); \ > + TEST_COMPARE (ret, 1); \ > + } \ > + while (0) > + > +#define CHECK_SCANF_ERR(OK, STR, FMT, ...) \ > + do \ > + { \ > + int ret = SSCANF (L_(STR), L_(FMT), __VA_ARGS__); \ > + TEST_VERIFY (ret == (OK)); \ > + TEST_COMPARE (errno, EINVAL); \ > + } \ > + while (0) > + > +static void > +test_w8 (void) > +{ > + { > + int8_t var, n; > + CHECK_SCANF1 (42, "42", "%w8d"); > + CHECK_SCANF1N (42, "42", "%w8d%w8n"); > + CHECK_SCANF1 (-43, "-43", "%w8d"); > + CHECK_SCANF1 (42, "42", "%w8i"); > + CHECK_SCANF1 (-43, "-43", "%w8i"); > + CHECK_SCANF1 (123, "0b1111011", "%w8i"); > + CHECK_SCANF1 (127, "0x7f", "%w8i"); > + CHECK_SCANF1 (-19, "-023", "%w8i"); > + } > + { > + uint8_t var; > + int8_t n; > + CHECK_SCANF1 (123, "1111011", "%w8b"); > + CHECK_SCANF1 (19, "023", "%w8o"); > + CHECK_SCANF1 (50, "50", "%w8u"); > + CHECK_SCANF1 (65, "41", "%w8x"); > + CHECK_SCANF1N (65, "41", "%w8x%w8n"); > + CHECK_SCANF1 (66, "42", "%w8X"); > + } > + { > + int_least8_t var, n; > + CHECK_SCANF1 (42, "42", "%w8d"); > + CHECK_SCANF1N (42, "42", "%w8d%w8n"); > + CHECK_SCANF1 (-43, "-43", "%w8d"); > + CHECK_SCANF1 (42, "42", "%w8i"); > + CHECK_SCANF1 (-43, "-43", "%w8i"); > + CHECK_SCANF1 (123, "0b1111011", "%w8i"); > + CHECK_SCANF1 (127, "0x7f", "%w8i"); > + CHECK_SCANF1 (-19, "-023", "%w8i"); > + } > + { > + uint_least8_t var; > + int_least8_t n; > + CHECK_SCANF1 (123, "1111011", "%w8b"); > + CHECK_SCANF1 (19, "023", "%w8o"); > + CHECK_SCANF1 (50, "50", "%w8u"); > + CHECK_SCANF1 (65, "41", "%w8x"); > + CHECK_SCANF1N (65, "41", "%w8x%w8n"); > + CHECK_SCANF1 (66, "42", "%w8X"); > + } > +} > + Ok. > +static void > +test_wf8 (void) > +{ > + { > + int_fast8_t var, n; > + CHECK_SCANF1 (42, "42", "%wf8d"); > + CHECK_SCANF1N (42, "42", "%wf8d%wf8n"); > + CHECK_SCANF1 (-43, "-43", "%wf8d"); > + CHECK_SCANF1 (42, "42", "%wf8i"); > + CHECK_SCANF1 (-43, "-43", "%wf8i"); > + CHECK_SCANF1 (123, "0b1111011", "%wf8i"); > + CHECK_SCANF1 (127, "0x7f", "%wf8i"); > + CHECK_SCANF1 (-19, "-023", "%wf8i"); > + } > + { > + uint_fast8_t var; > + int_fast8_t n; > + CHECK_SCANF1 (123, "1111011", "%wf8b"); > + CHECK_SCANF1 (19, "023", "%wf8o"); > + CHECK_SCANF1 (50, "50", "%wf8u"); > + CHECK_SCANF1 (65, "41", "%wf8x"); > + CHECK_SCANF1N (65, "41", "%wf8x%wf8n"); > + CHECK_SCANF1 (66, "42", "%wf8X"); > + } > +} > + > +static void > +test_w16 (void) > +{ > + { > + int16_t var, n; > + CHECK_SCANF1 (12345, "12345", "%w16d"); > + CHECK_SCANF1N (23456, "23456", "%w16d%w16n"); > + CHECK_SCANF1 (-10101, "-10101", "%w16d"); > + CHECK_SCANF1 (30000, "30000", "%w16i"); > + CHECK_SCANF1 (-19876, "-19876", "%w16i"); > + CHECK_SCANF1 (16384, "0b100000000000000", "%w16i"); > + CHECK_SCANF1 (32767, "0x7fff", "%w16i"); > + CHECK_SCANF1 (-16383, "-037777", "%w16i"); > + } > + { > + uint16_t var; > + int16_t n; > + CHECK_SCANF1 (32767, "111111111111111", "%w16b"); > + CHECK_SCANF1 (4095, "07777", "%w16o"); > + CHECK_SCANF1 (9999, "9999", "%w16u"); > + CHECK_SCANF1 (23456, "5ba0", "%w16x"); > + CHECK_SCANF1N (23456, "5ba0", "%w16x%w16n"); > + CHECK_SCANF1 (23457, "5ba1", "%w16X"); > + } > + { > + int_least16_t var, n; > + CHECK_SCANF1 (12345, "12345", "%w16d"); > + CHECK_SCANF1N (23456, "23456", "%w16d%w16n"); > + CHECK_SCANF1 (-10101, "-10101", "%w16d"); > + CHECK_SCANF1 (30000, "30000", "%w16i"); > + CHECK_SCANF1 (-19876, "-19876", "%w16i"); > + CHECK_SCANF1 (16384, "0b100000000000000", "%w16i"); > + CHECK_SCANF1 (32767, "0x7fff", "%w16i"); > + CHECK_SCANF1 (-16383, "-037777", "%w16i"); > + } > + { > + uint_least16_t var; > + int_least16_t n; > + CHECK_SCANF1 (32767, "111111111111111", "%w16b"); > + CHECK_SCANF1 (4095, "07777", "%w16o"); > + CHECK_SCANF1 (9999, "9999", "%w16u"); > + CHECK_SCANF1 (23456, "5ba0", "%w16x"); > + CHECK_SCANF1N (23456, "5ba0", "%w16x%w16n"); > + CHECK_SCANF1 (23457, "5ba1", "%w16X"); > + } > +} > + Ok. > +static void > +test_wf16 (void) > +{ > + { > + int_fast16_t var, n; > + CHECK_SCANF1 (12345, "12345", "%wf16d"); > + CHECK_SCANF1N (23456, "23456", "%wf16d%wf16n"); > + CHECK_SCANF1 (-10101, "-10101", "%wf16d"); > + CHECK_SCANF1 (30000, "30000", "%wf16i"); > + CHECK_SCANF1 (-19876, "-19876", "%wf16i"); > + CHECK_SCANF1 (16384, "0b100000000000000", "%wf16i"); > + CHECK_SCANF1 (32767, "0x7fff", "%wf16i"); > + CHECK_SCANF1 (-16383, "-037777", "%wf16i"); > + } > + { > + uint_fast16_t var; > + int_fast16_t n; > + CHECK_SCANF1 (32767, "111111111111111", "%wf16b"); > + CHECK_SCANF1 (4095, "07777", "%wf16o"); > + CHECK_SCANF1 (9999, "9999", "%wf16u"); > + CHECK_SCANF1 (23456, "5ba0", "%wf16x"); > + CHECK_SCANF1N (23456, "5ba0", "%wf16x%wf16n"); > + CHECK_SCANF1 (23457, "5ba1", "%wf16X"); > + } > +#if INT_FAST16_MAX >= INT32_MAX > + { > + int_fast16_t var, n; > + CHECK_SCANF1 (1234567, "1234567", "%wf16d"); > + CHECK_SCANF1N (2345678, "2345678", "%wf16d%wf16n"); > + CHECK_SCANF1 (-1010101, "-1010101", "%wf16d"); > + CHECK_SCANF1 (3000000, "3000000", "%wf16i"); > + CHECK_SCANF1 (-98765432, "-98765432", "%wf16i"); > + CHECK_SCANF1 (1048576, "0b100000000000000000000", "%wf16i"); > + CHECK_SCANF1 (1048575, "0xfffff", "%wf16i"); > + CHECK_SCANF1 (-1048575, "-03777777", "%wf16i"); > + } > + { > + uint_fast16_t var; > + int_fast16_t n; > + CHECK_SCANF1 (1234567, "100101101011010000111", "%wf16b"); > + CHECK_SCANF1 (1048575, "03777777", "%wf16o"); > + CHECK_SCANF1 (999999, "999999", "%wf16u"); > + CHECK_SCANF1 (987654, "f1206", "%wf16x"); > + CHECK_SCANF1N (987654, "f1206", "%wf16x%wf16n"); > + CHECK_SCANF1 (987655, "f1207", "%wf16X"); > + } > +#endif > +#if INT_FAST16_MAX >= INT64_MAX > + { > + int_fast16_t var, n; > + CHECK_SCANF1 (123456789012LL, "123456789012", "%wf16d"); > + CHECK_SCANF1N (234567890123LL, "234567890123", "%wf16d%wf16n"); > + CHECK_SCANF1 (-10101010101LL, "-10101010101", "%wf16d"); > + CHECK_SCANF1 (3000000000000000LL, "3000000000000000", "%wf16i"); > + CHECK_SCANF1 (-9876543210LL, "-9876543210", "%wf16i"); > + CHECK_SCANF1 (1LL << 40, "0b10000000000000000000000000000000000000000", > + "%wf16i"); > + CHECK_SCANF1 (1LL << 41, "0x20000000000", "%wf16i"); > + CHECK_SCANF1 (-(1LL << 42), "-0100000000000000", "%wf16i"); > + } > + { > + uint_fast16_t var; > + int_fast16_t n; > + CHECK_SCANF1 (123456789012ULL, "1110010111110100110010001101000010100", > + "%wf16b"); > + CHECK_SCANF1 (1ULL << 40, "20000000000000", "%wf16o"); > + CHECK_SCANF1 (999999999999ULL, "999999999999", "%wf16u"); > + CHECK_SCANF1 (9876543210ULL, "24cb016ea", "%wf16x"); > + CHECK_SCANF1N (9876543210ULL, "24cb016ea", "%wf16x%wf16n"); > + CHECK_SCANF1 (9876543211ULL, "24cb016eb", "%wf16X"); > + } > +#endif > +} > + Ok. > +static void > +test_w32 (void) > +{ > + { > + int32_t var, n; > + CHECK_SCANF1 (1234567, "1234567", "%w32d"); > + CHECK_SCANF1N (2345678, "2345678", "%w32d%w32n"); > + CHECK_SCANF1 (-1010101, "-1010101", "%w32d"); > + CHECK_SCANF1 (3000000, "3000000", "%w32i"); > + CHECK_SCANF1 (-98765432, "-98765432", "%w32i"); > + CHECK_SCANF1 (1048576, "0b100000000000000000000", "%w32i"); > + CHECK_SCANF1 (1048575, "0xfffff", "%w32i"); > + CHECK_SCANF1 (-1048575, "-03777777", "%w32i"); > + } > + { > + uint32_t var; > + int32_t n; > + CHECK_SCANF1 (1234567, "100101101011010000111", "%w32b"); > + CHECK_SCANF1 (1048575, "03777777", "%w32o"); > + CHECK_SCANF1 (999999, "999999", "%w32u"); > + CHECK_SCANF1 (987654, "f1206", "%w32x"); > + CHECK_SCANF1N (987654, "f1206", "%w32x%w32n"); > + CHECK_SCANF1 (987655, "f1207", "%w32X"); > + } > + { > + int_least32_t var, n; > + CHECK_SCANF1 (1234567, "1234567", "%w32d"); > + CHECK_SCANF1N (2345678, "2345678", "%w32d%w32n"); > + CHECK_SCANF1 (-1010101, "-1010101", "%w32d"); > + CHECK_SCANF1 (3000000, "3000000", "%w32i"); > + CHECK_SCANF1 (-98765432, "-98765432", "%w32i"); > + CHECK_SCANF1 (1048576, "0b100000000000000000000", "%w32i"); > + CHECK_SCANF1 (1048575, "0xfffff", "%w32i"); > + CHECK_SCANF1 (-1048575, "-03777777", "%w32i"); > + } > + { > + uint_least32_t var; > + int_least32_t n; > + CHECK_SCANF1 (1234567, "100101101011010000111", "%w32b"); > + CHECK_SCANF1 (1048575, "03777777", "%w32o"); > + CHECK_SCANF1 (999999, "999999", "%w32u"); > + CHECK_SCANF1 (987654, "f1206", "%w32x"); > + CHECK_SCANF1N (987654, "f1206", "%w32x%w32n"); > + CHECK_SCANF1 (987655, "f1207", "%w32X"); > + } > +} > + Ok. > +static void > +test_wf32 (void) > +{ > + { > + int_fast32_t var, n; > + CHECK_SCANF1 (1234567, "1234567", "%wf32d"); > + CHECK_SCANF1N (2345678, "2345678", "%wf32d%wf32n"); > + CHECK_SCANF1 (-1010101, "-1010101", "%wf32d"); > + CHECK_SCANF1 (3000000, "3000000", "%wf32i"); > + CHECK_SCANF1 (-98765432, "-98765432", "%wf32i"); > + CHECK_SCANF1 (1048576, "0b100000000000000000000", "%wf32i"); > + CHECK_SCANF1 (1048575, "0xfffff", "%wf32i"); > + CHECK_SCANF1 (-1048575, "-03777777", "%wf32i"); > + } > + { > + uint_fast32_t var; > + int_fast32_t n; > + CHECK_SCANF1 (1234567, "100101101011010000111", "%wf32b"); > + CHECK_SCANF1 (1048575, "03777777", "%wf32o"); > + CHECK_SCANF1 (999999, "999999", "%wf32u"); > + CHECK_SCANF1 (987654, "f1206", "%wf32x"); > + CHECK_SCANF1N (987654, "f1206", "%wf32x%wf32n"); > + CHECK_SCANF1 (987655, "f1207", "%wf32X"); > + } > +#if INT_FAST32_MAX >= INT64_MAX > + { > + int_fast32_t var, n; > + CHECK_SCANF1 (123456789012LL, "123456789012", "%wf32d"); > + CHECK_SCANF1N (234567890123LL, "234567890123", "%wf32d%wf32n"); > + CHECK_SCANF1 (-10101010101LL, "-10101010101", "%wf32d"); > + CHECK_SCANF1 (3000000000000000LL, "3000000000000000", "%wf32i"); > + CHECK_SCANF1 (-9876543210LL, "-9876543210", "%wf32i"); > + CHECK_SCANF1 (1LL << 40, "0b10000000000000000000000000000000000000000", > + "%wf32i"); > + CHECK_SCANF1 (1LL << 41, "0x20000000000", "%wf32i"); > + CHECK_SCANF1 (-(1LL << 42), "-0100000000000000", "%wf32i"); > + } > + { > + uint_fast32_t var; > + int_fast32_t n; > + CHECK_SCANF1 (123456789012ULL, "1110010111110100110010001101000010100", > + "%wf32b"); > + CHECK_SCANF1 (1ULL << 40, "20000000000000", "%wf32o"); > + CHECK_SCANF1 (999999999999ULL, "999999999999", "%wf32u"); > + CHECK_SCANF1 (9876543210ULL, "24cb016ea", "%wf32x"); > + CHECK_SCANF1N (9876543210ULL, "24cb016ea", "%wf32x%wf32n"); > + CHECK_SCANF1 (9876543211ULL, "24cb016eb", "%wf32X"); > + } > +#endif > +} > + Ok. > +static void > +test_w64 (void) > +{ > + { > + int64_t var, n; > + CHECK_SCANF1 (123456789012LL, "123456789012", "%w64d"); > + CHECK_SCANF1N (234567890123LL, "234567890123", "%w64d%w64n"); > + CHECK_SCANF1 (-10101010101LL, "-10101010101", "%w64d"); > + CHECK_SCANF1 (3000000000000000LL, "3000000000000000", "%w64i"); > + CHECK_SCANF1 (-9876543210LL, "-9876543210", "%w64i"); > + CHECK_SCANF1 (1LL << 40, "0b10000000000000000000000000000000000000000", > + "%w64i"); > + CHECK_SCANF1 (1LL << 41, "0x20000000000", "%w64i"); > + CHECK_SCANF1 (-(1LL << 42), "-0100000000000000", "%w64i"); > + } > + { > + uint64_t var; > + int64_t n; > + CHECK_SCANF1 (123456789012ULL, "1110010111110100110010001101000010100", > + "%w64b"); > + CHECK_SCANF1 (1ULL << 40, "20000000000000", "%w64o"); > + CHECK_SCANF1 (999999999999ULL, "999999999999", "%w64u"); > + CHECK_SCANF1 (9876543210ULL, "24cb016ea", "%w64x"); > + CHECK_SCANF1N (9876543210ULL, "24cb016ea", "%w64x%w64n"); > + CHECK_SCANF1 (9876543211ULL, "24cb016eb", "%w64X"); > + } > + { > + int_least64_t var, n; > + CHECK_SCANF1 (123456789012LL, "123456789012", "%w64d"); > + CHECK_SCANF1N (234567890123LL, "234567890123", "%w64d%w64n"); > + CHECK_SCANF1 (-10101010101LL, "-10101010101", "%w64d"); > + CHECK_SCANF1 (3000000000000000LL, "3000000000000000", "%w64i"); > + CHECK_SCANF1 (-9876543210LL, "-9876543210", "%w64i"); > + CHECK_SCANF1 (1LL << 40, "0b10000000000000000000000000000000000000000", > + "%w64i"); > + CHECK_SCANF1 (1LL << 41, "0x20000000000", "%w64i"); > + CHECK_SCANF1 (-(1LL << 42), "-0100000000000000", "%w64i"); > + } > + { > + uint_least64_t var; > + int_least64_t n; > + CHECK_SCANF1 (123456789012ULL, "1110010111110100110010001101000010100", > + "%w64b"); > + CHECK_SCANF1 (1ULL << 40, "20000000000000", "%w64o"); > + CHECK_SCANF1 (999999999999ULL, "999999999999", "%w64u"); > + CHECK_SCANF1 (9876543210ULL, "24cb016ea", "%w64x"); > + CHECK_SCANF1N (9876543210ULL, "24cb016ea", "%w64x%w64n"); > + CHECK_SCANF1 (9876543211ULL, "24cb016eb", "%w64X"); > + } > +} > + Ok. > +static void > +test_wf64 (void) > +{ > + { > + int_fast64_t var, n; > + CHECK_SCANF1 (123456789012LL, "123456789012", "%wf64d"); > + CHECK_SCANF1N (234567890123LL, "234567890123", "%wf64d%wf64n"); > + CHECK_SCANF1 (-10101010101LL, "-10101010101", "%wf64d"); > + CHECK_SCANF1 (3000000000000000LL, "3000000000000000", "%wf64i"); > + CHECK_SCANF1 (-9876543210LL, "-9876543210", "%wf64i"); > + CHECK_SCANF1 (1LL << 40, "0b10000000000000000000000000000000000000000", > + "%wf64i"); > + CHECK_SCANF1 (1LL << 41, "0x20000000000", "%wf64i"); > + CHECK_SCANF1 (-(1LL << 42), "-0100000000000000", "%wf64i"); > + } > + { > + uint_fast64_t var; > + int_fast64_t n; > + CHECK_SCANF1 (123456789012ULL, "1110010111110100110010001101000010100", > + "%wf64b"); > + CHECK_SCANF1 (1ULL << 40, "20000000000000", "%wf64o"); > + CHECK_SCANF1 (999999999999ULL, "999999999999", "%wf64u"); > + CHECK_SCANF1 (9876543210ULL, "24cb016ea", "%wf64x"); > + CHECK_SCANF1N (9876543210ULL, "24cb016ea", "%wf64x%wf64n"); > + CHECK_SCANF1 (9876543211ULL, "24cb016eb", "%wf64X"); > + } > +} > + > +static int > +do_test (void) > +{ > + int a, b; > + test_w8 (); > + test_wf8 (); > + test_w16 (); > + test_wf16 (); > + test_w32 (); > + test_wf32 (); > + test_w64 (); > + test_wf64 (); > + /* Bad N in %wN and %wfN are required to produce an error return (of > + the number of input items assigned) from scanf functions (and can > + also be seen to be invalid at compile time). */ > + DIAG_PUSH_NEEDS_COMMENT; > + DIAG_IGNORE_NEEDS_COMMENT (13, "-Wformat"); > + DIAG_IGNORE_NEEDS_COMMENT (13, "-Wformat-extra-args"); > + CHECK_SCANF_ERR (0, "1", "%w1d", &a); > + CHECK_SCANF_ERR (0, "1", "%w123d", &a); > + CHECK_SCANF_ERR (0, "1", "%w99999999999999999999d", &a); > + CHECK_SCANF_ERR (0, "1", "%wf1d", &a); > + CHECK_SCANF_ERR (0, "1", "%wf123d", &a); > + CHECK_SCANF_ERR (0, "1", "%wf99999999999999999999d", &a); > + CHECK_SCANF_ERR (1, "1 1", "%d %w1d", &a, &b); > + CHECK_SCANF_ERR (1, "1 1", "%d %w123d", &a, &b); > + CHECK_SCANF_ERR (1, "1 1", "%d %w99999999999999999999d", &a, &b); > + CHECK_SCANF_ERR (1, "1 1", "%d %wf1d", &a, &b); > + CHECK_SCANF_ERR (1, "1 1", "%d %wf123d", &a, &b); > + CHECK_SCANF_ERR (1, "1 1", "%d %wf99999999999999999999d", &a, &b); > + CHECK_SCANF_ERR (0, "1", "%1$w1d", &a); > + CHECK_SCANF_ERR (0, "1", "%1$w123d", &a); > + CHECK_SCANF_ERR (0, "1", "%1$w99999999999999999999d", &a); > + CHECK_SCANF_ERR (0, "1", "%1$wf1d", &a); > + CHECK_SCANF_ERR (0, "1", "%1$wf123d", &a); > + CHECK_SCANF_ERR (0, "1", "%1$wf99999999999999999999d", &a); > + DIAG_POP_NEEDS_COMMENT; > + return 0; > +} > + > +DIAG_POP_NEEDS_COMMENT; > + > +#include Ok. > diff --git a/stdio-common/tst-scanf-intn.c b/stdio-common/tst-scanf-intn.c > new file mode 100644 > index 0000000000..876eda30ee > --- /dev/null > +++ b/stdio-common/tst-scanf-intn.c > @@ -0,0 +1,24 @@ > +/* Test scanf formats for intN_t, int_leastN_t and int_fastN_t types. > + Narrow string version. > + Copyright (C) 2023 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +#define SSCANF sscanf > +#define STRLEN strlen > +#define L_(C) C > + > +#include Ok. > diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c > index 9b1197d751..cf94af4f54 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,51 @@ __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; Maybe it would be better to put this declaration on its own scope to avoid it escape on possible future extensions (at least this is what we are recently doing on tests). > + if (ISDIGIT (*f)) > + bitwidth = read_int (&f); > + if (is_fast) > + switch (bitwidth) > + { > + case 8: > + bitwidth = INT_FAST8_WIDTH; > + break; Isn't this redundant (at least for current supported INT_FAST8_WIDTH)? > + 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; Ok. > diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile > index 431136b9c9..cde9a3221e 100644 > --- a/wcsmbs/Makefile > +++ b/wcsmbs/Makefile > @@ -196,6 +196,7 @@ tests := \ > tst-wscanf-binary-c2x \ > tst-wscanf-binary-gnu11 \ > tst-wscanf-binary-gnu89 \ > + tst-wscanf-intn \ > tst-wscanf-to_inpunct \ > wcsatcliff \ > wcsmbs-tst1 \ Ok. > diff --git a/wcsmbs/tst-wscanf-intn.c b/wcsmbs/tst-wscanf-intn.c > new file mode 100644 > index 0000000000..8b6e6d3c0e > --- /dev/null > +++ b/wcsmbs/tst-wscanf-intn.c > @@ -0,0 +1,24 @@ > +/* Test scanf formats for intN_t, int_leastN_t and int_fastN_t types. > + Wide string version. > + Copyright (C) 2023 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > +#define SSCANF swscanf > +#define STRLEN wcslen > +#define L_(C) L ## C > + > +#include "../stdio-common/tst-scanf-intn-main.c" > Ok.