[PATCH v4 01/12] stdio-common: Add tests for formatted printf output specifiers

DJ Delorie dj@redhat.com
Sat Nov 2 00:58:20 GMT 2024


LGTM
Reviewed-by: DJ Delorie <dj@redhat.com>

"Maciej W. Rozycki" <macro@orcam.me.uk> writes:
> Index: glibc/stdio-common/Makefile
> ===================================================================
> --- glibc.orig/stdio-common/Makefile
> +++ glibc/stdio-common/Makefile
> @@ -22,6 +22,34 @@ subdir	:= stdio-common
>  
>  include ../Makeconfig
>  
> +# List of markers for printf family function tests.
> +xprintf-funcs := p
> +
> +# List of data types and formats for individual per-conversion printf tests.
> +fmt-convs := double ldouble
> +fmts := E e F f G g
> +
> +# List of data types grouping all conversions in single printf tests.
> +nonfmt-convs := c char int llong long s short
> +nonfmt-convs += uchar uint ullong ulong ushort
> +
> +convs := $(sort $(fmt-convs) $(nonfmt-convs))
> +
> +xprintf-srcs := \
> +  $(foreach p,$(xprintf-funcs), \
> +	    $(foreach c,$(convs),tst-printf-format-$(p)-$(c)))
> +
> +fmt-xprintf-stems := \
> +  $(foreach f,$(fmts), \
> +	    $(foreach p,$(xprintf-funcs), \
> +		      $(foreach c,$(fmt-convs), \
> +				tst-printf-format-$(p)-$(c)-$(f))))
> +nonfmt-xprintf-stems := \
> +  $(foreach p,$(xprintf-funcs), \
> +	    $(foreach c,$(nonfmt-convs),tst-printf-format-$(p)-$(c)))
> +
> +xprintf-stems := $(sort $(fmt-xprintf-stems) $(nonfmt-xprintf-stems))
> +

Ok.

>  test-srcs = \
> +  $(xprintf-srcs) \
>    tst-printf \
>    tst-printfsz-islongdouble \
>    tst-unbputc \
> @@ -324,6 +353,7 @@ test-srcs = \
>  
>  ifeq ($(run-built-tests),yes)
>  tests-special += \
> +  $(foreach f,$(xprintf-stems),$(objpfx)$(f).out) \
>    $(objpfx)tst-printf.out \
>    $(objpfx)tst-printfsz-islongdouble.out \
>    $(objpfx)tst-setvbuf1-cmp.out \
> @@ -333,6 +363,7 @@ tests-special += \
>  ifeq (yes,$(build-shared))
>  ifneq ($(PERL),no)
>  tests-special += \
> +  $(foreach f,$(xprintf-stems),$(objpfx)$(f)-mem.out) \
>    $(objpfx)tst-freopen2-mem.out \
>    $(objpfx)tst-freopen3-mem.out \
>    $(objpfx)tst-freopen4-mem.out \
> @@ -353,6 +384,8 @@ tests-special += \
>    # tests-special
>  
>  generated += \
> +  $(foreach f,$(xprintf-stems),$(f)-mem.out) \
> +  $(foreach f,$(xprintf-stems),$(f).mtrace) \
>    tst-freopen2-mem.out \
>    tst-freopen2.mtrace \
>    tst-freopen3-mem.out \

Ok.

> +# We can't split a quoted recipe line, so do it via an auxiliary variable.
> +make-tst-printf-format-out = \
> +  AWK='$(AWK)' BASH='$(BASH)' \
> +    $(BASH) $< $@ $(common-objpfx) \
> +    '$(run-program-prefix-before-env) \
> +     $(run-program-env) \
> +     MALLOC_TRACE=$(@:.out=.mtrace) \
> +     LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so \
> +     $(run-program-prefix-after-env)'
> +$(objpfx)tst-printf-format-%.out: \
> +  tst-printf-format.sh $(foreach c,$(convs),tst-printf-format-$(c).sh) \
> +  $(foreach f,$(xprintf-srcs),$(objpfx)$(f)) tst-printf-format.awk
> +	$(make-tst-printf-format-out) > $@; \
> +	$(evaluate-test)
> +

Ok.

>  $(objpfx)tst-%-mem.out: $(objpfx)tst-%.out
>  	$(common-objpfx)malloc/mtrace $(objpfx)tst-$*.mtrace > $@; \
>  	$(evaluate-test)
> +$(objpfx)tst-printf-format-%-mem.out: $(objpfx)tst-printf-format-%.out
> +	$(common-objpfx)malloc/mtrace \
> +	  $(objpfx)tst-printf-format-$*.mtrace > $@; \
> +	$(evaluate-test)

Ok.

> Index: glibc/stdio-common/tst-printf-format-c.sh

> +#!/bin/bash
> +# Testing of the 'c' printf conversion.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +echo Verifying c
> +(set -o pipefail
> + ${test_program_prefix} \
> +  ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-c c |
> +   $AWK -f tst-printf-format.awk 2>&1 |
> +   head -n 1 | sed "s/^/Conversion c output error, first line:\n/") 2>&1 ||
> +  exit 1

Ok.

> Index: glibc/stdio-common/tst-printf-format-char.sh

