[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