diff options
Diffstat (limited to 'stdio-common')
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')) |