> +#!/bin/bash
> +# Testing of signed char printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=0
> +
> +for f in d i; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-char $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-double.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-double.sh
> @@ -0,0 +1,74 @@
> +#!/bin/bash
> +# Testing of double printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +format=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +# For floating-point formats we need to use the bignum mode even if the
> +# regular mode would do, because GAWK in the latter mode uses sprintf(3)
> +# internally to process the conversion requested, so any bug in our code
> +# would then be verified against itself, defeating the objective of doing
> +# the verification against an independent implementation.
> +AWK="${AWK:-awk} -M"
> +
> +status=77
> +
> +# Verify that AWK can handle the range required.  It also catches:
> +# "gawk: warning: -M ignored: MPFR/GMP support not compiled in"
> +# message produced where bignum support is not there, which is the
> +# only indication as the use of '-M' does not affect the exit status
> +# in this case.
> +ref="-1.79769313486231570814527423731704357e+308"
> +val=$(echo "$ref" | $AWK '{ printf "%.35e\n", $1 }' 2>&1) &&
> +  test "$val" = "$ref" && status=0
> +
> +test $status -eq 0 || { echo "No working AWK found" && exit $status; }
> +
> +# Check for any additional conversions that AWK handles conditionally
> +# according to its version and/or the environment it has been built in.
> +# The 'A' and 'a' conversions are not suitable to use at this point, as
> +# output produced by AWK is different apparently due to a subtlety in
> +# rounding, so do not try them.
> +declare -A conversion_disabled
> +ref="-inf"
> +for f in f F; do
> +  conversion_disabled[$f]=true
> +  val=$(echo "$ref" | $AWK '{ printf "%'$f'\n", $1 }' 2>&1) &&
> +    test "${val^^}" = "${ref^^}" && unset conversion_disabled[$f]
> +done
> +
> +if test "${conversion_disabled[$format]+set}" = set; then
> +  echo Unsupported $format
> +  status=77
> +else
> +  echo Verifying $format
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-double $format |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 |
> +     sed "s/^/Conversion $format output error, first line:\n/") 2>&1 ||
> +    status=1
> +fi
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-int.sh

> +#!/bin/bash
> +# Testing of int printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=77
> +
> +# Verify that AWK can handle the range required.  It also catches:
> +# "gawk: warning: -M ignored: MPFR/GMP support not compiled in"
> +# message produced where bignum support is not there, which is the
> +# only indication as the use of '-M' does not affect the exit status
> +# in this case.
> +ref="-2147483648"
> +for AWK in "$AWK -M" "$AWK"; do
> +  val=$(echo "$ref" | $AWK '{ printf "%d\n", $1 }' 2>&1) || continue
> +  test "$val" = "$ref" && status=0 && break
> +done
> +
> +test $status -eq 0 || { echo "No working AWK found" && exit $status; }
> +
> +for f in d i; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-int $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-ldouble.sh

> +#!/bin/bash
> +# Testing of long double printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +format=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +# For floating-point formats we need to use the bignum mode even if the
> +# regular mode would do, because GAWK in the latter mode uses sprintf(3)
> +# internally to process the conversion requested, so any bug in our code
> +# would then be verified against itself, defeating the objective of doing
> +# the verification against an independent implementation.
> +AWK="${AWK:-awk} -M"
> +
> +status=77
> +
> +# Verify that AWK can handle the range required.  It also catches:
> +# "gawk: warning: -M ignored: MPFR/GMP support not compiled in"
> +# message produced where bignum support is not there, which is the
> +# only indication as the use of '-M' does not affect the exit status
> +# in this case.
> +ref="-1.18973149535723176508575932662800702e+4932"
> +val=$(echo "$ref" | $AWK '{ PREC=113; printf "%.35e\n", $1 }' 2>&1) &&
> +  test "$val" = "$ref" && status=0
> +
> +test $status -eq 0 || { echo "No working AWK found" && exit $status; }
> +
> +# Check for any additional conversions that AWK handles conditionally
> +# according to its version and/or the environment it has been built in.
> +# The 'A' and 'a' conversions are not suitable to use at this point, as
> +# output produced by AWK is different apparently due to a subtlety in
> +# rounding, so do not try them.
> +declare -A conversion_disabled
> +ref="-inf"
> +for f in f F; do
> +  conversion_disabled[$f]=true
> +  val=$(echo "$ref" | $AWK '{ printf "%'$f'\n", $1 }' 2>&1) &&
> +    test "${val^^}" = "${ref^^}" && unset conversion_disabled[$f]
> +done
> +
> +if test "${conversion_disabled[$format]+set}" = set; then
> +  echo Unsupported $format
> +  status=77
> +else
> +  echo Verifying $format
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-ldouble $format |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 |
> +     sed "s/^/Conversion $format output error, first line:\n/") 2>&1 ||
> +    status=1
> +fi
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-llong.sh

> +#!/bin/bash
> +# Testing of long long int printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=77
> +
> +# Verify that AWK can handle the range required.  It also catches:
> +# "gawk: warning: -M ignored: MPFR/GMP support not compiled in"
> +# message produced where bignum support is not there, which is the
> +# only indication as the use of '-M' does not affect the exit status
> +# in this case.
> +ref="9223372036854775807"
> +for AWK in "$AWK -M" "$AWK"; do
> +  val=$(echo "$ref" | $AWK '{ printf "%d\n", $1 }' 2>&1) || continue
> +  test "$val" = "$ref" && status=0 && break
> +done
> +
> +test $status -eq 0 || { echo "No working AWK found" && exit $status; }
> +
> +for f in d i; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-llong $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-long.sh

> +#!/bin/bash
> +# Testing of long int printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=77
> +
> +# Verify that AWK can handle the range required.  It also catches:
> +# "gawk: warning: -M ignored: MPFR/GMP support not compiled in"
> +# message produced where bignum support is not there, which is the
> +# only indication as the use of '-M' does not affect the exit status
> +# in this case.
> +ref="9223372036854775807"
> +for AWK in "$AWK -M" "$AWK"; do
> +  val=$(echo "$ref" | $AWK '{ printf "%d\n", $1 }' 2>&1) || continue
> +  test "$val" = "$ref" && status=0 && break
> +done
> +
> +test $status -eq 0 || { echo "No working AWK found" && exit $status; }
> +
> +for f in d i; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-long $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-c.c

