public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org, Joseph Myers <joseph@codesourcery.com>
Subject: Re: C2x scanf %wN, %wfN support
Date: Wed, 27 Sep 2023 17:26:44 -0300	[thread overview]
Message-ID: <2d9f1077-b2fd-42ef-b415-e2219f9392ed@linaro.org> (raw)
In-Reply-To: <611ae3f4-969-441e-8a51-68dbdf45f62a@codesourcery.com>



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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <wchar.h>
> +
> +#include <libc-diag.h>
> +#include <support/check.h>
> +
> +/* 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 <support/test-driver.c>

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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#define SSCANF sscanf
> +#define STRLEN strlen
> +#define L_(C) C
> +
> +#include <tst-scanf-intn-main.c>

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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#define SSCANF swscanf
> +#define STRLEN wcslen
> +#define L_(C) L ## C
> +
> +#include "../stdio-common/tst-scanf-intn-main.c"
> 

Ok.

  parent reply	other threads:[~2023-09-27 20:26 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-14 19:03 Joseph Myers
2023-09-20 13:26 ` Ping " Joseph Myers
2023-09-27 14:45   ` Ping^2 " Joseph Myers
2023-09-27 20:26 ` Adhemerval Zanella Netto [this message]
2023-09-28 17:31   ` Joseph Myers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2d9f1077-b2fd-42ef-b415-e2219f9392ed@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=joseph@codesourcery.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).