aboutsummaryrefslogtreecommitdiff
path: root/stdio-common
diff options
context:
space:
mode:
Diffstat (limited to 'stdio-common')
-rw-r--r--stdio-common/Makefile150
-rw-r--r--stdio-common/tst-fdopen2.c246
-rw-r--r--stdio-common/tst-fgets2.c253
-rw-r--r--stdio-common/tst-fread.c134
-rw-r--r--stdio-common/tst-freopen2-main.c519
-rw-r--r--stdio-common/tst-freopen2.c3
-rw-r--r--stdio-common/tst-freopen3-main.c92
-rw-r--r--stdio-common/tst-freopen3.c2
-rw-r--r--stdio-common/tst-freopen4-main.c102
-rw-r--r--stdio-common/tst-freopen4.c2
-rw-r--r--stdio-common/tst-freopen5.c144
-rw-r--r--stdio-common/tst-freopen6-main.c98
-rw-r--r--stdio-common/tst-freopen6.c2
-rw-r--r--stdio-common/tst-freopen64-2.c3
-rw-r--r--stdio-common/tst-freopen64-3.c2
-rw-r--r--stdio-common/tst-freopen64-4.c2
-rw-r--r--stdio-common/tst-freopen64-6.c2
-rw-r--r--stdio-common/tst-freopen64-7.c2
-rw-r--r--stdio-common/tst-freopen7-main.c155
-rw-r--r--stdio-common/tst-freopen7.c2
-rw-r--r--stdio-common/tst-fwrite-memstrm.c177
-rw-r--r--stdio-common/tst-fwrite-overflow.c130
-rw-r--r--stdio-common/tst-fwrite-ro.c65
-rw-r--r--stdio-common/tst-getline-enomem.c78
-rw-r--r--stdio-common/tst-getline.c451
-rw-r--r--stdio-common/tst-printf-format-as-c.c20
-rw-r--r--stdio-common/tst-printf-format-as-char.c20
-rw-r--r--stdio-common/tst-printf-format-as-double.c22
-rw-r--r--stdio-common/tst-printf-format-as-int.c20
-rw-r--r--stdio-common/tst-printf-format-as-ldouble.c22
-rw-r--r--stdio-common/tst-printf-format-as-llong.c20
-rw-r--r--stdio-common/tst-printf-format-as-long.c20
-rw-r--r--stdio-common/tst-printf-format-as-s.c20
-rw-r--r--stdio-common/tst-printf-format-as-short.c20
-rw-r--r--stdio-common/tst-printf-format-as-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-as-uint.c20
-rw-r--r--stdio-common/tst-printf-format-as-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-as-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-as-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-as.h46
-rw-r--r--stdio-common/tst-printf-format-c.sh34
-rw-r--r--stdio-common/tst-printf-format-char.sh40
-rw-r--r--stdio-common/tst-printf-format-d-c.c20
-rw-r--r--stdio-common/tst-printf-format-d-char.c20
-rw-r--r--stdio-common/tst-printf-format-d-double.c20
-rw-r--r--stdio-common/tst-printf-format-d-int.c20
-rw-r--r--stdio-common/tst-printf-format-d-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-d-llong.c20
-rw-r--r--stdio-common/tst-printf-format-d-long.c20
-rw-r--r--stdio-common/tst-printf-format-d-s.c20
-rw-r--r--stdio-common/tst-printf-format-d-short.c20
-rw-r--r--stdio-common/tst-printf-format-d-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-d-uint.c20
-rw-r--r--stdio-common/tst-printf-format-d-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-d-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-d-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-d.h58
-rw-r--r--stdio-common/tst-printf-format-double.sh74
-rw-r--r--stdio-common/tst-printf-format-f-c.c20
-rw-r--r--stdio-common/tst-printf-format-f-char.c20
-rw-r--r--stdio-common/tst-printf-format-f-double.c20
-rw-r--r--stdio-common/tst-printf-format-f-int.c20
-rw-r--r--stdio-common/tst-printf-format-f-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-f-llong.c20
-rw-r--r--stdio-common/tst-printf-format-f-long.c20
-rw-r--r--stdio-common/tst-printf-format-f-s.c20
-rw-r--r--stdio-common/tst-printf-format-f-short.c20
-rw-r--r--stdio-common/tst-printf-format-f-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-f-uint.c20
-rw-r--r--stdio-common/tst-printf-format-f-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-f-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-f-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-f.h29
-rw-r--r--stdio-common/tst-printf-format-int.sh53
-rw-r--r--stdio-common/tst-printf-format-ldouble.sh74
-rw-r--r--stdio-common/tst-printf-format-llong.sh53
-rw-r--r--stdio-common/tst-printf-format-long.sh53
-rw-r--r--stdio-common/tst-printf-format-p-c.c20
-rw-r--r--stdio-common/tst-printf-format-p-char.c20
-rw-r--r--stdio-common/tst-printf-format-p-double.c20
-rw-r--r--stdio-common/tst-printf-format-p-int.c20
-rw-r--r--stdio-common/tst-printf-format-p-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-p-llong.c20
-rw-r--r--stdio-common/tst-printf-format-p-long.c20
-rw-r--r--stdio-common/tst-printf-format-p-s.c20
-rw-r--r--stdio-common/tst-printf-format-p-short.c20
-rw-r--r--stdio-common/tst-printf-format-p-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-p-uint.c20
-rw-r--r--stdio-common/tst-printf-format-p-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-p-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-p-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-p.h29
-rw-r--r--stdio-common/tst-printf-format-s-c.c20
-rw-r--r--stdio-common/tst-printf-format-s-char.c20
-rw-r--r--stdio-common/tst-printf-format-s-double.c20
-rw-r--r--stdio-common/tst-printf-format-s-int.c20
-rw-r--r--stdio-common/tst-printf-format-s-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-s-llong.c20
-rw-r--r--stdio-common/tst-printf-format-s-long.c20
-rw-r--r--stdio-common/tst-printf-format-s-s.c20
-rw-r--r--stdio-common/tst-printf-format-s-short.c20
-rw-r--r--stdio-common/tst-printf-format-s-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-s-uint.c20
-rw-r--r--stdio-common/tst-printf-format-s-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-s-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-s-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-s.h60
-rw-r--r--stdio-common/tst-printf-format-s.sh34
-rw-r--r--stdio-common/tst-printf-format-short.sh40
-rw-r--r--stdio-common/tst-printf-format-skeleton-c.c29
-rw-r--r--stdio-common/tst-printf-format-skeleton-char.c31
-rw-r--r--stdio-common/tst-printf-format-skeleton-double.c33
-rw-r--r--stdio-common/tst-printf-format-skeleton-int.c29
-rw-r--r--stdio-common/tst-printf-format-skeleton-ldouble.c38
-rw-r--r--stdio-common/tst-printf-format-skeleton-llong.c29
-rw-r--r--stdio-common/tst-printf-format-skeleton-long.c29
-rw-r--r--stdio-common/tst-printf-format-skeleton-s.c30
-rw-r--r--stdio-common/tst-printf-format-skeleton-short.c31
-rw-r--r--stdio-common/tst-printf-format-skeleton-uchar.c30
-rw-r--r--stdio-common/tst-printf-format-skeleton-uint.c29
-rw-r--r--stdio-common/tst-printf-format-skeleton-ullong.c29
-rw-r--r--stdio-common/tst-printf-format-skeleton-ulong.c29
-rw-r--r--stdio-common/tst-printf-format-skeleton-ushort.c30
-rw-r--r--stdio-common/tst-printf-format-skeleton.c380
-rw-r--r--stdio-common/tst-printf-format-sn-c.c20
-rw-r--r--stdio-common/tst-printf-format-sn-char.c20
-rw-r--r--stdio-common/tst-printf-format-sn-double.c20
-rw-r--r--stdio-common/tst-printf-format-sn-int.c20
-rw-r--r--stdio-common/tst-printf-format-sn-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-sn-llong.c20
-rw-r--r--stdio-common/tst-printf-format-sn-long.c20
-rw-r--r--stdio-common/tst-printf-format-sn-s.c20
-rw-r--r--stdio-common/tst-printf-format-sn-short.c20
-rw-r--r--stdio-common/tst-printf-format-sn-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-sn-uint.c20
-rw-r--r--stdio-common/tst-printf-format-sn-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-sn-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-sn-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-sn.h60
-rw-r--r--stdio-common/tst-printf-format-uchar.sh40
-rw-r--r--stdio-common/tst-printf-format-uint.sh53
-rw-r--r--stdio-common/tst-printf-format-ullong.sh53
-rw-r--r--stdio-common/tst-printf-format-ulong.sh53
-rw-r--r--stdio-common/tst-printf-format-ushort.sh40
-rw-r--r--stdio-common/tst-printf-format-v-c.c20
-rw-r--r--stdio-common/tst-printf-format-v-char.c20
-rw-r--r--stdio-common/tst-printf-format-v-double.c20
-rw-r--r--stdio-common/tst-printf-format-v-int.c20
-rw-r--r--stdio-common/tst-printf-format-v-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-v-llong.c20
-rw-r--r--stdio-common/tst-printf-format-v-long.c20
-rw-r--r--stdio-common/tst-printf-format-v-s.c20
-rw-r--r--stdio-common/tst-printf-format-v-short.c20
-rw-r--r--stdio-common/tst-printf-format-v-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-v-uint.c20
-rw-r--r--stdio-common/tst-printf-format-v-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-v-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-v-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-v.h34
-rw-r--r--stdio-common/tst-printf-format-vas-c.c20
-rw-r--r--stdio-common/tst-printf-format-vas-char.c20
-rw-r--r--stdio-common/tst-printf-format-vas-double.c22
-rw-r--r--stdio-common/tst-printf-format-vas-int.c20
-rw-r--r--stdio-common/tst-printf-format-vas-ldouble.c22
-rw-r--r--stdio-common/tst-printf-format-vas-llong.c20
-rw-r--r--stdio-common/tst-printf-format-vas-long.c20
-rw-r--r--stdio-common/tst-printf-format-vas-s.c20
-rw-r--r--stdio-common/tst-printf-format-vas-short.c20
-rw-r--r--stdio-common/tst-printf-format-vas-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-vas-uint.c20
-rw-r--r--stdio-common/tst-printf-format-vas-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-vas-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-vas-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-vas.h50
-rw-r--r--stdio-common/tst-printf-format-vd-c.c20
-rw-r--r--stdio-common/tst-printf-format-vd-char.c20
-rw-r--r--stdio-common/tst-printf-format-vd-double.c20
-rw-r--r--stdio-common/tst-printf-format-vd-int.c20
-rw-r--r--stdio-common/tst-printf-format-vd-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-vd-llong.c20
-rw-r--r--stdio-common/tst-printf-format-vd-long.c20
-rw-r--r--stdio-common/tst-printf-format-vd-s.c20
-rw-r--r--stdio-common/tst-printf-format-vd-short.c20
-rw-r--r--stdio-common/tst-printf-format-vd-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-vd-uint.c20
-rw-r--r--stdio-common/tst-printf-format-vd-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-vd-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-vd-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-vd.h62
-rw-r--r--stdio-common/tst-printf-format-vf-c.c20
-rw-r--r--stdio-common/tst-printf-format-vf-char.c20
-rw-r--r--stdio-common/tst-printf-format-vf-double.c20
-rw-r--r--stdio-common/tst-printf-format-vf-int.c20
-rw-r--r--stdio-common/tst-printf-format-vf-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-vf-llong.c20
-rw-r--r--stdio-common/tst-printf-format-vf-long.c20
-rw-r--r--stdio-common/tst-printf-format-vf-s.c20
-rw-r--r--stdio-common/tst-printf-format-vf-short.c20
-rw-r--r--stdio-common/tst-printf-format-vf-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-vf-uint.c20
-rw-r--r--stdio-common/tst-printf-format-vf-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-vf-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-vf-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-vf.h34
-rw-r--r--stdio-common/tst-printf-format-vs-c.c20
-rw-r--r--stdio-common/tst-printf-format-vs-char.c20
-rw-r--r--stdio-common/tst-printf-format-vs-double.c20
-rw-r--r--stdio-common/tst-printf-format-vs-int.c20
-rw-r--r--stdio-common/tst-printf-format-vs-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-vs-llong.c20
-rw-r--r--stdio-common/tst-printf-format-vs-long.c20
-rw-r--r--stdio-common/tst-printf-format-vs-s.c20
-rw-r--r--stdio-common/tst-printf-format-vs-short.c20
-rw-r--r--stdio-common/tst-printf-format-vs-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-vs-uint.c20
-rw-r--r--stdio-common/tst-printf-format-vs-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-vs-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-vs-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-vs.h64
-rw-r--r--stdio-common/tst-printf-format-vsn-c.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-char.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-double.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-int.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-ldouble.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-llong.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-long.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-s.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-short.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-uchar.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-uint.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-ullong.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-ulong.c20
-rw-r--r--stdio-common/tst-printf-format-vsn-ushort.c20
-rw-r--r--stdio-common/tst-printf-format-vsn.h64
-rw-r--r--stdio-common/tst-printf-format.awk127
-rw-r--r--stdio-common/tst-printf-format.sh39
-rw-r--r--stdio-common/tst-renameat2.c2
-rw-r--r--stdio-common/tst-scanf-nan.c83
-rw-r--r--stdio-common/tst-ungetc-leak.c32
-rw-r--r--stdio-common/tst-ungetc.c114
-rw-r--r--stdio-common/vfscanf-internal.c46
241 files changed, 8659 insertions, 58 deletions
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index e4f0146..e76e40e 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -22,6 +22,34 @@ subdir := stdio-common
include ../Makeconfig
+# List of markers for printf family function tests.
+xprintf-funcs := p as d f s sn v vas vd vf vs vsn
+
+# 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))
+
headers := \
bits/printf-ldbl.h \
bits/stdio_lim.h \
@@ -207,8 +235,10 @@ tests := \
tst-cookie \
tst-dprintf-length \
tst-fdopen \
+ tst-fdopen2 \
tst-ferror \
tst-fgets \
+ tst-fgets2 \
tst-fileno \
tst-fmemopen \
tst-fmemopen2 \
@@ -216,8 +246,25 @@ tests := \
tst-fmemopen4 \
tst-fphex \
tst-fphex-wide \
+ tst-fread \
+ tst-freopen2 \
+ tst-freopen3 \
+ tst-freopen4 \
+ tst-freopen5 \
+ tst-freopen6 \
+ tst-freopen64-2 \
+ tst-freopen64-3 \
+ tst-freopen64-4 \
+ tst-freopen64-6 \
+ tst-freopen64-7 \
+ tst-freopen7 \
tst-fseek \
tst-fwrite \
+ tst-fwrite-memstrm \
+ tst-fwrite-overflow \
+ tst-fwrite-ro \
+ tst-getline \
+ tst-getline-enomem \
tst-gets \
tst-grouping \
tst-grouping2 \
@@ -242,6 +289,7 @@ tests := \
tst-scanf-binary-gnu89 \
tst-scanf-bz27650 \
tst-scanf-intn \
+ tst-scanf-nan \
tst-scanf-round \
tst-scanf-to_inpunct \
tst-setvbuf1 \
@@ -254,6 +302,7 @@ tests := \
tst-swscanf \
tst-tmpnam \
tst-ungetc \
+ tst-ungetc-leak \
tst-unlockedio \
tst-vfprintf-mbs-prec \
tst-vfprintf-user-type \
@@ -296,6 +345,7 @@ tests-internal = \
# tests-internal
test-srcs = \
+ $(xprintf-srcs) \
tst-printf \
tst-printfsz-islongdouble \
tst-unbputc \
@@ -303,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 \
@@ -312,14 +363,51 @@ 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 \
+ $(objpfx)tst-freopen5-mem.out \
+ $(objpfx)tst-freopen6-mem.out \
+ $(objpfx)tst-freopen64-2-mem.out \
+ $(objpfx)tst-freopen64-3-mem.out \
+ $(objpfx)tst-freopen64-4-mem.out \
+ $(objpfx)tst-freopen64-6-mem.out \
+ $(objpfx)tst-getline-enomem-mem.out \
+ $(objpfx)tst-getline-mem.out \
$(objpfx)tst-printf-bz18872-mem.out \
$(objpfx)tst-printf-bz25691-mem.out \
$(objpfx)tst-printf-fp-free-mem.out \
$(objpfx)tst-printf-fp-leak-mem.out \
+ $(objpfx)tst-ungetc-leak-mem.out \
$(objpfx)tst-vfprintf-width-prec-mem.out \
# 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 \
+ tst-freopen3.mtrace \
+ tst-freopen4-mem.out \
+ tst-freopen4.mtrace \
+ tst-freopen5-mem.out \
+ tst-freopen5.mtrace \
+ tst-freopen6-mem.out \
+ tst-freopen6.mtrace \
+ tst-freopen64-2-mem.out \
+ tst-freopen64-2.mtrace \
+ tst-freopen64-3-mem.out \
+ tst-freopen64-3.mtrace \
+ tst-freopen64-4-mem.out \
+ tst-freopen64-4.mtrace \
+ tst-freopen64-6-mem.out \
+ tst-freopen64-6.mtrace \
+ tst-getline-enomem-mem.out \
+ tst-getline-enomem.mtrace \
+ tst-getline-mem.out \
+ tst-getline.mtrace \
tst-printf-bz18872-mem.out \
tst-printf-bz18872.c \
tst-printf-bz18872.mtrace \
@@ -330,6 +418,8 @@ generated += \
tst-printf-fp-leak-mem.out \
tst-printf-fp-leak.mtrace \
tst-scanf-bz27650.mtrace \
+ tst-ungetc-leak-mem.out \
+ tst-ungetc-leak.mtrace \
tst-vfprintf-width-prec-mem.out \
tst-vfprintf-width-prec.mtrace \
# generated
@@ -424,6 +514,42 @@ tst-printf-fp-leak-ENV = \
tst-scanf-bz27650-ENV = \
MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \
LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-ungetc-leak-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-ungetc-leak.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-getline-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-getline.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-getline-enomem-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-getline-enomem.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen2-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen2.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen64-2-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen64-2.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen3-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen3.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen64-3-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen64-3.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen4-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen4.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen64-4-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen64-4.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen5-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen5.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen6-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen6.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
+tst-freopen64-6-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-freopen64-6.mtrace \
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
$(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
@@ -433,6 +559,21 @@ $(objpfx)tst-printf.out: tst-printf.sh $(objpfx)tst-printf
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
$(evaluate-test)
+# 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)
+
$(objpfx)tst-printfsz-islongdouble.out: \
tst-printfsz-islongdouble.sh $(objpfx)tst-printfsz-islongdouble
$(SHELL) $^ '$(test-program-prefix)' $@; \
@@ -446,6 +587,10 @@ $(objpfx)tst-printf-bz18872.c: tst-printf-bz18872.sh
$(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)
errlist-h = $(firstword $(wildcard $(addsuffix /errlist.h,$(sysdirs) .)))
@@ -508,7 +653,7 @@ CFLAGS-tst-gets.c += -Wno-deprecated-declarations
# BZ #11319 was first fixed for regular vdprintf, then reopened because
# the fortified version had the same bug.
-CFLAGS-tst-bz11319-fortify2.c += $(no-fortify-source),-D_FORTIFY_SOURCE=2
+CFLAGS-tst-bz11319-fortify2.c += $(no-fortify-source) -D_FORTIFY_SOURCE=2
CFLAGS-tst-memstream-string.c += -fno-builtin-fprintf
@@ -533,3 +678,6 @@ $(objpfx)tst-setvbuf1-cmp.out: tst-setvbuf1.expect $(objpfx)tst-setvbuf1.out
$(objpfx)tst-printf-round: $(libm)
$(objpfx)tst-scanf-round: $(libm)
+
+$(objpfx)tst-freopen7: $(shared-thread-library)
+$(objpfx)tst-freopen64-7: $(shared-thread-library)
diff --git a/stdio-common/tst-fdopen2.c b/stdio-common/tst-fdopen2.c
new file mode 100644
index 0000000..0c6625f
--- /dev/null
+++ b/stdio-common/tst-fdopen2.c
@@ -0,0 +1,246 @@
+/* Test the fdopen function.
+ 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>
+#include <errno.h>
+#include <fcntl.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xunistd.h>
+#include <support/temp_file.h>
+
+char *tmp_dir;
+char *path_to_file;
+
+void
+prepare_tmp_dir (void)
+{
+ tmp_dir = support_create_temp_directory ("tst-fdopen2");
+ path_to_file = xasprintf ("%s/tst-fdopen2.txt", tmp_dir);
+}
+
+/* open temp file descriptor with mode. */
+int
+open_tmp_fd (int mode)
+{
+ int fd = xopen (path_to_file, mode, 0644);
+ return fd;
+}
+
+
+/* close and remove temp file with close. */
+void
+close_tmp_fd (int fd)
+{
+ xclose (fd);
+ xunlink (path_to_file);
+}
+
+/* close and remove temp file with fclose. */
+void
+close_tmp_fp (FILE *fp)
+{
+ fclose (fp);
+ xunlink (path_to_file);
+}
+
+/* test "w" fdopen mode. */
+void
+do_test_fdopen_w (void)
+{
+ int fd, ret;
+ FILE *fp;
+ fd = open_tmp_fd (O_WRONLY | O_CREAT | O_TRUNC);
+
+ /* test mode mismatch. */
+ fp = fdopen (fd, "r");
+ if (fp != NULL || errno != EINVAL)
+ {
+ close_tmp_fd (fd);
+ FAIL_EXIT1 ("fdopen (%d, r) should fail with EINVAL: %m", fd);
+ }
+
+ fp = fdopen (fd, "w");
+ if (fp == NULL)
+ {
+ close_tmp_fd (fd);
+ FAIL_EXIT1 ("fdopen (%d, w): %m", fd);
+ }
+
+ const void *buf = "AAAA";
+ ret = fwrite (buf, 1, 4, fp);
+ if (ret != 4)
+ {
+ close_tmp_fp (fp);
+ FAIL_EXIT1 ("fwrite (): %m");
+ }
+
+ unsigned char buf2[4];
+ rewind (fp);
+ clearerr (fp);
+ /* fread should fail in "w" mode */
+ ret = fread (buf2, 1, 4, fp);
+ if (ret != 0 || ferror (fp) == 0)
+ {
+ close_tmp_fp (fp);
+ FAIL_EXIT1 ("fread should fail in \"w\" mode");
+ }
+
+ fclose (fp);
+}
+
+/* test "r" fdopen mode. */
+void
+do_test_fdopen_r (void)
+{
+ int fd, ret;
+ FILE *fp;
+ fd = open_tmp_fd (O_RDONLY);
+
+ /* test mode mismatch. */
+ fp = fdopen (fd, "w");
+ if (fp != NULL || errno != EINVAL)
+ {
+ close_tmp_fd (fd);
+ FAIL_EXIT1 ("fdopen (%d, w) should fail with EINVAL: %m", fd);
+ }
+
+ fp = fdopen (fd, "r");
+ if (fp == NULL)
+ {
+ close_tmp_fd (fd);
+ FAIL_EXIT1 ("fdopen (%d, w): %m", fd);
+ }
+
+ const void *buf = "BBBB";
+ /* fwrite should fail in "r" mode. */
+ ret = fwrite (buf, 1, 4, fp);
+ if (ret != 0 || ferror (fp) == 0)
+ {
+ close_tmp_fp (fp);
+ FAIL_EXIT1 ("fwrite should fail in \"r\" mode");
+ }
+
+ unsigned char buf2[4];
+ ret = fread (buf2, 1, 4, fp);
+ if (ret != 4)
+ {
+ close_tmp_fp (fp);
+ FAIL_EXIT1 ("fread (): %m");
+ }
+
+ fclose (fp);
+}
+
+/* test "a" fdopen mode. */
+void
+do_test_fdopen_a (void)
+{
+ int fd, ret;
+ FILE *fp;
+ fd = open_tmp_fd (O_WRONLY | O_CREAT | O_APPEND);
+
+ /* test mode mismatch. */
+ fp = fdopen (fd, "r+");
+ if (fp != NULL || errno != EINVAL)
+ {
+ close_tmp_fd (fd);
+ FAIL_EXIT1 ("fdopen (%d, \"r+\") should fail with EINVAL: %m", fd);
+ }
+
+ fp = fdopen (fd, "a");
+ if (fp == NULL)
+ {
+ close_tmp_fd (fd);
+ FAIL_EXIT1 ("fdopen (%d, w): %m", fd);
+ }
+
+ const void *buf = "CCCC";
+ ret = fwrite (buf, 1, 4, fp);
+ if (ret != 4)
+ {
+ close_tmp_fp (fp);
+ FAIL_EXIT1 ("fwrite (): %m");
+ }
+
+ /* fread should fail in "a" mode. */
+ unsigned char buf2[4];
+ clearerr (fp);
+ ret = fread (buf2, 1, 4, fp);
+ if (ret != 0 || ferror (fp) == 0)
+ {
+ close_tmp_fp (fp);
+ FAIL_EXIT1 ("fread should fail \"a\" mode");
+ }
+
+ fclose (fp);
+}
+
+void
+do_test_fdopen_mode (int mode, const char *fmode)
+{
+ int fd, ret;
+ FILE *fp;
+ fd = open_tmp_fd (mode);
+
+ fp = fdopen (fd, fmode);
+ if (fp == NULL)
+ {
+ close_tmp_fd (fd);
+ FAIL_EXIT1 ("fdopen (%d, %s): %m", fd, fmode);
+ }
+
+ const void *buf = "EEEE";
+ ret = fwrite (buf, 1, 4, fp);
+ if (ret != 4)
+ {
+ close_tmp_fp (fp);
+ FAIL_EXIT1 ("fwrite () in mode:%s returns %d: %m", fmode, ret);
+ }
+
+ rewind (fp);
+ unsigned char buf2[4];
+ ret = fread (buf2, 1, 4, fp);
+ if (ret != 4)
+ {
+ close_tmp_fp (fp);
+ FAIL_EXIT1 ("fread () in mode:%s returns %d: %m", fmode, ret);
+ }
+
+ fclose (fp);
+}
+
+static int
+do_test (void)
+{
+
+ prepare_tmp_dir ();
+
+ do_test_fdopen_w ();
+ do_test_fdopen_r ();
+ do_test_fdopen_a ();
+
+ /* test r+ w+ a+ fdopen modes. */
+ do_test_fdopen_mode (O_RDWR, "r+");
+ do_test_fdopen_mode (O_RDWR | O_CREAT | O_TRUNC, "w+");
+ do_test_fdopen_mode (O_RDWR | O_CREAT | O_APPEND, "a+");
+ xunlink (path_to_file);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-fgets2.c b/stdio-common/tst-fgets2.c
new file mode 100644
index 0000000..5b78447
--- /dev/null
+++ b/stdio-common/tst-fgets2.c
@@ -0,0 +1,253 @@
+/* Test for additional fgets error handling.
+ 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 <libc-diag.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+#include <limits.h>
+#include <mcheck.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <support/support.h>
+#include <support/check.h>
+
+/* This avoids compiler warnings about passing NULL where a valid
+ pointer is expected. */
+static void *volatile null = NULL;
+
+/* Implementation of our FILE stream backend. */
+
+static int bytes_read;
+static int cookie_valid = 0;
+struct Cookie {
+ const char *buffer;
+ int bufptr;
+ int bufsz;
+};
+
+#define VALIDATE_COOKIE() if (! cookie_valid) { \
+ FAIL ("call to %s after file closed", __FUNCTION__); \
+ return -1; \
+ }
+
+static ssize_t
+io_read (void *vcookie, char *buf, size_t size)
+{
+ struct Cookie *cookie = (struct Cookie *) vcookie;
+
+ VALIDATE_COOKIE ();
+
+ if (size > cookie->bufsz - cookie->bufptr)
+ size = cookie->bufsz - cookie->bufptr;
+
+ memcpy (buf, cookie->buffer + cookie->bufptr, size);
+ cookie->bufptr += size;
+ bytes_read += size;
+ return size;
+}
+
+static ssize_t
+io_write (void *vcookie, const char *buf, size_t size)
+{
+ VALIDATE_COOKIE ();
+ FAIL_EXIT1 ("io_write called");
+}
+
+static int
+io_seek (void *vcookie, off64_t *position, int whence)
+{
+ VALIDATE_COOKIE ();
+ FAIL_EXIT1 ("io_seek called");
+}
+
+static int
+io_clean (void *vcookie)
+{
+ struct Cookie *cookie = (struct Cookie *) vcookie;
+
+ VALIDATE_COOKIE ();
+
+ cookie->buffer = NULL;
+ cookie->bufsz = 0;
+ cookie->bufptr = 0;
+
+ cookie_valid = 0;
+ free (cookie);
+ return 0;
+}
+
+cookie_io_functions_t io_funcs = {
+ .read = io_read,
+ .write = io_write,
+ .seek = io_seek,
+ .close = io_clean
+};
+
+FILE *
+io_open (const char *buffer, int buflen, const char *mode, void **vcookie)
+{
+ FILE *f;
+ struct Cookie *cookie;
+
+ cookie = (struct Cookie *) xcalloc (1, sizeof (struct Cookie));
+ *vcookie = cookie;
+ cookie_valid = 1;
+
+ cookie->buffer = buffer;
+ cookie->bufsz = buflen;
+ bytes_read = 0;
+
+ f = fopencookie (cookie, mode, io_funcs);
+ if (f == NULL)
+ FAIL_EXIT1 ("fopencookie failed");
+
+ clearerr (f);
+ return f;
+}
+
+/* The test cases. */
+
+#define my_open(s,l,m) io_open (s, l, m, (void *) &cookie)
+
+#define TEST_COMPARE_0x11(buf, len) \
+ TEST_COMPARE_BLOB (buf + (len), sizeof (buf) - (len), \
+ buf2, sizeof (buf) - (len));
+
+#define check_flags(f, expected_eof, expected_err) \
+ { \
+ if (expected_eof) \
+ TEST_VERIFY (feof (f) != 0); \
+ else \
+ TEST_VERIFY (feof (f) == 0); \
+ if (expected_err) \
+ TEST_VERIFY (ferror (f) != 0); \
+ else \
+ TEST_VERIFY (ferror (f) == 0); \
+ }
+
+static int
+do_test (void)
+{
+ FILE *f;
+ struct Cookie *cookie;
+ char buf [10];
+ char buf2 [10];
+ char *returned_string;
+
+ memset (buf2, 0x11, sizeof (buf2));
+
+ printf ("testing base operation...\n");
+ f = my_open ("hello\n", 6, "r");
+ memset (buf, 0x11, sizeof (buf));
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
+ TEST_VERIFY (returned_string == buf);
+ TEST_COMPARE_BLOB (buf, bytes_read + 1, "hello\n\0", 7);
+ TEST_COMPARE_0x11 (buf, bytes_read + 1);
+ check_flags (f, 0, 0);
+
+ fclose (f);
+
+ printf ("testing zero size file...\n");
+ f = my_open ("hello\n", 0, "r");
+ memset (buf, 0x11, sizeof (buf));
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
+ TEST_VERIFY (returned_string == NULL);
+ TEST_VERIFY (bytes_read == 0);
+ check_flags (f, 1, 0);
+ fclose (f);
+
+ printf ("testing zero size buffer...\n");
+ f = my_open ("hello\n", 6, "r");
+ memset (buf, 0x11, sizeof (buf));
+ returned_string = fgets (buf, 0, f);
+ TEST_VERIFY (returned_string == NULL);
+ TEST_VERIFY (bytes_read == 0);
+ check_flags (f, 0, 0);
+ fclose (f);
+
+ printf ("testing NULL buffer with empty stream...\n");
+ f = my_open ("hello\n", 0, "r");
+ memset (buf, 0x11, sizeof (buf));
+
+ returned_string = fgets (null, sizeof (buf), f);
+
+ TEST_VERIFY (returned_string == NULL);
+ TEST_VERIFY (bytes_read == 0);
+ check_flags (f, 1, 0);
+ fclose (f);
+
+ printf ("testing embedded NUL...\n");
+ f = my_open ("hel\0lo\n", 7, "r");
+ memset (buf, 0x11, sizeof (buf));
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
+ TEST_VERIFY (returned_string == buf);
+ TEST_COMPARE_BLOB (buf, bytes_read + 1, "hel\0lo\n\0", 8);
+ TEST_COMPARE_0x11 (buf, bytes_read + 1);
+ check_flags (f, 0, 0);
+ fclose (f);
+
+ printf ("testing writable stream...\n");
+ f = my_open ("hel\0lo\n", 7, "w");
+ memset (buf, 0x11, sizeof (buf));
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
+ TEST_VERIFY (returned_string == NULL);
+ TEST_VERIFY (bytes_read == 0);
+ check_flags (f, 0, 1);
+ fclose (f);
+
+ printf ("testing closed fd stream...\n");
+ int fd = open ("/dev/null", O_RDONLY);
+ f = fdopen (fd, "r");
+ close (fd);
+ memset (buf, 0x11, sizeof (buf));
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
+ TEST_VERIFY (returned_string == NULL);
+ TEST_VERIFY (bytes_read == 0);
+ check_flags (f, 0, 1);
+ fclose (f);
+
+#ifdef IO_DEBUG
+ /* These tests only pass if glibc is built with -DIO_DEBUG, but are
+ included for reference. */
+
+ printf ("testing NULL descriptor...\n");
+ memset (buf, 0x11, sizeof (buf));
+ returned_string = fgets (buf, sizeof (buf) - 1, null);
+ TEST_VERIFY (returned_string == NULL);
+ TEST_VERIFY (bytes_read == 0);
+
+ printf ("testing closed descriptor...\n");
+ f = my_open ("hello\n", 7, "r");
+ fclose (f);
+ memset (buf, 0x11, sizeof (buf));
+ returned_string = fgets (buf, sizeof (buf) - 1, f);
+ TEST_VERIFY (returned_string == NULL);
+ TEST_VERIFY (bytes_read == 0);
+#endif
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-fread.c b/stdio-common/tst-fread.c
new file mode 100644
index 0000000..4d9a789
--- /dev/null
+++ b/stdio-common/tst-fread.c
@@ -0,0 +1,134 @@
+/* Test fread.
+ 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>
+#include <stdlib.h>
+#include <string.h>
+
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+int
+do_test (void)
+{
+ char *temp_dir = support_create_temp_directory ("tst-fread");
+ char *file1 = xasprintf ("%s/file1", temp_dir);
+ support_write_file_string (file1, "file1");
+ add_temp_file (file1);
+ FILE *fp;
+ size_t ret;
+ char buf[1024];
+
+ verbose_printf ("test single-byte reads\n");
+ fp = xfopen (file1, "r");
+ memset (buf, 0, sizeof buf);
+ ret = fread (buf, 1, 2, fp);
+ TEST_COMPARE (ret, 2);
+ TEST_COMPARE (buf[0], 'f');
+ TEST_COMPARE (buf[1], 'i');
+ TEST_COMPARE (feof (fp), 0);
+ TEST_COMPARE (ftell (fp), 2);
+ memset (buf, 0, sizeof buf);
+ ret = fread (buf, 1, 3, fp);
+ TEST_COMPARE (ret, 3);
+ TEST_COMPARE (buf[0], 'l');
+ TEST_COMPARE (buf[1], 'e');
+ TEST_COMPARE (buf[2], '1');
+ TEST_COMPARE (ftell (fp), 5);
+ TEST_COMPARE (feof (fp), 0);
+ memset (buf, 0, sizeof buf);
+ ret = fread (buf, 1, 1, fp);
+ TEST_COMPARE (ret, 0);
+ TEST_COMPARE (!!feof (fp), 1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (ftell (fp), 5);
+ xfclose (fp);
+
+ verbose_printf ("test single-byte reads, EOF part way through\n");
+ fp = xfopen (file1, "r");
+ memset (buf, 0, sizeof buf);
+ ret = fread (buf, 1, sizeof buf, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE (buf[0], 'f');
+ TEST_COMPARE (buf[1], 'i');
+ TEST_COMPARE (buf[2], 'l');
+ TEST_COMPARE (buf[3], 'e');
+ TEST_COMPARE (buf[4], '1');
+ TEST_COMPARE (!!feof (fp), 1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (ftell (fp), 5);
+ xfclose (fp);
+
+ verbose_printf ("test multi-byte reads\n");
+ fp = xfopen (file1, "r");
+ memset (buf, 0, sizeof buf);
+ ret = fread (buf, 2, 2, fp);
+ TEST_COMPARE (ret, 2);
+ TEST_COMPARE (buf[0], 'f');
+ TEST_COMPARE (buf[1], 'i');
+ TEST_COMPARE (buf[2], 'l');
+ TEST_COMPARE (buf[3], 'e');
+ TEST_COMPARE (feof (fp), 0);
+ TEST_COMPARE (ftell (fp), 4);
+ memset (buf, 0, sizeof buf);
+ ret = fread (buf, 3, 3, fp);
+ TEST_COMPARE (ret, 0);
+ /* The bytes written for a partial element read are unspecified. */
+ TEST_COMPARE (!!feof (fp), 1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (ftell (fp), 5);
+ xfclose (fp);
+
+ verbose_printf ("test read error\n");
+ fp = xfopen (file1, "r");
+ xclose (fileno (fp));
+ memset (buf, 0, sizeof buf);
+ ret = fread (buf, 1, sizeof buf, fp);
+ TEST_COMPARE (ret, 0);
+ TEST_COMPARE (feof (fp), 0);
+ TEST_COMPARE (!!ferror (fp), 1);
+ fclose (fp);
+
+ verbose_printf ("test zero size\n");
+ fp = xfopen (file1, "r");
+ ret = fread (buf, 0, SIZE_MAX, fp);
+ TEST_COMPARE (ret, 0);
+ TEST_COMPARE (feof (fp), 0);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (ftell (fp), 0);
+ xfclose (fp);
+
+ verbose_printf ("test zero items\n");
+ fp = xfopen (file1, "r");
+ ret = fread (buf, SIZE_MAX, 0, fp);
+ TEST_COMPARE (ret, 0);
+ TEST_COMPARE (feof (fp), 0);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (ftell (fp), 0);
+ xfclose (fp);
+
+ free (temp_dir);
+ free (file1);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-freopen2-main.c b/stdio-common/tst-freopen2-main.c
new file mode 100644
index 0000000..74c3125
--- /dev/null
+++ b/stdio-common/tst-freopen2-main.c
@@ -0,0 +1,519 @@
+/* Test freopen.
+ 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 <errno.h>
+#include <fcntl.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/file_contents.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+
+#define START_TEST(DESC) \
+ do \
+ { \
+ fds = support_descriptors_list (); \
+ verbose_printf (DESC); \
+ } \
+ while (0)
+
+#define END_TEST \
+ do \
+ { \
+ support_descriptors_check (fds); \
+ support_descriptors_free (fds); \
+ } \
+ while (0)
+
+int
+do_test (void)
+{
+ mtrace ();
+ struct support_descriptors *fds;
+ char *temp_dir = support_create_temp_directory ("tst-freopen2");
+ char *file1 = xasprintf ("%s/file1", temp_dir);
+ support_write_file_string (file1, "file1");
+ add_temp_file (file1);
+ char *file2 = xasprintf ("%s/file2", temp_dir);
+ support_write_file_string (file2, "file2");
+ add_temp_file (file2);
+ char *file3 = xasprintf ("%s/file3", temp_dir);
+ char *file4 = xasprintf ("%s/file4", temp_dir);
+ char *file1a = xasprintf ("%s/file1a", temp_dir);
+ FILE *fp;
+ int ret;
+ wint_t wc;
+
+ /* Test each pair of old and new modes from r w a. */
+
+ START_TEST ("Testing r -> r\n");
+ fp = xfopen (file1, "r");
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "file2");
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("Testing r -> w\n");
+ fp = xfopen (file1, "r");
+ fp = FREOPEN (file2, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("File2new", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file1, "file1");
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "File2new");
+ END_TEST;
+
+ START_TEST ("Testing r -> a\n");
+ fp = xfopen (file1, "r");
+ fp = FREOPEN (file2, "a", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("3", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "File2new3");
+ END_TEST;
+
+ START_TEST ("Testing w -> r\n");
+ fp = xfopen (file1, "w");
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "File2new3");
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("Testing w -> w\n");
+ fp = xfopen (file1, "w");
+ fp = FREOPEN (file2, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("next", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file1, "");
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "next");
+ END_TEST;
+
+ START_TEST ("Testing w -> a\n");
+ fp = xfopen (file1, "w");
+ fp = FREOPEN (file2, "a", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("4", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "next4");
+ END_TEST;
+
+ START_TEST ("Testing a -> r\n");
+ fp = xfopen (file1, "a");
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "next4");
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("Testing a -> w\n");
+ fp = xfopen (file1, "a");
+ fp = FREOPEN (file2, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("another", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another");
+ END_TEST;
+
+ START_TEST ("Testing a -> a\n");
+ fp = xfopen (file1, "a");
+ fp = FREOPEN (file2, "a", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("5", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another5");
+ END_TEST;
+
+ /* Test for file originally opened with fopen64. */
+ START_TEST ("Testing fopen64 a -> a\n");
+ fp = fopen64 (file1, "a");
+ TEST_VERIFY_EXIT (fp != NULL);
+ fp = FREOPEN (file2, "a", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("64", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "another564");
+ END_TEST;
+
+ /* Test calling freopen more than once on the same FILE *. */
+
+ START_TEST ("Testing r -> w -> r\n");
+ fp = xfopen (file1, "r");
+ fp = FREOPEN (file2, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("freopen-twice", fp);
+ TEST_VERIFY (ret >= 0);
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "freopen-twice");
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "freopen-twice");
+ END_TEST;
+
+ START_TEST ("Testing r -> w -> r (exactly one freopen64)\n");
+ fp = xfopen (file1, "r");
+ fp = OTHER_FREOPEN (file2, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("freopen-twice64", fp);
+ TEST_VERIFY (ret >= 0);
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "freopen-twice64");
+ END_TEST;
+
+ /* Test changing to/from b (binary, no-op). */
+
+ START_TEST ("Testing rb -> r\n");
+ fp = xfopen (file1, "rb");
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("Testing r -> rb\n");
+ fp = xfopen (file1, "r");
+ fp = FREOPEN (file2, "rb", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "freopen-twice64");
+ xfclose (fp);
+ END_TEST;
+
+ /* Test changing to/from + (read-and-write). */
+
+ START_TEST ("Testing r -> w+\n");
+ fp = xfopen (file1, "r");
+ fp = FREOPEN (file2, "w+", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("latest", fp);
+ TEST_VERIFY (ret >= 0);
+ ret = fseek (fp, 0, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ TEST_COMPARE_FILE_STRING (fp, "latest");
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "latest");
+ END_TEST;
+
+ START_TEST ("Testing w -> a+\n");
+ fp = xfopen (file1, "w");
+ fp = FREOPEN (file2, "a+", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("suffix", fp);
+ TEST_VERIFY (ret >= 0);
+ ret = fseek (fp, 0, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ TEST_COMPARE_FILE_STRING (fp, "latestsuffix");
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "latestsuffix");
+ END_TEST;
+
+ START_TEST ("Testing a -> r+\n");
+ fp = xfopen (file1, "a");
+ fp = FREOPEN (file2, "r+", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "latestsuffix");
+ ret = fseek (fp, 0, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ ret = fputs ("new", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "newestsuffix");
+ END_TEST;
+
+ START_TEST ("Testing r+ -> w\n");
+ fp = xfopen (file1, "r+");
+ fp = FREOPEN (file2, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("plusto", fp);
+ TEST_VERIFY (ret >= 0);
+ ret = fseek (fp, 0, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ errno = 0;
+ TEST_COMPARE (fgetc (fp), EOF);
+ TEST_COMPARE (errno, EBADF);
+ clearerr (fp);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plusto");
+ END_TEST;
+
+ START_TEST ("Testing w+ -> a\n");
+ fp = xfopen (file1, "w+");
+ fp = FREOPEN (file2, "a", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("more", fp);
+ TEST_VERIFY (ret >= 0);
+ ret = fseek (fp, 0, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ errno = 0;
+ TEST_COMPARE (fgetc (fp), EOF);
+ TEST_COMPARE (errno, EBADF);
+ clearerr (fp);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plustomore");
+ END_TEST;
+
+ START_TEST ("Testing a+ -> r\n");
+ fp = xfopen (file1, "a+");
+ fp = FREOPEN (file2, "rr", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
+ ret = fputs ("2", fp);
+ TEST_COMPARE (ret, EOF);
+ clearerr (fp);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "plustomore");
+ END_TEST;
+
+ /* Test changing to/from e (FD_CLOEXEC). */
+
+ START_TEST ("Testing re -> r\n");
+ fp = xfopen (file1, "re");
+ ret = fcntl (fileno (fp), F_GETFD);
+ TEST_VERIFY (ret != -1);
+ TEST_COMPARE (ret & FD_CLOEXEC, FD_CLOEXEC);
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fcntl (fileno (fp), F_GETFD);
+ TEST_VERIFY (ret != -1);
+ TEST_COMPARE (ret & FD_CLOEXEC, 0);
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("Testing r -> re\n");
+ fp = xfopen (file1, "r");
+ ret = fcntl (fileno (fp), F_GETFD);
+ TEST_VERIFY (ret != -1);
+ TEST_COMPARE (ret & FD_CLOEXEC, 0);
+ fp = FREOPEN (file2, "re", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fcntl (fileno (fp), F_GETFD);
+ TEST_VERIFY (ret != -1);
+ TEST_COMPARE (ret & FD_CLOEXEC, FD_CLOEXEC);
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
+ xfclose (fp);
+ END_TEST;
+
+ /* Test changing to/from m (mmap) (a no-op as far as testing
+ semantics is concerned). */
+
+ START_TEST ("Testing rm -> r\n");
+ fp = xfopen (file1, "rm");
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("Testing r -> rm\n");
+ fp = xfopen (file1, "r");
+ fp = FREOPEN (file2, "rm", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "plustomore");
+ xfclose (fp);
+ END_TEST;
+
+ /* Test changing to/from x (O_EXCL). */
+
+ START_TEST ("Testing wx -> w\n");
+ fp = xfopen (file3, "wx");
+ add_temp_file (file3);
+ fp = FREOPEN (file2, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = fputs ("wxtow", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file2, "wxtow");
+ END_TEST;
+
+ START_TEST ("Testing w -> wx (file does not exist)\n");
+ fp = xfopen (file1, "w");
+ fp = FREOPEN (file4, "wx", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ add_temp_file (file4);
+ ret = fputs ("wtowx", fp);
+ TEST_VERIFY (ret >= 0);
+ xfclose (fp);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file4, "wtowx");
+ END_TEST;
+
+ /* Test with ,ccs=CHARSET. */
+
+ START_TEST ("testing w,ccs=utf-8 -> r\n");
+ fp = xfopen (file1, "w,ccs=utf-8");
+ ret = fputws (L"\xc0\xc1", fp);
+ TEST_VERIFY (ret >= 0);
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "wxtow");
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("testing w,ccs=iso-8859-1 -> r,ccs=utf-8\n");
+ fp = xfopen (file2, "w,ccs=iso-8859-1");
+ ret = fputws (L"\xc0\xc1", fp);
+ TEST_VERIFY (ret >= 0);
+ fp = FREOPEN (file1, "r,ccs=utf-8", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ wc = fgetwc (fp);
+ TEST_COMPARE (wc, (wint_t) 0xc0);
+ wc = fgetwc (fp);
+ TEST_COMPARE (wc, (wint_t) 0xc1);
+ wc = fgetwc (fp);
+ TEST_COMPARE (wc, WEOF);
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("testing r,ccs=utf-8 -> r\n");
+ fp = xfopen (file1, "r,ccs=utf-8");
+ fp = FREOPEN (file1, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "\u00c0\u00c1");
+ xfclose (fp);
+ END_TEST;
+
+ /* Test that errors closing the old file are ignored. */
+
+ START_TEST ("testing errors closing old file ignored\n");
+ fp = xfopen ("/dev/full", "w");
+ fputc ('x', fp);
+ fp = FREOPEN (file1, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "\u00c0\u00c1");
+ xfclose (fp);
+ END_TEST;
+
+ /* Test that error / EOF state from the old file are cleared. */
+
+ START_TEST ("testing error state from old file cleared\n");
+ fp = xfopen ("/dev/full", "w");
+ fputc ('x', fp);
+ fflush (fp);
+ TEST_VERIFY (ferror (fp));
+ TEST_VERIFY (!feof (fp));
+ fp = FREOPEN (file2, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_VERIFY (!ferror (fp));
+ TEST_VERIFY (!feof (fp));
+ xfclose (fp);
+ END_TEST;
+
+ START_TEST ("testing EOF state from old file cleared\n");
+ fp = xfopen ("/dev/null", "r");
+ fgetc (fp);
+ TEST_VERIFY (!ferror (fp));
+ TEST_VERIFY (feof (fp));
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_VERIFY (!ferror (fp));
+ TEST_VERIFY (!feof (fp));
+ xfclose (fp);
+ END_TEST;
+
+ /* Test freopen with NULL, same mode (should flush content and reset
+ file offset). */
+
+ START_TEST ("testing freopen with NULL, same mode\n");
+ fp = xfopen (file1, "r+");
+ ret = fputs ("same mode", fp);
+ TEST_VERIFY (ret >= 0);
+ fp = FREOPEN (NULL, "r+", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "same mode");
+ xfclose (fp);
+ END_TEST;
+
+ /* Test freopen with NULL, different mode. */
+
+ START_TEST ("testing freopen with NULL, different mode\n");
+ fp = xfopen (file1, "w");
+ ret = fputs ("different mode", fp);
+ TEST_VERIFY (ret >= 0);
+ fp = FREOPEN (NULL, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "different mode");
+ xfclose (fp);
+ END_TEST;
+
+ /* Test freopen with NULL, renamed file. This verifies that
+ reopening succeeds (and resets the file position indicator to
+ start of file) even when the original path could no longer be
+ opened. */
+
+ START_TEST ("testing freopen with NULL, renamed file\n");
+ fp = xfopen (file1, "r+");
+ ret = fputs ("file has been renamed", fp);
+ TEST_VERIFY (ret >= 0);
+ ret = rename (file1, file1a);
+ TEST_COMPARE (ret, 0);
+ fp = FREOPEN (NULL, "r+", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "file has been renamed");
+ xfclose (fp);
+ ret = rename (file1a, file1);
+ TEST_COMPARE (ret, 0);
+ END_TEST;
+
+ /* Test freopen with NULL, deleted file. This verifies that
+ reopening succeeds (and resets the file position indicator to
+ start of file) even when the original path could no longer be
+ opened. */
+
+ START_TEST ("testing freopen with NULL, deleted file\n");
+ fp = xfopen (file1, "r+");
+ ret = fputs ("file has now been deleted", fp);
+ TEST_VERIFY (ret >= 0);
+ ret = remove (file1);
+ TEST_COMPARE (ret, 0);
+ fp = FREOPEN (NULL, "r+", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ TEST_COMPARE_FILE_STRING (fp, "file has now been deleted");
+ xfclose (fp);
+ /* Recreate the file so it is present when expected for temporary
+ file deletion. */
+ support_write_file_string (file1, "file1");
+ END_TEST;
+
+ free (temp_dir);
+ free (file1);
+ free (file2);
+ free (file3);
+ free (file4);
+ free (file1a);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-freopen2.c b/stdio-common/tst-freopen2.c
new file mode 100644
index 0000000..11ec7a9
--- /dev/null
+++ b/stdio-common/tst-freopen2.c
@@ -0,0 +1,3 @@
+#define FREOPEN freopen
+#define OTHER_FREOPEN freopen64
+#include <tst-freopen2-main.c>
diff --git a/stdio-common/tst-freopen3-main.c b/stdio-common/tst-freopen3-main.c
new file mode 100644
index 0000000..990a6e5
--- /dev/null
+++ b/stdio-common/tst-freopen3-main.c
@@ -0,0 +1,92 @@
+/* Test freopen failure.
+ 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 <errno.h>
+#include <fcntl.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/file_contents.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+
+#define START_TEST(DESC) \
+ do \
+ { \
+ fds = support_descriptors_list (); \
+ verbose_printf (DESC); \
+ } \
+ while (0)
+
+#define END_TEST \
+ do \
+ { \
+ support_descriptors_check (fds); \
+ support_descriptors_free (fds); \
+ } \
+ while (0)
+
+int
+do_test (void)
+{
+ mtrace ();
+ struct support_descriptors *fds;
+ char *temp_dir = support_create_temp_directory ("tst-freopen3");
+ char *file1 = xasprintf ("%s/file1", temp_dir);
+ support_write_file_string (file1, "file1");
+ add_temp_file (file1);
+ char *file2 = xasprintf ("%s/file2", temp_dir);
+ support_write_file_string (file2, "file2");
+ add_temp_file (file2);
+ char *file_nodir = xasprintf ("%s/nodir/file", temp_dir);
+ FILE *fp;
+ int ret;
+ int fd;
+
+ START_TEST ("Testing w -> wx (file exists)\n");
+ fp = xfopen (file1, "w");
+ fp = FREOPEN (file2, "wx", fp);
+ TEST_VERIFY (fp == NULL);
+ END_TEST;
+
+ /* Test old file is closed even when opening the new file fails. */
+
+ START_TEST ("testing r -> r (opening new file fails)\n");
+ fp = xfopen (file1, "r");
+ fd = fileno (fp);
+ fp = FREOPEN (file_nodir, "r", fp);
+ TEST_VERIFY (fp == NULL);
+ errno = 0;
+ ret = fcntl (fd, F_GETFL);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, EBADF);
+ END_TEST;
+
+ free (temp_dir);
+ free (file1);
+ free (file2);
+ free (file_nodir);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-freopen3.c b/stdio-common/tst-freopen3.c
new file mode 100644
index 0000000..5041b6b
--- /dev/null
+++ b/stdio-common/tst-freopen3.c
@@ -0,0 +1,2 @@
+#define FREOPEN freopen
+#include <tst-freopen3-main.c>
diff --git a/stdio-common/tst-freopen4-main.c b/stdio-common/tst-freopen4-main.c
new file mode 100644
index 0000000..7284677
--- /dev/null
+++ b/stdio-common/tst-freopen4-main.c
@@ -0,0 +1,102 @@
+/* Test freopen in chroot.
+ 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 <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <support/check.h>
+#include <support/file_contents.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+int
+do_test (void)
+{
+ mtrace ();
+ char *temp_dir;
+ FILE *fp;
+ int ret;
+
+ /* These chroot tests verify that either reopening a renamed or
+ deleted file works even in the absence of /proc, or that it fails
+ (without memory leaks); thus, for example, such reopening does
+ not crash in the absence of /proc. */
+
+ support_become_root ();
+ if (!support_can_chroot ())
+ return EXIT_UNSUPPORTED;
+
+ temp_dir = support_create_temp_directory ("tst-freopen4");
+ xchroot (temp_dir);
+
+ /* Test freopen with NULL, renamed file. This verifies that
+ reopening succeeds (and resets the file position indicator to
+ start of file) even when the original path could no longer be
+ opened, or fails without a memory leak. (It is not possible to
+ use <support/descriptors.h> to test for file descriptor leaks
+ here, because that also depends on /proc.) */
+
+ verbose_printf ("testing freopen with NULL, renamed file\n");
+ fp = xfopen ("/file1", "w+");
+ ret = fputs ("file has been renamed", fp);
+ TEST_VERIFY (ret >= 0);
+ ret = rename ("/file1", "/file1a");
+ TEST_COMPARE (ret, 0);
+ fp = FREOPEN (NULL, "r+", fp);
+ if (fp != NULL)
+ {
+ puts ("freopen of renamed file succeeded");
+ TEST_COMPARE_FILE_STRING (fp, "file has been renamed");
+ xfclose (fp);
+ }
+ else
+ puts ("freopen of renamed file failed (OK)");
+ ret = rename ("/file1a", "/file1");
+ TEST_COMPARE (ret, 0);
+
+ /* Test freopen with NULL, deleted file. This verifies that
+ reopening succeeds (and resets the file position indicator to
+ start of file) even when the original path could no longer be
+ opened, or fails without a memory leak. */
+
+ verbose_printf ("testing freopen with NULL, deleted file\n");
+ fp = xfopen ("/file1", "r+");
+ ret = fputs ("file has now been deleted", fp);
+ TEST_VERIFY (ret >= 0);
+ ret = remove ("/file1");
+ TEST_COMPARE (ret, 0);
+ fp = FREOPEN (NULL, "r+", fp);
+ if (fp != NULL)
+ {
+ puts ("freopen of deleted file succeeded");
+ TEST_COMPARE_FILE_STRING (fp, "file has now been deleted");
+ xfclose (fp);
+ }
+ else
+ puts ("freopen of deleted file failed (OK)");
+
+ free (temp_dir);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-freopen4.c b/stdio-common/tst-freopen4.c
new file mode 100644
index 0000000..f39ec0d
--- /dev/null
+++ b/stdio-common/tst-freopen4.c
@@ -0,0 +1,2 @@
+#define FREOPEN freopen
+#include <tst-freopen4-main.c>
diff --git a/stdio-common/tst-freopen5.c b/stdio-common/tst-freopen5.c
new file mode 100644
index 0000000..f32626b
--- /dev/null
+++ b/stdio-common/tst-freopen5.c
@@ -0,0 +1,144 @@
+/* Test freopen and freopen64 with large offsets.
+ 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 <errno.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+
+#define START_TEST(DESC) \
+ do \
+ { \
+ fds = support_descriptors_list (); \
+ verbose_printf (DESC); \
+ } \
+ while (0)
+
+#define END_TEST \
+ do \
+ { \
+ support_descriptors_check (fds); \
+ support_descriptors_free (fds); \
+ } \
+ while (0)
+
+int
+do_test (void)
+{
+ mtrace ();
+ struct support_descriptors *fds;
+ FILE *fp;
+ int ret;
+
+ char *temp_dir = support_create_temp_directory ("tst-freopen5");
+ /* This file is removed at the end of each test rather than left
+ around between tests to avoid problems with subsequent tests
+ reopening it as a large (2GB + 1 byte) file. */
+ char *file1 = xasprintf ("%s/file1", temp_dir);
+
+ /* fopen with freopen64: large offsets OK. */
+ START_TEST ("testing fopen with freopen64\n");
+ fp = fopen ("/dev/null", "r");
+ TEST_VERIFY_EXIT (fp != NULL);
+ fp = freopen64 (file1, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ setbuf (fp, NULL);
+ ret = fseeko64 (fp, 1LL << 32, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ ret = fputc ('x', fp);
+ TEST_COMPARE (ret, 'x');
+ xfclose (fp);
+ ret = remove (file1);
+ TEST_COMPARE (ret, 0);
+ END_TEST;
+
+ /* fopen64 with freopen64: large offsets OK. */
+ START_TEST ("testing fopen64 with freopen64\n");
+ fp = fopen64 ("/dev/null", "r");
+ TEST_VERIFY_EXIT (fp != NULL);
+ fp = freopen64 (file1, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ setbuf (fp, NULL);
+ ret = fseeko64 (fp, 1LL << 32, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ ret = fputc ('x', fp);
+ TEST_COMPARE (ret, 'x');
+ xfclose (fp);
+ ret = remove (file1);
+ TEST_COMPARE (ret, 0);
+ END_TEST;
+
+ /* fopen with freopen: large offsets not OK on 32-bit systems. */
+ START_TEST ("testing fopen with freopen\n");
+ fp = fopen ("/dev/null", "r");
+ TEST_VERIFY_EXIT (fp != NULL);
+ fp = freopen (file1, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ setbuf (fp, NULL);
+ ret = fseeko64 (fp, 1LL << 32, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ errno = 0;
+ ret = fputc ('x', fp);
+ if (sizeof (off_t) == 4)
+ {
+ TEST_COMPARE (ret, EOF);
+ TEST_COMPARE (errno, EFBIG);
+ }
+ else
+ TEST_COMPARE (ret, 'x');
+ fclose (fp);
+ ret = remove (file1);
+ TEST_COMPARE (ret, 0);
+ END_TEST;
+
+ /* fopen64 with freopen: large offsets not OK on 32-bit systems. */
+ START_TEST ("testing fopen64 with freopen\n");
+ fp = fopen64 ("/dev/null", "r");
+ TEST_VERIFY_EXIT (fp != NULL);
+ fp = freopen (file1, "w", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ setbuf (fp, NULL);
+ ret = fseeko64 (fp, 1LL << 32, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ errno = 0;
+ ret = fputc ('x', fp);
+ if (sizeof (off_t) == 4)
+ {
+ TEST_COMPARE (ret, EOF);
+ TEST_COMPARE (errno, EFBIG);
+ }
+ else
+ TEST_COMPARE (ret, 'x');
+ fclose (fp);
+ ret = remove (file1);
+ TEST_COMPARE (ret, 0);
+ END_TEST;
+
+ free (temp_dir);
+ free (file1);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-freopen6-main.c b/stdio-common/tst-freopen6-main.c
new file mode 100644
index 0000000..f493f42
--- /dev/null
+++ b/stdio-common/tst-freopen6-main.c
@@ -0,0 +1,98 @@
+/* Test freopen of stdin / stdout / stderr.
+ 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 <errno.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <support/check.h>
+#include <support/file_contents.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+
+int
+do_test (void)
+{
+ mtrace ();
+ char *temp_dir = support_create_temp_directory ("tst-freopen6");
+ char *file1 = xasprintf ("%s/file1", temp_dir);
+ support_write_file_string (file1, "file1");
+ add_temp_file (file1);
+ FILE *fp;
+ int ret;
+
+ verbose_printf ("Testing reopening stdin\n");
+ fp = FREOPEN (file1, "r", stdin);
+ TEST_VERIFY_EXIT (fp == stdin);
+ ret = getchar ();
+ TEST_COMPARE (ret, 'f');
+ ret = getchar ();
+ TEST_COMPARE (ret, 'i');
+ ret = getchar ();
+ TEST_COMPARE (ret, 'l');
+ ret = getchar ();
+ TEST_COMPARE (ret, 'e');
+ ret = getchar ();
+ TEST_COMPARE (ret, '1');
+ ret = getchar ();
+ TEST_COMPARE (ret, EOF);
+ xfclose (fp);
+
+ verbose_printf ("Testing reopening stderr\n");
+ fp = FREOPEN (file1, "w+", stderr);
+ TEST_VERIFY_EXIT (fp == stderr);
+ errno = EINVAL;
+ perror ("test");
+ ret = fseek (fp, 0, SEEK_SET);
+ TEST_COMPARE (ret, 0);
+ TEST_COMPARE_FILE_STRING (fp, "test: Invalid argument\n");
+ xfclose (fp);
+
+ verbose_printf ("Testing reopening stdout\n");
+ /* Defer checks until the old stdout has been restored to make it
+ more likely any errors are written to the old stdout (rather than
+ the temporary file used for the redirected stdout). */
+ int old_stdout = dup (STDOUT_FILENO);
+ TEST_VERIFY_EXIT (old_stdout != -1);
+ int ret_fseek = 0;
+ int ret_compare = 0;
+ fp = FREOPEN (file1, "w+", stdout);
+ int fp_eq_stdout = fp == stdout;
+ if (fp != NULL)
+ {
+ printf ("reopened\n");
+ ret_fseek = fseek (fp, 0, SEEK_SET);
+ ret_compare = support_compare_file_string (fp, "reopened\n");
+ }
+ xfclose (fp);
+ stdout = fdopen (old_stdout, "w");
+ TEST_VERIFY (fp_eq_stdout);
+ TEST_COMPARE (ret_fseek, 0);
+ TEST_COMPARE (ret_compare, 0);
+ xfclose (stdout);
+
+ free (temp_dir);
+ free (file1);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-freopen6.c b/stdio-common/tst-freopen6.c
new file mode 100644
index 0000000..8fd6957
--- /dev/null
+++ b/stdio-common/tst-freopen6.c
@@ -0,0 +1,2 @@
+#define FREOPEN freopen
+#include <tst-freopen6-main.c>
diff --git a/stdio-common/tst-freopen64-2.c b/stdio-common/tst-freopen64-2.c
new file mode 100644
index 0000000..88fdc64
--- /dev/null
+++ b/stdio-common/tst-freopen64-2.c
@@ -0,0 +1,3 @@
+#define FREOPEN freopen64
+#define OTHER_FREOPEN freopen
+#include <tst-freopen2-main.c>
diff --git a/stdio-common/tst-freopen64-3.c b/stdio-common/tst-freopen64-3.c
new file mode 100644
index 0000000..b91b6d2
--- /dev/null
+++ b/stdio-common/tst-freopen64-3.c
@@ -0,0 +1,2 @@
+#define FREOPEN freopen64
+#include <tst-freopen3-main.c>
diff --git a/stdio-common/tst-freopen64-4.c b/stdio-common/tst-freopen64-4.c
new file mode 100644
index 0000000..1411be2
--- /dev/null
+++ b/stdio-common/tst-freopen64-4.c
@@ -0,0 +1,2 @@
+#define FREOPEN freopen64
+#include <tst-freopen4-main.c>
diff --git a/stdio-common/tst-freopen64-6.c b/stdio-common/tst-freopen64-6.c
new file mode 100644
index 0000000..3ec509a
--- /dev/null
+++ b/stdio-common/tst-freopen64-6.c
@@ -0,0 +1,2 @@
+#define FREOPEN freopen64
+#include <tst-freopen6-main.c>
diff --git a/stdio-common/tst-freopen64-7.c b/stdio-common/tst-freopen64-7.c
new file mode 100644
index 0000000..f34c280
--- /dev/null
+++ b/stdio-common/tst-freopen64-7.c
@@ -0,0 +1,2 @@
+#define FREOPEN freopen64
+#include <tst-freopen7-main.c>
diff --git a/stdio-common/tst-freopen7-main.c b/stdio-common/tst-freopen7-main.c
new file mode 100644
index 0000000..965e0b4
--- /dev/null
+++ b/stdio-common/tst-freopen7-main.c
@@ -0,0 +1,155 @@
+/* Test freopen cancellation handling.
+ 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 <errno.h>
+#include <fcntl.h>
+#include <mcheck.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#include <support/check.h>
+#include <support/file_contents.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+
+char *file1, *file2, *file3, *fifo;
+
+sem_t sem;
+
+void *
+test_rc_to_r (void *p)
+{
+ int ret;
+ FILE *fp, *fp2;
+ ret = sem_post (&sem);
+ TEST_VERIFY_EXIT (ret == 0);
+ fp = xfopen (file1, "rc");
+ for (int i = 0; i < 1000000; i++)
+ {
+ fgetc (fp);
+ fseek (fp, 0, SEEK_SET);
+ }
+ fp2 = xfopen (file3, "wc");
+ fputs ("rc_to_r got to freopen", fp2);
+ xfclose (fp2);
+ /* Cancellation should occur at some point from here onwards
+ (possibly leaking memory and file descriptors associated with the
+ FILE). */
+ fp = FREOPEN (file2, "r", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ for (;;)
+ {
+ fgetc (fp);
+ fseek (fp, 0, SEEK_SET);
+ }
+}
+
+void *
+test_r_to_rc (void *p)
+{
+ int ret;
+ FILE *fp;
+ fp = xfopen (file1, "r");
+ fp = FREOPEN (fifo, "rc", fp);
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = sem_post (&sem);
+ TEST_VERIFY_EXIT (ret == 0);
+ /* No cancellation should occur for I/O on fifo. */
+ ret = fgetc (fp);
+ /* At this point, the other thread has called pthread_cancel and
+ then written a byte to the fifo, so this thread is cancelled at
+ the next cancellation point. */
+ TEST_VERIFY (ret == 'x');
+ xfclose (fp);
+ fp = xfopen (file3, "wc");
+ fputs ("r_to_rc got to fclose", fp);
+ xfclose (fp);
+ pthread_testcancel ();
+ FAIL_EXIT1 ("test_r_to_rc not cancelled\n");
+}
+
+int
+do_test (void)
+{
+ char *temp_dir = support_create_temp_directory ("tst-freopen-cancel");
+ file1 = xasprintf ("%s/file1", temp_dir);
+ support_write_file_string (file1, "file1");
+ add_temp_file (file1);
+ file2 = xasprintf ("%s/file2", temp_dir);
+ support_write_file_string (file2, "file2");
+ add_temp_file (file2);
+ file3 = xasprintf ("%s/file3", temp_dir);
+ support_write_file_string (file3, "file3");
+ add_temp_file (file3);
+ fifo = xasprintf ("%s/fifo", temp_dir);
+ xmkfifo (fifo, 0666);
+ add_temp_file (fifo);
+ int ret;
+ pthread_t thr;
+ void *retval;
+
+ /* Test changing to/from c (cancellation disabled). */
+
+ verbose_printf ("Testing rc -> r\n");
+ ret = sem_init (&sem, 0, 0);
+ TEST_VERIFY_EXIT (ret == 0);
+ thr = xpthread_create (NULL, test_rc_to_r, NULL);
+ ret = sem_wait (&sem);
+ TEST_VERIFY_EXIT (ret == 0);
+ xpthread_cancel (thr);
+ ret = pthread_join (thr, &retval);
+ TEST_COMPARE (ret, 0);
+ TEST_VERIFY (retval == PTHREAD_CANCELED);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file3, "rc_to_r got to freopen");
+
+ verbose_printf ("Testing r -> rc\n");
+ ret = sem_init (&sem, 0, 0);
+ TEST_VERIFY_EXIT (ret == 0);
+ thr = xpthread_create (NULL, test_r_to_rc, NULL);
+ FILE *fp = xfopen (fifo, "w");
+ ret = sem_wait (&sem);
+ TEST_VERIFY_EXIT (ret == 0);
+ /* This call happens while, or before, the other thread is waiting
+ to read a character from the fifo. It thus verifies that
+ cancellation does not occur from the fgetc call in that thread
+ (it should instead occur only in pthread_testcancel call),
+ because the expected string is only written to file3 after that
+ thread closes the fifo. */
+ xpthread_cancel (thr);
+ fputc ('x', fp);
+ xfclose (fp);
+ ret = pthread_join (thr, &retval);
+ TEST_COMPARE (ret, 0);
+ TEST_VERIFY (retval == PTHREAD_CANCELED);
+ TEST_OPEN_AND_COMPARE_FILE_STRING (file3, "r_to_rc got to fclose");
+
+ free (temp_dir);
+ free (file1);
+ free (file2);
+ free (file3);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-freopen7.c b/stdio-common/tst-freopen7.c
new file mode 100644
index 0000000..03d0de7
--- /dev/null
+++ b/stdio-common/tst-freopen7.c
@@ -0,0 +1,2 @@
+#define FREOPEN freopen
+#include <tst-freopen7-main.c>
diff --git a/stdio-common/tst-fwrite-memstrm.c b/stdio-common/tst-fwrite-memstrm.c
new file mode 100644
index 0000000..7ee3831
--- /dev/null
+++ b/stdio-common/tst-fwrite-memstrm.c
@@ -0,0 +1,177 @@
+/* Test fwrite on a memory stream.
+ 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>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+void
+test_ro (void)
+{
+ FILE *f;
+ char *out;
+
+ /* Try to allocate a small buffer for this test. */
+ out = malloc (2);
+ TEST_VERIFY_EXIT (out != NULL);
+
+ /* Try to open the allocated buffer as a read-only stream. */
+ f = fmemopen (out, 2, "r");
+ TEST_VERIFY_EXIT (f != NULL);
+
+ /* Try to write to the temporary file with nmemb = 0, then check that
+ fwrite returns 0. No errors are expected from this. */
+ TEST_COMPARE (fwrite ("a", 1, 0, f), 0);
+ TEST_COMPARE (ferror (f), 0);
+
+ /* Try to write to the temporary file with size = 0, then check that
+ fwrite returns 0. No errors are expected from this. */
+ TEST_COMPARE (fwrite ("a", 0, 1, f), 0);
+ TEST_COMPARE (ferror (f), 0);
+
+ /* Try to write a single byte to the temporary file, then check that
+ fwrite returns 0. Check if an error was reported. */
+ TEST_COMPARE (fwrite ("a", 1, 1, f), 0);
+ TEST_COMPARE (ferror (f), 1);
+
+ clearerr (f);
+ xfclose (f);
+ free (out);
+}
+
+/* Length of the output buffer in bytes. */
+#define RWBUF_SIZE 16 * 1024
+/* Maximum number of bytes to be written in output buffer. The rest will be
+ used to check against overflow. */
+#define RWBUF_SIZE_WRITABLE RWBUF_SIZE-2048
+
+/* Use the following byte to identify areas that should have not been
+ modified. */
+#define KNOWN_BYTE 0xaa
+
+void
+test_one_rw (const char *in, size_t size, size_t nmemb,
+ size_t expected_ret)
+{
+ FILE *f;
+ char *out, *expected_out;
+ /* Total number of bytes expected to be written. */
+ size_t expected_bytes = size * nmemb;
+
+ printf ("Testing with size = %zd, nmemb = %zd\n", size, nmemb);
+
+ TEST_VERIFY_EXIT (expected_ret <= RWBUF_SIZE_WRITABLE);
+ TEST_VERIFY_EXIT (expected_bytes <= RWBUF_SIZE_WRITABLE);
+
+ /* Try to allocate a buffer for this test and initialize it with
+ known contents. */
+ out = malloc (RWBUF_SIZE);
+ TEST_VERIFY_EXIT (out != NULL);
+ memset (out, KNOWN_BYTE, RWBUF_SIZE);
+
+ /* Try to allocate a buffer and fill it with the contents that are expected
+ to be in memory after flushing/closing the memory stream. */
+ expected_out = malloc (RWBUF_SIZE);
+ TEST_VERIFY_EXIT (expected_out != NULL);
+ if (expected_bytes > 0)
+ {
+ memcpy (expected_out, in, expected_bytes);
+ expected_out[expected_bytes] = 0;
+ memset (expected_out + expected_bytes + 1, KNOWN_BYTE,
+ RWBUF_SIZE - expected_bytes - 1);
+ }
+ else
+ {
+ /* No changes to the output are expected. */
+ memset (expected_out, KNOWN_BYTE, RWBUF_SIZE);
+ }
+
+ /* Try to open the allocated buffer as a read-write stream. */
+ f = fmemopen (out, RWBUF_SIZE, "w");
+ TEST_VERIFY_EXIT (f != NULL);
+
+ /* Try to write to the memory stream. Check if fwrite() returns the
+ expected value. No errors are expected. */
+ TEST_COMPARE (fwrite (in, size, nmemb, f), expected_ret);
+ TEST_COMPARE (ferror (f), 0);
+
+ xfclose (f);
+
+ /* Ensure the output has the expected contents. */
+ TEST_COMPARE (memcmp (out, expected_out, expected_bytes), 0);
+
+ free (expected_out);
+ free (out);
+}
+
+void
+test_rw (void)
+{
+ char * in;
+ int i, j;
+ size_t size[] = {1, 8, 11, 16, 17, 0};
+ size_t nmemb[] = {32, 83, 278, 709, 4097, RWBUF_SIZE / 2,
+ RWBUF_SIZE_WRITABLE, 0};
+ size_t n;
+
+ /* Try to write to the temporary file with nmemb = 0, then check that
+ fwrite returns 0; */
+ test_one_rw ("a", 1, 0, 0);
+
+ /* Try to write to the temporary file with size = 0, then check that
+ fwrite returns 0; */
+ test_one_rw ("a", 0, 1, 0);
+
+ /* Try to write a single byte to the temporary file, then check that
+ fwrite returns 1; */
+ test_one_rw ("a", 1, 2, 2);
+
+ in = malloc (RWBUF_SIZE);
+ TEST_VERIFY_EXIT (in != NULL);
+ for (i = 0; i < RWBUF_SIZE / 2; i++)
+ in[i] = i % 0xff;
+
+ /* Test with all posibilities of size[] x nmemb[]. */
+ for (i = 0; nmemb[i] != 0; i++)
+ {
+ for (j = 0; size[j] != 0; j++)
+ {
+ n = nmemb[i] / size[j];
+ test_one_rw (in, size[j], n, n);
+ }
+ /* Run the test with a single item of maximum size. */
+ test_one_rw (in, nmemb[i], 1, 1);
+ }
+
+ free (in);
+}
+
+static int
+do_test (void)
+{
+ test_ro ();
+ test_rw ();
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-fwrite-overflow.c b/stdio-common/tst-fwrite-overflow.c
new file mode 100644
index 0000000..fe503fd
--- /dev/null
+++ b/stdio-common/tst-fwrite-overflow.c
@@ -0,0 +1,130 @@
+/* Test the overflow of fwrite's internal buffer.
+ 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/>. */
+
+/* stdio.h provides BUFSIZ, which is the size of fwrite's internal buffer. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+#include <support/support.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+/* Length of the buffers in bytes. */
+#define RWBUF_SIZE (2 * BUFSIZ)
+
+void
+test_one_rw (const char *in, size_t size, size_t nmemb, size_t blocks)
+{
+ int fd;
+ FILE *f;
+ char *out;
+ size_t written, to_write;
+ const size_t requested = size * nmemb;
+
+ printf ("Testing with size = %zd, nmemb = %zd, blocks = %zd\n",
+ size, nmemb, blocks);
+
+ TEST_VERIFY_EXIT (requested <= RWBUF_SIZE);
+ /* Ensure fwrite's internal buffer will overflow. */
+ TEST_VERIFY_EXIT (requested > BUFSIZ);
+
+ /* Create a temporary file and open it for reading and writing. */
+ fd = create_temp_file ("tst-fwrite-overflow", NULL);
+ TEST_VERIFY_EXIT (fd != -1);
+ f = fdopen (fd, "w+");
+ TEST_VERIFY_EXIT (f != NULL);
+
+ /* Call fwrite() as many times as needed, until all data is written,
+ limiting the amount of data written per call to block items. */
+ for (written = 0; written < nmemb; written += to_write)
+ {
+ if (written + blocks <= nmemb)
+ to_write = blocks;
+ else
+ to_write = nmemb - written;
+ /* Check if fwrite() returns the expected value. No errors are
+ expected. */
+ TEST_COMPARE (fwrite (in + size * written, size, to_write, f),
+ to_write);
+ TEST_COMPARE (ferror (f), 0);
+ }
+ TEST_VERIFY_EXIT (written == nmemb);
+
+ /* Ensure all the data is flushed to file. */
+ TEST_COMPARE (fflush (f), 0);
+
+ /* We have to check if the contents in the file are correct. Go back to
+ the beginning of the file. */
+ rewind (f);
+ /* Try to allocate a buffer and save the contents of the generated file to
+ it. */
+ out = xmalloc (RWBUF_SIZE);
+ TEST_COMPARE (fread (out, size, nmemb, f), nmemb);
+
+ /* Ensure the output has the expected contents. */
+ TEST_COMPARE (memcmp (out, in, requested), 0);
+
+ xfclose (f);
+ free (out);
+}
+
+static int
+do_test (void)
+{
+ char * in;
+ int i, j;
+ size_t nmemb[] = {BUFSIZ + 1, RWBUF_SIZE, 0};
+ /* Maximum number of items written for each fwrite call. */
+ size_t block[] = {100, 1024, 2047, 0};
+ /* The largest block must fit entirely in fwrite's buffer. */
+ _Static_assert (2047 < BUFSIZ,
+ "a block must fit in fwrite's internal buffer");
+
+ in = xmalloc (RWBUF_SIZE);
+ for (i = 0; i < RWBUF_SIZE; i++)
+ in[i] = i % 0xff;
+
+ for (i = 0; nmemb[i] != 0; i++)
+ for (j = 0; block[j] != 0; j++)
+ {
+ /* Run a test with an array of nmemb bytes. Write at most block
+ items per fwrite call. */
+ test_one_rw (in, 1, nmemb[i], block[j]);
+ /* Run a test that overflows fwrite's internal buffer in a single call
+ by writting a single item of nmemb bytes.
+ This call should not use the buffer and should be written directly
+ to the file. */
+ test_one_rw (in, nmemb[i], 1, nmemb[i]);
+ }
+
+ for (j = 0; block[j] != 0; j++)
+ {
+ /* Run a test with size=2 and the minimum nmemb value that still
+ overflows the buffer. Write at most block items per fwrite call. */
+ test_one_rw (in, 2, BUFSIZ / 2 + 1, block[j]);
+ /* Likewise, but size=3. */
+ test_one_rw (in, 3, BUFSIZ / 3 + 1, block[j]);
+ }
+
+ free (in);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-fwrite-ro.c b/stdio-common/tst-fwrite-ro.c
new file mode 100644
index 0000000..7013bee
--- /dev/null
+++ b/stdio-common/tst-fwrite-ro.c
@@ -0,0 +1,65 @@
+/* Test fwrite on a read-only stream.
+ 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>
+#include <support/check.h>
+#include <support/temp_file.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+/* A small buffer size is enough to run this test. */
+#define BUFSIZE 4
+
+static int
+do_test (void)
+{
+ int fd;
+ FILE *f;
+ struct stat64 st;
+
+ /* Create a temporary file and open it in read-only mode. */
+ fd = create_temp_file ("tst-fwrite-ro", NULL);
+ TEST_VERIFY_EXIT (fd != -1);
+ f = fdopen (fd, "r");
+ TEST_VERIFY_EXIT (f != NULL);
+
+ /* Try to write to the temporary file with nmemb = 0, then check that
+ fwrite returns 0. No errors are expected from this. */
+ TEST_COMPARE (fwrite ("a", 1, 0, f), 0);
+ TEST_COMPARE (ferror (f), 0);
+
+ /* Try to write to the temporary file with size = 0, then check that
+ fwrite returns 0. No errors are expected from this. */
+ TEST_COMPARE (fwrite ("a", 0, 1, f), 0);
+ TEST_COMPARE (ferror (f), 0);
+
+ /* Try to write a single byte to the temporary file, then check that
+ fwrite returns 0. Check if an error was reported. */
+ TEST_COMPARE (fwrite ("a", 1, 1, f), 0);
+ TEST_COMPARE (ferror (f), 1);
+ clearerr (f);
+
+ xfstat64 (fd, &st);
+ TEST_COMPARE (st.st_size, 0);
+
+ xfclose (f);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-getline-enomem.c b/stdio-common/tst-getline-enomem.c
new file mode 100644
index 0000000..7fc70ea
--- /dev/null
+++ b/stdio-common/tst-getline-enomem.c
@@ -0,0 +1,78 @@
+/* Test getline: ENOMEM on allocation failure.
+ 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 <errno.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+
+#include <support/check.h>
+#include <support/test-driver.h>
+
+/* Produce a stream of test data based on data in COOKIE (ignored),
+ storing up to SIZE bytes in BUF. */
+
+static ssize_t
+io_read (void *cookie, char *buf, size_t size)
+{
+ memset (buf, 'x', size);
+ return size;
+}
+
+/* Set up a test stream with fopencookie. */
+
+static FILE *
+open_test_stream (void)
+{
+ static cookie_io_functions_t io_funcs = { .read = io_read };
+ static int cookie;
+ FILE *fp = fopencookie (&cookie, "r", io_funcs);
+ TEST_VERIFY_EXIT (fp != NULL);
+ return fp;
+}
+
+int
+do_test (void)
+{
+ FILE *fp;
+ char *lineptr = NULL;
+ size_t size = 0;
+ ssize_t ret;
+ mtrace ();
+ /* Test ENOMEM (and error indicator for stream set) for memory
+ allocation failure. */
+ verbose_printf ("Testing memory allocation failure\n");
+ fp = open_test_stream ();
+ struct rlimit limit;
+ TEST_VERIFY_EXIT (getrlimit (RLIMIT_AS, &limit) == 0);
+ limit.rlim_cur = 32 * 1024 * 1024;
+ TEST_VERIFY_EXIT (setrlimit (RLIMIT_AS, &limit) == 0);
+ errno = 0;
+ ret = getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, ENOMEM);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ free (lineptr);
+ fclose (fp);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-getline.c b/stdio-common/tst-getline.c
new file mode 100644
index 0000000..29eb7ce
--- /dev/null
+++ b/stdio-common/tst-getline.c
@@ -0,0 +1,451 @@
+/* Test getline.
+ 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 <errno.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <support/check.h>
+#include <support/test-driver.h>
+#include <support/support.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+static struct test_data
+{
+ /* Input test data for fopencookie stream. */
+ const char *in_data;
+
+ /* The amount of test data left. */
+ size_t in_data_left;
+
+ /* Error number for forcing an error on next read. */
+ int in_error;
+
+ /* Error number for forcing an error (rather than EOF) after all
+ bytes read. */
+ int in_error_after;
+} the_cookie;
+
+/* Produce a stream of test data based on data in COOKIE, storing up
+ to SIZE bytes in BUF. */
+
+static ssize_t
+io_read (void *cookie, char *buf, size_t size)
+{
+ struct test_data *p = cookie;
+ if (p->in_error)
+ {
+ errno = p->in_error;
+ return -1;
+ }
+ if (size > p->in_data_left)
+ size = p->in_data_left;
+ memcpy (buf, p->in_data, size);
+ p->in_data += size;
+ p->in_data_left -= size;
+ if (p->in_data_left == 0)
+ p->in_error = p->in_error_after;
+ return size;
+}
+
+/* Set up a test stream with fopencookie. */
+
+static FILE *
+open_test_stream (const char *in_data, size_t size)
+{
+ static cookie_io_functions_t io_funcs = { .read = io_read };
+ the_cookie.in_data = in_data;
+ the_cookie.in_data_left = size;
+ the_cookie.in_error = 0;
+ the_cookie.in_error_after = 0;
+ FILE *fp = fopencookie (&the_cookie, "r", io_funcs);
+ TEST_VERIFY_EXIT (fp != NULL);
+ return fp;
+}
+
+/* Set up a test stream with fopencookie, using data from a string
+ literal. */
+#define OPEN_TEST_STREAM(IN_DATA) open_test_stream (IN_DATA, sizeof (IN_DATA))
+
+/* Wrap getline to verify that (as per the glibc manual), *LINEPTR is
+ returned as non-null and with at least *N bytes (even on error or
+ EOF). Also clear errno for the benefit of tests that check the
+ value of errno after the call. */
+
+ssize_t
+wrap_getline (char **lineptr, size_t *n, FILE *stream)
+{
+ errno = 0;
+ ssize_t ret = getline (lineptr, n, stream);
+ if (lineptr != NULL && n != NULL)
+ {
+ TEST_VERIFY (*lineptr != NULL);
+ TEST_VERIFY (malloc_usable_size (*lineptr) >= *n);
+ }
+ return ret;
+}
+
+int
+do_test (void)
+{
+ FILE *fp;
+ char *lineptr = NULL;
+ size_t size = 0;
+ ssize_t ret;
+ mtrace ();
+ /* Test failure with EINVAL (and error indicator for stream set) if
+ lineptr is a null pointer. */
+ verbose_printf ("Testing lineptr == NULL\n");
+ fp = OPEN_TEST_STREAM ("test");
+ ret = wrap_getline (NULL, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, EINVAL);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ fclose (fp);
+ /* Test failure with EINVAL (and error indicator for stream set) if
+ n is a null pointer. */
+ verbose_printf ("Testing n == NULL\n");
+ fp = OPEN_TEST_STREAM ("test");
+ ret = wrap_getline (&lineptr, NULL, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, EINVAL);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ fclose (fp);
+ /* Test failure with EINVAL (and error indicator for stream set) if
+ both lineptr and n are null pointers. */
+ verbose_printf ("Testing lineptr == NULL and n == NULL\n");
+ fp = OPEN_TEST_STREAM ("test");
+ ret = wrap_getline (NULL, NULL, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, EINVAL);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ fclose (fp);
+ /* Test normal line, fitting in available space (including case with
+ null bytes). */
+ verbose_printf ("Testing normal nonempty input\n");
+ lineptr = xmalloc (10);
+ size = 10;
+ fp = OPEN_TEST_STREAM ("foo\nbar\0\n\0baz\nte\0st\n");
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "foo\n", 5);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "bar\0\n", 6);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "\0baz\n", 6);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 6);
+ TEST_COMPARE_BLOB (lineptr, 7, "te\0st\n", 7);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 1);
+ TEST_COMPARE_BLOB (lineptr, 1, "", 1);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (!!feof (fp), 1);
+ fclose (fp);
+ /* Test normal line, with reallocation (including case with null bytes). */
+ verbose_printf ("Testing normal nonempty input with reallocation\n");
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = OPEN_TEST_STREAM ("foo\nbar\0\n\0baz\nte\0st\n"
+ "foo\nbar\0\n\0baz\nte\0st\n");
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "foo\n", 5);
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "bar\0\n", 6);
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "\0baz\n", 6);
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 6);
+ TEST_COMPARE_BLOB (lineptr, 7, "te\0st\n", 7);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "foo\n", 5);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "bar\0\n", 6);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "\0baz\n", 6);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 6);
+ TEST_COMPARE_BLOB (lineptr, 7, "te\0st\n", 7);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 1);
+ TEST_COMPARE_BLOB (lineptr, 1, "", 1);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (!!feof (fp), 1);
+ fclose (fp);
+ /* Test EOF before delimiter but after some bytes read, fitting in
+ available space (including case with null bytes). */
+ verbose_printf ("Testing EOF before delimiter\n");
+ free (lineptr);
+ lineptr = xmalloc (10);
+ size = 10;
+ fp = open_test_stream ("foo", 3);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 3);
+ TEST_COMPARE_BLOB (lineptr, 4, "foo", 4);
+ fclose (fp);
+ free (lineptr);
+ lineptr = xmalloc (10);
+ size = 10;
+ fp = open_test_stream ("bar\0", 4);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "bar\0", 5);
+ fclose (fp);
+ free (lineptr);
+ lineptr = xmalloc (10);
+ size = 10;
+ fp = open_test_stream ("\0baz", 4);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "\0baz", 5);
+ fclose (fp);
+ free (lineptr);
+ lineptr = xmalloc (10);
+ size = 10;
+ fp = open_test_stream ("te\0st", 5);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "te\0st", 6);
+ fclose (fp);
+ /* Test EOF before delimiter but after some bytes read, with
+ reallocation (including case with null bytes). */
+ verbose_printf ("Testing EOF before delimiter with reallocation\n");
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = open_test_stream ("foo", 3);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 3);
+ TEST_COMPARE_BLOB (lineptr, 4, "foo", 4);
+ fclose (fp);
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = open_test_stream ("bar\0", 4);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "bar\0", 5);
+ fclose (fp);
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = open_test_stream ("\0baz", 4);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "\0baz", 5);
+ fclose (fp);
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = open_test_stream ("te\0st", 5);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "te\0st", 6);
+ fclose (fp);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ fp = open_test_stream ("foo", 3);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 3);
+ TEST_COMPARE_BLOB (lineptr, 4, "foo", 4);
+ fclose (fp);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ fp = open_test_stream ("bar\0", 4);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "bar\0", 5);
+ fclose (fp);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ fp = open_test_stream ("\0baz", 4);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 4);
+ TEST_COMPARE_BLOB (lineptr, 5, "\0baz", 5);
+ fclose (fp);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ fp = open_test_stream ("te\0st", 5);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 5);
+ TEST_COMPARE_BLOB (lineptr, 6, "te\0st", 6);
+ fclose (fp);
+ /* Test EOF with no bytes read (nothing is specified about anything
+ written to the buffer), including EOF again when already at end
+ of file. */
+ verbose_printf ("Testing EOF with no bytes read\n");
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = open_test_stream ("", 0);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (!!feof (fp), 1);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (!!feof (fp), 1);
+ fclose (fp);
+ free (lineptr);
+ lineptr = xmalloc (1);
+ size = 1;
+ fp = open_test_stream ("", 0);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (!!feof (fp), 1);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (ferror (fp), 0);
+ TEST_COMPARE (!!feof (fp), 1);
+ fclose (fp);
+ /* Test error occurring with no bytes read, including calling
+ wrap_getline again while the file is in error state. */
+ verbose_printf ("Testing error with no bytes read\n");
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = open_test_stream ("", 0);
+ the_cookie.in_error = EINVAL;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, EINVAL);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ /* Make sure error state is sticky. */
+ the_cookie.in_error = 0;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ fclose (fp);
+ /* Test error occurring after some bytes read. Specifications are
+ ambiguous here; at least in the fopencookie case used for
+ testing, glibc returns the partial line (but with the error
+ indicator on the stream set). */
+ verbose_printf ("Testing error after some bytes read\n");
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = open_test_stream ("foo", 3);
+ the_cookie.in_error_after = EINVAL;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, 3);
+ TEST_COMPARE_BLOB (lineptr, 4, "foo", 4);
+ TEST_COMPARE (errno, EINVAL);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ /* Make sure error state is sticky. */
+ the_cookie.in_error = 0;
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ fclose (fp);
+ /* Test EBADF error as a representative example of an fgetc error
+ resulting in an error from wrap_getline. We don't try to cover all
+ error cases for fgetc here. */
+ verbose_printf ("Testing EBADF error\n");
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ fp = xfopen ("/dev/null", "r");
+ xclose (fileno (fp));
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, EBADF);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ fclose (fp);
+ /* Test EAGAIN error as an example of an fgetc error on a valid file
+ descriptor. */
+ verbose_printf ("Testing EAGAIN error\n");
+ free (lineptr);
+ lineptr = NULL;
+ size = 0;
+ int pipefd[2];
+ xpipe (pipefd);
+ ret = fcntl (pipefd[0], F_SETFL, O_NONBLOCK);
+ TEST_VERIFY_EXIT (ret == 0);
+ fp = fdopen (pipefd[0], "r");
+ TEST_VERIFY_EXIT (fp != NULL);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, EAGAIN);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ /* Make sure error state is sticky (even after more data is
+ available to read). */
+ xwrite (pipefd[1], "x\n", 2);
+ ret = wrap_getline (&lineptr, &size, fp);
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (!!ferror (fp), 1);
+ TEST_COMPARE (feof (fp), 0);
+ fclose (fp);
+ free (lineptr);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-printf-format-as-c.c b/stdio-common/tst-printf-format-as-c.c
new file mode 100644
index 0000000..9eaf7ae
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-as-char.c b/stdio-common/tst-printf-format-as-char.c
new file mode 100644
index 0000000..d9266d5
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-as-double.c b/stdio-common/tst-printf-format-as-double.c
new file mode 100644
index 0000000..370ce8c
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-double.c
@@ -0,0 +1,22 @@
+/* Test for formatted 'asprintf' 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/>. */
+
+#define TIMEOUT (DEFAULT_TIMEOUT * 32)
+
+#include "tst-printf-format-as.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-as-int.c b/stdio-common/tst-printf-format-as-int.c
new file mode 100644
index 0000000..e6e10a9
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-as-ldouble.c b/stdio-common/tst-printf-format-as-ldouble.c
new file mode 100644
index 0000000..e7f7220
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-ldouble.c
@@ -0,0 +1,22 @@
+/* Test for formatted 'asprintf' 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/>. */
+
+#define TIMEOUT (DEFAULT_TIMEOUT * 128)
+
+#include "tst-printf-format-as.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-as-llong.c b/stdio-common/tst-printf-format-as-llong.c
new file mode 100644
index 0000000..beaad73
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-as-long.c b/stdio-common/tst-printf-format-as-long.c
new file mode 100644
index 0000000..7d968a8
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-as-s.c b/stdio-common/tst-printf-format-as-s.c
new file mode 100644
index 0000000..baa883d
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-as-short.c b/stdio-common/tst-printf-format-as-short.c
new file mode 100644
index 0000000..8d0b078
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-as-uchar.c b/stdio-common/tst-printf-format-as-uchar.c
new file mode 100644
index 0000000..8e46254
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-as-uint.c b/stdio-common/tst-printf-format-as-uint.c
new file mode 100644
index 0000000..8cf38d7
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-as-ullong.c b/stdio-common/tst-printf-format-as-ullong.c
new file mode 100644
index 0000000..30b31ed
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-as-ulong.c b/stdio-common/tst-printf-format-as-ulong.c
new file mode 100644
index 0000000..9b108aa
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-as-ushort.c b/stdio-common/tst-printf-format-as-ushort.c
new file mode 100644
index 0000000..44b912f
--- /dev/null
+++ b/stdio-common/tst-printf-format-as-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'asprintf' 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-as.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-as.h b/stdio-common/tst-printf-format-as.h
new file mode 100644
index 0000000..c30d2e2
--- /dev/null
+++ b/stdio-common/tst-printf-format-as.h
@@ -0,0 +1,46 @@
+/* Test feature wrapper for formatted 'asprintf' 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>
+#include <stdlib.h>
+
+#define printf_under_test(...) \
+({ \
+ __label__ out; \
+ int result; \
+ char *str; \
+ \
+ result = asprintf (&str, __VA_ARGS__); \
+ if (result < 0) \
+ { \
+ perror ("asprintf"); \
+ goto out; \
+ } \
+ if (fwrite (str, sizeof (*str), result, stdout) != result) \
+ { \
+ perror ("fwrite"); \
+ result = -1; \
+ } \
+ free (str); \
+out: \
+ result; \
+})
+
+#ifndef TIMEOUT
+# define TIMEOUT (DEFAULT_TIMEOUT * 12)
+#endif
diff --git a/stdio-common/tst-printf-format-c.sh b/stdio-common/tst-printf-format-c.sh
new file mode 100644
index 0000000..2b8d720
--- /dev/null
+++ b/stdio-common/tst-printf-format-c.sh
@@ -0,0 +1,34 @@
+#!/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
diff --git a/stdio-common/tst-printf-format-char.sh b/stdio-common/tst-printf-format-char.sh
new file mode 100644
index 0000000..9921967
--- /dev/null
+++ b/stdio-common/tst-printf-format-char.sh
@@ -0,0 +1,40 @@
+#!/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
diff --git a/stdio-common/tst-printf-format-d-c.c b/stdio-common/tst-printf-format-d-c.c
new file mode 100644
index 0000000..61fd066
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-d-char.c b/stdio-common/tst-printf-format-d-char.c
new file mode 100644
index 0000000..baa6e16
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-d-double.c b/stdio-common/tst-printf-format-d-double.c
new file mode 100644
index 0000000..e432a95
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-d-int.c b/stdio-common/tst-printf-format-d-int.c
new file mode 100644
index 0000000..6d59b23
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-d-ldouble.c b/stdio-common/tst-printf-format-d-ldouble.c
new file mode 100644
index 0000000..67a2bae
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-d-llong.c b/stdio-common/tst-printf-format-d-llong.c
new file mode 100644
index 0000000..950a2b8
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-d-long.c b/stdio-common/tst-printf-format-d-long.c
new file mode 100644
index 0000000..4fabb41
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-d-s.c b/stdio-common/tst-printf-format-d-s.c
new file mode 100644
index 0000000..1ef896e
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-d-short.c b/stdio-common/tst-printf-format-d-short.c
new file mode 100644
index 0000000..17767bb
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-d-uchar.c b/stdio-common/tst-printf-format-d-uchar.c
new file mode 100644
index 0000000..732479e
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-d-uint.c b/stdio-common/tst-printf-format-d-uint.c
new file mode 100644
index 0000000..5b68aec
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-d-ullong.c b/stdio-common/tst-printf-format-d-ullong.c
new file mode 100644
index 0000000..0e20a1d
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-d-ulong.c b/stdio-common/tst-printf-format-d-ulong.c
new file mode 100644
index 0000000..62085ac
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-d-ushort.c b/stdio-common/tst-printf-format-d-ushort.c
new file mode 100644
index 0000000..7d8ef76
--- /dev/null
+++ b/stdio-common/tst-printf-format-d-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'dprintf' 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-d.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-d.h b/stdio-common/tst-printf-format-d.h
new file mode 100644
index 0000000..af7f26c
--- /dev/null
+++ b/stdio-common/tst-printf-format-d.h
@@ -0,0 +1,58 @@
+/* Test feature wrapper for formatted 'dprintf' 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 <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* We need to go through the POSIX-mandated dance to switch between
+ handles on an open file description. */
+
+#define printf_under_test(...) \
+({ \
+ __label__ out; \
+ int result; \
+ \
+ result = fflush (stdout); \
+ if (result == EOF) \
+ { \
+ perror ("fflush"); \
+ goto out; \
+ } \
+ result = lseek (STDOUT_FILENO, 0, SEEK_END); \
+ if (result < 0 && errno == ESPIPE) \
+ result = 0; \
+ if (result < 0) \
+ { \
+ perror ("lseek"); \
+ goto out; \
+ } \
+ result = dprintf (STDOUT_FILENO, __VA_ARGS__); \
+ if (result < 0) \
+ { \
+ perror ("dprintf"); \
+ goto out; \
+ } \
+ result = fseek (stdout, 0, SEEK_END); \
+ if (result < 0 && errno == ESPIPE) \
+ result = 0; \
+ if (result < 0) \
+ perror ("fseek"); \
+out: \
+ result; \
+})
diff --git a/stdio-common/tst-printf-format-double.sh b/stdio-common/tst-printf-format-double.sh
new file mode 100644
index 0000000..b4e61ac
--- /dev/null
+++ b/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
diff --git a/stdio-common/tst-printf-format-f-c.c b/stdio-common/tst-printf-format-f-c.c
new file mode 100644
index 0000000..1db9e2b
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-f-char.c b/stdio-common/tst-printf-format-f-char.c
new file mode 100644
index 0000000..a492f31
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-f-double.c b/stdio-common/tst-printf-format-f-double.c
new file mode 100644
index 0000000..906ef0b
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-f-int.c b/stdio-common/tst-printf-format-f-int.c
new file mode 100644
index 0000000..92dc0c9
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-f-ldouble.c b/stdio-common/tst-printf-format-f-ldouble.c
new file mode 100644
index 0000000..0a0c88d
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-f-llong.c b/stdio-common/tst-printf-format-f-llong.c
new file mode 100644
index 0000000..ceb8d03
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-f-long.c b/stdio-common/tst-printf-format-f-long.c
new file mode 100644
index 0000000..a4a5dca
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-f-s.c b/stdio-common/tst-printf-format-f-s.c
new file mode 100644
index 0000000..da0e0f8
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-f-short.c b/stdio-common/tst-printf-format-f-short.c
new file mode 100644
index 0000000..3abd134
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-f-uchar.c b/stdio-common/tst-printf-format-f-uchar.c
new file mode 100644
index 0000000..f104cde
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-f-uint.c b/stdio-common/tst-printf-format-f-uint.c
new file mode 100644
index 0000000..0e1fdb4
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-f-ullong.c b/stdio-common/tst-printf-format-f-ullong.c
new file mode 100644
index 0000000..b4669fc
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-f-ulong.c b/stdio-common/tst-printf-format-f-ulong.c
new file mode 100644
index 0000000..3f4f900
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-f-ushort.c b/stdio-common/tst-printf-format-f-ushort.c
new file mode 100644
index 0000000..d49c237
--- /dev/null
+++ b/stdio-common/tst-printf-format-f-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'fprintf' 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-f.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-f.h b/stdio-common/tst-printf-format-f.h
new file mode 100644
index 0000000..efb3283
--- /dev/null
+++ b/stdio-common/tst-printf-format-f.h
@@ -0,0 +1,29 @@
+/* Test feature wrapper for formatted 'fprintf' 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 = fprintf (stdout, __VA_ARGS__); \
+ if (result < 0) \
+ perror ("fprintf"); \
+ result; \
+})
diff --git a/stdio-common/tst-printf-format-int.sh b/stdio-common/tst-printf-format-int.sh
new file mode 100644
index 0000000..32dcfb1
--- /dev/null
+++ b/stdio-common/tst-printf-format-int.sh
@@ -0,0 +1,53 @@
+#!/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
diff --git a/stdio-common/tst-printf-format-ldouble.sh b/stdio-common/tst-printf-format-ldouble.sh
new file mode 100644
index 0000000..4bfecad
--- /dev/null
+++ b/stdio-common/tst-printf-format-ldouble.sh
@@ -0,0 +1,74 @@
+#!/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
diff --git a/stdio-common/tst-printf-format-llong.sh b/stdio-common/tst-printf-format-llong.sh
new file mode 100644
index 0000000..b028a2c
--- /dev/null
+++ b/stdio-common/tst-printf-format-llong.sh
@@ -0,0 +1,53 @@
+#!/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
diff --git a/stdio-common/tst-printf-format-long.sh b/stdio-common/tst-printf-format-long.sh
new file mode 100644
index 0000000..77c67ea
--- /dev/null
+++ b/stdio-common/tst-printf-format-long.sh
@@ -0,0 +1,53 @@
+#!/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
diff --git a/stdio-common/tst-printf-format-p-c.c b/stdio-common/tst-printf-format-p-c.c
new file mode 100644
index 0000000..ba46f55
--- /dev/null
+++ b/stdio-common/tst-printf-format-p-c.c
@@ -0,0 +1,20 @@
+/* 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"
diff --git a/stdio-common/tst-printf-format-p-char.c b/stdio-common/tst-printf-format-p-char.c
new file mode 100644
index 0000000..7640bf8
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-double.c b/stdio-common/tst-printf-format-p-double.c
new file mode 100644
index 0000000..8271ec7
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-int.c b/stdio-common/tst-printf-format-p-int.c
new file mode 100644
index 0000000..cdfaaac
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-ldouble.c b/stdio-common/tst-printf-format-p-ldouble.c
new file mode 100644
index 0000000..266989d
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-llong.c b/stdio-common/tst-printf-format-p-llong.c
new file mode 100644
index 0000000..936f626
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-long.c b/stdio-common/tst-printf-format-p-long.c
new file mode 100644
index 0000000..c82c3ca
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-s.c b/stdio-common/tst-printf-format-p-s.c
new file mode 100644
index 0000000..4b0201a
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-short.c b/stdio-common/tst-printf-format-p-short.c
new file mode 100644
index 0000000..2bf17f1
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-uchar.c b/stdio-common/tst-printf-format-p-uchar.c
new file mode 100644
index 0000000..02a70c3
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-uint.c b/stdio-common/tst-printf-format-p-uint.c
new file mode 100644
index 0000000..e61455e
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-ullong.c b/stdio-common/tst-printf-format-p-ullong.c
new file mode 100644
index 0000000..16b2541
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-ulong.c b/stdio-common/tst-printf-format-p-ulong.c
new file mode 100644
index 0000000..0b3a7fd
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p-ushort.c b/stdio-common/tst-printf-format-p-ushort.c
new file mode 100644
index 0000000..fa62f50
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-p.h b/stdio-common/tst-printf-format-p.h
new file mode 100644
index 0000000..a9ffbb0
--- /dev/null
+++ b/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; \
+})
diff --git a/stdio-common/tst-printf-format-s-c.c b/stdio-common/tst-printf-format-s-c.c
new file mode 100644
index 0000000..87dad07
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-s-char.c b/stdio-common/tst-printf-format-s-char.c
new file mode 100644
index 0000000..f67ac94
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-s-double.c b/stdio-common/tst-printf-format-s-double.c
new file mode 100644
index 0000000..16186b5
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-s-int.c b/stdio-common/tst-printf-format-s-int.c
new file mode 100644
index 0000000..2ed7b2d
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-s-ldouble.c b/stdio-common/tst-printf-format-s-ldouble.c
new file mode 100644
index 0000000..0362cc5
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-s-llong.c b/stdio-common/tst-printf-format-s-llong.c
new file mode 100644
index 0000000..b49f849
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-s-long.c b/stdio-common/tst-printf-format-s-long.c
new file mode 100644
index 0000000..49224d7
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-s-s.c b/stdio-common/tst-printf-format-s-s.c
new file mode 100644
index 0000000..3a400f8
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-s-short.c b/stdio-common/tst-printf-format-s-short.c
new file mode 100644
index 0000000..c98a808
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-s-uchar.c b/stdio-common/tst-printf-format-s-uchar.c
new file mode 100644
index 0000000..befc368
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-s-uint.c b/stdio-common/tst-printf-format-s-uint.c
new file mode 100644
index 0000000..f3a4c49
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-s-ullong.c b/stdio-common/tst-printf-format-s-ullong.c
new file mode 100644
index 0000000..4ce5590
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-s-ulong.c b/stdio-common/tst-printf-format-s-ulong.c
new file mode 100644
index 0000000..81f9eea
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-s-ushort.c b/stdio-common/tst-printf-format-s-ushort.c
new file mode 100644
index 0000000..4b1cca6
--- /dev/null
+++ b/stdio-common/tst-printf-format-s-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'sprintf' 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-s.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-s.h b/stdio-common/tst-printf-format-s.h
new file mode 100644
index 0000000..7d1e72c
--- /dev/null
+++ b/stdio-common/tst-printf-format-s.h
@@ -0,0 +1,60 @@
+/* Test feature wrapper for formatted 'sprintf' 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>
+#include <stdlib.h>
+
+#include <support/next_to_fault.h>
+
+#define SPRINTF_BUFFER_SIZE 65536
+
+static struct support_next_to_fault ntf;
+
+#define PREPARE printf_under_test_init
+static void
+printf_under_test_init (int argc, char **argv)
+{
+ ntf = support_next_to_fault_allocate (SPRINTF_BUFFER_SIZE);
+}
+
+static void __attribute__ ((destructor))
+printf_under_test_fini (void)
+{
+ support_next_to_fault_free (&ntf);
+}
+
+#define printf_under_test(...) \
+({ \
+ __label__ out; \
+ char *str = ntf.buffer; \
+ int result; \
+ \
+ result = sprintf (str, __VA_ARGS__); \
+ if (result < 0) \
+ { \
+ perror ("sprintf"); \
+ goto out; \
+ } \
+ if (fwrite (str, sizeof (*str), result, stdout) != result) \
+ { \
+ perror ("fwrite"); \
+ result = -1; \
+ } \
+out: \
+ result; \
+})
diff --git a/stdio-common/tst-printf-format-s.sh b/stdio-common/tst-printf-format-s.sh
new file mode 100644
index 0000000..fa0690f
--- /dev/null
+++ b/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
diff --git a/stdio-common/tst-printf-format-short.sh b/stdio-common/tst-printf-format-short.sh
new file mode 100644
index 0000000..a610a15
--- /dev/null
+++ b/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
diff --git a/stdio-common/tst-printf-format-skeleton-c.c b/stdio-common/tst-printf-format-skeleton-c.c
new file mode 100644
index 0000000..3f9bbc9
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-char.c b/stdio-common/tst-printf-format-skeleton-char.c
new file mode 100644
index 0000000..8c7b44b
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-double.c b/stdio-common/tst-printf-format-skeleton-double.c
new file mode 100644
index 0000000..03ac594
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-int.c b/stdio-common/tst-printf-format-skeleton-int.c
new file mode 100644
index 0000000..5d2076c
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-ldouble.c b/stdio-common/tst-printf-format-skeleton-ldouble.c
new file mode 100644
index 0000000..ed47e77
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-llong.c b/stdio-common/tst-printf-format-skeleton-llong.c
new file mode 100644
index 0000000..9a4b7a3
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-long.c b/stdio-common/tst-printf-format-skeleton-long.c
new file mode 100644
index 0000000..bf011b7
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-s.c b/stdio-common/tst-printf-format-skeleton-s.c
new file mode 100644
index 0000000..59aab9f
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-short.c b/stdio-common/tst-printf-format-skeleton-short.c
new file mode 100644
index 0000000..1b7c8c0
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-uchar.c b/stdio-common/tst-printf-format-skeleton-uchar.c
new file mode 100644
index 0000000..389188d
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-uint.c b/stdio-common/tst-printf-format-skeleton-uint.c
new file mode 100644
index 0000000..6a41591
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-ullong.c b/stdio-common/tst-printf-format-skeleton-ullong.c
new file mode 100644
index 0000000..a2ad789
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-ulong.c b/stdio-common/tst-printf-format-skeleton-ulong.c
new file mode 100644
index 0000000..05cd4e0
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton-ushort.c b/stdio-common/tst-printf-format-skeleton-ushort.c
new file mode 100644
index 0000000..5cc2e02
--- /dev/null
+++ b/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"
diff --git a/stdio-common/tst-printf-format-skeleton.c b/stdio-common/tst-printf-format-skeleton.c
new file mode 100644
index 0000000..439fd78
--- /dev/null
+++ b/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>
+
+/* 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"
+
+/* 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} };
+
+/* 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}
+
+/* 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) };
+
+/* 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];
+ }
+ if (point)
+ fmt[idx++] = '.';
+ 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];
+ }
+ for (i = 0; length[i] != '\0'; i++)
+ fmt[idx++] = length[i];
+ fmt[idx++] = c;
+ fmt[idx] = ':';
+ fmt[idx + 1] = '\0';
+ if (fputs (fmt, stdout) == EOF)
+ {
+ perror ("fputs");
+ return -1;
+ }
+ fmt[idx++] = '\0';
+ 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;
+ }
+ }
+ }
+ 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;
+ }
+ if (result < 0)
+ return -1;
+ if (fputs (":\n", stdout) == EOF)
+ {
+ perror ("fputs");
+ return -1;
+ }
+ return 0;
+}
+
+/* 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;
+}
+
+/* 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;
+ }
+
+ mtrace ();
+
+ if (PREC && printf ("prec:%i\n", PREC) < 0)
+ {
+ perror ("printf");
+ return EXIT_FAILURE;
+ }
+
+ 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;
+ }
+
+ if (do_printf_flags (fmt, 1, length, c, vals[v]) < 0)
+ return EXIT_FAILURE;
+ 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;
+}
+
+/* Interpose 'dladdr' with a stub to speed up malloc tracing. */
+
+int
+dladdr (const void *addr, Dl_info *info)
+{
+ return 0;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-printf-format-sn-c.c b/stdio-common/tst-printf-format-sn-c.c
new file mode 100644
index 0000000..59f51d6
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-sn-char.c b/stdio-common/tst-printf-format-sn-char.c
new file mode 100644
index 0000000..8b682dd
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-sn-double.c b/stdio-common/tst-printf-format-sn-double.c
new file mode 100644
index 0000000..4719a58
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-sn-int.c b/stdio-common/tst-printf-format-sn-int.c
new file mode 100644
index 0000000..94c42f2
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-sn-ldouble.c b/stdio-common/tst-printf-format-sn-ldouble.c
new file mode 100644
index 0000000..921f3ff
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-sn-llong.c b/stdio-common/tst-printf-format-sn-llong.c
new file mode 100644
index 0000000..0135527
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-sn-long.c b/stdio-common/tst-printf-format-sn-long.c
new file mode 100644
index 0000000..58c8912
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-sn-s.c b/stdio-common/tst-printf-format-sn-s.c
new file mode 100644
index 0000000..aa3f170
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-sn-short.c b/stdio-common/tst-printf-format-sn-short.c
new file mode 100644
index 0000000..f7baa12
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-sn-uchar.c b/stdio-common/tst-printf-format-sn-uchar.c
new file mode 100644
index 0000000..6ae5f12
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-sn-uint.c b/stdio-common/tst-printf-format-sn-uint.c
new file mode 100644
index 0000000..f0a0c30
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-sn-ullong.c b/stdio-common/tst-printf-format-sn-ullong.c
new file mode 100644
index 0000000..0dc0a50
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-sn-ulong.c b/stdio-common/tst-printf-format-sn-ulong.c
new file mode 100644
index 0000000..23ff5a2
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-sn-ushort.c b/stdio-common/tst-printf-format-sn-ushort.c
new file mode 100644
index 0000000..1c5cffb
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'snprintf' 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-sn.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-sn.h b/stdio-common/tst-printf-format-sn.h
new file mode 100644
index 0000000..ec2645b
--- /dev/null
+++ b/stdio-common/tst-printf-format-sn.h
@@ -0,0 +1,60 @@
+/* Test feature wrapper for formatted 'snprintf' 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>
+#include <stdlib.h>
+
+#include <support/next_to_fault.h>
+
+#define SPRINTF_BUFFER_SIZE 65536
+
+static struct support_next_to_fault ntf;
+
+#define PREPARE printf_under_test_init
+static void
+printf_under_test_init (int argc, char **argv)
+{
+ ntf = support_next_to_fault_allocate (SPRINTF_BUFFER_SIZE);
+}
+
+static void __attribute__ ((destructor))
+printf_under_test_fini (void)
+{
+ support_next_to_fault_free (&ntf);
+}
+
+#define printf_under_test(...) \
+({ \
+ __label__ out; \
+ char *str = ntf.buffer; \
+ int result; \
+ \
+ result = snprintf (str, ntf.length, __VA_ARGS__); \
+ if (result < 0) \
+ { \
+ perror ("snprintf"); \
+ goto out; \
+ } \
+ if (fwrite (str, sizeof (*str), result, stdout) != result) \
+ { \
+ perror ("fwrite"); \
+ result = -1; \
+ } \
+out: \
+ result; \
+})
diff --git a/stdio-common/tst-printf-format-uchar.sh b/stdio-common/tst-printf-format-uchar.sh
new file mode 100644
index 0000000..8385d47
--- /dev/null
+++ b/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
diff --git a/stdio-common/tst-printf-format-uint.sh b/stdio-common/tst-printf-format-uint.sh
new file mode 100644
index 0000000..6806c99
--- /dev/null
+++ b/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
diff --git a/stdio-common/tst-printf-format-ullong.sh b/stdio-common/tst-printf-format-ullong.sh
new file mode 100644
index 0000000..c4fa69c
--- /dev/null
+++ b/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
diff --git a/stdio-common/tst-printf-format-ulong.sh b/stdio-common/tst-printf-format-ulong.sh
new file mode 100644
index 0000000..fce881a
--- /dev/null
+++ b/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
diff --git a/stdio-common/tst-printf-format-ushort.sh b/stdio-common/tst-printf-format-ushort.sh
new file mode 100644
index 0000000..2f411b7
--- /dev/null
+++ b/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
diff --git a/stdio-common/tst-printf-format-v-c.c b/stdio-common/tst-printf-format-v-c.c
new file mode 100644
index 0000000..94aa304
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-v-char.c b/stdio-common/tst-printf-format-v-char.c
new file mode 100644
index 0000000..c813d81
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-v-double.c b/stdio-common/tst-printf-format-v-double.c
new file mode 100644
index 0000000..90cc170
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-v-int.c b/stdio-common/tst-printf-format-v-int.c
new file mode 100644
index 0000000..6529425
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-v-ldouble.c b/stdio-common/tst-printf-format-v-ldouble.c
new file mode 100644
index 0000000..813f4a5
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-v-llong.c b/stdio-common/tst-printf-format-v-llong.c
new file mode 100644
index 0000000..270ad08
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-v-long.c b/stdio-common/tst-printf-format-v-long.c
new file mode 100644
index 0000000..2f5f653
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-v-s.c b/stdio-common/tst-printf-format-v-s.c
new file mode 100644
index 0000000..ebc253b
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-v-short.c b/stdio-common/tst-printf-format-v-short.c
new file mode 100644
index 0000000..92a59d9
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-v-uchar.c b/stdio-common/tst-printf-format-v-uchar.c
new file mode 100644
index 0000000..045ffd2
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-v-uint.c b/stdio-common/tst-printf-format-v-uint.c
new file mode 100644
index 0000000..17b1ce3
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-v-ullong.c b/stdio-common/tst-printf-format-v-ullong.c
new file mode 100644
index 0000000..590b04f
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-v-ulong.c b/stdio-common/tst-printf-format-v-ulong.c
new file mode 100644
index 0000000..6747677
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-v-ushort.c b/stdio-common/tst-printf-format-v-ushort.c
new file mode 100644
index 0000000..1e78271
--- /dev/null
+++ b/stdio-common/tst-printf-format-v-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vprintf' 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-v.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-v.h b/stdio-common/tst-printf-format-v.h
new file mode 100644
index 0000000..711b290
--- /dev/null
+++ b/stdio-common/tst-printf-format-v.h
@@ -0,0 +1,34 @@
+/* Test feature wrapper for formatted 'vprintf' 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 <stdarg.h>
+#include <stdio.h>
+
+static int
+printf_under_test (const char *restrict fmt, ...)
+{
+ va_list ap;
+ int result;
+
+ va_start (ap, fmt);
+ result = vprintf (fmt, ap);
+ va_end (ap);
+ if (result < 0)
+ perror ("vprintf");
+ return result;
+}
diff --git a/stdio-common/tst-printf-format-vas-c.c b/stdio-common/tst-printf-format-vas-c.c
new file mode 100644
index 0000000..f8cf814
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-vas-char.c b/stdio-common/tst-printf-format-vas-char.c
new file mode 100644
index 0000000..39c6e73
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-vas-double.c b/stdio-common/tst-printf-format-vas-double.c
new file mode 100644
index 0000000..25a21bb
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-double.c
@@ -0,0 +1,22 @@
+/* Test for formatted 'vasprintf' 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/>. */
+
+#define TIMEOUT (DEFAULT_TIMEOUT * 32)
+
+#include "tst-printf-format-vas.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-vas-int.c b/stdio-common/tst-printf-format-vas-int.c
new file mode 100644
index 0000000..9cd70c8
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-vas-ldouble.c b/stdio-common/tst-printf-format-vas-ldouble.c
new file mode 100644
index 0000000..60c3933
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-ldouble.c
@@ -0,0 +1,22 @@
+/* Test for formatted 'vasprintf' 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/>. */
+
+#define TIMEOUT (DEFAULT_TIMEOUT * 128)
+
+#include "tst-printf-format-vas.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-vas-llong.c b/stdio-common/tst-printf-format-vas-llong.c
new file mode 100644
index 0000000..5d5322b
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-vas-long.c b/stdio-common/tst-printf-format-vas-long.c
new file mode 100644
index 0000000..d965105
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-vas-s.c b/stdio-common/tst-printf-format-vas-s.c
new file mode 100644
index 0000000..6d74ab8
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-vas-short.c b/stdio-common/tst-printf-format-vas-short.c
new file mode 100644
index 0000000..a6d76a9
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-vas-uchar.c b/stdio-common/tst-printf-format-vas-uchar.c
new file mode 100644
index 0000000..c3dee11
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-vas-uint.c b/stdio-common/tst-printf-format-vas-uint.c
new file mode 100644
index 0000000..e56e893
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-vas-ullong.c b/stdio-common/tst-printf-format-vas-ullong.c
new file mode 100644
index 0000000..05691bc
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-vas-ulong.c b/stdio-common/tst-printf-format-vas-ulong.c
new file mode 100644
index 0000000..767d9cb
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-vas-ushort.c b/stdio-common/tst-printf-format-vas-ushort.c
new file mode 100644
index 0000000..284d79f
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vasprintf' 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-vas.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-vas.h b/stdio-common/tst-printf-format-vas.h
new file mode 100644
index 0000000..3e38e72
--- /dev/null
+++ b/stdio-common/tst-printf-format-vas.h
@@ -0,0 +1,50 @@
+/* Test feature wrapper for formatted 'vasprintf' 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int
+printf_under_test (const char *restrict fmt, ...)
+{
+ va_list ap;
+ int result;
+ char *str;
+
+ va_start (ap, fmt);
+ result = vasprintf (&str, fmt, ap);
+ va_end (ap);
+ if (result < 0)
+ {
+ perror ("vasprintf");
+ goto out;
+ }
+ if (fwrite (str, sizeof (*str), result, stdout) != result)
+ {
+ perror ("fwrite");
+ result = -1;
+ }
+ free (str);
+out:
+ return result;
+}
+
+#ifndef TIMEOUT
+# define TIMEOUT (DEFAULT_TIMEOUT * 12)
+#endif
diff --git a/stdio-common/tst-printf-format-vd-c.c b/stdio-common/tst-printf-format-vd-c.c
new file mode 100644
index 0000000..209b178
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-vd-char.c b/stdio-common/tst-printf-format-vd-char.c
new file mode 100644
index 0000000..8286b6d
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-vd-double.c b/stdio-common/tst-printf-format-vd-double.c
new file mode 100644
index 0000000..e89a2ca
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-vd-int.c b/stdio-common/tst-printf-format-vd-int.c
new file mode 100644
index 0000000..598a888
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-vd-ldouble.c b/stdio-common/tst-printf-format-vd-ldouble.c
new file mode 100644
index 0000000..d3ada6f
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-vd-llong.c b/stdio-common/tst-printf-format-vd-llong.c
new file mode 100644
index 0000000..ea6ea7b
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-vd-long.c b/stdio-common/tst-printf-format-vd-long.c
new file mode 100644
index 0000000..4ee1cda
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-vd-s.c b/stdio-common/tst-printf-format-vd-s.c
new file mode 100644
index 0000000..df7cf9a
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-vd-short.c b/stdio-common/tst-printf-format-vd-short.c
new file mode 100644
index 0000000..87128c8
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-vd-uchar.c b/stdio-common/tst-printf-format-vd-uchar.c
new file mode 100644
index 0000000..90dea71
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-vd-uint.c b/stdio-common/tst-printf-format-vd-uint.c
new file mode 100644
index 0000000..feb95dc
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-vd-ullong.c b/stdio-common/tst-printf-format-vd-ullong.c
new file mode 100644
index 0000000..8f62fb0
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-vd-ulong.c b/stdio-common/tst-printf-format-vd-ulong.c
new file mode 100644
index 0000000..59b2015
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-vd-ushort.c b/stdio-common/tst-printf-format-vd-ushort.c
new file mode 100644
index 0000000..5d09650
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vdprintf' 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-vd.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-vd.h b/stdio-common/tst-printf-format-vd.h
new file mode 100644
index 0000000..d721eda
--- /dev/null
+++ b/stdio-common/tst-printf-format-vd.h
@@ -0,0 +1,62 @@
+/* Test feature wrapper for formatted 'vdprintf' 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 <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* We need to go through the POSIX-mandated dance to switch between
+ handles on an open file description. */
+
+static int
+printf_under_test (const char *restrict fmt, ...)
+{
+ va_list ap;
+ int result;
+
+ result = fflush (stdout);
+ if (result == EOF)
+ {
+ perror ("fflush");
+ goto out;
+ }
+ result = lseek (STDOUT_FILENO, 0, SEEK_END);
+ if (result < 0 && errno == ESPIPE)
+ result = 0;
+ if (result < 0)
+ {
+ perror ("lseek");
+ goto out;
+ }
+ va_start (ap, fmt);
+ result = vdprintf (STDOUT_FILENO, fmt, ap);
+ va_end (ap);
+ if (result < 0)
+ {
+ perror ("vdprintf");
+ goto out;
+ }
+ result = fseek (stdout, 0, SEEK_END);
+ if (result < 0 && errno == ESPIPE)
+ result = 0;
+ if (result < 0)
+ perror ("fseek");
+out:
+ return result;
+}
diff --git a/stdio-common/tst-printf-format-vf-c.c b/stdio-common/tst-printf-format-vf-c.c
new file mode 100644
index 0000000..b31b551
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-vf-char.c b/stdio-common/tst-printf-format-vf-char.c
new file mode 100644
index 0000000..daa2886
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-vf-double.c b/stdio-common/tst-printf-format-vf-double.c
new file mode 100644
index 0000000..63ec8c0
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-vf-int.c b/stdio-common/tst-printf-format-vf-int.c
new file mode 100644
index 0000000..e687099
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-vf-ldouble.c b/stdio-common/tst-printf-format-vf-ldouble.c
new file mode 100644
index 0000000..801e359
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-vf-llong.c b/stdio-common/tst-printf-format-vf-llong.c
new file mode 100644
index 0000000..a1b9ae3
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-vf-long.c b/stdio-common/tst-printf-format-vf-long.c
new file mode 100644
index 0000000..7afc127
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-vf-s.c b/stdio-common/tst-printf-format-vf-s.c
new file mode 100644
index 0000000..6faa6d0
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-vf-short.c b/stdio-common/tst-printf-format-vf-short.c
new file mode 100644
index 0000000..c3d17ca
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-vf-uchar.c b/stdio-common/tst-printf-format-vf-uchar.c
new file mode 100644
index 0000000..643438c
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-vf-uint.c b/stdio-common/tst-printf-format-vf-uint.c
new file mode 100644
index 0000000..844192c
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-vf-ullong.c b/stdio-common/tst-printf-format-vf-ullong.c
new file mode 100644
index 0000000..ab58abd
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-vf-ulong.c b/stdio-common/tst-printf-format-vf-ulong.c
new file mode 100644
index 0000000..e76251f
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-vf-ushort.c b/stdio-common/tst-printf-format-vf-ushort.c
new file mode 100644
index 0000000..bf78a91
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vfprintf' 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-vf.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-vf.h b/stdio-common/tst-printf-format-vf.h
new file mode 100644
index 0000000..f824364
--- /dev/null
+++ b/stdio-common/tst-printf-format-vf.h
@@ -0,0 +1,34 @@
+/* Test feature wrapper for formatted 'vfprintf' 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 <stdarg.h>
+#include <stdio.h>
+
+static int
+printf_under_test (const char *restrict fmt, ...)
+{
+ va_list ap;
+ int result;
+
+ va_start (ap, fmt);
+ result = vfprintf (stdout, fmt, ap);
+ va_end (ap);
+ if (result < 0)
+ perror ("vfprintf");
+ return result;
+}
diff --git a/stdio-common/tst-printf-format-vs-c.c b/stdio-common/tst-printf-format-vs-c.c
new file mode 100644
index 0000000..72bcb5f
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-vs-char.c b/stdio-common/tst-printf-format-vs-char.c
new file mode 100644
index 0000000..30135cf
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-vs-double.c b/stdio-common/tst-printf-format-vs-double.c
new file mode 100644
index 0000000..56290d3
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-vs-int.c b/stdio-common/tst-printf-format-vs-int.c
new file mode 100644
index 0000000..f954e1f
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-vs-ldouble.c b/stdio-common/tst-printf-format-vs-ldouble.c
new file mode 100644
index 0000000..3088e42
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-vs-llong.c b/stdio-common/tst-printf-format-vs-llong.c
new file mode 100644
index 0000000..348ec2c
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-vs-long.c b/stdio-common/tst-printf-format-vs-long.c
new file mode 100644
index 0000000..874e3ba
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-vs-s.c b/stdio-common/tst-printf-format-vs-s.c
new file mode 100644
index 0000000..051f1b7
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-vs-short.c b/stdio-common/tst-printf-format-vs-short.c
new file mode 100644
index 0000000..36595a8
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-vs-uchar.c b/stdio-common/tst-printf-format-vs-uchar.c
new file mode 100644
index 0000000..8e35614
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-vs-uint.c b/stdio-common/tst-printf-format-vs-uint.c
new file mode 100644
index 0000000..4a13d6c
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-vs-ullong.c b/stdio-common/tst-printf-format-vs-ullong.c
new file mode 100644
index 0000000..313dfaf
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-vs-ulong.c b/stdio-common/tst-printf-format-vs-ulong.c
new file mode 100644
index 0000000..5ab7e2e
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-vs-ushort.c b/stdio-common/tst-printf-format-vs-ushort.c
new file mode 100644
index 0000000..a4af138
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsprintf' 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-vs.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-vs.h b/stdio-common/tst-printf-format-vs.h
new file mode 100644
index 0000000..e00e1b0
--- /dev/null
+++ b/stdio-common/tst-printf-format-vs.h
@@ -0,0 +1,64 @@
+/* Test feature wrapper for formatted 'vsprintf' 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <support/next_to_fault.h>
+
+#define SPRINTF_BUFFER_SIZE 65536
+
+static struct support_next_to_fault ntf;
+
+#define PREPARE printf_under_test_init
+static void
+printf_under_test_init (int argc, char **argv)
+{
+ ntf = support_next_to_fault_allocate (SPRINTF_BUFFER_SIZE);
+}
+
+static void __attribute__ ((destructor))
+printf_under_test_fini (void)
+{
+ support_next_to_fault_free (&ntf);
+}
+
+static int
+printf_under_test (const char *restrict fmt, ...)
+{
+ char *str = ntf.buffer;
+ va_list ap;
+ int result;
+
+ va_start (ap, fmt);
+ result = vsprintf (str, fmt, ap);
+ va_end (ap);
+ if (result < 0)
+ {
+ perror ("vsprintf");
+ goto out;
+ }
+ if (fwrite (str, sizeof (*str), result, stdout) != result)
+ {
+ perror ("fwrite");
+ result = -1;
+ }
+out:
+ return result;
+}
diff --git a/stdio-common/tst-printf-format-vsn-c.c b/stdio-common/tst-printf-format-vsn-c.c
new file mode 100644
index 0000000..47c8a0f
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-c.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-c.c"
diff --git a/stdio-common/tst-printf-format-vsn-char.c b/stdio-common/tst-printf-format-vsn-char.c
new file mode 100644
index 0000000..48d4393
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-char.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-char.c"
diff --git a/stdio-common/tst-printf-format-vsn-double.c b/stdio-common/tst-printf-format-vsn-double.c
new file mode 100644
index 0000000..06c1003
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-double.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-double.c"
diff --git a/stdio-common/tst-printf-format-vsn-int.c b/stdio-common/tst-printf-format-vsn-int.c
new file mode 100644
index 0000000..2aae926
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-int.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-int.c"
diff --git a/stdio-common/tst-printf-format-vsn-ldouble.c b/stdio-common/tst-printf-format-vsn-ldouble.c
new file mode 100644
index 0000000..0b5aafb
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-ldouble.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-ldouble.c"
diff --git a/stdio-common/tst-printf-format-vsn-llong.c b/stdio-common/tst-printf-format-vsn-llong.c
new file mode 100644
index 0000000..8e79b83
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-llong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-llong.c"
diff --git a/stdio-common/tst-printf-format-vsn-long.c b/stdio-common/tst-printf-format-vsn-long.c
new file mode 100644
index 0000000..e94f7de
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-long.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-long.c"
diff --git a/stdio-common/tst-printf-format-vsn-s.c b/stdio-common/tst-printf-format-vsn-s.c
new file mode 100644
index 0000000..efd8a4c
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-s.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-s.c"
diff --git a/stdio-common/tst-printf-format-vsn-short.c b/stdio-common/tst-printf-format-vsn-short.c
new file mode 100644
index 0000000..3d375b5
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-short.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-short.c"
diff --git a/stdio-common/tst-printf-format-vsn-uchar.c b/stdio-common/tst-printf-format-vsn-uchar.c
new file mode 100644
index 0000000..6d0f396
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-uchar.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-uchar.c"
diff --git a/stdio-common/tst-printf-format-vsn-uint.c b/stdio-common/tst-printf-format-vsn-uint.c
new file mode 100644
index 0000000..b637f7b
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-uint.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-uint.c"
diff --git a/stdio-common/tst-printf-format-vsn-ullong.c b/stdio-common/tst-printf-format-vsn-ullong.c
new file mode 100644
index 0000000..d244271
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-ullong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-ullong.c"
diff --git a/stdio-common/tst-printf-format-vsn-ulong.c b/stdio-common/tst-printf-format-vsn-ulong.c
new file mode 100644
index 0000000..67417d1
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-ulong.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-ulong.c"
diff --git a/stdio-common/tst-printf-format-vsn-ushort.c b/stdio-common/tst-printf-format-vsn-ushort.c
new file mode 100644
index 0000000..396ea43
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn-ushort.c
@@ -0,0 +1,20 @@
+/* Test for formatted 'vsnprintf' 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-vsn.h"
+#include "tst-printf-format-skeleton-ushort.c"
diff --git a/stdio-common/tst-printf-format-vsn.h b/stdio-common/tst-printf-format-vsn.h
new file mode 100644
index 0000000..4f25f1a
--- /dev/null
+++ b/stdio-common/tst-printf-format-vsn.h
@@ -0,0 +1,64 @@
+/* Test feature wrapper for formatted 'vsnprintf' 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <support/next_to_fault.h>
+
+#define SPRINTF_BUFFER_SIZE 65536
+
+static struct support_next_to_fault ntf;
+
+#define PREPARE printf_under_test_init
+static void
+printf_under_test_init (int argc, char **argv)
+{
+ ntf = support_next_to_fault_allocate (SPRINTF_BUFFER_SIZE);
+}
+
+static void __attribute__ ((destructor))
+printf_under_test_fini (void)
+{
+ support_next_to_fault_free (&ntf);
+}
+
+static int
+printf_under_test (const char *restrict fmt, ...)
+{
+ char *str = ntf.buffer;
+ va_list ap;
+ int result;
+
+ va_start (ap, fmt);
+ result = vsnprintf (str, ntf.length, fmt, ap);
+ va_end (ap);
+ if (result < 0)
+ {
+ perror ("vsnprintf");
+ goto out;
+ }
+ if (fwrite (str, sizeof (*str), result, stdout) != result)
+ {
+ perror ("fwrite");
+ result = -1;
+ }
+out:
+ return result;
+}
diff --git a/stdio-common/tst-printf-format.awk b/stdio-common/tst-printf-format.awk
new file mode 100644
index 0000000..8b4bc7b
--- /dev/null
+++ b/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
+}
+
+/^%/ {
+ # 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
+ }
+ # 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
+ }
+ # 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 "")
+ # 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)
+ }
+ # 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)
+ }
+ # 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
+}
+
+{
+ printf "unrecognized input: \"%s\"\n", $0 > "/dev/stderr"
+ status = 1
+}
+
+END {
+ exit status
+}
diff --git a/stdio-common/tst-printf-format.sh b/stdio-common/tst-printf-format.sh
new file mode 100644
index 0000000..466c4a5
--- /dev/null
+++ b/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 "$@"
diff --git a/stdio-common/tst-renameat2.c b/stdio-common/tst-renameat2.c
index b65afed..7f4345f 100644
--- a/stdio-common/tst-renameat2.c
+++ b/stdio-common/tst-renameat2.c
@@ -82,7 +82,7 @@ static void
check_size (const char *path, off64_t expected_size)
{
struct stat64 st;
- xstat (path, &st);
+ xstat64 (path, &st);
if (st.st_size != expected_size)
FAIL_EXIT1 ("file \"%s\": expected size %lld, actual size %lld",
path, (unsigned long long int) expected_size,
diff --git a/stdio-common/tst-scanf-nan.c b/stdio-common/tst-scanf-nan.c
new file mode 100644
index 0000000..7450b37
--- /dev/null
+++ b/stdio-common/tst-scanf-nan.c
@@ -0,0 +1,83 @@
+/* Test scanf formats for nan, nan(), nan(n-char-sequence) types.
+ Copyright The GNU Toolchain Authors.
+ 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 <stdint.h>
+#include <stdio.h>
+
+#include <support/check.h>
+
+#define CHECK_SCANF_RET(OK, STR, FMT, ...) \
+ do \
+ { \
+ int ret = sscanf (STR, FMT, __VA_ARGS__); \
+ TEST_VERIFY (ret == (OK)); \
+ } \
+ while (0)
+
+/* Valid nan types:
+ 1. nan
+ 2. nan()
+ 3. nan([a-zA-Z0-9_]+)
+ Any other nan format is invalid and should produce a conversion error.
+ The return value denotes the number of valid conversions. On conversion
+ error the rest of the input is discarded. */
+static int
+do_test (void)
+{
+ int a;
+ float b;
+ double c;
+ long double d;
+
+ /* All valid inputs. */
+ CHECK_SCANF_RET (1, "nan", "%lf", &c);
+ CHECK_SCANF_RET (1, "nan()", "%lf", &c);
+ CHECK_SCANF_RET (1, "nan(12345)", "%lf", &c);
+ CHECK_SCANF_RET (2, "nan12", "%lf%d", &c, &a);
+ CHECK_SCANF_RET (2, "nan nan()", "%f%Lf", &b, &d);
+ CHECK_SCANF_RET (2, "nan nan(12345foo)", "%lf%Lf", &c, &d);
+ CHECK_SCANF_RET (3, "nan nan() 12.234", "%lf%Lf%f", &c, &d, &b);
+ CHECK_SCANF_RET (4, "nannan()nan(foo)1234", "%lf%f%Lf%d", &c, &b, &d, &a);
+
+ /* Partially valid inputs. */
+ CHECK_SCANF_RET (1, "nan( )", "%3lf", &c);
+ CHECK_SCANF_RET (1, "nan nan(", "%lf%f", &c, &b);
+
+ /* Invalid inputs. */
+
+ /* Dangling parentheses. */
+ CHECK_SCANF_RET (0, "nan(", "%lf", &c);
+ CHECK_SCANF_RET (0, "nan(123", "%lf", &c);
+ CHECK_SCANF_RET (0, "nan(12345", "%lf%d", &c, &a);
+
+ /* Field width is not sufficient for valid conversion. */
+ CHECK_SCANF_RET (0, "nan()", "%4Lf", &d);
+ CHECK_SCANF_RET (0, "nan(1", "%5lf", &c);
+
+ /* Space is not a valid character. */
+ CHECK_SCANF_RET (0, "nan( )", "%lf", &c);
+ CHECK_SCANF_RET (0, "nan( )12.34", "%Lf%f", &d, &b);
+ CHECK_SCANF_RET (0, "nan(12 foo)", "%f", &b);
+
+ /* Period '.' is not a valid character. */
+ CHECK_SCANF_RET (0, "nan(12.34) nan(FooBar)", "%lf%Lf", &c, &d);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-ungetc-leak.c b/stdio-common/tst-ungetc-leak.c
new file mode 100644
index 0000000..6c5152b
--- /dev/null
+++ b/stdio-common/tst-ungetc-leak.c
@@ -0,0 +1,32 @@
+/* Test for memory leak with ungetc when stream is unused.
+ Copyright The GNU Toolchain Authors.
+ 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>
+#include <mcheck.h>
+#include <support/check.h>
+#include <support/support.h>
+
+static int
+do_test (void)
+{
+ mtrace ();
+ TEST_COMPARE (ungetc('y', stdin), 'y');
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
index 1344b2b..388b202 100644
--- a/stdio-common/tst-ungetc.c
+++ b/stdio-common/tst-ungetc.c
@@ -1,70 +1,74 @@
-/* Test for ungetc bugs. */
+/* Test for ungetc bugs.
+ Copyright (C) 1996-2024 Free Software Foundation, Inc.
+ Copyright The GNU Toolchain Authors.
+ 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>
#include <stdlib.h>
-#include <unistd.h>
-
-#undef assert
-#define assert(x) \
- if (!(x)) \
- { \
- fputs ("test failed: " #x "\n", stderr); \
- retval = 1; \
- goto the_end; \
- }
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
-int
-main (int argc, char *argv[])
+static int
+do_test (void)
{
- char name[] = "/tmp/tst-ungetc.XXXXXX";
+ char *name = NULL;
FILE *fp = NULL;
- int retval = 0;
int c;
char buffer[64];
- int fd = mkstemp (name);
+ int fd = create_temp_file ("tst-ungetc.", &name);
if (fd == -1)
- {
- printf ("mkstemp failed: %m\n");
- return 1;
- }
- close (fd);
- fp = fopen (name, "w");
- assert (fp != NULL)
- fputs ("bla", fp);
- fclose (fp);
- fp = NULL;
+ FAIL_EXIT1 ("cannot create temporary file: %m");
+ xclose (fd);
- fp = fopen (name, "r");
- assert (fp != NULL);
- assert (ungetc ('z', fp) == 'z');
- assert (getc (fp) == 'z');
- assert (getc (fp) == 'b');
- assert (getc (fp) == 'l');
- assert (ungetc ('m', fp) == 'm');
- assert (getc (fp) == 'm');
- assert ((c = getc (fp)) == 'a');
- assert (getc (fp) == EOF);
- assert (ungetc (c, fp) == c);
- assert (feof (fp) == 0);
- assert (getc (fp) == c);
- assert (getc (fp) == EOF);
- fclose (fp);
- fp = NULL;
+ fp = xfopen (name, "w");
+ fputs ("bla", fp);
+ xfclose (fp);
- fp = fopen (name, "r");
- assert (fp != NULL);
- assert (getc (fp) == 'b');
- assert (getc (fp) == 'l');
- assert (ungetc ('b', fp) == 'b');
- assert (fread (buffer, 1, 64, fp) == 2);
- assert (buffer[0] == 'b');
- assert (buffer[1] == 'a');
+ fp = xfopen (name, "r");
+ TEST_VERIFY_EXIT (ungetc ('z', fp) == 'z');
+ TEST_VERIFY_EXIT (getc (fp) == 'z');
+ TEST_VERIFY_EXIT (getc (fp) == 'b');
+ TEST_VERIFY_EXIT (getc (fp) == 'l');
+ TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
+ TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n');
+ TEST_VERIFY_EXIT (getc (fp) == 'n');
+ TEST_VERIFY_EXIT (getc (fp) == 'm');
+ TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
+ TEST_VERIFY_EXIT (getc (fp) == EOF);
+ TEST_VERIFY_EXIT (ungetc (c, fp) == c);
+ TEST_VERIFY_EXIT (feof (fp) == 0);
+ TEST_VERIFY_EXIT (getc (fp) == c);
+ TEST_VERIFY_EXIT (getc (fp) == EOF);
+ xfclose (fp);
-the_end:
- if (fp != NULL)
- fclose (fp);
- unlink (name);
+ fp = xfopen (name, "r");
+ TEST_VERIFY_EXIT (getc (fp) == 'b');
+ TEST_VERIFY_EXIT (getc (fp) == 'l');
+ TEST_VERIFY_EXIT (ungetc ('b', fp) == 'b');
+ TEST_VERIFY_EXIT (fread (buffer, 1, 64, fp) == 2);
+ TEST_VERIFY_EXIT (buffer[0] == 'b');
+ TEST_VERIFY_EXIT (buffer[1] == 'a');
+ xfclose (fp);
- return retval;
+ return 0;
}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c
index 1b82def..5f38f99 100644
--- a/stdio-common/vfscanf-internal.c
+++ b/stdio-common/vfscanf-internal.c
@@ -2028,7 +2028,51 @@ digits_extended_fail:
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
- /* It is "nan". */
+ /* It is at least "nan". Now we check for nan() and
+ nan(n-char-sequence). */
+ if (width != 0 && inchar () != EOF)
+ {
+ if (c == L_('('))
+ {
+ if (width > 0)
+ --width;
+ char_buffer_add (&charbuf, c);
+ /* A '(' was observed, check for a closing ')', there
+ may or may not be a n-char-sequence in between. We
+ have to check the longest prefix until there is a
+ conversion error or closing parenthesis. */
+ do
+ {
+ if (__glibc_unlikely (width == 0
+ || inchar () == EOF))
+ {
+ /* Conversion error because we ran out of
+ characters. */
+ conv_error ();
+ break;
+ }
+ if (!((c >= L_('0') && c <= L_('9'))
+ || (c >= L_('A') && c <= L_('Z'))
+ || (c >= L_('a') && c <= L_('z'))
+ || c == L_('_') || c == L_(')')))
+ {
+ /* Invalid character was observed. Only valid
+ characters are [a-zA-Z0-9_] and ')'. */
+ conv_error ();
+ break;
+ }
+ if (width > 0)
+ --width;
+ char_buffer_add (&charbuf, c);
+ }
+ while (c != L_(')'));
+ /* The loop only exits successfully when ')' is the
+ last character. */
+ }
+ else
+ /* It is only 'nan'. */
+ ungetc (c, s);
+ }
goto scan_float;
}
else if (TOLOWER (c) == L_('i'))