> +/* Test for formatted 'printf' output for the 'c' conversion.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-c.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-char.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-char.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for signed char conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-char.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-double.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-double.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for double conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-double.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-int.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-int.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for int conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-int.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-ldouble.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-ldouble.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for long double conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-ldouble.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-llong.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-llong.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for long long int conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-llong.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-long.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-long.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for long int conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-long.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-s.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-s.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for the 's' conversion.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-s.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-short.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-short.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for short int conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-short.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-uchar.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-uchar.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for unsigned char conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-uchar.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-uint.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-uint.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for unsigned int conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-uint.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-ullong.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-ullong.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for unsigned long long int conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-ullong.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-ulong.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-ulong.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for unsigned long int conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-ulong.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p-ushort.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p-ushort.c
> @@ -0,0 +1,20 @@
> +/* Test for formatted 'printf' output for unsigned short int conversions.
> +   Copyright (C) 2024 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 "tst-printf-format-p.h"
> +#include "tst-printf-format-skeleton-ushort.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-p.h
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-p.h
> @@ -0,0 +1,29 @@
> +/* Test feature wrapper for formatted 'printf' output.
> +   Copyright (C) 2024 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 <stdio.h>
> +
> +#define printf_under_test(...)						\
> +({									\
> +  int result;								\
> +									\
> +  result = printf (__VA_ARGS__);					\
> +  if (result < 0)							\
> +    perror ("printf");							\
> +  result;								\
> +})

Ok.

> Index: glibc/stdio-common/tst-printf-format-s.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-s.sh
> @@ -0,0 +1,34 @@
> +#!/bin/bash
> +# Testing of the 's' printf conversion.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +echo Verifying s
> +(set -o pipefail
> + ${test_program_prefix} \
> +  ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-s s |
> +   $AWK -f tst-printf-format.awk 2>&1 |
> +   head -n 1 | sed "s/^/Conversion s output error, first line:\n/") 2>&1 ||
> +  exit 1

Ok.

> Index: glibc/stdio-common/tst-printf-format-short.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-short.sh
> @@ -0,0 +1,40 @@
> +#!/bin/bash
> +# Testing of short int printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=0
> +
> +for f in d i; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-short $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-c.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-c.c
> @@ -0,0 +1,29 @@
> +/* Test skeleton for formatted printf output for the 'c' conversion.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 3
> +#define HUGE_WIDTH 4
> +#define REF_FMT "c"
> +#define REF_VAL(v) (v)
> +typedef unsigned char type_t;
> +static const type_t vals[] = { 0, 42, UCHAR_MAX };
> +static const char length[] = "";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-char.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-char.c
> @@ -0,0 +1,31 @@
> +/* Test skeleton for formatted printf output for signed char conversions.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 3
> +#define HUGE_WIDTH 5
> +#define REF_FMT "i"
> +#define REF_VAL(v) ((((v) & 0xff) ^ 0x80) - 0x80)
> +typedef int type_t;
> +static const type_t vals[] =
> +  { SCHAR_MIN - 123, SCHAR_MIN - 1, SCHAR_MIN, -123, -1, 0, 1, 42, SCHAR_MAX,
> +    SCHAR_MAX + 1, SCHAR_MAX + 42 };
> +static const char length[] = "hh";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-double.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-double.c
> @@ -0,0 +1,33 @@
> +/* Test skeleton for formatted printf output for double conversions.
> +   Copyright (C) 2024 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 <float.h>
> +#include <math.h>
> +
> +#define MID_WIDTH 20
> +#define HUGE_WIDTH 320
> +#define REF_FMT ".35e"
> +#define REF_VAL(v) (v)
> +#define PREC DBL_MANT_DIG
> +typedef double type_t;
> +static const type_t vals[] =
> +  { -HUGE_VAL, -DBL_MAX, -DBL_MIN, copysign (0, -1), -NAN, NAN, 0, DBL_MIN,
> +    DBL_MAX, HUGE_VAL };
> +static const char length[] = "";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-int.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-int.c
> @@ -0,0 +1,29 @@
> +/* Test skeleton for formatted printf output for int conversions.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 8
> +#define HUGE_WIDTH 15
> +#define REF_FMT "i"
> +#define REF_VAL(v) (v)
> +typedef int type_t;
> +static const type_t vals[] = { INT_MIN, -123, -1, 0, 1, 42, INT_MAX };
> +static const char length[] = "";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-ldouble.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-ldouble.c
> @@ -0,0 +1,38 @@
> +/* Test skeleton for formatted printf output for long double conversions.
> +   Copyright (C) 2024 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 <float.h>
> +#include <math.h>
> +#include <support/test-driver.h>
> +
> +#define MID_WIDTH 20
> +#define HUGE_WIDTH 4950
> +#define REF_FMT ".35Le"
> +#define REF_VAL(v) (v)
> +#define PREC LDBL_MANT_DIG
> +typedef long double type_t;
> +static const type_t vals[] =
> +  { -HUGE_VAL, -LDBL_MAX, -LDBL_MIN, copysign (0, -1), -NAN, NAN, 0, LDBL_MIN,
> +    LDBL_MAX, HUGE_VAL };
> +static const char length[] = "L";
> +
> +#ifndef TIMEOUT
> +# define TIMEOUT (DEFAULT_TIMEOUT * 64)
> +#endif
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-llong.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-llong.c
> @@ -0,0 +1,29 @@
> +/* Test skeleton for formatted printf output for long long int conversions.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 15
> +#define HUGE_WIDTH 25
> +#define REF_FMT "lli"
> +#define REF_VAL(v) (v)
> +typedef long long int type_t;
> +static const type_t vals[] = { LLONG_MIN, -123, -1, 0, 1, 42, LLONG_MAX };
> +static const char length[] = "ll";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-long.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-long.c
> @@ -0,0 +1,29 @@
> +/* Test skeleton for formatted printf output for long int conversions.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 15
> +#define HUGE_WIDTH 25
> +#define REF_FMT "li"
> +#define REF_VAL(v) (v)
> +typedef long int type_t;
> +static const type_t vals[] = { LONG_MIN, -123, -1, 0, 1, 42, LONG_MAX };
> +static const char length[] = "l";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-s.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-s.c
> @@ -0,0 +1,30 @@
> +/* Test skeleton for formatted printf output for the 's' conversion.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 5
> +#define HUGE_WIDTH 10
> +#define REF_FMT "s"
> +#define REF_VAL(v) (v)
> +typedef const char *type_t;
> +static const type_t vals[] =
> +  { "", "The", "quick", "brown fox", "jumps over the lazy dog" };
> +static const char length[] = "";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-short.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-short.c
> @@ -0,0 +1,31 @@
> +/* Test skeleton for formatted printf output for short int conversions.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 4
> +#define HUGE_WIDTH 7
> +#define REF_FMT "i"
> +#define REF_VAL(v) ((((v) & 0xffff) ^ 0x8000) - 0x8000)
> +typedef int type_t;
> +static const type_t vals[] =
> +  { SHRT_MIN - 123, SHRT_MIN - 1, SHRT_MIN, -123, -1, 0, 1, 42, SHRT_MAX,
> +    SHRT_MAX + 1, SHRT_MAX + 42 };
> +static const char length[] = "h";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-uchar.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-uchar.c
> @@ -0,0 +1,30 @@
> +/* Test skeleton for formatted printf output for unsigned char conversions.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 3
> +#define HUGE_WIDTH 4
> +#define REF_FMT "u"
> +#define REF_VAL(v) ((v) & 0xff)
> +typedef unsigned int type_t;
> +static const type_t vals[] =
> +  { 0, 1, 42, UCHAR_MAX, UCHAR_MAX + 1, UCHAR_MAX + 42 };
> +static const char length[] = "hh";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-uint.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-uint.c
> @@ -0,0 +1,29 @@
> +/* Test skeleton for formatted printf output for unsigned int conversions.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 7
> +#define HUGE_WIDTH 14
> +#define REF_FMT "u"
> +#define REF_VAL(v) (v)
> +typedef unsigned int type_t;
> +static const type_t vals[] = { 0, 1, 42, UINT_MAX };
> +static const char length[] = "";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-ullong.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-ullong.c
> @@ -0,0 +1,29 @@
> +/* Test skeleton for formatted printf output for unsigned long long int convs.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 14
> +#define HUGE_WIDTH 24
> +#define REF_FMT "llu"
> +#define REF_VAL(v) (v)
> +typedef unsigned long long int type_t;
> +static const type_t vals[] = { 0, 1, 42, UINT_MAX, ULLONG_MAX };
> +static const char length[] = "ll";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-ulong.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-ulong.c
> @@ -0,0 +1,29 @@
> +/* Test skeleton for formatted printf output for unsigned long int conversions.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 14
> +#define HUGE_WIDTH 24
> +#define REF_FMT "lu"
> +#define REF_VAL(v) (v)
> +typedef unsigned long int type_t;
> +static const type_t vals[] = { 0, 1, 42, ULONG_MAX };
> +static const char length[] = "l";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton-ushort.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton-ushort.c
> @@ -0,0 +1,30 @@
> +/* Test skeleton for formatted printf output for unsigned short int convs.
> +   Copyright (C) 2024 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 <limits.h>
> +
> +#define MID_WIDTH 3
> +#define HUGE_WIDTH 6
> +#define REF_FMT "u"
> +#define REF_VAL(v) ((v) & 0xffff)
> +typedef unsigned int type_t;
> +static const type_t vals[] =
> +  { 0, 1, 42, USHRT_MAX, USHRT_MAX + 1, USHRT_MAX + 42 };
> +static const char length[] = "h";
> +
> +#include "tst-printf-format-skeleton.c"

Ok.

> Index: glibc/stdio-common/tst-printf-format-skeleton.c
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-skeleton.c
> @@ -0,0 +1,380 @@
> +/* Test skeleton for formatted printf output.
> +   Copyright (C) 2024 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/>.  */
> +
> +/* The following definitions have to be supplied by the source including
> +   this skeleton:
> +
> +   Macros:
> +   MID_WIDTH	Medium width/precision positive integer constant.  Choose
> +		such as to cause some, but not all the strings produced
> +		to be truncated for the conversions handled.
> +   HUGE_WIDTH	Large width/precision positive integer constant.  Choose
> +		such as to cause none of the strings produced to be
> +		truncated for the conversions handled.
> +   REF_FMT	Reference output format string.  Use no flags and such
> +		a precision and length modifier, where applicable, and
> +		a conversion as to make sure the output produced allows
> +		the original value to be reproduced.
> +   REF_VAL(v)	Reference value V transformation.  For conversions with
> +		a truncating length modifier define such as to reproduce
> +		the truncation operation, otherwise let V pass through.
> +   PREC		[optional] Working precision positive integer constant.
> +		Set to the number of binary digits in the significand for
> +		the argument type handled; usually for floating-point
> +		conversions only, but it may be required for 128-bit or
> +		wider integer data types as well.
> +
> +   Typedefs:
> +   type_t	Variadic function argument type.  Define to the promoted
> +		type corresponding to the conversion argument type
> +		handled.
> +
> +   Variables:
> +   vals		Array of TYPE_T values.  Choose such as to cover boundary
> +		and any special cases.
> +   length	Length modifier string.  Define according to the
> +		conversion argument type handled.
> +
> +   The feature to be tested is wrapped into 'printf_under_test'.  It is up
> +   to the source including this skeleton if this is going to be a macro
> +   or an actual function.
> +
> +   See tst-*printf-format-*.c for usage examples.  */
> +
> +#include <array_length.h>
> +#include <dlfcn.h>
> +#include <mcheck.h>
> +#include <stdbool.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +

Ok.

> +/* Set to nonzero to select all possible tuples with repetitions of 1..n
> +   elements from the set of flags as defined in FLAGS array below; n is
> +   the length of FLAGS array.  Otherwise select all possible tuples with
> +   repetitions of 1..2 elements, followed by tuples of 3..n elements where
> +   the index of each element k; k = 2..n in FLAGS is lower than the index
> +   of element k-1 in FLAGS.  */
> +#ifndef TST_PRINTF_DUPS
> +# define TST_PRINTF_DUPS 0
> +#endif
> +/* Set to nonzero to report the precision (number of significand digits)
> +   required for floating-point calculations.  */
> +#ifndef PREC
> +# define PREC 0
> +#endif
> +
> +/* The list of conversions permitted for the '#' flag, the '0' flag,
> +   and precision respectively.  */
> +#define HASH_FORMATS "boxXaAeEfFgG"
> +#define ZERO_FORMATS "bdiouxXaAeEfFgG"
> +#define PREC_FORMATS "bdiouxXaAeEfFgGs"
> +

Ok.

> +/* Output format conversion flags.  */
> +static struct
> +{
> +  /* Flag character.  */
> +  char f;
> +  /* List of conversion specifiers the flag is valid for; NULL if all.  */
> +  const char *s;
> +} const flags[] =
> +  { {'-'}, {'+'}, {' '}, {'#', HASH_FORMATS}, {'0', ZERO_FORMATS} };
> +

Ok.

> +/* Helper to initialize elements of the PW array for the width and
> +   precision to be specified as a positive integer directly in the
> +   format, and then as both a negative and a positive argument to '*'.  */
> +#define STR(v) #v
> +#define WPINIT(v) {0, STR (v)}, {v, NULL}, {-v, NULL}
> +

Ok.

> +/* Width and precision settings to iterate over; zero is initialized
> +   directly as it has no corresponding negated value and other values
> +   use the helper above.  */
> +static struct wp
> +{
> +  /* Integer argument to '*', used if S is NULL.  */
> +  int i;
> +  /* String denoting an integer to use in the format, or NULL to use '*'.  */
> +  const char *s;
> +} const wp[] =
> +  { {0, "0"}, {0, NULL}, WPINIT (1), WPINIT (2),
> +    WPINIT (MID_WIDTH), WPINIT (HUGE_WIDTH) };
> +

Ok.

> +/* Produce a record according to '%' and zero or more output format flags
> +   already provided in FMT at indices 0..IDX-1, width W if non-NULL, '.'
> +   precision specifier if POINT set to true, precision P if non-NULL,
> +   any length modifiers L, conversion C, and value VAL.
> +
> +   Record formats produced:
> +
> +   %<FLAGS><L><C>:<VAL>:
> +   %<FLAGS>.<L><C>:<VAL>:
> +   %<FLAGS><W><L><C>:<VAL>:
> +   %<FLAGS><W>.<L><C>:<VAL>:
> +   %<FLAGS>.<P><L><C>:<VAL>:
> +   %<FLAGS><W>.<P><L><C>:<VAL>:
> +   %<FLAGS>*<L><C>:<W>:<VAL>:
> +   %<FLAGS>*.<L><C>:<W>:<VAL>:
> +   %<FLAGS>.*<L><C>:<P>:<VAL>:
> +   %<FLAGS>*.*<L><C>:<W>:<P>:<VAL>:
> +
> +   Return 0 on success, -1 on failure.  */
> +
> +static int
> +do_printf (char *fmt, size_t idx,
> +	   const struct wp *w, bool point, const struct wp *p,
> +	   const char *l, char c, type_t val)
> +{
> +  int wpval[2] = { 0 };
> +  size_t nint = 0;
> +  int result;
> +  size_t i;
> +
> +  if (w != NULL)
> +    {
> +      if (w->s == NULL)
> +	{
> +	  fmt[idx++] = '*';
> +	  wpval[nint++] = w->i;
> +	}
> +      else
> +	for (i = 0; w->s[i] != '\0'; i++)
> +	  fmt[idx++] = w->s[i];
> +    }

Ok.

> +  if (point)
> +    fmt[idx++] = '.';

Ok.

> +  if (p != NULL)
> +    {
> +      if (p->s == NULL)
> +	{
> +	  fmt[idx++] = '*';
> +	  wpval[nint++] = p->i;
> +	}
> +      else
> +	for (i = 0; p->s[i] != '\0'; i++)
> +	  fmt[idx++] = p->s[i];
> +    }

Ok.

> +  for (i = 0; length[i] != '\0'; i++)
> +    fmt[idx++] = length[i];

Ok.

> +  fmt[idx++] = c;
> +  fmt[idx] = ':';
> +  fmt[idx + 1] = '\0';

Ok.

> +  if (fputs (fmt, stdout) == EOF)
> +    {
> +      perror ("fputs");
> +      return -1;
> +    }
> +  fmt[idx++] = '\0';

Ok.

> +  if (nint > 0)
> +    {
> +      result = printf ("%i:", wpval[0]);
> +      if (result < 0)
> +	{
> +	  perror ("printf");
> +	  return -1;
> +	}
> +      if (nint > 1)
> +	{
> +	  result = printf ("%i:", wpval[1]);
> +	  if (result < 0)
> +	    {
> +	      perror ("printf");
> +	      return -1;
> +	    }
> +	}
> +    }

Ok.

> +  switch (nint)
> +    {
> +    case 0:
> +      result = printf_under_test (fmt, val);
> +      break;
> +    case 1:
> +      result = printf_under_test (fmt, wpval[0], val);
> +      break;
> +    case 2:
> +      result = printf_under_test (fmt, wpval[0], wpval[1], val);
> +      break;
> +    default:
> +      fputs ("Broken test, nint > 2\n", stderr);
> +      return -1;
> +    }

Ok.

> +  if (result < 0)
> +    return -1;
> +  if (fputs (":\n", stdout) == EOF)
> +    {
> +      perror ("fputs");
> +      return -1;
> +    }
> +  return 0;
> +}
> +

Ok.

> +/* Produce a list of records according to '%' and zero or more output
> +   format flags already provided in FMT at indices 0..IDX-1, iterating
> +   over widths and precisions defined in global WP array, any length
> +   modifiers L, conversion C, and value VAL.  Inline '0' is omitted for
> +   the width, as it is a flag already handled among the flags supplied.
> +   Precision is omitted where the conversion does not allow it.
> +
> +   Return 0 on success, -1 on failure.  */
> +
> +static int
> +do_printf_flags (char *fmt, size_t idx, const char *l, char c, type_t val)
> +{
> +  bool do_prec = strchr (PREC_FORMATS, c) != NULL;
> +  size_t i;
> +
> +  if (do_printf (fmt, idx, NULL, false, NULL, l, c, val) < 0)
> +    return -1;
> +  if (do_prec && do_printf (fmt, idx, NULL, true, NULL, l, c, val) < 0)
> +    return -1;
> +  for (i = 0; i < array_length (wp); i++)
> +    {
> +      size_t j;
> +
> +      if (do_prec && do_printf (fmt, idx, NULL, true, wp + i, l, c, val) < 0)
> +	return -1;
> +      /* Inline '0' is a flag rather than width and is handled elsewhere.  */
> +      if (wp[i].s != NULL && wp[i].s[0] == '0' && wp[i].s[1] == '\0')
> +	continue;
> +      if (do_printf (fmt, idx, wp + i, false, NULL, l, c, val) < 0)
> +	return -1;
> +      if (do_prec)
> +	{
> +	  if (do_printf (fmt, idx, wp + i, true, NULL, l, c, val) < 0)
> +	    return -1;
> +	  for (j = 0; j < array_length (wp); j++)
> +	    if (do_printf (fmt, idx, wp + i, true, wp + j, l, c, val) < 0)
> +	      return -1;
> +	}
> +    }
> +  return 0;
> +}
> +

Ok.

> +/* Produce a list of records using the formatted output specifier
> +   supplied in ARGV[1] preceded by any length modifier supplied in
> +   the global LENGTH variable, iterating over format flags defined
> +   in the global FLAGS array, and values supplied in the global VALS
> +   array.  Note that the output specifier supplied is not verified
> +   against TYPE_T, so undefined behavior will result if this is used
> +   incorrectly.
> +
> +   If PREC is nonzero, then this record:
> +
> +   prec:<PREC>
> +
> +   is produced at the beginning.  Then for each VAL from VALS a block
> +   of records is produced starting with:
> +
> +   val:<VAL>
> +
> +   where VAL is formatted according to REF_FMT output format.  The
> +   block continues with records as shown with DO_PRINTF above using
> +   flags iterated over according to TST_PRINTF_DUPS.
> +
> +   See the top of this file for the definitions that have to be
> +   provided by the source including this skeleton.  */
> +
> +static int
> +do_test (int argc, char *argv[])
> +{
> +  char fmt[100] = {'%'};
> +  size_t j;
> +  size_t v;
> +  char c;
> +
> +  if (argc < 2 || *argv[1] == '\0')
> +    {
> +      fprintf (stderr, "Usage: %s <specifier>\n", basename (argv[0]));
> +      return EXIT_FAILURE;
> +    }
> +

Ok.

> +  mtrace ();
> +
> +  if (PREC && printf ("prec:%i\n", PREC) < 0)
> +    {
> +      perror ("printf");
> +      return EXIT_FAILURE;
> +    }
> +

Ok.

> +  c = *argv[1];
> +  for (v = 0; v < array_length (vals); v++)
> +    {
> +      if (printf ("val:%" REF_FMT "\n", REF_VAL (vals[v])) < 0)
> +	{
> +	  perror ("printf");
> +	  return EXIT_FAILURE;
> +	}
> +

Ok.

> +      if (do_printf_flags (fmt, 1, length, c, vals[v]) < 0)
> +	return EXIT_FAILURE;

Ok.

> +      for (j = 0; j < array_length (flags); j++)
> +	{
> +	  bool done = false;
> +	  size_t i[j + 1];
> +	  size_t k;
> +
> +	  memset (i, 0, sizeof (i));
> +	  while (!done)
> +	    {
> +	      bool skip = false;
> +	      size_t idx = 1;
> +	      char f;
> +
> +	      for (k = 0; k <= j; k++)
> +		{
> +		  const char *s = flags[i[k]].s;
> +
> +		  if (s && strchr (s, c) == NULL)
> +		    skip = true;
> +		  if (!TST_PRINTF_DUPS && j > 1 && k > 0 && i[k] >= i[k - 1])
> +		    skip = true;
> +		  if (skip)
> +		    break;
> +
> +		  f = flags[i[k]].f;
> +		  fmt[idx++] = f;
> +		}
> +	      if (!skip && do_printf_flags (fmt, idx, length, c, vals[v]) < 0)
> +		return EXIT_FAILURE;
> +	      for (k = 0; k <= j; k++)
> +		{
> +		  i[k]++;
> +		  if (i[k] < array_length (flags))
> +		    break;
> +		  else if (k == j)
> +		    done = true;
> +		  else
> +		    i[k] = 0;
> +		}
> +	    }
> +	}
> +    }
> +
> +  return EXIT_SUCCESS;
> +}

Ok.

> +
> +/* Interpose 'dladdr' with a stub to speed up malloc tracing.  */
> +
> +int
> +dladdr (const void *, Dl_info *)
> +{
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION_ARGV do_test
> +#include <support/test-driver.c>

Ok.

> Index: glibc/stdio-common/tst-printf-format-uchar.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-uchar.sh
> @@ -0,0 +1,40 @@
> +#!/bin/bash
> +# Testing of unsigned char printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=0
> +
> +for f in o u x X; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-uchar $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-uint.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-uint.sh
> @@ -0,0 +1,53 @@
> +#!/bin/bash
> +# Testing of unsigned int printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=77
> +
> +# Verify that AWK can handle the range required.  It also catches:
> +# "gawk: warning: -M ignored: MPFR/GMP support not compiled in"
> +# message produced where bignum support is not there, which is the
> +# only indication as the use of '-M' does not affect the exit status
> +# in this case.
> +ref="4294967295"
> +for AWK in "$AWK -M" "$AWK"; do
> +  val=$(echo "$ref" | $AWK '{ printf "%d\n", $1 }' 2>&1) || continue
> +  test "$val" = "$ref" && status=0 && break
> +done
> +
> +test $status -eq 0 || { echo "No working AWK found" && exit $status; }
> +
> +for f in o u x X; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-uint $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-ullong.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-ullong.sh
> @@ -0,0 +1,53 @@
> +#!/bin/bash
> +# Testing of unsigned long long int printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=77
> +
> +# Verify that AWK can handle the range required.  It also catches:
> +# "gawk: warning: -M ignored: MPFR/GMP support not compiled in"
> +# message produced where bignum support is not there, which is the
> +# only indication as the use of '-M' does not affect the exit status
> +# in this case.
> +ref="18446744073709551615"
> +for AWK in "$AWK -M" "$AWK"; do
> +  val=$(echo "$ref" | $AWK '{ printf "%d\n", $1 }' 2>&1) || continue
> +  test "$val" = "$ref" && status=0 && break
> +done
> +
> +test $status -eq 0 || { echo "No working AWK found" && exit $status; }
> +
> +for f in o u x X; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-ullong $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-ulong.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-ulong.sh
> @@ -0,0 +1,53 @@
> +#!/bin/bash
> +# Testing of unsigned long int printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=77
> +
> +# Verify that AWK can handle the range required.  It also catches:
> +# "gawk: warning: -M ignored: MPFR/GMP support not compiled in"
> +# message produced where bignum support is not there, which is the
> +# only indication as the use of '-M' does not affect the exit status
> +# in this case.
> +ref="18446744073709551615"
> +for AWK in "$AWK -M" "$AWK"; do
> +  val=$(echo "$ref" | $AWK '{ printf "%d\n", $1 }' 2>&1) || continue
> +  test "$val" = "$ref" && status=0 && break
> +done
> +
> +test $status -eq 0 || { echo "No working AWK found" && exit $status; }
> +
> +for f in o u x X; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-ulong $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format-ushort.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format-ushort.sh
> @@ -0,0 +1,40 @@
> +#!/bin/bash
> +# Testing of unsigned short int printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +xprintf=$1; shift
> +common_objpfx=$1; shift
> +test_program_prefix=$1; shift
> +
> +AWK=${AWK:-awk}
> +
> +status=0
> +
> +for f in o u x X; do
> +  echo Verifying $f
> +  (set -o pipefail
> +   ${test_program_prefix} \
> +    ${common_objpfx}stdio-common/tst-printf-format-${xprintf}-ushort $f |
> +     $AWK -f tst-printf-format.awk 2>&1 |
> +     head -n 1 | sed "s/^/Conversion $f output error, first line:\n/") 2>&1 ||
> +    status=1
> +done
> +
> +exit $status

Ok.

> Index: glibc/stdio-common/tst-printf-format.awk
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format.awk
> @@ -0,0 +1,127 @@
> +# Testing of printf conversions.
> +# Copyright (C) 2024 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/>.
> +
> +BEGIN {
> +  FS = ":"
> +}
> +
> +/^prec:/ {
> +  PREC = $2
> +  next
> +}
> +
> +/^val:/ {
> +  val = $2
> +  # Prepend "+" for +Inf or +NaN value lacking a sign, because gawk
> +  # interpretes them as strings rather than numeric values in the
> +  # non-bignum mode unless a sign has been explicitly given.  Keep
> +  # original 'val' for reporting.
> +  value = gensub(/^(INF|NAN|inf|nan)/, "+\\1", 1, val)
> +  next
> +}
> +

Ok.

> +/^%/ {
> +  # Discard the trailing empty field, used to improve legibility of data.
> +  input = $--NF
> +  format = $1
> +  width = $2
> +  precision = "." $(NF - 1)
> +  # Discard any negative precision, which is to be taken as if omitted.
> +  sub(/\.-.*/, "", precision)
> +  # Simplify handling and paste the precision and width specified as
> +  # arguments to '*' directly into the format.
> +  sub(/\.\*/, precision, format)
> +  sub(/\*/, width, format)
> +  # Discard length modifiers.  They are only relevant to C data types.
> +  sub(/([DHLjhltz]|wf?[1-9][0-9]*)/, "", format)
> +  # Discard the '#' flag with the octal conversion if output starts with
> +  # 0 in the absence of this flag.  In that case no extra 0 is supposed
> +  # to be produced, but gawk prepends it anyway.
> +  if (format ~ /#.*o/)
> +    {
> +      tmpfmt = gensub(/#/, "", "g", format)
> +      tmpout = sprintf(tmpfmt, value)
> +      if (tmpout ~ /^ *0/)
> +	format = tmpfmt
> +    }

Ok.

> +  # Likewise with the hexadecimal conversion where zero value with the
> +  # precision of zero is supposed to produce no characters, but gawk
> +  # outputs 0 instead.
> +  else if (format ~ /#.*[Xx]/)
> +    {
> +      tmpfmt = gensub(/#/, "", "g", format)
> +      tmpout = sprintf(tmpfmt, value)
> +      if (tmpout ~ /^ *$/)
> +	format = tmpfmt
> +    }

Ok.

> +  # AWK interpretes input opportunistically as a number, which interferes
> +  # with how the 'c' conversion works: "a" input will result in "a" output
> +  # however "0" input will result in "^@" output rather than "0".  Force
> +  # the value to be interpreted as a string then, by appending "".
> +  output = sprintf(format, value "")

Ok.

> +  # Make up for various anomalies with the handling of +/-Inf and +/-NaN
> +  # values and reprint the output produced using the string conversion,
> +  # with the field width carried over and the relevant flags handled by
> +  # hand.
> +  if (format ~ /[EFGefg]/ && value ~ /(INF|NAN|inf|nan)/)
> +    {
> +      minus = format ~ /-/ ? "-" : ""
> +      sign = value ~ /-/ ? "-" : format ~ /\+/ ? "+" : format ~ / / ? " " : ""
> +      if (format ~ /^%[^\.1-9]*[1-9][0-9]*/)
> +	width = gensub(/^%[^\.1-9]*([1-9][0-9]*).*$/, "\\1", 1, format)
> +      else
> +	width = ""
> +      output = gensub(/[-+ ]/, "", "g", output)
> +      output = sprintf("%" minus width "s", sign output)
> +    }

Ok.

> +  # Produce "+" where the '+' flag has been used with a signed integer
> +  # conversion for zero value, observing any field width in effect.
> +  # In that case "+" is always supposed to be produced, but with the
> +  # precision of zero gawk in the non-bignum mode produces any padding
> +  # requested only.
> +  else if (format ~ /\+.*[di]/ && value == 0)
> +    {
> +      output = gensub(/^( *) $/, format ~ /-/ ? "+\\1" : "\\1+", 1, output)
> +      output = gensub(/^$/, "+", 1, output)
> +    }

Ok.

> +  # Produce " " where the space flag has been used with a signed integer
> +  # conversion for zero value.  In that case at least one " " is
> +  # supposed to be produced, but with the precision of zero gawk in the
> +  # non-bignum mode produces nothing.
> +  else if (format ~ / .*[di]/ && value == 0)
> +    {
> +      output = gensub(/^$/, " ", 1, output)
> +    }
> +  if (output != input)
> +    {
> +      printf "(\"%s\"%s%s, %s) => \"%s\", expected \"%s\"\n", \
> +	     $1, (NF > 2 ? ", " $2 : ""), (NF > 3 ? ", " $3 : ""), val, \
> +	     input, output > "/dev/stderr"
> +      status = 1
> +    }
> +  next
> +}
> +

Ok.

> +{
> +  printf "unrecognized input: \"%s\"\n", $0 > "/dev/stderr"
> +  status = 1
> +}
> +
> +END {
> +  exit status
> +}

Ok.

> Index: glibc/stdio-common/tst-printf-format.sh
> ===================================================================
> --- /dev/null
> +++ glibc/stdio-common/tst-printf-format.sh
> @@ -0,0 +1,39 @@
> +#!/bin/bash
> +# Formatted printf output test script dispatcher.
> +# Copyright (C) 2024 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/>.
> +
> +set -e
> +
> +output=${1##*/}; shift
> +
> +tmp=${output#tst-printf-format-}
> +tmp=${tmp%.out}
> +
> +# We are given the name of the make target in $1.  With the common prefix
> +# and suffix both removed we are left with the inner part, which encodes
> +# the function under test, the conversion type, and optionally the format
> +# specifier, all separated with hyphens, i.e. F-T-S or F-T.  Extract them
> +# and call the script corresponding to the conversion type, passing the
> +# function under test and any format specifier as arguments.
> +
> +xprintf=${tmp%%-*}; tmp=${tmp#*-}
> +conv=${tmp%%-*}; tmp=${tmp#${conv}}
> +fmt=${tmp#*-}
> +script=tst-printf-format-$conv.sh
> +
> +exec ${BASH:-bash} $script $xprintf $fmt "$@"

Ok.



More information about the Libc-alpha mailing list