summaryrefslogtreecommitdiff
path: root/tests/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'tests/gnu')
-rwxr-xr-xtests/gnu/Makefile.am1159
-rw-r--r--tests/gnu/Makefile.in3470
-rwxr-xr-xtests/gnu/getpagesize.c39
-rwxr-xr-xtests/gnu/gl_array_list.c680
-rwxr-xr-xtests/gnu/gl_array_list.h34
-rwxr-xr-xtests/gnu/gl_array_oset.c357
-rwxr-xr-xtests/gnu/gl_array_oset.h34
-rwxr-xr-xtests/gnu/ignore-value.h37
-rwxr-xr-xtests/gnu/init.sh345
-rwxr-xr-xtests/gnu/link.c203
-rwxr-xr-xtests/gnu/locale/fr/LC_MESSAGES/test-quotearg.mobin0 -> 90 bytes
-rwxr-xr-xtests/gnu/locale/fr/LC_MESSAGES/test-quotearg.po20
-rwxr-xr-xtests/gnu/macros.h64
-rwxr-xr-xtests/gnu/nan.h60
-rwxr-xr-xtests/gnu/obstack_printf.c92
-rwxr-xr-xtests/gnu/putenv.c132
-rwxr-xr-xtests/gnu/signature.h48
-rwxr-xr-xtests/gnu/strdup.c55
-rwxr-xr-xtests/gnu/symlink.c57
-rwxr-xr-xtests/gnu/test-alloca-opt.c62
-rwxr-xr-xtests/gnu/test-array_list.c329
-rwxr-xr-xtests/gnu/test-array_oset.c144
-rwxr-xr-xtests/gnu/test-avltree_oset.c136
-rwxr-xr-xtests/gnu/test-binary-io.c64
-rwxr-xr-xtests/gnu/test-binary-io.sh11
-rwxr-xr-xtests/gnu/test-bitrotate.c279
-rwxr-xr-xtests/gnu/test-btowc.c63
-rwxr-xr-xtests/gnu/test-btowc1.sh15
-rwxr-xr-xtests/gnu/test-btowc2.sh15
-rwxr-xr-xtests/gnu/test-c-ctype.c386
-rwxr-xr-xtests/gnu/test-c-strcase.sh21
-rwxr-xr-xtests/gnu/test-c-strcasecmp.c65
-rwxr-xr-xtests/gnu/test-c-strncasecmp.c79
-rwxr-xr-xtests/gnu/test-canonicalize-lgpl.c222
-rwxr-xr-xtests/gnu/test-cloexec.c141
-rwxr-xr-xtests/gnu/test-closein.c53
-rwxr-xr-xtests/gnu/test-closein.sh38
-rwxr-xr-xtests/gnu/test-dirname.c191
-rwxr-xr-xtests/gnu/test-dup-safer.c175
-rwxr-xr-xtests/gnu/test-dup2.c193
-rwxr-xr-xtests/gnu/test-environ.c44
-rwxr-xr-xtests/gnu/test-errno.c117
-rwxr-xr-xtests/gnu/test-fcntl-h.c38
-rwxr-xr-xtests/gnu/test-fcntl.c346
-rwxr-xr-xtests/gnu/test-fflush.c145
-rwxr-xr-xtests/gnu/test-fflush2.c108
-rwxr-xr-xtests/gnu/test-fflush2.sh9
-rwxr-xr-xtests/gnu/test-filenamecat.c66
-rwxr-xr-xtests/gnu/test-fopen-safer.c31
-rwxr-xr-xtests/gnu/test-fopen.c34
-rwxr-xr-xtests/gnu/test-fopen.h73
-rwxr-xr-xtests/gnu/test-fpending.c41
-rwxr-xr-xtests/gnu/test-fpending.sh12
-rwxr-xr-xtests/gnu/test-fprintf-posix.h151
-rwxr-xr-xtests/gnu/test-fpurge.c132
-rwxr-xr-xtests/gnu/test-freadahead.c73
-rwxr-xr-xtests/gnu/test-freadahead.sh5
-rwxr-xr-xtests/gnu/test-freading.c130
-rwxr-xr-xtests/gnu/test-freadptr.c94
-rwxr-xr-xtests/gnu/test-freadptr.sh5
-rwxr-xr-xtests/gnu/test-freadptr2.c62
-rwxr-xr-xtests/gnu/test-freadptr2.sh5
-rwxr-xr-xtests/gnu/test-freadseek.c93
-rwxr-xr-xtests/gnu/test-freadseek.sh5
-rwxr-xr-xtests/gnu/test-frexp.c199
-rwxr-xr-xtests/gnu/test-frexpl.c223
-rwxr-xr-xtests/gnu/test-fseeko.c74
-rwxr-xr-xtests/gnu/test-fseeko.sh5
-rwxr-xr-xtests/gnu/test-fseeko2.sh3
-rwxr-xr-xtests/gnu/test-fseterr.c44
-rwxr-xr-xtests/gnu/test-ftello.c118
-rwxr-xr-xtests/gnu/test-ftello.sh5
-rwxr-xr-xtests/gnu/test-ftello2.sh3
-rwxr-xr-xtests/gnu/test-getdtablesize.c34
-rwxr-xr-xtests/gnu/test-gettimeofday.c47
-rwxr-xr-xtests/gnu/test-iconv.c148
-rwxr-xr-xtests/gnu/test-inttypes.c121
-rwxr-xr-xtests/gnu/test-isnand-nolibm.c22
-rwxr-xr-xtests/gnu/test-isnand.h65
-rwxr-xr-xtests/gnu/test-isnanf-nolibm.c21
-rwxr-xr-xtests/gnu/test-isnanf.h67
-rwxr-xr-xtests/gnu/test-isnanl-nolibm.c23
-rwxr-xr-xtests/gnu/test-isnanl.h141
-rwxr-xr-xtests/gnu/test-langinfo.c92
-rwxr-xr-xtests/gnu/test-link.c47
-rwxr-xr-xtests/gnu/test-link.h176
-rwxr-xr-xtests/gnu/test-linkedhash_list.c441
-rwxr-xr-xtests/gnu/test-lseek.c96
-rwxr-xr-xtests/gnu/test-lseek.sh17
-rwxr-xr-xtests/gnu/test-lstat.c60
-rwxr-xr-xtests/gnu/test-lstat.h116
-rwxr-xr-xtests/gnu/test-malloca.c59
-rwxr-xr-xtests/gnu/test-math.c53
-rwxr-xr-xtests/gnu/test-mbrtowc.c323
-rwxr-xr-xtests/gnu/test-mbrtowc1.sh15
-rwxr-xr-xtests/gnu/test-mbrtowc2.sh15
-rwxr-xr-xtests/gnu/test-mbrtowc3.sh15
-rwxr-xr-xtests/gnu/test-mbrtowc4.sh15
-rwxr-xr-xtests/gnu/test-mbsinit.c53
-rwxr-xr-xtests/gnu/test-mbsinit.sh15
-rwxr-xr-xtests/gnu/test-mbsstr1.c128
-rwxr-xr-xtests/gnu/test-mbsstr2.c141
-rwxr-xr-xtests/gnu/test-mbsstr2.sh15
-rwxr-xr-xtests/gnu/test-mbsstr3.c81
-rwxr-xr-xtests/gnu/test-mbsstr3.sh15
-rwxr-xr-xtests/gnu/test-memchr.c119
-rwxr-xr-xtests/gnu/test-memchr2.c100
-rwxr-xr-xtests/gnu/test-memmem.c187
-rwxr-xr-xtests/gnu/test-nl_langinfo.c115
-rwxr-xr-xtests/gnu/test-nl_langinfo.sh17
-rwxr-xr-xtests/gnu/test-obstack-printf.c138
-rwxr-xr-xtests/gnu/test-open.c41
-rwxr-xr-xtests/gnu/test-open.h87
-rwxr-xr-xtests/gnu/test-pipe.c204
-rwxr-xr-xtests/gnu/test-pipe.sh8
-rwxr-xr-xtests/gnu/test-pipe2.c145
-rwxr-xr-xtests/gnu/test-posix_spawn1.c166
-rwxr-xr-xtests/gnu/test-posix_spawn1.in.sh2
-rwxr-xr-xtests/gnu/test-posix_spawn2.c139
-rwxr-xr-xtests/gnu/test-posix_spawn2.in.sh3
-rwxr-xr-xtests/gnu/test-printf-frexp.c119
-rwxr-xr-xtests/gnu/test-printf-frexpl.c134
-rwxr-xr-xtests/gnu/test-printf-posix.h153
-rwxr-xr-xtests/gnu/test-printf-posix.output40
-rwxr-xr-xtests/gnu/test-quotearg.c471
-rwxr-xr-xtests/gnu/test-quotearg.sh16
-rwxr-xr-xtests/gnu/test-rawmemchr.c76
-rwxr-xr-xtests/gnu/test-readlink.c48
-rwxr-xr-xtests/gnu/test-readlink.h119
-rwxr-xr-xtests/gnu/test-rename.c46
-rwxr-xr-xtests/gnu/test-rename.h446
-rwxr-xr-xtests/gnu/test-rmdir.c47
-rwxr-xr-xtests/gnu/test-rmdir.h101
-rwxr-xr-xtests/gnu/test-sched.c38
-rwxr-xr-xtests/gnu/test-setenv.c56
-rwxr-xr-xtests/gnu/test-sigaction.c116
-rwxr-xr-xtests/gnu/test-signal.c125
-rwxr-xr-xtests/gnu/test-signbit.c197
-rwxr-xr-xtests/gnu/test-snprintf-posix.c38
-rwxr-xr-xtests/gnu/test-snprintf-posix.h3113
-rwxr-xr-xtests/gnu/test-snprintf.c64
-rwxr-xr-xtests/gnu/test-spawn.c54
-rwxr-xr-xtests/gnu/test-sprintf-posix.c41
-rwxr-xr-xtests/gnu/test-sprintf-posix.h3099
-rwxr-xr-xtests/gnu/test-stat.c56
-rwxr-xr-xtests/gnu/test-stat.h100
-rwxr-xr-xtests/gnu/test-stdbool.c95
-rwxr-xr-xtests/gnu/test-stddef.c38
-rwxr-xr-xtests/gnu/test-stdint.c360
-rwxr-xr-xtests/gnu/test-stdio.c43
-rwxr-xr-xtests/gnu/test-stdlib.c43
-rwxr-xr-xtests/gnu/test-strchrnul.c86
-rwxr-xr-xtests/gnu/test-strerror.c57
-rwxr-xr-xtests/gnu/test-striconv.c180
-rwxr-xr-xtests/gnu/test-string.c33
-rwxr-xr-xtests/gnu/test-strtod.c918
-rwxr-xr-xtests/gnu/test-symlink.c47
-rwxr-xr-xtests/gnu/test-symlink.h95
-rwxr-xr-xtests/gnu/test-sys_stat.c288
-rwxr-xr-xtests/gnu/test-sys_time.c29
-rwxr-xr-xtests/gnu/test-sys_wait.c30
-rwxr-xr-xtests/gnu/test-time.c35
-rwxr-xr-xtests/gnu/test-unistd.c56
-rwxr-xr-xtests/gnu/test-unsetenv.c61
-rwxr-xr-xtests/gnu/test-update-copyright.sh526
-rwxr-xr-xtests/gnu/test-vasnprintf-posix.c3671
-rwxr-xr-xtests/gnu/test-vasnprintf-posix2.c63
-rwxr-xr-xtests/gnu/test-vasnprintf-posix2.sh22
-rwxr-xr-xtests/gnu/test-vasnprintf.c117
-rwxr-xr-xtests/gnu/test-vasprintf-posix.c3652
-rwxr-xr-xtests/gnu/test-vasprintf.c83
-rwxr-xr-xtests/gnu/test-vc-list-files-cvs.sh62
-rwxr-xr-xtests/gnu/test-vc-list-files-git.sh48
-rwxr-xr-xtests/gnu/test-vfprintf-posix.c52
-rwxr-xr-xtests/gnu/test-vfprintf-posix.sh16
-rwxr-xr-xtests/gnu/test-vprintf-posix.c52
-rwxr-xr-xtests/gnu/test-vprintf-posix.sh16
-rwxr-xr-xtests/gnu/test-wchar.c37
-rwxr-xr-xtests/gnu/test-wcrtomb.c154
-rwxr-xr-xtests/gnu/test-wcrtomb.sh35
-rwxr-xr-xtests/gnu/test-wctype.c74
-rwxr-xr-xtests/gnu/test-wcwidth.c81
-rwxr-xr-xtests/gnu/test-xalloc-die.c30
-rwxr-xr-xtests/gnu/test-xalloc-die.sh36
-rwxr-xr-xtests/gnu/test-xfprintf-posix.c40
-rwxr-xr-xtests/gnu/test-xmemdup0.c82
-rwxr-xr-xtests/gnu/test-xprintf-posix.c39
-rwxr-xr-xtests/gnu/test-xprintf-posix.sh24
-rwxr-xr-xtests/gnu/test-xvasprintf.c129
-rwxr-xr-xtests/gnu/uniwidth/test-uc_width.c56
-rwxr-xr-xtests/gnu/uniwidth/test-uc_width2.c86
-rwxr-xr-xtests/gnu/uniwidth/test-uc_width2.sh382
-rwxr-xr-xtests/gnu/wctob.c37
-rwxr-xr-xtests/gnu/zerosize-ptr.h68
194 files changed, 37386 insertions, 0 deletions
diff --git a/tests/gnu/Makefile.am b/tests/gnu/Makefile.am
new file mode 100755
index 00000000..f75fd8a4
--- /dev/null
+++ b/tests/gnu/Makefile.am
@@ -0,0 +1,1159 @@
+## DO NOT EDIT! GENERATED AUTOMATICALLY!
+## Process this file with automake to produce Makefile.in.
+# Copyright (C) 2002-2010 Free Software Foundation, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License. As a special exception to the GNU General
+# Public License, this file may be distributed as part of a program
+# that contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+
+AUTOMAKE_OPTIONS = 1.5 foreign subdir-objects
+
+SUBDIRS =
+TESTS =
+XFAIL_TESTS =
+TESTS_ENVIRONMENT =
+noinst_PROGRAMS =
+check_PROGRAMS =
+noinst_HEADERS =
+noinst_LIBRARIES =
+check_LIBRARIES = libtests.a
+EXTRA_DIST =
+BUILT_SOURCES =
+SUFFIXES =
+MOSTLYCLEANFILES = core *.stackdump
+MOSTLYCLEANDIRS =
+CLEANFILES =
+DISTCLEANFILES =
+MAINTAINERCLEANFILES =
+
+AM_CPPFLAGS = \
+ -I. -I$(srcdir) \
+ -I../.. -I$(srcdir)/../.. \
+ -I../../gnu -I$(srcdir)/../../gnu
+
+LDADD = libtests.a ../../gnu/libgnu.la libtests.a $(LIBTESTS_LIBDEPS)
+
+libtests_a_SOURCES =
+libtests_a_LIBADD = $(M4tests_LIBOBJS)
+libtests_a_DEPENDENCIES = $(M4tests_LIBOBJS)
+EXTRA_libtests_a_SOURCES =
+AM_LIBTOOLFLAGS = --preserve-dup-deps
+
+TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' srcdir='$(srcdir)'
+
+## begin gnulib module alloca-opt-tests
+
+TESTS += test-alloca-opt
+check_PROGRAMS += test-alloca-opt
+
+EXTRA_DIST += test-alloca-opt.c
+
+## end gnulib module alloca-opt-tests
+
+## begin gnulib module arg-nonnull
+
+# The BUILT_SOURCES created by this Makefile snippet are not used via #include
+# statements but through direct file reference. Therefore this snippet must be
+# present in all Makefile.am that need it. This is ensured by the applicability
+# 'all' defined above.
+
+BUILT_SOURCES += arg-nonnull.h
+# The arg-nonnull.h that gets inserted into generated .h files is the same as
+# build-aux/arg-nonnull.h, except that it has the copyright header cut off.
+arg-nonnull.h: $(top_srcdir)/build-aux/arg-nonnull.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/GL_ARG_NONNULL/,$$p' \
+ < $(top_srcdir)/build-aux/arg-nonnull.h \
+ > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t
+
+ARG_NONNULL_H=arg-nonnull.h
+
+EXTRA_DIST += $(top_srcdir)/build-aux/arg-nonnull.h
+
+## end gnulib module arg-nonnull
+
+## begin gnulib module array-list
+
+libtests_a_SOURCES += gl_array_list.h gl_array_list.c
+
+## end gnulib module array-list
+
+## begin gnulib module array-list-tests
+
+TESTS += test-array_list
+check_PROGRAMS += test-array_list
+
+EXTRA_DIST += test-array_list.c macros.h
+
+## end gnulib module array-list-tests
+
+## begin gnulib module array-oset
+
+libtests_a_SOURCES += gl_array_oset.h gl_array_oset.c
+
+## end gnulib module array-oset
+
+## begin gnulib module array-oset-tests
+
+TESTS += test-array_oset
+check_PROGRAMS += test-array_oset
+test_array_oset_LDADD = $(LDADD) @LIBINTL@
+
+EXTRA_DIST += test-array_oset.c macros.h
+
+## end gnulib module array-oset-tests
+
+## begin gnulib module avltree-oset-tests
+
+TESTS += test-avltree_oset
+check_PROGRAMS += test-avltree_oset
+EXTRA_DIST += test-avltree_oset.c macros.h
+
+## end gnulib module avltree-oset-tests
+
+## begin gnulib module binary-io-tests
+
+TESTS += test-binary-io.sh
+check_PROGRAMS += test-binary-io
+
+EXTRA_DIST += test-binary-io.sh test-binary-io.c macros.h
+
+## end gnulib module binary-io-tests
+
+## begin gnulib module bitrotate-tests
+
+TESTS += test-bitrotate
+check_PROGRAMS += test-bitrotate
+EXTRA_DIST += test-bitrotate.c macros.h
+
+## end gnulib module bitrotate-tests
+
+## begin gnulib module btowc-tests
+
+TESTS += test-btowc1.sh test-btowc2.sh
+TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
+check_PROGRAMS += test-btowc
+
+EXTRA_DIST += test-btowc1.sh test-btowc2.sh test-btowc.c signature.h macros.h
+
+## end gnulib module btowc-tests
+
+## begin gnulib module c-ctype-tests
+
+TESTS += test-c-ctype
+check_PROGRAMS += test-c-ctype
+
+EXTRA_DIST += test-c-ctype.c macros.h
+
+## end gnulib module c-ctype-tests
+
+## begin gnulib module c-strcase-tests
+
+TESTS += test-c-strcase.sh
+TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_TR_UTF8='@LOCALE_TR_UTF8@'
+check_PROGRAMS += test-c-strcasecmp test-c-strncasecmp
+EXTRA_DIST += test-c-strcase.sh test-c-strcasecmp.c test-c-strncasecmp.c macros.h
+
+## end gnulib module c-strcase-tests
+
+## begin gnulib module canonicalize-lgpl-tests
+
+TESTS += test-canonicalize-lgpl
+check_PROGRAMS += test-canonicalize-lgpl
+EXTRA_DIST += test-canonicalize-lgpl.c signature.h macros.h
+
+## end gnulib module canonicalize-lgpl-tests
+
+## begin gnulib module cloexec-tests
+
+TESTS += test-cloexec
+check_PROGRAMS += test-cloexec
+EXTRA_DIST += test-cloexec.c macros.h
+
+## end gnulib module cloexec-tests
+
+## begin gnulib module closein-tests
+
+TESTS += test-closein.sh
+check_PROGRAMS += test-closein
+test_closein_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-closein.sh test-closein.c
+
+## end gnulib module closein-tests
+
+## begin gnulib module dirname-tests
+
+TESTS += test-dirname
+check_PROGRAMS += test-dirname
+test_dirname_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-dirname.c
+
+## end gnulib module dirname-tests
+
+## begin gnulib module dup2-tests
+
+TESTS += test-dup2
+check_PROGRAMS += test-dup2
+EXTRA_DIST += test-dup2.c signature.h macros.h
+
+## end gnulib module dup2-tests
+
+## begin gnulib module environ-tests
+
+TESTS += test-environ
+check_PROGRAMS += test-environ
+
+EXTRA_DIST += test-environ.c
+
+## end gnulib module environ-tests
+
+## begin gnulib module errno-tests
+
+TESTS += test-errno
+check_PROGRAMS += test-errno
+
+EXTRA_DIST += test-errno.c
+
+## end gnulib module errno-tests
+
+## begin gnulib module fcntl-h-tests
+
+TESTS += test-fcntl-h
+check_PROGRAMS += test-fcntl-h
+EXTRA_DIST += test-fcntl-h.c
+
+## end gnulib module fcntl-h-tests
+
+## begin gnulib module fcntl-tests
+
+TESTS += test-fcntl
+check_PROGRAMS += test-fcntl
+EXTRA_DIST += test-fcntl.c signature.h macros.h
+
+## end gnulib module fcntl-tests
+
+## begin gnulib module fflush-tests
+
+TESTS += test-fflush test-fflush2.sh
+check_PROGRAMS += test-fflush test-fflush2
+MOSTLYCLEANFILES += test-fflush.txt
+EXTRA_DIST += test-fflush.c test-fflush2.sh test-fflush2.c signature.h macros.h
+
+## end gnulib module fflush-tests
+
+## begin gnulib module filenamecat-tests
+
+TESTS += test-filenamecat
+check_PROGRAMS += test-filenamecat
+test_filenamecat_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-filenamecat.c
+
+## end gnulib module filenamecat-tests
+
+## begin gnulib module fopen-safer-tests
+
+TESTS += test-fopen-safer
+check_PROGRAMS += test-fopen-safer
+EXTRA_DIST += test-fopen.h test-fopen-safer.c macros.h
+
+## end gnulib module fopen-safer-tests
+
+## begin gnulib module fopen-tests
+
+TESTS += test-fopen
+check_PROGRAMS += test-fopen
+
+EXTRA_DIST += test-fopen.h test-fopen.c signature.h macros.h
+
+## end gnulib module fopen-tests
+
+## begin gnulib module fpending-tests
+
+TESTS += test-fpending.sh
+check_PROGRAMS += test-fpending
+MOSTLYCLEANFILES += test-fpending.t
+EXTRA_DIST += test-fpending.c test-fpending.sh macros.h
+
+## end gnulib module fpending-tests
+
+## begin gnulib module fpurge-tests
+
+TESTS += test-fpurge
+check_PROGRAMS += test-fpurge
+MOSTLYCLEANFILES += t-fpurge.tmp
+EXTRA_DIST += test-fpurge.c macros.h
+
+## end gnulib module fpurge-tests
+
+## begin gnulib module freadahead-tests
+
+TESTS += test-freadahead.sh
+check_PROGRAMS += test-freadahead
+EXTRA_DIST += test-freadahead.c test-freadahead.sh macros.h
+
+## end gnulib module freadahead-tests
+
+## begin gnulib module freading-tests
+
+TESTS += test-freading
+check_PROGRAMS += test-freading
+MOSTLYCLEANFILES += t-freading.tmp
+EXTRA_DIST += test-freading.c macros.h
+
+## end gnulib module freading-tests
+
+## begin gnulib module freadptr-tests
+
+TESTS += test-freadptr.sh test-freadptr2.sh
+check_PROGRAMS += test-freadptr test-freadptr2
+EXTRA_DIST += test-freadptr.c test-freadptr.sh test-freadptr2.c test-freadptr2.sh macros.h
+
+## end gnulib module freadptr-tests
+
+## begin gnulib module freadseek-tests
+
+TESTS += test-freadseek.sh
+check_PROGRAMS += test-freadseek
+EXTRA_DIST += test-freadseek.c test-freadseek.sh macros.h
+
+## end gnulib module freadseek-tests
+
+## begin gnulib module frexp-nolibm-tests
+
+TESTS += test-frexp-nolibm
+check_PROGRAMS += test-frexp-nolibm
+test_frexp_nolibm_SOURCES = test-frexp.c
+EXTRA_DIST += test-frexp.c signature.h macros.h
+
+## end gnulib module frexp-nolibm-tests
+
+## begin gnulib module frexpl-nolibm-tests
+
+TESTS += test-frexpl-nolibm
+check_PROGRAMS += test-frexpl-nolibm
+test_frexpl_nolibm_SOURCES = test-frexpl.c
+EXTRA_DIST += test-frexpl.c signature.h macros.h
+
+## end gnulib module frexpl-nolibm-tests
+
+## begin gnulib module fseeko-tests
+
+TESTS += test-fseeko.sh test-fseeko2.sh
+check_PROGRAMS += test-fseeko
+EXTRA_DIST += test-fseeko.c test-fseeko.sh test-fseeko2.sh signature.h macros.h
+
+## end gnulib module fseeko-tests
+
+## begin gnulib module fseterr-tests
+
+TESTS += test-fseterr
+check_PROGRAMS += test-fseterr
+
+EXTRA_DIST += test-fseterr.c
+
+## end gnulib module fseterr-tests
+
+## begin gnulib module ftello-tests
+
+TESTS += test-ftello.sh test-ftello2.sh
+check_PROGRAMS += test-ftello
+EXTRA_DIST += test-ftello.c test-ftello.sh test-ftello2.sh signature.h macros.h
+
+## end gnulib module ftello-tests
+
+## begin gnulib module getdtablesize-tests
+
+TESTS += test-getdtablesize
+check_PROGRAMS += test-getdtablesize
+EXTRA_DIST += test-getdtablesize.c signature.h macros.h
+
+## end gnulib module getdtablesize-tests
+
+## begin gnulib module getpagesize
+
+
+EXTRA_DIST += getpagesize.c
+
+EXTRA_libtests_a_SOURCES += getpagesize.c
+
+## end gnulib module getpagesize
+
+## begin gnulib module gettimeofday-tests
+
+TESTS += test-gettimeofday
+check_PROGRAMS += test-gettimeofday
+
+EXTRA_DIST += signature.h test-gettimeofday.c
+
+## end gnulib module gettimeofday-tests
+
+## begin gnulib module iconv-tests
+
+TESTS += test-iconv
+check_PROGRAMS += test-iconv
+test_iconv_LDADD = $(LDADD) @LIBICONV@
+
+EXTRA_DIST += test-iconv.c signature.h macros.h
+
+## end gnulib module iconv-tests
+
+## begin gnulib module ignore-value
+
+libtests_a_SOURCES += ignore-value.h
+
+## end gnulib module ignore-value
+
+## begin gnulib module inttypes-tests
+
+TESTS += test-inttypes
+check_PROGRAMS += test-inttypes
+EXTRA_DIST += test-inttypes.c
+
+## end gnulib module inttypes-tests
+
+## begin gnulib module isnand-nolibm-tests
+
+TESTS += test-isnand-nolibm
+check_PROGRAMS += test-isnand-nolibm
+
+EXTRA_DIST += test-isnand-nolibm.c test-isnand.h nan.h macros.h
+
+## end gnulib module isnand-nolibm-tests
+
+## begin gnulib module isnanf-nolibm-tests
+
+TESTS += test-isnanf-nolibm
+check_PROGRAMS += test-isnanf-nolibm
+
+EXTRA_DIST += test-isnanf-nolibm.c test-isnanf.h nan.h macros.h
+
+## end gnulib module isnanf-nolibm-tests
+
+## begin gnulib module isnanl-nolibm-tests
+
+TESTS += test-isnanl-nolibm
+check_PROGRAMS += test-isnanl-nolibm
+
+EXTRA_DIST += test-isnanl-nolibm.c test-isnanl.h nan.h macros.h
+
+## end gnulib module isnanl-nolibm-tests
+
+## begin gnulib module langinfo-tests
+
+TESTS += test-langinfo
+check_PROGRAMS += test-langinfo
+EXTRA_DIST += test-langinfo.c
+
+## end gnulib module langinfo-tests
+
+## begin gnulib module link
+
+
+EXTRA_DIST += link.c
+
+EXTRA_libtests_a_SOURCES += link.c
+
+## end gnulib module link
+
+## begin gnulib module link-tests
+
+TESTS += test-link
+check_PROGRAMS += test-link
+EXTRA_DIST += test-link.h test-link.c signature.h macros.h
+
+## end gnulib module link-tests
+
+## begin gnulib module linkedhash-list-tests
+
+TESTS += test-linkedhash_list
+check_PROGRAMS += test-linkedhash_list
+EXTRA_DIST += test-linkedhash_list.c macros.h
+
+## end gnulib module linkedhash-list-tests
+
+## begin gnulib module lseek-tests
+
+TESTS += test-lseek.sh
+check_PROGRAMS += test-lseek
+EXTRA_DIST += test-lseek.c test-lseek.sh signature.h macros.h
+
+## end gnulib module lseek-tests
+
+## begin gnulib module lstat-tests
+
+TESTS += test-lstat
+check_PROGRAMS += test-lstat
+EXTRA_DIST += test-lstat.h test-lstat.c signature.h macros.h
+
+## end gnulib module lstat-tests
+
+## begin gnulib module malloca-tests
+
+TESTS += test-malloca
+check_PROGRAMS += test-malloca
+
+EXTRA_DIST += test-malloca.c
+
+## end gnulib module malloca-tests
+
+## begin gnulib module math-tests
+
+TESTS += test-math
+check_PROGRAMS += test-math
+EXTRA_DIST += test-math.c
+
+## end gnulib module math-tests
+
+## begin gnulib module mbrtowc-tests
+
+TESTS += test-mbrtowc1.sh test-mbrtowc2.sh test-mbrtowc3.sh test-mbrtowc4.sh
+TESTS_ENVIRONMENT += \
+ LOCALE_FR='@LOCALE_FR@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ LOCALE_JA='@LOCALE_JA@' \
+ LOCALE_ZH_CN='@LOCALE_ZH_CN@'
+check_PROGRAMS += test-mbrtowc
+
+EXTRA_DIST += test-mbrtowc1.sh test-mbrtowc2.sh test-mbrtowc3.sh test-mbrtowc4.sh test-mbrtowc.c signature.h macros.h
+
+## end gnulib module mbrtowc-tests
+
+## begin gnulib module mbsinit-tests
+
+TESTS += test-mbsinit.sh
+TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
+check_PROGRAMS += test-mbsinit
+
+EXTRA_DIST += test-mbsinit.sh test-mbsinit.c signature.h macros.h
+
+## end gnulib module mbsinit-tests
+
+## begin gnulib module mbsstr-tests
+
+TESTS += test-mbsstr1 test-mbsstr2.sh test-mbsstr3.sh
+TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' LOCALE_ZH_CN='@LOCALE_ZH_CN@'
+check_PROGRAMS += test-mbsstr1 test-mbsstr2 test-mbsstr3
+
+EXTRA_DIST += test-mbsstr1.c test-mbsstr2.sh test-mbsstr2.c test-mbsstr3.sh test-mbsstr3.c macros.h
+
+## end gnulib module mbsstr-tests
+
+## begin gnulib module memchr-tests
+
+TESTS += test-memchr
+check_PROGRAMS += test-memchr
+EXTRA_DIST += test-memchr.c zerosize-ptr.h signature.h macros.h
+
+## end gnulib module memchr-tests
+
+## begin gnulib module memchr2-tests
+
+TESTS += test-memchr2
+check_PROGRAMS += test-memchr2
+EXTRA_DIST += test-memchr2.c zerosize-ptr.h macros.h
+
+## end gnulib module memchr2-tests
+
+## begin gnulib module memmem-tests
+
+TESTS += test-memmem
+check_PROGRAMS += test-memmem
+
+EXTRA_DIST += test-memmem.c zerosize-ptr.h signature.h macros.h
+
+## end gnulib module memmem-tests
+
+## begin gnulib module nl_langinfo-tests
+
+TESTS += test-nl_langinfo.sh
+TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
+check_PROGRAMS += test-nl_langinfo
+EXTRA_DIST += test-nl_langinfo.sh test-nl_langinfo.c signature.h macros.h
+
+## end gnulib module nl_langinfo-tests
+
+## begin gnulib module obstack-printf
+
+
+EXTRA_DIST += obstack_printf.c
+
+EXTRA_libtests_a_SOURCES += obstack_printf.c
+
+## end gnulib module obstack-printf
+
+## begin gnulib module obstack-printf-tests
+
+TESTS += test-obstack-printf
+check_PROGRAMS += test-obstack-printf
+test_obstack_printf_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-obstack-printf.c signature.h macros.h
+
+## end gnulib module obstack-printf-tests
+
+## begin gnulib module open-tests
+
+TESTS += test-open
+check_PROGRAMS += test-open
+EXTRA_DIST += test-open.h test-open.c signature.h macros.h
+
+## end gnulib module open-tests
+
+## begin gnulib module pipe-tests
+
+TESTS += test-pipe.sh
+check_PROGRAMS += test-pipe
+test_pipe_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-pipe.sh test-pipe.c macros.h
+
+## end gnulib module pipe-tests
+
+## begin gnulib module pipe2-tests
+
+TESTS += test-pipe2
+check_PROGRAMS += test-pipe2
+EXTRA_DIST += test-pipe2.c signature.h macros.h
+
+## end gnulib module pipe2-tests
+
+## begin gnulib module posix_spawnp-tests
+
+if POSIX_SPAWN_PORTED
+TESTS += test-posix_spawn1 test-posix_spawn2
+check_PROGRAMS += test-posix_spawn1 test-posix_spawn2
+
+BUILT_SOURCES += test-posix_spawn1.sh
+test-posix_spawn1.sh: test-posix_spawn1.in.sh
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ cp $(srcdir)/test-posix_spawn1.in.sh $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += test-posix_spawn1.sh test-posix_spawn1.sh-t
+
+BUILT_SOURCES += test-posix_spawn2.sh
+test-posix_spawn2.sh: test-posix_spawn2.in.sh
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ cp $(srcdir)/test-posix_spawn2.in.sh $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += test-posix_spawn2.sh test-posix_spawn2.sh-t
+endif
+EXTRA_DIST += test-posix_spawn1.c test-posix_spawn1.in.sh test-posix_spawn2.c test-posix_spawn2.in.sh signature.h
+
+## end gnulib module posix_spawnp-tests
+
+## begin gnulib module printf-frexp-tests
+
+TESTS += test-printf-frexp
+check_PROGRAMS += test-printf-frexp
+EXTRA_DIST += test-printf-frexp.c macros.h
+
+## end gnulib module printf-frexp-tests
+
+## begin gnulib module printf-frexpl-tests
+
+TESTS += test-printf-frexpl
+check_PROGRAMS += test-printf-frexpl
+EXTRA_DIST += test-printf-frexpl.c macros.h
+
+## end gnulib module printf-frexpl-tests
+
+## begin gnulib module putenv
+
+
+EXTRA_DIST += putenv.c
+
+EXTRA_libtests_a_SOURCES += putenv.c
+
+## end gnulib module putenv
+
+## begin gnulib module quotearg-tests
+
+TESTS += test-quotearg.sh
+TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
+check_PROGRAMS += test-quotearg
+test_quotearg_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-quotearg.sh test-quotearg.c macros.h locale/fr/LC_MESSAGES/test-quotearg.po locale/fr/LC_MESSAGES/test-quotearg.mo
+
+## end gnulib module quotearg-tests
+
+## begin gnulib module rawmemchr-tests
+
+TESTS += test-rawmemchr
+check_PROGRAMS += test-rawmemchr
+EXTRA_DIST += test-rawmemchr.c signature.h macros.h
+
+## end gnulib module rawmemchr-tests
+
+## begin gnulib module readlink-tests
+
+TESTS += test-readlink
+check_PROGRAMS += test-readlink
+EXTRA_DIST += test-readlink.h test-readlink.c signature.h macros.h
+
+## end gnulib module readlink-tests
+
+## begin gnulib module rename-tests
+
+TESTS += test-rename
+check_PROGRAMS += test-rename
+EXTRA_DIST += test-rename.h test-rename.c signature.h macros.h
+
+## end gnulib module rename-tests
+
+## begin gnulib module rmdir-tests
+
+TESTS += test-rmdir
+check_PROGRAMS += test-rmdir
+EXTRA_DIST += test-rmdir.h test-rmdir.c signature.h macros.h
+
+## end gnulib module rmdir-tests
+
+## begin gnulib module sched-tests
+
+TESTS += test-sched
+check_PROGRAMS += test-sched
+EXTRA_DIST += test-sched.c
+
+## end gnulib module sched-tests
+
+## begin gnulib module setenv-tests
+
+TESTS += test-setenv
+check_PROGRAMS += test-setenv
+EXTRA_DIST += test-setenv.c signature.h macros.h
+
+## end gnulib module setenv-tests
+
+## begin gnulib module sigaction-tests
+
+TESTS += test-sigaction
+check_PROGRAMS += test-sigaction
+EXTRA_DIST += test-sigaction.c signature.h macros.h
+
+## end gnulib module sigaction-tests
+
+## begin gnulib module signal-tests
+
+TESTS += test-signal
+check_PROGRAMS += test-signal
+EXTRA_DIST += test-signal.c
+
+## end gnulib module signal-tests
+
+## begin gnulib module signbit-tests
+
+TESTS += test-signbit
+check_PROGRAMS += test-signbit
+
+EXTRA_DIST += test-signbit.c macros.h
+
+## end gnulib module signbit-tests
+
+## begin gnulib module snprintf-posix-tests
+
+TESTS += test-snprintf-posix test-snprintf
+check_PROGRAMS += test-snprintf-posix test-snprintf
+
+EXTRA_DIST += test-snprintf-posix.c test-snprintf-posix.h test-snprintf.c nan.h signature.h macros.h
+
+## end gnulib module snprintf-posix-tests
+
+## begin gnulib module snprintf-tests
+
+TESTS += test-snprintf
+check_PROGRAMS += test-snprintf
+
+EXTRA_DIST += test-snprintf.c signature.h macros.h
+
+## end gnulib module snprintf-tests
+
+## begin gnulib module spawn-tests
+
+TESTS += test-spawn
+check_PROGRAMS += test-spawn
+EXTRA_DIST += test-spawn.c
+
+## end gnulib module spawn-tests
+
+## begin gnulib module sprintf-posix-tests
+
+TESTS += test-sprintf-posix
+check_PROGRAMS += test-sprintf-posix
+
+EXTRA_DIST += test-sprintf-posix.c test-sprintf-posix.h nan.h signature.h macros.h
+
+## end gnulib module sprintf-posix-tests
+
+## begin gnulib module stat-tests
+
+TESTS += test-stat
+check_PROGRAMS += test-stat
+EXTRA_DIST += test-stat.h test-stat.c signature.h macros.h
+
+## end gnulib module stat-tests
+
+## begin gnulib module stdbool-tests
+
+TESTS += test-stdbool
+check_PROGRAMS += test-stdbool
+EXTRA_DIST += test-stdbool.c
+
+## end gnulib module stdbool-tests
+
+## begin gnulib module stddef-tests
+
+TESTS += test-stddef
+check_PROGRAMS += test-stddef
+EXTRA_DIST += test-stddef.c
+
+## end gnulib module stddef-tests
+
+## begin gnulib module stdint-tests
+
+TESTS += test-stdint
+check_PROGRAMS += test-stdint
+EXTRA_DIST += test-stdint.c
+
+## end gnulib module stdint-tests
+
+## begin gnulib module stdio-tests
+
+TESTS += test-stdio
+check_PROGRAMS += test-stdio
+EXTRA_DIST += test-stdio.c
+
+## end gnulib module stdio-tests
+
+## begin gnulib module stdlib-tests
+
+TESTS += test-stdlib
+check_PROGRAMS += test-stdlib
+EXTRA_DIST += test-stdlib.c
+
+## end gnulib module stdlib-tests
+
+## begin gnulib module strchrnul-tests
+
+TESTS += test-strchrnul
+check_PROGRAMS += test-strchrnul
+EXTRA_DIST += test-strchrnul.c signature.h macros.h
+
+## end gnulib module strchrnul-tests
+
+## begin gnulib module strdup-posix
+
+
+EXTRA_DIST += strdup.c
+
+EXTRA_libtests_a_SOURCES += strdup.c
+
+## end gnulib module strdup-posix
+
+## begin gnulib module strerror-tests
+
+TESTS += test-strerror
+check_PROGRAMS += test-strerror
+EXTRA_DIST += test-strerror.c signature.h macros.h
+
+## end gnulib module strerror-tests
+
+## begin gnulib module striconv-tests
+
+TESTS += test-striconv
+check_PROGRAMS += test-striconv
+test_striconv_LDADD = $(LDADD) @LIBICONV@
+
+EXTRA_DIST += test-striconv.c macros.h
+
+## end gnulib module striconv-tests
+
+## begin gnulib module string-tests
+
+TESTS += test-string
+check_PROGRAMS += test-string
+EXTRA_DIST += test-string.c
+
+## end gnulib module string-tests
+
+## begin gnulib module strtod-tests
+
+LIBS += $(POW_LIB)
+TESTS += test-strtod
+check_PROGRAMS += test-strtod
+EXTRA_DIST += test-strtod.c signature.h macros.h
+
+## end gnulib module strtod-tests
+
+## begin gnulib module symlink
+
+
+EXTRA_DIST += symlink.c
+
+EXTRA_libtests_a_SOURCES += symlink.c
+
+## end gnulib module symlink
+
+## begin gnulib module symlink-tests
+
+TESTS += test-symlink
+check_PROGRAMS += test-symlink
+EXTRA_DIST += test-symlink.h test-symlink.c signature.h macros.h
+
+## end gnulib module symlink-tests
+
+## begin gnulib module sys_stat-tests
+
+TESTS += test-sys_stat
+check_PROGRAMS += test-sys_stat
+EXTRA_DIST += test-sys_stat.c
+
+## end gnulib module sys_stat-tests
+
+## begin gnulib module sys_time-tests
+
+TESTS += test-sys_time
+check_PROGRAMS += test-sys_time
+EXTRA_DIST += test-sys_time.c
+
+## end gnulib module sys_time-tests
+
+## begin gnulib module sys_wait-tests
+
+TESTS += test-sys_wait
+check_PROGRAMS += test-sys_wait
+EXTRA_DIST += test-sys_wait.c
+
+## end gnulib module sys_wait-tests
+
+## begin gnulib module time-tests
+
+TESTS += test-time
+check_PROGRAMS += test-time
+EXTRA_DIST += test-time.c
+
+## end gnulib module time-tests
+
+## begin gnulib module unistd-safer-tests
+
+TESTS += test-dup-safer
+check_PROGRAMS += test-dup-safer
+EXTRA_DIST += test-dup-safer.c macros.h
+
+## end gnulib module unistd-safer-tests
+
+## begin gnulib module unistd-tests
+
+TESTS += test-unistd
+check_PROGRAMS += test-unistd
+EXTRA_DIST += test-unistd.c
+
+## end gnulib module unistd-tests
+
+## begin gnulib module uniwidth/width-tests
+
+TESTS += test-uc_width uniwidth/test-uc_width2.sh
+check_PROGRAMS += test-uc_width test-uc_width2
+test_uc_width_SOURCES = uniwidth/test-uc_width.c
+test_uc_width2_SOURCES = uniwidth/test-uc_width2.c
+
+EXTRA_DIST += uniwidth/test-uc_width.c uniwidth/test-uc_width2.c uniwidth/test-uc_width2.sh macros.h
+
+## end gnulib module uniwidth/width-tests
+
+## begin gnulib module unsetenv-tests
+
+TESTS += test-unsetenv
+check_PROGRAMS += test-unsetenv
+EXTRA_DIST += test-unsetenv.c signature.h macros.h
+
+## end gnulib module unsetenv-tests
+
+## begin gnulib module update-copyright-tests
+
+TESTS += test-update-copyright.sh
+TESTS_ENVIRONMENT += PATH='$(abs_aux_dir)'$(PATH_SEPARATOR)"$$PATH"
+EXTRA_DIST += test-update-copyright.sh
+
+## end gnulib module update-copyright-tests
+
+## begin gnulib module vasnprintf-posix-tests
+
+TESTS += test-vasnprintf-posix test-vasnprintf-posix2.sh
+TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
+check_PROGRAMS += test-vasnprintf-posix test-vasnprintf-posix2
+EXTRA_DIST += test-vasnprintf-posix.c test-vasnprintf-posix2.sh test-vasnprintf-posix2.c nan.h macros.h
+
+## end gnulib module vasnprintf-posix-tests
+
+## begin gnulib module vasnprintf-tests
+
+TESTS += test-vasnprintf
+check_PROGRAMS += test-vasnprintf
+
+EXTRA_DIST += test-vasnprintf.c macros.h
+
+## end gnulib module vasnprintf-tests
+
+## begin gnulib module vasprintf-posix-tests
+
+TESTS += test-vasprintf-posix
+check_PROGRAMS += test-vasprintf-posix
+
+EXTRA_DIST += test-vasprintf-posix.c nan.h macros.h
+
+## end gnulib module vasprintf-posix-tests
+
+## begin gnulib module vasprintf-tests
+
+TESTS += test-vasprintf
+check_PROGRAMS += test-vasprintf
+
+EXTRA_DIST += test-vasprintf.c signature.h macros.h
+
+## end gnulib module vasprintf-tests
+
+## begin gnulib module vc-list-files-tests
+
+TESTS += test-vc-list-files-git.sh
+TESTS += test-vc-list-files-cvs.sh
+TESTS_ENVIRONMENT += PATH='$(abs_aux_dir)'$(PATH_SEPARATOR)"$$PATH"
+EXTRA_DIST += test-vc-list-files-git.sh test-vc-list-files-cvs.sh
+
+## end gnulib module vc-list-files-tests
+
+## begin gnulib module vfprintf-posix-tests
+
+TESTS += test-vfprintf-posix.sh
+check_PROGRAMS += test-vfprintf-posix
+EXTRA_DIST += test-vfprintf-posix.sh test-vfprintf-posix.c test-fprintf-posix.h test-printf-posix.output signature.h macros.h
+
+## end gnulib module vfprintf-posix-tests
+
+## begin gnulib module vprintf-posix-tests
+
+TESTS += test-vprintf-posix.sh
+check_PROGRAMS += test-vprintf-posix
+EXTRA_DIST += test-vprintf-posix.sh test-vprintf-posix.c test-printf-posix.h test-printf-posix.output signature.h macros.h
+
+## end gnulib module vprintf-posix-tests
+
+## begin gnulib module warn-on-use
+
+BUILT_SOURCES += warn-on-use.h
+# The warn-on-use.h that gets inserted into generated .h files is the same as
+# build-aux/warn-on-use.h, except that it has the copyright header cut off.
+warn-on-use.h: $(top_srcdir)/build-aux/warn-on-use.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/^.ifndef/,$$p' \
+ < $(top_srcdir)/build-aux/warn-on-use.h \
+ > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t
+
+WARN_ON_USE_H=warn-on-use.h
+
+EXTRA_DIST += $(top_srcdir)/build-aux/warn-on-use.h
+
+## end gnulib module warn-on-use
+
+## begin gnulib module wchar-tests
+
+TESTS += test-wchar
+check_PROGRAMS += test-wchar
+EXTRA_DIST += test-wchar.c
+
+## end gnulib module wchar-tests
+
+## begin gnulib module wcrtomb-tests
+
+TESTS += test-wcrtomb.sh
+TESTS_ENVIRONMENT += \
+ LOCALE_FR='@LOCALE_FR@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ LOCALE_JA='@LOCALE_JA@' \
+ LOCALE_ZH_CN='@LOCALE_ZH_CN@'
+check_PROGRAMS += test-wcrtomb
+
+EXTRA_DIST += test-wcrtomb.sh test-wcrtomb.c signature.h macros.h
+
+## end gnulib module wcrtomb-tests
+
+## begin gnulib module wctob
+
+
+EXTRA_DIST += wctob.c
+
+EXTRA_libtests_a_SOURCES += wctob.c
+
+## end gnulib module wctob
+
+## begin gnulib module wctype-tests
+
+TESTS += test-wctype
+check_PROGRAMS += test-wctype
+EXTRA_DIST += test-wctype.c macros.h
+
+## end gnulib module wctype-tests
+
+## begin gnulib module wcwidth-tests
+
+TESTS += test-wcwidth
+check_PROGRAMS += test-wcwidth
+
+EXTRA_DIST += test-wcwidth.c signature.h macros.h
+
+## end gnulib module wcwidth-tests
+
+## begin gnulib module xalloc-die-tests
+
+TESTS += test-xalloc-die.sh
+check_PROGRAMS += test-xalloc-die
+test_xalloc_die_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-xalloc-die.c test-xalloc-die.sh init.sh
+
+## end gnulib module xalloc-die-tests
+
+## begin gnulib module xmemdup0-tests
+
+TESTS += test-xmemdup0
+check_PROGRAMS += test-xmemdup0
+test_xmemdup0_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-xmemdup0.c macros.h
+
+## end gnulib module xmemdup0-tests
+
+## begin gnulib module xprintf-posix-tests
+
+TESTS += test-xprintf-posix.sh
+check_PROGRAMS += test-xfprintf-posix test-xprintf-posix
+test_xfprintf_posix_LDADD = $(LDADD) @LIBINTL@
+test_xprintf_posix_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-xprintf-posix.sh test-xfprintf-posix.c test-xprintf-posix.c test-fprintf-posix.h test-printf-posix.h test-printf-posix.output macros.h
+
+## end gnulib module xprintf-posix-tests
+
+## begin gnulib module xvasprintf-tests
+
+TESTS += test-xvasprintf
+check_PROGRAMS += test-xvasprintf
+test_xvasprintf_LDADD = $(LDADD) @LIBINTL@
+
+EXTRA_DIST += test-xvasprintf.c macros.h
+
+## end gnulib module xvasprintf-tests
+
+# Clean up after Solaris cc.
+clean-local:
+ rm -rf SunWS_cache
+
+mostlyclean-local: mostlyclean-generic
+ @for dir in '' $(MOSTLYCLEANDIRS); do \
+ if test -n "$$dir" && test -d $$dir; then \
+ echo "rmdir $$dir"; rmdir $$dir; \
+ fi; \
+ done; \
+ :
diff --git a/tests/gnu/Makefile.in b/tests/gnu/Makefile.in
new file mode 100644
index 00000000..046750e9
--- /dev/null
+++ b/tests/gnu/Makefile.in
@@ -0,0 +1,3470 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2002-2010 Free Software Foundation, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License. As a special exception to the GNU General
+# Public License, this file may be distributed as part of a program
+# that contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = test-alloca-opt$(EXEEXT) test-array_list$(EXEEXT) \
+ test-array_oset$(EXEEXT) test-avltree_oset$(EXEEXT) \
+ test-binary-io.sh test-bitrotate$(EXEEXT) test-btowc1.sh \
+ test-btowc2.sh test-c-ctype$(EXEEXT) test-c-strcase.sh \
+ test-canonicalize-lgpl$(EXEEXT) test-cloexec$(EXEEXT) \
+ test-closein.sh test-dirname$(EXEEXT) test-dup2$(EXEEXT) \
+ test-environ$(EXEEXT) test-errno$(EXEEXT) \
+ test-fcntl-h$(EXEEXT) test-fcntl$(EXEEXT) test-fflush$(EXEEXT) \
+ test-fflush2.sh test-filenamecat$(EXEEXT) \
+ test-fopen-safer$(EXEEXT) test-fopen$(EXEEXT) test-fpending.sh \
+ test-fpurge$(EXEEXT) test-freadahead.sh test-freading$(EXEEXT) \
+ test-freadptr.sh test-freadptr2.sh test-freadseek.sh \
+ test-frexp-nolibm$(EXEEXT) test-frexpl-nolibm$(EXEEXT) \
+ test-fseeko.sh test-fseeko2.sh test-fseterr$(EXEEXT) \
+ test-ftello.sh test-ftello2.sh test-getdtablesize$(EXEEXT) \
+ test-gettimeofday$(EXEEXT) test-iconv$(EXEEXT) \
+ test-inttypes$(EXEEXT) test-isnand-nolibm$(EXEEXT) \
+ test-isnanf-nolibm$(EXEEXT) test-isnanl-nolibm$(EXEEXT) \
+ test-langinfo$(EXEEXT) test-link$(EXEEXT) \
+ test-linkedhash_list$(EXEEXT) test-lseek.sh \
+ test-lstat$(EXEEXT) test-malloca$(EXEEXT) test-math$(EXEEXT) \
+ test-mbrtowc1.sh test-mbrtowc2.sh test-mbrtowc3.sh \
+ test-mbrtowc4.sh test-mbsinit.sh test-mbsstr1$(EXEEXT) \
+ test-mbsstr2.sh test-mbsstr3.sh test-memchr$(EXEEXT) \
+ test-memchr2$(EXEEXT) test-memmem$(EXEEXT) test-nl_langinfo.sh \
+ test-obstack-printf$(EXEEXT) test-open$(EXEEXT) test-pipe.sh \
+ test-pipe2$(EXEEXT) $(am__EXEEXT_1) test-printf-frexp$(EXEEXT) \
+ test-printf-frexpl$(EXEEXT) test-quotearg.sh \
+ test-rawmemchr$(EXEEXT) test-readlink$(EXEEXT) \
+ test-rename$(EXEEXT) test-rmdir$(EXEEXT) test-sched$(EXEEXT) \
+ test-setenv$(EXEEXT) test-sigaction$(EXEEXT) \
+ test-signal$(EXEEXT) test-signbit$(EXEEXT) \
+ test-snprintf-posix$(EXEEXT) test-snprintf$(EXEEXT) \
+ test-snprintf$(EXEEXT) test-spawn$(EXEEXT) \
+ test-sprintf-posix$(EXEEXT) test-stat$(EXEEXT) \
+ test-stdbool$(EXEEXT) test-stddef$(EXEEXT) \
+ test-stdint$(EXEEXT) test-stdio$(EXEEXT) test-stdlib$(EXEEXT) \
+ test-strchrnul$(EXEEXT) test-strerror$(EXEEXT) \
+ test-striconv$(EXEEXT) test-string$(EXEEXT) \
+ test-strtod$(EXEEXT) test-symlink$(EXEEXT) \
+ test-sys_stat$(EXEEXT) test-sys_time$(EXEEXT) \
+ test-sys_wait$(EXEEXT) test-time$(EXEEXT) \
+ test-dup-safer$(EXEEXT) test-unistd$(EXEEXT) \
+ test-uc_width$(EXEEXT) uniwidth/test-uc_width2.sh \
+ test-unsetenv$(EXEEXT) test-update-copyright.sh \
+ test-vasnprintf-posix$(EXEEXT) test-vasnprintf-posix2.sh \
+ test-vasnprintf$(EXEEXT) test-vasprintf-posix$(EXEEXT) \
+ test-vasprintf$(EXEEXT) test-vc-list-files-git.sh \
+ test-vc-list-files-cvs.sh test-vfprintf-posix.sh \
+ test-vprintf-posix.sh test-wchar$(EXEEXT) test-wcrtomb.sh \
+ test-wctype$(EXEEXT) test-wcwidth$(EXEEXT) test-xalloc-die.sh \
+ test-xmemdup0$(EXEEXT) test-xprintf-posix.sh \
+ test-xvasprintf$(EXEEXT)
+XFAIL_TESTS =
+noinst_PROGRAMS =
+check_PROGRAMS = test-alloca-opt$(EXEEXT) test-array_list$(EXEEXT) \
+ test-array_oset$(EXEEXT) test-avltree_oset$(EXEEXT) \
+ test-binary-io$(EXEEXT) test-bitrotate$(EXEEXT) \
+ test-btowc$(EXEEXT) test-c-ctype$(EXEEXT) \
+ test-c-strcasecmp$(EXEEXT) test-c-strncasecmp$(EXEEXT) \
+ test-canonicalize-lgpl$(EXEEXT) test-cloexec$(EXEEXT) \
+ test-closein$(EXEEXT) test-dirname$(EXEEXT) test-dup2$(EXEEXT) \
+ test-environ$(EXEEXT) test-errno$(EXEEXT) \
+ test-fcntl-h$(EXEEXT) test-fcntl$(EXEEXT) test-fflush$(EXEEXT) \
+ test-fflush2$(EXEEXT) test-filenamecat$(EXEEXT) \
+ test-fopen-safer$(EXEEXT) test-fopen$(EXEEXT) \
+ test-fpending$(EXEEXT) test-fpurge$(EXEEXT) \
+ test-freadahead$(EXEEXT) test-freading$(EXEEXT) \
+ test-freadptr$(EXEEXT) test-freadptr2$(EXEEXT) \
+ test-freadseek$(EXEEXT) test-frexp-nolibm$(EXEEXT) \
+ test-frexpl-nolibm$(EXEEXT) test-fseeko$(EXEEXT) \
+ test-fseterr$(EXEEXT) test-ftello$(EXEEXT) \
+ test-getdtablesize$(EXEEXT) test-gettimeofday$(EXEEXT) \
+ test-iconv$(EXEEXT) test-inttypes$(EXEEXT) \
+ test-isnand-nolibm$(EXEEXT) test-isnanf-nolibm$(EXEEXT) \
+ test-isnanl-nolibm$(EXEEXT) test-langinfo$(EXEEXT) \
+ test-link$(EXEEXT) test-linkedhash_list$(EXEEXT) \
+ test-lseek$(EXEEXT) test-lstat$(EXEEXT) test-malloca$(EXEEXT) \
+ test-math$(EXEEXT) test-mbrtowc$(EXEEXT) test-mbsinit$(EXEEXT) \
+ test-mbsstr1$(EXEEXT) test-mbsstr2$(EXEEXT) \
+ test-mbsstr3$(EXEEXT) test-memchr$(EXEEXT) \
+ test-memchr2$(EXEEXT) test-memmem$(EXEEXT) \
+ test-nl_langinfo$(EXEEXT) test-obstack-printf$(EXEEXT) \
+ test-open$(EXEEXT) test-pipe$(EXEEXT) test-pipe2$(EXEEXT) \
+ $(am__EXEEXT_1) test-printf-frexp$(EXEEXT) \
+ test-printf-frexpl$(EXEEXT) test-quotearg$(EXEEXT) \
+ test-rawmemchr$(EXEEXT) test-readlink$(EXEEXT) \
+ test-rename$(EXEEXT) test-rmdir$(EXEEXT) test-sched$(EXEEXT) \
+ test-setenv$(EXEEXT) test-sigaction$(EXEEXT) \
+ test-signal$(EXEEXT) test-signbit$(EXEEXT) \
+ test-snprintf-posix$(EXEEXT) test-snprintf$(EXEEXT) \
+ test-snprintf$(EXEEXT) test-spawn$(EXEEXT) \
+ test-sprintf-posix$(EXEEXT) test-stat$(EXEEXT) \
+ test-stdbool$(EXEEXT) test-stddef$(EXEEXT) \
+ test-stdint$(EXEEXT) test-stdio$(EXEEXT) test-stdlib$(EXEEXT) \
+ test-strchrnul$(EXEEXT) test-strerror$(EXEEXT) \
+ test-striconv$(EXEEXT) test-string$(EXEEXT) \
+ test-strtod$(EXEEXT) test-symlink$(EXEEXT) \
+ test-sys_stat$(EXEEXT) test-sys_time$(EXEEXT) \
+ test-sys_wait$(EXEEXT) test-time$(EXEEXT) \
+ test-dup-safer$(EXEEXT) test-unistd$(EXEEXT) \
+ test-uc_width$(EXEEXT) test-uc_width2$(EXEEXT) \
+ test-unsetenv$(EXEEXT) test-vasnprintf-posix$(EXEEXT) \
+ test-vasnprintf-posix2$(EXEEXT) test-vasnprintf$(EXEEXT) \
+ test-vasprintf-posix$(EXEEXT) test-vasprintf$(EXEEXT) \
+ test-vfprintf-posix$(EXEEXT) test-vprintf-posix$(EXEEXT) \
+ test-wchar$(EXEEXT) test-wcrtomb$(EXEEXT) test-wctype$(EXEEXT) \
+ test-wcwidth$(EXEEXT) test-xalloc-die$(EXEEXT) \
+ test-xmemdup0$(EXEEXT) test-xfprintf-posix$(EXEEXT) \
+ test-xprintf-posix$(EXEEXT) test-xvasprintf$(EXEEXT)
+@POSIX_SPAWN_PORTED_TRUE@am__append_1 = test-posix_spawn1 test-posix_spawn2
+@POSIX_SPAWN_PORTED_TRUE@am__append_2 = test-posix_spawn1 test-posix_spawn2
+@POSIX_SPAWN_PORTED_TRUE@am__append_3 = test-posix_spawn1.sh \
+@POSIX_SPAWN_PORTED_TRUE@ test-posix_spawn2.sh
+@POSIX_SPAWN_PORTED_TRUE@am__append_4 = test-posix_spawn1.sh \
+@POSIX_SPAWN_PORTED_TRUE@ test-posix_spawn1.sh-t \
+@POSIX_SPAWN_PORTED_TRUE@ test-posix_spawn2.sh \
+@POSIX_SPAWN_PORTED_TRUE@ test-posix_spawn2.sh-t
+subdir = tests/gnu
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/ltdl/m4/00gnulib.m4 \
+ $(top_srcdir)/ltdl/m4/alloca.m4 $(top_srcdir)/ltdl/m4/argz.m4 \
+ $(top_srcdir)/ltdl/m4/assert.m4 \
+ $(top_srcdir)/ltdl/m4/autobuild.m4 \
+ $(top_srcdir)/ltdl/m4/btowc.m4 \
+ $(top_srcdir)/ltdl/m4/canonicalize.m4 \
+ $(top_srcdir)/ltdl/m4/cloexec.m4 \
+ $(top_srcdir)/ltdl/m4/close-stream.m4 \
+ $(top_srcdir)/ltdl/m4/closein.m4 \
+ $(top_srcdir)/ltdl/m4/closeout.m4 \
+ $(top_srcdir)/ltdl/m4/codeset.m4 \
+ $(top_srcdir)/ltdl/m4/config-h.m4 \
+ $(top_srcdir)/ltdl/m4/debug.m4 \
+ $(top_srcdir)/ltdl/m4/dirname.m4 $(top_srcdir)/ltdl/m4/dos.m4 \
+ $(top_srcdir)/ltdl/m4/double-slash-root.m4 \
+ $(top_srcdir)/ltdl/m4/dup2.m4 $(top_srcdir)/ltdl/m4/eealloc.m4 \
+ $(top_srcdir)/ltdl/m4/environ.m4 \
+ $(top_srcdir)/ltdl/m4/errno_h.m4 \
+ $(top_srcdir)/ltdl/m4/error.m4 \
+ $(top_srcdir)/ltdl/m4/execute.m4 \
+ $(top_srcdir)/ltdl/m4/exitfail.m4 \
+ $(top_srcdir)/ltdl/m4/exponentd.m4 \
+ $(top_srcdir)/ltdl/m4/exponentf.m4 \
+ $(top_srcdir)/ltdl/m4/exponentl.m4 \
+ $(top_srcdir)/ltdl/m4/extensions.m4 \
+ $(top_srcdir)/ltdl/m4/fatal-signal.m4 \
+ $(top_srcdir)/ltdl/m4/fcntl-o.m4 \
+ $(top_srcdir)/ltdl/m4/fcntl.m4 \
+ $(top_srcdir)/ltdl/m4/fcntl_h.m4 \
+ $(top_srcdir)/ltdl/m4/fflush.m4 \
+ $(top_srcdir)/ltdl/m4/filenamecat.m4 \
+ $(top_srcdir)/ltdl/m4/flexmember.m4 \
+ $(top_srcdir)/ltdl/m4/float_h.m4 \
+ $(top_srcdir)/ltdl/m4/fopen.m4 \
+ $(top_srcdir)/ltdl/m4/fpending.m4 \
+ $(top_srcdir)/ltdl/m4/fpieee.m4 \
+ $(top_srcdir)/ltdl/m4/fpurge.m4 \
+ $(top_srcdir)/ltdl/m4/freading.m4 \
+ $(top_srcdir)/ltdl/m4/frexp.m4 $(top_srcdir)/ltdl/m4/frexpl.m4 \
+ $(top_srcdir)/ltdl/m4/fseeko.m4 \
+ $(top_srcdir)/ltdl/m4/ftello.m4 \
+ $(top_srcdir)/ltdl/m4/getdtablesize.m4 \
+ $(top_srcdir)/ltdl/m4/getopt.m4 \
+ $(top_srcdir)/ltdl/m4/getpagesize.m4 \
+ $(top_srcdir)/ltdl/m4/gettext.m4 \
+ $(top_srcdir)/ltdl/m4/gettimeofday.m4 \
+ $(top_srcdir)/ltdl/m4/gl_list.m4 \
+ $(top_srcdir)/ltdl/m4/glibc21.m4 $(top_srcdir)/ltdl/m4/gmp.m4 \
+ $(top_srcdir)/ltdl/m4/gnulib-common.m4 \
+ $(top_srcdir)/ltdl/m4/gnulib-comp.m4 \
+ $(top_srcdir)/ltdl/m4/iconv.m4 \
+ $(top_srcdir)/ltdl/m4/iconv_h.m4 \
+ $(top_srcdir)/ltdl/m4/iconv_open.m4 \
+ $(top_srcdir)/ltdl/m4/include_next.m4 \
+ $(top_srcdir)/ltdl/m4/inline.m4 \
+ $(top_srcdir)/ltdl/m4/intlmacosx.m4 \
+ $(top_srcdir)/ltdl/m4/intmax_t.m4 \
+ $(top_srcdir)/ltdl/m4/inttypes-pri.m4 \
+ $(top_srcdir)/ltdl/m4/inttypes.m4 \
+ $(top_srcdir)/ltdl/m4/inttypes_h.m4 \
+ $(top_srcdir)/ltdl/m4/isnand.m4 \
+ $(top_srcdir)/ltdl/m4/isnanf.m4 \
+ $(top_srcdir)/ltdl/m4/isnanl.m4 \
+ $(top_srcdir)/ltdl/m4/langinfo_h.m4 \
+ $(top_srcdir)/ltdl/m4/ldexpl.m4 \
+ $(top_srcdir)/ltdl/m4/lib-ld.m4 \
+ $(top_srcdir)/ltdl/m4/lib-link.m4 \
+ $(top_srcdir)/ltdl/m4/lib-prefix.m4 \
+ $(top_srcdir)/ltdl/m4/libtool.m4 $(top_srcdir)/ltdl/m4/link.m4 \
+ $(top_srcdir)/ltdl/m4/localcharset.m4 \
+ $(top_srcdir)/ltdl/m4/locale-fr.m4 \
+ $(top_srcdir)/ltdl/m4/locale-ja.m4 \
+ $(top_srcdir)/ltdl/m4/locale-tr.m4 \
+ $(top_srcdir)/ltdl/m4/locale-zh.m4 \
+ $(top_srcdir)/ltdl/m4/longlong.m4 \
+ $(top_srcdir)/ltdl/m4/lseek.m4 $(top_srcdir)/ltdl/m4/lstat.m4 \
+ $(top_srcdir)/ltdl/m4/ltdl.m4 \
+ $(top_srcdir)/ltdl/m4/ltoptions.m4 \
+ $(top_srcdir)/ltdl/m4/ltsugar.m4 \
+ $(top_srcdir)/ltdl/m4/ltversion.m4 \
+ $(top_srcdir)/ltdl/m4/lt~obsolete.m4 \
+ $(top_srcdir)/ltdl/m4/m4-error.m4 \
+ $(top_srcdir)/ltdl/m4/m4-getopt.m4 \
+ $(top_srcdir)/ltdl/m4/m4-gettext.m4 \
+ $(top_srcdir)/ltdl/m4/m4-obstack.m4 \
+ $(top_srcdir)/ltdl/m4/m4-regex.m4 \
+ $(top_srcdir)/ltdl/m4/m4-rename.m4 \
+ $(top_srcdir)/ltdl/m4/m4-syscmd.m4 \
+ $(top_srcdir)/ltdl/m4/malloc.m4 \
+ $(top_srcdir)/ltdl/m4/malloca.m4 \
+ $(top_srcdir)/ltdl/m4/math_h.m4 \
+ $(top_srcdir)/ltdl/m4/mbchar.m4 \
+ $(top_srcdir)/ltdl/m4/mbiter.m4 \
+ $(top_srcdir)/ltdl/m4/mbrtowc.m4 \
+ $(top_srcdir)/ltdl/m4/mbsinit.m4 \
+ $(top_srcdir)/ltdl/m4/mbslen.m4 \
+ $(top_srcdir)/ltdl/m4/mbstate_t.m4 \
+ $(top_srcdir)/ltdl/m4/memchr.m4 \
+ $(top_srcdir)/ltdl/m4/memmem.m4 \
+ $(top_srcdir)/ltdl/m4/mkdtemp.m4 \
+ $(top_srcdir)/ltdl/m4/mkstemp.m4 \
+ $(top_srcdir)/ltdl/m4/mmap-anon.m4 \
+ $(top_srcdir)/ltdl/m4/mode_t.m4 \
+ $(top_srcdir)/ltdl/m4/multiarch.m4 \
+ $(top_srcdir)/ltdl/m4/nl_langinfo.m4 \
+ $(top_srcdir)/ltdl/m4/nls.m4 $(top_srcdir)/ltdl/m4/nocrash.m4 \
+ $(top_srcdir)/ltdl/m4/obstack-printf-posix.m4 \
+ $(top_srcdir)/ltdl/m4/obstack-printf.m4 \
+ $(top_srcdir)/ltdl/m4/open.m4 $(top_srcdir)/ltdl/m4/pathmax.m4 \
+ $(top_srcdir)/ltdl/m4/pipe.m4 $(top_srcdir)/ltdl/m4/pipe2.m4 \
+ $(top_srcdir)/ltdl/m4/po.m4 \
+ $(top_srcdir)/ltdl/m4/posix_spawn.m4 \
+ $(top_srcdir)/ltdl/m4/printf-frexp.m4 \
+ $(top_srcdir)/ltdl/m4/printf-frexpl.m4 \
+ $(top_srcdir)/ltdl/m4/printf.m4 \
+ $(top_srcdir)/ltdl/m4/progtest.m4 \
+ $(top_srcdir)/ltdl/m4/putenv.m4 $(top_srcdir)/ltdl/m4/quote.m4 \
+ $(top_srcdir)/ltdl/m4/quotearg.m4 \
+ $(top_srcdir)/ltdl/m4/rawmemchr.m4 \
+ $(top_srcdir)/ltdl/m4/readlink.m4 \
+ $(top_srcdir)/ltdl/m4/regex.m4 $(top_srcdir)/ltdl/m4/rename.m4 \
+ $(top_srcdir)/ltdl/m4/rmdir.m4 \
+ $(top_srcdir)/ltdl/m4/sched_h.m4 \
+ $(top_srcdir)/ltdl/m4/setenv.m4 \
+ $(top_srcdir)/ltdl/m4/sig_atomic_t.m4 \
+ $(top_srcdir)/ltdl/m4/sigaction.m4 \
+ $(top_srcdir)/ltdl/m4/signal_h.m4 \
+ $(top_srcdir)/ltdl/m4/signalblocking.m4 \
+ $(top_srcdir)/ltdl/m4/signbit.m4 \
+ $(top_srcdir)/ltdl/m4/size_max.m4 \
+ $(top_srcdir)/ltdl/m4/snprintf-posix.m4 \
+ $(top_srcdir)/ltdl/m4/snprintf.m4 \
+ $(top_srcdir)/ltdl/m4/spawn_h.m4 \
+ $(top_srcdir)/ltdl/m4/sprintf-posix.m4 \
+ $(top_srcdir)/ltdl/m4/ssize_t.m4 \
+ $(top_srcdir)/ltdl/m4/stackovf.m4 \
+ $(top_srcdir)/ltdl/m4/stat.m4 $(top_srcdir)/ltdl/m4/stdarg.m4 \
+ $(top_srcdir)/ltdl/m4/stdbool.m4 \
+ $(top_srcdir)/ltdl/m4/stddef_h.m4 \
+ $(top_srcdir)/ltdl/m4/stdint.m4 \
+ $(top_srcdir)/ltdl/m4/stdint_h.m4 \
+ $(top_srcdir)/ltdl/m4/stdio-safer.m4 \
+ $(top_srcdir)/ltdl/m4/stdio_h.m4 \
+ $(top_srcdir)/ltdl/m4/stdlib-safer.m4 \
+ $(top_srcdir)/ltdl/m4/stdlib_h.m4 \
+ $(top_srcdir)/ltdl/m4/strchrnul.m4 \
+ $(top_srcdir)/ltdl/m4/strdup.m4 \
+ $(top_srcdir)/ltdl/m4/strerror.m4 \
+ $(top_srcdir)/ltdl/m4/string_h.m4 \
+ $(top_srcdir)/ltdl/m4/strndup.m4 \
+ $(top_srcdir)/ltdl/m4/strnlen.m4 \
+ $(top_srcdir)/ltdl/m4/strtod.m4 \
+ $(top_srcdir)/ltdl/m4/strtol.m4 \
+ $(top_srcdir)/ltdl/m4/symlink.m4 \
+ $(top_srcdir)/ltdl/m4/sys_stat_h.m4 \
+ $(top_srcdir)/ltdl/m4/sys_time_h.m4 \
+ $(top_srcdir)/ltdl/m4/sys_wait_h.m4 \
+ $(top_srcdir)/ltdl/m4/tempname.m4 \
+ $(top_srcdir)/ltdl/m4/time_h.m4 \
+ $(top_srcdir)/ltdl/m4/tmpdir.m4 \
+ $(top_srcdir)/ltdl/m4/ulonglong.m4 \
+ $(top_srcdir)/ltdl/m4/ungetc.m4 \
+ $(top_srcdir)/ltdl/m4/unistd-safer.m4 \
+ $(top_srcdir)/ltdl/m4/unistd_h.m4 \
+ $(top_srcdir)/ltdl/m4/unlocked-io.m4 \
+ $(top_srcdir)/ltdl/m4/vasnprintf-posix.m4 \
+ $(top_srcdir)/ltdl/m4/vasnprintf.m4 \
+ $(top_srcdir)/ltdl/m4/vasprintf-posix.m4 \
+ $(top_srcdir)/ltdl/m4/vasprintf.m4 \
+ $(top_srcdir)/ltdl/m4/version-etc.m4 \
+ $(top_srcdir)/ltdl/m4/vfprintf-posix.m4 \
+ $(top_srcdir)/ltdl/m4/vprintf-posix.m4 \
+ $(top_srcdir)/ltdl/m4/wait-process.m4 \
+ $(top_srcdir)/ltdl/m4/warn-on-use.m4 \
+ $(top_srcdir)/ltdl/m4/wchar.m4 \
+ $(top_srcdir)/ltdl/m4/wchar_t.m4 \
+ $(top_srcdir)/ltdl/m4/wcrtomb.m4 \
+ $(top_srcdir)/ltdl/m4/wctob.m4 $(top_srcdir)/ltdl/m4/wctype.m4 \
+ $(top_srcdir)/ltdl/m4/wcwidth.m4 \
+ $(top_srcdir)/ltdl/m4/wint_t.m4 \
+ $(top_srcdir)/ltdl/m4/xalloc.m4 $(top_srcdir)/ltdl/m4/xsize.m4 \
+ $(top_srcdir)/ltdl/m4/xstrndup.m4 \
+ $(top_srcdir)/ltdl/m4/xvasprintf.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/gnu/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_$(V))
+am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY))
+am__v_AR_0 = @echo " AR " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+libtests_a_AR = $(AR) $(ARFLAGS)
+am__DEPENDENCIES_1 =
+am_libtests_a_OBJECTS = gl_array_list.$(OBJEXT) \
+ gl_array_oset.$(OBJEXT)
+libtests_a_OBJECTS = $(am_libtests_a_OBJECTS)
+@POSIX_SPAWN_PORTED_TRUE@am__EXEEXT_1 = test-posix_spawn1$(EXEEXT) \
+@POSIX_SPAWN_PORTED_TRUE@ test-posix_spawn2$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+test_alloca_opt_SOURCES = test-alloca-opt.c
+test_alloca_opt_OBJECTS = test-alloca-opt.$(OBJEXT)
+test_alloca_opt_LDADD = $(LDADD)
+test_alloca_opt_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+test_array_list_SOURCES = test-array_list.c
+test_array_list_OBJECTS = test-array_list.$(OBJEXT)
+test_array_list_LDADD = $(LDADD)
+test_array_list_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_array_oset_SOURCES = test-array_oset.c
+test_array_oset_OBJECTS = test-array_oset.$(OBJEXT)
+am__DEPENDENCIES_2 = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_array_oset_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_avltree_oset_SOURCES = test-avltree_oset.c
+test_avltree_oset_OBJECTS = test-avltree_oset.$(OBJEXT)
+test_avltree_oset_LDADD = $(LDADD)
+test_avltree_oset_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_binary_io_SOURCES = test-binary-io.c
+test_binary_io_OBJECTS = test-binary-io.$(OBJEXT)
+test_binary_io_LDADD = $(LDADD)
+test_binary_io_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_bitrotate_SOURCES = test-bitrotate.c
+test_bitrotate_OBJECTS = test-bitrotate.$(OBJEXT)
+test_bitrotate_LDADD = $(LDADD)
+test_bitrotate_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_btowc_SOURCES = test-btowc.c
+test_btowc_OBJECTS = test-btowc.$(OBJEXT)
+test_btowc_LDADD = $(LDADD)
+test_btowc_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_c_ctype_SOURCES = test-c-ctype.c
+test_c_ctype_OBJECTS = test-c-ctype.$(OBJEXT)
+test_c_ctype_LDADD = $(LDADD)
+test_c_ctype_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_c_strcasecmp_SOURCES = test-c-strcasecmp.c
+test_c_strcasecmp_OBJECTS = test-c-strcasecmp.$(OBJEXT)
+test_c_strcasecmp_LDADD = $(LDADD)
+test_c_strcasecmp_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_c_strncasecmp_SOURCES = test-c-strncasecmp.c
+test_c_strncasecmp_OBJECTS = test-c-strncasecmp.$(OBJEXT)
+test_c_strncasecmp_LDADD = $(LDADD)
+test_c_strncasecmp_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_canonicalize_lgpl_SOURCES = test-canonicalize-lgpl.c
+test_canonicalize_lgpl_OBJECTS = test-canonicalize-lgpl.$(OBJEXT)
+test_canonicalize_lgpl_LDADD = $(LDADD)
+test_canonicalize_lgpl_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_cloexec_SOURCES = test-cloexec.c
+test_cloexec_OBJECTS = test-cloexec.$(OBJEXT)
+test_cloexec_LDADD = $(LDADD)
+test_cloexec_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_closein_SOURCES = test-closein.c
+test_closein_OBJECTS = test-closein.$(OBJEXT)
+test_closein_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_dirname_SOURCES = test-dirname.c
+test_dirname_OBJECTS = test-dirname.$(OBJEXT)
+test_dirname_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_dup_safer_SOURCES = test-dup-safer.c
+test_dup_safer_OBJECTS = test-dup-safer.$(OBJEXT)
+test_dup_safer_LDADD = $(LDADD)
+test_dup_safer_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_dup2_SOURCES = test-dup2.c
+test_dup2_OBJECTS = test-dup2.$(OBJEXT)
+test_dup2_LDADD = $(LDADD)
+test_dup2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_environ_SOURCES = test-environ.c
+test_environ_OBJECTS = test-environ.$(OBJEXT)
+test_environ_LDADD = $(LDADD)
+test_environ_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_errno_SOURCES = test-errno.c
+test_errno_OBJECTS = test-errno.$(OBJEXT)
+test_errno_LDADD = $(LDADD)
+test_errno_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_fcntl_SOURCES = test-fcntl.c
+test_fcntl_OBJECTS = test-fcntl.$(OBJEXT)
+test_fcntl_LDADD = $(LDADD)
+test_fcntl_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_fcntl_h_SOURCES = test-fcntl-h.c
+test_fcntl_h_OBJECTS = test-fcntl-h.$(OBJEXT)
+test_fcntl_h_LDADD = $(LDADD)
+test_fcntl_h_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_fflush_SOURCES = test-fflush.c
+test_fflush_OBJECTS = test-fflush.$(OBJEXT)
+test_fflush_LDADD = $(LDADD)
+test_fflush_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_fflush2_SOURCES = test-fflush2.c
+test_fflush2_OBJECTS = test-fflush2.$(OBJEXT)
+test_fflush2_LDADD = $(LDADD)
+test_fflush2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_filenamecat_SOURCES = test-filenamecat.c
+test_filenamecat_OBJECTS = test-filenamecat.$(OBJEXT)
+test_filenamecat_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_fopen_SOURCES = test-fopen.c
+test_fopen_OBJECTS = test-fopen.$(OBJEXT)
+test_fopen_LDADD = $(LDADD)
+test_fopen_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_fopen_safer_SOURCES = test-fopen-safer.c
+test_fopen_safer_OBJECTS = test-fopen-safer.$(OBJEXT)
+test_fopen_safer_LDADD = $(LDADD)
+test_fopen_safer_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_fpending_SOURCES = test-fpending.c
+test_fpending_OBJECTS = test-fpending.$(OBJEXT)
+test_fpending_LDADD = $(LDADD)
+test_fpending_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_fpurge_SOURCES = test-fpurge.c
+test_fpurge_OBJECTS = test-fpurge.$(OBJEXT)
+test_fpurge_LDADD = $(LDADD)
+test_fpurge_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_freadahead_SOURCES = test-freadahead.c
+test_freadahead_OBJECTS = test-freadahead.$(OBJEXT)
+test_freadahead_LDADD = $(LDADD)
+test_freadahead_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_freading_SOURCES = test-freading.c
+test_freading_OBJECTS = test-freading.$(OBJEXT)
+test_freading_LDADD = $(LDADD)
+test_freading_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_freadptr_SOURCES = test-freadptr.c
+test_freadptr_OBJECTS = test-freadptr.$(OBJEXT)
+test_freadptr_LDADD = $(LDADD)
+test_freadptr_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_freadptr2_SOURCES = test-freadptr2.c
+test_freadptr2_OBJECTS = test-freadptr2.$(OBJEXT)
+test_freadptr2_LDADD = $(LDADD)
+test_freadptr2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_freadseek_SOURCES = test-freadseek.c
+test_freadseek_OBJECTS = test-freadseek.$(OBJEXT)
+test_freadseek_LDADD = $(LDADD)
+test_freadseek_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+am_test_frexp_nolibm_OBJECTS = test-frexp.$(OBJEXT)
+test_frexp_nolibm_OBJECTS = $(am_test_frexp_nolibm_OBJECTS)
+test_frexp_nolibm_LDADD = $(LDADD)
+test_frexp_nolibm_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+am_test_frexpl_nolibm_OBJECTS = test-frexpl.$(OBJEXT)
+test_frexpl_nolibm_OBJECTS = $(am_test_frexpl_nolibm_OBJECTS)
+test_frexpl_nolibm_LDADD = $(LDADD)
+test_frexpl_nolibm_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_fseeko_SOURCES = test-fseeko.c
+test_fseeko_OBJECTS = test-fseeko.$(OBJEXT)
+test_fseeko_LDADD = $(LDADD)
+test_fseeko_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_fseterr_SOURCES = test-fseterr.c
+test_fseterr_OBJECTS = test-fseterr.$(OBJEXT)
+test_fseterr_LDADD = $(LDADD)
+test_fseterr_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_ftello_SOURCES = test-ftello.c
+test_ftello_OBJECTS = test-ftello.$(OBJEXT)
+test_ftello_LDADD = $(LDADD)
+test_ftello_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_getdtablesize_SOURCES = test-getdtablesize.c
+test_getdtablesize_OBJECTS = test-getdtablesize.$(OBJEXT)
+test_getdtablesize_LDADD = $(LDADD)
+test_getdtablesize_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_gettimeofday_SOURCES = test-gettimeofday.c
+test_gettimeofday_OBJECTS = test-gettimeofday.$(OBJEXT)
+test_gettimeofday_LDADD = $(LDADD)
+test_gettimeofday_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_iconv_SOURCES = test-iconv.c
+test_iconv_OBJECTS = test-iconv.$(OBJEXT)
+test_iconv_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_inttypes_SOURCES = test-inttypes.c
+test_inttypes_OBJECTS = test-inttypes.$(OBJEXT)
+test_inttypes_LDADD = $(LDADD)
+test_inttypes_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_isnand_nolibm_SOURCES = test-isnand-nolibm.c
+test_isnand_nolibm_OBJECTS = test-isnand-nolibm.$(OBJEXT)
+test_isnand_nolibm_LDADD = $(LDADD)
+test_isnand_nolibm_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_isnanf_nolibm_SOURCES = test-isnanf-nolibm.c
+test_isnanf_nolibm_OBJECTS = test-isnanf-nolibm.$(OBJEXT)
+test_isnanf_nolibm_LDADD = $(LDADD)
+test_isnanf_nolibm_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_isnanl_nolibm_SOURCES = test-isnanl-nolibm.c
+test_isnanl_nolibm_OBJECTS = test-isnanl-nolibm.$(OBJEXT)
+test_isnanl_nolibm_LDADD = $(LDADD)
+test_isnanl_nolibm_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_langinfo_SOURCES = test-langinfo.c
+test_langinfo_OBJECTS = test-langinfo.$(OBJEXT)
+test_langinfo_LDADD = $(LDADD)
+test_langinfo_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_link_SOURCES = test-link.c
+test_link_OBJECTS = test-link.$(OBJEXT)
+test_link_LDADD = $(LDADD)
+test_link_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_linkedhash_list_SOURCES = test-linkedhash_list.c
+test_linkedhash_list_OBJECTS = test-linkedhash_list.$(OBJEXT)
+test_linkedhash_list_LDADD = $(LDADD)
+test_linkedhash_list_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_lseek_SOURCES = test-lseek.c
+test_lseek_OBJECTS = test-lseek.$(OBJEXT)
+test_lseek_LDADD = $(LDADD)
+test_lseek_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_lstat_SOURCES = test-lstat.c
+test_lstat_OBJECTS = test-lstat.$(OBJEXT)
+test_lstat_LDADD = $(LDADD)
+test_lstat_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_malloca_SOURCES = test-malloca.c
+test_malloca_OBJECTS = test-malloca.$(OBJEXT)
+test_malloca_LDADD = $(LDADD)
+test_malloca_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_math_SOURCES = test-math.c
+test_math_OBJECTS = test-math.$(OBJEXT)
+test_math_LDADD = $(LDADD)
+test_math_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_mbrtowc_SOURCES = test-mbrtowc.c
+test_mbrtowc_OBJECTS = test-mbrtowc.$(OBJEXT)
+test_mbrtowc_LDADD = $(LDADD)
+test_mbrtowc_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_mbsinit_SOURCES = test-mbsinit.c
+test_mbsinit_OBJECTS = test-mbsinit.$(OBJEXT)
+test_mbsinit_LDADD = $(LDADD)
+test_mbsinit_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_mbsstr1_SOURCES = test-mbsstr1.c
+test_mbsstr1_OBJECTS = test-mbsstr1.$(OBJEXT)
+test_mbsstr1_LDADD = $(LDADD)
+test_mbsstr1_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_mbsstr2_SOURCES = test-mbsstr2.c
+test_mbsstr2_OBJECTS = test-mbsstr2.$(OBJEXT)
+test_mbsstr2_LDADD = $(LDADD)
+test_mbsstr2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_mbsstr3_SOURCES = test-mbsstr3.c
+test_mbsstr3_OBJECTS = test-mbsstr3.$(OBJEXT)
+test_mbsstr3_LDADD = $(LDADD)
+test_mbsstr3_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_memchr_SOURCES = test-memchr.c
+test_memchr_OBJECTS = test-memchr.$(OBJEXT)
+test_memchr_LDADD = $(LDADD)
+test_memchr_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_memchr2_SOURCES = test-memchr2.c
+test_memchr2_OBJECTS = test-memchr2.$(OBJEXT)
+test_memchr2_LDADD = $(LDADD)
+test_memchr2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_memmem_SOURCES = test-memmem.c
+test_memmem_OBJECTS = test-memmem.$(OBJEXT)
+test_memmem_LDADD = $(LDADD)
+test_memmem_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_nl_langinfo_SOURCES = test-nl_langinfo.c
+test_nl_langinfo_OBJECTS = test-nl_langinfo.$(OBJEXT)
+test_nl_langinfo_LDADD = $(LDADD)
+test_nl_langinfo_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_obstack_printf_SOURCES = test-obstack-printf.c
+test_obstack_printf_OBJECTS = test-obstack-printf.$(OBJEXT)
+test_obstack_printf_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_open_SOURCES = test-open.c
+test_open_OBJECTS = test-open.$(OBJEXT)
+test_open_LDADD = $(LDADD)
+test_open_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_pipe_SOURCES = test-pipe.c
+test_pipe_OBJECTS = test-pipe.$(OBJEXT)
+test_pipe_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_pipe2_SOURCES = test-pipe2.c
+test_pipe2_OBJECTS = test-pipe2.$(OBJEXT)
+test_pipe2_LDADD = $(LDADD)
+test_pipe2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_posix_spawn1_SOURCES = test-posix_spawn1.c
+test_posix_spawn1_OBJECTS = test-posix_spawn1.$(OBJEXT)
+test_posix_spawn1_LDADD = $(LDADD)
+test_posix_spawn1_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_posix_spawn2_SOURCES = test-posix_spawn2.c
+test_posix_spawn2_OBJECTS = test-posix_spawn2.$(OBJEXT)
+test_posix_spawn2_LDADD = $(LDADD)
+test_posix_spawn2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_printf_frexp_SOURCES = test-printf-frexp.c
+test_printf_frexp_OBJECTS = test-printf-frexp.$(OBJEXT)
+test_printf_frexp_LDADD = $(LDADD)
+test_printf_frexp_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_printf_frexpl_SOURCES = test-printf-frexpl.c
+test_printf_frexpl_OBJECTS = test-printf-frexpl.$(OBJEXT)
+test_printf_frexpl_LDADD = $(LDADD)
+test_printf_frexpl_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_quotearg_SOURCES = test-quotearg.c
+test_quotearg_OBJECTS = test-quotearg.$(OBJEXT)
+test_quotearg_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_rawmemchr_SOURCES = test-rawmemchr.c
+test_rawmemchr_OBJECTS = test-rawmemchr.$(OBJEXT)
+test_rawmemchr_LDADD = $(LDADD)
+test_rawmemchr_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_readlink_SOURCES = test-readlink.c
+test_readlink_OBJECTS = test-readlink.$(OBJEXT)
+test_readlink_LDADD = $(LDADD)
+test_readlink_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_rename_SOURCES = test-rename.c
+test_rename_OBJECTS = test-rename.$(OBJEXT)
+test_rename_LDADD = $(LDADD)
+test_rename_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_rmdir_SOURCES = test-rmdir.c
+test_rmdir_OBJECTS = test-rmdir.$(OBJEXT)
+test_rmdir_LDADD = $(LDADD)
+test_rmdir_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_sched_SOURCES = test-sched.c
+test_sched_OBJECTS = test-sched.$(OBJEXT)
+test_sched_LDADD = $(LDADD)
+test_sched_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_setenv_SOURCES = test-setenv.c
+test_setenv_OBJECTS = test-setenv.$(OBJEXT)
+test_setenv_LDADD = $(LDADD)
+test_setenv_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_sigaction_SOURCES = test-sigaction.c
+test_sigaction_OBJECTS = test-sigaction.$(OBJEXT)
+test_sigaction_LDADD = $(LDADD)
+test_sigaction_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_signal_SOURCES = test-signal.c
+test_signal_OBJECTS = test-signal.$(OBJEXT)
+test_signal_LDADD = $(LDADD)
+test_signal_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_signbit_SOURCES = test-signbit.c
+test_signbit_OBJECTS = test-signbit.$(OBJEXT)
+test_signbit_LDADD = $(LDADD)
+test_signbit_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_snprintf_SOURCES = test-snprintf.c
+test_snprintf_OBJECTS = test-snprintf.$(OBJEXT)
+test_snprintf_LDADD = $(LDADD)
+test_snprintf_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_snprintf_posix_SOURCES = test-snprintf-posix.c
+test_snprintf_posix_OBJECTS = test-snprintf-posix.$(OBJEXT)
+test_snprintf_posix_LDADD = $(LDADD)
+test_snprintf_posix_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_spawn_SOURCES = test-spawn.c
+test_spawn_OBJECTS = test-spawn.$(OBJEXT)
+test_spawn_LDADD = $(LDADD)
+test_spawn_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_sprintf_posix_SOURCES = test-sprintf-posix.c
+test_sprintf_posix_OBJECTS = test-sprintf-posix.$(OBJEXT)
+test_sprintf_posix_LDADD = $(LDADD)
+test_sprintf_posix_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_stat_SOURCES = test-stat.c
+test_stat_OBJECTS = test-stat.$(OBJEXT)
+test_stat_LDADD = $(LDADD)
+test_stat_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_stdbool_SOURCES = test-stdbool.c
+test_stdbool_OBJECTS = test-stdbool.$(OBJEXT)
+test_stdbool_LDADD = $(LDADD)
+test_stdbool_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_stddef_SOURCES = test-stddef.c
+test_stddef_OBJECTS = test-stddef.$(OBJEXT)
+test_stddef_LDADD = $(LDADD)
+test_stddef_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_stdint_SOURCES = test-stdint.c
+test_stdint_OBJECTS = test-stdint.$(OBJEXT)
+test_stdint_LDADD = $(LDADD)
+test_stdint_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_stdio_SOURCES = test-stdio.c
+test_stdio_OBJECTS = test-stdio.$(OBJEXT)
+test_stdio_LDADD = $(LDADD)
+test_stdio_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_stdlib_SOURCES = test-stdlib.c
+test_stdlib_OBJECTS = test-stdlib.$(OBJEXT)
+test_stdlib_LDADD = $(LDADD)
+test_stdlib_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_strchrnul_SOURCES = test-strchrnul.c
+test_strchrnul_OBJECTS = test-strchrnul.$(OBJEXT)
+test_strchrnul_LDADD = $(LDADD)
+test_strchrnul_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_strerror_SOURCES = test-strerror.c
+test_strerror_OBJECTS = test-strerror.$(OBJEXT)
+test_strerror_LDADD = $(LDADD)
+test_strerror_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_striconv_SOURCES = test-striconv.c
+test_striconv_OBJECTS = test-striconv.$(OBJEXT)
+test_striconv_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_string_SOURCES = test-string.c
+test_string_OBJECTS = test-string.$(OBJEXT)
+test_string_LDADD = $(LDADD)
+test_string_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_strtod_SOURCES = test-strtod.c
+test_strtod_OBJECTS = test-strtod.$(OBJEXT)
+test_strtod_LDADD = $(LDADD)
+test_strtod_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_symlink_SOURCES = test-symlink.c
+test_symlink_OBJECTS = test-symlink.$(OBJEXT)
+test_symlink_LDADD = $(LDADD)
+test_symlink_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_sys_stat_SOURCES = test-sys_stat.c
+test_sys_stat_OBJECTS = test-sys_stat.$(OBJEXT)
+test_sys_stat_LDADD = $(LDADD)
+test_sys_stat_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_sys_time_SOURCES = test-sys_time.c
+test_sys_time_OBJECTS = test-sys_time.$(OBJEXT)
+test_sys_time_LDADD = $(LDADD)
+test_sys_time_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_sys_wait_SOURCES = test-sys_wait.c
+test_sys_wait_OBJECTS = test-sys_wait.$(OBJEXT)
+test_sys_wait_LDADD = $(LDADD)
+test_sys_wait_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_time_SOURCES = test-time.c
+test_time_OBJECTS = test-time.$(OBJEXT)
+test_time_LDADD = $(LDADD)
+test_time_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_test_uc_width_OBJECTS = uniwidth/test-uc_width.$(OBJEXT)
+test_uc_width_OBJECTS = $(am_test_uc_width_OBJECTS)
+test_uc_width_LDADD = $(LDADD)
+test_uc_width_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+am_test_uc_width2_OBJECTS = uniwidth/test-uc_width2.$(OBJEXT)
+test_uc_width2_OBJECTS = $(am_test_uc_width2_OBJECTS)
+test_uc_width2_LDADD = $(LDADD)
+test_uc_width2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_unistd_SOURCES = test-unistd.c
+test_unistd_OBJECTS = test-unistd.$(OBJEXT)
+test_unistd_LDADD = $(LDADD)
+test_unistd_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_unsetenv_SOURCES = test-unsetenv.c
+test_unsetenv_OBJECTS = test-unsetenv.$(OBJEXT)
+test_unsetenv_LDADD = $(LDADD)
+test_unsetenv_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_vasnprintf_SOURCES = test-vasnprintf.c
+test_vasnprintf_OBJECTS = test-vasnprintf.$(OBJEXT)
+test_vasnprintf_LDADD = $(LDADD)
+test_vasnprintf_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_vasnprintf_posix_SOURCES = test-vasnprintf-posix.c
+test_vasnprintf_posix_OBJECTS = test-vasnprintf-posix.$(OBJEXT)
+test_vasnprintf_posix_LDADD = $(LDADD)
+test_vasnprintf_posix_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_vasnprintf_posix2_SOURCES = test-vasnprintf-posix2.c
+test_vasnprintf_posix2_OBJECTS = test-vasnprintf-posix2.$(OBJEXT)
+test_vasnprintf_posix2_LDADD = $(LDADD)
+test_vasnprintf_posix2_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_vasprintf_SOURCES = test-vasprintf.c
+test_vasprintf_OBJECTS = test-vasprintf.$(OBJEXT)
+test_vasprintf_LDADD = $(LDADD)
+test_vasprintf_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_vasprintf_posix_SOURCES = test-vasprintf-posix.c
+test_vasprintf_posix_OBJECTS = test-vasprintf-posix.$(OBJEXT)
+test_vasprintf_posix_LDADD = $(LDADD)
+test_vasprintf_posix_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_vfprintf_posix_SOURCES = test-vfprintf-posix.c
+test_vfprintf_posix_OBJECTS = test-vfprintf-posix.$(OBJEXT)
+test_vfprintf_posix_LDADD = $(LDADD)
+test_vfprintf_posix_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_vprintf_posix_SOURCES = test-vprintf-posix.c
+test_vprintf_posix_OBJECTS = test-vprintf-posix.$(OBJEXT)
+test_vprintf_posix_LDADD = $(LDADD)
+test_vprintf_posix_DEPENDENCIES = libtests.a ../../gnu/libgnu.la \
+ libtests.a $(am__DEPENDENCIES_1)
+test_wchar_SOURCES = test-wchar.c
+test_wchar_OBJECTS = test-wchar.$(OBJEXT)
+test_wchar_LDADD = $(LDADD)
+test_wchar_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_wcrtomb_SOURCES = test-wcrtomb.c
+test_wcrtomb_OBJECTS = test-wcrtomb.$(OBJEXT)
+test_wcrtomb_LDADD = $(LDADD)
+test_wcrtomb_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_wctype_SOURCES = test-wctype.c
+test_wctype_OBJECTS = test-wctype.$(OBJEXT)
+test_wctype_LDADD = $(LDADD)
+test_wctype_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_wcwidth_SOURCES = test-wcwidth.c
+test_wcwidth_OBJECTS = test-wcwidth.$(OBJEXT)
+test_wcwidth_LDADD = $(LDADD)
+test_wcwidth_DEPENDENCIES = libtests.a ../../gnu/libgnu.la libtests.a \
+ $(am__DEPENDENCIES_1)
+test_xalloc_die_SOURCES = test-xalloc-die.c
+test_xalloc_die_OBJECTS = test-xalloc-die.$(OBJEXT)
+test_xalloc_die_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_xfprintf_posix_SOURCES = test-xfprintf-posix.c
+test_xfprintf_posix_OBJECTS = test-xfprintf-posix.$(OBJEXT)
+test_xfprintf_posix_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_xmemdup0_SOURCES = test-xmemdup0.c
+test_xmemdup0_OBJECTS = test-xmemdup0.$(OBJEXT)
+test_xmemdup0_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_xprintf_posix_SOURCES = test-xprintf-posix.c
+test_xprintf_posix_OBJECTS = test-xprintf-posix.$(OBJEXT)
+test_xprintf_posix_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_xvasprintf_SOURCES = test-xvasprintf.c
+test_xvasprintf_OBJECTS = test-xvasprintf.$(OBJEXT)
+test_xvasprintf_DEPENDENCIES = $(am__DEPENDENCIES_2)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/gnu
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libtests_a_SOURCES) $(EXTRA_libtests_a_SOURCES) \
+ test-alloca-opt.c test-array_list.c test-array_oset.c \
+ test-avltree_oset.c test-binary-io.c test-bitrotate.c \
+ test-btowc.c test-c-ctype.c test-c-strcasecmp.c \
+ test-c-strncasecmp.c test-canonicalize-lgpl.c test-cloexec.c \
+ test-closein.c test-dirname.c test-dup-safer.c test-dup2.c \
+ test-environ.c test-errno.c test-fcntl.c test-fcntl-h.c \
+ test-fflush.c test-fflush2.c test-filenamecat.c test-fopen.c \
+ test-fopen-safer.c test-fpending.c test-fpurge.c \
+ test-freadahead.c test-freading.c test-freadptr.c \
+ test-freadptr2.c test-freadseek.c $(test_frexp_nolibm_SOURCES) \
+ $(test_frexpl_nolibm_SOURCES) test-fseeko.c test-fseterr.c \
+ test-ftello.c test-getdtablesize.c test-gettimeofday.c \
+ test-iconv.c test-inttypes.c test-isnand-nolibm.c \
+ test-isnanf-nolibm.c test-isnanl-nolibm.c test-langinfo.c \
+ test-link.c test-linkedhash_list.c test-lseek.c test-lstat.c \
+ test-malloca.c test-math.c test-mbrtowc.c test-mbsinit.c \
+ test-mbsstr1.c test-mbsstr2.c test-mbsstr3.c test-memchr.c \
+ test-memchr2.c test-memmem.c test-nl_langinfo.c \
+ test-obstack-printf.c test-open.c test-pipe.c test-pipe2.c \
+ test-posix_spawn1.c test-posix_spawn2.c test-printf-frexp.c \
+ test-printf-frexpl.c test-quotearg.c test-rawmemchr.c \
+ test-readlink.c test-rename.c test-rmdir.c test-sched.c \
+ test-setenv.c test-sigaction.c test-signal.c test-signbit.c \
+ test-snprintf.c test-snprintf-posix.c test-spawn.c \
+ test-sprintf-posix.c test-stat.c test-stdbool.c test-stddef.c \
+ test-stdint.c test-stdio.c test-stdlib.c test-strchrnul.c \
+ test-strerror.c test-striconv.c test-string.c test-strtod.c \
+ test-symlink.c test-sys_stat.c test-sys_time.c test-sys_wait.c \
+ test-time.c $(test_uc_width_SOURCES) $(test_uc_width2_SOURCES) \
+ test-unistd.c test-unsetenv.c test-vasnprintf.c \
+ test-vasnprintf-posix.c test-vasnprintf-posix2.c \
+ test-vasprintf.c test-vasprintf-posix.c test-vfprintf-posix.c \
+ test-vprintf-posix.c test-wchar.c test-wcrtomb.c test-wctype.c \
+ test-wcwidth.c test-xalloc-die.c test-xfprintf-posix.c \
+ test-xmemdup0.c test-xprintf-posix.c test-xvasprintf.c
+DIST_SOURCES = $(libtests_a_SOURCES) $(EXTRA_libtests_a_SOURCES) \
+ test-alloca-opt.c test-array_list.c test-array_oset.c \
+ test-avltree_oset.c test-binary-io.c test-bitrotate.c \
+ test-btowc.c test-c-ctype.c test-c-strcasecmp.c \
+ test-c-strncasecmp.c test-canonicalize-lgpl.c test-cloexec.c \
+ test-closein.c test-dirname.c test-dup-safer.c test-dup2.c \
+ test-environ.c test-errno.c test-fcntl.c test-fcntl-h.c \
+ test-fflush.c test-fflush2.c test-filenamecat.c test-fopen.c \
+ test-fopen-safer.c test-fpending.c test-fpurge.c \
+ test-freadahead.c test-freading.c test-freadptr.c \
+ test-freadptr2.c test-freadseek.c $(test_frexp_nolibm_SOURCES) \
+ $(test_frexpl_nolibm_SOURCES) test-fseeko.c test-fseterr.c \
+ test-ftello.c test-getdtablesize.c test-gettimeofday.c \
+ test-iconv.c test-inttypes.c test-isnand-nolibm.c \
+ test-isnanf-nolibm.c test-isnanl-nolibm.c test-langinfo.c \
+ test-link.c test-linkedhash_list.c test-lseek.c test-lstat.c \
+ test-malloca.c test-math.c test-mbrtowc.c test-mbsinit.c \
+ test-mbsstr1.c test-mbsstr2.c test-mbsstr3.c test-memchr.c \
+ test-memchr2.c test-memmem.c test-nl_langinfo.c \
+ test-obstack-printf.c test-open.c test-pipe.c test-pipe2.c \
+ test-posix_spawn1.c test-posix_spawn2.c test-printf-frexp.c \
+ test-printf-frexpl.c test-quotearg.c test-rawmemchr.c \
+ test-readlink.c test-rename.c test-rmdir.c test-sched.c \
+ test-setenv.c test-sigaction.c test-signal.c test-signbit.c \
+ test-snprintf.c test-snprintf-posix.c test-spawn.c \
+ test-sprintf-posix.c test-stat.c test-stdbool.c test-stddef.c \
+ test-stdint.c test-stdio.c test-stdlib.c test-strchrnul.c \
+ test-strerror.c test-striconv.c test-string.c test-strtod.c \
+ test-symlink.c test-sys_stat.c test-sys_time.c test-sys_wait.c \
+ test-time.c $(test_uc_width_SOURCES) $(test_uc_width2_SOURCES) \
+ test-unistd.c test-unsetenv.c test-vasnprintf.c \
+ test-vasnprintf-posix.c test-vasnprintf-posix2.c \
+ test-vasprintf.c test-vasprintf-posix.c test-vfprintf-posix.c \
+ test-vprintf-posix.c test-wchar.c test-wcrtomb.c test-wctype.c \
+ test-wcwidth.c test-xalloc-die.c test-xfprintf-posix.c \
+ test-xmemdup0.c test-xprintf-posix.c test-xvasprintf.c
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+HEADERS = $(noinst_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ check check-html recheck recheck-html distdir
+ETAGS = etags
+CTAGS = ctags
+# If stdout is a non-dumb tty, use colors. If test -t is not supported,
+# then this fails; a conservative approach. Of course do not redirect
+# stdout here, just stderr.
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=; \
+test "X$(AM_COLOR_TESTS)" != Xno \
+&& test "X$$TERM" != Xdumb \
+&& { test "X$(AM_COLOR_TESTS)" = Xalways || test -t 1 2>/dev/null; } \
+&& { \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ std=''; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+# Restructured Text title and section.
+am__rst_title = sed 's/.*/ & /;h;s/./=/g;p;x;p;g;p;s/.*//'
+am__rst_section = sed 'p;s/./=/g;p;g'
+# Put stdin (possibly several lines separated by ". ") in a box.
+am__text_box = $(AWK) '{ \
+ n = split($$0, lines, "\\. "); max = 0; \
+ for (i = 1; i <= n; ++i) \
+ if (max < length(lines[i])) \
+ max = length(lines[i]); \
+ for (i = 0; i < max; ++i) line = line "="; \
+ print line; \
+ for (i = 1; i <= n; ++i) if (lines[i]) print lines[i];\
+ print line; \
+}'
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL). This contradicts POSIX. Work around the problem
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log, and passes
+# TESTS_ENVIRONMENT. Save and restore TERM around use of
+# TESTS_ENVIRONMENT, in case that unsets it.
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+srcdir=$(srcdir); export srcdir; \
+rm -f $@-t; \
+trap 'st=$$?; rm -f '\''$(abs_builddir)/$@-t'\''; (exit $$st); exit $$st' \
+ 1 2 13 15; \
+am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`; \
+test "x$$am__odir" = x. || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; __SAVED_TERM=$$TERM; \
+$(TESTS_ENVIRONMENT)
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_SUITE_HTML = $(TEST_SUITE_LOG:.log=.html)
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+TEST_LOGS_TMP = $(TEST_LOGS:.log=.log-t)
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+ARGZ_H = @ARGZ_H@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONFIG_INCLUDE = @CONFIG_INCLUDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DLPREOPEN = @DLPREOPEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DYNAMIC_MODULES = @DYNAMIC_MODULES@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
+EMULTIHOP_VALUE = @EMULTIHOP_VALUE@
+ENOLINK_HIDDEN = @ENOLINK_HIDDEN@
+ENOLINK_VALUE = @ENOLINK_VALUE@
+EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ERRNO_H = @ERRNO_H@
+ERROR_H = @ERROR_H@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FLOAT_H = @FLOAT_H@
+GETOPT_H = @GETOPT_H@
+GETTEXT_H = @GETTEXT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIB_ACOSL = @GNULIB_ACOSL@
+GNULIB_ASINL = @GNULIB_ASINL@
+GNULIB_ATANL = @GNULIB_ATANL@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CEILF = @GNULIB_CEILF@
+GNULIB_CEILL = @GNULIB_CEILL@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_COSL = @GNULIB_COSL@
+GNULIB_DPRINTF = @GNULIB_DPRINTF@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_EXPL = @GNULIB_EXPL@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FCNTL = @GNULIB_FCNTL@
+GNULIB_FFLUSH = @GNULIB_FFLUSH@
+GNULIB_FLOORF = @GNULIB_FLOORF@
+GNULIB_FLOORL = @GNULIB_FLOORL@
+GNULIB_FOPEN = @GNULIB_FOPEN@
+GNULIB_FPRINTF = @GNULIB_FPRINTF@
+GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
+GNULIB_FPURGE = @GNULIB_FPURGE@
+GNULIB_FPUTC = @GNULIB_FPUTC@
+GNULIB_FPUTS = @GNULIB_FPUTS@
+GNULIB_FREOPEN = @GNULIB_FREOPEN@
+GNULIB_FREXP = @GNULIB_FREXP@
+GNULIB_FREXPL = @GNULIB_FREXPL@
+GNULIB_FSEEK = @GNULIB_FSEEK@
+GNULIB_FSEEKO = @GNULIB_FSEEKO@
+GNULIB_FSTATAT = @GNULIB_FSTATAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTELL = @GNULIB_FTELL@
+GNULIB_FTELLO = @GNULIB_FTELLO@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_FUTIMENS = @GNULIB_FUTIMENS@
+GNULIB_FWRITE = @GNULIB_FWRITE@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDELIM = @GNULIB_GETDELIM@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLINE = @GNULIB_GETLINE@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_IMAXABS = @GNULIB_IMAXABS@
+GNULIB_IMAXDIV = @GNULIB_IMAXDIV@
+GNULIB_ISFINITE = @GNULIB_ISFINITE@
+GNULIB_ISINF = @GNULIB_ISINF@
+GNULIB_ISNAN = @GNULIB_ISNAN@
+GNULIB_ISNAND = @GNULIB_ISNAND@
+GNULIB_ISNANF = @GNULIB_ISNANF@
+GNULIB_ISNANL = @GNULIB_ISNANL@
+GNULIB_LCHMOD = @GNULIB_LCHMOD@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LDEXPL = @GNULIB_LDEXPL@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LOGL = @GNULIB_LOGL@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_LSTAT = @GNULIB_LSTAT@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
+GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
+GNULIB_MBSCHR = @GNULIB_MBSCHR@
+GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSLEN = @GNULIB_MBSLEN@
+GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
+GNULIB_MBSNLEN = @GNULIB_MBSNLEN@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
+GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
+GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MBSSEP = @GNULIB_MBSSEP@
+GNULIB_MBSSPN = @GNULIB_MBSSPN@
+GNULIB_MBSSTR = @GNULIB_MBSSTR@
+GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
+GNULIB_MEMCHR = @GNULIB_MEMCHR@
+GNULIB_MEMMEM = @GNULIB_MEMMEM@
+GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
+GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
+GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKFIFO = @GNULIB_MKFIFO@
+GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@
+GNULIB_MKNOD = @GNULIB_MKNOD@
+GNULIB_MKNODAT = @GNULIB_MKNODAT@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
+GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_OPEN = @GNULIB_OPEN@
+GNULIB_OPENAT = @GNULIB_OPENAT@
+GNULIB_PERROR = @GNULIB_PERROR@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_POPEN = @GNULIB_POPEN@
+GNULIB_POSIX_SPAWN = @GNULIB_POSIX_SPAWN@
+GNULIB_POSIX_SPAWNATTR_DESTROY = @GNULIB_POSIX_SPAWNATTR_DESTROY@
+GNULIB_POSIX_SPAWNATTR_GETFLAGS = @GNULIB_POSIX_SPAWNATTR_GETFLAGS@
+GNULIB_POSIX_SPAWNATTR_GETPGROUP = @GNULIB_POSIX_SPAWNATTR_GETPGROUP@
+GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM = @GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM@
+GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY = @GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY@
+GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT = @GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT@
+GNULIB_POSIX_SPAWNATTR_GETSIGMASK = @GNULIB_POSIX_SPAWNATTR_GETSIGMASK@
+GNULIB_POSIX_SPAWNATTR_INIT = @GNULIB_POSIX_SPAWNATTR_INIT@
+GNULIB_POSIX_SPAWNATTR_SETFLAGS = @GNULIB_POSIX_SPAWNATTR_SETFLAGS@
+GNULIB_POSIX_SPAWNATTR_SETPGROUP = @GNULIB_POSIX_SPAWNATTR_SETPGROUP@
+GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM = @GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM@
+GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY = @GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY@
+GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT = @GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT@
+GNULIB_POSIX_SPAWNATTR_SETSIGMASK = @GNULIB_POSIX_SPAWNATTR_SETSIGMASK@
+GNULIB_POSIX_SPAWNP = @GNULIB_POSIX_SPAWNP@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PRINTF = @GNULIB_PRINTF@
+GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_REMOVE = @GNULIB_REMOVE@
+GNULIB_RENAME = @GNULIB_RENAME@
+GNULIB_RENAMEAT = @GNULIB_RENAMEAT@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_ROUND = @GNULIB_ROUND@
+GNULIB_ROUNDF = @GNULIB_ROUNDF@
+GNULIB_ROUNDL = @GNULIB_ROUNDL@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SIGACTION = @GNULIB_SIGACTION@
+GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
+GNULIB_SIGNBIT = @GNULIB_SIGNBIT@
+GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
+GNULIB_SINL = @GNULIB_SINL@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
+GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
+GNULIB_SQRTL = @GNULIB_SQRTL@
+GNULIB_STAT = @GNULIB_STAT@
+GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@
+GNULIB_STPCPY = @GNULIB_STPCPY@
+GNULIB_STPNCPY = @GNULIB_STPNCPY@
+GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
+GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
+GNULIB_STRDUP = @GNULIB_STRDUP@
+GNULIB_STRERROR = @GNULIB_STRERROR@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_TANL = @GNULIB_TANL@
+GNULIB_TRUNC = @GNULIB_TRUNC@
+GNULIB_TRUNCF = @GNULIB_TRUNCF@
+GNULIB_TRUNCL = @GNULIB_TRUNCL@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@
+GNULIB_VASPRINTF = @GNULIB_VASPRINTF@
+GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
+GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
+GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
+GNULIB_VPRINTF = @GNULIB_VPRINTF@
+GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
+GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
+GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WRITE = @GNULIB_WRITE@
+GREP = @GREP@
+HAVE_ACOSL = @HAVE_ACOSL@
+HAVE_ASINL = @HAVE_ASINL@
+HAVE_ATANL = @HAVE_ATANL@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CALLOC_POSIX = @HAVE_CALLOC_POSIX@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_COSL = @HAVE_COSL@
+HAVE_DECL_ACOSL = @HAVE_DECL_ACOSL@
+HAVE_DECL_ASINL = @HAVE_DECL_ASINL@
+HAVE_DECL_ATANL = @HAVE_DECL_ATANL@
+HAVE_DECL_COSL = @HAVE_DECL_COSL@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_EXPL = @HAVE_DECL_EXPL@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_FREXPL = @HAVE_DECL_FREXPL@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@
+HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@
+HAVE_DECL_LDEXPL = @HAVE_DECL_LDEXPL@
+HAVE_DECL_LOGL = @HAVE_DECL_LOGL@
+HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_SINL = @HAVE_DECL_SINL@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_SQRTL = @HAVE_DECL_SQRTL@
+HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@
+HAVE_DECL_STRERROR = @HAVE_DECL_STRERROR@
+HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@
+HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@
+HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@
+HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@
+HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@
+HAVE_DECL_TANL = @HAVE_DECL_TANL@
+HAVE_DECL_TRUNC = @HAVE_DECL_TRUNC@
+HAVE_DECL_TRUNCF = @HAVE_DECL_TRUNCF@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXPL = @HAVE_EXPL@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHMODAT = @HAVE_FCHMODAT@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FCNTL = @HAVE_FCNTL@
+HAVE_FSTATAT = @HAVE_FSTATAT@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_FUTIMENS = @HAVE_FUTIMENS@
+HAVE_GETDOMAINNAME = @HAVE_GETDOMAINNAME@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETOPT_H = @HAVE_GETOPT_H@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@
+HAVE_GETUSERSHELL = @HAVE_GETUSERSHELL@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISNAND = @HAVE_ISNAND@
+HAVE_ISNANF = @HAVE_ISNANF@
+HAVE_ISNANL = @HAVE_ISNANL@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LOGL = @HAVE_LOGL@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_LSTAT = @HAVE_LSTAT@
+HAVE_MALLOC_POSIX = @HAVE_MALLOC_POSIX@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MEMPCPY = @HAVE_MEMPCPY@
+HAVE_MKDIRAT = @HAVE_MKDIRAT@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKFIFO = @HAVE_MKFIFO@
+HAVE_MKFIFOAT = @HAVE_MKFIFOAT@
+HAVE_MKNOD = @HAVE_MKNOD@
+HAVE_MKNODAT = @HAVE_MKNODAT@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@
+HAVE_POSIX_SPAWN = @HAVE_POSIX_SPAWN@
+HAVE_POSIX_SPAWNATTR_T = @HAVE_POSIX_SPAWNATTR_T@
+HAVE_POSIX_SPAWN_FILE_ACTIONS_T = @HAVE_POSIX_SPAWN_FILE_ACTIONS_T@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALLOC_POSIX = @HAVE_REALLOC_POSIX@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SCHED_H = @HAVE_SCHED_H@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SIGACTION = @HAVE_SIGACTION@
+HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SIGSET_T = @HAVE_SIGSET_T@
+HAVE_SINL = @HAVE_SINL@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_SPAWN_H = @HAVE_SPAWN_H@
+HAVE_SQRTL = @HAVE_SQRTL@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STPCPY = @HAVE_STPCPY@
+HAVE_STPNCPY = @HAVE_STPNCPY@
+HAVE_STRCASESTR = @HAVE_STRCASESTR@
+HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRUCT_SCHED_PARAM = @HAVE_STRUCT_SCHED_PARAM@
+HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
+HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@
+HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_TANL = @HAVE_TANL@
+HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNSETENV = @HAVE_UNSETENV@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE__BOOL = @HAVE__BOOL@
+ICONV_H = @ICONV_H@
+INCLTDL = @INCLTDL@
+INCLUDE_ERROR_H = @INCLUDE_ERROR_H@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INCLUDE_OBSTACK_H = @INCLUDE_OBSTACK_H@
+INCLUDE_REGEX_H = @INCLUDE_REGEX_H@
+INCLUDE_STDBOOL_H = @INCLUDE_STDBOOL_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@
+INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_GMP = @LIBADD_GMP@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBLTDL = @LIBLTDL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@ $(POW_LIB)
+LIBTESTS_LIBDEPS = @LIBTESTS_LIBDEPS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_TR_UTF8 = @LOCALE_TR_UTF8@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTALLOCA = @LTALLOCA@
+LTDLDEPS = @LTDLDEPS@
+LTDLINCL = @LTDLINCL@
+LTDLOPEN = @LTDLOPEN@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_CONFIG_H = @LT_CONFIG_H@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
+M4_LIBOBJS = @M4_LIBOBJS@
+M4_LTLIBOBJS = @M4_LTLIBOBJS@
+M4tests_LIBOBJS = @M4tests_LIBOBJS@
+M4tests_LTLIBOBJS = @M4tests_LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@
+NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
+NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
+NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
+NEXT_AS_FIRST_DIRECTIVE_ICONV_H = @NEXT_AS_FIRST_DIRECTIVE_ICONV_H@
+NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_MATH_H = @NEXT_AS_FIRST_DIRECTIVE_MATH_H@
+NEXT_AS_FIRST_DIRECTIVE_SCHED_H = @NEXT_AS_FIRST_DIRECTIVE_SCHED_H@
+NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
+NEXT_AS_FIRST_DIRECTIVE_SPAWN_H = @NEXT_AS_FIRST_DIRECTIVE_SPAWN_H@
+NEXT_AS_FIRST_DIRECTIVE_STDARG_H = @NEXT_AS_FIRST_DIRECTIVE_STDARG_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@
+NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_ICONV_H = @NEXT_ICONV_H@
+NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_MATH_H = @NEXT_MATH_H@
+NEXT_SCHED_H = @NEXT_SCHED_H@
+NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
+NEXT_SPAWN_H = @NEXT_SPAWN_H@
+NEXT_STDARG_H = @NEXT_STDARG_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDIO_H = @NEXT_STDIO_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_STRING_H = @NEXT_STRING_H@
+NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@
+NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@
+NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@
+NEXT_TIME_H = @NEXT_TIME_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OBSTACK_H = @OBSTACK_H@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+POSUB = @POSUB@
+POW_LIB = @POW_LIB@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PREOPEN_DEPENDENCIES = @PREOPEN_DEPENDENCIES@
+PRIPTR_PREFIX = @PRIPTR_PREFIX@
+PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REGEX_H = @REGEX_H@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CEILF = @REPLACE_CEILF@
+REPLACE_CEILL = @REPLACE_CEILL@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHDIR = @REPLACE_FCHDIR@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FLOORF = @REPLACE_FLOORF@
+REPLACE_FLOORL = @REPLACE_FLOORL@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+REPLACE_FREOPEN = @REPLACE_FREOPEN@
+REPLACE_FREXP = @REPLACE_FREXP@
+REPLACE_FREXPL = @REPLACE_FREXPL@
+REPLACE_FSEEK = @REPLACE_FSEEK@
+REPLACE_FSEEKO = @REPLACE_FSEEKO@
+REPLACE_FSTAT = @REPLACE_FSTAT@
+REPLACE_FSTATAT = @REPLACE_FSTATAT@
+REPLACE_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_FUTIMENS = @REPLACE_FUTIMENS@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
+REPLACE_HUGE_VAL = @REPLACE_HUGE_VAL@
+REPLACE_ICONV = @REPLACE_ICONV@
+REPLACE_ICONV_OPEN = @REPLACE_ICONV_OPEN@
+REPLACE_ICONV_UTF = @REPLACE_ICONV_UTF@
+REPLACE_ISFINITE = @REPLACE_ISFINITE@
+REPLACE_ISINF = @REPLACE_ISINF@
+REPLACE_ISNAN = @REPLACE_ISNAN@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LDEXPL = @REPLACE_LDEXPL@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_LSTAT = @REPLACE_LSTAT@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKDIR = @REPLACE_MKDIR@
+REPLACE_MKFIFO = @REPLACE_MKFIFO@
+REPLACE_MKNOD = @REPLACE_MKNOD@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_MKTIME = @REPLACE_MKTIME@
+REPLACE_NAN = @REPLACE_NAN@
+REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_POSIX_SPAWN = @REPLACE_POSIX_SPAWN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_ROUND = @REPLACE_ROUND@
+REPLACE_ROUNDF = @REPLACE_ROUNDF@
+REPLACE_ROUNDL = @REPLACE_ROUNDL@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SIGNBIT = @REPLACE_SIGNBIT@
+REPLACE_SIGNBIT_USING_GCC = @REPLACE_SIGNBIT_USING_GCC@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
+REPLACE_SPRINTF = @REPLACE_SPRINTF@
+REPLACE_STAT = @REPLACE_STAT@
+REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRPTIME = @REPLACE_STRPTIME@
+REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@
+REPLACE_STRSTR = @REPLACE_STRSTR@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TIMEGM = @REPLACE_TIMEGM@
+REPLACE_TRUNCL = @REPLACE_TRUNCL@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@
+REPLACE_VASPRINTF = @REPLACE_VASPRINTF@
+REPLACE_VDPRINTF = @REPLACE_VDPRINTF@
+REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
+REPLACE_VPRINTF = @REPLACE_VPRINTF@
+REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
+REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SCHED_H = @SCHED_H@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDARG_H = @STDARG_H@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
+TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
+UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
+UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+USE_GMP = @USE_GMP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WCTYPE_H = @WCTYPE_H@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_aux_dir = @abs_aux_dir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+ltdl_LIBOBJS = @ltdl_LIBOBJS@
+ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sys_symbol_underscore = @sys_symbol_underscore@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = 1.5 foreign subdir-objects
+SUBDIRS =
+TESTS_ENVIRONMENT = EXEEXT='@EXEEXT@' srcdir='$(srcdir)' \
+ LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ LOCALE_FR='@LOCALE_FR@' LOCALE_TR_UTF8='@LOCALE_TR_UTF8@' \
+ LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ LOCALE_JA='@LOCALE_JA@' LOCALE_ZH_CN='@LOCALE_ZH_CN@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ LOCALE_ZH_CN='@LOCALE_ZH_CN@' LOCALE_FR='@LOCALE_FR@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' LOCALE_FR='@LOCALE_FR@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ PATH='$(abs_aux_dir)'$(PATH_SEPARATOR)"$$PATH" \
+ LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ PATH='$(abs_aux_dir)'$(PATH_SEPARATOR)"$$PATH" \
+ LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ LOCALE_JA='@LOCALE_JA@' LOCALE_ZH_CN='@LOCALE_ZH_CN@'
+noinst_HEADERS =
+noinst_LIBRARIES =
+check_LIBRARIES = libtests.a
+EXTRA_DIST = test-alloca-opt.c $(top_srcdir)/build-aux/arg-nonnull.h \
+ test-array_list.c macros.h test-array_oset.c macros.h \
+ test-avltree_oset.c macros.h test-binary-io.sh \
+ test-binary-io.c macros.h test-bitrotate.c macros.h \
+ test-btowc1.sh test-btowc2.sh test-btowc.c signature.h \
+ macros.h test-c-ctype.c macros.h test-c-strcase.sh \
+ test-c-strcasecmp.c test-c-strncasecmp.c macros.h \
+ test-canonicalize-lgpl.c signature.h macros.h test-cloexec.c \
+ macros.h test-closein.sh test-closein.c test-dirname.c \
+ test-dup2.c signature.h macros.h test-environ.c test-errno.c \
+ test-fcntl-h.c test-fcntl.c signature.h macros.h test-fflush.c \
+ test-fflush2.sh test-fflush2.c signature.h macros.h \
+ test-filenamecat.c test-fopen.h test-fopen-safer.c macros.h \
+ test-fopen.h test-fopen.c signature.h macros.h test-fpending.c \
+ test-fpending.sh macros.h test-fpurge.c macros.h \
+ test-freadahead.c test-freadahead.sh macros.h test-freading.c \
+ macros.h test-freadptr.c test-freadptr.sh test-freadptr2.c \
+ test-freadptr2.sh macros.h test-freadseek.c test-freadseek.sh \
+ macros.h test-frexp.c signature.h macros.h test-frexpl.c \
+ signature.h macros.h test-fseeko.c test-fseeko.sh \
+ test-fseeko2.sh signature.h macros.h test-fseterr.c \
+ test-ftello.c test-ftello.sh test-ftello2.sh signature.h \
+ macros.h test-getdtablesize.c signature.h macros.h \
+ getpagesize.c signature.h test-gettimeofday.c test-iconv.c \
+ signature.h macros.h test-inttypes.c test-isnand-nolibm.c \
+ test-isnand.h nan.h macros.h test-isnanf-nolibm.c \
+ test-isnanf.h nan.h macros.h test-isnanl-nolibm.c \
+ test-isnanl.h nan.h macros.h test-langinfo.c link.c \
+ test-link.h test-link.c signature.h macros.h \
+ test-linkedhash_list.c macros.h test-lseek.c test-lseek.sh \
+ signature.h macros.h test-lstat.h test-lstat.c signature.h \
+ macros.h test-malloca.c test-math.c test-mbrtowc1.sh \
+ test-mbrtowc2.sh test-mbrtowc3.sh test-mbrtowc4.sh \
+ test-mbrtowc.c signature.h macros.h test-mbsinit.sh \
+ test-mbsinit.c signature.h macros.h test-mbsstr1.c \
+ test-mbsstr2.sh test-mbsstr2.c test-mbsstr3.sh test-mbsstr3.c \
+ macros.h test-memchr.c zerosize-ptr.h signature.h macros.h \
+ test-memchr2.c zerosize-ptr.h macros.h test-memmem.c \
+ zerosize-ptr.h signature.h macros.h test-nl_langinfo.sh \
+ test-nl_langinfo.c signature.h macros.h obstack_printf.c \
+ test-obstack-printf.c signature.h macros.h test-open.h \
+ test-open.c signature.h macros.h test-pipe.sh test-pipe.c \
+ macros.h test-pipe2.c signature.h macros.h test-posix_spawn1.c \
+ test-posix_spawn1.in.sh test-posix_spawn2.c \
+ test-posix_spawn2.in.sh signature.h test-printf-frexp.c \
+ macros.h test-printf-frexpl.c macros.h putenv.c \
+ test-quotearg.sh test-quotearg.c macros.h \
+ locale/fr/LC_MESSAGES/test-quotearg.po \
+ locale/fr/LC_MESSAGES/test-quotearg.mo test-rawmemchr.c \
+ signature.h macros.h test-readlink.h test-readlink.c \
+ signature.h macros.h test-rename.h test-rename.c signature.h \
+ macros.h test-rmdir.h test-rmdir.c signature.h macros.h \
+ test-sched.c test-setenv.c signature.h macros.h \
+ test-sigaction.c signature.h macros.h test-signal.c \
+ test-signbit.c macros.h test-snprintf-posix.c \
+ test-snprintf-posix.h test-snprintf.c nan.h signature.h \
+ macros.h test-snprintf.c signature.h macros.h test-spawn.c \
+ test-sprintf-posix.c test-sprintf-posix.h nan.h signature.h \
+ macros.h test-stat.h test-stat.c signature.h macros.h \
+ test-stdbool.c test-stddef.c test-stdint.c test-stdio.c \
+ test-stdlib.c test-strchrnul.c signature.h macros.h strdup.c \
+ test-strerror.c signature.h macros.h test-striconv.c macros.h \
+ test-string.c test-strtod.c signature.h macros.h symlink.c \
+ test-symlink.h test-symlink.c signature.h macros.h \
+ test-sys_stat.c test-sys_time.c test-sys_wait.c test-time.c \
+ test-dup-safer.c macros.h test-unistd.c \
+ uniwidth/test-uc_width.c uniwidth/test-uc_width2.c \
+ uniwidth/test-uc_width2.sh macros.h test-unsetenv.c \
+ signature.h macros.h test-update-copyright.sh \
+ test-vasnprintf-posix.c test-vasnprintf-posix2.sh \
+ test-vasnprintf-posix2.c nan.h macros.h test-vasnprintf.c \
+ macros.h test-vasprintf-posix.c nan.h macros.h \
+ test-vasprintf.c signature.h macros.h \
+ test-vc-list-files-git.sh test-vc-list-files-cvs.sh \
+ test-vfprintf-posix.sh test-vfprintf-posix.c \
+ test-fprintf-posix.h test-printf-posix.output signature.h \
+ macros.h test-vprintf-posix.sh test-vprintf-posix.c \
+ test-printf-posix.h test-printf-posix.output signature.h \
+ macros.h $(top_srcdir)/build-aux/warn-on-use.h test-wchar.c \
+ test-wcrtomb.sh test-wcrtomb.c signature.h macros.h wctob.c \
+ test-wctype.c macros.h test-wcwidth.c signature.h macros.h \
+ test-xalloc-die.c test-xalloc-die.sh init.sh test-xmemdup0.c \
+ macros.h test-xprintf-posix.sh test-xfprintf-posix.c \
+ test-xprintf-posix.c test-fprintf-posix.h test-printf-posix.h \
+ test-printf-posix.output macros.h test-xvasprintf.c macros.h
+
+# The BUILT_SOURCES created by this Makefile snippet are not used via #include
+# statements but through direct file reference. Therefore this snippet must be
+# present in all Makefile.am that need it. This is ensured by the applicability
+# 'all' defined above.
+BUILT_SOURCES = arg-nonnull.h $(am__append_3) warn-on-use.h
+SUFFIXES =
+MOSTLYCLEANFILES = core *.stackdump arg-nonnull.h arg-nonnull.h-t \
+ test-fflush.txt test-fpending.t t-fpurge.tmp t-freading.tmp \
+ $(am__append_4) warn-on-use.h warn-on-use.h-t
+MOSTLYCLEANDIRS =
+CLEANFILES =
+DISTCLEANFILES =
+MAINTAINERCLEANFILES =
+AM_CPPFLAGS = \
+ -I. -I$(srcdir) \
+ -I../.. -I$(srcdir)/../.. \
+ -I../../gnu -I$(srcdir)/../../gnu
+
+LDADD = libtests.a ../../gnu/libgnu.la libtests.a $(LIBTESTS_LIBDEPS)
+libtests_a_SOURCES = gl_array_list.h gl_array_list.c gl_array_oset.h \
+ gl_array_oset.c ignore-value.h
+libtests_a_LIBADD = $(M4tests_LIBOBJS)
+libtests_a_DEPENDENCIES = $(M4tests_LIBOBJS)
+EXTRA_libtests_a_SOURCES = getpagesize.c link.c obstack_printf.c \
+ putenv.c strdup.c symlink.c wctob.c
+AM_LIBTOOLFLAGS = --preserve-dup-deps
+ARG_NONNULL_H = arg-nonnull.h
+test_array_oset_LDADD = $(LDADD) @LIBINTL@
+test_closein_LDADD = $(LDADD) @LIBINTL@
+test_dirname_LDADD = $(LDADD) @LIBINTL@
+test_filenamecat_LDADD = $(LDADD) @LIBINTL@
+test_frexp_nolibm_SOURCES = test-frexp.c
+test_frexpl_nolibm_SOURCES = test-frexpl.c
+test_iconv_LDADD = $(LDADD) @LIBICONV@
+test_obstack_printf_LDADD = $(LDADD) @LIBINTL@
+test_pipe_LDADD = $(LDADD) @LIBINTL@
+test_quotearg_LDADD = $(LDADD) @LIBINTL@
+test_striconv_LDADD = $(LDADD) @LIBICONV@
+test_uc_width_SOURCES = uniwidth/test-uc_width.c
+test_uc_width2_SOURCES = uniwidth/test-uc_width2.c
+WARN_ON_USE_H = warn-on-use.h
+test_xalloc_die_LDADD = $(LDADD) @LIBINTL@
+test_xmemdup0_LDADD = $(LDADD) @LIBINTL@
+test_xfprintf_posix_LDADD = $(LDADD) @LIBINTL@
+test_xprintf_posix_LDADD = $(LDADD) @LIBINTL@
+test_xvasprintf_LDADD = $(LDADD) @LIBINTL@
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .html .lo .log .o .obj .test .test$(EXEEXT)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/gnu/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/gnu/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkLIBRARIES:
+ -test -z "$(check_LIBRARIES)" || rm -f $(check_LIBRARIES)
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libtests.a: $(libtests_a_OBJECTS) $(libtests_a_DEPENDENCIES)
+ $(AM_V_at)-rm -f libtests.a
+ $(AM_V_AR)$(libtests_a_AR) libtests.a $(libtests_a_OBJECTS) $(libtests_a_LIBADD)
+ $(AM_V_at)$(RANLIB) libtests.a
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+test-alloca-opt$(EXEEXT): $(test_alloca_opt_OBJECTS) $(test_alloca_opt_DEPENDENCIES)
+ @rm -f test-alloca-opt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_alloca_opt_OBJECTS) $(test_alloca_opt_LDADD) $(LIBS)
+test-array_list$(EXEEXT): $(test_array_list_OBJECTS) $(test_array_list_DEPENDENCIES)
+ @rm -f test-array_list$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_array_list_OBJECTS) $(test_array_list_LDADD) $(LIBS)
+test-array_oset$(EXEEXT): $(test_array_oset_OBJECTS) $(test_array_oset_DEPENDENCIES)
+ @rm -f test-array_oset$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_array_oset_OBJECTS) $(test_array_oset_LDADD) $(LIBS)
+test-avltree_oset$(EXEEXT): $(test_avltree_oset_OBJECTS) $(test_avltree_oset_DEPENDENCIES)
+ @rm -f test-avltree_oset$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_avltree_oset_OBJECTS) $(test_avltree_oset_LDADD) $(LIBS)
+test-binary-io$(EXEEXT): $(test_binary_io_OBJECTS) $(test_binary_io_DEPENDENCIES)
+ @rm -f test-binary-io$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_binary_io_OBJECTS) $(test_binary_io_LDADD) $(LIBS)
+test-bitrotate$(EXEEXT): $(test_bitrotate_OBJECTS) $(test_bitrotate_DEPENDENCIES)
+ @rm -f test-bitrotate$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_bitrotate_OBJECTS) $(test_bitrotate_LDADD) $(LIBS)
+test-btowc$(EXEEXT): $(test_btowc_OBJECTS) $(test_btowc_DEPENDENCIES)
+ @rm -f test-btowc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_btowc_OBJECTS) $(test_btowc_LDADD) $(LIBS)
+test-c-ctype$(EXEEXT): $(test_c_ctype_OBJECTS) $(test_c_ctype_DEPENDENCIES)
+ @rm -f test-c-ctype$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_c_ctype_OBJECTS) $(test_c_ctype_LDADD) $(LIBS)
+test-c-strcasecmp$(EXEEXT): $(test_c_strcasecmp_OBJECTS) $(test_c_strcasecmp_DEPENDENCIES)
+ @rm -f test-c-strcasecmp$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_c_strcasecmp_OBJECTS) $(test_c_strcasecmp_LDADD) $(LIBS)
+test-c-strncasecmp$(EXEEXT): $(test_c_strncasecmp_OBJECTS) $(test_c_strncasecmp_DEPENDENCIES)
+ @rm -f test-c-strncasecmp$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_c_strncasecmp_OBJECTS) $(test_c_strncasecmp_LDADD) $(LIBS)
+test-canonicalize-lgpl$(EXEEXT): $(test_canonicalize_lgpl_OBJECTS) $(test_canonicalize_lgpl_DEPENDENCIES)
+ @rm -f test-canonicalize-lgpl$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_canonicalize_lgpl_OBJECTS) $(test_canonicalize_lgpl_LDADD) $(LIBS)
+test-cloexec$(EXEEXT): $(test_cloexec_OBJECTS) $(test_cloexec_DEPENDENCIES)
+ @rm -f test-cloexec$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_cloexec_OBJECTS) $(test_cloexec_LDADD) $(LIBS)
+test-closein$(EXEEXT): $(test_closein_OBJECTS) $(test_closein_DEPENDENCIES)
+ @rm -f test-closein$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_closein_OBJECTS) $(test_closein_LDADD) $(LIBS)
+test-dirname$(EXEEXT): $(test_dirname_OBJECTS) $(test_dirname_DEPENDENCIES)
+ @rm -f test-dirname$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_dirname_OBJECTS) $(test_dirname_LDADD) $(LIBS)
+test-dup-safer$(EXEEXT): $(test_dup_safer_OBJECTS) $(test_dup_safer_DEPENDENCIES)
+ @rm -f test-dup-safer$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_dup_safer_OBJECTS) $(test_dup_safer_LDADD) $(LIBS)
+test-dup2$(EXEEXT): $(test_dup2_OBJECTS) $(test_dup2_DEPENDENCIES)
+ @rm -f test-dup2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_dup2_OBJECTS) $(test_dup2_LDADD) $(LIBS)
+test-environ$(EXEEXT): $(test_environ_OBJECTS) $(test_environ_DEPENDENCIES)
+ @rm -f test-environ$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_environ_OBJECTS) $(test_environ_LDADD) $(LIBS)
+test-errno$(EXEEXT): $(test_errno_OBJECTS) $(test_errno_DEPENDENCIES)
+ @rm -f test-errno$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_errno_OBJECTS) $(test_errno_LDADD) $(LIBS)
+test-fcntl$(EXEEXT): $(test_fcntl_OBJECTS) $(test_fcntl_DEPENDENCIES)
+ @rm -f test-fcntl$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fcntl_OBJECTS) $(test_fcntl_LDADD) $(LIBS)
+test-fcntl-h$(EXEEXT): $(test_fcntl_h_OBJECTS) $(test_fcntl_h_DEPENDENCIES)
+ @rm -f test-fcntl-h$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fcntl_h_OBJECTS) $(test_fcntl_h_LDADD) $(LIBS)
+test-fflush$(EXEEXT): $(test_fflush_OBJECTS) $(test_fflush_DEPENDENCIES)
+ @rm -f test-fflush$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fflush_OBJECTS) $(test_fflush_LDADD) $(LIBS)
+test-fflush2$(EXEEXT): $(test_fflush2_OBJECTS) $(test_fflush2_DEPENDENCIES)
+ @rm -f test-fflush2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fflush2_OBJECTS) $(test_fflush2_LDADD) $(LIBS)
+test-filenamecat$(EXEEXT): $(test_filenamecat_OBJECTS) $(test_filenamecat_DEPENDENCIES)
+ @rm -f test-filenamecat$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_filenamecat_OBJECTS) $(test_filenamecat_LDADD) $(LIBS)
+test-fopen$(EXEEXT): $(test_fopen_OBJECTS) $(test_fopen_DEPENDENCIES)
+ @rm -f test-fopen$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fopen_OBJECTS) $(test_fopen_LDADD) $(LIBS)
+test-fopen-safer$(EXEEXT): $(test_fopen_safer_OBJECTS) $(test_fopen_safer_DEPENDENCIES)
+ @rm -f test-fopen-safer$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fopen_safer_OBJECTS) $(test_fopen_safer_LDADD) $(LIBS)
+test-fpending$(EXEEXT): $(test_fpending_OBJECTS) $(test_fpending_DEPENDENCIES)
+ @rm -f test-fpending$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fpending_OBJECTS) $(test_fpending_LDADD) $(LIBS)
+test-fpurge$(EXEEXT): $(test_fpurge_OBJECTS) $(test_fpurge_DEPENDENCIES)
+ @rm -f test-fpurge$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fpurge_OBJECTS) $(test_fpurge_LDADD) $(LIBS)
+test-freadahead$(EXEEXT): $(test_freadahead_OBJECTS) $(test_freadahead_DEPENDENCIES)
+ @rm -f test-freadahead$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_freadahead_OBJECTS) $(test_freadahead_LDADD) $(LIBS)
+test-freading$(EXEEXT): $(test_freading_OBJECTS) $(test_freading_DEPENDENCIES)
+ @rm -f test-freading$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_freading_OBJECTS) $(test_freading_LDADD) $(LIBS)
+test-freadptr$(EXEEXT): $(test_freadptr_OBJECTS) $(test_freadptr_DEPENDENCIES)
+ @rm -f test-freadptr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_freadptr_OBJECTS) $(test_freadptr_LDADD) $(LIBS)
+test-freadptr2$(EXEEXT): $(test_freadptr2_OBJECTS) $(test_freadptr2_DEPENDENCIES)
+ @rm -f test-freadptr2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_freadptr2_OBJECTS) $(test_freadptr2_LDADD) $(LIBS)
+test-freadseek$(EXEEXT): $(test_freadseek_OBJECTS) $(test_freadseek_DEPENDENCIES)
+ @rm -f test-freadseek$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_freadseek_OBJECTS) $(test_freadseek_LDADD) $(LIBS)
+test-frexp-nolibm$(EXEEXT): $(test_frexp_nolibm_OBJECTS) $(test_frexp_nolibm_DEPENDENCIES)
+ @rm -f test-frexp-nolibm$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_frexp_nolibm_OBJECTS) $(test_frexp_nolibm_LDADD) $(LIBS)
+test-frexpl-nolibm$(EXEEXT): $(test_frexpl_nolibm_OBJECTS) $(test_frexpl_nolibm_DEPENDENCIES)
+ @rm -f test-frexpl-nolibm$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_frexpl_nolibm_OBJECTS) $(test_frexpl_nolibm_LDADD) $(LIBS)
+test-fseeko$(EXEEXT): $(test_fseeko_OBJECTS) $(test_fseeko_DEPENDENCIES)
+ @rm -f test-fseeko$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fseeko_OBJECTS) $(test_fseeko_LDADD) $(LIBS)
+test-fseterr$(EXEEXT): $(test_fseterr_OBJECTS) $(test_fseterr_DEPENDENCIES)
+ @rm -f test-fseterr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fseterr_OBJECTS) $(test_fseterr_LDADD) $(LIBS)
+test-ftello$(EXEEXT): $(test_ftello_OBJECTS) $(test_ftello_DEPENDENCIES)
+ @rm -f test-ftello$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ftello_OBJECTS) $(test_ftello_LDADD) $(LIBS)
+test-getdtablesize$(EXEEXT): $(test_getdtablesize_OBJECTS) $(test_getdtablesize_DEPENDENCIES)
+ @rm -f test-getdtablesize$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_getdtablesize_OBJECTS) $(test_getdtablesize_LDADD) $(LIBS)
+test-gettimeofday$(EXEEXT): $(test_gettimeofday_OBJECTS) $(test_gettimeofday_DEPENDENCIES)
+ @rm -f test-gettimeofday$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_gettimeofday_OBJECTS) $(test_gettimeofday_LDADD) $(LIBS)
+test-iconv$(EXEEXT): $(test_iconv_OBJECTS) $(test_iconv_DEPENDENCIES)
+ @rm -f test-iconv$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_iconv_OBJECTS) $(test_iconv_LDADD) $(LIBS)
+test-inttypes$(EXEEXT): $(test_inttypes_OBJECTS) $(test_inttypes_DEPENDENCIES)
+ @rm -f test-inttypes$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_inttypes_OBJECTS) $(test_inttypes_LDADD) $(LIBS)
+test-isnand-nolibm$(EXEEXT): $(test_isnand_nolibm_OBJECTS) $(test_isnand_nolibm_DEPENDENCIES)
+ @rm -f test-isnand-nolibm$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_isnand_nolibm_OBJECTS) $(test_isnand_nolibm_LDADD) $(LIBS)
+test-isnanf-nolibm$(EXEEXT): $(test_isnanf_nolibm_OBJECTS) $(test_isnanf_nolibm_DEPENDENCIES)
+ @rm -f test-isnanf-nolibm$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_isnanf_nolibm_OBJECTS) $(test_isnanf_nolibm_LDADD) $(LIBS)
+test-isnanl-nolibm$(EXEEXT): $(test_isnanl_nolibm_OBJECTS) $(test_isnanl_nolibm_DEPENDENCIES)
+ @rm -f test-isnanl-nolibm$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_isnanl_nolibm_OBJECTS) $(test_isnanl_nolibm_LDADD) $(LIBS)
+test-langinfo$(EXEEXT): $(test_langinfo_OBJECTS) $(test_langinfo_DEPENDENCIES)
+ @rm -f test-langinfo$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_langinfo_OBJECTS) $(test_langinfo_LDADD) $(LIBS)
+test-link$(EXEEXT): $(test_link_OBJECTS) $(test_link_DEPENDENCIES)
+ @rm -f test-link$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_link_OBJECTS) $(test_link_LDADD) $(LIBS)
+test-linkedhash_list$(EXEEXT): $(test_linkedhash_list_OBJECTS) $(test_linkedhash_list_DEPENDENCIES)
+ @rm -f test-linkedhash_list$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_linkedhash_list_OBJECTS) $(test_linkedhash_list_LDADD) $(LIBS)
+test-lseek$(EXEEXT): $(test_lseek_OBJECTS) $(test_lseek_DEPENDENCIES)
+ @rm -f test-lseek$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_lseek_OBJECTS) $(test_lseek_LDADD) $(LIBS)
+test-lstat$(EXEEXT): $(test_lstat_OBJECTS) $(test_lstat_DEPENDENCIES)
+ @rm -f test-lstat$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_lstat_OBJECTS) $(test_lstat_LDADD) $(LIBS)
+test-malloca$(EXEEXT): $(test_malloca_OBJECTS) $(test_malloca_DEPENDENCIES)
+ @rm -f test-malloca$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_malloca_OBJECTS) $(test_malloca_LDADD) $(LIBS)
+test-math$(EXEEXT): $(test_math_OBJECTS) $(test_math_DEPENDENCIES)
+ @rm -f test-math$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_math_OBJECTS) $(test_math_LDADD) $(LIBS)
+test-mbrtowc$(EXEEXT): $(test_mbrtowc_OBJECTS) $(test_mbrtowc_DEPENDENCIES)
+ @rm -f test-mbrtowc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_mbrtowc_OBJECTS) $(test_mbrtowc_LDADD) $(LIBS)
+test-mbsinit$(EXEEXT): $(test_mbsinit_OBJECTS) $(test_mbsinit_DEPENDENCIES)
+ @rm -f test-mbsinit$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_mbsinit_OBJECTS) $(test_mbsinit_LDADD) $(LIBS)
+test-mbsstr1$(EXEEXT): $(test_mbsstr1_OBJECTS) $(test_mbsstr1_DEPENDENCIES)
+ @rm -f test-mbsstr1$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_mbsstr1_OBJECTS) $(test_mbsstr1_LDADD) $(LIBS)
+test-mbsstr2$(EXEEXT): $(test_mbsstr2_OBJECTS) $(test_mbsstr2_DEPENDENCIES)
+ @rm -f test-mbsstr2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_mbsstr2_OBJECTS) $(test_mbsstr2_LDADD) $(LIBS)
+test-mbsstr3$(EXEEXT): $(test_mbsstr3_OBJECTS) $(test_mbsstr3_DEPENDENCIES)
+ @rm -f test-mbsstr3$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_mbsstr3_OBJECTS) $(test_mbsstr3_LDADD) $(LIBS)
+test-memchr$(EXEEXT): $(test_memchr_OBJECTS) $(test_memchr_DEPENDENCIES)
+ @rm -f test-memchr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_memchr_OBJECTS) $(test_memchr_LDADD) $(LIBS)
+test-memchr2$(EXEEXT): $(test_memchr2_OBJECTS) $(test_memchr2_DEPENDENCIES)
+ @rm -f test-memchr2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_memchr2_OBJECTS) $(test_memchr2_LDADD) $(LIBS)
+test-memmem$(EXEEXT): $(test_memmem_OBJECTS) $(test_memmem_DEPENDENCIES)
+ @rm -f test-memmem$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_memmem_OBJECTS) $(test_memmem_LDADD) $(LIBS)
+test-nl_langinfo$(EXEEXT): $(test_nl_langinfo_OBJECTS) $(test_nl_langinfo_DEPENDENCIES)
+ @rm -f test-nl_langinfo$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_nl_langinfo_OBJECTS) $(test_nl_langinfo_LDADD) $(LIBS)
+test-obstack-printf$(EXEEXT): $(test_obstack_printf_OBJECTS) $(test_obstack_printf_DEPENDENCIES)
+ @rm -f test-obstack-printf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_obstack_printf_OBJECTS) $(test_obstack_printf_LDADD) $(LIBS)
+test-open$(EXEEXT): $(test_open_OBJECTS) $(test_open_DEPENDENCIES)
+ @rm -f test-open$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_open_OBJECTS) $(test_open_LDADD) $(LIBS)
+test-pipe$(EXEEXT): $(test_pipe_OBJECTS) $(test_pipe_DEPENDENCIES)
+ @rm -f test-pipe$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_pipe_OBJECTS) $(test_pipe_LDADD) $(LIBS)
+test-pipe2$(EXEEXT): $(test_pipe2_OBJECTS) $(test_pipe2_DEPENDENCIES)
+ @rm -f test-pipe2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_pipe2_OBJECTS) $(test_pipe2_LDADD) $(LIBS)
+test-posix_spawn1$(EXEEXT): $(test_posix_spawn1_OBJECTS) $(test_posix_spawn1_DEPENDENCIES)
+ @rm -f test-posix_spawn1$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_posix_spawn1_OBJECTS) $(test_posix_spawn1_LDADD) $(LIBS)
+test-posix_spawn2$(EXEEXT): $(test_posix_spawn2_OBJECTS) $(test_posix_spawn2_DEPENDENCIES)
+ @rm -f test-posix_spawn2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_posix_spawn2_OBJECTS) $(test_posix_spawn2_LDADD) $(LIBS)
+test-printf-frexp$(EXEEXT): $(test_printf_frexp_OBJECTS) $(test_printf_frexp_DEPENDENCIES)
+ @rm -f test-printf-frexp$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_printf_frexp_OBJECTS) $(test_printf_frexp_LDADD) $(LIBS)
+test-printf-frexpl$(EXEEXT): $(test_printf_frexpl_OBJECTS) $(test_printf_frexpl_DEPENDENCIES)
+ @rm -f test-printf-frexpl$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_printf_frexpl_OBJECTS) $(test_printf_frexpl_LDADD) $(LIBS)
+test-quotearg$(EXEEXT): $(test_quotearg_OBJECTS) $(test_quotearg_DEPENDENCIES)
+ @rm -f test-quotearg$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_quotearg_OBJECTS) $(test_quotearg_LDADD) $(LIBS)
+test-rawmemchr$(EXEEXT): $(test_rawmemchr_OBJECTS) $(test_rawmemchr_DEPENDENCIES)
+ @rm -f test-rawmemchr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_rawmemchr_OBJECTS) $(test_rawmemchr_LDADD) $(LIBS)
+test-readlink$(EXEEXT): $(test_readlink_OBJECTS) $(test_readlink_DEPENDENCIES)
+ @rm -f test-readlink$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_readlink_OBJECTS) $(test_readlink_LDADD) $(LIBS)
+test-rename$(EXEEXT): $(test_rename_OBJECTS) $(test_rename_DEPENDENCIES)
+ @rm -f test-rename$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_rename_OBJECTS) $(test_rename_LDADD) $(LIBS)
+test-rmdir$(EXEEXT): $(test_rmdir_OBJECTS) $(test_rmdir_DEPENDENCIES)
+ @rm -f test-rmdir$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_rmdir_OBJECTS) $(test_rmdir_LDADD) $(LIBS)
+test-sched$(EXEEXT): $(test_sched_OBJECTS) $(test_sched_DEPENDENCIES)
+ @rm -f test-sched$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_sched_OBJECTS) $(test_sched_LDADD) $(LIBS)
+test-setenv$(EXEEXT): $(test_setenv_OBJECTS) $(test_setenv_DEPENDENCIES)
+ @rm -f test-setenv$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_setenv_OBJECTS) $(test_setenv_LDADD) $(LIBS)
+test-sigaction$(EXEEXT): $(test_sigaction_OBJECTS) $(test_sigaction_DEPENDENCIES)
+ @rm -f test-sigaction$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_sigaction_OBJECTS) $(test_sigaction_LDADD) $(LIBS)
+test-signal$(EXEEXT): $(test_signal_OBJECTS) $(test_signal_DEPENDENCIES)
+ @rm -f test-signal$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_signal_OBJECTS) $(test_signal_LDADD) $(LIBS)
+test-signbit$(EXEEXT): $(test_signbit_OBJECTS) $(test_signbit_DEPENDENCIES)
+ @rm -f test-signbit$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_signbit_OBJECTS) $(test_signbit_LDADD) $(LIBS)
+test-snprintf$(EXEEXT): $(test_snprintf_OBJECTS) $(test_snprintf_DEPENDENCIES)
+ @rm -f test-snprintf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_snprintf_OBJECTS) $(test_snprintf_LDADD) $(LIBS)
+test-snprintf-posix$(EXEEXT): $(test_snprintf_posix_OBJECTS) $(test_snprintf_posix_DEPENDENCIES)
+ @rm -f test-snprintf-posix$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_snprintf_posix_OBJECTS) $(test_snprintf_posix_LDADD) $(LIBS)
+test-spawn$(EXEEXT): $(test_spawn_OBJECTS) $(test_spawn_DEPENDENCIES)
+ @rm -f test-spawn$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_spawn_OBJECTS) $(test_spawn_LDADD) $(LIBS)
+test-sprintf-posix$(EXEEXT): $(test_sprintf_posix_OBJECTS) $(test_sprintf_posix_DEPENDENCIES)
+ @rm -f test-sprintf-posix$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_sprintf_posix_OBJECTS) $(test_sprintf_posix_LDADD) $(LIBS)
+test-stat$(EXEEXT): $(test_stat_OBJECTS) $(test_stat_DEPENDENCIES)
+ @rm -f test-stat$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_stat_OBJECTS) $(test_stat_LDADD) $(LIBS)
+test-stdbool$(EXEEXT): $(test_stdbool_OBJECTS) $(test_stdbool_DEPENDENCIES)
+ @rm -f test-stdbool$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_stdbool_OBJECTS) $(test_stdbool_LDADD) $(LIBS)
+test-stddef$(EXEEXT): $(test_stddef_OBJECTS) $(test_stddef_DEPENDENCIES)
+ @rm -f test-stddef$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_stddef_OBJECTS) $(test_stddef_LDADD) $(LIBS)
+test-stdint$(EXEEXT): $(test_stdint_OBJECTS) $(test_stdint_DEPENDENCIES)
+ @rm -f test-stdint$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_stdint_OBJECTS) $(test_stdint_LDADD) $(LIBS)
+test-stdio$(EXEEXT): $(test_stdio_OBJECTS) $(test_stdio_DEPENDENCIES)
+ @rm -f test-stdio$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_stdio_OBJECTS) $(test_stdio_LDADD) $(LIBS)
+test-stdlib$(EXEEXT): $(test_stdlib_OBJECTS) $(test_stdlib_DEPENDENCIES)
+ @rm -f test-stdlib$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_stdlib_OBJECTS) $(test_stdlib_LDADD) $(LIBS)
+test-strchrnul$(EXEEXT): $(test_strchrnul_OBJECTS) $(test_strchrnul_DEPENDENCIES)
+ @rm -f test-strchrnul$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_strchrnul_OBJECTS) $(test_strchrnul_LDADD) $(LIBS)
+test-strerror$(EXEEXT): $(test_strerror_OBJECTS) $(test_strerror_DEPENDENCIES)
+ @rm -f test-strerror$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_strerror_OBJECTS) $(test_strerror_LDADD) $(LIBS)
+test-striconv$(EXEEXT): $(test_striconv_OBJECTS) $(test_striconv_DEPENDENCIES)
+ @rm -f test-striconv$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_striconv_OBJECTS) $(test_striconv_LDADD) $(LIBS)
+test-string$(EXEEXT): $(test_string_OBJECTS) $(test_string_DEPENDENCIES)
+ @rm -f test-string$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_string_OBJECTS) $(test_string_LDADD) $(LIBS)
+test-strtod$(EXEEXT): $(test_strtod_OBJECTS) $(test_strtod_DEPENDENCIES)
+ @rm -f test-strtod$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_strtod_OBJECTS) $(test_strtod_LDADD) $(LIBS)
+test-symlink$(EXEEXT): $(test_symlink_OBJECTS) $(test_symlink_DEPENDENCIES)
+ @rm -f test-symlink$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_symlink_OBJECTS) $(test_symlink_LDADD) $(LIBS)
+test-sys_stat$(EXEEXT): $(test_sys_stat_OBJECTS) $(test_sys_stat_DEPENDENCIES)
+ @rm -f test-sys_stat$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_sys_stat_OBJECTS) $(test_sys_stat_LDADD) $(LIBS)
+test-sys_time$(EXEEXT): $(test_sys_time_OBJECTS) $(test_sys_time_DEPENDENCIES)
+ @rm -f test-sys_time$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_sys_time_OBJECTS) $(test_sys_time_LDADD) $(LIBS)
+test-sys_wait$(EXEEXT): $(test_sys_wait_OBJECTS) $(test_sys_wait_DEPENDENCIES)
+ @rm -f test-sys_wait$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_sys_wait_OBJECTS) $(test_sys_wait_LDADD) $(LIBS)
+test-time$(EXEEXT): $(test_time_OBJECTS) $(test_time_DEPENDENCIES)
+ @rm -f test-time$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_time_OBJECTS) $(test_time_LDADD) $(LIBS)
+uniwidth/$(am__dirstamp):
+ @$(MKDIR_P) uniwidth
+ @: > uniwidth/$(am__dirstamp)
+uniwidth/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) uniwidth/$(DEPDIR)
+ @: > uniwidth/$(DEPDIR)/$(am__dirstamp)
+uniwidth/test-uc_width.$(OBJEXT): uniwidth/$(am__dirstamp) \
+ uniwidth/$(DEPDIR)/$(am__dirstamp)
+test-uc_width$(EXEEXT): $(test_uc_width_OBJECTS) $(test_uc_width_DEPENDENCIES)
+ @rm -f test-uc_width$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_uc_width_OBJECTS) $(test_uc_width_LDADD) $(LIBS)
+uniwidth/test-uc_width2.$(OBJEXT): uniwidth/$(am__dirstamp) \
+ uniwidth/$(DEPDIR)/$(am__dirstamp)
+test-uc_width2$(EXEEXT): $(test_uc_width2_OBJECTS) $(test_uc_width2_DEPENDENCIES)
+ @rm -f test-uc_width2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_uc_width2_OBJECTS) $(test_uc_width2_LDADD) $(LIBS)
+test-unistd$(EXEEXT): $(test_unistd_OBJECTS) $(test_unistd_DEPENDENCIES)
+ @rm -f test-unistd$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_unistd_OBJECTS) $(test_unistd_LDADD) $(LIBS)
+test-unsetenv$(EXEEXT): $(test_unsetenv_OBJECTS) $(test_unsetenv_DEPENDENCIES)
+ @rm -f test-unsetenv$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_unsetenv_OBJECTS) $(test_unsetenv_LDADD) $(LIBS)
+test-vasnprintf$(EXEEXT): $(test_vasnprintf_OBJECTS) $(test_vasnprintf_DEPENDENCIES)
+ @rm -f test-vasnprintf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_vasnprintf_OBJECTS) $(test_vasnprintf_LDADD) $(LIBS)
+test-vasnprintf-posix$(EXEEXT): $(test_vasnprintf_posix_OBJECTS) $(test_vasnprintf_posix_DEPENDENCIES)
+ @rm -f test-vasnprintf-posix$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_vasnprintf_posix_OBJECTS) $(test_vasnprintf_posix_LDADD) $(LIBS)
+test-vasnprintf-posix2$(EXEEXT): $(test_vasnprintf_posix2_OBJECTS) $(test_vasnprintf_posix2_DEPENDENCIES)
+ @rm -f test-vasnprintf-posix2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_vasnprintf_posix2_OBJECTS) $(test_vasnprintf_posix2_LDADD) $(LIBS)
+test-vasprintf$(EXEEXT): $(test_vasprintf_OBJECTS) $(test_vasprintf_DEPENDENCIES)
+ @rm -f test-vasprintf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_vasprintf_OBJECTS) $(test_vasprintf_LDADD) $(LIBS)
+test-vasprintf-posix$(EXEEXT): $(test_vasprintf_posix_OBJECTS) $(test_vasprintf_posix_DEPENDENCIES)
+ @rm -f test-vasprintf-posix$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_vasprintf_posix_OBJECTS) $(test_vasprintf_posix_LDADD) $(LIBS)
+test-vfprintf-posix$(EXEEXT): $(test_vfprintf_posix_OBJECTS) $(test_vfprintf_posix_DEPENDENCIES)
+ @rm -f test-vfprintf-posix$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_vfprintf_posix_OBJECTS) $(test_vfprintf_posix_LDADD) $(LIBS)
+test-vprintf-posix$(EXEEXT): $(test_vprintf_posix_OBJECTS) $(test_vprintf_posix_DEPENDENCIES)
+ @rm -f test-vprintf-posix$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_vprintf_posix_OBJECTS) $(test_vprintf_posix_LDADD) $(LIBS)
+test-wchar$(EXEEXT): $(test_wchar_OBJECTS) $(test_wchar_DEPENDENCIES)
+ @rm -f test-wchar$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_wchar_OBJECTS) $(test_wchar_LDADD) $(LIBS)
+test-wcrtomb$(EXEEXT): $(test_wcrtomb_OBJECTS) $(test_wcrtomb_DEPENDENCIES)
+ @rm -f test-wcrtomb$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_wcrtomb_OBJECTS) $(test_wcrtomb_LDADD) $(LIBS)
+test-wctype$(EXEEXT): $(test_wctype_OBJECTS) $(test_wctype_DEPENDENCIES)
+ @rm -f test-wctype$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_wctype_OBJECTS) $(test_wctype_LDADD) $(LIBS)
+test-wcwidth$(EXEEXT): $(test_wcwidth_OBJECTS) $(test_wcwidth_DEPENDENCIES)
+ @rm -f test-wcwidth$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_wcwidth_OBJECTS) $(test_wcwidth_LDADD) $(LIBS)
+test-xalloc-die$(EXEEXT): $(test_xalloc_die_OBJECTS) $(test_xalloc_die_DEPENDENCIES)
+ @rm -f test-xalloc-die$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_xalloc_die_OBJECTS) $(test_xalloc_die_LDADD) $(LIBS)
+test-xfprintf-posix$(EXEEXT): $(test_xfprintf_posix_OBJECTS) $(test_xfprintf_posix_DEPENDENCIES)
+ @rm -f test-xfprintf-posix$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_xfprintf_posix_OBJECTS) $(test_xfprintf_posix_LDADD) $(LIBS)
+test-xmemdup0$(EXEEXT): $(test_xmemdup0_OBJECTS) $(test_xmemdup0_DEPENDENCIES)
+ @rm -f test-xmemdup0$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_xmemdup0_OBJECTS) $(test_xmemdup0_LDADD) $(LIBS)
+test-xprintf-posix$(EXEEXT): $(test_xprintf_posix_OBJECTS) $(test_xprintf_posix_DEPENDENCIES)
+ @rm -f test-xprintf-posix$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_xprintf_posix_OBJECTS) $(test_xprintf_posix_LDADD) $(LIBS)
+test-xvasprintf$(EXEEXT): $(test_xvasprintf_OBJECTS) $(test_xvasprintf_DEPENDENCIES)
+ @rm -f test-xvasprintf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_xvasprintf_OBJECTS) $(test_xvasprintf_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f uniwidth/test-uc_width.$(OBJEXT)
+ -rm -f uniwidth/test-uc_width2.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getpagesize.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_array_list.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_array_oset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obstack_printf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putenv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strdup.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symlink.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-alloca-opt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-array_list.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-array_oset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-avltree_oset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-binary-io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-bitrotate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-btowc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-c-ctype.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-c-strcasecmp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-c-strncasecmp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-canonicalize-lgpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-cloexec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-closein.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dirname.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dup-safer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dup2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-environ.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-errno.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fcntl-h.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fcntl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fflush.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fflush2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-filenamecat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fopen-safer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fopen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fpending.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fpurge.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-freadahead.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-freading.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-freadptr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-freadptr2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-freadseek.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-frexp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-frexpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fseeko.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fseterr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ftello.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-getdtablesize.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-gettimeofday.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-iconv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-inttypes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-isnand-nolibm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-isnanf-nolibm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-isnanl-nolibm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-langinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-link.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-linkedhash_list.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-lseek.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-lstat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-malloca.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-math.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-mbrtowc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-mbsinit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-mbsstr1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-mbsstr2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-mbsstr3.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-memchr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-memchr2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-memmem.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nl_langinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-obstack-printf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-open.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-pipe.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-pipe2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-posix_spawn1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-posix_spawn2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-printf-frexp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-printf-frexpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-quotearg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-rawmemchr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-readlink.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-rename.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-rmdir.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sched.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-setenv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sigaction.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-signal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-signbit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-snprintf-posix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-snprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-spawn.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sprintf-posix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stdbool.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stddef.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stdint.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stdio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stdlib.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-strchrnul.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-strerror.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-striconv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-string.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-strtod.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-symlink.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sys_stat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sys_time.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sys_wait.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-time.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-unistd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-unsetenv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-vasnprintf-posix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-vasnprintf-posix2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-vasnprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-vasprintf-posix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-vasprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-vfprintf-posix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-vprintf-posix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wchar.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wcrtomb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wctype.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wcwidth.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-xalloc-die.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-xfprintf-posix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-xmemdup0.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-xprintf-posix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-xvasprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wctob.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@uniwidth/$(DEPDIR)/test-uc_width.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@uniwidth/$(DEPDIR)/test-uc_width2.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# To be appended to the command running the test. Handle the stdout
+# and stderr redirection, and catch the exit status.
+am__check_post = \
+>$@-t 2>&1; \
+estatus=$$?; \
+if test -n '$(DISABLE_HARD_ERRORS)' \
+ && test $$estatus -eq 99; then \
+ estatus=1; \
+fi; \
+TERM=$$__SAVED_TERM; export TERM; \
+$(am__tty_colors); \
+xfailed=PASS; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ xfailed=XFAIL;; \
+esac; \
+case $$estatus:$$xfailed in \
+ 0:XFAIL) col=$$red; res=XPASS;; \
+ 0:*) col=$$grn; res=PASS ;; \
+ 77:*) col=$$blu; res=SKIP ;; \
+ 99:*) col=$$red; res=FAIL ;; \
+ *:XFAIL) col=$$lgn; res=XFAIL;; \
+ *:*) col=$$red; res=FAIL ;; \
+esac; \
+echo "$${col}$$res$${std}: $$f"; \
+echo "$$res: $$f (exit: $$estatus)" | \
+ $(am__rst_section) >$@; \
+cat $@-t >>$@; \
+rm -f $@-t
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__sh_e_setup); \
+ list='$(TEST_LOGS)'; \
+ results=`for f in $$list; do \
+ read line < $$f && echo "$$line" || echo FAIL; \
+ done`; \
+ all=`echo "$$results" | sed '/^$$/d' | wc -l | sed -e 's/^[ ]*//'`; \
+ fail=`echo "$$results" | grep -c '^FAIL'`; \
+ pass=`echo "$$results" | grep -c '^PASS'`; \
+ skip=`echo "$$results" | grep -c '^SKIP'`; \
+ xfail=`echo "$$results" | grep -c '^XFAIL'`; \
+ xpass=`echo "$$results" | grep -c '^XPASS'`; \
+ failures=`expr $$fail + $$xpass`; \
+ all=`expr $$all - $$skip`; \
+ if test "$$all" -eq 1; then tests=test; All=; \
+ else tests=tests; All="All "; fi; \
+ case fail=$$fail:xpass=$$xpass:xfail=$$xfail in \
+ fail=0:xpass=0:xfail=0) \
+ msg="$$All$$all $$tests passed. "; \
+ exit=true;; \
+ fail=0:xpass=0:xfail=*) \
+ msg="$$All$$all $$tests behaved as expected"; \
+ if test "$$xfail" -eq 1; then xfailures=failure; \
+ else xfailures=failures; fi; \
+ msg="$$msg ($$xfail expected $$xfailures). "; \
+ exit=true;; \
+ fail=*:xpass=0:xfail=*) \
+ msg="$$fail of $$all $$tests failed. "; \
+ exit=false;; \
+ fail=*:xpass=*:xfail=*) \
+ msg="$$failures of $$all $$tests did not behave as expected"; \
+ if test "$$xpass" -eq 1; then xpasses=pass; \
+ else xpasses=passes; fi; \
+ msg="$$msg ($$xpass unexpected $$xpasses). "; \
+ exit=false;; \
+ *) \
+ echo >&2 "incorrect case"; exit 4;; \
+ esac; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ msg="$$msg($$skip test was not run). "; \
+ else \
+ msg="$$msg($$skip tests were not run). "; \
+ fi; \
+ fi; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ echo "$$msg"; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for f in $$list; do \
+ read line < $$f; \
+ case $$line in \
+ PASS:*|XFAIL:*);; \
+ *) echo; cat $$f;; \
+ esac; \
+ done; \
+ } >$(TEST_SUITE_LOG).tmp; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if test "$$failures" -ne 0; then \
+ msg="$${msg}See $(subdir)/$(TEST_SUITE_LOG). "; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ msg="$${msg}Please report to $(PACKAGE_BUGREPORT). "; \
+ fi; \
+ fi; \
+ test x"$$VERBOSE" = x || $$exit || cat $(TEST_SUITE_LOG); \
+ $(am__tty_colors); \
+ if $$exit; then \
+ echo $(ECHO_N) "$$grn$(ECHO_C)"; \
+ else \
+ echo $(ECHO_N) "$$red$(ECHO_C)"; \
+ fi; \
+ echo "$$msg" | $(am__text_box); \
+ echo $(ECHO_N) "$$std$(ECHO_C)"; \
+ $$exit
+
+# Run all the tests.
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @list='$(TEST_LOGS)'; \
+ list=`for f in $$list; do \
+ test .log = $$f || echo $$f; \
+ done | tr '\012\015' ' '`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$list"
+
+.log.html:
+ @list='$(RST2HTML) $$RST2HTML rst2html rst2html.py'; \
+ for r2h in $$list; do \
+ if ($$r2h --version) >/dev/null 2>&1; then \
+ R2H=$$r2h; \
+ fi; \
+ done; \
+ if test -z "$$R2H"; then \
+ echo >&2 "cannot find rst2html, cannot create $@"; \
+ exit 2; \
+ fi; \
+ $$R2H $< >$@.tmp
+ @mv $@.tmp $@
+
+# Be sure to run check first, and then to convert the result.
+# Beware of concurrent executions. Run "check" not "check-TESTS", as
+# check-SCRIPTS and other dependencies are rebuilt by the former only.
+# And expect check to fail.
+check-html:
+ @if $(MAKE) $(AM_MAKEFLAGS) check; then \
+ rv=0; else rv=$$?; \
+ fi; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_HTML) || exit 4; \
+ exit $$rv
+recheck recheck-html:
+ @target=`echo $@ | sed 's,^re,,'`; \
+ list='$(TEST_LOGS)'; \
+ list=`for f in $$list; do \
+ test -f $$f || continue; \
+ if read line < $$f; then \
+ case $$line in FAIL*|XPASS*) echo $$f;; esac; \
+ else echo $$f; fi; \
+ done | tr '\012\015' ' '`; \
+ $(MAKE) $(AM_MAKEFLAGS) $$target AM_MAKEFLAGS='$(AM_MAKEFLAGS) TEST_LOGS="'"$$list"'"'
+test-alloca-opt.log: test-alloca-opt$(EXEEXT)
+ @p='test-alloca-opt$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-array_list.log: test-array_list$(EXEEXT)
+ @p='test-array_list$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-array_oset.log: test-array_oset$(EXEEXT)
+ @p='test-array_oset$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-avltree_oset.log: test-avltree_oset$(EXEEXT)
+ @p='test-avltree_oset$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-binary-io.sh.log: test-binary-io.sh
+ @p='test-binary-io.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-bitrotate.log: test-bitrotate$(EXEEXT)
+ @p='test-bitrotate$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-btowc1.sh.log: test-btowc1.sh
+ @p='test-btowc1.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-btowc2.sh.log: test-btowc2.sh
+ @p='test-btowc2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-c-ctype.log: test-c-ctype$(EXEEXT)
+ @p='test-c-ctype$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-c-strcase.sh.log: test-c-strcase.sh
+ @p='test-c-strcase.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-canonicalize-lgpl.log: test-canonicalize-lgpl$(EXEEXT)
+ @p='test-canonicalize-lgpl$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-cloexec.log: test-cloexec$(EXEEXT)
+ @p='test-cloexec$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-closein.sh.log: test-closein.sh
+ @p='test-closein.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-dirname.log: test-dirname$(EXEEXT)
+ @p='test-dirname$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-dup2.log: test-dup2$(EXEEXT)
+ @p='test-dup2$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-environ.log: test-environ$(EXEEXT)
+ @p='test-environ$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-errno.log: test-errno$(EXEEXT)
+ @p='test-errno$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fcntl-h.log: test-fcntl-h$(EXEEXT)
+ @p='test-fcntl-h$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fcntl.log: test-fcntl$(EXEEXT)
+ @p='test-fcntl$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fflush.log: test-fflush$(EXEEXT)
+ @p='test-fflush$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fflush2.sh.log: test-fflush2.sh
+ @p='test-fflush2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-filenamecat.log: test-filenamecat$(EXEEXT)
+ @p='test-filenamecat$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fopen-safer.log: test-fopen-safer$(EXEEXT)
+ @p='test-fopen-safer$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fopen.log: test-fopen$(EXEEXT)
+ @p='test-fopen$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fpending.sh.log: test-fpending.sh
+ @p='test-fpending.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fpurge.log: test-fpurge$(EXEEXT)
+ @p='test-fpurge$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-freadahead.sh.log: test-freadahead.sh
+ @p='test-freadahead.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-freading.log: test-freading$(EXEEXT)
+ @p='test-freading$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-freadptr.sh.log: test-freadptr.sh
+ @p='test-freadptr.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-freadptr2.sh.log: test-freadptr2.sh
+ @p='test-freadptr2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-freadseek.sh.log: test-freadseek.sh
+ @p='test-freadseek.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-frexp-nolibm.log: test-frexp-nolibm$(EXEEXT)
+ @p='test-frexp-nolibm$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-frexpl-nolibm.log: test-frexpl-nolibm$(EXEEXT)
+ @p='test-frexpl-nolibm$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fseeko.sh.log: test-fseeko.sh
+ @p='test-fseeko.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fseeko2.sh.log: test-fseeko2.sh
+ @p='test-fseeko2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-fseterr.log: test-fseterr$(EXEEXT)
+ @p='test-fseterr$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-ftello.sh.log: test-ftello.sh
+ @p='test-ftello.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-ftello2.sh.log: test-ftello2.sh
+ @p='test-ftello2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-getdtablesize.log: test-getdtablesize$(EXEEXT)
+ @p='test-getdtablesize$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-gettimeofday.log: test-gettimeofday$(EXEEXT)
+ @p='test-gettimeofday$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-iconv.log: test-iconv$(EXEEXT)
+ @p='test-iconv$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-inttypes.log: test-inttypes$(EXEEXT)
+ @p='test-inttypes$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-isnand-nolibm.log: test-isnand-nolibm$(EXEEXT)
+ @p='test-isnand-nolibm$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-isnanf-nolibm.log: test-isnanf-nolibm$(EXEEXT)
+ @p='test-isnanf-nolibm$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-isnanl-nolibm.log: test-isnanl-nolibm$(EXEEXT)
+ @p='test-isnanl-nolibm$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-langinfo.log: test-langinfo$(EXEEXT)
+ @p='test-langinfo$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-link.log: test-link$(EXEEXT)
+ @p='test-link$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-linkedhash_list.log: test-linkedhash_list$(EXEEXT)
+ @p='test-linkedhash_list$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-lseek.sh.log: test-lseek.sh
+ @p='test-lseek.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-lstat.log: test-lstat$(EXEEXT)
+ @p='test-lstat$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-malloca.log: test-malloca$(EXEEXT)
+ @p='test-malloca$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-math.log: test-math$(EXEEXT)
+ @p='test-math$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbrtowc1.sh.log: test-mbrtowc1.sh
+ @p='test-mbrtowc1.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbrtowc2.sh.log: test-mbrtowc2.sh
+ @p='test-mbrtowc2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbrtowc3.sh.log: test-mbrtowc3.sh
+ @p='test-mbrtowc3.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbrtowc4.sh.log: test-mbrtowc4.sh
+ @p='test-mbrtowc4.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbsinit.sh.log: test-mbsinit.sh
+ @p='test-mbsinit.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbsstr1.log: test-mbsstr1$(EXEEXT)
+ @p='test-mbsstr1$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbsstr2.sh.log: test-mbsstr2.sh
+ @p='test-mbsstr2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbsstr3.sh.log: test-mbsstr3.sh
+ @p='test-mbsstr3.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-memchr.log: test-memchr$(EXEEXT)
+ @p='test-memchr$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-memchr2.log: test-memchr2$(EXEEXT)
+ @p='test-memchr2$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-memmem.log: test-memmem$(EXEEXT)
+ @p='test-memmem$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-nl_langinfo.sh.log: test-nl_langinfo.sh
+ @p='test-nl_langinfo.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-obstack-printf.log: test-obstack-printf$(EXEEXT)
+ @p='test-obstack-printf$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-open.log: test-open$(EXEEXT)
+ @p='test-open$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-pipe.sh.log: test-pipe.sh
+ @p='test-pipe.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-pipe2.log: test-pipe2$(EXEEXT)
+ @p='test-pipe2$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-posix_spawn1.log: test-posix_spawn1$(EXEEXT)
+ @p='test-posix_spawn1$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-posix_spawn2.log: test-posix_spawn2$(EXEEXT)
+ @p='test-posix_spawn2$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-printf-frexp.log: test-printf-frexp$(EXEEXT)
+ @p='test-printf-frexp$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-printf-frexpl.log: test-printf-frexpl$(EXEEXT)
+ @p='test-printf-frexpl$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-quotearg.sh.log: test-quotearg.sh
+ @p='test-quotearg.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-rawmemchr.log: test-rawmemchr$(EXEEXT)
+ @p='test-rawmemchr$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-readlink.log: test-readlink$(EXEEXT)
+ @p='test-readlink$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-rename.log: test-rename$(EXEEXT)
+ @p='test-rename$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-rmdir.log: test-rmdir$(EXEEXT)
+ @p='test-rmdir$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-sched.log: test-sched$(EXEEXT)
+ @p='test-sched$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-setenv.log: test-setenv$(EXEEXT)
+ @p='test-setenv$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-sigaction.log: test-sigaction$(EXEEXT)
+ @p='test-sigaction$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-signal.log: test-signal$(EXEEXT)
+ @p='test-signal$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-signbit.log: test-signbit$(EXEEXT)
+ @p='test-signbit$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-snprintf-posix.log: test-snprintf-posix$(EXEEXT)
+ @p='test-snprintf-posix$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-snprintf.log: test-snprintf$(EXEEXT)
+ @p='test-snprintf$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-spawn.log: test-spawn$(EXEEXT)
+ @p='test-spawn$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-sprintf-posix.log: test-sprintf-posix$(EXEEXT)
+ @p='test-sprintf-posix$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-stat.log: test-stat$(EXEEXT)
+ @p='test-stat$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-stdbool.log: test-stdbool$(EXEEXT)
+ @p='test-stdbool$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-stddef.log: test-stddef$(EXEEXT)
+ @p='test-stddef$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-stdint.log: test-stdint$(EXEEXT)
+ @p='test-stdint$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-stdio.log: test-stdio$(EXEEXT)
+ @p='test-stdio$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-stdlib.log: test-stdlib$(EXEEXT)
+ @p='test-stdlib$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-strchrnul.log: test-strchrnul$(EXEEXT)
+ @p='test-strchrnul$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-strerror.log: test-strerror$(EXEEXT)
+ @p='test-strerror$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-striconv.log: test-striconv$(EXEEXT)
+ @p='test-striconv$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-string.log: test-string$(EXEEXT)
+ @p='test-string$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-strtod.log: test-strtod$(EXEEXT)
+ @p='test-strtod$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-symlink.log: test-symlink$(EXEEXT)
+ @p='test-symlink$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-sys_stat.log: test-sys_stat$(EXEEXT)
+ @p='test-sys_stat$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-sys_time.log: test-sys_time$(EXEEXT)
+ @p='test-sys_time$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-sys_wait.log: test-sys_wait$(EXEEXT)
+ @p='test-sys_wait$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-time.log: test-time$(EXEEXT)
+ @p='test-time$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-dup-safer.log: test-dup-safer$(EXEEXT)
+ @p='test-dup-safer$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-unistd.log: test-unistd$(EXEEXT)
+ @p='test-unistd$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-uc_width.log: test-uc_width$(EXEEXT)
+ @p='test-uc_width$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+uniwidth/test-uc_width2.sh.log: uniwidth/test-uc_width2.sh
+ @p='uniwidth/test-uc_width2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-unsetenv.log: test-unsetenv$(EXEEXT)
+ @p='test-unsetenv$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-update-copyright.sh.log: test-update-copyright.sh
+ @p='test-update-copyright.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vasnprintf-posix.log: test-vasnprintf-posix$(EXEEXT)
+ @p='test-vasnprintf-posix$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vasnprintf-posix2.sh.log: test-vasnprintf-posix2.sh
+ @p='test-vasnprintf-posix2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vasnprintf.log: test-vasnprintf$(EXEEXT)
+ @p='test-vasnprintf$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vasprintf-posix.log: test-vasprintf-posix$(EXEEXT)
+ @p='test-vasprintf-posix$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vasprintf.log: test-vasprintf$(EXEEXT)
+ @p='test-vasprintf$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vc-list-files-git.sh.log: test-vc-list-files-git.sh
+ @p='test-vc-list-files-git.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vc-list-files-cvs.sh.log: test-vc-list-files-cvs.sh
+ @p='test-vc-list-files-cvs.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vfprintf-posix.sh.log: test-vfprintf-posix.sh
+ @p='test-vfprintf-posix.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-vprintf-posix.sh.log: test-vprintf-posix.sh
+ @p='test-vprintf-posix.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wchar.log: test-wchar$(EXEEXT)
+ @p='test-wchar$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wcrtomb.sh.log: test-wcrtomb.sh
+ @p='test-wcrtomb.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wctype.log: test-wctype$(EXEEXT)
+ @p='test-wctype$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wcwidth.log: test-wcwidth$(EXEEXT)
+ @p='test-wcwidth$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-xalloc-die.sh.log: test-xalloc-die.sh
+ @p='test-xalloc-die.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-xmemdup0.log: test-xmemdup0$(EXEEXT)
+ @p='test-xmemdup0$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-xprintf-posix.sh.log: test-xprintf-posix.sh
+ @p='test-xprintf-posix.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-xvasprintf.log: test-xvasprintf$(EXEEXT)
+ @p='test-xvasprintf$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+.test.log:
+ @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LIBRARIES) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS_TMP)" || rm -f $(TEST_LOGS_TMP)
+ -test -z "$(TEST_SUITE_HTML)" || rm -f $(TEST_SUITE_HTML)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f uniwidth/$(DEPDIR)/$(am__dirstamp)
+ -rm -f uniwidth/$(am__dirstamp)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-checkLIBRARIES clean-checkPROGRAMS clean-generic \
+ clean-libtool clean-local clean-noinstLIBRARIES \
+ clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR) uniwidth/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR) uniwidth/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-local
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+ check-am check-html ctags-recursive install install-am \
+ install-strip recheck recheck-html tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-TESTS check-am check-html clean \
+ clean-checkLIBRARIES clean-checkPROGRAMS clean-generic \
+ clean-libtool clean-local clean-noinstLIBRARIES \
+ clean-noinstPROGRAMS ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-local pdf pdf-am ps ps-am \
+ recheck recheck-html tags tags-recursive uninstall \
+ uninstall-am
+
+# The arg-nonnull.h that gets inserted into generated .h files is the same as
+# build-aux/arg-nonnull.h, except that it has the copyright header cut off.
+arg-nonnull.h: $(top_srcdir)/build-aux/arg-nonnull.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/GL_ARG_NONNULL/,$$p' \
+ < $(top_srcdir)/build-aux/arg-nonnull.h \
+ > $@-t && \
+ mv $@-t $@
+@POSIX_SPAWN_PORTED_TRUE@test-posix_spawn1.sh: test-posix_spawn1.in.sh
+@POSIX_SPAWN_PORTED_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \
+@POSIX_SPAWN_PORTED_TRUE@ cp $(srcdir)/test-posix_spawn1.in.sh $@-t && \
+@POSIX_SPAWN_PORTED_TRUE@ mv $@-t $@
+@POSIX_SPAWN_PORTED_TRUE@test-posix_spawn2.sh: test-posix_spawn2.in.sh
+@POSIX_SPAWN_PORTED_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \
+@POSIX_SPAWN_PORTED_TRUE@ cp $(srcdir)/test-posix_spawn2.in.sh $@-t && \
+@POSIX_SPAWN_PORTED_TRUE@ mv $@-t $@
+# The warn-on-use.h that gets inserted into generated .h files is the same as
+# build-aux/warn-on-use.h, except that it has the copyright header cut off.
+warn-on-use.h: $(top_srcdir)/build-aux/warn-on-use.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/^.ifndef/,$$p' \
+ < $(top_srcdir)/build-aux/warn-on-use.h \
+ > $@-t && \
+ mv $@-t $@
+
+# Clean up after Solaris cc.
+clean-local:
+ rm -rf SunWS_cache
+
+mostlyclean-local: mostlyclean-generic
+ @for dir in '' $(MOSTLYCLEANDIRS); do \
+ if test -n "$$dir" && test -d $$dir; then \
+ echo "rmdir $$dir"; rmdir $$dir; \
+ fi; \
+ done; \
+ :
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/gnu/getpagesize.c b/tests/gnu/getpagesize.c
new file mode 100755
index 00000000..cc252687
--- /dev/null
+++ b/tests/gnu/getpagesize.c
@@ -0,0 +1,39 @@
+/* getpagesize emulation for systems where it cannot be done in a C macro.
+
+ Copyright (C) 2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible and Martin Lambers. */
+
+#include <config.h>
+
+/* Specification. */
+#include <unistd.h>
+
+/* This implementation is only for native Win32 systems. */
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+int
+getpagesize (void)
+{
+ SYSTEM_INFO system_info;
+ GetSystemInfo (&system_info);
+ return system_info.dwPageSize;
+}
+
+#endif
diff --git a/tests/gnu/gl_array_list.c b/tests/gnu/gl_array_list.c
new file mode 100755
index 00000000..106dc216
--- /dev/null
+++ b/tests/gnu/gl_array_list.c
@@ -0,0 +1,680 @@
+/* Sequential list data type implemented by an array.
+ Copyright (C) 2006-2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include "gl_array_list.h"
+
+#include <stdlib.h>
+/* Get memcpy. */
+#include <string.h>
+
+/* Checked size_t computations. */
+#include "xsize.h"
+
+#ifndef uintptr_t
+# define uintptr_t unsigned long
+#endif
+
+/* -------------------------- gl_list_t Data Type -------------------------- */
+
+/* Concrete gl_list_impl type, valid for this file only. */
+struct gl_list_impl
+{
+ struct gl_list_impl_base base;
+ /* An array of ALLOCATED elements, of which the first COUNT are used.
+ 0 <= COUNT <= ALLOCATED. */
+ const void **elements;
+ size_t count;
+ size_t allocated;
+};
+
+/* struct gl_list_node_impl doesn't exist here. The pointers are actually
+ indices + 1. */
+#define INDEX_TO_NODE(index) (gl_list_node_t)(uintptr_t)(size_t)((index) + 1)
+#define NODE_TO_INDEX(node) ((uintptr_t)(node) - 1)
+
+static gl_list_t
+gl_array_nx_create_empty (gl_list_implementation_t implementation,
+ gl_listelement_equals_fn equals_fn,
+ gl_listelement_hashcode_fn hashcode_fn,
+ gl_listelement_dispose_fn dispose_fn,
+ bool allow_duplicates)
+{
+ struct gl_list_impl *list =
+ (struct gl_list_impl *) malloc (sizeof (struct gl_list_impl));
+
+ if (list == NULL)
+ return NULL;
+
+ list->base.vtable = implementation;
+ list->base.equals_fn = equals_fn;
+ list->base.hashcode_fn = hashcode_fn;
+ list->base.dispose_fn = dispose_fn;
+ list->base.allow_duplicates = allow_duplicates;
+ list->elements = NULL;
+ list->count = 0;
+ list->allocated = 0;
+
+ return list;
+}
+
+static gl_list_t
+gl_array_nx_create (gl_list_implementation_t implementation,
+ gl_listelement_equals_fn equals_fn,
+ gl_listelement_hashcode_fn hashcode_fn,
+ gl_listelement_dispose_fn dispose_fn,
+ bool allow_duplicates,
+ size_t count, const void **contents)
+{
+ struct gl_list_impl *list =
+ (struct gl_list_impl *) malloc (sizeof (struct gl_list_impl));
+
+ if (list == NULL)
+ return NULL;
+
+ list->base.vtable = implementation;
+ list->base.equals_fn = equals_fn;
+ list->base.hashcode_fn = hashcode_fn;
+ list->base.dispose_fn = dispose_fn;
+ list->base.allow_duplicates = allow_duplicates;
+ if (count > 0)
+ {
+ if (size_overflow_p (xtimes (count, sizeof (const void *))))
+ goto fail;
+ list->elements = (const void **) malloc (count * sizeof (const void *));
+ if (list->elements == NULL)
+ goto fail;
+ memcpy (list->elements, contents, count * sizeof (const void *));
+ }
+ else
+ list->elements = NULL;
+ list->count = count;
+ list->allocated = count;
+
+ return list;
+
+ fail:
+ free (list);
+ return NULL;
+}
+
+static size_t
+gl_array_size (gl_list_t list)
+{
+ return list->count;
+}
+
+static const void *
+gl_array_node_value (gl_list_t list, gl_list_node_t node)
+{
+ uintptr_t index = NODE_TO_INDEX (node);
+ if (!(index < list->count))
+ /* Invalid argument. */
+ abort ();
+ return list->elements[index];
+}
+
+static int
+gl_array_node_nx_set_value (gl_list_t list, gl_list_node_t node,
+ const void *elt)
+{
+ uintptr_t index = NODE_TO_INDEX (node);
+ if (!(index < list->count))
+ /* Invalid argument. */
+ abort ();
+ list->elements[index] = elt;
+ return 0;
+}
+
+static gl_list_node_t
+gl_array_next_node (gl_list_t list, gl_list_node_t node)
+{
+ uintptr_t index = NODE_TO_INDEX (node);
+ if (!(index < list->count))
+ /* Invalid argument. */
+ abort ();
+ index++;
+ if (index < list->count)
+ return INDEX_TO_NODE (index);
+ else
+ return NULL;
+}
+
+static gl_list_node_t
+gl_array_previous_node (gl_list_t list, gl_list_node_t node)
+{
+ uintptr_t index = NODE_TO_INDEX (node);
+ if (!(index < list->count))
+ /* Invalid argument. */
+ abort ();
+ if (index > 0)
+ return INDEX_TO_NODE (index - 1);
+ else
+ return NULL;
+}
+
+static const void *
+gl_array_get_at (gl_list_t list, size_t position)
+{
+ size_t count = list->count;
+
+ if (!(position < count))
+ /* Invalid argument. */
+ abort ();
+ return list->elements[position];
+}
+
+static gl_list_node_t
+gl_array_nx_set_at (gl_list_t list, size_t position, const void *elt)
+{
+ size_t count = list->count;
+
+ if (!(position < count))
+ /* Invalid argument. */
+ abort ();
+ list->elements[position] = elt;
+ return INDEX_TO_NODE (position);
+}
+
+static size_t
+gl_array_indexof_from_to (gl_list_t list, size_t start_index, size_t end_index,
+ const void *elt)
+{
+ size_t count = list->count;
+
+ if (!(start_index <= end_index && end_index <= count))
+ /* Invalid arguments. */
+ abort ();
+
+ if (start_index < end_index)
+ {
+ gl_listelement_equals_fn equals = list->base.equals_fn;
+ if (equals != NULL)
+ {
+ size_t i;
+
+ for (i = start_index;;)
+ {
+ if (equals (elt, list->elements[i]))
+ return i;
+ i++;
+ if (i == end_index)
+ break;
+ }
+ }
+ else
+ {
+ size_t i;
+
+ for (i = start_index;;)
+ {
+ if (elt == list->elements[i])
+ return i;
+ i++;
+ if (i == end_index)
+ break;
+ }
+ }
+ }
+ return (size_t)(-1);
+}
+
+static gl_list_node_t
+gl_array_search_from_to (gl_list_t list, size_t start_index, size_t end_index,
+ const void *elt)
+{
+ size_t index = gl_array_indexof_from_to (list, start_index, end_index, elt);
+ return INDEX_TO_NODE (index);
+}
+
+/* Ensure that list->allocated > list->count.
+ Return 0 upon success, -1 upon out-of-memory. */
+static int
+grow (gl_list_t list)
+{
+ size_t new_allocated;
+ size_t memory_size;
+ const void **memory;
+
+ new_allocated = xtimes (list->allocated, 2);
+ new_allocated = xsum (new_allocated, 1);
+ memory_size = xtimes (new_allocated, sizeof (const void *));
+ if (size_overflow_p (memory_size))
+ /* Overflow, would lead to out of memory. */
+ return -1;
+ memory = (const void **) realloc (list->elements, memory_size);
+ if (memory == NULL)
+ /* Out of memory. */
+ return -1;
+ list->elements = memory;
+ list->allocated = new_allocated;
+ return 0;
+}
+
+static gl_list_node_t
+gl_array_nx_add_first (gl_list_t list, const void *elt)
+{
+ size_t count = list->count;
+ const void **elements;
+ size_t i;
+
+ if (count == list->allocated)
+ if (grow (list) < 0)
+ return NULL;
+ elements = list->elements;
+ for (i = count; i > 0; i--)
+ elements[i] = elements[i - 1];
+ elements[0] = elt;
+ list->count = count + 1;
+ return INDEX_TO_NODE (0);
+}
+
+static gl_list_node_t
+gl_array_nx_add_last (gl_list_t list, const void *elt)
+{
+ size_t count = list->count;
+
+ if (count == list->allocated)
+ if (grow (list) < 0)
+ return NULL;
+ list->elements[count] = elt;
+ list->count = count + 1;
+ return INDEX_TO_NODE (count);
+}
+
+static gl_list_node_t
+gl_array_nx_add_before (gl_list_t list, gl_list_node_t node, const void *elt)
+{
+ size_t count = list->count;
+ uintptr_t index = NODE_TO_INDEX (node);
+ size_t position;
+ const void **elements;
+ size_t i;
+
+ if (!(index < count))
+ /* Invalid argument. */
+ abort ();
+ position = index;
+ if (count == list->allocated)
+ if (grow (list) < 0)
+ return NULL;
+ elements = list->elements;
+ for (i = count; i > position; i--)
+ elements[i] = elements[i - 1];
+ elements[position] = elt;
+ list->count = count + 1;
+ return INDEX_TO_NODE (position);
+}
+
+static gl_list_node_t
+gl_array_nx_add_after (gl_list_t list, gl_list_node_t node, const void *elt)
+{
+ size_t count = list->count;
+ uintptr_t index = NODE_TO_INDEX (node);
+ size_t position;
+ const void **elements;
+ size_t i;
+
+ if (!(index < count))
+ /* Invalid argument. */
+ abort ();
+ position = index + 1;
+ if (count == list->allocated)
+ if (grow (list) < 0)
+ return NULL;
+ elements = list->elements;
+ for (i = count; i > position; i--)
+ elements[i] = elements[i - 1];
+ elements[position] = elt;
+ list->count = count + 1;
+ return INDEX_TO_NODE (position);
+}
+
+static gl_list_node_t
+gl_array_nx_add_at (gl_list_t list, size_t position, const void *elt)
+{
+ size_t count = list->count;
+ const void **elements;
+ size_t i;
+
+ if (!(position <= count))
+ /* Invalid argument. */
+ abort ();
+ if (count == list->allocated)
+ if (grow (list) < 0)
+ return NULL;
+ elements = list->elements;
+ for (i = count; i > position; i--)
+ elements[i] = elements[i - 1];
+ elements[position] = elt;
+ list->count = count + 1;
+ return INDEX_TO_NODE (position);
+}
+
+static bool
+gl_array_remove_node (gl_list_t list, gl_list_node_t node)
+{
+ size_t count = list->count;
+ uintptr_t index = NODE_TO_INDEX (node);
+ size_t position;
+ const void **elements;
+ size_t i;
+
+ if (!(index < count))
+ /* Invalid argument. */
+ abort ();
+ position = index;
+ elements = list->elements;
+ if (list->base.dispose_fn != NULL)
+ list->base.dispose_fn (elements[position]);
+ for (i = position + 1; i < count; i++)
+ elements[i - 1] = elements[i];
+ list->count = count - 1;
+ return true;
+}
+
+static bool
+gl_array_remove_at (gl_list_t list, size_t position)
+{
+ size_t count = list->count;
+ const void **elements;
+ size_t i;
+
+ if (!(position < count))
+ /* Invalid argument. */
+ abort ();
+ elements = list->elements;
+ if (list->base.dispose_fn != NULL)
+ list->base.dispose_fn (elements[position]);
+ for (i = position + 1; i < count; i++)
+ elements[i - 1] = elements[i];
+ list->count = count - 1;
+ return true;
+}
+
+static bool
+gl_array_remove (gl_list_t list, const void *elt)
+{
+ size_t position = gl_array_indexof_from_to (list, 0, list->count, elt);
+ if (position == (size_t)(-1))
+ return false;
+ else
+ return gl_array_remove_at (list, position);
+}
+
+static void
+gl_array_list_free (gl_list_t list)
+{
+ if (list->elements != NULL)
+ {
+ if (list->base.dispose_fn != NULL)
+ {
+ size_t count = list->count;
+
+ if (count > 0)
+ {
+ gl_listelement_dispose_fn dispose = list->base.dispose_fn;
+ const void **elements = list->elements;
+
+ do
+ dispose (*elements++);
+ while (--count > 0);
+ }
+ }
+ free (list->elements);
+ }
+ free (list);
+}
+
+/* --------------------- gl_list_iterator_t Data Type --------------------- */
+
+static gl_list_iterator_t
+gl_array_iterator (gl_list_t list)
+{
+ gl_list_iterator_t result;
+
+ result.vtable = list->base.vtable;
+ result.list = list;
+ result.count = list->count;
+ result.p = list->elements + 0;
+ result.q = list->elements + list->count;
+#ifdef lint
+ result.i = 0;
+ result.j = 0;
+#endif
+
+ return result;
+}
+
+static gl_list_iterator_t
+gl_array_iterator_from_to (gl_list_t list, size_t start_index, size_t end_index)
+{
+ gl_list_iterator_t result;
+
+ if (!(start_index <= end_index && end_index <= list->count))
+ /* Invalid arguments. */
+ abort ();
+ result.vtable = list->base.vtable;
+ result.list = list;
+ result.count = list->count;
+ result.p = list->elements + start_index;
+ result.q = list->elements + end_index;
+#ifdef lint
+ result.i = 0;
+ result.j = 0;
+#endif
+
+ return result;
+}
+
+static bool
+gl_array_iterator_next (gl_list_iterator_t *iterator,
+ const void **eltp, gl_list_node_t *nodep)
+{
+ gl_list_t list = iterator->list;
+ if (iterator->count != list->count)
+ {
+ if (iterator->count != list->count + 1)
+ /* Concurrent modifications were done on the list. */
+ abort ();
+ /* The last returned element was removed. */
+ iterator->count--;
+ iterator->p = (const void **) iterator->p - 1;
+ iterator->q = (const void **) iterator->q - 1;
+ }
+ if (iterator->p < iterator->q)
+ {
+ const void **p = (const void **) iterator->p;
+ *eltp = *p;
+ if (nodep != NULL)
+ *nodep = INDEX_TO_NODE (p - list->elements);
+ iterator->p = p + 1;
+ return true;
+ }
+ else
+ return false;
+}
+
+static void
+gl_array_iterator_free (gl_list_iterator_t *iterator)
+{
+}
+
+/* ---------------------- Sorted gl_list_t Data Type ---------------------- */
+
+static size_t
+gl_array_sortedlist_indexof_from_to (gl_list_t list,
+ gl_listelement_compar_fn compar,
+ size_t low, size_t high,
+ const void *elt)
+{
+ if (!(low <= high && high <= list->count))
+ /* Invalid arguments. */
+ abort ();
+ if (low < high)
+ {
+ /* At each loop iteration, low < high; for indices < low the values
+ are smaller than ELT; for indices >= high the values are greater
+ than ELT. So, if the element occurs in the list, it is at
+ low <= position < high. */
+ do
+ {
+ size_t mid = low + (high - low) / 2; /* low <= mid < high */
+ int cmp = compar (list->elements[mid], elt);
+
+ if (cmp < 0)
+ low = mid + 1;
+ else if (cmp > 0)
+ high = mid;
+ else /* cmp == 0 */
+ {
+ /* We have an element equal to ELT at index MID. But we need
+ the minimal such index. */
+ high = mid;
+ /* At each loop iteration, low <= high and
+ compar (list->elements[high], elt) == 0,
+ and we know that the first occurrence of the element is at
+ low <= position <= high. */
+ while (low < high)
+ {
+ size_t mid2 = low + (high - low) / 2; /* low <= mid2 < high */
+ int cmp2 = compar (list->elements[mid2], elt);
+
+ if (cmp2 < 0)
+ low = mid2 + 1;
+ else if (cmp2 > 0)
+ /* The list was not sorted. */
+ abort ();
+ else /* cmp2 == 0 */
+ {
+ if (mid2 == low)
+ break;
+ high = mid2 - 1;
+ }
+ }
+ return low;
+ }
+ }
+ while (low < high);
+ /* Here low == high. */
+ }
+ return (size_t)(-1);
+}
+
+static size_t
+gl_array_sortedlist_indexof (gl_list_t list, gl_listelement_compar_fn compar,
+ const void *elt)
+{
+ return gl_array_sortedlist_indexof_from_to (list, compar, 0, list->count,
+ elt);
+}
+
+static gl_list_node_t
+gl_array_sortedlist_search_from_to (gl_list_t list,
+ gl_listelement_compar_fn compar,
+ size_t low, size_t high,
+ const void *elt)
+{
+ size_t index =
+ gl_array_sortedlist_indexof_from_to (list, compar, low, high, elt);
+ return INDEX_TO_NODE (index);
+}
+
+static gl_list_node_t
+gl_array_sortedlist_search (gl_list_t list, gl_listelement_compar_fn compar,
+ const void *elt)
+{
+ size_t index =
+ gl_array_sortedlist_indexof_from_to (list, compar, 0, list->count, elt);
+ return INDEX_TO_NODE (index);
+}
+
+static gl_list_node_t
+gl_array_sortedlist_nx_add (gl_list_t list, gl_listelement_compar_fn compar,
+ const void *elt)
+{
+ size_t count = list->count;
+ size_t low = 0;
+ size_t high = count;
+
+ /* At each loop iteration, low <= high; for indices < low the values are
+ smaller than ELT; for indices >= high the values are greater than ELT. */
+ while (low < high)
+ {
+ size_t mid = low + (high - low) / 2; /* low <= mid < high */
+ int cmp = compar (list->elements[mid], elt);
+
+ if (cmp < 0)
+ low = mid + 1;
+ else if (cmp > 0)
+ high = mid;
+ else /* cmp == 0 */
+ {
+ low = mid;
+ break;
+ }
+ }
+ return gl_array_nx_add_at (list, low, elt);
+}
+
+static bool
+gl_array_sortedlist_remove (gl_list_t list, gl_listelement_compar_fn compar,
+ const void *elt)
+{
+ size_t index = gl_array_sortedlist_indexof (list, compar, elt);
+ if (index == (size_t)(-1))
+ return false;
+ else
+ return gl_array_remove_at (list, index);
+}
+
+
+const struct gl_list_implementation gl_array_list_implementation =
+ {
+ gl_array_nx_create_empty,
+ gl_array_nx_create,
+ gl_array_size,
+ gl_array_node_value,
+ gl_array_node_nx_set_value,
+ gl_array_next_node,
+ gl_array_previous_node,
+ gl_array_get_at,
+ gl_array_nx_set_at,
+ gl_array_search_from_to,
+ gl_array_indexof_from_to,
+ gl_array_nx_add_first,
+ gl_array_nx_add_last,
+ gl_array_nx_add_before,
+ gl_array_nx_add_after,
+ gl_array_nx_add_at,
+ gl_array_remove_node,
+ gl_array_remove_at,
+ gl_array_remove,
+ gl_array_list_free,
+ gl_array_iterator,
+ gl_array_iterator_from_to,
+ gl_array_iterator_next,
+ gl_array_iterator_free,
+ gl_array_sortedlist_search,
+ gl_array_sortedlist_search_from_to,
+ gl_array_sortedlist_indexof,
+ gl_array_sortedlist_indexof_from_to,
+ gl_array_sortedlist_nx_add,
+ gl_array_sortedlist_remove
+ };
diff --git a/tests/gnu/gl_array_list.h b/tests/gnu/gl_array_list.h
new file mode 100755
index 00000000..a763bca4
--- /dev/null
+++ b/tests/gnu/gl_array_list.h
@@ -0,0 +1,34 @@
+/* Sequential list data type implemented by an array.
+ Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _GL_ARRAY_LIST_H
+#define _GL_ARRAY_LIST_H
+
+#include "gl_list.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const struct gl_list_implementation gl_array_list_implementation;
+#define GL_ARRAY_LIST &gl_array_list_implementation
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GL_ARRAY_LIST_H */
diff --git a/tests/gnu/gl_array_oset.c b/tests/gnu/gl_array_oset.c
new file mode 100755
index 00000000..a6d4584c
--- /dev/null
+++ b/tests/gnu/gl_array_oset.c
@@ -0,0 +1,357 @@
+/* Ordered set data type implemented by an array.
+ Copyright (C) 2006-2007, 2009-2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include "gl_array_oset.h"
+
+#include <stdlib.h>
+
+/* Checked size_t computations. */
+#include "xsize.h"
+
+/* -------------------------- gl_oset_t Data Type -------------------------- */
+
+/* Concrete gl_oset_impl type, valid for this file only. */
+struct gl_oset_impl
+{
+ struct gl_oset_impl_base base;
+ /* An array of ALLOCATED elements, of which the first COUNT are used.
+ 0 <= COUNT <= ALLOCATED. */
+ const void **elements;
+ size_t count;
+ size_t allocated;
+};
+
+static gl_oset_t
+gl_array_nx_create_empty (gl_oset_implementation_t implementation,
+ gl_setelement_compar_fn compar_fn,
+ gl_setelement_dispose_fn dispose_fn)
+{
+ struct gl_oset_impl *set =
+ (struct gl_oset_impl *) malloc (sizeof (struct gl_oset_impl));
+
+ if (set == NULL)
+ return NULL;
+
+ set->base.vtable = implementation;
+ set->base.compar_fn = compar_fn;
+ set->base.dispose_fn = dispose_fn;
+ set->elements = NULL;
+ set->count = 0;
+ set->allocated = 0;
+
+ return set;
+}
+
+static size_t
+gl_array_size (gl_oset_t set)
+{
+ return set->count;
+}
+
+static size_t
+gl_array_indexof (gl_oset_t set, const void *elt)
+{
+ size_t count = set->count;
+
+ if (count > 0)
+ {
+ gl_setelement_compar_fn compar = set->base.compar_fn;
+ size_t low = 0;
+ size_t high = count;
+
+ /* At each loop iteration, low < high; for indices < low the values
+ are smaller than ELT; for indices >= high the values are greater
+ than ELT. So, if the element occurs in the list, it is at
+ low <= position < high. */
+ do
+ {
+ size_t mid = low + (high - low) / 2; /* low <= mid < high */
+ int cmp = (compar != NULL
+ ? compar (set->elements[mid], elt)
+ : (set->elements[mid] > elt ? 1 :
+ set->elements[mid] < elt ? -1 : 0));
+
+ if (cmp < 0)
+ low = mid + 1;
+ else if (cmp > 0)
+ high = mid;
+ else /* cmp == 0 */
+ /* We have an element equal to ELT at index MID. */
+ return mid;
+ }
+ while (low < high);
+ }
+ return (size_t)(-1);
+}
+
+static bool
+gl_array_search (gl_oset_t set, const void *elt)
+{
+ return gl_array_indexof (set, elt) != (size_t)(-1);
+}
+
+static bool
+gl_array_search_atleast (gl_oset_t set,
+ gl_setelement_threshold_fn threshold_fn,
+ const void *threshold,
+ const void **eltp)
+{
+ size_t count = set->count;
+
+ if (count > 0)
+ {
+ size_t low = 0;
+ size_t high = count;
+
+ /* At each loop iteration, low < high; for indices < low the values are
+ smaller than THRESHOLD; for indices >= high the values are nonexistent.
+ So, if an element >= THRESHOLD occurs in the list, it is at
+ low <= position < high. */
+ do
+ {
+ size_t mid = low + (high - low) / 2; /* low <= mid < high */
+
+ if (! threshold_fn (set->elements[mid], threshold))
+ low = mid + 1;
+ else
+ {
+ /* We have an element >= THRESHOLD at index MID. But we need the
+ minimal such index. */
+ high = mid;
+ /* At each loop iteration, low <= high and
+ compar (list->elements[high], value) >= 0,
+ and we know that the first occurrence of the element is at
+ low <= position <= high. */
+ while (low < high)
+ {
+ size_t mid2 = low + (high - low) / 2; /* low <= mid2 < high */
+
+ if (! threshold_fn (set->elements[mid2], threshold))
+ low = mid2 + 1;
+ else
+ high = mid2;
+ }
+ *eltp = set->elements[low];
+ return true;
+ }
+ }
+ while (low < high);
+ }
+ return false;
+}
+
+/* Ensure that set->allocated > set->count.
+ Return 0 upon success, -1 upon out-of-memory. */
+static int
+grow (gl_oset_t set)
+{
+ size_t new_allocated;
+ size_t memory_size;
+ const void **memory;
+
+ new_allocated = xtimes (set->allocated, 2);
+ new_allocated = xsum (new_allocated, 1);
+ memory_size = xtimes (new_allocated, sizeof (const void *));
+ if (size_overflow_p (memory_size))
+ /* Overflow, would lead to out of memory. */
+ return -1;
+ memory = (const void **) realloc (set->elements, memory_size);
+ if (memory == NULL)
+ /* Out of memory. */
+ return -1;
+ set->elements = memory;
+ set->allocated = new_allocated;
+ return 0;
+}
+
+/* Add the given element ELT at the given position,
+ 0 <= position <= gl_oset_size (set).
+ Return 1 upon success, -1 upon out-of-memory. */
+static inline int
+gl_array_nx_add_at (gl_oset_t set, size_t position, const void *elt)
+{
+ size_t count = set->count;
+ const void **elements;
+ size_t i;
+
+ if (count == set->allocated)
+ if (grow (set) < 0)
+ return -1;
+ elements = set->elements;
+ for (i = count; i > position; i--)
+ elements[i] = elements[i - 1];
+ elements[position] = elt;
+ set->count = count + 1;
+ return 1;
+}
+
+/* Remove the element at the given position,
+ 0 <= position < gl_oset_size (set). */
+static inline void
+gl_array_remove_at (gl_oset_t set, size_t position)
+{
+ size_t count = set->count;
+ const void **elements;
+ size_t i;
+
+ elements = set->elements;
+ if (set->base.dispose_fn != NULL)
+ set->base.dispose_fn (elements[position]);
+ for (i = position + 1; i < count; i++)
+ elements[i - 1] = elements[i];
+ set->count = count - 1;
+}
+
+static int
+gl_array_nx_add (gl_oset_t set, const void *elt)
+{
+ size_t count = set->count;
+ size_t low = 0;
+
+ if (count > 0)
+ {
+ gl_setelement_compar_fn compar = set->base.compar_fn;
+ size_t high = count;
+
+ /* At each loop iteration, low < high; for indices < low the values
+ are smaller than ELT; for indices >= high the values are greater
+ than ELT. So, if the element occurs in the list, it is at
+ low <= position < high. */
+ do
+ {
+ size_t mid = low + (high - low) / 2; /* low <= mid < high */
+ int cmp = (compar != NULL
+ ? compar (set->elements[mid], elt)
+ : (set->elements[mid] > elt ? 1 :
+ set->elements[mid] < elt ? -1 : 0));
+
+ if (cmp < 0)
+ low = mid + 1;
+ else if (cmp > 0)
+ high = mid;
+ else /* cmp == 0 */
+ return false;
+ }
+ while (low < high);
+ }
+ return gl_array_nx_add_at (set, low, elt);
+}
+
+static bool
+gl_array_remove (gl_oset_t set, const void *elt)
+{
+ size_t index = gl_array_indexof (set, elt);
+ if (index != (size_t)(-1))
+ {
+ gl_array_remove_at (set, index);
+ return true;
+ }
+ else
+ return false;
+}
+
+static void
+gl_array_free (gl_oset_t set)
+{
+ if (set->elements != NULL)
+ {
+ if (set->base.dispose_fn != NULL)
+ {
+ size_t count = set->count;
+
+ if (count > 0)
+ {
+ gl_setelement_dispose_fn dispose = set->base.dispose_fn;
+ const void **elements = set->elements;
+
+ do
+ dispose (*elements++);
+ while (--count > 0);
+ }
+ }
+ free (set->elements);
+ }
+ free (set);
+}
+
+/* --------------------- gl_oset_iterator_t Data Type --------------------- */
+
+static gl_oset_iterator_t
+gl_array_iterator (gl_oset_t set)
+{
+ gl_oset_iterator_t result;
+
+ result.vtable = set->base.vtable;
+ result.set = set;
+ result.count = set->count;
+ result.p = set->elements + 0;
+ result.q = set->elements + set->count;
+#ifdef lint
+ result.i = 0;
+ result.j = 0;
+#endif
+
+ return result;
+}
+
+static bool
+gl_array_iterator_next (gl_oset_iterator_t *iterator, const void **eltp)
+{
+ gl_oset_t set = iterator->set;
+ if (iterator->count != set->count)
+ {
+ if (iterator->count != set->count + 1)
+ /* Concurrent modifications were done on the set. */
+ abort ();
+ /* The last returned element was removed. */
+ iterator->count--;
+ iterator->p = (const void **) iterator->p - 1;
+ iterator->q = (const void **) iterator->q - 1;
+ }
+ if (iterator->p < iterator->q)
+ {
+ const void **p = (const void **) iterator->p;
+ *eltp = *p;
+ iterator->p = p + 1;
+ return true;
+ }
+ else
+ return false;
+}
+
+static void
+gl_array_iterator_free (gl_oset_iterator_t *iterator)
+{
+}
+
+
+const struct gl_oset_implementation gl_array_oset_implementation =
+ {
+ gl_array_nx_create_empty,
+ gl_array_size,
+ gl_array_search,
+ gl_array_search_atleast,
+ gl_array_nx_add,
+ gl_array_remove,
+ gl_array_free,
+ gl_array_iterator,
+ gl_array_iterator_next,
+ gl_array_iterator_free
+ };
diff --git a/tests/gnu/gl_array_oset.h b/tests/gnu/gl_array_oset.h
new file mode 100755
index 00000000..190a96bd
--- /dev/null
+++ b/tests/gnu/gl_array_oset.h
@@ -0,0 +1,34 @@
+/* Ordered set data type implemented by an array.
+ Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _GL_ARRAY_OSET_H
+#define _GL_ARRAY_OSET_H
+
+#include "gl_oset.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const struct gl_oset_implementation gl_array_oset_implementation;
+#define GL_ARRAY_OSET &gl_array_oset_implementation
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GL_ARRAY_OSET_H */
diff --git a/tests/gnu/ignore-value.h b/tests/gnu/ignore-value.h
new file mode 100755
index 00000000..2eb6918d
--- /dev/null
+++ b/tests/gnu/ignore-value.h
@@ -0,0 +1,37 @@
+/* ignore a function return without a compiler warning
+
+ Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Jim Meyering. */
+
+/* Use these functions to avoid a warning when using a function declared with
+ gcc's warn_unused_result attribute, but for which you really do want to
+ ignore the result. Traditionally, people have used a "(void)" cast to
+ indicate that a function's return value is deliberately unused. However,
+ if the function is declared with __attribute__((warn_unused_result)),
+ gcc issues a warning even with the cast.
+
+ Caution: most of the time, you really should heed gcc's warning, and
+ check the return value. However, in those exceptional cases in which
+ you're sure you know what you're doing, use this function.
+
+ For the record, here's one of the ignorable warnings:
+ "copy.c:233: warning: ignoring return value of 'fchown',
+ declared with attribute warn_unused_result". */
+
+static inline void ignore_value (int i) { (void) i; }
+static inline void ignore_ptr (void* p) { (void) p; }
+/* FIXME: what about aggregate types? */
diff --git a/tests/gnu/init.sh b/tests/gnu/init.sh
new file mode 100755
index 00000000..3154f595
--- /dev/null
+++ b/tests/gnu/init.sh
@@ -0,0 +1,345 @@
+# source this file; set up for tests
+
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Using this file in a test
+# =========================
+#
+# The typical skeleton of a test looks like this:
+#
+# #!/bin/sh
+# : ${srcdir=.}
+# . "$srcdir/init.sh"; path_prepend_ .
+# Execute some commands.
+# Note that these commands are executed in a subdirectory, therefore you
+# need to prepend "../" to relative filenames in the build directory.
+# Set the exit code 0 for success, 77 for skipped, or 1 or other for failure.
+# Use the skip_ and fail_ functions to print a diagnostic and then exit
+# with the corresponding exit code.
+# Exit $?
+
+# Executing a test that uses this file
+# ====================================
+#
+# Running a single test:
+# $ make check TESTS=test-foo.sh
+#
+# Running a single test, with verbose output:
+# $ make check TESTS=test-foo.sh VERBOSE=yes
+#
+# Running a single test, with single-stepping:
+# 1. Go into a sub-shell:
+# $ bash
+# 2. Set relevant environment variables from TESTS_ENVIRONMENT in the
+# Makefile:
+# $ export srcdir=../../tests # this is an example
+# 3. Execute the commands from the test, copy&pasting them one by one:
+# $ . "$srcdir/init.sh"; path_prepend_ .
+# ...
+# 4. Finally
+# $ exit
+
+# We require $(...) support unconditionally.
+# We require a few additional shell features only when $EXEEXT is nonempty,
+# in order to support automatic $EXEEXT emulation:
+# - hyphen-containing alias names
+# - we prefer to use ${var#...} substitution, rather than having
+# to work around lack of support for that feature.
+# The following code attempts to find a shell with support for these features
+# and re-exec's it. If not, it skips the current test.
+
+gl_shell_test_script_='
+test $(echo y) = y || exit 1
+test -z "$EXEEXT" && exit 0
+shopt -s expand_aliases
+alias a-b="echo zoo"
+v=abx
+ test ${v%x} = ab \
+ && test ${v#a} = bx \
+ && test $(a-b) = zoo
+'
+
+if test "x$1" = "x--no-reexec"; then
+ shift
+else
+ for re_shell_ in "${CONFIG_SHELL:-no_shell}" /bin/sh bash dash zsh pdksh fail
+ do
+ test "$re_shell_" = no_shell && continue
+ test "$re_shell_" = fail && skip_ failed to find an adequate shell
+ if "$re_shell_" -c "$gl_shell_test_script_" 2>/dev/null; then
+ exec "$re_shell_" "$0" --no-reexec "$@"
+ echo "$ME_: exec failed" 1>&2
+ exit 127
+ fi
+ done
+fi
+
+test -n "$EXEEXT" && shopt -s expand_aliases
+
+# We use a trap below for cleanup. This requires us to go through
+# hoops to get the right exit status transported through the handler.
+# So use `Exit STATUS' instead of `exit STATUS' inside of the tests.
+# Turn off errexit here so that we don't trip the bug with OSF1/Tru64
+# sh inside this function.
+Exit () { set +e; (exit $1); exit $1; }
+
+fail_() { echo "$ME_: failed test: $@" 1>&2; Exit 1; }
+skip_() { echo "$ME_: skipped test: $@" 1>&2; Exit 77; }
+
+# This is a stub function that is run upon trap (upon regular exit and
+# interrupt). Override it with a per-test function, e.g., to unmount
+# a partition, or to undo any other global state changes.
+cleanup_() { :; }
+
+if ( diff --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+ compare() { diff -u "$@"; }
+elif ( cmp --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+ compare() { cmp -s "$@"; }
+else
+ compare() { cmp "$@"; }
+fi
+
+# An arbitrary prefix to help distinguish test directories.
+testdir_prefix_() { printf gt; }
+
+# Run the user-overridable cleanup_ function, remove the temporary
+# directory and exit with the incoming value of $?.
+remove_tmp_()
+{
+ __st=$?
+ cleanup_
+ # cd out of the directory we're about to remove
+ cd "$initial_cwd_" || cd / || cd /tmp
+ chmod -R u+rwx "$test_dir_"
+ # If removal fails and exit status was to be 0, then change it to 1.
+ rm -rf "$test_dir_" || { test $__st = 0 && __st=1; }
+ exit $__st
+}
+
+# Given a directory name, DIR, if every entry in it that matches *.exe
+# contains only the specified bytes (see the case stmt below), then print
+# a space-separated list of those names and return 0. Otherwise, don't
+# print anything and return 1. Naming constraints apply also to DIR.
+find_exe_basenames_()
+{
+ feb_dir_=$1
+ feb_fail_=0
+ feb_result_=
+ feb_sp_=
+ for feb_file_ in $feb_dir_/*.exe; do
+ case $feb_file_ in
+ *[!-a-zA-Z/0-9_.+]*) feb_fail_=1; break;;
+ *) # Remove leading file name components as well as the .exe suffix.
+ feb_file_=${feb_file_##*/}
+ feb_file_=${feb_file_%.exe}
+ feb_result_="$feb_result_$feb_sp_$feb_file_";;
+ esac
+ feb_sp_=' '
+ done
+ test $feb_fail_ = 0 && printf %s "$feb_result_"
+ return $feb_fail_
+}
+
+# Consider the files in directory, $1.
+# For each file name of the form PROG.exe, create an alias named
+# PROG that simply invokes PROG.exe, then return 0. If any selected
+# file name or the directory name, $1, contains an unexpected character,
+# define no function and return 1.
+create_exe_shims_()
+{
+ case $EXEEXT in
+ '') return 0 ;;
+ .exe) ;;
+ *) echo "$0: unexpected \$EXEEXT value: $EXEEXT" 1>&2; return 1 ;;
+ esac
+
+ base_names_=`find_exe_basenames_ $1` \
+ || { echo "$0 (exe_shim): skipping directory: $1" 1>&2; return 1; }
+
+ if test -n "$base_names_"; then
+ for base_ in $base_names_; do
+ alias "$base_"="$base_$EXEEXT"
+ done
+ fi
+
+ return 0
+}
+
+# Use this function to prepend to PATH an absolute name for each
+# specified, possibly-$initial_cwd_-relative, directory.
+path_prepend_()
+{
+ while test $# != 0; do
+ path_dir_=$1
+ case $path_dir_ in
+ '') fail_ "invalid path dir: '$1'";;
+ /*) abs_path_dir_=$path_dir_;;
+ *) abs_path_dir_=`cd "$initial_cwd_/$path_dir_" && echo "$PWD"` \
+ || fail_ "invalid path dir: $path_dir_";;
+ esac
+ case $abs_path_dir_ in
+ *:*) fail_ "invalid path dir: '$abs_path_dir_'";;
+ esac
+ PATH="$abs_path_dir_:$PATH"
+
+ # Create an alias, FOO, for each FOO.exe in this directory.
+ create_exe_shims_ "$abs_path_dir_" \
+ || fail_ "something failed (above): $abs_path_dir_"
+ shift
+ done
+ export PATH
+}
+
+setup_()
+{
+ test "$VERBOSE" = yes && set -x
+
+ initial_cwd_=$PWD
+ ME_=`expr "./$0" : '.*/\(.*\)$'`
+
+ pfx_=`testdir_prefix_`
+ test_dir_=`mktempd_ "$initial_cwd_" "$pfx_-$ME_.XXXX"` \
+ || fail_ "failed to create temporary directory in $initial_cwd_"
+ cd "$test_dir_"
+
+ # This pair of trap statements ensures that the temporary directory,
+ # $test_dir_, is removed upon exit as well as upon catchable signal.
+ trap remove_tmp_ 0
+ trap 'Exit $?' 1 2 13 15
+}
+
+# Create a temporary directory, much like mktemp -d does.
+# Written by Jim Meyering.
+#
+# Usage: mktempd_ /tmp phoey.XXXXXXXXXX
+#
+# First, try to use the mktemp program.
+# Failing that, we'll roll our own mktemp-like function:
+# - try to get random bytes from /dev/urandom
+# - failing that, generate output from a combination of quickly-varying
+# sources and gzip. Ignore non-varying gzip header, and extract
+# "random" bits from there.
+# - given those bits, map to file-name bytes using tr, and try to create
+# the desired directory.
+# - make only $MAX_TRIES_ attempts
+
+# Helper function. Print $N pseudo-random bytes from a-zA-Z0-9.
+rand_bytes_()
+{
+ n_=$1
+
+ # Maybe try openssl rand -base64 $n_prime_|tr '+/=\012' abcd first?
+ # But if they have openssl, they probably have mktemp, too.
+
+ chars_=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+ dev_rand_=/dev/urandom
+ if test -r "$dev_rand_"; then
+ # Note: 256-length($chars_) == 194; 3 copies of $chars_ is 186 + 8 = 194.
+ dd ibs=$n_ count=1 if=$dev_rand_ 2>/dev/null \
+ | tr -c $chars_ 01234567$chars_$chars_$chars_
+ return
+ fi
+
+ n_plus_50_=`expr $n_ + 50`
+ cmds_='date; date +%N; free; who -a; w; ps auxww; ps ef; netstat -n'
+ data_=` (eval "$cmds_") 2>&1 | gzip `
+
+ # Ensure that $data_ has length at least 50+$n_
+ while :; do
+ len_=`echo "$data_"|wc -c`
+ test $n_plus_50_ -le $len_ && break;
+ data_=` (echo "$data_"; eval "$cmds_") 2>&1 | gzip `
+ done
+
+ echo "$data_" \
+ | dd bs=1 skip=50 count=$n_ 2>/dev/null \
+ | tr -c $chars_ 01234567$chars_$chars_$chars_
+}
+
+mktempd_()
+{
+ case $# in
+ 2);;
+ *) fail_ "Usage: $ME DIR TEMPLATE";;
+ esac
+
+ destdir_=$1
+ template_=$2
+
+ MAX_TRIES_=4
+
+ # Disallow any trailing slash on specified destdir:
+ # it would subvert the post-mktemp "case"-based destdir test.
+ case $destdir_ in
+ /) ;;
+ */) fail_ "invalid destination dir: remove trailing slash(es)";;
+ esac
+
+ case $template_ in
+ *XXXX) ;;
+ *) fail_ "invalid template: $template_ (must have a suffix of at least 4 X's)";;
+ esac
+
+ fail=0
+
+ # First, try to use mktemp.
+ d=`env -u TMPDIR mktemp -d -t -p "$destdir_" "$template_" 2>/dev/null` \
+ || fail=1
+
+ # The resulting name must be in the specified directory.
+ case $d in "$destdir_"*);; *) fail=1;; esac
+
+ # It must have created the directory.
+ test -d "$d" || fail=1
+
+ # It must have 0700 permissions. Handle sticky "S" bits.
+ perms=`ls -dgo "$d" 2>/dev/null|tr S -` || fail=1
+ case $perms in drwx------*) ;; *) fail=1;; esac
+
+ test $fail = 0 && {
+ echo "$d"
+ return
+ }
+
+ # If we reach this point, we'll have to create a directory manually.
+
+ # Get a copy of the template without its suffix of X's.
+ base_template_=`echo "$template_"|sed 's/XX*$//'`
+
+ # Calculate how many X's we've just removed.
+ template_length_=`echo "$template_" | wc -c`
+ nx_=`echo "$base_template_" | wc -c`
+ nx_=`expr $template_length_ - $nx_`
+
+ err_=
+ i_=1
+ while :; do
+ X_=`rand_bytes_ $nx_`
+ candidate_dir_="$destdir_/$base_template_$X_"
+ err_=`mkdir -m 0700 "$candidate_dir_" 2>&1` \
+ && { echo "$candidate_dir_"; return; }
+ test $MAX_TRIES_ -le $i_ && break;
+ i_=`expr $i_ + 1`
+ done
+ fail_ "$err_"
+}
+
+# If you want to override the testdir_prefix_ function,
+# or to add more utility functions, use this file.
+test -f "$srcdir/init.cfg" \
+ && . "$srcdir/init.cfg"
+
+setup_ "$@"
diff --git a/tests/gnu/link.c b/tests/gnu/link.c
new file mode 100755
index 00000000..b9635e5a
--- /dev/null
+++ b/tests/gnu/link.c
@@ -0,0 +1,203 @@
+/* Emulate link on platforms that lack it, namely native Windows platforms.
+
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#if !HAVE_LINK
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+/* CreateHardLink was introduced only in Windows 2000. */
+typedef BOOL (WINAPI * CreateHardLinkFuncType) (LPCTSTR lpFileName,
+ LPCTSTR lpExistingFileName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+static CreateHardLinkFuncType CreateHardLinkFunc = NULL;
+static BOOL initialized = FALSE;
+
+static void
+initialize (void)
+{
+ HMODULE kernel32 = GetModuleHandle ("kernel32.dll");
+ if (kernel32 != NULL)
+ {
+ CreateHardLinkFunc =
+ (CreateHardLinkFuncType) GetProcAddress (kernel32, "CreateHardLinkA");
+ }
+ initialized = TRUE;
+}
+
+int
+link (const char *file1, const char *file2)
+{
+ char *dir;
+ size_t len1 = strlen (file1);
+ size_t len2 = strlen (file2);
+ if (!initialized)
+ initialize ();
+ if (CreateHardLinkFunc == NULL)
+ {
+ /* System does not support hard links. */
+ errno = EPERM;
+ return -1;
+ }
+ /* Reject trailing slashes on non-directories; mingw does not
+ support hard-linking directories. */
+ if ((len1 && (file1[len1 - 1] == '/' || file1[len1 - 1] == '\\'))
+ || (len2 && (file2[len2 - 1] == '/' || file2[len2 - 1] == '\\')))
+ {
+ struct stat st;
+ if (stat (file1, &st) == 0 && S_ISDIR (st.st_mode))
+ errno = EPERM;
+ else
+ errno = ENOTDIR;
+ return -1;
+ }
+ /* CreateHardLink("b/.","a",NULL) creates file "b", so we must check
+ that dirname(file2) exists. */
+ dir = strdup (file2);
+ if (!dir)
+ return -1;
+ {
+ struct stat st;
+ char *p = strchr (dir, '\0');
+ while (dir < p && (*--p != '/' && *p != '\\'));
+ *p = '\0';
+ if (p != dir && stat (dir, &st) == -1)
+ {
+ int saved_errno = errno;
+ free (dir);
+ errno = saved_errno;
+ return -1;
+ }
+ free (dir);
+ }
+ /* Now create the link. */
+ if (CreateHardLinkFunc (file2, file1, NULL) == 0)
+ {
+ /* It is not documented which errors CreateHardLink() can produce.
+ * The following conversions are based on tests on a Windows XP SP2
+ * system. */
+ DWORD err = GetLastError ();
+ switch (err)
+ {
+ case ERROR_ACCESS_DENIED:
+ errno = EACCES;
+ break;
+
+ case ERROR_INVALID_FUNCTION: /* fs does not support hard links */
+ errno = EPERM;
+ break;
+
+ case ERROR_NOT_SAME_DEVICE:
+ errno = EXDEV;
+ break;
+
+ case ERROR_PATH_NOT_FOUND:
+ case ERROR_FILE_NOT_FOUND:
+ errno = ENOENT;
+ break;
+
+ case ERROR_INVALID_PARAMETER:
+ errno = ENAMETOOLONG;
+ break;
+
+ case ERROR_TOO_MANY_LINKS:
+ errno = EMLINK;
+ break;
+
+ case ERROR_ALREADY_EXISTS:
+ errno = EEXIST;
+ break;
+
+ default:
+ errno = EIO;
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+# else /* !Windows */
+
+# error "This platform lacks a link function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib."
+
+# endif /* !Windows */
+#else /* HAVE_LINK */
+
+# undef link
+
+/* Create a hard link from FILE1 to FILE2, working around platform bugs. */
+int
+rpl_link (char const *file1, char const *file2)
+{
+ /* Reject trailing slashes on non-directories. */
+ size_t len1 = strlen (file1);
+ size_t len2 = strlen (file2);
+ if ((len1 && file1[len1 - 1] == '/')
+ || (len2 && file2[len2 - 1] == '/'))
+ {
+ /* Let link() decide whether hard-linking directories is legal.
+ If stat() fails, then link() should fail for the same reason
+ (although on Solaris 9, link("file/","oops") mistakenly
+ succeeds); if stat() succeeds, require a directory. */
+ struct stat st;
+ if (stat (file1, &st))
+ return -1;
+ if (!S_ISDIR (st.st_mode))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+ }
+ else
+ {
+ /* Fix Cygwin 1.5.x bug where link("a","b/.") creates file "b". */
+ char *dir = strdup (file2);
+ struct stat st;
+ char *p;
+ if (!dir)
+ return -1;
+ /* We already know file2 does not end in slash. Strip off the
+ basename, then check that the dirname exists. */
+ p = strrchr (dir, '/');
+ if (p)
+ {
+ *p = '\0';
+ if (stat (dir, &st) == -1)
+ {
+ int saved_errno = errno;
+ free (dir);
+ errno = saved_errno;
+ return -1;
+ }
+ }
+ free (dir);
+ }
+ return link (file1, file2);
+}
+#endif /* HAVE_LINK */
diff --git a/tests/gnu/locale/fr/LC_MESSAGES/test-quotearg.mo b/tests/gnu/locale/fr/LC_MESSAGES/test-quotearg.mo
new file mode 100755
index 00000000..87e97e1e
--- /dev/null
+++ b/tests/gnu/locale/fr/LC_MESSAGES/test-quotearg.mo
Binary files differ
diff --git a/tests/gnu/locale/fr/LC_MESSAGES/test-quotearg.po b/tests/gnu/locale/fr/LC_MESSAGES/test-quotearg.po
new file mode 100755
index 00000000..1ea251f4
--- /dev/null
+++ b/tests/gnu/locale/fr/LC_MESSAGES/test-quotearg.po
@@ -0,0 +1,20 @@
+# Message catalog that maps the ASCII replacements for single-quote characters
+# to real single-quote characters.
+# The header entry is commented out on purpose, so that gettext() performs no
+# no character set conversion from the PO file's encoding to the locale
+# encoding. This allows us to use the same PO file in various locales.
+#msgid ""
+#msgstr ""
+#"Project-Id-Version: GNU gnulib\n"
+#"PO-Revision-Date: 2009-01-26 01:02+01:00\n"
+#"Last-Translator: Eric Blake <ebb9@byu.net>\n"
+#"Language-Team: Undetermined <und@li.org>\n"
+#"MIME-Version: 1.0\n"
+#"Content-Type: text/plain; charset=UTF-8\n"
+#"Content-Transfer-Encoding: 8bit\n"
+
+msgid "`"
+msgstr "\302\253"
+
+msgid "'"
+msgstr "\302\273"
diff --git a/tests/gnu/macros.h b/tests/gnu/macros.h
new file mode 100755
index 00000000..11db5a8a
--- /dev/null
+++ b/tests/gnu/macros.h
@@ -0,0 +1,64 @@
+/* Common macros used by gnulib tests.
+ Copyright (C) 2006-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+/* This file contains macros that are used by many gnulib tests.
+ Put here only frequently used macros, say, used by 10 tests or more. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Define ASSERT_STREAM before including this file if ASSERT must
+ target a stream other than stderr. */
+#ifndef ASSERT_STREAM
+# define ASSERT_STREAM stderr
+#endif
+
+/* ASSERT (condition);
+ verifies that the specified condition is fulfilled. If not, a message
+ is printed to ASSERT_STREAM if defined (defaulting to stderr if
+ undefined) and the program is terminated with an error code.
+
+ This macro has the following properties:
+ - The programmer specifies the expected condition, not the failure
+ condition. This simplifies thinking.
+ - The condition is tested always, regardless of compilation flags.
+ (Unlike the macro from <assert.h>.)
+ - On Unix platforms, the tester can debug the test program with a
+ debugger (provided core dumps are enabled: "ulimit -c unlimited").
+ - For the sake of platforms where no debugger is available (such as
+ some mingw systems), an error message is printed on the error
+ stream that includes the source location of the ASSERT invocation.
+ */
+#define ASSERT(expr) \
+ do \
+ { \
+ if (!(expr)) \
+ { \
+ fprintf (ASSERT_STREAM, "%s:%d: assertion failed\n", \
+ __FILE__, __LINE__); \
+ fflush (ASSERT_STREAM); \
+ abort (); \
+ } \
+ } \
+ while (0)
+
+/* SIZEOF (array)
+ returns the number of elements of an array. It works for arrays that are
+ declared outside functions and for local variables of array type. It does
+ *not* work for function parameters of array type, because they are actually
+ parameters of pointer type. */
+#define SIZEOF(array) (sizeof (array) / sizeof (array[0]))
diff --git a/tests/gnu/nan.h b/tests/gnu/nan.h
new file mode 100755
index 00000000..611eed3e
--- /dev/null
+++ b/tests/gnu/nan.h
@@ -0,0 +1,60 @@
+/* Macros for not-a-number.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+/* NaNf () returns a 'float' not-a-number. */
+
+/* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0. */
+#ifdef __DECC
+static float
+NaNf ()
+{
+ static float zero = 0.0f;
+ return zero / zero;
+}
+#else
+# define NaNf() (0.0f / 0.0f)
+#endif
+
+
+/* NaNd () returns a 'double' not-a-number. */
+
+/* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0. */
+#ifdef __DECC
+static double
+NaNd ()
+{
+ static double zero = 0.0;
+ return zero / zero;
+}
+#else
+# define NaNd() (0.0 / 0.0)
+#endif
+
+
+/* NaNl () returns a 'long double' not-a-number. */
+
+/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the
+ runtime type conversion. */
+#ifdef __sgi
+static long double NaNl ()
+{
+ double zero = 0.0;
+ return zero / zero;
+}
+#else
+# define NaNl() (0.0L / 0.0L)
+#endif
diff --git a/tests/gnu/obstack_printf.c b/tests/gnu/obstack_printf.c
new file mode 100755
index 00000000..b8e1114c
--- /dev/null
+++ b/tests/gnu/obstack_printf.c
@@ -0,0 +1,92 @@
+/* Formatted output to obstacks.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+/* Specification. */
+#include <stdio.h>
+
+#include "obstack.h"
+#include "vasnprintf.h"
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* Grow an obstack with formatted output. Return the number of bytes
+ added to OBS. No trailing nul byte is added, and the object should
+ be closed with obstack_finish before use.
+
+ Upon memory allocation error, call obstack_alloc_failed_handler.
+ Upon other error, return -1. */
+int
+obstack_printf (struct obstack *obs, const char *format, ...)
+{
+ va_list args;
+ int result;
+
+ va_start (args, format);
+ result = obstack_vprintf (obs, format, args);
+ va_end (args);
+ return result;
+}
+
+/* Grow an obstack with formatted output. Return the number of bytes
+ added to OBS. No trailing nul byte is added, and the object should
+ be closed with obstack_finish before use.
+
+ Upon memory allocation error, call obstack_alloc_failed_handler.
+ Upon other error, return -1. */
+int
+obstack_vprintf (struct obstack *obs, const char *format, va_list args)
+{
+ /* If we are close to the end of the current obstack chunk, use a
+ stack-allocated buffer and copy, to reduce the likelihood of a
+ small-size malloc. Otherwise, print directly into the
+ obstack. */
+ enum { CUTOFF = 1024 };
+ char buf[CUTOFF];
+ char *base = obstack_next_free (obs);
+ size_t len = obstack_room (obs);
+ char *str;
+
+ if (len < CUTOFF)
+ {
+ base = buf;
+ len = CUTOFF;
+ }
+ str = vasnprintf (base, &len, format, args);
+ if (!str)
+ {
+ if (errno == ENOMEM)
+ obstack_alloc_failed_handler ();
+ return -1;
+ }
+ if (str == base && str != buf)
+ /* The output was already computed in place, but we need to
+ account for its size. */
+ obstack_blank_fast (obs, len);
+ else
+ {
+ /* The output exceeded available obstack space or we used buf;
+ copy the resulting string. */
+ obstack_grow (obs, str, len);
+ if (str != buf)
+ free (str);
+ }
+ return len;
+}
diff --git a/tests/gnu/putenv.c b/tests/gnu/putenv.c
new file mode 100755
index 00000000..030f5675
--- /dev/null
+++ b/tests/gnu/putenv.c
@@ -0,0 +1,132 @@
+/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2010 Free Software
+ Foundation, Inc.
+
+ NOTE: The canonical source of this file is maintained with the GNU C
+ Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3 of the License, or any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <stdlib.h>
+
+#include <stddef.h>
+
+/* Include errno.h *after* sys/types.h to work around header problems
+ on AIX 3.2.5. */
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(ev) ((errno) = (ev))
+#endif
+
+#include <string.h>
+#include <unistd.h>
+
+#if HAVE_GNU_LD
+# define environ __environ
+#else
+extern char **environ;
+#endif
+
+#if _LIBC
+/* This lock protects against simultaneous modifications of `environ'. */
+# include <bits/libc-lock.h>
+__libc_lock_define_initialized (static, envlock)
+# define LOCK __libc_lock_lock (envlock)
+# define UNLOCK __libc_lock_unlock (envlock)
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+static int
+_unsetenv (const char *name)
+{
+ size_t len;
+ char **ep;
+
+ if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ len = strlen (name);
+
+ LOCK;
+
+ ep = environ;
+ while (*ep != NULL)
+ if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
+ {
+ /* Found it. Remove this pointer by moving later ones back. */
+ char **dp = ep;
+
+ do
+ dp[0] = dp[1];
+ while (*dp++);
+ /* Continue the loop in case NAME appears again. */
+ }
+ else
+ ++ep;
+
+ UNLOCK;
+
+ return 0;
+}
+
+
+/* Put STRING, which is of the form "NAME=VALUE", in the environment.
+ If STRING contains no `=', then remove STRING from the environment. */
+int
+putenv (char *string)
+{
+ const char *const name_end = strchr (string, '=');
+ register size_t size;
+ register char **ep;
+
+ if (name_end == NULL)
+ {
+ /* Remove the variable from the environment. */
+ return _unsetenv (string);
+ }
+
+ size = 0;
+ for (ep = environ; *ep != NULL; ++ep)
+ if (!strncmp (*ep, string, name_end - string) &&
+ (*ep)[name_end - string] == '=')
+ break;
+ else
+ ++size;
+
+ if (*ep == NULL)
+ {
+ static char **last_environ = NULL;
+ char **new_environ = (char **) malloc ((size + 2) * sizeof (char *));
+ if (new_environ == NULL)
+ return -1;
+ (void) memcpy ((void *) new_environ, (void *) environ,
+ size * sizeof (char *));
+ new_environ[size] = (char *) string;
+ new_environ[size + 1] = NULL;
+ free (last_environ);
+ last_environ = new_environ;
+ environ = new_environ;
+ }
+ else
+ *ep = string;
+
+ return 0;
+}
diff --git a/tests/gnu/signature.h b/tests/gnu/signature.h
new file mode 100755
index 00000000..6e15c43a
--- /dev/null
+++ b/tests/gnu/signature.h
@@ -0,0 +1,48 @@
+/* Macro for checking that a function declaration is compliant.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SIGNATURE_CHECK
+
+/* Check that the function FN takes the specified arguments ARGS with
+ a return type of RET. This header is designed to be included after
+ <config.h> and the one system header that is supposed to contain
+ the function being checked, but prior to any other system headers
+ that are necessary for the unit test. Therefore, this file does
+ not include any system headers, nor reference anything outside of
+ the macro arguments. For an example, if foo.h should provide:
+
+ extern int foo (char, float);
+
+ then the unit test named test-foo.c would start out with:
+
+ #include <config.h>
+ #include <foo.h>
+ #include "signature.h"
+ SIGNATURE_CHECK (foo, int, (char, float));
+ #include <other.h>
+ ...
+*/
+# define SIGNATURE_CHECK(fn, ret, args) \
+ SIGNATURE_CHECK1 (fn, ret, args, __LINE__)
+
+/* Necessary to allow multiple SIGNATURE_CHECK lines in a unit test.
+ Note that the checks must not occupy the same line. */
+# define SIGNATURE_CHECK1(fn, ret, args, id) \
+ SIGNATURE_CHECK2 (fn, ret, args, id) /* macroexpand line */
+# define SIGNATURE_CHECK2(fn, ret, args, id) \
+ static ret (* _GL_UNUSED signature_check ## id) args = fn
+
+#endif /* SIGNATURE_CHECK */
diff --git a/tests/gnu/strdup.c b/tests/gnu/strdup.c
new file mode 100755
index 00000000..4b1794ec
--- /dev/null
+++ b/tests/gnu/strdup.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1991, 1996, 1997, 1998, 2002, 2003, 2004, 2006, 2007, 2009,
+ 2010 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+/* Get specification. */
+#include <string.h>
+
+#include <stdlib.h>
+
+#undef __strdup
+#ifdef _LIBC
+# undef strdup
+#endif
+
+#ifndef weak_alias
+# define __strdup strdup
+#endif
+
+/* Duplicate S, returning an identical malloc'd string. */
+char *
+__strdup (const char *s)
+{
+ size_t len = strlen (s) + 1;
+ void *new = malloc (len);
+
+ if (new == NULL)
+ return NULL;
+
+ return (char *) memcpy (new, s, len);
+}
+#ifdef libc_hidden_def
+libc_hidden_def (__strdup)
+#endif
+#ifdef weak_alias
+weak_alias (__strdup, strdup)
+#endif
diff --git a/tests/gnu/symlink.c b/tests/gnu/symlink.c
new file mode 100755
index 00000000..40bbb804
--- /dev/null
+++ b/tests/gnu/symlink.c
@@ -0,0 +1,57 @@
+/* Stub for symlink().
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <unistd.h>
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+
+#if HAVE_SYMLINK
+
+# undef symlink
+
+/* Create a symlink, but reject trailing slash. */
+int
+rpl_symlink (char const *contents, char const *name)
+{
+ size_t len = strlen (name);
+ if (len && name[len - 1] == '/')
+ {
+ struct stat st;
+ if (lstat (name, &st) == 0)
+ errno = EEXIST;
+ return -1;
+ }
+ return symlink (contents, name);
+}
+
+#else /* !HAVE_SYMLINK */
+
+/* The system does not support symlinks. */
+int
+symlink (char const *contents _GL_UNUSED,
+ char const *name _GL_UNUSED)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+#endif /* !HAVE_SYMLINK */
diff --git a/tests/gnu/test-alloca-opt.c b/tests/gnu/test-alloca-opt.c
new file mode 100755
index 00000000..cfbecafc
--- /dev/null
+++ b/tests/gnu/test-alloca-opt.c
@@ -0,0 +1,62 @@
+/* Test of optional automatic memory allocation.
+ Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <alloca.h>
+
+#if HAVE_ALLOCA
+
+static void
+do_allocation (int n)
+{
+ void *ptr = alloca (n);
+ (void) ptr;
+}
+
+void (*func) (int) = do_allocation;
+
+#endif
+
+int
+main ()
+{
+#if HAVE_ALLOCA
+ int i;
+
+ /* Repeat a lot of times, to make sure there's no memory leak. */
+ for (i = 0; i < 100000; i++)
+ {
+ /* Try various values.
+ n = 0 gave a crash on Alpha with gcc-2.5.8.
+ Some versions of MacOS X have a stack size limit of 512 KB. */
+ func (34);
+ func (134);
+ func (399);
+ func (510823);
+ func (129321);
+ func (0);
+ func (4070);
+ func (4095);
+ func (1);
+ func (16582);
+ }
+#endif
+
+ return 0;
+}
diff --git a/tests/gnu/test-array_list.c b/tests/gnu/test-array_list.c
new file mode 100755
index 00000000..d2987794
--- /dev/null
+++ b/tests/gnu/test-array_list.c
@@ -0,0 +1,329 @@
+/* Test of sequential list data type implementation.
+ Copyright (C) 2006-2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2007.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "gl_array_list.h"
+
+#include <stdlib.h>
+
+#include "progname.h"
+#include "macros.h"
+
+static const char *objects[15] =
+ {
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"
+ };
+
+#define RANDOM(n) (rand () % (n))
+#define RANDOM_OBJECT() objects[RANDOM (SIZEOF (objects))]
+
+static void
+check_equals (gl_list_t list1, gl_list_t list2)
+{
+ size_t n, i;
+
+ n = gl_list_size (list1);
+ ASSERT (n == gl_list_size (list2));
+ for (i = 0; i < n; i++)
+ {
+ ASSERT (gl_list_get_at (list1, i) == gl_list_get_at (list2, i));
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ gl_list_t list1, list2;
+
+ set_program_name (argv[0]);
+
+ /* Allow the user to provide a non-default random seed on the command line. */
+ if (argc > 1)
+ srand (atoi (argv[1]));
+
+ {
+ size_t initial_size = RANDOM (50);
+ const void **contents =
+ (const void **) malloc (initial_size * sizeof (const void *));
+ size_t i;
+ unsigned int repeat;
+
+ for (i = 0; i < initial_size; i++)
+ contents[i] = RANDOM_OBJECT ();
+
+ /* Create list1. */
+ list1 = gl_list_nx_create (GL_ARRAY_LIST, NULL, NULL, NULL, true,
+ initial_size, contents);
+ ASSERT (list1 != NULL);
+ /* Create list2. */
+ list2 = gl_list_nx_create_empty (GL_ARRAY_LIST, NULL, NULL, NULL, true);
+ ASSERT (list2 != NULL);
+ for (i = 0; i < initial_size; i++)
+ ASSERT (gl_list_nx_add_last (list2, contents[i]) != NULL);
+
+ check_equals (list1, list2);
+
+ for (repeat = 0; repeat < 10000; repeat++)
+ {
+ unsigned int operation = RANDOM (16);
+ switch (operation)
+ {
+ case 0:
+ if (gl_list_size (list1) > 0)
+ {
+ size_t index = RANDOM (gl_list_size (list1));
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2;
+
+ node1 = gl_list_nx_set_at (list1, index, obj);
+ ASSERT (node1 != NULL);
+ ASSERT (gl_list_get_at (list1, index) == obj);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+
+ node2 = gl_list_nx_set_at (list2, index, obj);
+ ASSERT (node2 != NULL);
+ ASSERT (gl_list_get_at (list2, index) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+
+ if (index > 0)
+ {
+ ASSERT (gl_list_node_value (list1, gl_list_previous_node (list1, node1))
+ == gl_list_get_at (list1, index - 1));
+ }
+ if (index + 1 < gl_list_size (list1))
+ {
+ ASSERT (gl_list_node_value (list1, gl_list_next_node (list1, node1))
+ == gl_list_get_at (list1, index + 1));
+ }
+ }
+ break;
+ case 1:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2;
+ node1 = gl_list_search (list1, obj);
+ node2 = gl_list_search (list2, obj);
+ if (node1 == NULL)
+ {
+ ASSERT (node2 == NULL);
+ }
+ else
+ {
+ ASSERT (node2 != NULL);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+ }
+ }
+ break;
+ case 2:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ size_t index1, index2;
+ index1 = gl_list_indexof (list1, obj);
+ index2 = gl_list_indexof (list2, obj);
+ if (index1 == (size_t)(-1))
+ {
+ ASSERT (index2 == (size_t)(-1));
+ }
+ else
+ {
+ ASSERT (index2 != (size_t)(-1));
+ ASSERT (gl_list_get_at (list1, index1) == obj);
+ ASSERT (gl_list_get_at (list2, index2) == obj);
+ ASSERT (index2 == index1);
+ }
+ }
+ break;
+ case 3: /* add 1 element */
+ {
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2;
+ node1 = gl_list_nx_add_first (list1, obj);
+ ASSERT (node1 != NULL);
+ node2 = gl_list_nx_add_first (list2, obj);
+ ASSERT (node2 != NULL);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+ ASSERT (gl_list_get_at (list1, 0) == obj);
+ ASSERT (gl_list_get_at (list2, 0) == obj);
+ }
+ break;
+ case 4: /* add 1 element */
+ {
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2;
+ node1 = gl_list_nx_add_last (list1, obj);
+ ASSERT (node1 != NULL);
+ node2 = gl_list_nx_add_last (list2, obj);
+ ASSERT (node2 != NULL);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+ ASSERT (gl_list_get_at (list1, gl_list_size (list1) - 1) == obj);
+ ASSERT (gl_list_get_at (list2, gl_list_size (list2) - 1) == obj);
+ }
+ break;
+ case 5: /* add 3 elements */
+ {
+ const char *obj0 = RANDOM_OBJECT ();
+ const char *obj1 = RANDOM_OBJECT ();
+ const char *obj2 = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2;
+ node1 = gl_list_nx_add_first (list1, obj2);
+ ASSERT (node1 != NULL);
+ node1 = gl_list_nx_add_before (list1, node1, obj0);
+ ASSERT (node1 != NULL);
+ node1 = gl_list_nx_add_after (list1, node1, obj1);
+ ASSERT (node1 != NULL);
+ node2 = gl_list_nx_add_first (list2, obj2);
+ ASSERT (node2 != NULL);
+ node2 = gl_list_nx_add_before (list2, node2, obj0);
+ ASSERT (node2 != NULL);
+ node2 = gl_list_nx_add_after (list2, node2, obj1);
+ ASSERT (node2 != NULL);
+ ASSERT (gl_list_node_value (list1, node1) == obj1);
+ ASSERT (gl_list_node_value (list2, node2) == obj1);
+ ASSERT (gl_list_get_at (list1, 0) == obj0);
+ ASSERT (gl_list_get_at (list1, 1) == obj1);
+ ASSERT (gl_list_get_at (list1, 2) == obj2);
+ ASSERT (gl_list_get_at (list2, 0) == obj0);
+ ASSERT (gl_list_get_at (list2, 1) == obj1);
+ ASSERT (gl_list_get_at (list2, 2) == obj2);
+ }
+ break;
+ case 6: /* add 1 element */
+ {
+ size_t index = RANDOM (gl_list_size (list1) + 1);
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2;
+ node1 = gl_list_nx_add_at (list1, index, obj);
+ ASSERT (node1 != NULL);
+ node2 = gl_list_nx_add_at (list2, index, obj);
+ ASSERT (node2 != NULL);
+ ASSERT (gl_list_get_at (list1, index) == obj);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+ ASSERT (gl_list_get_at (list2, index) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+ if (index > 0)
+ {
+ ASSERT (gl_list_node_value (list1, gl_list_previous_node (list1, node1))
+ == gl_list_get_at (list1, index - 1));
+ }
+ if (index + 1 < gl_list_size (list1))
+ {
+ ASSERT (gl_list_node_value (list1, gl_list_next_node (list1, node1))
+ == gl_list_get_at (list1, index + 1));
+ }
+ }
+ break;
+ case 7: case 8: /* remove 1 element */
+ if (gl_list_size (list1) > 0)
+ {
+ size_t n = gl_list_size (list1);
+ const char *obj = gl_list_get_at (list1, RANDOM (n));
+ gl_list_node_t node1, node2;
+ node1 = gl_list_search (list1, obj);
+ node2 = gl_list_search (list2, obj);
+ ASSERT (node1 != NULL);
+ ASSERT (node2 != NULL);
+ ASSERT (gl_list_remove_node (list1, node1));
+ ASSERT (gl_list_remove_node (list2, node2));
+ ASSERT (gl_list_size (list1) == n - 1);
+ }
+ break;
+ case 9: case 10: /* remove 1 element */
+ if (gl_list_size (list1) > 0)
+ {
+ size_t n = gl_list_size (list1);
+ size_t index = RANDOM (n);
+ ASSERT (gl_list_remove_at (list1, index));
+ ASSERT (gl_list_remove_at (list2, index));
+ ASSERT (gl_list_size (list1) == n - 1);
+ }
+ break;
+ case 11: case 12: /* remove 1 element */
+ if (gl_list_size (list1) > 0)
+ {
+ size_t n = gl_list_size (list1);
+ const char *obj = gl_list_get_at (list1, RANDOM (n));
+ ASSERT (gl_list_remove (list1, obj));
+ ASSERT (gl_list_remove (list2, obj));
+ ASSERT (gl_list_size (list1) == n - 1);
+ }
+ break;
+ case 13:
+ if (gl_list_size (list1) > 0)
+ {
+ size_t n = gl_list_size (list1);
+ const char *obj = "xyzzy";
+ ASSERT (!gl_list_remove (list1, obj));
+ ASSERT (!gl_list_remove (list2, obj));
+ ASSERT (gl_list_size (list1) == n);
+ }
+ break;
+ case 14:
+ {
+ size_t n = gl_list_size (list1);
+ gl_list_iterator_t iter1, iter2;
+ const void *elt;
+ iter1 = gl_list_iterator (list1);
+ iter2 = gl_list_iterator (list2);
+ for (i = 0; i < n; i++)
+ {
+ ASSERT (gl_list_iterator_next (&iter1, &elt, NULL));
+ ASSERT (gl_list_get_at (list1, i) == elt);
+ ASSERT (gl_list_iterator_next (&iter2, &elt, NULL));
+ ASSERT (gl_list_get_at (list2, i) == elt);
+ }
+ ASSERT (!gl_list_iterator_next (&iter1, &elt, NULL));
+ ASSERT (!gl_list_iterator_next (&iter2, &elt, NULL));
+ gl_list_iterator_free (&iter1);
+ gl_list_iterator_free (&iter2);
+ }
+ break;
+ case 15:
+ {
+ size_t end = RANDOM (gl_list_size (list1) + 1);
+ size_t start = RANDOM (end + 1);
+ gl_list_iterator_t iter1, iter2;
+ const void *elt;
+ iter1 = gl_list_iterator_from_to (list1, start, end);
+ iter2 = gl_list_iterator_from_to (list2, start, end);
+ for (i = start; i < end; i++)
+ {
+ ASSERT (gl_list_iterator_next (&iter1, &elt, NULL));
+ ASSERT (gl_list_get_at (list1, i) == elt);
+ ASSERT (gl_list_iterator_next (&iter2, &elt, NULL));
+ ASSERT (gl_list_get_at (list2, i) == elt);
+ }
+ ASSERT (!gl_list_iterator_next (&iter1, &elt, NULL));
+ ASSERT (!gl_list_iterator_next (&iter2, &elt, NULL));
+ gl_list_iterator_free (&iter1);
+ gl_list_iterator_free (&iter2);
+ }
+ break;
+ }
+ check_equals (list1, list2);
+ }
+
+ gl_list_free (list1);
+ gl_list_free (list2);
+ free (contents);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-array_oset.c b/tests/gnu/test-array_oset.c
new file mode 100755
index 00000000..9ec6171c
--- /dev/null
+++ b/tests/gnu/test-array_oset.c
@@ -0,0 +1,144 @@
+/* Test of ordered set data type implementation.
+ Copyright (C) 2006-2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2007.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "gl_array_oset.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gl_xlist.h"
+#include "gl_array_list.h"
+#include "progname.h"
+#include "macros.h"
+
+static const char *objects[30] =
+ {
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
+ "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "<", ">", "[", "]"
+ };
+
+#define RANDOM(n) (rand () % (n))
+#define RANDOM_OBJECT() objects[RANDOM (SIZEOF (objects))]
+
+static void
+check_equals (gl_oset_t set1, gl_list_t set2)
+{
+ size_t n = gl_oset_size (set1);
+ gl_oset_iterator_t iter1;
+ gl_list_iterator_t iter2;
+ const void *elt1;
+ const void *elt2;
+ gl_list_node_t node2;
+ size_t i;
+
+ iter1 = gl_oset_iterator (set1);
+ iter2 = gl_list_iterator (set2);
+ for (i = 0; i < n; i++)
+ {
+ ASSERT (gl_oset_iterator_next (&iter1, &elt1));
+ ASSERT (gl_list_iterator_next (&iter2, &elt2, &node2));
+ ASSERT (elt1 == elt2);
+ }
+ ASSERT (!gl_oset_iterator_next (&iter1, &elt1));
+ ASSERT (!gl_list_iterator_next (&iter2, &elt2, &node2));
+ gl_oset_iterator_free (&iter1);
+ gl_list_iterator_free (&iter2);
+}
+
+static void
+check_all (gl_oset_t set1, gl_list_t set2)
+{
+ check_equals (set1, set2);
+}
+
+int
+main (int argc, char *argv[])
+{
+ gl_oset_t set1;
+ gl_list_t set2;
+
+ set_program_name (argv[0]);
+
+ /* Allow the user to provide a non-default random seed on the command line. */
+ if (argc > 1)
+ srand (atoi (argv[1]));
+
+ {
+ size_t initial_size = RANDOM (20);
+ size_t i;
+ unsigned int repeat;
+
+ /* Create set1. */
+ set1 = gl_oset_nx_create_empty (GL_ARRAY_OSET, (gl_setelement_compar_fn) strcmp, NULL);
+ ASSERT (set1 != NULL);
+
+ /* Create set2. */
+ set2 = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, NULL, false);
+
+ check_all (set1, set2);
+
+ /* Initialize them. */
+ for (i = 0; i < initial_size; i++)
+ {
+ const char *obj = RANDOM_OBJECT ();
+ ASSERT (gl_oset_nx_add (set1, obj)
+ == (gl_sortedlist_search (set2, (gl_listelement_compar_fn)strcmp, obj) != NULL
+ ? false
+ : (gl_sortedlist_add (set2, (gl_listelement_compar_fn)strcmp, obj), true)));
+ check_all (set1, set2);
+ }
+
+ for (repeat = 0; repeat < 100000; repeat++)
+ {
+ unsigned int operation = RANDOM (3);
+ switch (operation)
+ {
+ case 0:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ ASSERT (gl_oset_search (set1, obj)
+ == (gl_sortedlist_search (set2, (gl_listelement_compar_fn)strcmp, obj) != NULL));
+ }
+ break;
+ case 1:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ ASSERT (gl_oset_nx_add (set1, obj)
+ == (gl_sortedlist_search (set2, (gl_listelement_compar_fn)strcmp, obj) != NULL
+ ? false
+ : (gl_sortedlist_add (set2, (gl_listelement_compar_fn)strcmp, obj), true)));
+ }
+ break;
+ case 2:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ ASSERT (gl_oset_remove (set1, obj)
+ == gl_sortedlist_remove (set2, (gl_listelement_compar_fn)strcmp, obj));
+ }
+ break;
+ }
+ check_all (set1, set2);
+ }
+
+ gl_oset_free (set1);
+ gl_list_free (set2);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-avltree_oset.c b/tests/gnu/test-avltree_oset.c
new file mode 100755
index 00000000..211c8332
--- /dev/null
+++ b/tests/gnu/test-avltree_oset.c
@@ -0,0 +1,136 @@
+/* Test of ordered set data type implementation.
+ Copyright (C) 2006-2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "gl_avltree_oset.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gl_array_oset.h"
+#include "progname.h"
+#include "macros.h"
+
+extern void gl_avltree_oset_check_invariants (gl_oset_t set);
+
+static const char *objects[30] =
+ {
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
+ "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "<", ">", "[", "]"
+ };
+
+#define RANDOM(n) (rand () % (n))
+#define RANDOM_OBJECT() objects[RANDOM (SIZEOF (objects))]
+
+static void
+check_equals (gl_oset_t set1, gl_oset_t set2)
+{
+ size_t n = gl_oset_size (set1);
+ gl_oset_iterator_t iter1, iter2;
+ const void *elt1;
+ const void *elt2;
+ size_t i;
+
+ iter1 = gl_oset_iterator (set1);
+ iter2 = gl_oset_iterator (set2);
+ for (i = 0; i < n; i++)
+ {
+ ASSERT (gl_oset_iterator_next (&iter1, &elt1));
+ ASSERT (gl_oset_iterator_next (&iter2, &elt2));
+ ASSERT (elt1 == elt2);
+ }
+ ASSERT (!gl_oset_iterator_next (&iter1, &elt1));
+ ASSERT (!gl_oset_iterator_next (&iter2, &elt2));
+ gl_oset_iterator_free (&iter1);
+ gl_oset_iterator_free (&iter2);
+}
+
+static void
+check_all (gl_oset_t set1, gl_oset_t set2)
+{
+ gl_avltree_oset_check_invariants (set2);
+ check_equals (set1, set2);
+}
+
+int
+main (int argc, char *argv[])
+{
+ gl_oset_t set1, set2;
+
+ set_program_name (argv[0]);
+
+ /* Allow the user to provide a non-default random seed on the command line. */
+ if (argc > 1)
+ srand (atoi (argv[1]));
+
+ {
+ size_t initial_size = RANDOM (20);
+ size_t i;
+ unsigned int repeat;
+
+ /* Create set1. */
+ set1 = gl_oset_nx_create_empty (GL_ARRAY_OSET, (gl_setelement_compar_fn) strcmp, NULL);
+ ASSERT (set1 != NULL);
+
+ /* Create set2. */
+ set2 = gl_oset_nx_create_empty (GL_AVLTREE_OSET, (gl_setelement_compar_fn) strcmp, NULL);
+ ASSERT (set2 != NULL);
+
+ check_all (set1, set2);
+
+ /* Initialize them. */
+ for (i = 0; i < initial_size; i++)
+ {
+ const char *obj = RANDOM_OBJECT ();
+ ASSERT (gl_oset_nx_add (set1, obj) == gl_oset_nx_add (set2, obj));
+ check_all (set1, set2);
+ }
+
+ for (repeat = 0; repeat < 100000; repeat++)
+ {
+ unsigned int operation = RANDOM (3);
+ switch (operation)
+ {
+ case 0:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ ASSERT (gl_oset_search (set1, obj) == gl_oset_search (set2, obj));
+ }
+ break;
+ case 1:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ ASSERT (gl_oset_nx_add (set1, obj) == gl_oset_nx_add (set2, obj));
+ }
+ break;
+ case 2:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ ASSERT (gl_oset_remove (set1, obj) == gl_oset_remove (set2, obj));
+ }
+ break;
+ }
+ check_all (set1, set2);
+ }
+
+ gl_oset_free (set1);
+ gl_oset_free (set2);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-binary-io.c b/tests/gnu/test-binary-io.c
new file mode 100755
index 00000000..125150b2
--- /dev/null
+++ b/tests/gnu/test-binary-io.c
@@ -0,0 +1,64 @@
+/* Test of binary mode I/O.
+ Copyright (C) 2005, 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005. */
+
+#include <config.h>
+
+#include "binary-io.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* Test the O_BINARY macro. */
+ {
+ int fd =
+ open ("t-bin-out2.tmp", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600);
+ if (write (fd, "Hello\n", 6) < 0)
+ exit (1);
+ close (fd);
+ }
+ {
+ struct stat statbuf;
+ if (stat ("t-bin-out2.tmp", &statbuf) < 0)
+ exit (1);
+ ASSERT (statbuf.st_size == 6);
+ }
+ unlink ("t-bin-out2.tmp");
+
+ /* Test the SET_BINARY macro. */
+ SET_BINARY (1);
+ fputs ("Hello\n", stdout);
+ fclose (stdout);
+ fclose (stderr);
+ {
+ struct stat statbuf;
+ if (stat ("t-bin-out1.tmp", &statbuf) < 0)
+ exit (1);
+ ASSERT (statbuf.st_size == 6);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-binary-io.sh b/tests/gnu/test-binary-io.sh
new file mode 100755
index 00000000..33e128c3
--- /dev/null
+++ b/tests/gnu/test-binary-io.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles t-bin-out1.tmp t-bin-out2.tmp"
+./test-binary-io${EXEEXT} > t-bin-out1.tmp || exit 1
+
+rm -fr $tmpfiles
+
+exit 0
diff --git a/tests/gnu/test-bitrotate.c b/tests/gnu/test-bitrotate.c
new file mode 100755
index 00000000..59c95a87
--- /dev/null
+++ b/tests/gnu/test-bitrotate.c
@@ -0,0 +1,279 @@
+/* Test of <bitrotate.h> substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson <simon@josefsson.org>, 2008. */
+
+#include <config.h>
+
+#include "bitrotate.h"
+
+#include "macros.h"
+
+int
+main (void)
+{
+ ASSERT (rotl8 (42, 0) == 42);
+ ASSERT (rotl8 (42, 1) == 84);
+ ASSERT (rotl8 (42, 2) == 168);
+ ASSERT (rotl8 (42, 3) == 81);
+ ASSERT (rotl8 (42, 4) == 162);
+ ASSERT (rotl8 (42, 5) == 69);
+ ASSERT (rotl8 (42, 6) == 138);
+ ASSERT (rotl8 (42, 7) == 21);
+ ASSERT (rotl8 (42, 8) == 42);
+
+ ASSERT (rotr8 (42, 0) == 42);
+ ASSERT (rotr8 (42, 1) == 21);
+ ASSERT (rotr8 (42, 2) == 138);
+ ASSERT (rotr8 (42, 3) == 69);
+ ASSERT (rotr8 (42, 4) == 162);
+ ASSERT (rotr8 (42, 5) == 81);
+ ASSERT (rotr8 (42, 6) == 168);
+ ASSERT (rotr8 (42, 7) == 84);
+ ASSERT (rotr8 (42, 8) == 42);
+
+ ASSERT (rotl16 (43981, 0) == 43981);
+ ASSERT (rotl16 (43981, 1) == 22427);
+ ASSERT (rotl16 (43981, 2) == 44854);
+ ASSERT (rotl16 (43981, 3) == 24173);
+ ASSERT (rotl16 (43981, 4) == 48346);
+ ASSERT (rotl16 (43981, 5) == 31157);
+ ASSERT (rotl16 (43981, 6) == 62314);
+ ASSERT (rotl16 (43981, 7) == 59093);
+ ASSERT (rotl16 (43981, 8) == 52651);
+ ASSERT (rotl16 (43981, 9) == 39767);
+ ASSERT (rotl16 (43981, 10) == 13999);
+ ASSERT (rotl16 (43981, 11) == 27998);
+ ASSERT (rotl16 (43981, 12) == 55996);
+ ASSERT (rotl16 (43981, 13) == 46457);
+ ASSERT (rotl16 (43981, 14) == 27379);
+ ASSERT (rotl16 (43981, 15) == 54758);
+ ASSERT (rotl16 (43981, 16) == 43981);
+
+ ASSERT (rotr16 (43981, 0) == 43981);
+ ASSERT (rotr16 (43981, 1) == 54758);
+ ASSERT (rotr16 (43981, 2) == 27379);
+ ASSERT (rotr16 (43981, 3) == 46457);
+ ASSERT (rotr16 (43981, 4) == 55996);
+ ASSERT (rotr16 (43981, 5) == 27998);
+ ASSERT (rotr16 (43981, 6) == 13999);
+ ASSERT (rotr16 (43981, 7) == 39767);
+ ASSERT (rotr16 (43981, 8) == 52651);
+ ASSERT (rotr16 (43981, 9) == 59093);
+ ASSERT (rotr16 (43981, 10) == 62314);
+ ASSERT (rotr16 (43981, 11) == 31157);
+ ASSERT (rotr16 (43981, 12) == 48346);
+ ASSERT (rotr16 (43981, 13) == 24173);
+ ASSERT (rotr16 (43981, 14) == 44854);
+ ASSERT (rotr16 (43981, 15) == 22427);
+ ASSERT (rotr16 (43981, 16) == 43981);
+
+ ASSERT (rotl32 (2309737967U, 1) == 324508639U);
+ ASSERT (rotl32 (2309737967U, 2) == 649017278U);
+ ASSERT (rotl32 (2309737967U, 3) == 1298034556U);
+ ASSERT (rotl32 (2309737967U, 4) == 2596069112U);
+ ASSERT (rotl32 (2309737967U, 5) == 897170929U);
+ ASSERT (rotl32 (2309737967U, 6) == 1794341858U);
+ ASSERT (rotl32 (2309737967U, 7) == 3588683716U);
+ ASSERT (rotl32 (2309737967U, 8) == 2882400137U);
+ ASSERT (rotl32 (2309737967U, 9) == 1469832979U);
+ ASSERT (rotl32 (2309737967U, 10) == 2939665958U);
+ ASSERT (rotl32 (2309737967U, 11) == 1584364621U);
+ ASSERT (rotl32 (2309737967U, 12) == 3168729242U);
+ ASSERT (rotl32 (2309737967U, 13) == 2042491189U);
+ ASSERT (rotl32 (2309737967U, 14) == 4084982378U);
+ ASSERT (rotl32 (2309737967U, 15) == 3874997461U);
+ ASSERT (rotl32 (2309737967U, 16) == 3455027627U);
+ ASSERT (rotl32 (2309737967U, 17) == 2615087959U);
+ ASSERT (rotl32 (2309737967U, 18) == 935208623U);
+ ASSERT (rotl32 (2309737967U, 19) == 1870417246U);
+ ASSERT (rotl32 (2309737967U, 20) == 3740834492U);
+ ASSERT (rotl32 (2309737967U, 21) == 3186701689U);
+ ASSERT (rotl32 (2309737967U, 22) == 2078436083U);
+ ASSERT (rotl32 (2309737967U, 23) == 4156872166U);
+ ASSERT (rotl32 (2309737967U, 24) == 4018777037U);
+ ASSERT (rotl32 (2309737967U, 25) == 3742586779U);
+ ASSERT (rotl32 (2309737967U, 26) == 3190206263U);
+ ASSERT (rotl32 (2309737967U, 27) == 2085445231U);
+ ASSERT (rotl32 (2309737967U, 28) == 4170890462U);
+ ASSERT (rotl32 (2309737967U, 29) == 4046813629U);
+ ASSERT (rotl32 (2309737967U, 30) == 3798659963U);
+ ASSERT (rotl32 (2309737967U, 31) == 3302352631U);
+
+ ASSERT (rotr32 (2309737967U, 1) == 3302352631lU);
+ ASSERT (rotr32 (2309737967U, 2) == 3798659963lU);
+ ASSERT (rotr32 (2309737967U, 3) == 4046813629lU);
+ ASSERT (rotr32 (2309737967U, 4) == 4170890462lU);
+ ASSERT (rotr32 (2309737967U, 5) == 2085445231lU);
+ ASSERT (rotr32 (2309737967U, 6) == 3190206263lU);
+ ASSERT (rotr32 (2309737967U, 7) == 3742586779lU);
+ ASSERT (rotr32 (2309737967U, 8) == 4018777037lU);
+ ASSERT (rotr32 (2309737967U, 9) == 4156872166lU);
+ ASSERT (rotr32 (2309737967U, 10) == 2078436083lU);
+ ASSERT (rotr32 (2309737967U, 11) == 3186701689lU);
+ ASSERT (rotr32 (2309737967U, 12) == 3740834492lU);
+ ASSERT (rotr32 (2309737967U, 13) == 1870417246lU);
+ ASSERT (rotr32 (2309737967U, 14) == 935208623lU);
+ ASSERT (rotr32 (2309737967U, 15) == 2615087959lU);
+ ASSERT (rotr32 (2309737967U, 16) == 3455027627lU);
+ ASSERT (rotr32 (2309737967U, 17) == 3874997461lU);
+ ASSERT (rotr32 (2309737967U, 18) == 4084982378lU);
+ ASSERT (rotr32 (2309737967U, 19) == 2042491189lU);
+ ASSERT (rotr32 (2309737967U, 20) == 3168729242lU);
+ ASSERT (rotr32 (2309737967U, 21) == 1584364621lU);
+ ASSERT (rotr32 (2309737967U, 22) == 2939665958lU);
+ ASSERT (rotr32 (2309737967U, 23) == 1469832979lU);
+ ASSERT (rotr32 (2309737967U, 24) == 2882400137lU);
+ ASSERT (rotr32 (2309737967U, 25) == 3588683716lU);
+ ASSERT (rotr32 (2309737967U, 26) == 1794341858lU);
+ ASSERT (rotr32 (2309737967U, 27) == 897170929lU);
+ ASSERT (rotr32 (2309737967U, 28) == 2596069112lU);
+ ASSERT (rotr32 (2309737967U, 29) == 1298034556lU);
+ ASSERT (rotr32 (2309737967U, 30) == 649017278lU);
+ ASSERT (rotr32 (2309737967U, 31) == 324508639lU);
+
+#ifdef UINT64_MAX
+ ASSERT (rotl64 (16045690984503098046ULL, 1) == 13644637895296644477ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 2) == 8842531716883737339ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 3) == 17685063433767474678ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 4) == 16923382793825397741ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 5) == 15400021513941243867ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 6) == 12353298954172936119ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 7) == 6259853834636320623ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 8) == 12519707669272641246ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 9) == 6592671264835730877ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 10) == 13185342529671461754ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 11) == 7923940985633371893ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 12) == 15847881971266743786ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 13) == 13249019868823935957ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 14) == 8051295663938320299ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 15) == 16102591327876640598ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 16) == 13758438582043729581ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 17) == 9070133090377907547ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 18) == 18140266180755815094ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 19) == 17833788287802078573ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 20) == 17220832501894605531ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 21) == 15994920930079659447ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 22) == 13543097786449767279ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 23) == 8639451499189982943ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 24) == 17278902998379965886ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 25) == 16111061923050380157ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 26) == 13775379772391208699ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 27) == 9104015471072865783ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 28) == 18208030942145731566ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 29) == 17969317810581911517ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 30) == 17491891547454271419ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 31) == 16537039021198991223ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 32) == 14627333968688430831ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 33) == 10807923863667310047ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 34) == 3169103653625068479ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 35) == 6338207307250136958ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 36) == 12676414614500273916ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 37) == 6906085155290996217ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 38) == 13812170310581992434ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 39) == 9177596547454433253ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 40) == 18355193094908866506ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 41) == 18263642116108181397ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 42) == 18080540158506811179ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 43) == 17714336243304070743ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 44) == 16981928412898589871ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 45) == 15517112752087628127ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 46) == 12587481430465704639ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 47) == 6728218787221857663ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 48) == 13456437574443715326ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 49) == 8466131075177879037ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 50) == 16932262150355758074ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 51) == 15417780227001964533ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 52) == 12388816380294377451ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 53) == 6330888686879203287ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 54) == 12661777373758406574ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 55) == 6876810673807261533ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 56) == 13753621347614523066ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 57) == 9060498621519494517ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 58) == 18120997243038989034ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 59) == 17795250412368426453ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 60) == 17143756751027301291ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 61) == 15840769428345050967ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 62) == 13234794782980550319ULL);
+ ASSERT (rotl64 (16045690984503098046ULL, 63) == 8022845492251549023ULL);
+
+ ASSERT (rotr64 (16045690984503098046ULL, 1) == 8022845492251549023ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 2) == 13234794782980550319ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 3) == 15840769428345050967ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 4) == 17143756751027301291ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 5) == 17795250412368426453ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 6) == 18120997243038989034ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 7) == 9060498621519494517ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 8) == 13753621347614523066ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 9) == 6876810673807261533ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 10) == 12661777373758406574ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 11) == 6330888686879203287ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 12) == 12388816380294377451ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 13) == 15417780227001964533ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 14) == 16932262150355758074ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 15) == 8466131075177879037ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 16) == 13456437574443715326ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 17) == 6728218787221857663ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 18) == 12587481430465704639ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 19) == 15517112752087628127ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 20) == 16981928412898589871ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 21) == 17714336243304070743ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 22) == 18080540158506811179ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 23) == 18263642116108181397ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 24) == 18355193094908866506ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 25) == 9177596547454433253ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 26) == 13812170310581992434ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 27) == 6906085155290996217ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 28) == 12676414614500273916ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 29) == 6338207307250136958ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 30) == 3169103653625068479ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 31) == 10807923863667310047ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 32) == 14627333968688430831ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 33) == 16537039021198991223ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 34) == 17491891547454271419ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 35) == 17969317810581911517ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 36) == 18208030942145731566ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 37) == 9104015471072865783ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 38) == 13775379772391208699ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 39) == 16111061923050380157ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 40) == 17278902998379965886ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 41) == 8639451499189982943ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 42) == 13543097786449767279ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 43) == 15994920930079659447ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 44) == 17220832501894605531ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 45) == 17833788287802078573ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 46) == 18140266180755815094ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 47) == 9070133090377907547ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 48) == 13758438582043729581ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 49) == 16102591327876640598ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 50) == 8051295663938320299ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 51) == 13249019868823935957ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 52) == 15847881971266743786ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 53) == 7923940985633371893ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 54) == 13185342529671461754ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 55) == 6592671264835730877ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 56) == 12519707669272641246ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 57) == 6259853834636320623ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 58) == 12353298954172936119ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 59) == 15400021513941243867ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 60) == 16923382793825397741ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 61) == 17685063433767474678ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 62) == 8842531716883737339ULL);
+ ASSERT (rotr64 (16045690984503098046ULL, 63) == 13644637895296644477ULL);
+#endif /* UINT64_MAX */
+
+ return 0;
+}
diff --git a/tests/gnu/test-btowc.c b/tests/gnu/test-btowc.c
new file mode 100755
index 00000000..9d115960
--- /dev/null
+++ b/tests/gnu/test-btowc.c
@@ -0,0 +1,63 @@
+/* Test of conversion of unibyte character to wide character.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <wchar.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (btowc, wint_t, (int));
+
+#include <locale.h>
+#include <stdio.h>
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ int c;
+
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ ASSERT (btowc (EOF) == WEOF);
+
+ if (argc > 1)
+ switch (argv[1][0])
+ {
+ case '1':
+ /* Locale encoding is ISO-8859-1 or ISO-8859-15. */
+ for (c = 0; c < 0x80; c++)
+ ASSERT (btowc (c) == c);
+ for (c = 0xA0; c < 0x100; c++)
+ ASSERT (btowc (c) != WEOF);
+ return 0;
+
+ case '2':
+ /* Locale encoding is UTF-8. */
+ for (c = 0; c < 0x80; c++)
+ ASSERT (btowc (c) == c);
+ for (c = 0x80; c < 0x100; c++)
+ ASSERT (btowc (c) == WEOF);
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/tests/gnu/test-btowc1.sh b/tests/gnu/test-btowc1.sh
new file mode 100755
index 00000000..aaef48d2
--- /dev/null
+++ b/tests/gnu/test-btowc1.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test in an ISO-8859-1 or ISO-8859-15 locale.
+: ${LOCALE_FR=fr_FR}
+if test $LOCALE_FR = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no traditional french locale is installed"
+ else
+ echo "Skipping test: no traditional french locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_FR \
+./test-btowc${EXEEXT} 1
diff --git a/tests/gnu/test-btowc2.sh b/tests/gnu/test-btowc2.sh
new file mode 100755
index 00000000..2e060384
--- /dev/null
+++ b/tests/gnu/test-btowc2.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test whether a specific UTF-8 locale is installed.
+: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
+if test $LOCALE_FR_UTF8 = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no french Unicode locale is installed"
+ else
+ echo "Skipping test: no french Unicode locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_FR_UTF8 \
+./test-btowc${EXEEXT} 2
diff --git a/tests/gnu/test-c-ctype.c b/tests/gnu/test-c-ctype.c
new file mode 100755
index 00000000..ebe594dd
--- /dev/null
+++ b/tests/gnu/test-c-ctype.c
@@ -0,0 +1,386 @@
+/* Test of character handling in C locale.
+ Copyright (C) 2005, 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005. */
+
+#include <config.h>
+
+#include "c-ctype.h"
+
+#include <locale.h>
+
+#include "macros.h"
+
+static void
+test_all (void)
+{
+ int c;
+
+ for (c = -0x80; c < 0x100; c++)
+ {
+ ASSERT (c_isascii (c) == (c >= 0 && c < 0x80));
+
+ switch (c)
+ {
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+ case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ ASSERT (c_isalnum (c) == 1);
+ break;
+ default:
+ ASSERT (c_isalnum (c) == 0);
+ break;
+ }
+
+ switch (c)
+ {
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+ case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ ASSERT (c_isalpha (c) == 1);
+ break;
+ default:
+ ASSERT (c_isalpha (c) == 0);
+ break;
+ }
+
+ switch (c)
+ {
+ case '\t': case ' ':
+ ASSERT (c_isblank (c) == 1);
+ break;
+ default:
+ ASSERT (c_isblank (c) == 0);
+ break;
+ }
+
+ ASSERT (c_iscntrl (c) == ((c >= 0 && c < 0x20) || c == 0x7f));
+
+ switch (c)
+ {
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ ASSERT (c_isdigit (c) == 1);
+ break;
+ default:
+ ASSERT (c_isdigit (c) == 0);
+ break;
+ }
+
+ switch (c)
+ {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+ case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ ASSERT (c_islower (c) == 1);
+ break;
+ default:
+ ASSERT (c_islower (c) == 0);
+ break;
+ }
+
+ ASSERT (c_isgraph (c) == ((c >= 0x20 && c < 0x7f) && c != ' '));
+
+ ASSERT (c_isprint (c) == (c >= 0x20 && c < 0x7f));
+
+ ASSERT (c_ispunct (c) == (c_isgraph (c) && !c_isalnum (c)));
+
+ switch (c)
+ {
+ case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
+ ASSERT (c_isspace (c) == 1);
+ break;
+ default:
+ ASSERT (c_isspace (c) == 0);
+ break;
+ }
+
+ switch (c)
+ {
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ ASSERT (c_isupper (c) == 1);
+ break;
+ default:
+ ASSERT (c_isupper (c) == 0);
+ break;
+ }
+
+ switch (c)
+ {
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ ASSERT (c_isxdigit (c) == 1);
+ break;
+ default:
+ ASSERT (c_isxdigit (c) == 0);
+ break;
+ }
+
+ switch (c)
+ {
+ case 'A':
+ ASSERT (c_tolower (c) == 'a');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'B':
+ ASSERT (c_tolower (c) == 'b');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'C':
+ ASSERT (c_tolower (c) == 'c');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'D':
+ ASSERT (c_tolower (c) == 'd');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'E':
+ ASSERT (c_tolower (c) == 'e');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'F':
+ ASSERT (c_tolower (c) == 'f');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'G':
+ ASSERT (c_tolower (c) == 'g');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'H':
+ ASSERT (c_tolower (c) == 'h');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'I':
+ ASSERT (c_tolower (c) == 'i');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'J':
+ ASSERT (c_tolower (c) == 'j');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'K':
+ ASSERT (c_tolower (c) == 'k');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'L':
+ ASSERT (c_tolower (c) == 'l');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'M':
+ ASSERT (c_tolower (c) == 'm');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'N':
+ ASSERT (c_tolower (c) == 'n');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'O':
+ ASSERT (c_tolower (c) == 'o');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'P':
+ ASSERT (c_tolower (c) == 'p');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'Q':
+ ASSERT (c_tolower (c) == 'q');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'R':
+ ASSERT (c_tolower (c) == 'r');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'S':
+ ASSERT (c_tolower (c) == 's');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'T':
+ ASSERT (c_tolower (c) == 't');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'U':
+ ASSERT (c_tolower (c) == 'u');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'V':
+ ASSERT (c_tolower (c) == 'v');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'W':
+ ASSERT (c_tolower (c) == 'w');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'X':
+ ASSERT (c_tolower (c) == 'x');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'Y':
+ ASSERT (c_tolower (c) == 'y');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'Z':
+ ASSERT (c_tolower (c) == 'z');
+ ASSERT (c_toupper (c) == c);
+ break;
+ case 'a':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'A');
+ break;
+ case 'b':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'B');
+ break;
+ case 'c':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'C');
+ break;
+ case 'd':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'D');
+ break;
+ case 'e':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'E');
+ break;
+ case 'f':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'F');
+ break;
+ case 'g':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'G');
+ break;
+ case 'h':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'H');
+ break;
+ case 'i':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'I');
+ break;
+ case 'j':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'J');
+ break;
+ case 'k':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'K');
+ break;
+ case 'l':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'L');
+ break;
+ case 'm':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'M');
+ break;
+ case 'n':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'N');
+ break;
+ case 'o':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'O');
+ break;
+ case 'p':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'P');
+ break;
+ case 'q':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'Q');
+ break;
+ case 'r':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'R');
+ break;
+ case 's':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'S');
+ break;
+ case 't':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'T');
+ break;
+ case 'u':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'U');
+ break;
+ case 'v':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'V');
+ break;
+ case 'w':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'W');
+ break;
+ case 'x':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'X');
+ break;
+ case 'y':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'Y');
+ break;
+ case 'z':
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == 'Z');
+ break;
+ default:
+ ASSERT (c_tolower (c) == c);
+ ASSERT (c_toupper (c) == c);
+ break;
+ }
+ }
+}
+
+int
+main ()
+{
+ test_all ();
+
+ setlocale (LC_ALL, "de_DE");
+ test_all ();
+
+ setlocale (LC_ALL, "ja_JP.EUC-JP");
+ test_all ();
+
+ return 0;
+}
diff --git a/tests/gnu/test-c-strcase.sh b/tests/gnu/test-c-strcase.sh
new file mode 100755
index 00000000..5fcf906b
--- /dev/null
+++ b/tests/gnu/test-c-strcase.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Test in the C locale.
+./test-c-strcasecmp${EXEEXT} || exit 1
+./test-c-strncasecmp${EXEEXT} || exit 1
+
+# Test in an ISO-8859-1 or ISO-8859-15 locale.
+: ${LOCALE_FR=fr_FR}
+if test $LOCALE_FR != none; then
+ LC_ALL=$LOCALE_FR ./test-c-strcasecmp${EXEEXT} locale || exit 1
+ LC_ALL=$LOCALE_FR ./test-c-strncasecmp${EXEEXT} locale || exit 1
+fi
+
+# Test in a Turkish UTF-8 locale.
+: ${LOCALE_TR_UTF8=tr_TR.UTF-8}
+if test $LOCALE_TR_UTF8 != none; then
+ LC_ALL=$LOCALE_TR_UTF8 ./test-c-strcasecmp${EXEEXT} locale || exit 1
+ LC_ALL=$LOCALE_TR_UTF8 ./test-c-strncasecmp${EXEEXT} locale || exit 1
+fi
+
+exit 0
diff --git a/tests/gnu/test-c-strcasecmp.c b/tests/gnu/test-c-strcasecmp.c
new file mode 100755
index 00000000..84ea9b55
--- /dev/null
+++ b/tests/gnu/test-c-strcasecmp.c
@@ -0,0 +1,65 @@
+/* Test of case-insensitive string comparison function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "c-strcase.h"
+
+#include <locale.h>
+#include <string.h>
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+ }
+
+ ASSERT (c_strcasecmp ("paragraph", "Paragraph") == 0);
+
+ ASSERT (c_strcasecmp ("paragrapH", "parAgRaph") == 0);
+
+ ASSERT (c_strcasecmp ("paragraph", "paraLyzed") < 0);
+ ASSERT (c_strcasecmp ("paraLyzed", "paragraph") > 0);
+
+ ASSERT (c_strcasecmp ("para", "paragraph") < 0);
+ ASSERT (c_strcasecmp ("paragraph", "para") > 0);
+
+ /* The following tests shows how c_strcasecmp() is different from
+ strcasecmp(). */
+
+ ASSERT (c_strcasecmp ("\311mile", "\351mile") < 0);
+ ASSERT (c_strcasecmp ("\351mile", "\311mile") > 0);
+
+ /* The following tests shows how c_strcasecmp() is different from
+ mbscasecmp(). */
+
+ ASSERT (c_strcasecmp ("\303\266zg\303\274r", "\303\226ZG\303\234R") > 0); /* özgür */
+ ASSERT (c_strcasecmp ("\303\226ZG\303\234R", "\303\266zg\303\274r") < 0); /* özgür */
+
+ /* This test shows how strings of different size cannot compare equal. */
+ ASSERT (c_strcasecmp ("turkish", "TURK\304\260SH") < 0);
+ ASSERT (c_strcasecmp ("TURK\304\260SH", "turkish") > 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-c-strncasecmp.c b/tests/gnu/test-c-strncasecmp.c
new file mode 100755
index 00000000..f02cb2d6
--- /dev/null
+++ b/tests/gnu/test-c-strncasecmp.c
@@ -0,0 +1,79 @@
+/* Test of case-insensitive string comparison function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "c-strcase.h"
+
+#include <locale.h>
+#include <string.h>
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+ }
+
+ ASSERT (c_strncasecmp ("paragraph", "Paragraph", 1000000) == 0);
+ ASSERT (c_strncasecmp ("paragraph", "Paragraph", 9) == 0);
+
+ ASSERT (c_strncasecmp ("paragrapH", "parAgRaph", 1000000) == 0);
+ ASSERT (c_strncasecmp ("paragrapH", "parAgRaph", 9) == 0);
+
+ ASSERT (c_strncasecmp ("paragraph", "paraLyzed", 10) < 0);
+ ASSERT (c_strncasecmp ("paragraph", "paraLyzed", 9) < 0);
+ ASSERT (c_strncasecmp ("paragraph", "paraLyzed", 5) < 0);
+ ASSERT (c_strncasecmp ("paragraph", "paraLyzed", 4) == 0);
+ ASSERT (c_strncasecmp ("paraLyzed", "paragraph", 10) > 0);
+ ASSERT (c_strncasecmp ("paraLyzed", "paragraph", 9) > 0);
+ ASSERT (c_strncasecmp ("paraLyzed", "paragraph", 5) > 0);
+ ASSERT (c_strncasecmp ("paraLyzed", "paragraph", 4) == 0);
+
+ ASSERT (c_strncasecmp ("para", "paragraph", 10) < 0);
+ ASSERT (c_strncasecmp ("para", "paragraph", 9) < 0);
+ ASSERT (c_strncasecmp ("para", "paragraph", 5) < 0);
+ ASSERT (c_strncasecmp ("para", "paragraph", 4) == 0);
+ ASSERT (c_strncasecmp ("paragraph", "para", 10) > 0);
+ ASSERT (c_strncasecmp ("paragraph", "para", 9) > 0);
+ ASSERT (c_strncasecmp ("paragraph", "para", 5) > 0);
+ ASSERT (c_strncasecmp ("paragraph", "para", 4) == 0);
+
+ /* The following tests shows how c_strncasecmp() is different from
+ strncasecmp(). */
+
+ ASSERT (c_strncasecmp ("\311mily", "\351mile", 4) < 0);
+ ASSERT (c_strncasecmp ("\351mile", "\311mily", 4) > 0);
+
+ /* The following tests shows how c_strncasecmp() is different from
+ mbsncasecmp(). */
+
+ ASSERT (c_strncasecmp ("\303\266zg\303\274r", "\303\226ZG\303\234R", 99) > 0); /* özgür */
+ ASSERT (c_strncasecmp ("\303\226ZG\303\234R", "\303\266zg\303\274r", 99) < 0); /* özgür */
+
+ /* This test shows how strings of different size cannot compare equal. */
+ ASSERT (c_strncasecmp ("turkish", "TURK\304\260SH", 7) < 0);
+ ASSERT (c_strncasecmp ("TURK\304\260SH", "turkish", 7) > 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-canonicalize-lgpl.c b/tests/gnu/test-canonicalize-lgpl.c
new file mode 100755
index 00000000..cbf481d3
--- /dev/null
+++ b/tests/gnu/test-canonicalize-lgpl.c
@@ -0,0 +1,222 @@
+/* Test of execution of program termination handlers.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (realpath, char *, (const char *, char *));
+SIGNATURE_CHECK (canonicalize_file_name, char *, (const char *));
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "same-inode.h"
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "t-can-lgpl.tmp"
+
+static void *
+null_ptr (void)
+{
+ return NULL;
+}
+
+int
+main (void)
+{
+#ifdef GNULIB_CANONICALIZE
+ /* No need to test canonicalize-lgpl module if canonicalize is also
+ in use. */
+ return 0;
+#endif
+
+ /* Setup some hierarchy to be used by this test. Start by removing
+ any leftovers from a previous partial run. */
+ {
+ int fd;
+ ignore_value (system ("rm -rf " BASE " ise"));
+ ASSERT (mkdir (BASE, 0700) == 0);
+ fd = creat (BASE "/tra", 0600);
+ ASSERT (0 <= fd);
+ ASSERT (close (fd) == 0);
+ }
+
+ /* Check for ., .., intermediate // handling, and for error cases. */
+ {
+ char *result = canonicalize_file_name (BASE "//./..//" BASE "/tra");
+ ASSERT (result != NULL);
+ ASSERT (strstr (result, "/" BASE "/tra")
+ == result + strlen (result) - strlen ("/" BASE "/tra"));
+ free (result);
+ errno = 0;
+ result = canonicalize_file_name ("");
+ ASSERT (result == NULL);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ result = canonicalize_file_name (null_ptr ());
+ ASSERT (result == NULL);
+ ASSERT (errno == EINVAL);
+ }
+
+ /* Check that a non-directory with trailing slash yields NULL. */
+ {
+ char *result;
+ errno = 0;
+ result = canonicalize_file_name (BASE "/tra/");
+ ASSERT (result == NULL);
+ ASSERT (errno == ENOTDIR);
+ }
+
+ /* Check that a missing directory yields NULL. */
+ {
+ char *result;
+ errno = 0;
+ result = canonicalize_file_name (BASE "/zzz/..");
+ ASSERT (result == NULL);
+ ASSERT (errno == ENOENT);
+ }
+
+ /* From here on out, tests involve symlinks. */
+ if (symlink (BASE "/ket", "ise") != 0)
+ {
+ ASSERT (remove (BASE "/tra") == 0);
+ ASSERT (rmdir (BASE) == 0);
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+ ASSERT (symlink ("bef", BASE "/plo") == 0);
+ ASSERT (symlink ("tra", BASE "/huk") == 0);
+ ASSERT (symlink ("lum", BASE "/bef") == 0);
+ ASSERT (symlink ("wum", BASE "/ouk") == 0);
+ ASSERT (symlink ("../ise", BASE "/ket") == 0);
+ ASSERT (mkdir (BASE "/lum", 0700) == 0);
+ ASSERT (symlink ("//.//../..", BASE "/droot") == 0);
+
+ /* Check that the symbolic link to a file can be resolved. */
+ {
+ char *result1 = canonicalize_file_name (BASE "/huk");
+ char *result2 = canonicalize_file_name (BASE "/tra");
+ ASSERT (result1 != NULL);
+ ASSERT (result2 != NULL);
+ ASSERT (strcmp (result1, result2) == 0);
+ ASSERT (strcmp (result1 + strlen (result1) - strlen ("/" BASE "/tra"),
+ "/" BASE "/tra") == 0);
+ free (result1);
+ free (result2);
+ }
+
+ /* Check that the symbolic link to a directory can be resolved. */
+ {
+ char *result1 = canonicalize_file_name (BASE "/plo");
+ char *result2 = canonicalize_file_name (BASE "/bef");
+ char *result3 = canonicalize_file_name (BASE "/lum");
+ ASSERT (result1 != NULL);
+ ASSERT (result2 != NULL);
+ ASSERT (result3 != NULL);
+ ASSERT (strcmp (result1, result2) == 0);
+ ASSERT (strcmp (result2, result3) == 0);
+ ASSERT (strcmp (result1 + strlen (result1) - strlen ("/" BASE "/lum"),
+ "/" BASE "/lum") == 0);
+ free (result1);
+ free (result2);
+ free (result3);
+ }
+
+ /* Check that a symbolic link to a nonexistent file yields NULL. */
+ {
+ char *result;
+ errno = 0;
+ result = canonicalize_file_name (BASE "/ouk");
+ ASSERT (result == NULL);
+ ASSERT (errno == ENOENT);
+ }
+
+ /* Check that a non-directory symlink with trailing slash yields NULL. */
+ {
+ char *result;
+ errno = 0;
+ result = canonicalize_file_name (BASE "/huk/");
+ ASSERT (result == NULL);
+ ASSERT (errno == ENOTDIR);
+ }
+
+ /* Check that a missing directory via symlink yields NULL. */
+ {
+ char *result;
+ errno = 0;
+ result = canonicalize_file_name (BASE "/ouk/..");
+ ASSERT (result == NULL);
+ ASSERT (errno == ENOENT);
+ }
+
+ /* Check that a loop of symbolic links is detected. */
+ {
+ char *result;
+ errno = 0;
+ result = canonicalize_file_name ("ise");
+ ASSERT (result == NULL);
+ ASSERT (errno == ELOOP);
+ }
+
+ /* Check that leading // is honored correctly. */
+ {
+ struct stat st1;
+ struct stat st2;
+ char *result1 = canonicalize_file_name ("//.");
+ char *result2 = canonicalize_file_name (BASE "/droot");
+ ASSERT (result1);
+ ASSERT (result2);
+ ASSERT (stat ("/", &st1) == 0);
+ ASSERT (stat ("//", &st2) == 0);
+ if (SAME_INODE (st1, st2))
+ {
+ ASSERT (strcmp (result1, "/") == 0);
+ ASSERT (strcmp (result2, "/") == 0);
+ }
+ else
+ {
+ ASSERT (strcmp (result1, "//") == 0);
+ ASSERT (strcmp (result2, "//") == 0);
+ }
+ free (result1);
+ free (result2);
+ }
+
+
+ /* Cleanup. */
+ ASSERT (remove (BASE "/droot") == 0);
+ ASSERT (remove (BASE "/plo") == 0);
+ ASSERT (remove (BASE "/huk") == 0);
+ ASSERT (remove (BASE "/bef") == 0);
+ ASSERT (remove (BASE "/ouk") == 0);
+ ASSERT (remove (BASE "/ket") == 0);
+ ASSERT (remove (BASE "/lum") == 0);
+ ASSERT (remove (BASE "/tra") == 0);
+ ASSERT (remove (BASE) == 0);
+ ASSERT (remove ("ise") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-cloexec.c b/tests/gnu/test-cloexec.c
new file mode 100755
index 00000000..801ac232
--- /dev/null
+++ b/tests/gnu/test-cloexec.c
@@ -0,0 +1,141 @@
+/* Test duplicating non-inheritable file descriptors.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include "cloexec.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions. */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#include "binary-io.h"
+#include "macros.h"
+
+/* Return non-zero if FD is open and inheritable across exec/spawn. */
+static int
+is_inheritable (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On Win32, the initial state of unassigned standard file
+ descriptors is that they are open but point to an
+ INVALID_HANDLE_VALUE, and there is no fcntl. */
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ DWORD flags;
+ if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
+ return 0;
+ return (flags & HANDLE_FLAG_INHERIT) != 0;
+#else
+# ifndef F_GETFD
+# error Please port fcntl to your platform
+# endif
+ int i = fcntl (fd, F_GETFD);
+ return 0 <= i && (i & FD_CLOEXEC) == 0;
+#endif
+}
+
+#if !O_BINARY
+# define setmode(f,m) zero ()
+static int zero (void) { return 0; }
+#endif
+
+/* Return non-zero if FD is open in the given MODE, which is either
+ O_TEXT or O_BINARY. */
+static int
+is_mode (int fd, int mode)
+{
+ int value = setmode (fd, O_BINARY);
+ setmode (fd, value);
+ return mode == value;
+}
+
+int
+main (void)
+{
+ const char *file = "test-cloexec.tmp";
+ int fd = creat (file, 0600);
+ int fd2;
+
+ /* Assume std descriptors were provided by invoker. */
+ ASSERT (STDERR_FILENO < fd);
+ ASSERT (is_inheritable (fd));
+
+ /* Normal use of set_cloexec_flag. */
+ ASSERT (set_cloexec_flag (fd, true) == 0);
+#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+ ASSERT (!is_inheritable (fd));
+#endif
+ ASSERT (set_cloexec_flag (fd, false) == 0);
+ ASSERT (is_inheritable (fd));
+
+ /* Normal use of dup_cloexec. */
+ fd2 = dup_cloexec (fd);
+ ASSERT (fd < fd2);
+ ASSERT (!is_inheritable (fd2));
+ ASSERT (close (fd) == 0);
+ ASSERT (dup_cloexec (fd2) == fd);
+ ASSERT (!is_inheritable (fd));
+ ASSERT (close (fd2) == 0);
+
+ /* On systems that distinguish between text and binary mode,
+ dup_cloexec reuses the mode of the source. */
+ setmode (fd, O_BINARY);
+ ASSERT (is_mode (fd, O_BINARY));
+ fd2 = dup_cloexec (fd);
+ ASSERT (fd < fd2);
+ ASSERT (is_mode (fd2, O_BINARY));
+ ASSERT (close (fd2) == 0);
+ setmode (fd, O_TEXT);
+ ASSERT (is_mode (fd, O_TEXT));
+ fd2 = dup_cloexec (fd);
+ ASSERT (fd < fd2);
+ ASSERT (is_mode (fd2, O_TEXT));
+ ASSERT (close (fd2) == 0);
+
+ /* Test error handling. */
+ errno = 0;
+ ASSERT (set_cloexec_flag (-1, false) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (set_cloexec_flag (10000000, false) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (set_cloexec_flag (fd2, false) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (dup_cloexec (-1) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (dup_cloexec (10000000) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (dup_cloexec (fd2) == -1);
+ ASSERT (errno == EBADF);
+
+ /* Clean up. */
+ ASSERT (close (fd) == 0);
+ ASSERT (unlink (file) == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-closein.c b/tests/gnu/test-closein.c
new file mode 100755
index 00000000..6b99b186
--- /dev/null
+++ b/tests/gnu/test-closein.c
@@ -0,0 +1,53 @@
+/* Test of closein module.
+ Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Eric Blake. */
+
+#include <config.h>
+
+#include "closein.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "binary-io.h"
+#include "ignore-value.h"
+
+char *program_name;
+
+/* With no arguments, do nothing. With arguments, attempt to consume
+ first 6 bytes of stdin. In either case, let exit() take care of
+ closing std streams and changing exit status if ferror(stdin). */
+int
+main (int argc, char **argv)
+{
+ char buf[7];
+ atexit (close_stdin);
+ program_name = argv[0];
+
+ /* close_stdin currently relies on ftell, but mingw ftell is
+ unreliable on text mode input. */
+ SET_BINARY (0);
+
+ if (argc > 2)
+ close (0);
+
+ if (argc > 1)
+ ignore_value (fread (buf, 1, 6, stdin));
+ return 0;
+}
diff --git a/tests/gnu/test-closein.sh b/tests/gnu/test-closein.sh
new file mode 100755
index 00000000..a75929a2
--- /dev/null
+++ b/tests/gnu/test-closein.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+tmpfiles=
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+p=t-closein-
+tmpfiles="${p}in.tmp ${p}xout.tmp ${p}out1.tmp ${p}out2.tmp"
+
+echo Hello world > ${p}in.tmp
+echo world > ${p}xout.tmp
+
+# Test with seekable stdin; followon process must see remaining data
+(./test-closein${EXEEXT}; cat) < ${p}in.tmp > ${p}out1.tmp || exit 1
+cmp ${p}out1.tmp ${p}in.tmp || exit 1
+
+(./test-closein${EXEEXT} consume; cat) < ${p}in.tmp > ${p}out2.tmp || exit 1
+cmp ${p}out2.tmp ${p}xout.tmp || exit 1
+
+# Test for lack of error on pipe. Ignore any EPIPE failures from cat.
+cat ${p}in.tmp 2>/dev/null | ./test-closein${EXEEXT} || exit 1
+
+cat ${p}in.tmp 2>/dev/null | ./test-closein${EXEEXT} consume || exit 1
+
+# Test for lack of error when nothing is read
+./test-closein${EXEEXT} </dev/null || exit 1
+
+./test-closein${EXEEXT} <&- || exit 1
+
+# Test for no error when EOF is read early
+./test-closein${EXEEXT} consume </dev/null || exit 1
+
+# Test for error when read fails because no file available
+./test-closein${EXEEXT} consume close <&- 2>/dev/null && exit 1
+
+# Cleanup
+rm -fr $tmpfiles
+
+exit 0
diff --git a/tests/gnu/test-dirname.c b/tests/gnu/test-dirname.c
new file mode 100755
index 00000000..88cb8d65
--- /dev/null
+++ b/tests/gnu/test-dirname.c
@@ -0,0 +1,191 @@
+/* Test the gnulib dirname module.
+ Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "dirname.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct test {
+ const char *name; /* Name under test. */
+ const char *dir; /* dir_name (name). */
+ const char *last; /* last_component (name). */
+ const char *base; /* base_name (name). */
+ const char *stripped; /* name after strip_trailing_slashes (name). */
+ bool modified; /* result of strip_trailing_slashes (name). */
+ bool absolute; /* IS_ABSOLUTE_FILE_NAME (name). */
+};
+
+static struct test tests[] = {
+ {"d/f", "d", "f", "f", "d/f", false, false},
+ {"/d/f", "/d", "f", "f", "/d/f", false, true},
+ {"d/f/", "d", "f/", "f/", "d/f", true, false},
+ {"d/f//", "d", "f//", "f/", "d/f", true, false},
+ {"f", ".", "f", "f", "f", false, false},
+ {"/", "/", "", "/", "/", false, true},
+#if DOUBLE_SLASH_IS_DISTINCT_ROOT
+ {"//", "//", "", "//", "//", false, true},
+ {"//d", "//", "d", "d", "//d", false, true},
+#else
+ {"//", "/", "", "/", "/", true, true},
+ {"//d", "/", "d", "d", "//d", false, true},
+#endif
+ {"///", "/", "", "/", "/", true, true},
+ {"///a///", "/", "a///", "a/", "///a", true, true},
+ /* POSIX requires dirname("") and basename("") to both return ".",
+ but dir_name and base_name are defined differently. */
+ {"", ".", "", "", "", false, false},
+ {".", ".", ".", ".", ".", false, false},
+ {"..", ".", "..", "..", "..", false, false},
+#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
+ {"a\\", ".", "a\\", "a\\", "a", true, false},
+ {"a\\b", "a", "b", "b", "a\\b", false, false},
+ {"\\", "\\", "", "\\", "\\", false, true},
+ {"\\/\\", "\\", "", "\\", "\\", true, true},
+ {"\\\\/", "\\", "", "\\", "\\", true, true},
+ {"\\//", "\\", "", "\\", "\\", true, true},
+ {"//\\", "/", "", "/", "/", true, true},
+#else
+ {"a\\", ".", "a\\", "a\\", "a\\", false, false},
+ {"a\\b", ".", "a\\b", "a\\b", "a\\b", false, false},
+ {"\\", ".", "\\", "\\", "\\", false, false},
+ {"\\/\\", "\\", "\\", "\\", "\\/\\",false, false},
+ {"\\\\/", ".", "\\\\/","\\\\/","\\\\", true, false},
+ {"\\//", ".", "\\//", "\\/", "\\", true, false},
+# if DOUBLE_SLASH_IS_DISTINCT_ROOT
+ {"//\\", "//", "\\", "\\", "//\\", false, true},
+# else
+ {"//\\", "/", "\\", "\\", "//\\", false, true},
+# endif
+#endif
+#if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+ {"c:", "c:", "", "c:", "c:", false, false},
+ {"c:/", "c:/", "", "c:/", "c:/", false, true},
+ {"c://", "c:/", "", "c:/", "c:/", true, true},
+ {"c:/d", "c:/", "d", "d", "c:/d", false, true},
+ {"c://d", "c:/", "d", "d", "c://d",false, true},
+ {"c:/d/", "c:/", "d/", "d/", "c:/d", true, true},
+ {"c:/d/f", "c:/d", "f", "f", "c:/d/f",false, true},
+ {"c:d", "c:.", "d", "d", "c:d", false, false},
+ {"c:d/", "c:.", "d/", "d/", "c:d", true, false},
+ {"c:d/f", "c:d", "f", "f", "c:d/f",false, false},
+ {"a:b:c", "a:.", "b:c", "./b:c","a:b:c",false, false},
+ {"a/b:c", "a", "b:c", "./b:c","a/b:c",false, false},
+ {"a/b:c/", "a", "b:c/", "./b:c/","a/b:c",true, false},
+# else /* ! FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE */
+ {"c:", "c:", "", "c:", "c:", false, true},
+ {"c:/", "c:", "", "c:", "c:", true, true},
+ {"c://", "c:", "", "c:", "c:", true, true},
+ {"c:/d", "c:", "d", "d", "c:/d", false, true},
+ {"c://d", "c:", "d", "d", "c://d",false, true},
+ {"c:/d/", "c:", "d/", "d/", "c:/d", true, true},
+ {"c:/d/f", "c:/d", "f", "f", "c:/d/f",false, true},
+ {"c:d", "c:", "d", "d", "c:d", false, true},
+ {"c:d/", "c:", "d/", "d/", "c:d", true, true},
+ {"c:d/f", "c:d", "f", "f", "c:d/f",false, true},
+ {"a:b:c", "a:", "b:c", "./b:c","a:b:c",false, true},
+ {"a/b:c", "a", "b:c", "./b:c","a/b:c",false, false},
+ {"a/b:c/", "a", "b:c/", "./b:c/","a/b:c",true, false},
+# endif
+#else /* ! FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX */
+ {"c:", ".", "c:", "c:", "c:", false, false},
+ {"c:/", ".", "c:/", "c:/", "c:", true, false},
+ {"c://", ".", "c://", "c:/", "c:", true, false},
+ {"c:/d", "c:", "d", "d", "c:/d", false, false},
+ {"c://d", "c:", "d", "d", "c://d",false, false},
+ {"c:/d/", "c:", "d/", "d/", "c:/d", true, false},
+ {"c:/d/f", "c:/d", "f", "f", "c:/d/f",false, false},
+ {"c:d", ".", "c:d", "c:d", "c:d", false, false},
+ {"c:d/", ".", "c:d/", "c:d/", "c:d", true, false},
+ {"c:d/f", "c:d", "f", "f", "c:d/f",false, false},
+ {"a:b:c", ".", "a:b:c","a:b:c","a:b:c",false, false},
+ {"a/b:c", "a", "b:c", "b:c", "a/b:c",false, false},
+ {"a/b:c/", "a", "b:c/", "b:c/", "a/b:c",true, false},
+#endif
+ {"1:", ".", "1:", "1:", "1:", false, false},
+ {"1:/", ".", "1:/", "1:/", "1:", true, false},
+ {"/:", "/", ":", ":", "/:", false, true},
+ {"/:/", "/", ":/", ":/", "/:", true, true},
+ /* End sentinel. */
+ {NULL, NULL, NULL, NULL, NULL, false, false}
+};
+
+int
+main (void)
+{
+ struct test *t;
+ bool ok = true;
+
+ for (t = tests; t->name; t++)
+ {
+ char *dir = dir_name (t->name);
+ int dirlen = dir_len (t->name);
+ char *last = last_component (t->name);
+ char *base = base_name (t->name);
+ int baselen = base_len (base);
+ char *stripped = strdup (t->name);
+ bool modified = strip_trailing_slashes (stripped);
+ bool absolute = IS_ABSOLUTE_FILE_NAME (t->name);
+ if (! (strcmp (dir, t->dir) == 0
+ && (dirlen == strlen (dir)
+ || (dirlen + 1 == strlen (dir) && dir[dirlen] == '.'))))
+ {
+ ok = false;
+ printf ("dir_name `%s': got `%s' len %d, expected `%s' len %ld\n",
+ t->name, dir, dirlen,
+ t->dir, (unsigned long) strlen (t->dir));
+ }
+ if (strcmp (last, t->last))
+ {
+ ok = false;
+ printf ("last_component `%s': got `%s', expected `%s'\n",
+ t->name, last, t->last);
+ }
+ if (! (strcmp (base, t->base) == 0
+ && (baselen == strlen (base)
+ || (baselen + 1 == strlen (base)
+ && ISSLASH (base[baselen])))))
+ {
+ ok = false;
+ printf ("base_name `%s': got `%s' len %d, expected `%s' len %ld\n",
+ t->name, base, baselen,
+ t->base, (unsigned long) strlen (t->base));
+ }
+ if (strcmp (stripped, t->stripped) || modified != t->modified)
+ {
+ ok = false;
+ printf ("strip_trailing_slashes `%s': got %s %s, expected %s %s\n",
+ t->name, stripped, modified ? "changed" : "unchanged",
+ t->stripped, t->modified ? "changed" : "unchanged");
+ }
+ if (t->absolute != absolute)
+ {
+ ok = false;
+ printf ("`%s': got %s, expected %s\n", t->name,
+ absolute ? "absolute" : "relative",
+ t->absolute ? "absolute" : "relative");
+ }
+ free (dir);
+ free (base);
+ free (stripped);
+ }
+ return ok ? 0 : 1;
+}
diff --git a/tests/gnu/test-dup-safer.c b/tests/gnu/test-dup-safer.c
new file mode 100755
index 00000000..28f13177
--- /dev/null
+++ b/tests/gnu/test-dup-safer.c
@@ -0,0 +1,175 @@
+/* Test that dup_safer leaves standard fds alone.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include "unistd--.h"
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "binary-io.h"
+#include "cloexec.h"
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions. */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#if !O_BINARY
+# define setmode(f,m) zero ()
+static int zero (void) { return 0; }
+#endif
+#ifndef O_CLOEXEC
+# define O_CLOEXEC 0
+#endif
+
+/* This test intentionally closes stderr. So, we arrange to have fd 10
+ (outside the range of interesting fd's during the test) set up to
+ duplicate the original stderr. */
+
+#define BACKUP_STDERR_FILENO 10
+#define ASSERT_STREAM myerr
+#include "macros.h"
+
+static FILE *myerr;
+
+/* Return true if FD is open. */
+static bool
+is_open (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On Win32, the initial state of unassigned standard file
+ descriptors is that they are open but point to an
+ INVALID_HANDLE_VALUE, and there is no fcntl. */
+ return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
+#else
+# ifndef F_GETFL
+# error Please port fcntl to your platform
+# endif
+ return 0 <= fcntl (fd, F_GETFL);
+#endif
+}
+
+/* Return true if FD is open and inheritable across exec/spawn. */
+static bool
+is_inheritable (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On Win32, the initial state of unassigned standard file
+ descriptors is that they are open but point to an
+ INVALID_HANDLE_VALUE, and there is no fcntl. */
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ DWORD flags;
+ if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
+ return 0;
+ return (flags & HANDLE_FLAG_INHERIT) != 0;
+#else
+# ifndef F_GETFD
+# error Please port fcntl to your platform
+# endif
+ int i = fcntl (fd, F_GETFD);
+ return 0 <= i && (i & FD_CLOEXEC) == 0;
+#endif
+}
+
+/* Return true if FD is open in the given MODE, which is either
+ O_TEXT or O_BINARY. */
+static bool
+is_mode (int fd, int mode)
+{
+ int value = setmode (fd, O_BINARY);
+ setmode (fd, value);
+ return mode == value;
+}
+
+#define witness "test-dup-safer.txt"
+
+int
+main (void)
+{
+ int i;
+ int fd;
+
+ /* We close fd 2 later, so save it in fd 10. */
+ if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
+ || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
+ return 2;
+
+ /* Create file for later checks. */
+ fd = creat (witness, 0600);
+ ASSERT (STDERR_FILENO < fd);
+
+ /* Four iterations, with progressively more standard descriptors
+ closed. */
+ for (i = -1; i <= STDERR_FILENO; i++)
+ {
+ if (0 <= i)
+ ASSERT (close (i) == 0);
+
+ /* Detect errors. */
+ errno = 0;
+ ASSERT (dup (-1) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (dup (10000000) == -1);
+ ASSERT (errno == EBADF);
+ close (fd + 1);
+ errno = 0;
+ ASSERT (dup (fd + 1) == -1);
+ ASSERT (errno == EBADF);
+
+ /* Preserve text vs. binary. */
+ setmode (fd, O_BINARY);
+ ASSERT (dup (fd) == fd + 1);
+ ASSERT (is_open (fd + 1));
+ ASSERT (is_inheritable (fd + 1));
+ ASSERT (is_mode (fd + 1, O_BINARY));
+
+ ASSERT (close (fd + 1) == 0);
+ setmode (fd, O_TEXT);
+ ASSERT (dup (fd) == fd + 1);
+ ASSERT (is_open (fd + 1));
+ ASSERT (is_inheritable (fd + 1));
+ ASSERT (is_mode (fd + 1, O_TEXT));
+
+ /* Create cloexec copy. */
+ ASSERT (close (fd + 1) == 0);
+ ASSERT (fd_safer_flag (dup_cloexec (fd), O_CLOEXEC) == fd + 1);
+ ASSERT (set_cloexec_flag (fd + 1, true) == 0);
+ ASSERT (is_open (fd + 1));
+ ASSERT (!is_inheritable (fd + 1));
+ ASSERT (close (fd) == 0);
+
+ /* dup always creates inheritable copies. Also, check that
+ earliest slot past std fds is used. */
+ ASSERT (dup (fd + 1) == fd);
+ ASSERT (is_open (fd));
+ ASSERT (is_inheritable (fd));
+ ASSERT (close (fd + 1) == 0);
+ }
+
+ /* Cleanup. */
+ ASSERT (close (fd) == 0);
+ ASSERT (unlink (witness) == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-dup2.c b/tests/gnu/test-dup2.c
new file mode 100755
index 00000000..3bad63a0
--- /dev/null
+++ b/tests/gnu/test-dup2.c
@@ -0,0 +1,193 @@
+/* Test duplicating file descriptors.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (dup2, int, (int, int));
+
+#include <errno.h>
+#include <fcntl.h>
+
+#include "binary-io.h"
+
+#if GNULIB_CLOEXEC
+# include "cloexec.h"
+#endif
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions. */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#include "macros.h"
+
+/* Return non-zero if FD is open. */
+static int
+is_open (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On Win32, the initial state of unassigned standard file
+ descriptors is that they are open but point to an
+ INVALID_HANDLE_VALUE, and there is no fcntl. */
+ return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
+#else
+# ifndef F_GETFL
+# error Please port fcntl to your platform
+# endif
+ return 0 <= fcntl (fd, F_GETFL);
+#endif
+}
+
+#if GNULIB_CLOEXEC
+/* Return non-zero if FD is open and inheritable across exec/spawn. */
+static int
+is_inheritable (int fd)
+{
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On Win32, the initial state of unassigned standard file
+ descriptors is that they are open but point to an
+ INVALID_HANDLE_VALUE, and there is no fcntl. */
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ DWORD flags;
+ if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
+ return 0;
+ return (flags & HANDLE_FLAG_INHERIT) != 0;
+# else
+# ifndef F_GETFD
+# error Please port fcntl to your platform
+# endif
+ int i = fcntl (fd, F_GETFD);
+ return 0 <= i && (i & FD_CLOEXEC) == 0;
+# endif
+}
+#endif /* GNULIB_CLOEXEC */
+
+#if !O_BINARY
+# define setmode(f,m) zero ()
+static int zero (void) { return 0; }
+#endif
+
+/* Return non-zero if FD is open in the given MODE, which is either
+ O_TEXT or O_BINARY. */
+static int
+is_mode (int fd, int mode)
+{
+ int value = setmode (fd, O_BINARY);
+ setmode (fd, value);
+ return mode == value;
+}
+
+int
+main (void)
+{
+ const char *file = "test-dup2.tmp";
+ char buffer[1];
+ int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600);
+
+ /* Assume std descriptors were provided by invoker. */
+ ASSERT (STDERR_FILENO < fd);
+ ASSERT (is_open (fd));
+ /* Ignore any other fd's leaked into this process. */
+ close (fd + 1);
+ close (fd + 2);
+ ASSERT (!is_open (fd + 1));
+ ASSERT (!is_open (fd + 2));
+
+ /* Assigning to self must be a no-op. */
+ ASSERT (dup2 (fd, fd) == fd);
+ ASSERT (is_open (fd));
+
+ /* The source must be valid. */
+ errno = 0;
+ ASSERT (dup2 (-1, fd) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (dup2 (AT_FDCWD, fd) == -1);
+ ASSERT (errno == EBADF);
+ ASSERT (is_open (fd));
+
+ /* If the source is not open, then the destination is unaffected. */
+ errno = 0;
+ ASSERT (dup2 (fd + 1, fd + 1) == -1);
+ ASSERT (errno == EBADF);
+ ASSERT (!is_open (fd + 1));
+ errno = 0;
+ ASSERT (dup2 (fd + 1, fd) == -1);
+ ASSERT (errno == EBADF);
+ ASSERT (is_open (fd));
+
+ /* The destination must be valid. */
+ errno = 0;
+ ASSERT (dup2 (fd, -2) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (dup2 (fd, 10000000) == -1);
+ ASSERT (errno == EBADF);
+
+ /* Using dup2 can skip fds. */
+ ASSERT (dup2 (fd, fd + 2) == fd + 2);
+ ASSERT (is_open (fd));
+ ASSERT (!is_open (fd + 1));
+ ASSERT (is_open (fd + 2));
+
+ /* Verify that dup2 closes the previous occupant of a fd. */
+ ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1);
+ ASSERT (dup2 (fd + 1, fd) == fd);
+ ASSERT (close (fd + 1) == 0);
+ ASSERT (write (fd, "1", 1) == 1);
+ ASSERT (dup2 (fd + 2, fd) == fd);
+ ASSERT (lseek (fd, 0, SEEK_END) == 0);
+ ASSERT (write (fd + 2, "2", 1) == 1);
+ ASSERT (lseek (fd, 0, SEEK_SET) == 0);
+ ASSERT (read (fd, buffer, 1) == 1);
+ ASSERT (*buffer == '2');
+
+#if GNULIB_CLOEXEC
+ /* Any new fd created by dup2 must not be cloexec. */
+ ASSERT (close (fd + 2) == 0);
+ ASSERT (dup_cloexec (fd) == fd + 1);
+ ASSERT (!is_inheritable (fd + 1));
+ ASSERT (dup2 (fd + 1, fd + 1) == fd + 1);
+ ASSERT (!is_inheritable (fd + 1));
+ ASSERT (dup2 (fd + 1, fd + 2) == fd + 2);
+ ASSERT (is_inheritable (fd + 2));
+#endif
+
+ /* On systems that distinguish between text and binary mode, dup2
+ reuses the mode of the source. */
+ setmode (fd, O_BINARY);
+ ASSERT (is_mode (fd, O_BINARY));
+ ASSERT (dup2 (fd, fd + 1) == fd + 1);
+ ASSERT (is_mode (fd + 1, O_BINARY));
+ setmode (fd, O_TEXT);
+ ASSERT (is_mode (fd, O_TEXT));
+ ASSERT (dup2 (fd, fd + 1) == fd + 1);
+ ASSERT (is_mode (fd + 1, O_TEXT));
+
+ /* Clean up. */
+ ASSERT (close (fd + 2) == 0);
+ ASSERT (close (fd + 1) == 0);
+ ASSERT (close (fd) == 0);
+ ASSERT (unlink (file) == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-environ.c b/tests/gnu/test-environ.c
new file mode 100755
index 00000000..534c4e60
--- /dev/null
+++ b/tests/gnu/test-environ.c
@@ -0,0 +1,44 @@
+/* Test of environ variable.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <string.h>
+
+int
+main ()
+{
+ /* The environment variables that are set even in the weirdest situations
+ are HOME and PATH.
+ POSIX says that HOME is initialized by the system, and that PATH may be
+ unset. But in practice it's more frequent to see HOME unset and PATH
+ set. So we test the presence of PATH. */
+ char **remaining_variables = environ;
+ char *string;
+
+ for (; (string = *remaining_variables) != NULL; remaining_variables++)
+ {
+ if (strncmp (string, "PATH=", 5) == 0)
+ /* Found the PATH environment variable. */
+ return 0;
+ }
+ /* Failed to find the PATH environment variable. */
+ return 1;
+}
diff --git a/tests/gnu/test-errno.c b/tests/gnu/test-errno.c
new file mode 100755
index 00000000..129b236f
--- /dev/null
+++ b/tests/gnu/test-errno.c
@@ -0,0 +1,117 @@
+/* Test of <errno.h> substitute.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <errno.h>
+
+/* Verify that the POSIX mandated errno values exist and can be used as
+ initializers outside of a function.
+ The variable names happen to match the Linux/x86 error numbers. */
+int e1 = EPERM;
+int e2 = ENOENT;
+int e3 = ESRCH;
+int e4 = EINTR;
+int e5 = EIO;
+int e6 = ENXIO;
+int e7 = E2BIG;
+int e8 = ENOEXEC;
+int e9 = EBADF;
+int e10 = ECHILD;
+int e11 = EAGAIN;
+int e11a = EWOULDBLOCK;
+int e12 = ENOMEM;
+int e13 = EACCES;
+int e14 = EFAULT;
+int e16 = EBUSY;
+int e17 = EEXIST;
+int e18 = EXDEV;
+int e19 = ENODEV;
+int e20 = ENOTDIR;
+int e21 = EISDIR;
+int e22 = EINVAL;
+int e23 = ENFILE;
+int e24 = EMFILE;
+int e25 = ENOTTY;
+int e26 = ETXTBSY;
+int e27 = EFBIG;
+int e28 = ENOSPC;
+int e29 = ESPIPE;
+int e30 = EROFS;
+int e31 = EMLINK;
+int e32 = EPIPE;
+int e33 = EDOM;
+int e34 = ERANGE;
+int e35 = EDEADLK;
+int e36 = ENAMETOOLONG;
+int e37 = ENOLCK;
+int e38 = ENOSYS;
+int e39 = ENOTEMPTY;
+int e40 = ELOOP;
+int e42 = ENOMSG;
+int e43 = EIDRM;
+int e67 = ENOLINK;
+int e71 = EPROTO;
+int e72 = EMULTIHOP;
+int e74 = EBADMSG;
+int e75 = EOVERFLOW;
+int e84 = EILSEQ;
+int e88 = ENOTSOCK;
+int e89 = EDESTADDRREQ;
+int e90 = EMSGSIZE;
+int e91 = EPROTOTYPE;
+int e92 = ENOPROTOOPT;
+int e93 = EPROTONOSUPPORT;
+int e95 = EOPNOTSUPP;
+int e95a = ENOTSUP;
+int e97 = EAFNOSUPPORT;
+int e98 = EADDRINUSE;
+int e99 = EADDRNOTAVAIL;
+int e100 = ENETDOWN;
+int e101 = ENETUNREACH;
+int e102 = ENETRESET;
+int e103 = ECONNABORTED;
+int e104 = ECONNRESET;
+int e105 = ENOBUFS;
+int e106 = EISCONN;
+int e107 = ENOTCONN;
+int e110 = ETIMEDOUT;
+int e111 = ECONNREFUSED;
+int e113 = EHOSTUNREACH;
+int e114 = EALREADY;
+int e115 = EINPROGRESS;
+int e116 = ESTALE;
+int e122 = EDQUOT;
+int e125 = ECANCELED;
+
+/* Don't verify that these errno values are all different, except for possibly
+ EWOULDBLOCK == EAGAIN. Even Linux/x86 does not pass this check: it has
+ ENOTSUP == EOPNOTSUPP. */
+
+int
+main ()
+{
+ /* Verify that errno can be assigned. */
+ errno = EOVERFLOW;
+
+ /* snprintf() callers want to distinguish EINVAL and EOVERFLOW. */
+ if (errno == EINVAL)
+ return 1;
+
+ return 0;
+}
diff --git a/tests/gnu/test-fcntl-h.c b/tests/gnu/test-fcntl-h.c
new file mode 100755
index 00000000..0ce33f0d
--- /dev/null
+++ b/tests/gnu/test-fcntl-h.c
@@ -0,0 +1,38 @@
+/* Test of <fcntl.h> substitute.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <fcntl.h>
+
+/* Check that the various O_* macros are defined. */
+int o = O_DIRECT | O_DIRECTORY | O_DSYNC | O_NDELAY | O_NOATIME | O_NONBLOCK
+ | O_NOCTTY | O_NOFOLLOW | O_NOLINKS | O_RSYNC | O_SYNC | O_TTY_INIT
+ | O_BINARY | O_TEXT;
+
+/* Check that the various SEEK_* macros are defined. */
+int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
+
+/* Check that the FD_* macros are defined. */
+int fd = FD_CLOEXEC;
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-fcntl.c b/tests/gnu/test-fcntl.c
new file mode 100755
index 00000000..71dfb986
--- /dev/null
+++ b/tests/gnu/test-fcntl.c
@@ -0,0 +1,346 @@
+/* Test of fcntl(2).
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+/* Specification. */
+#include <fcntl.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (fcntl, int, (int, int, ...));
+
+/* Helpers. */
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions. */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#include "binary-io.h"
+#include "macros.h"
+
+/* Use O_CLOEXEC if available, but test works without it. */
+#ifndef O_CLOEXEC
+# define O_CLOEXEC 0
+#endif
+
+#if !O_BINARY
+# define setmode(f,m) zero ()
+static int zero (void) { return 0; }
+#endif
+
+/* Return true if FD is open. */
+static bool
+is_open (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On Win32, the initial state of unassigned standard file
+ descriptors is that they are open but point to an
+ INVALID_HANDLE_VALUE, and there is no fcntl. */
+ return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
+#else
+# ifndef F_GETFL
+# error Please port fcntl to your platform
+# endif
+ return 0 <= fcntl (fd, F_GETFL);
+#endif
+}
+
+/* Return true if FD is open and inheritable across exec/spawn. */
+static bool
+is_inheritable (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On Win32, the initial state of unassigned standard file
+ descriptors is that they are open but point to an
+ INVALID_HANDLE_VALUE, and there is no fcntl. */
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ DWORD flags;
+ if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
+ return false;
+ return (flags & HANDLE_FLAG_INHERIT) != 0;
+#else
+# ifndef F_GETFD
+# error Please port fcntl to your platform
+# endif
+ int i = fcntl (fd, F_GETFD);
+ return 0 <= i && (i & FD_CLOEXEC) == 0;
+#endif
+}
+
+/* Return non-zero if FD is open in the given MODE, which is either
+ O_TEXT or O_BINARY. */
+static bool
+is_mode (int fd, int mode)
+{
+ int value = setmode (fd, O_BINARY);
+ setmode (fd, value);
+ return mode == value;
+}
+
+/* Since native fcntl can have more supported operations than our
+ replacement is aware of, and since various operations assign
+ different types to the vararg argument, a wrapper around fcntl must
+ be able to pass a vararg of unknown type on through to the original
+ fcntl. Make sure that this works properly: func1 behaves like the
+ original fcntl interpreting the vararg as an int or a pointer to a
+ struct, and func2 behaves like rpl_fcntl that doesn't know what
+ type to forward. */
+struct dummy_struct
+{
+ long filler;
+ int value;
+};
+static int
+func1 (int a, ...)
+{
+ va_list arg;
+ int i;
+ va_start (arg, a);
+ if (a < 4)
+ i = va_arg (arg, int);
+ else
+ {
+ struct dummy_struct *s = va_arg (arg, struct dummy_struct *);
+ i = s->value;
+ }
+ va_end (arg);
+ return i;
+}
+static int
+func2 (int a, ...)
+{
+ va_list arg;
+ void *p;
+ va_start (arg, a);
+ p = va_arg (arg, void *);
+ va_end (arg);
+ return func1 (a, p);
+}
+
+/* Ensure that all supported fcntl actions are distinct, and
+ usable in preprocessor expressions. */
+static void
+check_flags (void)
+{
+ switch (0)
+ {
+ case F_DUPFD:
+#if F_DUPFD
+#endif
+
+ case F_DUPFD_CLOEXEC:
+#if F_DUPFD_CLOEXEC
+#endif
+
+ case F_GETFD:
+#if F_GETFD
+#endif
+
+#ifdef F_SETFD
+ case F_SETFD:
+# if F_SETFD
+# endif
+#endif
+
+#ifdef F_GETFL
+ case F_GETFL:
+# if F_GETFL
+# endif
+#endif
+
+#ifdef F_SETFL
+ case F_SETFL:
+# if F_SETFL
+# endif
+#endif
+
+#ifdef F_GETOWN
+ case F_GETOWN:
+# if F_GETOWN
+# endif
+#endif
+
+#ifdef F_SETOWN
+ case F_SETOWN:
+# if F_SETOWN
+# endif
+#endif
+
+#ifdef F_GETLK
+ case F_GETLK:
+# if F_GETLK
+# endif
+#endif
+
+#ifdef F_SETLK
+ case F_SETLK:
+# if F_SETLK
+# endif
+#endif
+
+#ifdef F_SETLKW
+ case F_SETLKW:
+# if F_SETLKW
+# endif
+#endif
+
+ ;
+ }
+}
+
+int
+main (void)
+{
+ const char *file = "test-fcntl.tmp";
+ int fd;
+
+ /* Sanity check that rpl_fcntl is likely to work. */
+ ASSERT (func2 (1, 2) == 2);
+ ASSERT (func2 (2, -2) == -2);
+ ASSERT (func2 (3, 0x80000000) == 0x80000000);
+ {
+ struct dummy_struct s = { 0L, 4 };
+ ASSERT (func2 (4, &s) == 4);
+ }
+ check_flags ();
+
+ /* Assume std descriptors were provided by invoker, and ignore fds
+ that might have been inherited. */
+ fd = creat (file, 0600);
+ ASSERT (STDERR_FILENO < fd);
+ close (fd + 1);
+ close (fd + 2);
+
+ /* For F_DUPFD*, the source must be valid. */
+ errno = 0;
+ ASSERT (fcntl (-1, F_DUPFD, 0) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (fcntl (fd + 1, F_DUPFD, 0) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (fcntl (10000000, F_DUPFD, 0) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (fcntl (-1, F_DUPFD_CLOEXEC, 0) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (fcntl (fd + 1, F_DUPFD_CLOEXEC, 0) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (fcntl (10000000, F_DUPFD_CLOEXEC, 0) == -1);
+ ASSERT (errno == EBADF);
+
+ /* For F_DUPFD*, the destination must be valid. */
+ ASSERT (getdtablesize () < 10000000);
+ errno = 0;
+ ASSERT (fcntl (fd, F_DUPFD, -1) == -1);
+ ASSERT (errno == EINVAL);
+ errno = 0;
+ ASSERT (fcntl (fd, F_DUPFD, 10000000) == -1);
+ ASSERT (errno == EINVAL);
+ ASSERT (getdtablesize () < 10000000);
+ errno = 0;
+ ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, -1) == -1);
+ ASSERT (errno == EINVAL);
+ errno = 0;
+ ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, 10000000) == -1);
+ ASSERT (errno == EINVAL);
+
+ /* For F_DUPFD*, check for correct inheritance, as well as
+ preservation of text vs. binary. */
+ setmode (fd, O_BINARY);
+ ASSERT (is_open (fd));
+ ASSERT (!is_open (fd + 1));
+ ASSERT (!is_open (fd + 2));
+ ASSERT (is_inheritable (fd));
+ ASSERT (is_mode (fd, O_BINARY));
+
+ ASSERT (fcntl (fd, F_DUPFD, fd) == fd + 1);
+ ASSERT (is_open (fd));
+ ASSERT (is_open (fd + 1));
+ ASSERT (!is_open (fd + 2));
+ ASSERT (is_inheritable (fd + 1));
+ ASSERT (is_mode (fd, O_BINARY));
+ ASSERT (is_mode (fd + 1, O_BINARY));
+ ASSERT (close (fd + 1) == 0);
+
+ ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, fd + 2) == fd + 2);
+ ASSERT (is_open (fd));
+ ASSERT (!is_open (fd + 1));
+ ASSERT (is_open (fd + 2));
+ ASSERT (is_inheritable (fd));
+ ASSERT (!is_inheritable (fd + 2));
+ ASSERT (is_mode (fd, O_BINARY));
+ ASSERT (is_mode (fd + 2, O_BINARY));
+ ASSERT (close (fd) == 0);
+
+ setmode (fd + 2, O_TEXT);
+ ASSERT (fcntl (fd + 2, F_DUPFD, fd + 1) == fd + 1);
+ ASSERT (!is_open (fd));
+ ASSERT (is_open (fd + 1));
+ ASSERT (is_open (fd + 2));
+ ASSERT (is_inheritable (fd + 1));
+ ASSERT (!is_inheritable (fd + 2));
+ ASSERT (is_mode (fd + 1, O_TEXT));
+ ASSERT (is_mode (fd + 2, O_TEXT));
+ ASSERT (close (fd + 1) == 0);
+
+ ASSERT (fcntl (fd + 2, F_DUPFD_CLOEXEC, 0) == fd);
+ ASSERT (is_open (fd));
+ ASSERT (!is_open (fd + 1));
+ ASSERT (is_open (fd + 2));
+ ASSERT (!is_inheritable (fd));
+ ASSERT (!is_inheritable (fd + 2));
+ ASSERT (is_mode (fd, O_TEXT));
+ ASSERT (is_mode (fd + 2, O_TEXT));
+ ASSERT (close (fd + 2) == 0);
+
+ /* Test F_GETFD. */
+ errno = 0;
+ ASSERT (fcntl (-1, F_GETFD) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (fcntl (fd + 1, F_GETFD) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (fcntl (10000000, F_GETFD) == -1);
+ ASSERT (errno == EBADF);
+ {
+ int result = fcntl (fd, F_GETFD);
+ ASSERT (0 <= result);
+ ASSERT ((result & FD_CLOEXEC) == FD_CLOEXEC);
+ ASSERT (dup (fd) == fd + 1);
+ result = fcntl (fd + 1, F_GETFD);
+ ASSERT (0 <= result);
+ ASSERT ((result & FD_CLOEXEC) == 0);
+ ASSERT (close (fd + 1) == 0);
+ }
+
+ /* Cleanup. */
+ ASSERT (close (fd) == 0);
+ ASSERT (unlink (file) == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-fflush.c b/tests/gnu/test-fflush.c
new file mode 100755
index 00000000..12403e2a
--- /dev/null
+++ b/tests/gnu/test-fflush.c
@@ -0,0 +1,145 @@
+/* Test of POSIX compatible fflush() function.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake, 2007. */
+
+#include <config.h>
+
+/* None of the files accessed by this test are large, so disable the
+ ftell link warning if we are not using the gnulib ftell module. */
+#define _GL_NO_LARGE_FILES
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (fflush, int, (FILE *));
+
+#include <unistd.h>
+
+int
+main (void)
+{
+ FILE *f;
+ char buffer[10];
+ int fd;
+
+ /* Create test file. */
+ f = fopen ("test-fflush.txt", "w");
+ if (!f || fwrite ("1234567890ABCDEFG", 1, 17, f) != 17 || fclose (f) != 0)
+ {
+ fputs ("Failed to create sample file.\n", stderr);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+
+ /* Test fflush. */
+ f = fopen ("test-fflush.txt", "r");
+ fd = fileno (f);
+ if (!f || 0 > fd || fread (buffer, 1, 5, f) != 5)
+ {
+ fputs ("Failed initial read of sample file.\n", stderr);
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ /* For deterministic results, ensure f read a bigger buffer.
+ This is not the case on BeOS, nor on uClibc. */
+#if !(defined __BEOS__ || defined __UCLIBC__)
+ if (lseek (fd, 0, SEEK_CUR) == 5)
+ {
+ fputs ("Sample file was not buffered after fread.\n", stderr);
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+#endif
+ /* POSIX requires fflush-fseek to set file offset of fd. */
+ if (fflush (f) != 0 || fseeko (f, 0, SEEK_CUR) != 0)
+ {
+ fputs ("Failed to flush-fseek sample file.\n", stderr);
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ /* Check that offset is correct. */
+ if (lseek (fd, 0, SEEK_CUR) != 5)
+ {
+ fprintf (stderr, "File offset is wrong after fseek: %ld.\n",
+ (long) lseek (fd, 0, SEEK_CUR));
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ if (ftell (f) != 5)
+ {
+ fprintf (stderr, "ftell result is wrong after fseek: %ld.\n",
+ (long) ftell (f));
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ /* Check that file reading resumes at correct location. */
+ if (fgetc (f) != '6')
+ {
+ fputs ("Failed to read next byte after fseek.\n", stderr);
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ /* For deterministic results, ensure f read a bigger buffer. */
+ if (lseek (fd, 0, SEEK_CUR) == 6)
+ {
+ fputs ("Sample file was not buffered after fgetc.\n", stderr);
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ /* POSIX requires fflush-fseeko to set file offset of fd. */
+ if (fflush (f) != 0 || fseeko (f, 0, SEEK_CUR) != 0)
+ {
+ fputs ("Failed to flush-fseeko sample file.\n", stderr);
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ /* Check that offset is correct. */
+ if (lseek (fd, 0, SEEK_CUR) != 6)
+ {
+ fprintf (stderr, "File offset is wrong after fseeko: %ld.\n",
+ (long) lseek (fd, 0, SEEK_CUR));
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ if (ftell (f) != 6)
+ {
+ fprintf (stderr, "ftell result is wrong after fseeko: %ld.\n",
+ (long) ftell (f));
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ /* Check that file reading resumes at correct location. */
+ if (fgetc (f) != '7')
+ {
+ fputs ("Failed to read next byte after fseeko.\n", stderr);
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 1;
+ }
+ fclose (f);
+ unlink ("test-fflush.txt");
+ return 0;
+}
diff --git a/tests/gnu/test-fflush2.c b/tests/gnu/test-fflush2.c
new file mode 100755
index 00000000..c89dc912
--- /dev/null
+++ b/tests/gnu/test-fflush2.c
@@ -0,0 +1,108 @@
+/* Test of POSIX compatible fflush() function.
+ Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "binary-io.h"
+#include "macros.h"
+
+int
+main (int argc, char **argv)
+{
+ int c;
+
+ /* Avoid the well-known bugs of fflush() on streams in O_TEXT mode
+ on native Windows platforms. */
+ SET_BINARY (0);
+
+ if (argc > 1)
+ switch (argv[1][0])
+ {
+ case '1':
+ /* Check fflush after a backup ungetc() call. This is case 1a in
+ terms of
+ <http://lists.gnu.org/archive/html/bug-gnulib/2008-03/msg00131.html>,
+ according to the Austin Group's resolution on 2009-01-08. */
+
+ c = fgetc (stdin);
+ ASSERT (c == '#');
+
+ c = fgetc (stdin);
+ ASSERT (c == '!');
+
+ /* Here the file-position indicator must be 2. */
+
+ c = ungetc ('!', stdin);
+ ASSERT (c == '!');
+
+ fflush (stdin);
+
+ /* Here the file-position indicator must be 1. */
+
+ c = fgetc (stdin);
+ ASSERT (c == '!');
+
+ c = fgetc (stdin);
+ ASSERT (c == '/');
+
+ return 0;
+
+ case '2':
+ /* Check fflush after a non-backup ungetc() call. This is case 2a in
+ terms of
+ <http://lists.gnu.org/archive/html/bug-gnulib/2008-03/msg00131.html>,
+ according to the Austin Group's resolution on 2009-01-08. */
+ /* Check that fflush after a non-backup ungetc() call discards the
+ ungetc buffer. This is mandated by POSIX
+ <http://www.opengroup.org/susv3/functions/ungetc.html>:
+ "The value of the file-position indicator for the stream after
+ reading or discarding all pushed-back bytes shall be the same
+ as it was before the bytes were pushed back."
+ <http://www.opengroup.org/austin/aardvark/latest/xshbug3.txt>
+ "[After fflush(),] the file offset of the underlying open file
+ description shall be set to the file position of the stream, and
+ any characters pushed back onto the stream by ungetc() or
+ ungetwc() that have not subsequently been read from the stream
+ shall be discarded." */
+
+ c = fgetc (stdin);
+ ASSERT (c == '#');
+
+ c = fgetc (stdin);
+ ASSERT (c == '!');
+
+ /* Here the file-position indicator must be 2. */
+
+ c = ungetc ('@', stdin);
+ ASSERT (c == '@');
+
+ fflush (stdin);
+
+ /* Here the file-position indicator must be 1. */
+
+ c = fgetc (stdin);
+ ASSERT (c == '!');
+
+ c = fgetc (stdin);
+ ASSERT (c == '/');
+
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/tests/gnu/test-fflush2.sh b/tests/gnu/test-fflush2.sh
new file mode 100755
index 00000000..ef77fa48
--- /dev/null
+++ b/tests/gnu/test-fflush2.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Execute the test only with seekable input stream.
+# The behaviour of fflush() on a non-seekable input stream is undefined.
+./test-fflush2${EXEEXT} 1 < "$srcdir/test-fflush2.sh" || exit $?
+./test-fflush2${EXEEXT} 2 < "$srcdir/test-fflush2.sh" || exit $?
+#cat "$srcdir/test-fflush2.sh" | ./test-fflush2${EXEEXT} || exit $?
+
+exit 0
diff --git a/tests/gnu/test-filenamecat.c b/tests/gnu/test-filenamecat.c
new file mode 100755
index 00000000..b01645a4
--- /dev/null
+++ b/tests/gnu/test-filenamecat.c
@@ -0,0 +1,66 @@
+/* Test of concatenation of two arbitrary file names.
+
+ Copyright (C) 1996-2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Jim Meyering. */
+
+#include <config.h>
+
+#include "filenamecat.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "progname.h"
+
+int
+main (int argc _GL_UNUSED, char *argv[])
+{
+ static char const *const tests[][3] =
+ {
+ {"a", "b", "a/b"},
+ {"a/", "b", "a/b"},
+ {"a/", "/b", "a/b"},
+ {"a", "/b", "a/b"},
+
+ {"/", "b", "/b"},
+ {"/", "/b", "/b"},
+ {"/", "/", "/"},
+ {"a", "/", "a/"}, /* this might deserve a diagnostic */
+ {"/a", "/", "/a/"}, /* this might deserve a diagnostic */
+ {"a", "//b", "a/b"},
+ {"", "a", "a"}, /* this might deserve a diagnostic */
+ };
+ unsigned int i;
+ bool fail = false;
+
+ set_program_name (argv[0]);
+
+ for (i = 0; i < sizeof tests / sizeof tests[0]; i++)
+ {
+ char *base_in_result;
+ char const *const *t = tests[i];
+ char *res = file_name_concat (t[0], t[1], &base_in_result);
+ if (strcmp (res, t[2]) != 0)
+ {
+ fprintf (stderr, "test #%u: got %s, expected %s\n", i, res, t[2]);
+ fail = true;
+ }
+ }
+ exit (fail ? EXIT_FAILURE : EXIT_SUCCESS);
+}
diff --git a/tests/gnu/test-fopen-safer.c b/tests/gnu/test-fopen-safer.c
new file mode 100755
index 00000000..c12080dc
--- /dev/null
+++ b/tests/gnu/test-fopen-safer.c
@@ -0,0 +1,31 @@
+/* Test of opening a file stream.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "stdio--.h"
+
+#define BASE "test-fopen-safer.t"
+
+#include "test-fopen.h"
+
+int
+main (void)
+{
+ return test_fopen ();
+}
diff --git a/tests/gnu/test-fopen.c b/tests/gnu/test-fopen.c
new file mode 100755
index 00000000..d788d84e
--- /dev/null
+++ b/tests/gnu/test-fopen.c
@@ -0,0 +1,34 @@
+/* Test of opening a file stream.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (fopen, FILE *, (char const *, char const *));
+
+#define BASE "test-fopen.t"
+
+#include "test-fopen.h"
+
+int
+main (void)
+{
+ return test_fopen ();
+}
diff --git a/tests/gnu/test-fopen.h b/tests/gnu/test-fopen.h
new file mode 100755
index 00000000..765f2f8a
--- /dev/null
+++ b/tests/gnu/test-fopen.h
@@ -0,0 +1,73 @@
+/* Test of opening a file stream.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+/* Include <config.h> and a form of <stdio.h> first. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+/* Test fopen. Assumes BASE is defined. */
+
+static int
+test_fopen (void)
+{
+ FILE *f;
+ /* Remove anything from prior partial run. */
+ unlink (BASE "file");
+
+ /* Read requires existing file. */
+ errno = 0;
+ ASSERT (fopen (BASE "file", "r") == NULL);
+ ASSERT (errno == ENOENT);
+
+ /* Write can create a file. */
+ f = fopen (BASE "file", "w");
+ ASSERT (f);
+ ASSERT (fclose (f) == 0);
+
+ /* Trailing slash is invalid on non-directory. */
+ errno = 0;
+ ASSERT (fopen (BASE "file/", "r") == NULL);
+ ASSERT (errno == ENOTDIR || errno == EISDIR || errno == EINVAL);
+
+ /* Cannot create a directory. */
+ errno = 0;
+ ASSERT (fopen ("nonexist.ent/", "w") == NULL);
+ ASSERT (errno == ENOTDIR || errno == EISDIR || errno == ENOENT
+ || errno == EINVAL);
+
+ /* Directories cannot be opened for writing. */
+ errno = 0;
+ ASSERT (fopen (".", "w") == NULL);
+ ASSERT (errno == EISDIR || errno == EINVAL || errno == EACCES);
+
+ /* /dev/null must exist, and be writable. */
+ f = fopen ("/dev/null", "r");
+ ASSERT (f);
+ ASSERT (fclose (f) == 0);
+ f = fopen ("/dev/null", "w");
+ ASSERT (f);
+ ASSERT (fclose (f) == 0);
+
+ /* Cleanup. */
+ ASSERT (unlink (BASE "file") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-fpending.c b/tests/gnu/test-fpending.c
new file mode 100755
index 00000000..d79a2083
--- /dev/null
+++ b/tests/gnu/test-fpending.c
@@ -0,0 +1,41 @@
+/* Ensure that __fpending works.
+
+ Copyright (C) 2004, 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Written by Jim Meyering. */
+
+#include <config.h>
+
+#include "fpending.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "macros.h"
+
+int
+main (void)
+{
+ ASSERT (__fpending (stdout) == 0);
+
+ fputs ("foo", stdout);
+ ASSERT (__fpending (stdout) == 3);
+
+ fflush (stdout);
+ ASSERT (__fpending (stdout) == 0);
+
+ exit (0);
+}
diff --git a/tests/gnu/test-fpending.sh b/tests/gnu/test-fpending.sh
new file mode 100755
index 00000000..636af25a
--- /dev/null
+++ b/tests/gnu/test-fpending.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+tmpfile=
+trap 'rm -fr $tmpfile' 1 2 3 15
+
+tmpfile=test-fpending.t
+
+./test-fpending${EXEEXT} > $tmpfile || exit 1
+
+rm -fr $tmpfile
+
+exit 0
diff --git a/tests/gnu/test-fprintf-posix.h b/tests/gnu/test-fprintf-posix.h
new file mode 100755
index 00000000..dcd65021
--- /dev/null
+++ b/tests/gnu/test-fprintf-posix.h
@@ -0,0 +1,151 @@
+/* Test of POSIX compatible vsprintf() and sprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+static void
+test_function (int (*my_fprintf) (FILE *, const char *, ...))
+{
+ /* Here we don't test output that may be platform dependent.
+ The bulk of the tests is done as part of the 'vasnprintf-posix' module. */
+
+ /* Test support of size specifiers as in C99. */
+
+ my_fprintf (stdout, "%ju %d\n", (uintmax_t) 12345671, 33, 44, 55);
+
+ my_fprintf (stdout, "%zu %d\n", (size_t) 12345672, 33, 44, 55);
+
+ my_fprintf (stdout, "%tu %d\n", (ptrdiff_t) 12345673, 33, 44, 55);
+
+ /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
+ output of floating-point numbers. */
+
+ /* Positive zero. */
+ my_fprintf (stdout, "%a %d\n", 0.0, 33, 44, 55);
+
+ /* Positive infinity. */
+ my_fprintf (stdout, "%a %d\n", 1.0 / 0.0, 33, 44, 55);
+
+ /* Negative infinity. */
+ my_fprintf (stdout, "%a %d\n", -1.0 / 0.0, 33, 44, 55);
+
+ /* FLAG_ZERO with infinite number. */
+ my_fprintf (stdout, "%010a %d\n", 1.0 / 0.0, 33, 44, 55);
+
+ /* Test the support of the %f format directive. */
+
+ /* A positive number. */
+ my_fprintf (stdout, "%f %d\n", 12.75, 33, 44, 55);
+
+ /* A larger positive number. */
+ my_fprintf (stdout, "%f %d\n", 1234567.0, 33, 44, 55);
+
+ /* A negative number. */
+ my_fprintf (stdout, "%f %d\n", -0.03125, 33, 44, 55);
+
+ /* Positive zero. */
+ my_fprintf (stdout, "%f %d\n", 0.0, 33, 44, 55);
+
+ /* FLAG_ZERO. */
+ my_fprintf (stdout, "%015f %d\n", 1234.0, 33, 44, 55);
+
+ /* Precision. */
+ my_fprintf (stdout, "%.f %d\n", 1234.0, 33, 44, 55);
+
+ /* Precision with no rounding. */
+ my_fprintf (stdout, "%.2f %d\n", 999.95, 33, 44, 55);
+
+ /* Precision with rounding. */
+ my_fprintf (stdout, "%.2f %d\n", 999.996, 33, 44, 55);
+
+ /* A positive number. */
+ my_fprintf (stdout, "%Lf %d\n", 12.75L, 33, 44, 55);
+
+ /* A larger positive number. */
+ my_fprintf (stdout, "%Lf %d\n", 1234567.0L, 33, 44, 55);
+
+ /* A negative number. */
+ my_fprintf (stdout, "%Lf %d\n", -0.03125L, 33, 44, 55);
+
+ /* Positive zero. */
+ my_fprintf (stdout, "%Lf %d\n", 0.0L, 33, 44, 55);
+
+ /* FLAG_ZERO. */
+ my_fprintf (stdout, "%015Lf %d\n", 1234.0L, 33, 44, 55);
+
+ /* Precision. */
+ my_fprintf (stdout, "%.Lf %d\n", 1234.0L, 33, 44, 55);
+
+ /* Precision with no rounding. */
+ my_fprintf (stdout, "%.2Lf %d\n", 999.95L, 33, 44, 55);
+
+ /* Precision with rounding. */
+ my_fprintf (stdout, "%.2Lf %d\n", 999.996L, 33, 44, 55);
+
+ /* Test the support of the %F format directive. */
+
+ /* A positive number. */
+ my_fprintf (stdout, "%F %d\n", 12.75, 33, 44, 55);
+
+ /* A larger positive number. */
+ my_fprintf (stdout, "%F %d\n", 1234567.0, 33, 44, 55);
+
+ /* A negative number. */
+ my_fprintf (stdout, "%F %d\n", -0.03125, 33, 44, 55);
+
+ /* Positive zero. */
+ my_fprintf (stdout, "%F %d\n", 0.0, 33, 44, 55);
+
+ /* FLAG_ZERO. */
+ my_fprintf (stdout, "%015F %d\n", 1234.0, 33, 44, 55);
+
+ /* Precision. */
+ my_fprintf (stdout, "%.F %d\n", 1234.0, 33, 44, 55);
+
+ /* Precision with no rounding. */
+ my_fprintf (stdout, "%.2F %d\n", 999.95, 33, 44, 55);
+
+ /* Precision with rounding. */
+ my_fprintf (stdout, "%.2F %d\n", 999.996, 33, 44, 55);
+
+ /* A positive number. */
+ my_fprintf (stdout, "%LF %d\n", 12.75L, 33, 44, 55);
+
+ /* A larger positive number. */
+ my_fprintf (stdout, "%LF %d\n", 1234567.0L, 33, 44, 55);
+
+ /* A negative number. */
+ my_fprintf (stdout, "%LF %d\n", -0.03125L, 33, 44, 55);
+
+ /* Positive zero. */
+ my_fprintf (stdout, "%LF %d\n", 0.0L, 33, 44, 55);
+
+ /* FLAG_ZERO. */
+ my_fprintf (stdout, "%015LF %d\n", 1234.0L, 33, 44, 55);
+
+ /* Precision. */
+ my_fprintf (stdout, "%.LF %d\n", 1234.0L, 33, 44, 55);
+
+ /* Precision with no rounding. */
+ my_fprintf (stdout, "%.2LF %d\n", 999.95L, 33, 44, 55);
+
+ /* Precision with rounding. */
+ my_fprintf (stdout, "%.2LF %d\n", 999.996L, 33, 44, 55);
+
+ /* Test the support of the POSIX/XSI format strings with positions. */
+
+ my_fprintf (stdout, "%2$d %1$d\n", 33, 55);
+}
diff --git a/tests/gnu/test-fpurge.c b/tests/gnu/test-fpurge.c
new file mode 100755
index 00000000..89fe8c0c
--- /dev/null
+++ b/tests/gnu/test-fpurge.c
@@ -0,0 +1,132 @@
+/* Test of fpurge() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+/* None of the files accessed by this test are large, so disable the
+ fseek link warning if we are not using the gnulib fseek module. */
+#define _GL_NO_LARGE_FILES
+#include <stdio.h>
+
+#include <string.h>
+
+#include "macros.h"
+
+#define TESTFILE "t-fpurge.tmp"
+
+int
+main (void)
+{
+ int check_filepos;
+
+ for (check_filepos = 0; check_filepos <= 1; check_filepos++)
+ {
+ FILE *fp;
+
+ /* Create a file with some contents. */
+ fp = fopen (TESTFILE, "w");
+ if (fp == NULL)
+ goto skip;
+ if (fwrite ("foobarsh", 1, 8, fp) < 8)
+ goto skip;
+ if (fclose (fp))
+ goto skip;
+
+ /* The file's contents is now "foobarsh". */
+
+ /* Open it in read-write mode. */
+ fp = fopen (TESTFILE, "r+");
+ if (fp == NULL)
+ goto skip;
+ if (fseek (fp, 3, SEEK_CUR))
+ goto skip;
+ if (fwrite ("g", 1, 1, fp) < 1)
+ goto skip;
+ if (fflush (fp))
+ goto skip;
+ if (fwrite ("bz", 1, 2, fp) < 2)
+ goto skip;
+ /* Discard pending write. */
+ ASSERT (fpurge (fp) == 0);
+ /* Verify that when discarding pending output, the file position is set
+ back to where it was before the write calls. */
+ if (check_filepos)
+ ASSERT (ftell (fp) == 4);
+ ASSERT (fclose (fp) == 0);
+
+ /* Open it in read-only mode. */
+ fp = fopen (TESTFILE, "r");
+ if (fp == NULL)
+ goto skip;
+ /* Verify that the pending writes before the fpurge were really
+ discarded. */
+ {
+ char buf[8];
+ if (fread (buf, 1, 7, fp) < 7)
+ goto skip;
+ ASSERT (memcmp (buf, "foogars", 7) == 0);
+ }
+ /* Discard the buffered 'h'. */
+ if (check_filepos)
+ ASSERT (ftell (fp) == 7);
+ ASSERT (fpurge (fp) == 0);
+ /* Verify that when discarding pending input, the file position is
+ advanced to match the end of the previously read input. */
+ if (check_filepos)
+ ASSERT (ftell (fp) == 8);
+ ASSERT (getc (fp) == EOF);
+ ASSERT (fclose (fp) == 0);
+
+ /* The file's contents is now "foogarsh". */
+
+ /* Ensure that purging a read does not corrupt subsequent writes. */
+ fp = fopen (TESTFILE, "r+");
+ if (fp == NULL)
+ goto skip;
+ if (fseek (fp, -1, SEEK_END))
+ goto skip;
+ ASSERT (getc (fp) == 'h');
+ ASSERT (getc (fp) == EOF);
+ if (check_filepos)
+ ASSERT (ftell (fp) == 8);
+ ASSERT (fpurge (fp) == 0);
+ if (check_filepos)
+ ASSERT (ftell (fp) == 8);
+ ASSERT (putc ('!', fp) == '!');
+ ASSERT (fclose (fp) == 0);
+ fp = fopen (TESTFILE, "r");
+ if (fp == NULL)
+ goto skip;
+ {
+ char buf[10];
+ ASSERT (fread (buf, 1, 10, fp) == 9);
+ ASSERT (memcmp (buf, "foogarsh!", 9) == 0);
+ }
+ ASSERT (fclose (fp) == 0);
+
+ /* The file's contents is now "foogarsh!". */
+ }
+
+ remove (TESTFILE);
+ return 0;
+
+ skip:
+ fprintf (stderr, "Skipping test: prerequisite file operations failed.\n");
+ remove (TESTFILE);
+ return 77;
+}
diff --git a/tests/gnu/test-freadahead.c b/tests/gnu/test-freadahead.c
new file mode 100755
index 00000000..3f34a421
--- /dev/null
+++ b/tests/gnu/test-freadahead.c
@@ -0,0 +1,73 @@
+/* Test of freadahead() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "freadahead.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+int
+main (int argc, char **argv)
+{
+ int nbytes = atoi (argv[1]);
+ if (nbytes > 0)
+ {
+ void *buf = malloc (nbytes);
+ ASSERT (fread (buf, 1, nbytes, stdin) == nbytes);
+ }
+
+ if (nbytes == 0)
+ ASSERT (freadahead (stdin) == 0);
+ else
+ {
+ if (lseek (0, 0, SEEK_CUR) == nbytes)
+ /* An unbuffered stdio, such as BeOS or on uClibc compiled without
+ __STDIO_BUFFERS. */
+ ASSERT (freadahead (stdin) == 0);
+ else
+ {
+ /* Normal buffered stdio. */
+ size_t buffered;
+ int c, c2;
+
+ ASSERT (freadahead (stdin) != 0);
+ buffered = freadahead (stdin);
+
+ c = fgetc (stdin);
+ ASSERT (freadahead (stdin) == buffered - 1);
+ ungetc (c, stdin);
+ ASSERT (freadahead (stdin) == buffered);
+ c2 = fgetc (stdin);
+ ASSERT (c2 == c);
+ ASSERT (freadahead (stdin) == buffered - 1);
+
+ c = '@';
+ ungetc (c, stdin);
+ ASSERT (freadahead (stdin) == buffered);
+ c2 = fgetc (stdin);
+ ASSERT (c2 == c);
+ ASSERT (freadahead (stdin) == buffered - 1);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-freadahead.sh b/tests/gnu/test-freadahead.sh
new file mode 100755
index 00000000..27cf5504
--- /dev/null
+++ b/tests/gnu/test-freadahead.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-freadahead${EXEEXT} 0 < "$srcdir/test-freadahead.sh" || exit 1
+./test-freadahead${EXEEXT} 5 < "$srcdir/test-freadahead.sh" || exit 1
+exit 0
diff --git a/tests/gnu/test-freading.c b/tests/gnu/test-freading.c
new file mode 100755
index 00000000..fee82284
--- /dev/null
+++ b/tests/gnu/test-freading.c
@@ -0,0 +1,130 @@
+/* Test of freading() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+/* None of the files accessed by this test are large, so disable the
+ fseek link warning if we are not using the gnulib fseek module. */
+#define _GL_NO_LARGE_FILES
+#include "freading.h"
+
+#include <stdio.h>
+
+#include "macros.h"
+
+#define TESTFILE "t-freading.tmp"
+
+int
+main (void)
+{
+ FILE *fp;
+
+ /* Create a file with some contents. Write-only file is never reading. */
+ fp = fopen (TESTFILE, "w");
+ ASSERT (fp);
+ ASSERT (!freading (fp));
+ ASSERT (fwrite ("foobarsh", 1, 8, fp) == 8);
+ ASSERT (!freading (fp));
+ ASSERT (fclose (fp) == 0);
+
+ /* Open it in read-only mode. Read-only file is always reading. */
+ fp = fopen (TESTFILE, "r");
+ ASSERT (fp);
+ ASSERT (freading (fp));
+ ASSERT (fgetc (fp) == 'f');
+ ASSERT (freading (fp));
+ ASSERT (fseek (fp, 2, SEEK_CUR) == 0);
+ ASSERT (freading (fp));
+ ASSERT (fgetc (fp) == 'b');
+ ASSERT (freading (fp));
+ fflush (fp);
+ ASSERT (freading (fp));
+ ASSERT (fgetc (fp) == 'a');
+ ASSERT (freading (fp));
+ ASSERT (fseek (fp, 0, SEEK_END) == 0);
+ ASSERT (freading (fp));
+ ASSERT (fclose (fp) == 0);
+
+ /* Open it in read-write mode. POSIX requires a reposition (fseek,
+ fsetpos, rewind) or EOF when transitioning from read to write;
+ freading is only deterministic after input or output, but this
+ test case should be portable even on open, after reposition, and
+ at EOF. */
+ /* First a scenario with only fgetc, fseek, fputc. */
+ fp = fopen (TESTFILE, "r+");
+ ASSERT (fp);
+ ASSERT (!freading (fp));
+ ASSERT (fgetc (fp) == 'f');
+ ASSERT (freading (fp));
+ ASSERT (fseek (fp, 2, SEEK_CUR) == 0);
+ /* freading (fp) is undefined here, but fwriting (fp) is false. */
+ ASSERT (fgetc (fp) == 'b');
+ ASSERT (freading (fp));
+ /* This fseek call is necessary when switching from reading to writing.
+ See the description of fopen(), ISO C 99 7.19.5.3.(6). */
+ ASSERT (fseek (fp, 0, SEEK_CUR) == 0);
+ /* freading (fp) is undefined here, but fwriting (fp) is false. */
+ ASSERT (fputc ('x', fp) == 'x');
+ ASSERT (!freading (fp));
+ ASSERT (fseek (fp, 0, SEEK_END) == 0);
+ /* freading (fp) is undefined here, because on some implementations (e.g.
+ glibc) fseek causes a buffer to be read.
+ fwriting (fp) is undefined as well. */
+ ASSERT (fclose (fp) == 0);
+
+ /* Open it in read-write mode. POSIX requires a reposition (fseek,
+ fsetpos, rewind) or EOF when transitioning from read to write;
+ freading is only deterministic after input or output, but this
+ test case should be portable even on open, after reposition, and
+ at EOF. */
+ /* Here a scenario that includes fflush. */
+ fp = fopen (TESTFILE, "r+");
+ ASSERT (fp);
+ ASSERT (!freading (fp));
+ ASSERT (fgetc (fp) == 'f');
+ ASSERT (freading (fp));
+ ASSERT (fseek (fp, 2, SEEK_CUR) == 0);
+ /* freading (fp) is undefined here, but fwriting (fp) is false. */
+ ASSERT (fgetc (fp) == 'b');
+ ASSERT (freading (fp));
+ fflush (fp);
+ /* freading (fp) is undefined here, but fwriting (fp) is false. */
+ ASSERT (fgetc (fp) == 'x');
+ ASSERT (freading (fp));
+ /* This fseek call is necessary when switching from reading to writing.
+ See the description of fopen(), ISO C 99 7.19.5.3.(6). */
+ ASSERT (fseek (fp, 0, SEEK_CUR) == 0);
+ /* freading (fp) is undefined here, but fwriting (fp) is false. */
+ ASSERT (fputc ('z', fp) == 'z');
+ ASSERT (!freading (fp));
+ ASSERT (fseek (fp, 0, SEEK_END) == 0);
+ /* freading (fp) is undefined here, because on some implementations (e.g.
+ glibc) fseek causes a buffer to be read.
+ fwriting (fp) is undefined as well. */
+ ASSERT (fclose (fp) == 0);
+
+ /* Open it in append mode. Write-only file is never reading. */
+ fp = fopen (TESTFILE, "a");
+ ASSERT (fp);
+ ASSERT (!freading (fp));
+ ASSERT (fwrite ("bla", 1, 3, fp) == 3);
+ ASSERT (!freading (fp));
+ ASSERT (fclose (fp) == 0);
+ ASSERT (remove (TESTFILE) == 0);
+ return 0;
+}
diff --git a/tests/gnu/test-freadptr.c b/tests/gnu/test-freadptr.c
new file mode 100755
index 00000000..f73b0fcd
--- /dev/null
+++ b/tests/gnu/test-freadptr.c
@@ -0,0 +1,94 @@
+/* Test of freadptr() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include "freadptr.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+int
+main (int argc, char **argv)
+{
+ int nbytes = atoi (argv[1]);
+ void *buf = malloc (nbytes);
+ ASSERT (fread (buf, 1, nbytes, stdin) == nbytes);
+
+ if (lseek (0, 0, SEEK_CUR) == nbytes)
+ {
+ /* An unbuffered stdio, such as BeOS or on uClibc compiled without
+ __STDIO_BUFFERS. Or stdin is a pipe. */
+ size_t size;
+ ASSERT (freadptr (stdin, &size) == NULL);
+ }
+ else
+ {
+ /* Normal buffered stdio. */
+ const char stdin_contents[] =
+ "#!/bin/sh\n\n./test-freadptr${EXEEXT} 5 < \"$srcdir/test-freadptr.sh\" || exit 1\ncat \"$srcdir/test-freadptr.sh\" | ./test-freadptr${EXEEXT} 5 || exit 1\nexit 0\n";
+ const char *expected = stdin_contents + nbytes;
+ size_t available1;
+ size_t available2;
+ size_t available3;
+
+ /* Test normal behaviour. */
+ {
+ const char *ptr = freadptr (stdin, &available1);
+
+ ASSERT (ptr != NULL);
+ ASSERT (available1 != 0);
+ ASSERT (available1 <= strlen (expected));
+ ASSERT (memcmp (ptr, expected, available1) == 0);
+ }
+
+ /* Test behaviour after normal ungetc. */
+ ungetc (fgetc (stdin), stdin);
+ {
+ const char *ptr = freadptr (stdin, &available2);
+
+ if (ptr != NULL)
+ {
+ ASSERT (available2 == available1);
+ ASSERT (memcmp (ptr, expected, available2) == 0);
+ }
+ }
+
+ /* Test behaviour after arbitrary ungetc. */
+ fgetc (stdin);
+ ungetc ('@', stdin);
+ {
+ const char *ptr = freadptr (stdin, &available3);
+
+ if (ptr != NULL)
+ {
+ ASSERT (available3 == 1 || available3 == available1);
+ ASSERT (ptr[0] == '@');
+ if (available3 > 1)
+ {
+ ASSERT (memcmp (ptr + 1, expected + 1, available3 - 1) == 0);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-freadptr.sh b/tests/gnu/test-freadptr.sh
new file mode 100755
index 00000000..97819b29
--- /dev/null
+++ b/tests/gnu/test-freadptr.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-freadptr${EXEEXT} 5 < "$srcdir/test-freadptr.sh" || exit 1
+cat "$srcdir/test-freadptr.sh" | ./test-freadptr${EXEEXT} 5 || exit 1
+exit 0
diff --git a/tests/gnu/test-freadptr2.c b/tests/gnu/test-freadptr2.c
new file mode 100755
index 00000000..cec011c5
--- /dev/null
+++ b/tests/gnu/test-freadptr2.c
@@ -0,0 +1,62 @@
+/* Test of freadptr() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "freadptr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+static int
+freadptrbufsize (FILE *fp)
+{
+ size_t size = 0;
+
+ freadptr (fp, &size);
+ return size;
+}
+
+int
+main (int argc, char **argv)
+{
+ int nbytes = atoi (argv[1]);
+ if (nbytes > 0)
+ {
+ void *buf = malloc (nbytes);
+ ASSERT (fread (buf, 1, nbytes, stdin) == nbytes);
+ }
+
+ if (nbytes == 0)
+ ASSERT (freadptrbufsize (stdin) == 0);
+ else
+ {
+ if (lseek (0, 0, SEEK_CUR) == nbytes)
+ /* An unbuffered stdio, such as BeOS or on uClibc compiled without
+ __STDIO_BUFFERS. */
+ ASSERT (freadptrbufsize (stdin) == 0);
+ else
+ /* Normal buffered stdio. */
+ ASSERT (freadptrbufsize (stdin) != 0);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-freadptr2.sh b/tests/gnu/test-freadptr2.sh
new file mode 100755
index 00000000..7634d85f
--- /dev/null
+++ b/tests/gnu/test-freadptr2.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-freadptr2${EXEEXT} 0 < "$srcdir/test-freadptr2.sh" || exit 1
+./test-freadptr2${EXEEXT} 5 < "$srcdir/test-freadptr2.sh" || exit 1
+exit 0
diff --git a/tests/gnu/test-freadseek.c b/tests/gnu/test-freadseek.c
new file mode 100755
index 00000000..1da24c18
--- /dev/null
+++ b/tests/gnu/test-freadseek.c
@@ -0,0 +1,93 @@
+/* Test of freadseek() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include "freadseek.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+int
+main (int argc, char **argv)
+{
+ static const char stdin_contents[] =
+ "#!/bin/sh\n\n./test-freadseek${EXEEXT} 5 19 6 7 18 9 19 < \"$srcdir/test-freadseek.sh\" || exit 1\ncat \"$srcdir/test-freadseek.sh\" | ./test-freadseek${EXEEXT} 5 19 6 7 18 9 19 || exit 1\nexit 0\n";
+ int nbytes1 = atoi (argv[1]);
+ int nbytes2 = atoi (argv[2]);
+ int nbytes3 = atoi (argv[3]);
+ int nbytes4 = atoi (argv[4]);
+ int nbytes5 = atoi (argv[5]);
+ int nbytes6 = atoi (argv[6]);
+ int nbytes7 = atoi (argv[7]);
+ void *buf1 = malloc (nbytes1);
+ void *buf3 = malloc (nbytes3);
+ void *buf5 = malloc (nbytes5);
+ void *buf7 = malloc (nbytes7);
+ /* A private variable to keep track of the position. */
+ size_t position = 0;
+
+ ASSERT (fread (buf1, 1, nbytes1, stdin) == nbytes1);
+ ASSERT (memcmp (buf1, stdin_contents + position, nbytes1) == 0);
+ position += nbytes1;
+
+ /* Test normal behaviour. */
+ ASSERT (freadseek (stdin, nbytes2) == 0);
+ position += nbytes2;
+
+ ASSERT (fread (buf3, 1, nbytes3, stdin) == nbytes3);
+ ASSERT (memcmp (buf3, stdin_contents + position, nbytes3) == 0);
+ position += nbytes3;
+
+ /* Test behaviour after normal ungetc. */
+ ungetc (fgetc (stdin), stdin);
+ ASSERT (freadseek (stdin, nbytes4) == 0);
+ position += nbytes4;
+
+ ASSERT (fread (buf5, 1, nbytes5, stdin) == nbytes5);
+ ASSERT (memcmp (buf5, stdin_contents + position, nbytes5) == 0);
+ position += nbytes5;
+
+ /* Test behaviour after arbitrary ungetc. */
+ fgetc (stdin);
+ ungetc ('@', stdin);
+ ASSERT (freadseek (stdin, nbytes6) == 0);
+ position += nbytes6;
+
+ ASSERT (fread (buf7, 1, nbytes7, stdin) == nbytes7);
+ ASSERT (memcmp (buf7, stdin_contents + position, nbytes7) == 0);
+ position += nbytes7;
+
+ /* Test move to end of file. */
+ ASSERT (freadseek (stdin, strlen (stdin_contents) - position) == 0);
+ ASSERT (fgetc (stdin) == EOF);
+ ASSERT (!ferror (stdin));
+
+#if !defined __MINT__ /* FreeMiNT has problems seeking past end of file */
+ /* Test move beyond end of file. */
+ ASSERT (freadseek (stdin, 1000000) == 0);
+ ASSERT (fgetc (stdin) == EOF);
+ ASSERT (!ferror (stdin));
+#endif
+
+ return 0;
+}
diff --git a/tests/gnu/test-freadseek.sh b/tests/gnu/test-freadseek.sh
new file mode 100755
index 00000000..453cadfd
--- /dev/null
+++ b/tests/gnu/test-freadseek.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-freadseek${EXEEXT} 5 19 6 7 18 9 19 < "$srcdir/test-freadseek.sh" || exit 1
+cat "$srcdir/test-freadseek.sh" | ./test-freadseek${EXEEXT} 5 19 6 7 18 9 19 || exit 1
+exit 0
diff --git a/tests/gnu/test-frexp.c b/tests/gnu/test-frexp.c
new file mode 100755
index 00000000..d5ab7e50
--- /dev/null
+++ b/tests/gnu/test-frexp.c
@@ -0,0 +1,199 @@
+/* Test of splitting a double into fraction and mantissa.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <math.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (frexp, double, (double, int *));
+
+#include <float.h>
+
+#include "isnand-nolibm.h"
+#include "nan.h"
+#include "macros.h"
+
+/* Avoid some warnings from "gcc -Wshadow".
+ This file doesn't use the exp() function. */
+#undef exp
+#define exp exponent
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ So we use -zero instead. */
+double zero = 0.0;
+
+static double
+my_ldexp (double x, int d)
+{
+ for (; d > 0; d--)
+ x *= 2.0;
+ for (; d < 0; d++)
+ x *= 0.5;
+ return x;
+}
+
+int
+main ()
+{
+ int i;
+ /* The use of 'volatile' guarantees that excess precision bits are dropped
+ when dealing with denormalized numbers. It is necessary on x86 systems
+ where double-floats are not IEEE compliant by default, to avoid that the
+ results become platform and compiler option dependent. 'volatile' is a
+ portable alternative to gcc's -ffloat-store option. */
+ volatile double x;
+
+ { /* NaN. */
+ int exp = -9999;
+ double mantissa;
+ x = NaNd ();
+ mantissa = frexp (x, &exp);
+ ASSERT (isnand (mantissa));
+ }
+
+ { /* Positive infinity. */
+ int exp = -9999;
+ double mantissa;
+ x = 1.0 / 0.0;
+ mantissa = frexp (x, &exp);
+ ASSERT (mantissa == x);
+ }
+
+ { /* Negative infinity. */
+ int exp = -9999;
+ double mantissa;
+ x = -1.0 / 0.0;
+ mantissa = frexp (x, &exp);
+ ASSERT (mantissa == x);
+ }
+
+ { /* Positive zero. */
+ int exp = -9999;
+ double mantissa;
+ x = 0.0;
+ mantissa = frexp (x, &exp);
+ ASSERT (exp == 0);
+ ASSERT (mantissa == x);
+ ASSERT (!signbit (mantissa));
+ }
+
+ { /* Negative zero. */
+ int exp = -9999;
+ double mantissa;
+ x = -zero;
+ mantissa = frexp (x, &exp);
+ ASSERT (exp == 0);
+ ASSERT (mantissa == x);
+ ASSERT (signbit (mantissa));
+ }
+
+ for (i = 1, x = 1.0; i <= DBL_MAX_EXP; i++, x *= 2.0)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.5);
+ }
+ for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.5);
+ }
+ for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.5);
+ }
+
+ for (i = 1, x = -1.0; i <= DBL_MAX_EXP; i++, x *= 2.0)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == -0.5);
+ }
+ for (i = 1, x = -1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == -0.5);
+ }
+ for (; i >= DBL_MIN_EXP - 100 && x < 0.0; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == -0.5);
+ }
+
+ for (i = 1, x = 1.01; i <= DBL_MAX_EXP; i++, x *= 2.0)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.505);
+ }
+ for (i = 1, x = 1.01; i >= DBL_MIN_EXP; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.505);
+ }
+ for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa >= 0.5);
+ ASSERT (mantissa < 1.0);
+ ASSERT (mantissa == my_ldexp (x, - exp));
+ }
+
+ for (i = 1, x = 1.73205; i <= DBL_MAX_EXP; i++, x *= 2.0)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.866025);
+ }
+ for (i = 1, x = 1.73205; i >= DBL_MIN_EXP; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.866025);
+ }
+ for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = frexp (x, &exp);
+ ASSERT (exp == i || exp == i + 1);
+ ASSERT (mantissa >= 0.5);
+ ASSERT (mantissa < 1.0);
+ ASSERT (mantissa == my_ldexp (x, - exp));
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-frexpl.c b/tests/gnu/test-frexpl.c
new file mode 100755
index 00000000..8d9d41d2
--- /dev/null
+++ b/tests/gnu/test-frexpl.c
@@ -0,0 +1,223 @@
+/* Test of splitting a 'long double' into fraction and mantissa.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <math.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (frexpl, long double, (long double, int *));
+
+#include <float.h>
+
+#include "fpucw.h"
+#include "isnanl-nolibm.h"
+#include "nan.h"
+#include "macros.h"
+
+/* Avoid some warnings from "gcc -Wshadow".
+ This file doesn't use the exp() function. */
+#undef exp
+#define exp exponent
+
+/* On MIPS IRIX machines, LDBL_MIN_EXP is -1021, but the smallest reliable
+ exponent for 'long double' is -964. Similarly, on PowerPC machines,
+ LDBL_MIN_EXP is -1021, but the smallest reliable exponent for 'long double'
+ is -968. For exponents below that, the precision may be truncated to the
+ precision used for 'double'. */
+#ifdef __sgi
+# define MIN_NORMAL_EXP (LDBL_MIN_EXP + 57)
+#elif defined __ppc || defined __ppc__ || defined __powerpc || defined __powerpc__
+# define MIN_NORMAL_EXP (LDBL_MIN_EXP + 53)
+#else
+# define MIN_NORMAL_EXP LDBL_MIN_EXP
+#endif
+
+/* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
+ So we use minus_zero instead.
+ IRIX cc can't put -0.0L into .data, but can compute at runtime.
+ Note that the expression -LDBL_MIN * LDBL_MIN does not work on other
+ platforms, such as when cross-compiling to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi
+static long double
+compute_minus_zero (void)
+{
+ return -LDBL_MIN * LDBL_MIN;
+}
+# define minus_zero compute_minus_zero ()
+#else
+long double minus_zero = -0.0L;
+#endif
+
+static long double
+my_ldexp (long double x, int d)
+{
+ for (; d > 0; d--)
+ x *= 2.0L;
+ for (; d < 0; d++)
+ x *= 0.5L;
+ return x;
+}
+
+int
+main ()
+{
+ int i;
+ long double x;
+ DECL_LONG_DOUBLE_ROUNDING
+
+ BEGIN_LONG_DOUBLE_ROUNDING ();
+
+ { /* NaN. */
+ int exp = -9999;
+ long double mantissa;
+ x = NaNl ();
+ mantissa = frexpl (x, &exp);
+ ASSERT (isnanl (mantissa));
+ }
+
+ { /* Positive infinity. */
+ int exp = -9999;
+ long double mantissa;
+ x = 1.0L / 0.0L;
+ mantissa = frexpl (x, &exp);
+ ASSERT (mantissa == x);
+ }
+
+ { /* Negative infinity. */
+ int exp = -9999;
+ long double mantissa;
+ x = -1.0L / 0.0L;
+ mantissa = frexpl (x, &exp);
+ ASSERT (mantissa == x);
+ }
+
+ { /* Positive zero. */
+ int exp = -9999;
+ long double mantissa;
+ x = 0.0L;
+ mantissa = frexpl (x, &exp);
+ ASSERT (exp == 0);
+ ASSERT (mantissa == x);
+ ASSERT (!signbit (mantissa));
+ }
+
+ { /* Negative zero. */
+ int exp = -9999;
+ long double mantissa;
+ x = minus_zero;
+ mantissa = frexpl (x, &exp);
+ ASSERT (exp == 0);
+ ASSERT (mantissa == x);
+ ASSERT (signbit (mantissa));
+ }
+
+ for (i = 1, x = 1.0L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.5L);
+ }
+ for (i = 1, x = 1.0L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.5L);
+ }
+ for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.5L);
+ }
+
+ for (i = 1, x = -1.0L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == -0.5L);
+ }
+ for (i = 1, x = -1.0L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == -0.5L);
+ }
+ for (; i >= LDBL_MIN_EXP - 100 && x < 0.0L; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == -0.5L);
+ }
+
+ for (i = 1, x = 1.01L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.505L);
+ }
+ for (i = 1, x = 1.01L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.505L);
+ }
+ for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa >= 0.5L);
+ ASSERT (mantissa < 1.0L);
+ ASSERT (mantissa == my_ldexp (x, - exp));
+ }
+
+ for (i = 1, x = 1.73205L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.866025L);
+ }
+ for (i = 1, x = 1.73205L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i);
+ ASSERT (mantissa == 0.866025L);
+ }
+ for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = frexpl (x, &exp);
+ ASSERT (exp == i || exp == i + 1);
+ ASSERT (mantissa >= 0.5L);
+ ASSERT (mantissa < 1.0L);
+ ASSERT (mantissa == my_ldexp (x, - exp));
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-fseeko.c b/tests/gnu/test-fseeko.c
new file mode 100755
index 00000000..be2a78dc
--- /dev/null
+++ b/tests/gnu/test-fseeko.c
@@ -0,0 +1,74 @@
+/* Test of fseeko() function.
+ Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+/* None of the files accessed by this test are large, so disable the
+ fseek link warning if we are not using the gnulib fseek module. */
+#define _GL_NO_LARGE_FILES
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (fseeko, int, (FILE *, off_t, int));
+
+
+#include "macros.h"
+
+#ifndef FUNC_UNGETC_BROKEN
+# define FUNC_UNGETC_BROKEN 0
+#endif
+
+int
+main (int argc, char **argv _GL_UNUSED)
+{
+ /* Assume stdin is non-empty, seekable, and starts with '#!/bin/sh'
+ iff argc > 1. */
+ int expected = argc > 1 ? 0 : -1;
+ /* Exit with success only if fseek/fseeko agree. */
+ int r1 = fseeko (stdin, 0, SEEK_CUR);
+ int r2 = fseek (stdin, 0, SEEK_CUR);
+ ASSERT (r1 == r2 && r1 == expected);
+ if (argc > 1)
+ {
+ /* Test that fseek discards previously read ungetc data. */
+ int ch = fgetc (stdin);
+ ASSERT (ch == '#');
+ ASSERT (ungetc (ch, stdin) == ch);
+ ASSERT (fseeko (stdin, 2, SEEK_SET) == 0);
+ ch = fgetc (stdin);
+ ASSERT (ch == '/');
+ if (2 < argc)
+ {
+ if (FUNC_UNGETC_BROKEN)
+ {
+ fputs ("Skipping test: ungetc cannot handle arbitrary bytes\n",
+ stderr);
+ return 77;
+ }
+ /* Test that fseek discards random ungetc data. */
+ ASSERT (ungetc (ch ^ 0xff, stdin) == (ch ^ 0xff));
+ }
+ ASSERT (fseeko (stdin, 0, SEEK_END) == 0);
+ ASSERT (fgetc (stdin) == EOF);
+ /* Test that fseek resets end-of-file marker. */
+ ASSERT (feof (stdin));
+ ASSERT (fseeko (stdin, 0, SEEK_END) == 0);
+ ASSERT (!feof (stdin));
+ }
+ return 0;
+}
diff --git a/tests/gnu/test-fseeko.sh b/tests/gnu/test-fseeko.sh
new file mode 100755
index 00000000..5c558272
--- /dev/null
+++ b/tests/gnu/test-fseeko.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-fseeko${EXEEXT} 1 < "$srcdir/test-fseeko.sh" || exit 1
+echo hi | ./test-fseeko${EXEEXT} || exit 1
+exit 0
diff --git a/tests/gnu/test-fseeko2.sh b/tests/gnu/test-fseeko2.sh
new file mode 100755
index 00000000..6e1130cf
--- /dev/null
+++ b/tests/gnu/test-fseeko2.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./test-fseeko${EXEEXT} 1 2 < "$srcdir/test-fseeko2.sh"
diff --git a/tests/gnu/test-fseterr.c b/tests/gnu/test-fseterr.c
new file mode 100755
index 00000000..c114f1a1
--- /dev/null
+++ b/tests/gnu/test-fseterr.c
@@ -0,0 +1,44 @@
+/* Test setting the error indicator of a stream.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "fseterr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+ /* All streams are initially created with the error indicator cleared. */
+ if (ferror (stdout))
+ abort ();
+
+ /* Verify that fseterr() works. */
+ fseterr (stdout);
+ if (!ferror (stdout))
+ abort ();
+
+ /* Verify fseterr's effect can be undone by clearerr(). */
+ clearerr (stdout);
+ if (ferror (stdout))
+ abort ();
+
+ return 0;
+}
diff --git a/tests/gnu/test-ftello.c b/tests/gnu/test-ftello.c
new file mode 100755
index 00000000..5fae570f
--- /dev/null
+++ b/tests/gnu/test-ftello.c
@@ -0,0 +1,118 @@
+/* Test of ftello() function.
+ Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+/* None of the files accessed by this test are large, so disable the
+ fseek link warning if we are not using the gnulib fseek module. */
+#define _GL_NO_LARGE_FILES
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (ftello, off_t, (FILE *));
+
+#include "binary-io.h"
+#include "macros.h"
+
+#ifndef FUNC_UNGETC_BROKEN
+# define FUNC_UNGETC_BROKEN 0
+#endif
+
+int
+main (int argc, char **argv _GL_UNUSED)
+{
+ int ch;
+ /* Assume stdin is seekable iff argc > 1. */
+ if (argc == 1)
+ {
+ ASSERT (ftell (stdin) == -1);
+ ASSERT (ftello (stdin) == -1);
+ return 0;
+ }
+
+ /* mingw ftell is unreliable on text mode input. */
+ SET_BINARY (0);
+
+ /* Simple tests. For each test, make sure ftell and ftello agree. */
+ ASSERT (ftell (stdin) == 0);
+ ASSERT (ftello (stdin) == 0);
+
+ ch = fgetc (stdin);
+ ASSERT (ch == '#');
+ ASSERT (ftell (stdin) == 1);
+ ASSERT (ftello (stdin) == 1);
+
+ /* Test ftell after ungetc of read input. */
+ ch = ungetc ('#', stdin);
+ ASSERT (ch == '#');
+ ASSERT (ftell (stdin) == 0);
+ ASSERT (ftello (stdin) == 0);
+
+ ch = fgetc (stdin);
+ ASSERT (ch == '#');
+ ASSERT (ftell (stdin) == 1);
+ ASSERT (ftello (stdin) == 1);
+
+ /* Test ftell after fseek. */
+ ASSERT (fseek (stdin, 2, SEEK_SET) == 0);
+ ASSERT (ftell (stdin) == 2);
+ ASSERT (ftello (stdin) == 2);
+
+ /* Test ftell after random ungetc. */
+ ch = fgetc (stdin);
+ ASSERT (ch == '/');
+ ch = ungetc ('@', stdin);
+ ASSERT (ch == '@');
+ ASSERT (ftell (stdin) == 2);
+ ASSERT (ftello (stdin) == 2);
+
+ ch = fgetc (stdin);
+ ASSERT (ch == '@');
+ ASSERT (ftell (stdin) == 3);
+ ASSERT (ftello (stdin) == 3);
+
+ if (2 < argc)
+ {
+ if (FUNC_UNGETC_BROKEN)
+ {
+ fputs ("Skipping test: ungetc cannot handle arbitrary bytes\n",
+ stderr);
+ return 77;
+ }
+ /* Test ftell after ungetc without read. */
+ ASSERT (fseek (stdin, 0, SEEK_CUR) == 0);
+ ASSERT (ftell (stdin) == 3);
+ ASSERT (ftello (stdin) == 3);
+
+ ch = ungetc ('~', stdin);
+ ASSERT (ch == '~');
+ ASSERT (ftell (stdin) == 2);
+ ASSERT (ftello (stdin) == 2);
+ }
+
+#if !defined __MINT__ /* FreeMiNT has problems seeking past end of file */
+ /* Test ftell beyond end of file. */
+ ASSERT (fseek (stdin, 0, SEEK_END) == 0);
+ ch = ftello (stdin);
+ ASSERT (fseek (stdin, 10, SEEK_END) == 0);
+ ASSERT (ftell (stdin) == ch + 10);
+ ASSERT (ftello (stdin) == ch + 10);
+#endif
+
+ return 0;
+}
diff --git a/tests/gnu/test-ftello.sh b/tests/gnu/test-ftello.sh
new file mode 100755
index 00000000..33d2e838
--- /dev/null
+++ b/tests/gnu/test-ftello.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-ftello${EXEEXT} 1 < "$srcdir/test-ftello.sh" || exit 1
+echo hi | ./test-ftello${EXEEXT} || exit 1
+exit 0
diff --git a/tests/gnu/test-ftello2.sh b/tests/gnu/test-ftello2.sh
new file mode 100755
index 00000000..ba750b00
--- /dev/null
+++ b/tests/gnu/test-ftello2.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./test-ftello${EXEEXT} 1 2 < "$srcdir/test-ftello2.sh"
diff --git a/tests/gnu/test-getdtablesize.c b/tests/gnu/test-getdtablesize.c
new file mode 100755
index 00000000..20e18732
--- /dev/null
+++ b/tests/gnu/test-getdtablesize.c
@@ -0,0 +1,34 @@
+/* Test of getdtablesize() function.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (getdtablesize, int, (void));
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ ASSERT (getdtablesize () >= 3);
+
+ return 0;
+}
diff --git a/tests/gnu/test-gettimeofday.c b/tests/gnu/test-gettimeofday.c
new file mode 100755
index 00000000..ff2bc72b
--- /dev/null
+++ b/tests/gnu/test-gettimeofday.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
+ * Written by Jim Meyering.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <sys/time.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (gettimeofday, int,
+ (struct timeval *, GETTIMEOFDAY_TIMEZONE *));
+
+#include <time.h>
+
+#include <stdio.h>
+#include <string.h>
+
+int
+main (void)
+{
+ time_t t = 0;
+ struct tm *lt;
+ struct tm saved_lt;
+ struct timeval tv;
+ lt = localtime (&t);
+ saved_lt = *lt;
+ gettimeofday (&tv, NULL);
+ if (memcmp (lt, &saved_lt, sizeof (struct tm)) != 0)
+ {
+ fprintf (stderr, "gettimeofday still clobbers the localtime buffer!\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/tests/gnu/test-iconv.c b/tests/gnu/test-iconv.c
new file mode 100755
index 00000000..cf00ac89
--- /dev/null
+++ b/tests/gnu/test-iconv.c
@@ -0,0 +1,148 @@
+/* Test of character set conversion.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#if HAVE_ICONV
+# include <iconv.h>
+
+# ifndef ICONV_CONST
+# define ICONV_CONST /* empty */
+# endif
+
+#include "signature.h"
+SIGNATURE_CHECK (iconv, size_t, (iconv_t, ICONV_CONST char **, size_t *,
+ char **, size_t *));
+SIGNATURE_CHECK (iconv_close, int, (iconv_t x));
+SIGNATURE_CHECK (iconv_open, iconv_t, (char const *, char const *));
+
+#endif
+
+#include <errno.h>
+#include <string.h>
+
+#include "macros.h"
+
+int
+main ()
+{
+#if HAVE_ICONV
+ /* Assume that iconv() supports at least the encodings ASCII, ISO-8859-1,
+ and UTF-8. */
+ iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
+ iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8");
+
+ ASSERT (cd_88591_to_utf8 != (iconv_t)(-1));
+ ASSERT (cd_utf8_to_88591 != (iconv_t)(-1));
+
+ /* Test conversion from ISO-8859-1 to UTF-8 with no errors. */
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ static const char expected[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
+ char buf[50];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_88591_to_utf8,
+ (ICONV_CONST char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ ASSERT (res == 0 && inbytesleft == 0);
+ ASSERT (outptr == buf + strlen (expected));
+ ASSERT (memcmp (buf, expected, strlen (expected)) == 0);
+ }
+
+ /* Test conversion from ISO-8859-1 to UTF-8 with E2BIG. */
+ {
+ static const char input[] = "\304";
+ static char buf[2] = { (char)0xDE, (char)0xAD };
+ const char *inptr = input;
+ size_t inbytesleft = 1;
+ char *outptr = buf;
+ size_t outbytesleft = 1;
+ size_t res = iconv (cd_88591_to_utf8,
+ (ICONV_CONST char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ ASSERT (res == (size_t)(-1) && errno == E2BIG);
+ ASSERT (inbytesleft == 1);
+ ASSERT (outbytesleft == 1);
+ ASSERT ((unsigned char) buf[1] == 0xAD);
+ ASSERT ((unsigned char) buf[0] == 0xDE);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with no errors. */
+ {
+ static const char input[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
+ static const char expected[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ char buf[50];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_utf8_to_88591,
+ (ICONV_CONST char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ ASSERT (res == 0 && inbytesleft == 0);
+ ASSERT (outptr == buf + strlen (expected));
+ ASSERT (memcmp (buf, expected, strlen (expected)) == 0);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with EILSEQ. */
+ {
+ static const char input[] = "\342\202\254"; /* EURO SIGN */
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_utf8_to_88591,
+ (ICONV_CONST char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == (size_t)(-1))
+ {
+ ASSERT (errno == EILSEQ);
+ ASSERT (inbytesleft == strlen (input) && outptr == buf);
+ }
+ else
+ {
+ ASSERT (res == 1);
+ ASSERT (inbytesleft == 0);
+ }
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with EINVAL. */
+ {
+ static const char input[] = "\342";
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = 1;
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_utf8_to_88591,
+ (ICONV_CONST char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ ASSERT (res == (size_t)(-1) && errno == EINVAL);
+ ASSERT (inbytesleft == 1 && outptr == buf);
+ }
+
+ iconv_close (cd_88591_to_utf8);
+ iconv_close (cd_utf8_to_88591);
+#endif
+
+ return 0;
+}
diff --git a/tests/gnu/test-inttypes.c b/tests/gnu/test-inttypes.c
new file mode 100755
index 00000000..f055a4e8
--- /dev/null
+++ b/tests/gnu/test-inttypes.c
@@ -0,0 +1,121 @@
+/* Test of <inttypes.h> substitute.
+ Copyright (C) 2006-2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */
+#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */
+#define __STDC_FORMAT_MACROS 1 /* to make it work also in C++ mode */
+#include <inttypes.h>
+
+#include <stddef.h>
+
+/* Tests for macros supposed to be defined in inttypes.h. */
+
+const char *k = /* implicit string concatenation */
+#ifdef INT8_MAX
+ PRId8 PRIi8
+#endif
+#ifdef UINT8_MAX
+ PRIo8 PRIu8 PRIx8 PRIX8
+#endif
+#ifdef INT16_MAX
+ PRId16 PRIi16
+#endif
+#ifdef UINT16_MAX
+ PRIo16 PRIu16 PRIx16 PRIX16
+#endif
+#ifdef INT32_MAX
+ PRId32 PRIi32
+#endif
+#ifdef UINT32_MAX
+ PRIo32 PRIu32 PRIx32 PRIX32
+#endif
+#ifdef INT64_MAX
+ PRId64 PRIi64
+#endif
+#ifdef UINT64_MAX
+ PRIo64 PRIu64 PRIx64 PRIX64
+#endif
+ PRIdLEAST8 PRIiLEAST8 PRIoLEAST8 PRIuLEAST8 PRIxLEAST8 PRIXLEAST8
+ PRIdLEAST16 PRIiLEAST16 PRIoLEAST16 PRIuLEAST16 PRIxLEAST16 PRIXLEAST16
+ PRIdLEAST32 PRIiLEAST32 PRIoLEAST32 PRIuLEAST32 PRIxLEAST32 PRIXLEAST32
+ PRIdLEAST64 PRIiLEAST64
+ PRIoLEAST64 PRIuLEAST64 PRIxLEAST64 PRIXLEAST64
+ PRIdFAST8 PRIiFAST8 PRIoFAST8 PRIuFAST8 PRIxFAST8 PRIXFAST8
+ PRIdFAST16 PRIiFAST16 PRIoFAST16 PRIuFAST16 PRIxFAST16 PRIXFAST16
+ PRIdFAST32 PRIiFAST32 PRIoFAST32 PRIuFAST32 PRIxFAST32 PRIXFAST32
+ PRIdFAST64 PRIiFAST64
+ PRIoFAST64 PRIuFAST64 PRIxFAST64 PRIXFAST64
+ PRIdMAX PRIiMAX PRIoMAX PRIuMAX PRIxMAX PRIXMAX
+#ifdef INTPTR_MAX
+ PRIdPTR PRIiPTR
+#endif
+#ifdef UINTPTR_MAX
+ PRIoPTR PRIuPTR PRIxPTR PRIXPTR
+#endif
+ ;
+const char *l = /* implicit string concatenation */
+#ifdef INT8_MAX
+ SCNd8 SCNi8
+#endif
+#ifdef UINT8_MAX
+ SCNo8 SCNu8 SCNx8
+#endif
+#ifdef INT16_MAX
+ SCNd16 SCNi16
+#endif
+#ifdef UINT16_MAX
+ SCNo16 SCNu16 SCNx16
+#endif
+#ifdef INT32_MAX
+ SCNd32 SCNi32
+#endif
+#ifdef UINT32_MAX
+ SCNo32 SCNu32 SCNx32
+#endif
+#ifdef INT64_MAX
+ SCNd64 SCNi64
+#endif
+#ifdef UINT64_MAX
+ SCNo64 SCNu64 SCNx64
+#endif
+ SCNdLEAST8 SCNiLEAST8 SCNoLEAST8 SCNuLEAST8 SCNxLEAST8
+ SCNdLEAST16 SCNiLEAST16 SCNoLEAST16 SCNuLEAST16 SCNxLEAST16
+ SCNdLEAST32 SCNiLEAST32 SCNoLEAST32 SCNuLEAST32 SCNxLEAST32
+ SCNdLEAST64 SCNiLEAST64
+ SCNoLEAST64 SCNuLEAST64 SCNxLEAST64
+ SCNdFAST8 SCNiFAST8 SCNoFAST8 SCNuFAST8 SCNxFAST8
+ SCNdFAST16 SCNiFAST16 SCNoFAST16 SCNuFAST16 SCNxFAST16
+ SCNdFAST32 SCNiFAST32 SCNoFAST32 SCNuFAST32 SCNxFAST32
+ SCNdFAST64 SCNiFAST64
+ SCNoFAST64 SCNuFAST64 SCNxFAST64
+ SCNdMAX SCNiMAX SCNoMAX SCNuMAX SCNxMAX
+#ifdef INTPTR_MAX
+ SCNdPTR SCNiPTR
+#endif
+#ifdef UINTPTR_MAX
+ SCNoPTR SCNuPTR SCNxPTR
+#endif
+ ;
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-isnand-nolibm.c b/tests/gnu/test-isnand-nolibm.c
new file mode 100755
index 00000000..b0ac0ba4
--- /dev/null
+++ b/tests/gnu/test-isnand-nolibm.c
@@ -0,0 +1,22 @@
+/* Test of isnand() substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "isnand-nolibm.h"
+
+#include "test-isnand.h"
+
diff --git a/tests/gnu/test-isnand.h b/tests/gnu/test-isnand.h
new file mode 100755
index 00000000..f9866217
--- /dev/null
+++ b/tests/gnu/test-isnand.h
@@ -0,0 +1,65 @@
+/* Test of isnand() substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <limits.h>
+
+#include "nan.h"
+#include "macros.h"
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ So we use -zero instead. */
+double zero = 0.0;
+
+int
+main ()
+{
+ /* Finite values. */
+ ASSERT (!isnand (3.141));
+ ASSERT (!isnand (3.141e30));
+ ASSERT (!isnand (3.141e-30));
+ ASSERT (!isnand (-2.718));
+ ASSERT (!isnand (-2.718e30));
+ ASSERT (!isnand (-2.718e-30));
+ ASSERT (!isnand (0.0));
+ ASSERT (!isnand (-zero));
+ /* Infinite values. */
+ ASSERT (!isnand (1.0 / 0.0));
+ ASSERT (!isnand (-1.0 / 0.0));
+ /* Quiet NaN. */
+ ASSERT (isnand (NaNd ()));
+#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
+ /* Signalling NaN. */
+ {
+ #define NWORDS \
+ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ typedef union { double value; unsigned int word[NWORDS]; } memory_double;
+ memory_double m;
+ m.value = NaNd ();
+# if DBL_EXPBIT0_BIT > 0
+ m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1);
+# else
+ m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+ m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ |= (unsigned int) 1 << DBL_EXPBIT0_BIT;
+ ASSERT (isnand (m.value));
+ }
+#endif
+ return 0;
+}
diff --git a/tests/gnu/test-isnanf-nolibm.c b/tests/gnu/test-isnanf-nolibm.c
new file mode 100755
index 00000000..6ac69e0d
--- /dev/null
+++ b/tests/gnu/test-isnanf-nolibm.c
@@ -0,0 +1,21 @@
+/* Test of isnanf() substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "isnanf-nolibm.h"
+
+#include "test-isnanf.h"
diff --git a/tests/gnu/test-isnanf.h b/tests/gnu/test-isnanf.h
new file mode 100755
index 00000000..d071b2cc
--- /dev/null
+++ b/tests/gnu/test-isnanf.h
@@ -0,0 +1,67 @@
+/* Test of isnanf() substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <limits.h>
+
+#include "nan.h"
+#include "macros.h"
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0f.
+ So we use -zero instead. */
+float zero = 0.0f;
+
+int
+main ()
+{
+ /* Finite values. */
+ ASSERT (!isnanf (3.141f));
+ ASSERT (!isnanf (3.141e30f));
+ ASSERT (!isnanf (3.141e-30f));
+ ASSERT (!isnanf (-2.718f));
+ ASSERT (!isnanf (-2.718e30f));
+ ASSERT (!isnanf (-2.718e-30f));
+ ASSERT (!isnanf (0.0f));
+ ASSERT (!isnanf (-zero));
+ /* Infinite values. */
+ ASSERT (!isnanf (1.0f / 0.0f));
+ ASSERT (!isnanf (-1.0f / 0.0f));
+ /* Quiet NaN. */
+ ASSERT (isnanf (NaNf ()));
+#if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
+ /* Signalling NaN. */
+ {
+ #define NWORDS \
+ ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ typedef union { float value; unsigned int word[NWORDS]; } memory_float;
+ memory_float m;
+ m.value = NaNf ();
+# if FLT_EXPBIT0_BIT > 0
+ m.word[FLT_EXPBIT0_WORD] ^= (unsigned int) 1 << (FLT_EXPBIT0_BIT - 1);
+# else
+ m.word[FLT_EXPBIT0_WORD + (FLT_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+ if (FLT_EXPBIT0_WORD < NWORDS / 2)
+ m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT;
+ else
+ m.word[0] |= (unsigned int) 1;
+ ASSERT (isnanf (m.value));
+ }
+#endif
+ return 0;
+}
diff --git a/tests/gnu/test-isnanl-nolibm.c b/tests/gnu/test-isnanl-nolibm.c
new file mode 100755
index 00000000..eeca6d8f
--- /dev/null
+++ b/tests/gnu/test-isnanl-nolibm.c
@@ -0,0 +1,23 @@
+/* Test of isnanl() substitute.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "isnanl-nolibm.h"
+
+#include "test-isnanl.h"
diff --git a/tests/gnu/test-isnanl.h b/tests/gnu/test-isnanl.h
new file mode 100755
index 00000000..1665cf41
--- /dev/null
+++ b/tests/gnu/test-isnanl.h
@@ -0,0 +1,141 @@
+/* Test of isnanl() substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <float.h>
+#include <limits.h>
+
+#include "nan.h"
+#include "macros.h"
+
+/* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
+ So we use minus_zero instead.
+ IRIX cc can't put -0.0L into .data, but can compute at runtime.
+ Note that the expression -LDBL_MIN * LDBL_MIN does not work on other
+ platforms, such as when cross-compiling to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi
+static long double
+compute_minus_zero (void)
+{
+ return -LDBL_MIN * LDBL_MIN;
+}
+# define minus_zero compute_minus_zero ()
+#else
+long double minus_zero = -0.0L;
+#endif
+
+int
+main ()
+{
+ #define NWORDS \
+ ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ typedef union { unsigned int word[NWORDS]; long double value; }
+ memory_long_double;
+
+ /* Finite values. */
+ ASSERT (!isnanl (3.141L));
+ ASSERT (!isnanl (3.141e30L));
+ ASSERT (!isnanl (3.141e-30L));
+ ASSERT (!isnanl (-2.718L));
+ ASSERT (!isnanl (-2.718e30L));
+ ASSERT (!isnanl (-2.718e-30L));
+ ASSERT (!isnanl (0.0L));
+ ASSERT (!isnanl (minus_zero));
+ /* Infinite values. */
+ ASSERT (!isnanl (1.0L / 0.0L));
+ ASSERT (!isnanl (-1.0L / 0.0L));
+ /* Quiet NaN. */
+ ASSERT (isnanl (NaNl ()));
+
+#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
+ /* A bit pattern that is different from a Quiet NaN. With a bit of luck,
+ it's a Signalling NaN. */
+ {
+ memory_long_double m;
+ m.value = NaNl ();
+# if LDBL_EXPBIT0_BIT > 0
+ m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1);
+# else
+ m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+ m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ |= (unsigned int) 1 << LDBL_EXPBIT0_BIT;
+ ASSERT (isnanl (m.value));
+ }
+#endif
+
+#if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+ of 'unsigned int' words. */
+# ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+ ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
+ (unsigned int) (mantlo) << 16 \
+ }
+# else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { mantlo, manthi, exponent }
+# endif
+ { /* Quiet NaN. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ ASSERT (isnanl (x.value));
+ }
+ {
+ /* Signalling NaN. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ ASSERT (isnanl (x.value));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ ASSERT (isnanl (x.value));
+ }
+ { /* Pseudo-Infinity. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ ASSERT (isnanl (x.value));
+ }
+ { /* Pseudo-Zero. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ ASSERT (isnanl (x.value));
+ }
+ { /* Unnormalized number. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ ASSERT (isnanl (x.value));
+ }
+ { /* Pseudo-Denormal. */
+ static memory_long_double x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ ASSERT (isnanl (x.value));
+ }
+#endif
+
+ return 0;
+}
diff --git a/tests/gnu/test-langinfo.c b/tests/gnu/test-langinfo.c
new file mode 100755
index 00000000..7547f3bf
--- /dev/null
+++ b/tests/gnu/test-langinfo.c
@@ -0,0 +1,92 @@
+/* Test of <langinfo.h> substitute.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2009. */
+
+#include <config.h>
+
+#include <langinfo.h>
+
+/* Check that all the nl_item values are defined. */
+int items[] =
+ {
+ /* nl_langinfo items of the LC_CTYPE category */
+ CODESET,
+ /* nl_langinfo items of the LC_NUMERIC category */
+ RADIXCHAR,
+ THOUSEP,
+ /* nl_langinfo items of the LC_TIME category */
+ D_T_FMT,
+ D_FMT,
+ T_FMT,
+ T_FMT_AMPM,
+ AM_STR,
+ PM_STR,
+ DAY_1,
+ DAY_2,
+ DAY_3,
+ DAY_4,
+ DAY_5,
+ DAY_6,
+ DAY_7,
+ ABDAY_1,
+ ABDAY_2,
+ ABDAY_3,
+ ABDAY_4,
+ ABDAY_5,
+ ABDAY_6,
+ ABDAY_7,
+ MON_1,
+ MON_2,
+ MON_3,
+ MON_4,
+ MON_5,
+ MON_6,
+ MON_7,
+ MON_8,
+ MON_9,
+ MON_10,
+ MON_11,
+ MON_12,
+ ABMON_1,
+ ABMON_2,
+ ABMON_3,
+ ABMON_4,
+ ABMON_5,
+ ABMON_6,
+ ABMON_7,
+ ABMON_8,
+ ABMON_9,
+ ABMON_10,
+ ABMON_11,
+ ABMON_12,
+ ERA,
+ ERA_D_FMT,
+ ERA_D_T_FMT,
+ ERA_T_FMT,
+ ALT_DIGITS,
+ /* nl_langinfo items of the LC_MONETARY category */
+ CRNCYSTR,
+ /* nl_langinfo items of the LC_MESSAGES category */
+ YESEXPR,
+ NOEXPR
+ };
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-link.c b/tests/gnu/test-link.c
new file mode 100755
index 00000000..65ee9e09
--- /dev/null
+++ b/tests/gnu/test-link.c
@@ -0,0 +1,47 @@
+/* Test of link() function.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (link, int, (char const *, char const *));
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "test-link.t"
+
+#include "test-link.h"
+
+int
+main (void)
+{
+ /* Remove any garbage left from previous partial runs. */
+ ignore_value (system ("rm -rf " BASE "*"));
+
+ return test_link (link, true);
+}
diff --git a/tests/gnu/test-link.h b/tests/gnu/test-link.h
new file mode 100755
index 00000000..28bdcc13
--- /dev/null
+++ b/tests/gnu/test-link.h
@@ -0,0 +1,176 @@
+/* Test of link() function.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This file is designed to test both link(a,b) and
+ linkat(AT_FDCWD,a,AT_FDCWD,b,0). FUNC is the function to test.
+ Assumes that BASE and ASSERT are already defined, and that
+ appropriate headers are already included. If PRINT, warn before
+ skipping tests with status 77. This test does not try to create
+ hard links to symlinks, but does test other aspects of symlink. */
+
+static int
+test_link (int (*func) (char const *, char const *), bool print)
+{
+ int fd;
+ int ret;
+
+ /* Create first file. */
+ fd = open (BASE "a", O_CREAT | O_EXCL | O_WRONLY, 0600);
+ ASSERT (0 <= fd);
+ ASSERT (write (fd, "hello", 5) == 5);
+ ASSERT (close (fd) == 0);
+
+ /* Not all file systems support link. Mingw doesn't have reliable
+ st_nlink on hard links, but our implementation does fail with
+ EPERM on poor file systems, and we can detect the inferior stat()
+ via st_ino. Cygwin 1.5.x copies rather than links files on those
+ file systems, but there, st_nlink and st_ino are reliable. */
+ ret = func (BASE "a", BASE "b");
+ if (!ret)
+ {
+ struct stat st;
+ ASSERT (stat (BASE "b", &st) == 0);
+ if (st.st_ino && st.st_nlink != 2)
+ {
+ ASSERT (unlink (BASE "b") == 0);
+ errno = EPERM;
+ ret = -1;
+ }
+ }
+ if (ret == -1)
+ {
+ /* If the device does not support hard links, errno is
+ EPERM on Linux, EOPNOTSUPP on FreeBSD. */
+ switch (errno)
+ {
+ case EPERM:
+ case EOPNOTSUPP:
+ if (print)
+ fputs ("skipping test: "
+ "hard links not supported on this file system\n",
+ stderr);
+ ASSERT (unlink (BASE "a") == 0);
+ return 77;
+ default:
+ perror ("link");
+ return 1;
+ }
+ }
+ ASSERT (ret == 0);
+
+ /* Now, for some behavior tests. Modify the contents of 'b', and
+ ensure that 'a' can see it, both while 'b' exists and after. */
+ fd = open (BASE "b", O_APPEND | O_WRONLY);
+ ASSERT (0 <= fd);
+ ASSERT (write (fd, "world", 5) == 5);
+ ASSERT (close (fd) == 0);
+ {
+ char buf[11] = { 0 };
+ fd = open (BASE "a", O_RDONLY);
+ ASSERT (0 <= fd);
+ ASSERT (read (fd, buf, 10) == 10);
+ ASSERT (strcmp (buf, "helloworld") == 0);
+ ASSERT (close (fd) == 0);
+ ASSERT (unlink (BASE "b") == 0);
+ fd = open (BASE "a", O_RDONLY);
+ ASSERT (0 <= fd);
+ ASSERT (read (fd, buf, 10) == 10);
+ ASSERT (strcmp (buf, "helloworld") == 0);
+ ASSERT (close (fd) == 0);
+ }
+
+ /* Test for various error conditions. */
+ ASSERT (mkdir (BASE "d", 0700) == 0);
+ errno = 0;
+ ASSERT (func (BASE "a", ".") == -1);
+ ASSERT (errno == EEXIST || errno == EINVAL);
+ errno = 0;
+ ASSERT (func (BASE "a", BASE "a") == -1);
+ ASSERT (errno == EEXIST);
+ ASSERT (func (BASE "a", BASE "b") == 0);
+ errno = 0;
+ ASSERT (func (BASE "a", BASE "b") == -1);
+ ASSERT (errno == EEXIST);
+ errno = 0;
+ ASSERT (func (BASE "a", BASE "d") == -1);
+ ASSERT (errno == EEXIST);
+ errno = 0;
+ ASSERT (func (BASE "c", BASE "e") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "a", BASE "c/.") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "a/", BASE "c") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "a", BASE "c/") == -1);
+ ASSERT (errno == ENOTDIR || errno == ENOENT);
+
+ /* Most platforms reject hard links to directories, and even on
+ those that do permit it, most users can't create them. We assume
+ that if this test is run as root and we managed to create a hard
+ link, then unlink better be able to clean it up. */
+ {
+ int result;
+ errno = 0;
+ result = func (BASE "d", BASE "c");
+ if (result == 0)
+ {
+ /* Probably root on Solaris. */
+ ASSERT (unlink (BASE "c") == 0);
+ }
+ else
+ {
+ /* Most everyone else. */
+ ASSERT (errno == EPERM || errno == EACCES);
+ errno = 0;
+ ASSERT (func (BASE "d/.", BASE "c") == -1);
+ ASSERT (errno == EPERM || errno == EACCES || errno == EINVAL);
+ errno = 0;
+ ASSERT (func (BASE "d/.//", BASE "c") == -1);
+ ASSERT (errno == EPERM || errno == EACCES || errno == EINVAL);
+ }
+ }
+ ASSERT (unlink (BASE "a") == 0);
+ errno = 0;
+ ASSERT (unlink (BASE "c") == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (rmdir (BASE "d") == 0);
+
+ /* Test invalid use of symlink. */
+ if (symlink (BASE "a", BASE "link") != 0)
+ {
+ ASSERT (unlink (BASE "b") == 0);
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+ errno = 0;
+ ASSERT (func (BASE "b", BASE "link/") == -1);
+ ASSERT (errno == ENOTDIR || errno == ENOENT || errno == EEXIST);
+ ASSERT (rename (BASE "b", BASE "a") == 0);
+ errno = 0;
+ ASSERT (func (BASE "link/", BASE "b") == -1);
+ ASSERT (errno == ENOTDIR || errno == EEXIST);
+
+ /* Clean up. */
+ ASSERT (unlink (BASE "a") == 0);
+ ASSERT (unlink (BASE "link") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-linkedhash_list.c b/tests/gnu/test-linkedhash_list.c
new file mode 100755
index 00000000..9139c212
--- /dev/null
+++ b/tests/gnu/test-linkedhash_list.c
@@ -0,0 +1,441 @@
+/* Test of sequential list data type implementation.
+ Copyright (C) 2006-2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "gl_linkedhash_list.h"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gl_array_list.h"
+#include "progname.h"
+#include "macros.h"
+
+static const char *objects[15] =
+ {
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"
+ };
+
+#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
+
+static bool
+string_equals (const void *x1, const void *x2)
+{
+ const char *s1 = x1;
+ const char *s2 = x2;
+ return strcmp (s1, s2) == 0;
+}
+
+/* A hash function for NUL-terminated char* strings using
+ the method described by Bruno Haible.
+ See http://www.haible.de/bruno/hashfunc.html. */
+static size_t
+string_hash (const void *x)
+{
+ const char *s = x;
+ size_t h = 0;
+
+ for (; *s; s++)
+ h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
+
+ return h;
+}
+
+#define RANDOM(n) (rand () % (n))
+#define RANDOM_OBJECT() objects[RANDOM (SIZEOF (objects))]
+
+static void
+check_equals (gl_list_t list1, gl_list_t list2)
+{
+ size_t n, i;
+
+ n = gl_list_size (list1);
+ ASSERT (n == gl_list_size (list2));
+ for (i = 0; i < n; i++)
+ {
+ ASSERT (gl_list_get_at (list1, i) == gl_list_get_at (list2, i));
+ }
+}
+
+static void
+check_all (gl_list_t list1, gl_list_t list2, gl_list_t list3)
+{
+ check_equals (list1, list2);
+ check_equals (list1, list3);
+}
+
+int
+main (int argc, char *argv[])
+{
+ gl_list_t list1, list2, list3;
+
+ set_program_name (argv[0]);
+
+ /* Allow the user to provide a non-default random seed on the command line. */
+ if (argc > 1)
+ srand (atoi (argv[1]));
+
+ {
+ size_t initial_size = RANDOM (50);
+ const void **contents =
+ (const void **) malloc (initial_size * sizeof (const void *));
+ size_t i;
+ unsigned int repeat;
+
+ for (i = 0; i < initial_size; i++)
+ contents[i] = RANDOM_OBJECT ();
+
+ /* Create list1. */
+ list1 = gl_list_nx_create (GL_ARRAY_LIST,
+ string_equals, string_hash, NULL, true,
+ initial_size, contents);
+ ASSERT (list1 != NULL);
+ /* Create list2. */
+ list2 = gl_list_nx_create_empty (GL_LINKEDHASH_LIST,
+ string_equals, string_hash, NULL, true);
+ ASSERT (list2 != NULL);
+ for (i = 0; i < initial_size; i++)
+ ASSERT (gl_list_nx_add_last (list2, contents[i]) != NULL);
+
+ /* Create list3. */
+ list3 = gl_list_nx_create (GL_LINKEDHASH_LIST,
+ string_equals, string_hash, NULL, true,
+ initial_size, contents);
+ ASSERT (list3 != NULL);
+
+ check_all (list1, list2, list3);
+
+ for (repeat = 0; repeat < 10000; repeat++)
+ {
+ unsigned int operation = RANDOM (16);
+ switch (operation)
+ {
+ case 0:
+ if (gl_list_size (list1) > 0)
+ {
+ size_t index = RANDOM (gl_list_size (list1));
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2, node3;
+
+ node1 = gl_list_nx_set_at (list1, index, obj);
+ ASSERT (node1 != NULL);
+ ASSERT (gl_list_get_at (list1, index) == obj);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+
+ node2 = gl_list_nx_set_at (list2, index, obj);
+ ASSERT (node2 != NULL);
+ ASSERT (gl_list_get_at (list2, index) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+
+ node3 = gl_list_nx_set_at (list3, index, obj);
+ ASSERT (node3 != NULL);
+ ASSERT (gl_list_get_at (list3, index) == obj);
+ ASSERT (gl_list_node_value (list3, node3) == obj);
+
+ if (index > 0)
+ {
+ ASSERT (gl_list_node_value (list1, gl_list_previous_node (list1, node1))
+ == gl_list_get_at (list1, index - 1));
+ ASSERT (gl_list_node_value (list2, gl_list_previous_node (list3, node3))
+ == gl_list_get_at (list2, index - 1));
+ ASSERT (gl_list_node_value (list3, gl_list_previous_node (list3, node3))
+ == gl_list_get_at (list2, index - 1));
+ }
+ if (index + 1 < gl_list_size (list1))
+ {
+ ASSERT (gl_list_node_value (list1, gl_list_next_node (list1, node1))
+ == gl_list_get_at (list1, index + 1));
+ ASSERT (gl_list_node_value (list2, gl_list_next_node (list3, node3))
+ == gl_list_get_at (list2, index + 1));
+ ASSERT (gl_list_node_value (list3, gl_list_next_node (list3, node3))
+ == gl_list_get_at (list2, index + 1));
+ }
+ }
+ break;
+ case 1:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2, node3;
+ node1 = gl_list_search (list1, obj);
+ node2 = gl_list_search (list2, obj);
+ node3 = gl_list_search (list3, obj);
+ if (node1 == NULL)
+ {
+ ASSERT (node2 == NULL);
+ ASSERT (node3 == NULL);
+ }
+ else
+ {
+ ASSERT (node2 != NULL);
+ ASSERT (node3 != NULL);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+ ASSERT (gl_list_node_value (list3, node3) == obj);
+ }
+ }
+ break;
+ case 2:
+ {
+ const char *obj = RANDOM_OBJECT ();
+ size_t index1, index2, index3;
+ index1 = gl_list_indexof (list1, obj);
+ index2 = gl_list_indexof (list2, obj);
+ index3 = gl_list_indexof (list3, obj);
+ if (index1 == (size_t)(-1))
+ {
+ ASSERT (index2 == (size_t)(-1));
+ ASSERT (index3 == (size_t)(-1));
+ }
+ else
+ {
+ ASSERT (index2 != (size_t)(-1));
+ ASSERT (index3 != (size_t)(-1));
+ ASSERT (gl_list_get_at (list1, index1) == obj);
+ ASSERT (gl_list_get_at (list2, index2) == obj);
+ ASSERT (gl_list_get_at (list3, index3) == obj);
+ ASSERT (index2 == index1);
+ ASSERT (index3 == index1);
+ }
+ }
+ break;
+ case 3: /* add 1 element */
+ {
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2, node3;
+ node1 = gl_list_nx_add_first (list1, obj);
+ ASSERT (node1 != NULL);
+ node2 = gl_list_nx_add_first (list2, obj);
+ ASSERT (node2 != NULL);
+ node3 = gl_list_nx_add_first (list3, obj);
+ ASSERT (node3 != NULL);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+ ASSERT (gl_list_node_value (list3, node3) == obj);
+ ASSERT (gl_list_get_at (list1, 0) == obj);
+ ASSERT (gl_list_get_at (list2, 0) == obj);
+ ASSERT (gl_list_get_at (list3, 0) == obj);
+ }
+ break;
+ case 4: /* add 1 element */
+ {
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2, node3;
+ node1 = gl_list_nx_add_last (list1, obj);
+ ASSERT (node1 != NULL);
+ node2 = gl_list_nx_add_last (list2, obj);
+ ASSERT (node2 != NULL);
+ node3 = gl_list_nx_add_last (list3, obj);
+ ASSERT (node3 != NULL);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+ ASSERT (gl_list_node_value (list3, node3) == obj);
+ ASSERT (gl_list_get_at (list1, gl_list_size (list1) - 1) == obj);
+ ASSERT (gl_list_get_at (list2, gl_list_size (list2) - 1) == obj);
+ ASSERT (gl_list_get_at (list3, gl_list_size (list3) - 1) == obj);
+ }
+ break;
+ case 5: /* add 3 elements */
+ {
+ const char *obj0 = RANDOM_OBJECT ();
+ const char *obj1 = RANDOM_OBJECT ();
+ const char *obj2 = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2, node3;
+ node1 = gl_list_nx_add_first (list1, obj2);
+ ASSERT (node1 != NULL);
+ node1 = gl_list_nx_add_before (list1, node1, obj0);
+ ASSERT (node1 != NULL);
+ node1 = gl_list_nx_add_after (list1, node1, obj1);
+ ASSERT (node1 != NULL);
+ node2 = gl_list_nx_add_first (list2, obj2);
+ ASSERT (node2 != NULL);
+ node2 = gl_list_nx_add_before (list2, node2, obj0);
+ ASSERT (node2 != NULL);
+ node2 = gl_list_nx_add_after (list2, node2, obj1);
+ ASSERT (node2 != NULL);
+ node3 = gl_list_nx_add_first (list3, obj2);
+ ASSERT (node3 != NULL);
+ node3 = gl_list_nx_add_before (list3, node3, obj0);
+ ASSERT (node3 != NULL);
+ node3 = gl_list_nx_add_after (list3, node3, obj1);
+ ASSERT (node3 != NULL);
+ ASSERT (gl_list_node_value (list1, node1) == obj1);
+ ASSERT (gl_list_node_value (list2, node2) == obj1);
+ ASSERT (gl_list_node_value (list3, node3) == obj1);
+ ASSERT (gl_list_get_at (list1, 0) == obj0);
+ ASSERT (gl_list_get_at (list1, 1) == obj1);
+ ASSERT (gl_list_get_at (list1, 2) == obj2);
+ ASSERT (gl_list_get_at (list2, 0) == obj0);
+ ASSERT (gl_list_get_at (list2, 1) == obj1);
+ ASSERT (gl_list_get_at (list2, 2) == obj2);
+ ASSERT (gl_list_get_at (list3, 0) == obj0);
+ ASSERT (gl_list_get_at (list3, 1) == obj1);
+ ASSERT (gl_list_get_at (list3, 2) == obj2);
+ }
+ break;
+ case 6: /* add 1 element */
+ {
+ size_t index = RANDOM (gl_list_size (list1) + 1);
+ const char *obj = RANDOM_OBJECT ();
+ gl_list_node_t node1, node2, node3;
+ node1 = gl_list_nx_add_at (list1, index, obj);
+ ASSERT (node1 != NULL);
+ node2 = gl_list_nx_add_at (list2, index, obj);
+ ASSERT (node2 != NULL);
+ node3 = gl_list_nx_add_at (list3, index, obj);
+ ASSERT (node3 != NULL);
+ ASSERT (gl_list_get_at (list1, index) == obj);
+ ASSERT (gl_list_node_value (list1, node1) == obj);
+ ASSERT (gl_list_get_at (list2, index) == obj);
+ ASSERT (gl_list_node_value (list2, node2) == obj);
+ ASSERT (gl_list_get_at (list3, index) == obj);
+ ASSERT (gl_list_node_value (list3, node3) == obj);
+ if (index > 0)
+ {
+ ASSERT (gl_list_node_value (list1, gl_list_previous_node (list1, node1))
+ == gl_list_get_at (list1, index - 1));
+ ASSERT (gl_list_node_value (list2, gl_list_previous_node (list3, node3))
+ == gl_list_get_at (list2, index - 1));
+ ASSERT (gl_list_node_value (list3, gl_list_previous_node (list3, node3))
+ == gl_list_get_at (list2, index - 1));
+ }
+ if (index + 1 < gl_list_size (list1))
+ {
+ ASSERT (gl_list_node_value (list1, gl_list_next_node (list1, node1))
+ == gl_list_get_at (list1, index + 1));
+ ASSERT (gl_list_node_value (list2, gl_list_next_node (list3, node3))
+ == gl_list_get_at (list2, index + 1));
+ ASSERT (gl_list_node_value (list3, gl_list_next_node (list3, node3))
+ == gl_list_get_at (list2, index + 1));
+ }
+ }
+ break;
+ case 7: case 8: /* remove 1 element */
+ if (gl_list_size (list1) > 0)
+ {
+ size_t n = gl_list_size (list1);
+ const char *obj = gl_list_get_at (list1, RANDOM (n));
+ gl_list_node_t node1, node2, node3;
+ node1 = gl_list_search (list1, obj);
+ node2 = gl_list_search (list2, obj);
+ node3 = gl_list_search (list3, obj);
+ ASSERT (node1 != NULL);
+ ASSERT (node2 != NULL);
+ ASSERT (node3 != NULL);
+ ASSERT (gl_list_remove_node (list1, node1));
+ ASSERT (gl_list_remove_node (list2, node2));
+ ASSERT (gl_list_remove_node (list3, node3));
+ ASSERT (gl_list_size (list1) == n - 1);
+ }
+ break;
+ case 9: case 10: /* remove 1 element */
+ if (gl_list_size (list1) > 0)
+ {
+ size_t n = gl_list_size (list1);
+ size_t index = RANDOM (n);
+ ASSERT (gl_list_remove_at (list1, index));
+ ASSERT (gl_list_remove_at (list2, index));
+ ASSERT (gl_list_remove_at (list3, index));
+ ASSERT (gl_list_size (list1) == n - 1);
+ }
+ break;
+ case 11: case 12: /* remove 1 element */
+ if (gl_list_size (list1) > 0)
+ {
+ size_t n = gl_list_size (list1);
+ const char *obj = gl_list_get_at (list1, RANDOM (n));
+ ASSERT (gl_list_remove (list1, obj));
+ ASSERT (gl_list_remove (list2, obj));
+ ASSERT (gl_list_remove (list3, obj));
+ ASSERT (gl_list_size (list1) == n - 1);
+ }
+ break;
+ case 13:
+ if (gl_list_size (list1) > 0)
+ {
+ size_t n = gl_list_size (list1);
+ const char *obj = "xyzzy";
+ ASSERT (!gl_list_remove (list1, obj));
+ ASSERT (!gl_list_remove (list2, obj));
+ ASSERT (!gl_list_remove (list3, obj));
+ ASSERT (gl_list_size (list1) == n);
+ }
+ break;
+ case 14:
+ {
+ size_t n = gl_list_size (list1);
+ gl_list_iterator_t iter1, iter2, iter3;
+ const void *elt;
+ iter1 = gl_list_iterator (list1);
+ iter2 = gl_list_iterator (list2);
+ iter3 = gl_list_iterator (list3);
+ for (i = 0; i < n; i++)
+ {
+ ASSERT (gl_list_iterator_next (&iter1, &elt, NULL));
+ ASSERT (gl_list_get_at (list1, i) == elt);
+ ASSERT (gl_list_iterator_next (&iter2, &elt, NULL));
+ ASSERT (gl_list_get_at (list2, i) == elt);
+ ASSERT (gl_list_iterator_next (&iter3, &elt, NULL));
+ ASSERT (gl_list_get_at (list3, i) == elt);
+ }
+ ASSERT (!gl_list_iterator_next (&iter1, &elt, NULL));
+ ASSERT (!gl_list_iterator_next (&iter2, &elt, NULL));
+ ASSERT (!gl_list_iterator_next (&iter3, &elt, NULL));
+ gl_list_iterator_free (&iter1);
+ gl_list_iterator_free (&iter2);
+ gl_list_iterator_free (&iter3);
+ }
+ break;
+ case 15:
+ {
+ size_t end = RANDOM (gl_list_size (list1) + 1);
+ size_t start = RANDOM (end + 1);
+ gl_list_iterator_t iter1, iter2, iter3;
+ const void *elt;
+ iter1 = gl_list_iterator_from_to (list1, start, end);
+ iter2 = gl_list_iterator_from_to (list2, start, end);
+ iter3 = gl_list_iterator_from_to (list3, start, end);
+ for (i = start; i < end; i++)
+ {
+ ASSERT (gl_list_iterator_next (&iter1, &elt, NULL));
+ ASSERT (gl_list_get_at (list1, i) == elt);
+ ASSERT (gl_list_iterator_next (&iter2, &elt, NULL));
+ ASSERT (gl_list_get_at (list2, i) == elt);
+ ASSERT (gl_list_iterator_next (&iter3, &elt, NULL));
+ ASSERT (gl_list_get_at (list3, i) == elt);
+ }
+ ASSERT (!gl_list_iterator_next (&iter1, &elt, NULL));
+ ASSERT (!gl_list_iterator_next (&iter2, &elt, NULL));
+ ASSERT (!gl_list_iterator_next (&iter3, &elt, NULL));
+ gl_list_iterator_free (&iter1);
+ gl_list_iterator_free (&iter2);
+ gl_list_iterator_free (&iter3);
+ }
+ break;
+ }
+ check_all (list1, list2, list3);
+ }
+
+ gl_list_free (list1);
+ gl_list_free (list2);
+ gl_list_free (list3);
+ free (contents);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-lseek.c b/tests/gnu/test-lseek.c
new file mode 100755
index 00000000..bafa9b58
--- /dev/null
+++ b/tests/gnu/test-lseek.c
@@ -0,0 +1,96 @@
+/* Test of lseek() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake, 2007. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (lseek, off_t, (int, off_t, int));
+
+#include <errno.h>
+
+#include "macros.h"
+
+/* ARGC must be 2; *ARGV[1] is '0' if stdin and stdout are files, '1'
+ if they are pipes, and '2' if they are closed. Check for proper
+ semantics of lseek. */
+int
+main (int argc, char **argv)
+{
+ if (argc != 2)
+ return 2;
+ switch (*argv[1])
+ {
+ case '0': /* regular files */
+ ASSERT (lseek (0, (off_t)2, SEEK_SET) == 2);
+ ASSERT (lseek (0, (off_t)-4, SEEK_CUR) == -1);
+ ASSERT (errno == EINVAL);
+ errno = 0;
+#if ! defined __BEOS__
+ /* POSIX says that the last lseek call, when failing, does not change
+ the current offset. But BeOS sets it to 0. */
+ ASSERT (lseek (0, (off_t)0, SEEK_CUR) == 2);
+#endif
+#if 0 /* leads to SIGSYS on IRIX 6.5 */
+ ASSERT (lseek (0, (off_t)0, (SEEK_SET | SEEK_CUR | SEEK_END) + 1) == -1);
+ ASSERT (errno == EINVAL);
+#endif
+ ASSERT (lseek (1, (off_t)2, SEEK_SET) == 2);
+ errno = 0;
+ ASSERT (lseek (1, (off_t)-4, SEEK_CUR) == -1);
+ ASSERT (errno == EINVAL);
+ errno = 0;
+#if ! defined __BEOS__
+ /* POSIX says that the last lseek call, when failing, does not change
+ the current offset. But BeOS sets it to 0. */
+ ASSERT (lseek (1, (off_t)0, SEEK_CUR) == 2);
+#endif
+#if 0 /* leads to SIGSYS on IRIX 6.5 */
+ ASSERT (lseek (1, (off_t)0, (SEEK_SET | SEEK_CUR | SEEK_END) + 1) == -1);
+ ASSERT (errno == EINVAL);
+#endif
+ break;
+
+ case '1': /* pipes */
+ errno = 0;
+ ASSERT (lseek (0, (off_t)0, SEEK_CUR) == -1);
+ ASSERT (errno == ESPIPE);
+ errno = 0;
+ ASSERT (lseek (1, (off_t)0, SEEK_CUR) == -1);
+ ASSERT (errno == ESPIPE);
+ break;
+
+ case '2': /* closed */
+ /* Explicitly close file descriptors 0 and 1. The <&- and >&- in the
+ invoking shell are not enough on HP-UX. */
+ close (0);
+ close (1);
+ errno = 0;
+ ASSERT (lseek (0, (off_t)0, SEEK_CUR) == -1);
+ ASSERT (errno == EBADF);
+ errno = 0;
+ ASSERT (lseek (1, (off_t)0, SEEK_CUR) == -1);
+ ASSERT (errno == EBADF);
+ break;
+
+ default:
+ return 1;
+ }
+ return 0;
+}
diff --git a/tests/gnu/test-lseek.sh b/tests/gnu/test-lseek.sh
new file mode 100755
index 00000000..e84c2bb4
--- /dev/null
+++ b/tests/gnu/test-lseek.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+tmpfiles=
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles=t-lseek.tmp
+# seekable files
+./test-lseek${EXEEXT} 0 < "$srcdir/test-lseek.sh" > t-lseek.tmp || exit 1
+
+# pipes
+echo hi | ./test-lseek${EXEEXT} 1 | cat || exit 1
+
+# closed descriptors
+./test-lseek${EXEEXT} 2 <&- >&- || exit 1
+
+rm -rf $tmpfiles
+exit 0
diff --git a/tests/gnu/test-lstat.c b/tests/gnu/test-lstat.c
new file mode 100755
index 00000000..b8f9237e
--- /dev/null
+++ b/tests/gnu/test-lstat.c
@@ -0,0 +1,60 @@
+/* Test of lstat() function.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson, 2008; and Eric Blake, 2009. */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+/* Caution: lstat may be a function-like macro. Although this
+ signature check must pass, it may be the signature of the real (and
+ broken) lstat rather than rpl_lstat. Most code should not use the
+ address of lstat. */
+#include "signature.h"
+SIGNATURE_CHECK (lstat, int, (char const *, struct stat *));
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "same-inode.h"
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "test-lstat.t"
+
+#include "test-lstat.h"
+
+/* Wrapper around lstat, which works even if lstat is a function-like
+ macro, where test_lstat_func(lstat) would do the wrong thing. */
+static int
+do_lstat (char const *name, struct stat *st)
+{
+ return lstat (name, st);
+}
+
+int
+main (void)
+{
+ /* Remove any leftovers from a previous partial run. */
+ ignore_value (system ("rm -rf " BASE "*"));
+
+ return test_lstat_func (do_lstat, true);
+}
diff --git a/tests/gnu/test-lstat.h b/tests/gnu/test-lstat.h
new file mode 100755
index 00000000..f120f4c5
--- /dev/null
+++ b/tests/gnu/test-lstat.h
@@ -0,0 +1,116 @@
+/* Test of lstat() function.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson, 2008; and Eric Blake, 2009. */
+
+/* This file is designed to test both lstat(n,buf) and
+ fstatat(AT_FDCWD,n,buf,AT_SYMLINK_NOFOLLOW). FUNC is the function
+ to test. Assumes that BASE and ASSERT are already defined, and
+ that appropriate headers are already included. If PRINT, warn
+ before skipping symlink tests with status 77. */
+
+static int
+test_lstat_func (int (*func) (char const *, struct stat *), bool print)
+{
+ struct stat st1;
+ struct stat st2;
+
+ /* Test for common directories. */
+ ASSERT (func (".", &st1) == 0);
+ ASSERT (func ("./", &st2) == 0);
+ ASSERT (SAME_INODE (st1, st2));
+ ASSERT (S_ISDIR (st1.st_mode));
+ ASSERT (S_ISDIR (st2.st_mode));
+ ASSERT (func ("/", &st1) == 0);
+ ASSERT (func ("///", &st2) == 0);
+ ASSERT (SAME_INODE (st1, st2));
+ ASSERT (S_ISDIR (st1.st_mode));
+ ASSERT (S_ISDIR (st2.st_mode));
+ ASSERT (func ("..", &st1) == 0);
+ ASSERT (S_ISDIR (st1.st_mode));
+
+ /* Test for error conditions. */
+ errno = 0;
+ ASSERT (func ("", &st1) == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func ("nosuch", &st1) == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func ("nosuch/", &st1) == -1);
+ ASSERT (errno == ENOENT);
+
+ ASSERT (close (creat (BASE "file", 0600)) == 0);
+ ASSERT (func (BASE "file", &st1) == 0);
+ ASSERT (S_ISREG (st1.st_mode));
+ errno = 0;
+ ASSERT (func (BASE "file/", &st1) == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Now for some symlink tests, where supported. We set up:
+ link1 -> directory
+ link2 -> file
+ link3 -> dangling
+ link4 -> loop
+ then test behavior both with and without trailing slash.
+ */
+ if (symlink (".", BASE "link1") != 0)
+ {
+ ASSERT (unlink (BASE "file") == 0);
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+ ASSERT (symlink (BASE "file", BASE "link2") == 0);
+ ASSERT (symlink (BASE "nosuch", BASE "link3") == 0);
+ ASSERT (symlink (BASE "link4", BASE "link4") == 0);
+
+ ASSERT (func (BASE "link1", &st1) == 0);
+ ASSERT (S_ISLNK (st1.st_mode));
+ ASSERT (func (BASE "link1/", &st1) == 0);
+ ASSERT (stat (BASE "link1", &st2) == 0);
+ ASSERT (S_ISDIR (st1.st_mode));
+ ASSERT (S_ISDIR (st2.st_mode));
+ ASSERT (SAME_INODE (st1, st2));
+
+ ASSERT (func (BASE "link2", &st1) == 0);
+ ASSERT (S_ISLNK (st1.st_mode));
+ errno = 0;
+ ASSERT (func (BASE "link2/", &st1) == -1);
+ ASSERT (errno == ENOTDIR);
+
+ ASSERT (func (BASE "link3", &st1) == 0);
+ ASSERT (S_ISLNK (st1.st_mode));
+ errno = 0;
+ ASSERT (func (BASE "link3/", &st1) == -1);
+ ASSERT (errno == ENOENT);
+
+ ASSERT (func (BASE "link4", &st1) == 0);
+ ASSERT (S_ISLNK (st1.st_mode));
+ errno = 0;
+ ASSERT (func (BASE "link4/", &st1) == -1);
+ ASSERT (errno == ELOOP);
+
+ /* Cleanup. */
+ ASSERT (unlink (BASE "file") == 0);
+ ASSERT (unlink (BASE "link1") == 0);
+ ASSERT (unlink (BASE "link2") == 0);
+ ASSERT (unlink (BASE "link3") == 0);
+ ASSERT (unlink (BASE "link4") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-malloca.c b/tests/gnu/test-malloca.c
new file mode 100755
index 00000000..14ef3a9d
--- /dev/null
+++ b/tests/gnu/test-malloca.c
@@ -0,0 +1,59 @@
+/* Test of safe automatic memory allocation.
+ Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005. */
+
+#include <config.h>
+
+#include "malloca.h"
+
+#include <stdlib.h>
+
+static void
+do_allocation (int n)
+{
+ void *ptr = malloca (n);
+ freea (ptr);
+ ptr = safe_alloca (n);
+}
+
+void (*func) (int) = do_allocation;
+
+int
+main ()
+{
+ int i;
+
+ /* Repeat a lot of times, to make sure there's no memory leak. */
+ for (i = 0; i < 50000; i++)
+ {
+ /* Try various values.
+ n = 0 gave a crash on Alpha with gcc-2.5.8.
+ Some versions of MacOS X have a stack size limit of 512 KB. */
+ func (34);
+ func (134);
+ func (399);
+ func (510823);
+ func (129321);
+ func (0);
+ func (4070);
+ func (4095);
+ func (1);
+ func (16582);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-math.c b/tests/gnu/test-math.c
new file mode 100755
index 00000000..f940a249
--- /dev/null
+++ b/tests/gnu/test-math.c
@@ -0,0 +1,53 @@
+/* Test of <math.h> substitute.
+ Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <math.h>
+
+#ifndef NAN
+# error NAN should be defined
+choke me
+#endif
+
+#if 0
+/* Check that NAN expands into a constant expression. */
+static float n = NAN;
+#endif
+
+/* Compare two numbers with ==.
+ This is a separate function because IRIX 6.5 "cc -O" miscompiles an
+ 'x == x' test. */
+static int
+numeric_equal (double x, double y)
+{
+ return x == y;
+}
+
+int
+main (void)
+{
+ double d = NAN;
+ double zero = 0.0;
+ if (numeric_equal (d, d))
+ return 1;
+ d = HUGE_VAL;
+ if (!numeric_equal (d, 1.0 / zero))
+ return 1;
+ return 0;
+}
diff --git a/tests/gnu/test-mbrtowc.c b/tests/gnu/test-mbrtowc.c
new file mode 100755
index 00000000..5477677c
--- /dev/null
+++ b/tests/gnu/test-mbrtowc.c
@@ -0,0 +1,323 @@
+/* Test of conversion of multibyte character to wide character.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <wchar.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (mbrtowc, size_t, (wchar_t *, char const *, size_t,
+ mbstate_t *));
+
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ mbstate_t state;
+ wchar_t wc;
+ size_t ret;
+
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ /* Test zero-length input. */
+ {
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "x", 0, &state);
+ /* gnulib's implementation returns (size_t)(-2).
+ The AIX 5.1 implementation returns (size_t)(-1).
+ glibc's implementation returns 0. */
+ ASSERT (ret == (size_t)(-2) || ret == (size_t)(-1) || ret == 0);
+ ASSERT (mbsinit (&state));
+ }
+
+ /* Test NUL byte input. */
+ {
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "", 1, &state);
+ ASSERT (ret == 0);
+ ASSERT (wc == 0);
+ ASSERT (mbsinit (&state));
+ ret = mbrtowc (NULL, "", 1, &state);
+ ASSERT (ret == 0);
+ ASSERT (mbsinit (&state));
+ }
+
+ /* Test single-byte input. */
+ {
+ int c;
+ char buf[1];
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ for (c = 0; c < 0x100; c++)
+ switch (c)
+ {
+ case '\t': case '\v': case '\f':
+ case ' ': case '!': case '"': case '#': case '%':
+ case '&': case '\'': case '(': case ')': case '*':
+ case '+': case ',': case '-': case '.': case '/':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case ':': case ';': case '<': case '=': case '>':
+ case '?':
+ case 'A': case 'B': case 'C': case 'D': case 'E':
+ case 'F': case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'P': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y':
+ case 'Z':
+ case '[': case '\\': case ']': case '^': case '_':
+ case 'a': case 'b': case 'c': case 'd': case 'e':
+ case 'f': case 'g': case 'h': case 'i': case 'j':
+ case 'k': case 'l': case 'm': case 'n': case 'o':
+ case 'p': case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x': case 'y':
+ case 'z': case '{': case '|': case '}': case '~':
+ /* c is in the ISO C "basic character set". */
+ buf[0] = c;
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, buf, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == c);
+ ASSERT (mbsinit (&state));
+ ret = mbrtowc (NULL, buf, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (mbsinit (&state));
+ break;
+ }
+ }
+
+ /* Test special calling convention, passing a NULL pointer. */
+ {
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, NULL, 5, &state);
+ ASSERT (ret == 0);
+ ASSERT (wc == (wchar_t) 0xBADFACE);
+ ASSERT (mbsinit (&state));
+ }
+
+ if (argc > 1)
+ switch (argv[1][0])
+ {
+ case '1':
+ /* Locale encoding is ISO-8859-1 or ISO-8859-15. */
+ {
+ char input[] = "B\374\337er"; /* "Büßer" */
+ memset (&state, '\0', sizeof (mbstate_t));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'B');
+ ASSERT (mbsinit (&state));
+ input[0] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 1, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wctob (wc) == (unsigned char) '\374');
+ ASSERT (mbsinit (&state));
+ input[1] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 2, 3, &state);
+ ASSERT (ret == 1);
+ ASSERT (wctob (wc) == (unsigned char) '\337');
+ ASSERT (mbsinit (&state));
+ input[2] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 3, 2, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'e');
+ ASSERT (mbsinit (&state));
+ input[3] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 4, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'r');
+ ASSERT (mbsinit (&state));
+ }
+ return 0;
+
+ case '2':
+ /* Locale encoding is UTF-8. */
+ {
+ char input[] = "B\303\274\303\237er"; /* "Büßer" */
+ memset (&state, '\0', sizeof (mbstate_t));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'B');
+ ASSERT (mbsinit (&state));
+ input[0] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 1, 1, &state);
+ ASSERT (ret == (size_t)(-2));
+ ASSERT (wc == (wchar_t) 0xBADFACE);
+ ASSERT (!mbsinit (&state));
+ input[1] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 2, 5, &state);
+ ASSERT (ret == 1);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (mbsinit (&state));
+ input[2] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 3, 4, &state);
+ ASSERT (ret == 2);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (mbsinit (&state));
+ input[3] = '\0';
+ input[4] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 5, 2, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'e');
+ ASSERT (mbsinit (&state));
+ input[5] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 6, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'r');
+ ASSERT (mbsinit (&state));
+ }
+ return 0;
+
+ case '3':
+ /* Locale encoding is EUC-JP. */
+ {
+ char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */
+ memset (&state, '\0', sizeof (mbstate_t));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == '<');
+ ASSERT (mbsinit (&state));
+ input[0] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 1, 2, &state);
+ ASSERT (ret == 2);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (mbsinit (&state));
+ input[1] = '\0';
+ input[2] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 3, 1, &state);
+ ASSERT (ret == (size_t)(-2));
+ ASSERT (wc == (wchar_t) 0xBADFACE);
+ ASSERT (!mbsinit (&state));
+ input[3] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 4, 4, &state);
+ ASSERT (ret == 1);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (mbsinit (&state));
+ input[4] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 5, 3, &state);
+ ASSERT (ret == 2);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (mbsinit (&state));
+ input[5] = '\0';
+ input[6] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 7, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == '>');
+ ASSERT (mbsinit (&state));
+ }
+ return 0;
+
+ case '4':
+ /* Locale encoding is GB18030. */
+ {
+ char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
+ memset (&state, '\0', sizeof (mbstate_t));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'B');
+ ASSERT (mbsinit (&state));
+ input[0] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 1, 1, &state);
+ ASSERT (ret == (size_t)(-2));
+ ASSERT (wc == (wchar_t) 0xBADFACE);
+ ASSERT (!mbsinit (&state));
+ input[1] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 2, 7, &state);
+ ASSERT (ret == 1);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (mbsinit (&state));
+ input[2] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 3, 6, &state);
+ ASSERT (ret == 4);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (mbsinit (&state));
+ input[3] = '\0';
+ input[4] = '\0';
+ input[5] = '\0';
+ input[6] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 7, 2, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'e');
+ ASSERT (mbsinit (&state));
+ input[5] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 8, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'r');
+ ASSERT (mbsinit (&state));
+ }
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/tests/gnu/test-mbrtowc1.sh b/tests/gnu/test-mbrtowc1.sh
new file mode 100755
index 00000000..3becba3a
--- /dev/null
+++ b/tests/gnu/test-mbrtowc1.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test in an ISO-8859-1 or ISO-8859-15 locale.
+: ${LOCALE_FR=fr_FR}
+if test $LOCALE_FR = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no traditional french locale is installed"
+ else
+ echo "Skipping test: no traditional french locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_FR \
+./test-mbrtowc${EXEEXT} 1
diff --git a/tests/gnu/test-mbrtowc2.sh b/tests/gnu/test-mbrtowc2.sh
new file mode 100755
index 00000000..0405abaf
--- /dev/null
+++ b/tests/gnu/test-mbrtowc2.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test whether a specific UTF-8 locale is installed.
+: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
+if test $LOCALE_FR_UTF8 = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no french Unicode locale is installed"
+ else
+ echo "Skipping test: no french Unicode locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_FR_UTF8 \
+./test-mbrtowc${EXEEXT} 2
diff --git a/tests/gnu/test-mbrtowc3.sh b/tests/gnu/test-mbrtowc3.sh
new file mode 100755
index 00000000..63a89a2e
--- /dev/null
+++ b/tests/gnu/test-mbrtowc3.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test whether a specific EUC-JP locale is installed.
+: ${LOCALE_JA=ja_JP}
+if test $LOCALE_JA = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no traditional japanese locale is installed"
+ else
+ echo "Skipping test: no traditional japanese locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_JA \
+./test-mbrtowc${EXEEXT} 3
diff --git a/tests/gnu/test-mbrtowc4.sh b/tests/gnu/test-mbrtowc4.sh
new file mode 100755
index 00000000..b299a2c4
--- /dev/null
+++ b/tests/gnu/test-mbrtowc4.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test whether a specific GB18030 locale is installed.
+: ${LOCALE_ZH_CN=zh_CN.GB18030}
+if test $LOCALE_ZH_CN = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no transitional chinese locale is installed"
+ else
+ echo "Skipping test: no transitional chinese locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_ZH_CN \
+./test-mbrtowc${EXEEXT} 4
diff --git a/tests/gnu/test-mbsinit.c b/tests/gnu/test-mbsinit.c
new file mode 100755
index 00000000..4ca0fc37
--- /dev/null
+++ b/tests/gnu/test-mbsinit.c
@@ -0,0 +1,53 @@
+/* Test of test for initial conversion state.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <wchar.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (mbsinit, int, (const mbstate_t *));
+
+#include <locale.h>
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ static mbstate_t state;
+
+ ASSERT (mbsinit (&state));
+
+ if (argc > 1)
+ {
+ static const char input[1] = "\303";
+ wchar_t wc;
+ size_t ret;
+
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ ret = mbrtowc (&wc, input, 1, &state);
+ ASSERT (ret == (size_t)(-2));
+ ASSERT (!mbsinit (&state));
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-mbsinit.sh b/tests/gnu/test-mbsinit.sh
new file mode 100755
index 00000000..bbda48d2
--- /dev/null
+++ b/tests/gnu/test-mbsinit.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test whether a specific UTF-8 locale is installed.
+: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
+if test $LOCALE_FR_UTF8 = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no french Unicode locale is installed"
+ else
+ echo "Skipping test: no french Unicode locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_FR_UTF8 \
+./test-mbsinit${EXEEXT}
diff --git a/tests/gnu/test-mbsstr1.c b/tests/gnu/test-mbsstr1.c
new file mode 100755
index 00000000..e9fb50ea
--- /dev/null
+++ b/tests/gnu/test-mbsstr1.c
@@ -0,0 +1,128 @@
+/* Test of searching in a string.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <stdlib.h>
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* This test is executed in the C locale. */
+
+ {
+ const char input[] = "foo";
+ const char *result = mbsstr (input, "");
+ ASSERT (result == input);
+ }
+
+ {
+ const char input[] = "foo";
+ const char *result = mbsstr (input, "o");
+ ASSERT (result == input + 1);
+ }
+
+ {
+ const char input[] = "ABC ABCDAB ABCDABCDABDE";
+ const char *result = mbsstr (input, "ABCDABD");
+ ASSERT (result == input + 15);
+ }
+
+ {
+ const char input[] = "ABC ABCDAB ABCDABCDABDE";
+ const char *result = mbsstr (input, "ABCDABE");
+ ASSERT (result == NULL);
+ }
+
+ /* Check that a very long haystack is handled quickly if the needle is
+ short and occurs near the beginning. */
+ {
+ size_t repeat = 10000;
+ size_t m = 1000000;
+ char *needle =
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ char *haystack = (char *) malloc (m + 1);
+ if (haystack != NULL)
+ {
+ memset (haystack, 'A', m);
+ haystack[0] = 'B';
+ haystack[m] = '\0';
+
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (mbsstr (haystack, needle) == haystack + 1);
+ }
+
+ free (haystack);
+ }
+ }
+
+ /* Check that a very long needle is discarded quickly if the haystack is
+ short. */
+ {
+ size_t repeat = 10000;
+ size_t m = 1000000;
+ char *haystack =
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB";
+ char *needle = (char *) malloc (m + 1);
+ if (needle != NULL)
+ {
+ memset (needle, 'A', m);
+ needle[m] = '\0';
+
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (mbsstr (haystack, needle) == NULL);
+ }
+
+ free (needle);
+ }
+ }
+
+ /* Check that the asymptotic worst-case complexity is not quadratic. */
+ {
+ size_t m = 1000000;
+ char *haystack = (char *) malloc (2 * m + 2);
+ char *needle = (char *) malloc (m + 2);
+ if (haystack != NULL && needle != NULL)
+ {
+ const char *result;
+
+ memset (haystack, 'A', 2 * m);
+ haystack[2 * m] = 'B';
+ haystack[2 * m + 1] = '\0';
+
+ memset (needle, 'A', m);
+ needle[m] = 'B';
+ needle[m + 1] = '\0';
+
+ result = mbsstr (haystack, needle);
+ ASSERT (result == haystack + m);
+ }
+ free (needle);
+ free (haystack);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-mbsstr2.c b/tests/gnu/test-mbsstr2.c
new file mode 100755
index 00000000..488b2108
--- /dev/null
+++ b/tests/gnu/test-mbsstr2.c
@@ -0,0 +1,141 @@
+/* Test of searching in a string.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <locale.h>
+#include <stdlib.h>
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ {
+ const char input[] = "f\303\266\303\266";
+ const char *result = mbsstr (input, "");
+ ASSERT (result == input);
+ }
+
+ {
+ const char input[] = "f\303\266\303\266";
+ const char *result = mbsstr (input, "\303\266");
+ ASSERT (result == input + 1);
+ }
+
+ {
+ const char input[] = "f\303\266\303\266";
+ const char *result = mbsstr (input, "\266\303");
+ ASSERT (result == NULL);
+ }
+
+ {
+ const char input[] = "\303\204BC \303\204BCD\303\204B \303\204BCD\303\204BCD\303\204BDE"; /* "ÄBC ÄBCDÄB ÄBCDÄBCDÄBDE" */
+ const char *result = mbsstr (input, "\303\204BCD\303\204BD"); /* "ÄBCDÄBD" */
+ ASSERT (result == input + 19);
+ }
+
+ {
+ const char input[] = "\303\204BC \303\204BCD\303\204B \303\204BCD\303\204BCD\303\204BDE"; /* "ÄBC ÄBCDÄB ÄBCDÄBCDÄBDE" */
+ const char *result = mbsstr (input, "\303\204BCD\303\204BE"); /* "ÄBCDÄBE" */
+ ASSERT (result == NULL);
+ }
+
+ /* Check that a very long haystack is handled quickly if the needle is
+ short and occurs near the beginning. */
+ {
+ size_t repeat = 10000;
+ size_t m = 1000000;
+ char *needle =
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ char *haystack = (char *) malloc (m + 1);
+ if (haystack != NULL)
+ {
+ memset (haystack, 'A', m);
+ haystack[0] = '\303'; haystack[1] = '\204';
+ haystack[m] = '\0';
+
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (mbsstr (haystack, needle) == haystack + 2);
+ }
+
+ free (haystack);
+ }
+ }
+
+ /* Check that a very long needle is discarded quickly if the haystack is
+ short. */
+ {
+ size_t repeat = 10000;
+ size_t m = 1000000;
+ char *haystack =
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207"
+ "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207"
+ "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207"
+ "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207"
+ "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207";
+ char *needle = (char *) malloc (m + 1);
+ if (needle != NULL)
+ {
+ memset (needle, 'A', m);
+ needle[m] = '\0';
+
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (mbsstr (haystack, needle) == NULL);
+ }
+
+ free (needle);
+ }
+ }
+
+ /* Check that the asymptotic worst-case complexity is not quadratic. */
+ {
+ size_t m = 1000000;
+ char *haystack = (char *) malloc (2 * m + 3);
+ char *needle = (char *) malloc (m + 3);
+ if (haystack != NULL && needle != NULL)
+ {
+ const char *result;
+
+ memset (haystack, 'A', 2 * m);
+ haystack[2 * m] = '\303'; haystack[2 * m + 1] = '\207';
+ haystack[2 * m + 2] = '\0';
+
+ memset (needle, 'A', m);
+ needle[m] = '\303'; needle[m + 1] = '\207';
+ needle[m + 2] = '\0';
+
+ result = mbsstr (haystack, needle);
+ ASSERT (result == haystack + m);
+ }
+ free (needle);
+ free (haystack);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-mbsstr2.sh b/tests/gnu/test-mbsstr2.sh
new file mode 100755
index 00000000..79d06df6
--- /dev/null
+++ b/tests/gnu/test-mbsstr2.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test whether a specific UTF-8 locale is installed.
+: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
+if test $LOCALE_FR_UTF8 = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no french Unicode locale is installed"
+ else
+ echo "Skipping test: no french Unicode locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_FR_UTF8 \
+./test-mbsstr2${EXEEXT}
diff --git a/tests/gnu/test-mbsstr3.c b/tests/gnu/test-mbsstr3.c
new file mode 100755
index 00000000..a1479be4
--- /dev/null
+++ b/tests/gnu/test-mbsstr3.c
@@ -0,0 +1,81 @@
+/* Test of searching in a string.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <locale.h>
+
+#include "macros.h"
+
+int
+main ()
+{
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ /* Tests with a character < 0x30. */
+ {
+ const char input[] = "\312\276\300\375 \312\276\300\375 \312\276\300\375"; /* "示例 示例 示例" */
+ const char *result = mbsstr (input, " ");
+ ASSERT (result == input + 4);
+ }
+
+ {
+ const char input[] = "\312\276\300\375"; /* "示例" */
+ const char *result = mbsstr (input, " ");
+ ASSERT (result == NULL);
+ }
+
+ /* Tests with a character >= 0x30. */
+ {
+ const char input[] = "\272\305123\324\313\320\320\241\243"; /* "号123运行。" */
+ const char *result = mbsstr (input, "2");
+ ASSERT (result == input + 3);
+ }
+
+ /* The following tests show how mbsstr() is different from strstr(). */
+
+ {
+ const char input[] = "\313\320\320\320"; /* "诵行" */
+ const char *result = mbsstr (input, "\320\320"); /* "行" */
+ ASSERT (result == input + 2);
+ }
+
+ {
+ const char input[] = "\203\062\332\066123\324\313\320\320\241\243"; /* "씋123运行。" */
+ const char *result = mbsstr (input, "2");
+ ASSERT (result == input + 5);
+ }
+
+ {
+ const char input[] = "\312\276\300\375 \312\276\300\375 \312\276\300\375"; /* "示例 示例 示例" */
+ const char *result = mbsstr (input, "\276\300"); /* "纠" */
+ ASSERT (result == NULL);
+ }
+
+ {
+ const char input[] = "\312\276\300\375 \312\276\300\375 \312\276\300\375"; /* "示例 示例 示例" */
+ const char *result = mbsstr (input, "\375 "); /* invalid multibyte sequence */
+ ASSERT (result == NULL);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-mbsstr3.sh b/tests/gnu/test-mbsstr3.sh
new file mode 100755
index 00000000..732c01fd
--- /dev/null
+++ b/tests/gnu/test-mbsstr3.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test whether a specific GB18030 locale is installed.
+: ${LOCALE_ZH_CN=zh_CN.GB18030}
+if test $LOCALE_ZH_CN = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no chinese GB18030 locale is installed"
+ else
+ echo "Skipping test: no chinese GB18030 locale is supported"
+ fi
+ exit 77
+fi
+
+LC_ALL=$LOCALE_ZH_CN \
+./test-mbsstr3${EXEEXT}
diff --git a/tests/gnu/test-memchr.c b/tests/gnu/test-memchr.c
new file mode 100755
index 00000000..a8016140
--- /dev/null
+++ b/tests/gnu/test-memchr.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2008-2010 Free Software Foundation, Inc.
+ * Written by Eric Blake and Bruno Haible
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (memchr, void *, (void const *, int, size_t));
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+/* Calculating void * + int is not portable, so this wrapper converts
+ to char * to make the tests easier to write. */
+#define MEMCHR (char *) memchr
+
+int
+main (void)
+{
+ size_t n = 0x100000;
+ char *input = malloc (n);
+ ASSERT (input);
+
+ input[0] = 'a';
+ input[1] = 'b';
+ memset (input + 2, 'c', 1024);
+ memset (input + 1026, 'd', n - 1028);
+ input[n - 2] = 'e';
+ input[n - 1] = 'a';
+
+ /* Basic behavior tests. */
+ ASSERT (MEMCHR (input, 'a', n) == input);
+
+ ASSERT (MEMCHR (input, 'a', 0) == NULL);
+ ASSERT (MEMCHR (zerosize_ptr (), 'a', 0) == NULL);
+
+ ASSERT (MEMCHR (input, 'b', n) == input + 1);
+ ASSERT (MEMCHR (input, 'c', n) == input + 2);
+ ASSERT (MEMCHR (input, 'd', n) == input + 1026);
+
+ ASSERT (MEMCHR (input + 1, 'a', n - 1) == input + n - 1);
+ ASSERT (MEMCHR (input + 1, 'e', n - 1) == input + n - 2);
+
+ ASSERT (MEMCHR (input, 'f', n) == NULL);
+ ASSERT (MEMCHR (input, '\0', n) == NULL);
+
+ /* Check that a very long haystack is handled quickly if the byte is
+ found near the beginning. */
+ {
+ size_t repeat = 10000;
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (MEMCHR (input, 'c', n) == input + 2);
+ }
+ }
+
+ /* Alignment tests. */
+ {
+ int i, j;
+ for (i = 0; i < 32; i++)
+ {
+ for (j = 0; j < 256; j++)
+ input[i + j] = j;
+ for (j = 0; j < 256; j++)
+ {
+ ASSERT (MEMCHR (input + i, j, 256) == input + i + j);
+ }
+ }
+ }
+
+ /* Check that memchr() does not read past the first occurrence of the
+ byte being searched. See the Austin Group's clarification
+ <http://www.opengroup.org/austin/docs/austin_454.txt>. */
+ {
+ char *page_boundary = (char *) zerosize_ptr ();
+
+ if (page_boundary != NULL)
+ {
+ for (n = 1; n <= 500; n++)
+ {
+ char *mem = page_boundary - n;
+ memset (mem, 'X', n);
+ ASSERT (MEMCHR (mem, 'U', n) == NULL);
+
+ {
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ {
+ mem[i] = 'U';
+ ASSERT (MEMCHR (mem, 'U', 4000) == mem + i);
+ mem[i] = 'X';
+ }
+ }
+ }
+ }
+ }
+
+ free (input);
+
+ return 0;
+}
diff --git a/tests/gnu/test-memchr2.c b/tests/gnu/test-memchr2.c
new file mode 100755
index 00000000..bb81c0b4
--- /dev/null
+++ b/tests/gnu/test-memchr2.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008-2010 Free Software Foundation, Inc.
+ * Written by Eric Blake
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "memchr2.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+/* Calculating void * + int is not portable, so this wrapper converts
+ to char * to make the tests easier to write. */
+#define MEMCHR2 (char *) memchr2
+
+int
+main (void)
+{
+ size_t n = 0x100000;
+ char *input = malloc (n);
+ ASSERT (input);
+
+ input[0] = 'a';
+ input[1] = 'b';
+ memset (input + 2, 'c', 1024);
+ memset (input + 1026, 'd', n - 1028);
+ input[n - 2] = 'e';
+ input[n - 1] = 'a';
+
+ /* Basic behavior tests. */
+ ASSERT (MEMCHR2 (input, 'a', 'b', n) == input);
+ ASSERT (MEMCHR2 (input, 'b', 'a', n) == input);
+
+ ASSERT (MEMCHR2 (input, 'a', 'b', 0) == NULL);
+ ASSERT (MEMCHR2 (zerosize_ptr (), 'a', 'b', 0) == NULL);
+
+ ASSERT (MEMCHR2 (input, 'b', 'd', n) == input + 1);
+ ASSERT (MEMCHR2 (input + 2, 'b', 'd', n - 2) == input + 1026);
+
+ ASSERT (MEMCHR2 (input, 'd', 'e', n) == input + 1026);
+ ASSERT (MEMCHR2 (input, 'e', 'd', n) == input + 1026);
+
+ ASSERT (MEMCHR2 (input + 1, 'a', 'e', n - 1) == input + n - 2);
+ ASSERT (MEMCHR2 (input + 1, 'e', 'a', n - 1) == input + n - 2);
+
+ ASSERT (MEMCHR2 (input, 'f', 'g', n) == NULL);
+ ASSERT (MEMCHR2 (input, 'f', '\0', n) == NULL);
+
+ ASSERT (MEMCHR2 (input, 'a', 'a', n) == input);
+ ASSERT (MEMCHR2 (input + 1, 'a', 'a', n - 1) == input + n - 1);
+ ASSERT (MEMCHR2 (input, 'f', 'f', n) == NULL);
+
+ /* Check that a very long haystack is handled quickly if one of the
+ two bytes is found near the beginning. */
+ {
+ size_t repeat = 10000;
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (MEMCHR2 (input, 'c', 'e', n) == input + 2);
+ ASSERT (MEMCHR2 (input, 'e', 'c', n) == input + 2);
+ ASSERT (MEMCHR2 (input, 'c', '\0', n) == input + 2);
+ ASSERT (MEMCHR2 (input, '\0', 'c', n) == input + 2);
+ }
+ }
+
+ /* Alignment tests. */
+ {
+ int i, j;
+ for (i = 0; i < 32; i++)
+ {
+ for (j = 0; j < 256; j++)
+ input[i + j] = j;
+ for (j = 0; j < 256; j++)
+ {
+ ASSERT (MEMCHR2 (input + i, j, 0xff, 256) == input + i + j);
+ ASSERT (MEMCHR2 (input + i, 0xff, j, 256) == input + i + j);
+ }
+ }
+ }
+
+ free (input);
+
+ return 0;
+}
diff --git a/tests/gnu/test-memmem.c b/tests/gnu/test-memmem.c
new file mode 100755
index 00000000..a9d3558c
--- /dev/null
+++ b/tests/gnu/test-memmem.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2004, 2007-2010 Free Software Foundation, Inc.
+ * Written by Bruno Haible and Eric Blake
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (memmem, void *, (void const *, size_t, void const *, size_t));
+
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+static void *
+null_ptr (void)
+{
+ return NULL;
+}
+
+int
+main (int argc, char *argv[])
+{
+#if HAVE_DECL_ALARM
+ /* Declare failure if test takes too long, by using default abort
+ caused by SIGALRM. All known platforms that lack alarm also lack
+ memmem, and the replacement memmem is known to not take too
+ long. */
+ signal (SIGALRM, SIG_DFL);
+ alarm (100);
+#endif
+
+ {
+ const char input[] = "foo";
+ const char *result = memmem (input, strlen (input), "", 0);
+ ASSERT (result == input);
+ }
+
+ {
+ const char input[] = "foo";
+ const char *result = memmem (input, strlen (input), "o", 1);
+ ASSERT (result == input + 1);
+ }
+
+ {
+ const char input[] = "ABC ABCDAB ABCDABCDABDE";
+ const char *result = memmem (input, strlen (input), "ABCDABD", 7);
+ ASSERT (result == input + 15);
+ }
+
+ {
+ const char input[] = "ABC ABCDAB ABCDABCDABDE";
+ const char *result = memmem (input, strlen (input), "ABCDABE", 7);
+ ASSERT (result == NULL);
+ }
+
+ {
+ const char input[] = "ABC ABCDAB ABCDABCDABDE";
+ const char *result = memmem (input, strlen (input), "ABCDABCD", 8);
+ ASSERT (result == input + 11);
+ }
+
+ /* Check that length 0 does not dereference the pointer. */
+ {
+ const char *result = memmem (zerosize_ptr (), 0, "foo", 3);
+ ASSERT (result == NULL);
+ }
+
+ {
+ const char input[] = "foo";
+ const char *result = memmem (input, strlen (input), null_ptr (), 0);
+ ASSERT (result == input);
+ }
+
+ /* Check that a very long haystack is handled quickly if the needle is
+ short and occurs near the beginning. */
+ {
+ size_t repeat = 10000;
+ size_t m = 1000000;
+ char *needle =
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ size_t n = strlen (needle);
+ char *haystack = (char *) malloc (m + 1);
+ if (haystack != NULL)
+ {
+ memset (haystack, 'A', m);
+ haystack[0] = 'B';
+
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (memmem (haystack, m, needle, n) == haystack + 1);
+ }
+
+ free (haystack);
+ }
+ }
+
+ /* Check that a very long needle is discarded quickly if the haystack is
+ short. */
+ {
+ size_t repeat = 10000;
+ size_t m = 1000000;
+ char *haystack =
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB";
+ size_t n = strlen (haystack);
+ char *needle = (char *) malloc (m + 1);
+ if (needle != NULL)
+ {
+ memset (needle, 'A', m);
+
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (memmem (haystack, n, needle, m) == NULL);
+ }
+
+ free (needle);
+ }
+ }
+
+ /* Check that the asymptotic worst-case complexity is not quadratic. */
+ {
+ size_t m = 1000000;
+ char *haystack = (char *) malloc (2 * m + 1);
+ char *needle = (char *) malloc (m + 1);
+ if (haystack != NULL && needle != NULL)
+ {
+ const char *result;
+
+ memset (haystack, 'A', 2 * m);
+ haystack[2 * m] = 'B';
+
+ memset (needle, 'A', m);
+ needle[m] = 'B';
+
+ result = memmem (haystack, 2 * m + 1, needle, m + 1);
+ ASSERT (result == haystack + m);
+ }
+ free (needle);
+ free (haystack);
+ }
+
+ /* Check that long needles not present in a haystack can be handled
+ with sublinear speed. */
+ {
+ size_t repeat = 10000;
+ size_t m = 1000000;
+ size_t n = 1000;
+ char *haystack = (char *) malloc (m);
+ char *needle = (char *) malloc (n);
+ if (haystack != NULL && needle != NULL)
+ {
+ const char *result;
+
+ memset (haystack, 'A', m);
+ memset (needle, 'B', n);
+
+ for (; repeat > 0; repeat--)
+ {
+ result = memmem (haystack, m, needle, n);
+ ASSERT (result == NULL);
+ }
+ }
+ free (haystack);
+ free (needle);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-nl_langinfo.c b/tests/gnu/test-nl_langinfo.c
new file mode 100755
index 00000000..ec89b3f7
--- /dev/null
+++ b/tests/gnu/test-nl_langinfo.c
@@ -0,0 +1,115 @@
+/* Test of nl_langinfo replacement.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2009. */
+
+#include <config.h>
+
+#include <langinfo.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (nl_langinfo, char *, (nl_item));
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "c-strcase.h"
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ int pass = atoi (argv[1]);
+ /* pass locale
+ 0 C
+ 1 traditional French locale
+ 2 French UTF-8 locale
+ */
+
+ setlocale (LC_ALL, "");
+
+ /* nl_langinfo items of the LC_CTYPE category */
+ ASSERT (strlen (nl_langinfo (CODESET)) > 0);
+ if (pass == 2)
+ {
+ const char *codeset = nl_langinfo (CODESET);
+ ASSERT (c_strcasecmp (codeset, "UTF-8") == 0 || c_strcasecmp (codeset, "UTF8") == 0);
+ }
+ /* nl_langinfo items of the LC_NUMERIC category */
+ ASSERT (strlen (nl_langinfo (RADIXCHAR)) > 0);
+ ASSERT (strlen (nl_langinfo (THOUSEP)) >= 0);
+ /* nl_langinfo items of the LC_TIME category */
+ ASSERT (strlen (nl_langinfo (D_T_FMT)) > 0);
+ ASSERT (strlen (nl_langinfo (D_FMT)) > 0);
+ ASSERT (strlen (nl_langinfo (T_FMT)) > 0);
+ ASSERT (strlen (nl_langinfo (T_FMT_AMPM)) >= (pass == 0 ? 1 : 0));
+ ASSERT (strlen (nl_langinfo (AM_STR)) >= (pass == 0 ? 1 : 0));
+ ASSERT (strlen (nl_langinfo (PM_STR)) >= (pass == 0 ? 1 : 0));
+ ASSERT (strlen (nl_langinfo (DAY_1)) > 0);
+ ASSERT (strlen (nl_langinfo (DAY_2)) > 0);
+ ASSERT (strlen (nl_langinfo (DAY_3)) > 0);
+ ASSERT (strlen (nl_langinfo (DAY_4)) > 0);
+ ASSERT (strlen (nl_langinfo (DAY_5)) > 0);
+ ASSERT (strlen (nl_langinfo (DAY_6)) > 0);
+ ASSERT (strlen (nl_langinfo (DAY_7)) > 0);
+ ASSERT (strlen (nl_langinfo (ABDAY_1)) > 0);
+ ASSERT (strlen (nl_langinfo (ABDAY_2)) > 0);
+ ASSERT (strlen (nl_langinfo (ABDAY_3)) > 0);
+ ASSERT (strlen (nl_langinfo (ABDAY_4)) > 0);
+ ASSERT (strlen (nl_langinfo (ABDAY_5)) > 0);
+ ASSERT (strlen (nl_langinfo (ABDAY_6)) > 0);
+ ASSERT (strlen (nl_langinfo (ABDAY_7)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_1)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_2)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_3)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_4)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_5)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_6)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_7)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_8)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_9)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_10)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_11)) > 0);
+ ASSERT (strlen (nl_langinfo (MON_12)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_1)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_2)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_3)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_4)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_5)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_6)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_7)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_8)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_9)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_10)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_11)) > 0);
+ ASSERT (strlen (nl_langinfo (ABMON_12)) > 0);
+ ASSERT (strlen (nl_langinfo (ERA)) >= 0);
+ ASSERT (strlen (nl_langinfo (ERA_D_FMT)) >= 0);
+ ASSERT (strlen (nl_langinfo (ERA_D_T_FMT)) >= 0);
+ ASSERT (strlen (nl_langinfo (ERA_T_FMT)) >= 0);
+ ASSERT (nl_langinfo (ALT_DIGITS) != NULL);
+ /* nl_langinfo items of the LC_MONETARY category */
+ {
+ const char *currency = nl_langinfo (CRNCYSTR);
+ ASSERT (strlen (currency) >= (pass > 0 ? 1 : 0));
+ }
+ /* nl_langinfo items of the LC_MESSAGES category */
+ ASSERT (strlen (nl_langinfo (YESEXPR)) > 0);
+ ASSERT (strlen (nl_langinfo (NOEXPR)) > 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-nl_langinfo.sh b/tests/gnu/test-nl_langinfo.sh
new file mode 100755
index 00000000..3168f426
--- /dev/null
+++ b/tests/gnu/test-nl_langinfo.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+LC_ALL=C ./test-nl_langinfo${EXEEXT} 0 || exit 1
+
+# Test whether a specific traditional locale is installed.
+: ${LOCALE_FR=fr_FR}
+if test $LOCALE_FR != none; then
+ LC_ALL=$LOCALE_FR ./test-nl_langinfo${EXEEXT} 1 || exit 1
+fi
+
+# Test whether a specific UTF-8 locale is installed.
+: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
+if test $LOCALE_FR_UTF8 != none; then
+ LC_ALL=$LOCALE_FR_UTF8 ./test-nl_langinfo${EXEEXT} 2 || exit 1
+fi
+
+exit 0
diff --git a/tests/gnu/test-obstack-printf.c b/tests/gnu/test-obstack-printf.c
new file mode 100755
index 00000000..6d2aceca
--- /dev/null
+++ b/tests/gnu/test-obstack-printf.c
@@ -0,0 +1,138 @@
+/* Test of obstack_printf() and obstack_vprintf() functions.
+ Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2008. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (obstack_printf, int, (struct obstack *, char const *, ...));
+SIGNATURE_CHECK (obstack_vprintf, int, (struct obstack *, char const *,
+ va_list));
+
+#include "obstack.h"
+#include "xalloc.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "progname.h"
+#include "macros.h"
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
+static void
+test_function (int (*my_obstack_printf) (struct obstack *, const char *, ...))
+{
+ struct obstack obs;
+ obstack_init (&obs);
+ /* In general, be careful that arguments to obstack_* don't have
+ side effects, as not all compilers evaluate macro arguments only
+ once. */
+
+ /* Grow the obstack to near its boundary, then check that short
+ output longer than the obstack free space grows the obstack. */
+ {
+ char *base = obstack_base (&obs);
+ char *new_base;
+ int result;
+ int room = obstack_room (&obs) - 4;
+
+ obstack_blank_fast (&obs, room);
+ result = my_obstack_printf (&obs, "%d %s", 123, "456");
+ ASSERT (result == 7);
+ ASSERT (result + room == obstack_object_size (&obs));
+ obstack_1grow (&obs, 0);
+ new_base = obstack_finish (&obs);
+ ASSERT (base != new_base);
+ ASSERT (strcmp (new_base + room, "123 456") == 0);
+ }
+
+ /* Check that strings shorter than the obstack free space don't
+ cause a reshuffling of the obstack. */
+ {
+ char *base = obstack_base (&obs);
+ char *new_base;
+ int result;
+ int room = obstack_room (&obs);
+
+ ASSERT (8 < room);
+ result = my_obstack_printf (&obs, "%d %s", 123, "456");
+ ASSERT (result == 7);
+ ASSERT (result == obstack_object_size (&obs));
+ new_base = obstack_base (&obs);
+ ASSERT (base == new_base);
+ ASSERT (strncmp (base, "123 456", result) == 0);
+ obstack_finish (&obs);
+ }
+
+ /* Check for generating much more output than a chunk size. */
+ {
+ char *base = obstack_base (&obs);
+ char *new_base;
+ int result;
+ int i;
+
+ ASSERT (obstack_chunk_size (&obs) < 10000);
+ result = my_obstack_printf (&obs, "%010000d", 0);
+ ASSERT (result == 10000);
+ ASSERT (result == obstack_object_size (&obs));
+ new_base = obstack_base (&obs);
+ ASSERT (base != new_base);
+ for (i = 0; i < 10000; i++)
+ ASSERT (new_base[i] == '0');
+ }
+
+ obstack_free (&obs, NULL);
+}
+
+static int
+my_obstack_printf (struct obstack *obs, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = obstack_vprintf (obs, format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_obstack_vprintf ()
+{
+ test_function (my_obstack_printf);
+}
+
+static void
+test_obstack_printf ()
+{
+ test_function (obstack_printf);
+}
+
+int
+main (int argc, char *argv[])
+{
+ set_program_name (argv[0]);
+
+ test_obstack_vprintf ();
+ test_obstack_printf ();
+ return 0;
+}
diff --git a/tests/gnu/test-open.c b/tests/gnu/test-open.c
new file mode 100755
index 00000000..ae9b3aca
--- /dev/null
+++ b/tests/gnu/test-open.c
@@ -0,0 +1,41 @@
+/* Test of opening a file descriptor.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <fcntl.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (open, int, (char const *, int, ...));
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+#define BASE "test-open.t"
+
+#include "test-open.h"
+
+int
+main (void)
+{
+ return test_open (open, true);
+}
diff --git a/tests/gnu/test-open.h b/tests/gnu/test-open.h
new file mode 100755
index 00000000..6341a635
--- /dev/null
+++ b/tests/gnu/test-open.h
@@ -0,0 +1,87 @@
+/* Test of opening a file descriptor.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+/* This file is designed to test both open(n,buf[,mode]) and
+ openat(AT_FDCWD,n,buf[,mode]). FUNC is the function to test.
+ Assumes that BASE and ASSERT are already defined, and that
+ appropriate headers are already included. If PRINT, warn before
+ skipping symlink tests with status 77. */
+
+static int
+test_open (int (*func) (char const *, int, ...), bool print)
+{
+ int fd;
+ /* Remove anything from prior partial run. */
+ unlink (BASE "file");
+
+ /* Cannot create directory. */
+ errno = 0;
+ ASSERT (func ("nonexist.ent/", O_CREAT | O_RDONLY, 0600) == -1);
+ ASSERT (errno == ENOTDIR || errno == EISDIR || errno == ENOENT
+ || errno == EINVAL);
+
+ /* Create a regular file. */
+ fd = func (BASE "file", O_CREAT | O_RDONLY, 0600);
+ ASSERT (0 <= fd);
+ ASSERT (close (fd) == 0);
+
+ /* Trailing slash handling. */
+ errno = 0;
+ ASSERT (func (BASE "file/", O_RDONLY) == -1);
+ ASSERT (errno == ENOTDIR || errno == EISDIR || errno == EINVAL);
+
+ /* Directories cannot be opened for writing. */
+ errno = 0;
+ ASSERT (func (".", O_WRONLY) == -1);
+ ASSERT (errno == EISDIR || errno == EACCES);
+
+ /* /dev/null must exist, and be writable. */
+ fd = func ("/dev/null", O_RDONLY);
+ ASSERT (0 <= fd);
+ {
+ char c;
+ ASSERT (read (fd, &c, 1) == 0);
+ }
+ ASSERT (close (fd) == 0);
+ fd = func ("/dev/null", O_WRONLY);
+ ASSERT (0 <= fd);
+ ASSERT (write (fd, "c", 1) == 1);
+ ASSERT (close (fd) == 0);
+
+ /* Symlink handling, where supported. */
+ if (symlink (BASE "file", BASE "link") != 0)
+ {
+ ASSERT (unlink (BASE "file") == 0);
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+ errno = 0;
+ ASSERT (func (BASE "link/", O_RDONLY) == -1);
+ ASSERT (errno == ENOTDIR);
+ fd = func (BASE "link", O_RDONLY);
+ ASSERT (0 <= fd);
+ ASSERT (close (fd) == 0);
+
+ /* Cleanup. */
+ ASSERT (unlink (BASE "file") == 0);
+ ASSERT (unlink (BASE "link") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-pipe.c b/tests/gnu/test-pipe.c
new file mode 100755
index 00000000..2dcab58b
--- /dev/null
+++ b/tests/gnu/test-pipe.c
@@ -0,0 +1,204 @@
+/* Test of create_pipe_bidi/wait_subprocess.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+#include "pipe.h"
+#include "wait-process.h"
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Depending on arguments, this test intentionally closes stderr or
+ starts life with stderr closed. So, we arrange to have fd 10
+ (outside the range of interesting fd's during the test) set up to
+ duplicate the original stderr. */
+
+#define BACKUP_STDERR_FILENO 10
+#define ASSERT_STREAM myerr
+#include "macros.h"
+
+static FILE *myerr;
+
+/* Code executed by the child process. argv[1] = "child". */
+static int
+child_main (int argc, char *argv[])
+{
+ char buffer[2] = { 's', 't' };
+ int fd;
+ int ret;
+
+ ASSERT (argc == 3);
+
+ /* Read one byte from fd 0, and write its value plus one to fd 1.
+ fd 2 should be closed iff the argument is 1. Check that no other file
+ descriptors leaked. */
+
+ ASSERT (read (STDIN_FILENO, buffer, 2) == 1);
+
+ buffer[0]++;
+ ASSERT (write (STDOUT_FILENO, buffer, 1) == 1);
+
+ errno = 0;
+ ret = dup2 (STDERR_FILENO, STDERR_FILENO);
+ switch (atoi (argv[2]))
+ {
+ case 0:
+ /* Expect fd 2 is open. */
+ ASSERT (ret == STDERR_FILENO);
+ break;
+ case 1:
+ /* Expect fd 2 is closed. */
+ ASSERT (ret == -1);
+ ASSERT (errno == EBADF);
+ break;
+ default:
+ ASSERT (false);
+ }
+
+ for (fd = 3; fd < 7; fd++)
+ {
+ errno = 0;
+ ASSERT (close (fd) == -1);
+ ASSERT (errno == EBADF);
+ }
+
+ return 0;
+}
+
+/* Create a bi-directional pipe to a test child, and validate that the
+ child program returns the expected output. The child is the same
+ program as the parent ARGV0, but with different arguments.
+ STDERR_CLOSED is true if we have already closed fd 2. */
+static void
+test_pipe (const char *argv0, bool stderr_closed)
+{
+ int fd[2];
+ char *argv[4];
+ pid_t pid;
+ char buffer[2] = { 'a', 't' };
+
+ /* Set up child. */
+ argv[0] = (char *) argv0;
+ argv[1] = (char *) "child";
+ argv[2] = (char *) (stderr_closed ? "1" : "0");
+ argv[3] = NULL;
+ pid = create_pipe_bidi (argv0, argv0, argv, false, true, true, fd);
+ ASSERT (0 <= pid);
+ ASSERT (STDERR_FILENO < fd[0]);
+ ASSERT (STDERR_FILENO < fd[1]);
+
+ /* Push child's input. */
+ ASSERT (write (fd[1], buffer, 1) == 1);
+ ASSERT (close (fd[1]) == 0);
+
+ /* Get child's output. */
+ ASSERT (read (fd[0], buffer, 2) == 1);
+
+ /* Wait for child. */
+ ASSERT (wait_subprocess (pid, argv0, true, false, true, true, NULL) == 0);
+ ASSERT (close (fd[0]) == 0);
+
+ /* Check the result. */
+ ASSERT (buffer[0] == 'b');
+ ASSERT (buffer[1] == 't');
+}
+
+/* Code executed by the parent process. */
+static int
+parent_main (int argc, char *argv[])
+{
+ int test;
+ int fd;
+
+ ASSERT (argc == 2);
+
+ /* Selectively close various standard fds, to verify the child process is
+ not impacted by this. */
+ test = atoi (argv[1]);
+ switch (test)
+ {
+ case 0:
+ break;
+ case 1:
+ close (0);
+ break;
+ case 2:
+ close (1);
+ break;
+ case 3:
+ close (0);
+ close (1);
+ break;
+ case 4:
+ close (2);
+ break;
+ case 5:
+ close (0);
+ close (2);
+ break;
+ case 6:
+ close (1);
+ close (2);
+ break;
+ case 7:
+ close (0);
+ close (1);
+ close (2);
+ break;
+ default:
+ ASSERT (false);
+ }
+
+ /* Plug any file descriptor leaks inherited from outside world before
+ starting, so that child has a clean slate (at least for the fds that we
+ might be manipulating). */
+ for (fd = 3; fd < 7; fd++)
+ close (fd);
+
+ test_pipe (argv[0], test >= 4);
+
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf (stderr, "%s: need arguments\n", argv[0]);
+ return 2;
+ }
+ if (strcmp (argv[1], "child") == 0)
+ {
+ /* fd 2 might be closed, but fd BACKUP_STDERR_FILENO is the original
+ stderr. */
+ myerr = fdopen (BACKUP_STDERR_FILENO, "w");
+ if (!myerr)
+ return 2;
+ return child_main (argc, argv);
+ }
+ /* We might close fd 2 later, so save it in fd 10. */
+ if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
+ || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
+ return 2;
+ return parent_main (argc, argv);
+}
diff --git a/tests/gnu/test-pipe.sh b/tests/gnu/test-pipe.sh
new file mode 100755
index 00000000..323c90fb
--- /dev/null
+++ b/tests/gnu/test-pipe.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+st=0
+for i in 0 1 2 3 4 5 6 7 ; do
+ ./test-pipe${EXEEXT} $i \
+ || { echo test-pipe.sh: iteration $i failed >&2; st=1; }
+done
+exit $st
diff --git a/tests/gnu/test-pipe2.c b/tests/gnu/test-pipe2.c
new file mode 100755
index 00000000..bd6df7ce
--- /dev/null
+++ b/tests/gnu/test-pipe2.c
@@ -0,0 +1,145 @@
+/* Test of pipe2.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (pipe2, int, (int[2], int));
+
+#include <fcntl.h>
+#include <stdbool.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions. */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#include "binary-io.h"
+#include "macros.h"
+
+/* Return true if FD is open. */
+static bool
+is_open (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On Win32, the initial state of unassigned standard file
+ descriptors is that they are open but point to an
+ INVALID_HANDLE_VALUE, and there is no fcntl. */
+ return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
+#else
+# ifndef F_GETFL
+# error Please port fcntl to your platform
+# endif
+ return 0 <= fcntl (fd, F_GETFL);
+#endif
+}
+
+/* Return true if FD is not inherited to child processes. */
+static bool
+is_cloexec (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ DWORD flags;
+ ASSERT (GetHandleInformation (h, &flags));
+ return (flags & HANDLE_FLAG_INHERIT) == 0;
+#else
+ int flags;
+ ASSERT ((flags = fcntl (fd, F_GETFD)) >= 0);
+ return (flags & FD_CLOEXEC) != 0;
+#endif
+}
+
+/* Return true if FD is in non-blocking mode. */
+static bool
+is_nonblocking (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* We don't use the non-blocking mode for sockets here. */
+ return 0;
+#else
+ int flags;
+ ASSERT ((flags = fcntl (fd, F_GETFL)) >= 0);
+ return (flags & O_NONBLOCK) != 0;
+#endif
+}
+
+int
+main ()
+{
+ int use_nonblocking;
+ int use_cloexec;
+
+#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+ for (use_nonblocking = 0; use_nonblocking <= 1; use_nonblocking++)
+#else
+ use_nonblocking = 0;
+#endif
+#if defined O_CLOEXEC
+ for (use_cloexec = 0; use_cloexec <= 1; use_cloexec++)
+#else
+ use_cloexec = 0;
+#endif
+ {
+ int o_flags;
+ int fd[2];
+
+ o_flags = 0;
+#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+ if (use_nonblocking)
+ o_flags |= O_NONBLOCK;
+#endif
+#if defined O_CLOEXEC
+ if (use_cloexec)
+ o_flags |= O_CLOEXEC;
+#endif
+
+ fd[0] = -1;
+ fd[1] = -1;
+ ASSERT (pipe2 (fd, o_flags) >= 0);
+ ASSERT (fd[0] >= 0);
+ ASSERT (fd[1] >= 0);
+ ASSERT (fd[0] != fd[1]);
+ ASSERT (is_open (fd[0]) >= 0);
+ ASSERT (is_open (fd[1]) >= 0);
+ if (use_cloexec)
+ {
+ ASSERT (is_cloexec (fd[0]));
+ ASSERT (is_cloexec (fd[1]));
+ }
+ else
+ {
+ ASSERT (!is_cloexec (fd[0]));
+ ASSERT (!is_cloexec (fd[1]));
+ }
+ if (use_nonblocking)
+ {
+ ASSERT (is_nonblocking (fd[0]));
+ ASSERT (is_nonblocking (fd[1]));
+ }
+ else
+ {
+ ASSERT (!is_nonblocking (fd[0]));
+ ASSERT (!is_nonblocking (fd[1]));
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-posix_spawn1.c b/tests/gnu/test-posix_spawn1.c
new file mode 100755
index 00000000..659d76a1
--- /dev/null
+++ b/tests/gnu/test-posix_spawn1.c
@@ -0,0 +1,166 @@
+/* Test of posix_spawn() function.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <spawn.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (posix_spawnp, int, (pid_t *, char const *,
+ posix_spawn_file_actions_t const *,
+ posix_spawnattr_t const *,
+ char *const[], char *const[]));
+SIGNATURE_CHECK (posix_spawnattr_init, int, (posix_spawnattr_t *));
+SIGNATURE_CHECK (posix_spawnattr_destroy, int, (posix_spawnattr_t *));
+SIGNATURE_CHECK (posix_spawnattr_setsigmask, int, (posix_spawnattr_t *,
+ sigset_t const *));
+SIGNATURE_CHECK (posix_spawnattr_setflags, int, (posix_spawnattr_t *, short));
+SIGNATURE_CHECK (posix_spawn_file_actions_init, int,
+ (posix_spawn_file_actions_t *));
+SIGNATURE_CHECK (posix_spawn_file_actions_destroy, int,
+ (posix_spawn_file_actions_t *));
+SIGNATURE_CHECK (posix_spawn_file_actions_addclose, int,
+ (posix_spawn_file_actions_t *, int));
+SIGNATURE_CHECK (posix_spawn_file_actions_addopen, int,
+ (posix_spawn_file_actions_t *, int, char const *, int,
+ mode_t));
+SIGNATURE_CHECK (posix_spawn_file_actions_adddup2, int,
+ (posix_spawn_file_actions_t *, int, int));
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+extern char **environ;
+
+#define CHILD_PROGRAM_FILENAME "test-posix_spawn1.sh"
+
+static int
+fd_safer (int fd)
+{
+ if (0 <= fd && fd <= 2)
+ {
+ int f = fd_safer (dup (fd));
+ int e = errno;
+ close (fd);
+ errno = e;
+ fd = f;
+ }
+
+ return fd;
+}
+
+int
+main ()
+{
+ char *argv[3] = { "/bin/sh", CHILD_PROGRAM_FILENAME, NULL };
+ int ifd[2];
+ sigset_t blocked_signals;
+ sigset_t fatal_signal_set;
+ posix_spawn_file_actions_t actions;
+ bool actions_allocated;
+ posix_spawnattr_t attrs;
+ bool attrs_allocated;
+ int err;
+ pid_t child;
+ int fd;
+ FILE *fp;
+ char line[80];
+ int status;
+ int exitstatus;
+
+ if (pipe (ifd) < 0 || (ifd[0] = fd_safer (ifd[0])) < 0)
+ {
+ perror ("cannot create pipe");
+ exit (1);
+ }
+ sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
+ sigemptyset (&fatal_signal_set);
+ sigaddset (&fatal_signal_set, SIGINT);
+ sigaddset (&fatal_signal_set, SIGTERM);
+ sigaddset (&fatal_signal_set, SIGHUP);
+ sigaddset (&fatal_signal_set, SIGPIPE);
+ sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
+ actions_allocated = false;
+ attrs_allocated = false;
+ if ((err = posix_spawn_file_actions_init (&actions)) != 0
+ || (actions_allocated = true,
+ (err = posix_spawn_file_actions_adddup2 (&actions, ifd[1], STDOUT_FILENO)) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) != 0
+ || (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, "/dev/null", O_RDONLY, 0)) != 0
+ || (err = posix_spawnattr_init (&attrs)) != 0
+ || (attrs_allocated = true,
+ (err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
+ || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
+ || (err = posix_spawnp (&child, "/bin/sh", &actions, &attrs, argv, environ)) != 0))
+ {
+ if (actions_allocated)
+ posix_spawn_file_actions_destroy (&actions);
+ if (attrs_allocated)
+ posix_spawnattr_destroy (&attrs);
+ sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+ errno = err;
+ perror ("subprocess failed");
+ exit (1);
+ }
+ posix_spawn_file_actions_destroy (&actions);
+ posix_spawnattr_destroy (&attrs);
+ sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+ close (ifd[1]);
+ fd = ifd[0];
+ fp = fdopen (fd, "r");
+ if (fp == NULL)
+ {
+ fprintf (stderr, "fdopen() failed\n");
+ exit (1);
+ }
+ if (fread (line, 1, 80, fp) < 12)
+ {
+ fprintf (stderr, "could not read expected output\n");
+ exit (1);
+ }
+ if (memcmp (line, "Halle Potta", 11) != 0)
+ {
+ fprintf (stderr, "read output is not the expected output");
+ exit (1);
+ }
+ fclose (fp);
+ status = 0;
+ while (waitpid (child, &status, 0) != child)
+ ;
+ if (!WIFEXITED (status))
+ {
+ fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
+ exit (1);
+ }
+ exitstatus = WEXITSTATUS (status);
+ if (exitstatus != 0)
+ {
+ fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
+ exit (1);
+ }
+ return 0;
+}
diff --git a/tests/gnu/test-posix_spawn1.in.sh b/tests/gnu/test-posix_spawn1.in.sh
new file mode 100755
index 00000000..b370856d
--- /dev/null
+++ b/tests/gnu/test-posix_spawn1.in.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Halle Potta"
diff --git a/tests/gnu/test-posix_spawn2.c b/tests/gnu/test-posix_spawn2.c
new file mode 100755
index 00000000..d76c25c4
--- /dev/null
+++ b/tests/gnu/test-posix_spawn2.c
@@ -0,0 +1,139 @@
+/* Test of posix_spawn() function.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <spawn.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+extern char **environ;
+
+#define CHILD_PROGRAM_FILENAME "test-posix_spawn2.sh"
+
+static int
+fd_safer (int fd)
+{
+ if (0 <= fd && fd <= 2)
+ {
+ int f = fd_safer (dup (fd));
+ int e = errno;
+ close (fd);
+ errno = e;
+ fd = f;
+ }
+
+ return fd;
+}
+
+int
+main ()
+{
+ char *argv[3] = { "/bin/sh", CHILD_PROGRAM_FILENAME, NULL };
+ int ofd[2];
+ sigset_t blocked_signals;
+ sigset_t fatal_signal_set;
+ posix_spawn_file_actions_t actions;
+ bool actions_allocated;
+ posix_spawnattr_t attrs;
+ bool attrs_allocated;
+ int err;
+ pid_t child;
+ int fd;
+ FILE *fp;
+ int written;
+ int status;
+ int exitstatus;
+
+ if (pipe (ofd) < 0 || (ofd[1] = fd_safer (ofd[1])) < 0)
+ {
+ perror ("cannot create pipe");
+ exit (1);
+ }
+ sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
+ sigemptyset (&fatal_signal_set);
+ sigaddset (&fatal_signal_set, SIGINT);
+ sigaddset (&fatal_signal_set, SIGTERM);
+ sigaddset (&fatal_signal_set, SIGHUP);
+ sigaddset (&fatal_signal_set, SIGPIPE);
+ sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
+ actions_allocated = false;
+ attrs_allocated = false;
+ if ((err = posix_spawn_file_actions_init (&actions)) != 0
+ || (actions_allocated = true,
+ (err = posix_spawn_file_actions_adddup2 (&actions, ofd[0], STDIN_FILENO)) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0
+ || (err = posix_spawnattr_init (&attrs)) != 0
+ || (attrs_allocated = true,
+ (err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
+ || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
+ || (err = posix_spawnp (&child, "/bin/sh", &actions, &attrs, argv, environ)) != 0))
+ {
+ if (actions_allocated)
+ posix_spawn_file_actions_destroy (&actions);
+ if (attrs_allocated)
+ posix_spawnattr_destroy (&attrs);
+ sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+ errno = err;
+ perror ("subprocess failed");
+ exit (1);
+ }
+ posix_spawn_file_actions_destroy (&actions);
+ posix_spawnattr_destroy (&attrs);
+ sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+ close (ofd[0]);
+ fd = ofd[1];
+ fp = fdopen (fd, "w");
+ if (fp == NULL)
+ {
+ fprintf (stderr, "fdopen() failed\n");
+ exit (1);
+ }
+ written = fwrite ("Halle Potta\n", 1, 12, fp);
+ if (written < 12)
+ {
+ fprintf (stderr, "could not write input\n");
+ exit (1);
+ }
+ fclose (fp);
+ status = 0;
+ while (waitpid (child, &status, 0) != child)
+ ;
+ if (!WIFEXITED (status))
+ {
+ fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
+ exit (1);
+ }
+ exitstatus = WEXITSTATUS (status);
+ if (exitstatus != 0)
+ {
+ fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
+ exit (1);
+ }
+ return 0;
+}
diff --git a/tests/gnu/test-posix_spawn2.in.sh b/tests/gnu/test-posix_spawn2.in.sh
new file mode 100755
index 00000000..29a9b28f
--- /dev/null
+++ b/tests/gnu/test-posix_spawn2.in.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+read line
+test "$line" = "Halle Potta"
diff --git a/tests/gnu/test-printf-frexp.c b/tests/gnu/test-printf-frexp.c
new file mode 100755
index 00000000..13e1c30e
--- /dev/null
+++ b/tests/gnu/test-printf-frexp.c
@@ -0,0 +1,119 @@
+/* Test of splitting a double into fraction and mantissa.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "printf-frexp.h"
+
+#include <float.h>
+
+#include "macros.h"
+
+static double
+my_ldexp (double x, int d)
+{
+ for (; d > 0; d--)
+ x *= 2.0;
+ for (; d < 0; d++)
+ x *= 0.5;
+ return x;
+}
+
+int
+main ()
+{
+ int i;
+ /* The use of 'volatile' guarantees that excess precision bits are dropped
+ when dealing with denormalized numbers. It is necessary on x86 systems
+ where double-floats are not IEEE compliant by default, to avoid that the
+ results become platform and compiler option dependent. 'volatile' is a
+ portable alternative to gcc's -ffloat-store option. */
+ volatile double x;
+
+ for (i = 1, x = 1.0; i <= DBL_MAX_EXP; i++, x *= 2.0)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.0);
+ }
+ for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.0);
+ }
+ for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == DBL_MIN_EXP - 1);
+ ASSERT (mantissa == my_ldexp (1.0, i - DBL_MIN_EXP));
+ }
+
+ for (i = 1, x = 1.01; i <= DBL_MAX_EXP; i++, x *= 2.0)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.01);
+ }
+ for (i = 1, x = 1.01; i >= DBL_MIN_EXP; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.01);
+ }
+ for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == DBL_MIN_EXP - 1);
+ ASSERT (mantissa >= my_ldexp (1.0, i - DBL_MIN_EXP));
+ ASSERT (mantissa <= my_ldexp (2.0, i - DBL_MIN_EXP));
+ ASSERT (mantissa == my_ldexp (x, - exp));
+ }
+
+ for (i = 1, x = 1.73205; i <= DBL_MAX_EXP; i++, x *= 2.0)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.73205);
+ }
+ for (i = 1, x = 1.73205; i >= DBL_MIN_EXP; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.73205);
+ }
+ for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
+ {
+ int exp = -9999;
+ double mantissa = printf_frexp (x, &exp);
+ ASSERT (exp == DBL_MIN_EXP - 1);
+ ASSERT (mantissa >= my_ldexp (1.0, i - DBL_MIN_EXP));
+ ASSERT (mantissa <= my_ldexp (2.0, i - DBL_MIN_EXP));
+ ASSERT (mantissa == my_ldexp (x, - exp));
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-printf-frexpl.c b/tests/gnu/test-printf-frexpl.c
new file mode 100755
index 00000000..6f7e4f7e
--- /dev/null
+++ b/tests/gnu/test-printf-frexpl.c
@@ -0,0 +1,134 @@
+/* Test of splitting a 'long double' into fraction and mantissa.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "printf-frexpl.h"
+
+#include <float.h>
+
+#include "fpucw.h"
+#include "macros.h"
+
+/* On MIPS IRIX machines, LDBL_MIN_EXP is -1021, but the smallest reliable
+ exponent for 'long double' is -964. Similarly, on PowerPC machines,
+ LDBL_MIN_EXP is -1021, but the smallest reliable exponent for 'long double'
+ is -968. For exponents below that, the precision may be truncated to the
+ precision used for 'double'. */
+#ifdef __sgi
+# define MIN_NORMAL_EXP (LDBL_MIN_EXP + 57)
+# define MIN_SUBNORMAL_EXP MIN_NORMAL_EXP
+#elif defined __ppc || defined __ppc__ || defined __powerpc || defined __powerpc__
+# define MIN_NORMAL_EXP (LDBL_MIN_EXP + 53)
+# define MIN_SUBNORMAL_EXP MIN_NORMAL_EXP
+#else
+# define MIN_NORMAL_EXP LDBL_MIN_EXP
+# define MIN_SUBNORMAL_EXP (LDBL_MIN_EXP - 100)
+#endif
+
+static long double
+my_ldexp (long double x, int d)
+{
+ for (; d > 0; d--)
+ x *= 2.0L;
+ for (; d < 0; d++)
+ x *= 0.5L;
+ return x;
+}
+
+int
+main ()
+{
+ int i;
+ long double x;
+ DECL_LONG_DOUBLE_ROUNDING
+
+ BEGIN_LONG_DOUBLE_ROUNDING ();
+
+ for (i = 1, x = 1.0L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.0L);
+ }
+ for (i = 1, x = 1.0L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.0L);
+ }
+ for (; i >= MIN_SUBNORMAL_EXP && x > 0.0L; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == LDBL_MIN_EXP - 1);
+ ASSERT (mantissa == my_ldexp (1.0L, i - LDBL_MIN_EXP));
+ }
+
+ for (i = 1, x = 1.01L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.01L);
+ }
+ for (i = 1, x = 1.01L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.01L);
+ }
+ for (; i >= MIN_SUBNORMAL_EXP && x > 0.0L; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == LDBL_MIN_EXP - 1);
+ ASSERT (mantissa >= my_ldexp (1.0L, i - LDBL_MIN_EXP));
+ ASSERT (mantissa <= my_ldexp (2.0L, i - LDBL_MIN_EXP));
+ ASSERT (mantissa == my_ldexp (x, - exp));
+ }
+
+ for (i = 1, x = 1.73205L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.73205L);
+ }
+ for (i = 1, x = 1.73205L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == i - 1);
+ ASSERT (mantissa == 1.73205L);
+ }
+ for (; i >= MIN_SUBNORMAL_EXP && x > 0.0L; i--, x *= 0.5L)
+ {
+ int exp = -9999;
+ long double mantissa = printf_frexpl (x, &exp);
+ ASSERT (exp == LDBL_MIN_EXP - 1);
+ ASSERT (mantissa >= my_ldexp (1.0L, i - LDBL_MIN_EXP));
+ ASSERT (mantissa <= my_ldexp (2.0L, i - LDBL_MIN_EXP));
+ ASSERT (mantissa == my_ldexp (x, - exp));
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-printf-posix.h b/tests/gnu/test-printf-posix.h
new file mode 100755
index 00000000..32e6468f
--- /dev/null
+++ b/tests/gnu/test-printf-posix.h
@@ -0,0 +1,153 @@
+/* Test of POSIX compatible vsprintf() and sprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+static void
+test_function (int (*my_printf) (const char *, ...))
+{
+ /* Here we don't test output that may be platform dependent.
+ The bulk of the tests is done as part of the 'vasnprintf-posix' module. */
+
+ /* Test support of size specifiers as in C99. */
+
+ my_printf ("%ju %d\n", (uintmax_t) 12345671, 33, 44, 55);
+
+ my_printf ("%zu %d\n", (size_t) 12345672, 33, 44, 55);
+
+ my_printf ("%tu %d\n", (ptrdiff_t) 12345673, 33, 44, 55);
+
+ /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
+ output of floating-point numbers. */
+
+ /* Positive zero. */
+ my_printf ("%a %d\n", 0.0, 33, 44, 55);
+
+ /* Positive infinity. */
+ my_printf ("%a %d\n", 1.0 / 0.0, 33, 44, 55);
+
+ /* Negative infinity. */
+ my_printf ("%a %d\n", -1.0 / 0.0, 33, 44, 55);
+
+ /* FLAG_ZERO with infinite number. */
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ my_printf ("%010a %d\n", 1.0 / 0.0, 33, 44, 55);
+
+ /* Test the support of the %f format directive. */
+
+ /* A positive number. */
+ my_printf ("%f %d\n", 12.75, 33, 44, 55);
+
+ /* A larger positive number. */
+ my_printf ("%f %d\n", 1234567.0, 33, 44, 55);
+
+ /* A negative number. */
+ my_printf ("%f %d\n", -0.03125, 33, 44, 55);
+
+ /* Positive zero. */
+ my_printf ("%f %d\n", 0.0, 33, 44, 55);
+
+ /* FLAG_ZERO. */
+ my_printf ("%015f %d\n", 1234.0, 33, 44, 55);
+
+ /* Precision. */
+ my_printf ("%.f %d\n", 1234.0, 33, 44, 55);
+
+ /* Precision with no rounding. */
+ my_printf ("%.2f %d\n", 999.95, 33, 44, 55);
+
+ /* Precision with rounding. */
+ my_printf ("%.2f %d\n", 999.996, 33, 44, 55);
+
+ /* A positive number. */
+ my_printf ("%Lf %d\n", 12.75L, 33, 44, 55);
+
+ /* A larger positive number. */
+ my_printf ("%Lf %d\n", 1234567.0L, 33, 44, 55);
+
+ /* A negative number. */
+ my_printf ("%Lf %d\n", -0.03125L, 33, 44, 55);
+
+ /* Positive zero. */
+ my_printf ("%Lf %d\n", 0.0L, 33, 44, 55);
+
+ /* FLAG_ZERO. */
+ my_printf ("%015Lf %d\n", 1234.0L, 33, 44, 55);
+
+ /* Precision. */
+ my_printf ("%.Lf %d\n", 1234.0L, 33, 44, 55);
+
+ /* Precision with no rounding. */
+ my_printf ("%.2Lf %d\n", 999.95L, 33, 44, 55);
+
+ /* Precision with rounding. */
+ my_printf ("%.2Lf %d\n", 999.996L, 33, 44, 55);
+
+ /* Test the support of the %F format directive. */
+
+ /* A positive number. */
+ my_printf ("%F %d\n", 12.75, 33, 44, 55);
+
+ /* A larger positive number. */
+ my_printf ("%F %d\n", 1234567.0, 33, 44, 55);
+
+ /* A negative number. */
+ my_printf ("%F %d\n", -0.03125, 33, 44, 55);
+
+ /* Positive zero. */
+ my_printf ("%F %d\n", 0.0, 33, 44, 55);
+
+ /* FLAG_ZERO. */
+ my_printf ("%015F %d\n", 1234.0, 33, 44, 55);
+
+ /* Precision. */
+ my_printf ("%.F %d\n", 1234.0, 33, 44, 55);
+
+ /* Precision with no rounding. */
+ my_printf ("%.2F %d\n", 999.95, 33, 44, 55);
+
+ /* Precision with rounding. */
+ my_printf ("%.2F %d\n", 999.996, 33, 44, 55);
+
+ /* A positive number. */
+ my_printf ("%LF %d\n", 12.75L, 33, 44, 55);
+
+ /* A larger positive number. */
+ my_printf ("%LF %d\n", 1234567.0L, 33, 44, 55);
+
+ /* A negative number. */
+ my_printf ("%LF %d\n", -0.03125L, 33, 44, 55);
+
+ /* Positive zero. */
+ my_printf ("%LF %d\n", 0.0L, 33, 44, 55);
+
+ /* FLAG_ZERO. */
+ my_printf ("%015LF %d\n", 1234.0L, 33, 44, 55);
+
+ /* Precision. */
+ my_printf ("%.LF %d\n", 1234.0L, 33, 44, 55);
+
+ /* Precision with no rounding. */
+ my_printf ("%.2LF %d\n", 999.95L, 33, 44, 55);
+
+ /* Precision with rounding. */
+ my_printf ("%.2LF %d\n", 999.996L, 33, 44, 55);
+
+ /* Test the support of the POSIX/XSI format strings with positions. */
+
+ my_printf ("%2$d %1$d\n", 33, 55);
+}
diff --git a/tests/gnu/test-printf-posix.output b/tests/gnu/test-printf-posix.output
new file mode 100755
index 00000000..618825bb
--- /dev/null
+++ b/tests/gnu/test-printf-posix.output
@@ -0,0 +1,40 @@
+12345671 33
+12345672 33
+12345673 33
+0x0p+0 33
+inf 33
+-inf 33
+ inf 33
+12.750000 33
+1234567.000000 33
+-0.031250 33
+0.000000 33
+00001234.000000 33
+1234 33
+999.95 33
+1000.00 33
+12.750000 33
+1234567.000000 33
+-0.031250 33
+0.000000 33
+00001234.000000 33
+1234 33
+999.95 33
+1000.00 33
+12.750000 33
+1234567.000000 33
+-0.031250 33
+0.000000 33
+00001234.000000 33
+1234 33
+999.95 33
+1000.00 33
+12.750000 33
+1234567.000000 33
+-0.031250 33
+0.000000 33
+00001234.000000 33
+1234 33
+999.95 33
+1000.00 33
+55 33
diff --git a/tests/gnu/test-quotearg.c b/tests/gnu/test-quotearg.c
new file mode 100755
index 00000000..1928679f
--- /dev/null
+++ b/tests/gnu/test-quotearg.c
@@ -0,0 +1,471 @@
+/* Test of quotearg family of functions.
+ Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2008. */
+
+#include <config.h>
+
+#include "quotearg.h"
+
+#include <ctype.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "progname.h"
+#include "gettext.h"
+#include "macros.h"
+
+struct result_strings {
+ char const *str1; /* Translation of "". */
+ char const *str2; /* Translation of "\0""1\0". */
+ size_t len2; /* Length of str2. */
+ char const *str3; /* Translation of "simple". */
+ char const *str4; /* Translation of " \t\n'\"\033?""?/\\". */
+ char const *str5; /* Translation of "a:b". */
+ char const *str6; /* Translation of "a\\b". */
+ char const *str7a; /* Translation of LQ RQ, in ASCII charset. */
+ char const *str7b; /* Translation of LQ RQ, in Latin1 or UTF-8 charset. */
+};
+
+struct result_groups {
+ struct result_strings group1; /* Via quotearg_buffer. */
+ struct result_strings group2; /* Via quotearg{,_mem}. */
+ struct result_strings group3; /* Via quotearg_colon{,_mem}. */
+};
+
+/* These quotes are borrowed from a pt_PT.utf8 translation. */
+# define LQ "\302\253"
+# define RQ "\302\273"
+# define LQ_ENC "\\302\\253"
+# define RQ_ENC "\\302\\273"
+# define RQ_ESC "\\\302\273"
+
+static struct result_strings inputs = {
+ "", "\0001\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+ LQ RQ, NULL
+};
+
+static struct result_groups results_g[] = {
+ /* literal_quoting_style */
+ { { "", "\0""1\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+ LQ RQ, LQ RQ },
+ { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+ LQ RQ, LQ RQ },
+ { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+ LQ RQ, LQ RQ } },
+
+ /* shell_quoting_style */
+ { { "''", "\0""1\0", 3, "simple", "' \t\n'\\''\"\033?""?/\\'", "a:b",
+ "'a\\b'", LQ RQ, LQ RQ },
+ { "''", "1", 1, "simple", "' \t\n'\\''\"\033?""?/\\'", "a:b",
+ "'a\\b'", LQ RQ, LQ RQ },
+ { "''", "1", 1, "simple", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
+ "'a\\b'", LQ RQ, LQ RQ } },
+
+ /* shell_always_quoting_style */
+ { { "''", "'\0""1\0'", 5, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
+ "'a\\b'", "'" LQ RQ "'", "'" LQ RQ "'" },
+ { "''", "'1'", 3, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
+ "'a\\b'", "'" LQ RQ "'", "'" LQ RQ "'" },
+ { "''", "'1'", 3, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
+ "'a\\b'", "'" LQ RQ "'", "'" LQ RQ "'" } },
+
+ /* c_quoting_style */
+ { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
+ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
+ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } },
+
+ /* c_maybe_quoting_style */
+ { { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
+ "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
+ { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
+ "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
+ { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
+ "\"a:b\"", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ } },
+
+ /* escape_quoting_style */
+ { { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a:b",
+ "a\\\\b", LQ_ENC RQ_ENC, LQ RQ },
+ { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a:b",
+ "a\\\\b", LQ_ENC RQ_ENC, LQ RQ },
+ { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a\\:b",
+ "a\\\\b", LQ_ENC RQ_ENC, LQ RQ } },
+
+ /* locale_quoting_style */
+ { { "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
+ "`a:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'", "`" LQ RQ "'" },
+ { "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
+ "`a:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'", "`" LQ RQ "'" },
+ { "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
+ "`a\\:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'", "`" LQ RQ "'" } },
+
+ /* clocale_quoting_style */
+ { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
+ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
+ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } }
+};
+
+static struct result_groups flag_results[] = {
+ /* literal_quoting_style and QA_ELIDE_NULL_BYTES */
+ { { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ,
+ LQ RQ },
+ { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ,
+ LQ RQ },
+ { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ,
+ LQ RQ } },
+
+ /* c_quoting_style and QA_ELIDE_OUTER_QUOTES */
+ { { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
+ "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
+ { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
+ "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
+ { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
+ "\"a:b\"", "a\\b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ } },
+
+ /* c_quoting_style and QA_SPLIT_TRIGRAPHS */
+ { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
+ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
+ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+ "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } }
+};
+
+#if ENABLE_NLS
+
+static struct result_groups locale_results[] = {
+ /* locale_quoting_style */
+ { { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ },
+ { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ},
+ { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a\\:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ } },
+
+ /* clocale_quoting_style */
+ { { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ },
+ { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ },
+ { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a\\:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ } }
+};
+
+#endif /* ENABLE_NLS */
+
+static char const *custom_quotes[][2] = {
+ { "", "" },
+ { "'", "'" },
+ { "(", ")" },
+ { ":", " " },
+ { " ", ":" },
+ { "# ", "\n" },
+ { "\"'", "'\"" }
+};
+
+static struct result_groups custom_results[] = {
+ /* left_quote = right_quote = "" */
+ { { "", "\\0001\\0", 7, "simple",
+ " \\t\\n'\"\\033?""?/\\\\", "a:b", "a\\\\b",
+ LQ_ENC RQ_ENC, LQ RQ },
+ { "", "\\0001\\0", 7, "simple",
+ " \\t\\n'\"\\033?""?/\\\\", "a:b", "a\\\\b",
+ LQ_ENC RQ_ENC, LQ RQ },
+ { "", "\\0001\\0", 7, "simple",
+ " \\t\\n'\"\\033?""?/\\\\", "a\\:b", "a\\\\b",
+ LQ_ENC RQ_ENC, LQ RQ } },
+
+ /* left_quote = right_quote = "'" */
+ { { "''", "'\\0001\\0'", 9, "'simple'",
+ "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'",
+ "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
+ { "''", "'\\0001\\0'", 9, "'simple'",
+ "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'",
+ "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
+ { "''", "'\\0001\\0'", 9, "'simple'",
+ "' \\t\\n\\'\"\\033?""?/\\\\'", "'a\\:b'", "'a\\\\b'",
+ "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" } },
+
+ /* left_quote = "(" and right_quote = ")" */
+ { { "()", "(\\0001\\0)", 9, "(simple)",
+ "( \\t\\n'\"\\033?""?/\\\\)", "(a:b)", "(a\\\\b)",
+ "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" },
+ { "()", "(\\0001\\0)", 9, "(simple)",
+ "( \\t\\n'\"\\033?""?/\\\\)", "(a:b)", "(a\\\\b)",
+ "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" },
+ { "()", "(\\0001\\0)", 9, "(simple)",
+ "( \\t\\n'\"\\033?""?/\\\\)", "(a\\:b)", "(a\\\\b)",
+ "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" } },
+
+ /* left_quote = ":" and right_quote = " " */
+ { { ": ", ":\\0001\\0 ", 9, ":simple ",
+ ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a:b ", ":a\\\\b ",
+ ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " },
+ { ": ", ":\\0001\\0 ", 9, ":simple ",
+ ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a:b ", ":a\\\\b ",
+ ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " },
+ { ": ", ":\\0001\\0 ", 9, ":simple ",
+ ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a\\:b ", ":a\\\\b ",
+ ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " } },
+
+ /* left_quote = " " and right_quote = ":" */
+ { { " :", " \\0001\\0:", 9, " simple:",
+ " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
+ " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" },
+ { " :", " \\0001\\0:", 9, " simple:",
+ " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
+ " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" },
+ { " :", " \\0001\\0:", 9, " simple:",
+ " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
+ " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" } },
+
+ /* left_quote = "# " and right_quote = "\n" */
+ { { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+ "# \\t\\n'\"\\033?""?/\\\\\n", "# a:b\n", "# a\\\\b\n",
+ "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" },
+ { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+ "# \\t\\n'\"\\033?""?/\\\\\n", "# a:b\n", "# a\\\\b\n",
+ "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" },
+ { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+ "# \\t\\n'\"\\033?""?/\\\\\n", "# a\\:b\n", "# a\\\\b\n",
+ "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" } },
+
+ /* left_quote = "\"'" and right_quote = "'\"" */
+ { { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+ "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a:b'\"", "\"'a\\\\b'\"",
+ "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" },
+ { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+ "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a:b'\"", "\"'a\\\\b'\"",
+ "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" },
+ { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+ "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a\\:b'\"", "\"'a\\\\b'\"",
+ "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" } }
+};
+
+static void
+compare (char const *a, size_t la, char const *b, size_t lb)
+{
+ ASSERT (la == lb);
+ ASSERT (memcmp (a, b, la) == 0);
+ ASSERT (b[lb] == '\0');
+}
+
+static void
+compare_strings (char *(func) (char const *, size_t *),
+ struct result_strings *results, bool ascii_only)
+{
+ size_t len;
+ char *p;
+
+ len = 0;
+ p = func (inputs.str1, &len);
+ compare (results->str1, strlen (results->str1), p, len);
+
+ len = inputs.len2;
+ p = func (inputs.str2, &len);
+ compare (results->str2, results->len2, p, len);
+
+ len = SIZE_MAX;
+ p = func (inputs.str3, &len);
+ compare (results->str3, strlen (results->str3), p, len);
+
+ len = strlen (inputs.str4);
+ p = func (inputs.str4, &len);
+ compare (results->str4, strlen (results->str4), p, len);
+
+ len = SIZE_MAX;
+ p = func (inputs.str5, &len);
+ compare (results->str5, strlen (results->str5), p, len);
+
+ len = strlen (inputs.str6);
+ p = func (inputs.str6, &len);
+ compare (results->str6, strlen (results->str6), p, len);
+
+ len = strlen (inputs.str7a);
+ p = func (inputs.str7a, &len);
+ if (ascii_only)
+ compare (results->str7a, strlen (results->str7a), p, len);
+ else
+ compare (results->str7b, strlen (results->str7b), p, len);
+}
+
+static char *
+use_quotearg_buffer (const char *str, size_t *len)
+{
+ static char buf[100];
+ size_t size;
+ memset (buf, 0xa5, 100);
+ size = quotearg_buffer (buf, 100, str, *len, NULL);
+ *len = size;
+ ASSERT ((unsigned char) buf[size + 1] == 0xa5);
+ return buf;
+}
+
+static char *
+use_quotearg (const char *str, size_t *len)
+{
+ char *p = *len == SIZE_MAX ? quotearg (str) : quotearg_mem (str, *len);
+ *len = strlen (p);
+ return p;
+}
+
+static char *
+use_quote_double_quotes (const char *str, size_t *len)
+{
+ char *p = *len == SIZE_MAX ? quotearg_char (str, '"')
+ : quotearg_char_mem (str, *len, '"');
+ *len = strlen (p);
+ return p;
+}
+
+static char *
+use_quotearg_colon (const char *str, size_t *len)
+{
+ char *p = (*len == SIZE_MAX ? quotearg_colon (str)
+ : quotearg_colon_mem (str, *len));
+ *len = strlen (p);
+ return p;
+}
+
+int
+main (int argc _GL_UNUSED, char *argv[])
+{
+ int i;
+ bool ascii_only = MB_CUR_MAX == 1 && !isprint ((unsigned char) LQ[0]);
+
+ set_program_name (argv[0]);
+
+ /* This part of the program is hard-wired to the C locale since it
+ does not call setlocale. However, according to POSIX, the use of
+ 8-bit bytes in a character context in the C locale gives
+ unspecified results (that is, the C locale charset is allowed to
+ be unibyte with 8-bit bytes rejected [ASCII], unibyte with 8-bit
+ bytes being characters [often ISO-8859-1], or multibyte [often
+ UTF-8]). We assume that the latter two cases will be
+ indistinguishable in this test - that is, the LQ and RQ sequences
+ will pass through unchanged in either type of charset. So when
+ testing for quoting of str7, use the ascii_only flag to decide
+ what to expect for the 8-bit data being quoted. */
+ ASSERT (!isprint ('\033'));
+ for (i = literal_quoting_style; i <= clocale_quoting_style; i++)
+ {
+ set_quoting_style (NULL, i);
+ compare_strings (use_quotearg_buffer, &results_g[i].group1, ascii_only);
+ compare_strings (use_quotearg, &results_g[i].group2, ascii_only);
+ if (i == c_quoting_style)
+ compare_strings (use_quote_double_quotes, &results_g[i].group2,
+ ascii_only);
+ compare_strings (use_quotearg_colon, &results_g[i].group3, ascii_only);
+ }
+
+ set_quoting_style (NULL, literal_quoting_style);
+ ASSERT (set_quoting_flags (NULL, QA_ELIDE_NULL_BYTES) == 0);
+ compare_strings (use_quotearg_buffer, &flag_results[0].group1, ascii_only);
+ compare_strings (use_quotearg, &flag_results[0].group2, ascii_only);
+ compare_strings (use_quotearg_colon, &flag_results[0].group3, ascii_only);
+
+ set_quoting_style (NULL, c_quoting_style);
+ ASSERT (set_quoting_flags (NULL, QA_ELIDE_OUTER_QUOTES)
+ == QA_ELIDE_NULL_BYTES);
+ compare_strings (use_quotearg_buffer, &flag_results[1].group1, ascii_only);
+ compare_strings (use_quotearg, &flag_results[1].group2, ascii_only);
+ compare_strings (use_quote_double_quotes, &flag_results[1].group2,
+ ascii_only);
+ compare_strings (use_quotearg_colon, &flag_results[1].group3, ascii_only);
+
+ ASSERT (set_quoting_flags (NULL, QA_SPLIT_TRIGRAPHS)
+ == QA_ELIDE_OUTER_QUOTES);
+ compare_strings (use_quotearg_buffer, &flag_results[2].group1, ascii_only);
+ compare_strings (use_quotearg, &flag_results[2].group2, ascii_only);
+ compare_strings (use_quote_double_quotes, &flag_results[2].group2,
+ ascii_only);
+ compare_strings (use_quotearg_colon, &flag_results[2].group3, ascii_only);
+
+ ASSERT (set_quoting_flags (NULL, 0) == QA_SPLIT_TRIGRAPHS);
+
+ for (i = 0; i < sizeof custom_quotes / sizeof *custom_quotes; ++i)
+ {
+ set_custom_quoting (NULL,
+ custom_quotes[i][0], custom_quotes[i][1]);
+ compare_strings (use_quotearg_buffer, &custom_results[i].group1,
+ ascii_only);
+ compare_strings (use_quotearg, &custom_results[i].group2, ascii_only);
+ compare_strings (use_quotearg_colon, &custom_results[i].group3,
+ ascii_only);
+ }
+
+#if ENABLE_NLS
+ /* Clean up environment. */
+ unsetenv ("LANGUAGE");
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LANG");
+ unsetenv ("OUTPUT_CHARSET");
+
+ /* This program part runs in a French UTF-8 locale. It uses
+ the test-quotearg.mo message catalog. */
+ {
+ const char *locale_name = getenv ("LOCALE");
+
+ if (locale_name != NULL && strcmp (locale_name, "none") != 0
+ && setenv ("LC_ALL", locale_name, 1) == 0
+ && setlocale (LC_ALL, "") != NULL)
+ {
+ textdomain ("test-quotearg");
+ bindtextdomain ("test-quotearg", getenv ("LOCALEDIR"));
+
+ set_quoting_style (NULL, locale_quoting_style);
+ compare_strings (use_quotearg_buffer, &locale_results[0].group1, false);
+ compare_strings (use_quotearg, &locale_results[0].group2, false);
+ compare_strings (use_quotearg_colon, &locale_results[0].group3, false);
+
+ set_quoting_style (NULL, clocale_quoting_style);
+ compare_strings (use_quotearg_buffer, &locale_results[1].group1, false);
+ compare_strings (use_quotearg, &locale_results[1].group2, false);
+ compare_strings (use_quotearg_colon, &locale_results[1].group3, false);
+ }
+ }
+#endif /* ENABLE_NLS */
+
+ quotearg_free ();
+ return 0;
+}
diff --git a/tests/gnu/test-quotearg.sh b/tests/gnu/test-quotearg.sh
new file mode 100755
index 00000000..e050d078
--- /dev/null
+++ b/tests/gnu/test-quotearg.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# Choose an existing locale. The locale encoding does not matter; see the
+# comment in test-quotearg.po.
+if test $LOCALE_FR_UTF8 != none; then
+ locale=$LOCALE_FR_UTF8
+else
+ if test $LOCALE_FR != none; then
+ locale=$LOCALE_FR
+ else
+ locale=none
+ fi
+fi
+
+LOCALE=$locale LOCALEDIR="$srcdir/locale" \
+./test-quotearg${EXEEXT}
diff --git a/tests/gnu/test-rawmemchr.c b/tests/gnu/test-rawmemchr.c
new file mode 100755
index 00000000..94768183
--- /dev/null
+++ b/tests/gnu/test-rawmemchr.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+ * Written by Eric Blake and Bruno Haible
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (rawmemchr, void *, (void const *, int));
+
+#include <stdlib.h>
+
+#include "macros.h"
+
+/* Calculating void * + int is not portable, so this wrapper converts
+ to char * to make the tests easier to write. */
+#define RAWMEMCHR (char *) rawmemchr
+
+int
+main (void)
+{
+ size_t n = 0x100000;
+ char *input = malloc (n + 1);
+ ASSERT (input);
+
+ input[0] = 'a';
+ input[1] = 'b';
+ memset (input + 2, 'c', 1024);
+ memset (input + 1026, 'd', n - 1028);
+ input[n - 2] = 'e';
+ input[n - 1] = 'a';
+ input[n] = '\0';
+
+ /* Basic behavior tests. */
+ ASSERT (RAWMEMCHR (input, 'a') == input);
+ ASSERT (RAWMEMCHR (input, 'b') == input + 1);
+ ASSERT (RAWMEMCHR (input, 'c') == input + 2);
+ ASSERT (RAWMEMCHR (input, 'd') == input + 1026);
+
+ ASSERT (RAWMEMCHR (input + 1, 'a') == input + n - 1);
+ ASSERT (RAWMEMCHR (input + 1, 'e') == input + n - 2);
+
+ ASSERT (RAWMEMCHR (input, '\0') == input + n);
+
+ /* Alignment tests. */
+ {
+ int i, j;
+ for (i = 0; i < 32; i++)
+ {
+ for (j = 0; j < 256; j++)
+ input[i + j] = j;
+ for (j = 0; j < 256; j++)
+ {
+ ASSERT (RAWMEMCHR (input + i, j) == input + i + j);
+ }
+ }
+ }
+
+ free (input);
+
+ return 0;
+}
diff --git a/tests/gnu/test-readlink.c b/tests/gnu/test-readlink.c
new file mode 100755
index 00000000..a144964f
--- /dev/null
+++ b/tests/gnu/test-readlink.c
@@ -0,0 +1,48 @@
+/* Tests of readlink.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (readlink, ssize_t, (char const *, char *, size_t));
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "test-readlink.t"
+
+#include "test-readlink.h"
+
+int
+main (void)
+{
+ /* Remove any leftovers from a previous partial run. */
+ ignore_value (system ("rm -rf " BASE "*"));
+
+ return test_readlink (readlink, true);
+}
diff --git a/tests/gnu/test-readlink.h b/tests/gnu/test-readlink.h
new file mode 100755
index 00000000..1e482dfe
--- /dev/null
+++ b/tests/gnu/test-readlink.h
@@ -0,0 +1,119 @@
+/* Tests of readlink.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+/* This file is designed to test both readlink(a,b,c) and
+ readlinkat(AT_FDCWD,a,b,c). FUNC is the function to test. Assumes
+ that BASE and ASSERT are already defined, and that appropriate
+ headers are already included. If PRINT, warn before skipping
+ symlink tests with status 77. */
+
+static int
+test_readlink (ssize_t (*func) (char const *, char *, size_t), bool print)
+{
+ char buf[80];
+
+ /* Sanity checks of failures. Mingw lacks symlink, but readlink can
+ still distinguish between various errors. */
+ memset (buf, 0xff, sizeof buf);
+ errno = 0;
+ ASSERT (func ("no_such", buf, sizeof buf) == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func ("no_such/", buf, sizeof buf) == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func ("", buf, sizeof buf) == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (".", buf, sizeof buf) == -1);
+ ASSERT (errno == EINVAL);
+ errno = 0;
+ ASSERT (func ("./", buf, sizeof buf) == -1);
+ ASSERT (errno == EINVAL);
+ ASSERT (close (creat (BASE "file", 0600)) == 0);
+ errno = 0;
+ ASSERT (func (BASE "file", buf, sizeof buf) == -1);
+ ASSERT (errno == EINVAL);
+ errno = 0;
+ ASSERT (func (BASE "file/", buf, sizeof buf) == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Now test actual symlinks. */
+ if (symlink (BASE "dir", BASE "link"))
+ {
+ ASSERT (unlink (BASE "file") == 0);
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ errno = 0;
+ ASSERT (func (BASE "link/", buf, sizeof buf) == -1);
+ ASSERT (errno == EINVAL);
+ ASSERT (symlink (BASE "link", BASE "link2") == 0);
+ errno = 0;
+ ASSERT (func (BASE "link2/", buf, sizeof buf) == -1);
+ ASSERT (errno == EINVAL);
+ ASSERT (unlink (BASE "link2") == 0);
+ ASSERT (symlink (BASE "file", BASE "link2") == 0);
+ errno = 0;
+ ASSERT (func (BASE "link2/", buf, sizeof buf) == -1);
+ ASSERT (errno == ENOTDIR);
+ ASSERT (unlink (BASE "file") == 0);
+ ASSERT (unlink (BASE "link2") == 0);
+ {
+ /* Up till now, no readlink has been successful, so buf should be
+ unchanged. */
+ int i;
+ for (i = 0; i < sizeof buf; i++)
+ ASSERT (buf[i] == (char) 0xff);
+ }
+ {
+ size_t len = strlen (BASE "dir");
+ /* When passing too small of a buffer, expect the truncated
+ length, or an ERANGE failure. However, a size of 0 is not
+ portable enough to test. */
+ ssize_t result;
+ errno = 0;
+ result = readlink (BASE "link", buf, 1);
+ if (result == -1)
+ {
+ ASSERT (errno == ERANGE);
+ ASSERT (buf[0] == (char) 0xff);
+ }
+ else
+ {
+ ASSERT (result == 1);
+ ASSERT (buf[0] == BASE[0]);
+ }
+ ASSERT (buf[1] == (char) 0xff);
+ ASSERT (func (BASE "link", buf, len) == len);
+ ASSERT (strncmp (buf, BASE "dir", len) == 0);
+ ASSERT (buf[len] == (char) 0xff);
+ ASSERT (func (BASE "link", buf, sizeof buf) == len);
+ ASSERT (strncmp (buf, BASE "dir", len) == 0);
+ /* POSIX says rest of buf is unspecified; but in practice, it is
+ either left alone, or NUL-terminated. */
+ ASSERT (buf[len] == '\0' || buf[len] == (char) 0xff);
+ }
+ ASSERT (rmdir (BASE "dir") == 0);
+ ASSERT (unlink (BASE "link") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-rename.c b/tests/gnu/test-rename.c
new file mode 100755
index 00000000..c5c6c439
--- /dev/null
+++ b/tests/gnu/test-rename.c
@@ -0,0 +1,46 @@
+/* Test of rename() function.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (rename, int, (char const *, char const *));
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "test-rename.t"
+
+#include "test-rename.h"
+
+int
+main (void)
+{
+ /* Remove any garbage left from previous partial runs. */
+ ignore_value (system ("rm -rf " BASE "*"));
+
+ return test_rename (rename, true);
+}
diff --git a/tests/gnu/test-rename.h b/tests/gnu/test-rename.h
new file mode 100755
index 00000000..9a3f4ecf
--- /dev/null
+++ b/tests/gnu/test-rename.h
@@ -0,0 +1,446 @@
+/* Test of rename() function.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This file is designed to test both rename(a,b) and
+ renameat(AT_FDCWD,a,AT_FDCWD,b). FUNC is the function to test.
+ Assumes that BASE and ASSERT are already defined, and that
+ appropriate headers are already included. If PRINT, warn before
+ skipping symlink tests with status 77. */
+
+static int
+test_rename (int (*func) (char const *, char const *), bool print)
+{
+ /* Setup. */
+ struct stat st;
+ int fd = creat (BASE "file", 0600);
+ ASSERT (0 <= fd);
+ ASSERT (write (fd, "hi", 2) == 2);
+ ASSERT (close (fd) == 0);
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+
+ /* Obvious errors. */
+
+ errno = 0; /* Missing source. */
+ ASSERT (func (BASE "missing", BASE "missing") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "missing/", BASE "missing") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "missing", BASE "missing/") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0; /* Empty operand. */
+ ASSERT (func ("", BASE "missing") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "file", "") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "", "") == -1);
+ ASSERT (errno == ENOENT);
+
+ /* Files. */
+ errno = 0; /* Trailing slash. */
+ ASSERT (func (BASE "file", BASE "file2/") == -1);
+ ASSERT (errno == ENOENT || errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "file/", BASE "file2") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0;
+ ASSERT (stat (BASE "file2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (func (BASE "file", BASE "file2") == 0); /* Simple rename. */
+ errno = 0;
+ ASSERT (stat (BASE "file", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (stat (BASE "file2", &st) == 0);
+ ASSERT (st.st_size == 2);
+ ASSERT (close (creat (BASE "file", 0600)) == 0); /* Overwrite. */
+ errno = 0;
+ ASSERT (func (BASE "file2", BASE "file/") == -1);
+ ASSERT (errno == ENOTDIR);
+ ASSERT (func (BASE "file2", BASE "file") == 0);
+ memset (&st, 0, sizeof st);
+ ASSERT (stat (BASE "file", &st) == 0);
+ ASSERT (st.st_size == 2);
+ errno = 0;
+ ASSERT (stat (BASE "file2", &st) == -1);
+ ASSERT (errno == ENOENT);
+
+ /* Directories. */
+ ASSERT (func (BASE "dir", BASE "dir2/") == 0); /* Simple rename. */
+ errno = 0;
+ ASSERT (stat (BASE "dir", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (stat (BASE "dir2", &st) == 0);
+ ASSERT (func (BASE "dir2/", BASE "dir") == 0);
+ ASSERT (stat (BASE "dir", &st) == 0);
+ errno = 0;
+ ASSERT (stat (BASE "dir2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (func (BASE "dir", BASE "dir2") == 0);
+ errno = 0;
+ ASSERT (stat (BASE "dir", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (stat (BASE "dir2", &st) == 0);
+ ASSERT (mkdir (BASE "dir", 0700) == 0); /* Empty onto empty. */
+ ASSERT (func (BASE "dir2", BASE "dir") == 0);
+ ASSERT (mkdir (BASE "dir2", 0700) == 0);
+ ASSERT (func (BASE "dir2", BASE "dir/") == 0);
+ ASSERT (mkdir (BASE "dir2", 0700) == 0);
+ ASSERT (func (BASE "dir2/", BASE "dir") == 0);
+ ASSERT (mkdir (BASE "dir2", 0700) == 0);
+ ASSERT (close (creat (BASE "dir/file", 0600)) == 0); /* Empty onto full. */
+ errno = 0;
+ ASSERT (func (BASE "dir2", BASE "dir") == -1);
+ ASSERT (errno == EEXIST || errno == ENOTEMPTY);
+ errno = 0;
+ ASSERT (func (BASE "dir2/", BASE "dir") == -1);
+ ASSERT (errno == EEXIST || errno == ENOTEMPTY);
+ errno = 0;
+ ASSERT (func (BASE "dir2", BASE "dir/") == -1);
+ ASSERT (errno == EEXIST || errno == ENOTEMPTY);
+ ASSERT (func (BASE "dir", BASE "dir2") == 0); /* Full onto empty. */
+ errno = 0;
+ ASSERT (stat (BASE "dir", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (stat (BASE "dir2/file", &st) == 0);
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ ASSERT (func (BASE "dir2/", BASE "dir") == 0);
+ ASSERT (stat (BASE "dir/file", &st) == 0);
+ errno = 0;
+ ASSERT (stat (BASE "dir2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (mkdir (BASE "dir2", 0700) == 0);
+ ASSERT (func (BASE "dir", BASE "dir2/") == 0);
+ errno = 0;
+ ASSERT (stat (BASE "dir", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (stat (BASE "dir2/file", &st) == 0);
+ ASSERT (unlink (BASE "dir2/file") == 0);
+ errno = 0; /* Reject trailing dot. */
+ ASSERT (func (BASE "dir2", BASE "dir/.") == -1);
+ ASSERT (errno == EINVAL || errno == ENOENT);
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ errno = 0;
+ ASSERT (func (BASE "dir2", BASE "dir/.") == -1);
+ ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR
+ || errno == ENOTEMPTY);
+ errno = 0;
+ ASSERT (func (BASE "dir2/.", BASE "dir") == -1);
+ ASSERT (errno == EINVAL || errno == EBUSY);
+ ASSERT (rmdir (BASE "dir") == 0);
+ errno = 0;
+ ASSERT (func (BASE "dir2", BASE "dir/.//") == -1);
+ ASSERT (errno == EINVAL || errno == ENOENT);
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ errno = 0;
+ ASSERT (func (BASE "dir2", BASE "dir/.//") == -1);
+ ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR
+ || errno == ENOTEMPTY);
+ errno = 0;
+ ASSERT (func (BASE "dir2/.//", BASE "dir") == -1);
+ ASSERT (errno == EINVAL || errno == EBUSY);
+ ASSERT (rmdir (BASE "dir2") == 0);
+ errno = 0; /* Move into subdir. */
+ ASSERT (func (BASE "dir", BASE "dir/sub") == -1);
+ ASSERT (errno == EINVAL || errno == EACCES);
+ errno = 0;
+ ASSERT (stat (BASE "dir/sub", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (mkdir (BASE "dir/sub", 0700) == 0);
+ errno = 0;
+ ASSERT (func (BASE "dir", BASE "dir/sub") == -1);
+ ASSERT (errno == EINVAL);
+ ASSERT (stat (BASE "dir/sub", &st) == 0);
+ ASSERT (rmdir (BASE "dir/sub") == 0);
+
+ /* Mixing file and directory. */
+ errno = 0; /* File onto dir. */
+ ASSERT (func (BASE "file", BASE "dir") == -1);
+ ASSERT (errno == EISDIR || errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "file", BASE "dir/") == -1);
+ ASSERT (errno == EISDIR || errno == ENOTDIR);
+ errno = 0; /* Dir onto file. */
+ ASSERT (func (BASE "dir", BASE "file") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "dir/", BASE "file") == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Hard links. */
+ ASSERT (func (BASE "file", BASE "file") == 0); /* File onto self. */
+ memset (&st, 0, sizeof st);
+ ASSERT (stat (BASE "file", &st) == 0);
+ ASSERT (st.st_size == 2);
+ ASSERT (func (BASE "dir", BASE "dir") == 0); /* Empty dir onto self. */
+ ASSERT (stat (BASE "dir", &st) == 0);
+ ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
+ ASSERT (func (BASE "dir", BASE "dir") == 0); /* Full dir onto self. */
+ ASSERT (unlink (BASE "dir/file") == 0);
+ {
+ /* Not all file systems support link. Mingw doesn't have
+ reliable st_nlink on hard links, but our implementation does
+ fail with EPERM on poor file systems, and we can detect the
+ inferior stat() via st_ino. Cygwin 1.5.x copies rather than
+ links files on those file systems, but there, st_nlink and
+ st_ino are reliable. */
+ int ret = link (BASE "file", BASE "file2");
+ if (!ret)
+ {
+ memset (&st, 0, sizeof st);
+ ASSERT (stat (BASE "file2", &st) == 0);
+ if (st.st_ino && st.st_nlink != 2)
+ {
+ ASSERT (unlink (BASE "file2") == 0);
+ errno = EPERM;
+ ret = -1;
+ }
+ }
+ if (ret == -1)
+ {
+ /* If the device does not support hard links, errno is
+ EPERM on Linux, EOPNOTSUPP on FreeBSD. */
+ switch (errno)
+ {
+ case EPERM:
+ case EOPNOTSUPP:
+ if (print)
+ fputs ("skipping test: "
+ "hard links not supported on this file system\n",
+ stderr);
+ ASSERT (unlink (BASE "file") == 0);
+ ASSERT (rmdir (BASE "dir") == 0);
+ return 77;
+ default:
+ perror ("link");
+ return 1;
+ }
+ }
+ ASSERT (ret == 0);
+ }
+ ASSERT (func (BASE "file", BASE "file2") == 0); /* File onto hard link. */
+ memset (&st, 0, sizeof st);
+ ASSERT (stat (BASE "file", &st) == 0);
+ ASSERT (st.st_size == 2);
+ memset (&st, 0, sizeof st);
+ ASSERT (stat (BASE "file2", &st) == 0);
+ ASSERT (st.st_size == 2);
+ ASSERT (unlink (BASE "file2") == 0);
+
+ /* Symlinks. */
+ if (symlink (BASE "file", BASE "link1"))
+ {
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ ASSERT (unlink (BASE "file") == 0);
+ ASSERT (rmdir (BASE "dir") == 0);
+ return 77;
+ }
+ ASSERT (func (BASE "link1", BASE "link2") == 0); /* Simple rename. */
+ ASSERT (stat (BASE "file", &st) == 0);
+ errno = 0;
+ ASSERT (lstat (BASE "link1", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link2", &st) == 0);
+ ASSERT (S_ISLNK (st.st_mode));
+ ASSERT (symlink (BASE "nowhere", BASE "link1") == 0); /* Overwrite. */
+ ASSERT (func (BASE "link2", BASE "link1") == 0);
+ memset (&st, 0, sizeof st);
+ ASSERT (stat (BASE "link1", &st) == 0);
+ ASSERT (st.st_size == 2);
+ errno = 0;
+ ASSERT (lstat (BASE "link2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (symlink (BASE "link2", BASE "link2") == 0); /* Symlink loop. */
+ ASSERT (func (BASE "link2", BASE "link2") == 0);
+ errno = 0;
+ ASSERT (func (BASE "link2/", BASE "link2") == -1);
+ ASSERT (errno == ELOOP || errno == ENOTDIR);
+ ASSERT (func (BASE "link2", BASE "link3") == 0);
+ ASSERT (unlink (BASE "link3") == 0);
+ ASSERT (symlink (BASE "nowhere", BASE "link2") == 0); /* Dangling link. */
+ ASSERT (func (BASE "link2", BASE "link3") == 0);
+ errno = 0;
+ ASSERT (lstat (BASE "link2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link3", &st) == 0);
+ errno = 0; /* Trailing slash on dangling. */
+ ASSERT (func (BASE "link3/", BASE "link2") == -1);
+ ASSERT (errno == ENOENT || errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "link3", BASE "link2/") == -1);
+ ASSERT (errno == ENOENT || errno == ENOTDIR);
+ errno = 0;
+ ASSERT (lstat (BASE "link2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link3", &st) == 0);
+ errno = 0; /* Trailing slash on link to file. */
+ ASSERT (func (BASE "link1/", BASE "link2") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "link1", BASE "link3/") == -1);
+ ASSERT (errno == ENOENT || errno == ENOTDIR);
+
+ /* Mixing symlink and file. */
+ ASSERT (close (creat (BASE "file2", 0600)) == 0); /* File onto link. */
+ ASSERT (func (BASE "file2", BASE "link3") == 0);
+ errno = 0;
+ ASSERT (stat (BASE "file2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link3", &st) == 0);
+ ASSERT (S_ISREG (st.st_mode));
+ ASSERT (unlink (BASE "link3") == 0);
+ ASSERT (symlink (BASE "nowhere", BASE "link2") == 0); /* Link onto file. */
+ ASSERT (close (creat (BASE "file2", 0600)) == 0);
+ ASSERT (func (BASE "link2", BASE "file2") == 0);
+ errno = 0;
+ ASSERT (lstat (BASE "link2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "file2", &st) == 0);
+ ASSERT (S_ISLNK (st.st_mode));
+ ASSERT (unlink (BASE "file2") == 0);
+ errno = 0; /* Trailing slash. */
+ ASSERT (func (BASE "file/", BASE "link1") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "file", BASE "link1/") == -1);
+ ASSERT (errno == ENOTDIR || errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "link1/", BASE "file") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "link1", BASE "file/") == -1);
+ ASSERT (errno == ENOTDIR || errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "file", &st) == 0);
+ ASSERT (S_ISREG (st.st_mode));
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link1", &st) == 0);
+ ASSERT (S_ISLNK (st.st_mode));
+
+ /* Mixing symlink and directory. */
+ errno = 0; /* Directory onto link. */
+ ASSERT (func (BASE "dir", BASE "link1") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "dir/", BASE "link1") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "dir", BASE "link1/") == -1);
+ ASSERT (errno == ENOTDIR);
+ errno = 0; /* Link onto directory. */
+ ASSERT (func (BASE "link1", BASE "dir") == -1);
+ ASSERT (errno == EISDIR || errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "link1", BASE "dir/") == -1);
+ ASSERT (errno == EISDIR || errno == ENOTDIR);
+ errno = 0;
+ ASSERT (func (BASE "link1/", BASE "dir") == -1);
+ ASSERT (errno == ENOTDIR);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link1", &st) == 0);
+ ASSERT (S_ISLNK (st.st_mode));
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "dir", &st) == 0);
+ ASSERT (S_ISDIR (st.st_mode));
+
+ /* POSIX requires rename("link-to-dir/","other") to rename "dir" and
+ leave "link-to-dir" dangling, but GNU rejects this. POSIX
+ requires rename("dir","dangling/") to create the directory so
+ that "dangling/" now resolves, but GNU rejects this. While we
+ prefer GNU behavior, we don't enforce it. However, we do test
+ that the system either follows POSIX in both cases, or follows
+ GNU. */
+ {
+ int result;
+ ASSERT (symlink (BASE "dir2", BASE "link2") == 0);
+ errno = 0;
+ result = func (BASE "dir", BASE "link2/");
+ if (result == 0)
+ {
+ /* POSIX. */
+ errno = 0;
+ ASSERT (lstat (BASE "dir", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "dir2", &st) == 0);
+ ASSERT (S_ISDIR (st.st_mode));
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link2", &st) == 0);
+ ASSERT (S_ISLNK (st.st_mode));
+ ASSERT (func (BASE "link2/", BASE "dir") == 0);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "dir", &st) == 0);
+ ASSERT (S_ISDIR (st.st_mode));
+ errno = 0;
+ ASSERT (lstat (BASE "dir2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link2", &st) == 0);
+ ASSERT (S_ISLNK (st.st_mode));
+ }
+ else
+ {
+ /* GNU. */
+ ASSERT (result == -1);
+ ASSERT (errno == ENOTDIR);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "dir", &st) == 0);
+ ASSERT (S_ISDIR (st.st_mode));
+ errno = 0;
+ ASSERT (lstat (BASE "dir2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link2", &st) == 0);
+ ASSERT (S_ISLNK (st.st_mode));
+ ASSERT (unlink (BASE "link2") == 0);
+ ASSERT (symlink (BASE "dir", BASE "link2") == 0);
+ errno = 0; /* OpenBSD notices that link2/ and dir are the same. */
+ result = func (BASE "link2/", BASE "dir");
+ if (result) /* GNU/Linux rejects attempts to use link2/. */
+ {
+ ASSERT (result == -1);
+ ASSERT (errno == ENOTDIR);
+ }
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "dir", &st) == 0);
+ ASSERT (S_ISDIR (st.st_mode));
+ errno = 0;
+ ASSERT (lstat (BASE "dir2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ memset (&st, 0, sizeof st);
+ ASSERT (lstat (BASE "link2", &st) == 0);
+ ASSERT (S_ISLNK (st.st_mode));
+ }
+ }
+
+ /* Clean up. */
+ ASSERT (unlink (BASE "file") == 0);
+ ASSERT (rmdir (BASE "dir") == 0);
+ ASSERT (unlink (BASE "link1") == 0);
+ ASSERT (unlink (BASE "link2") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-rmdir.c b/tests/gnu/test-rmdir.c
new file mode 100755
index 00000000..7b1ef37d
--- /dev/null
+++ b/tests/gnu/test-rmdir.c
@@ -0,0 +1,47 @@
+/* Tests of rmdir.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (rmdir, int, (char const *));
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "test-rmdir.t"
+
+#include "test-rmdir.h"
+
+int
+main (void)
+{
+ /* Remove any leftovers from a previous partial run. */
+ ignore_value (system ("rm -rf " BASE "*"));
+
+ return test_rmdir_func (rmdir, true);
+}
diff --git a/tests/gnu/test-rmdir.h b/tests/gnu/test-rmdir.h
new file mode 100755
index 00000000..6d5d56ef
--- /dev/null
+++ b/tests/gnu/test-rmdir.h
@@ -0,0 +1,101 @@
+/* Tests of rmdir.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+/* This file is designed to test both rmdir(n) and
+ unlinkat(AT_FDCWD,n,AT_REMOVEDIR). FUNC is the function to test.
+ Assumes that BASE and ASSERT are already defined, and that
+ appropriate headers are already included. If PRINT, then warn
+ before returning status 77 when symlinks are unsupported. */
+
+static int
+test_rmdir_func (int (*func) (char const *name), bool print)
+{
+ /* Setup. */
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
+
+ /* Basic error conditions. */
+ errno = 0;
+ ASSERT (func ("") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "nosuch") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "nosuch/") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (".") == -1);
+ ASSERT (errno == EINVAL || errno == EBUSY);
+ /* Resulting errno after ".." or "/" is too varied to test; it is
+ reasonable to see any of EINVAL, EBUSY, EEXIST, ENOTEMPTY,
+ EACCES, EPERM. */
+ ASSERT (func ("..") == -1);
+ ASSERT (func ("/") == -1);
+ ASSERT (func ("///") == -1);
+ errno = 0;
+ ASSERT (func (BASE "dir/file/") == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Non-empty directory. */
+ errno = 0;
+ ASSERT (func (BASE "dir") == -1);
+ ASSERT (errno == EEXIST || errno == ENOTEMPTY);
+
+ /* Non-directory. */
+ errno = 0;
+ ASSERT (func (BASE "dir/file") == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Empty directory. */
+ ASSERT (unlink (BASE "dir/file") == 0);
+ errno = 0;
+ ASSERT (func (BASE "dir/.//") == -1);
+ ASSERT (errno == EINVAL || errno == EBUSY);
+ ASSERT (func (BASE "dir") == 0);
+
+ /* Test symlink behavior. Specifying trailing slash should remove
+ referent directory (POSIX), or cause ENOTDIR failure (Linux), but
+ not touch symlink. We prefer the Linux behavior for its
+ intuitiveness (especially compared to rmdir("symlink-to-file/")),
+ but not enough to penalize POSIX systems with an rpl_rmdir. */
+ if (symlink (BASE "dir", BASE "link") != 0)
+ {
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ errno = 0;
+ if (func (BASE "link/") == 0)
+ {
+ struct stat st;
+ errno = 0;
+ ASSERT (stat (BASE "link", &st) == -1);
+ ASSERT (errno == ENOENT);
+ }
+ else
+ {
+ ASSERT (errno == ENOTDIR);
+ ASSERT (func (BASE "dir") == 0);
+ }
+ ASSERT (unlink (BASE "link") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-sched.c b/tests/gnu/test-sched.c
new file mode 100755
index 00000000..15680d41
--- /dev/null
+++ b/tests/gnu/test-sched.c
@@ -0,0 +1,38 @@
+/* Test of <sched.h> substitute.
+ Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <sched.h>
+
+/* Check that 'struct sched_param' is defined. */
+static struct sched_param a;
+
+/* Check that the SCHED_* macros are defined and compile-time constants. */
+int b[] = { SCHED_FIFO, SCHED_RR, SCHED_OTHER };
+
+static int f1;
+
+int
+main ()
+{
+ /* Check fields of 'struct sched_param'. */
+ f1 = a.sched_priority;
+
+ return 0;
+}
diff --git a/tests/gnu/test-setenv.c b/tests/gnu/test-setenv.c
new file mode 100755
index 00000000..de589c1b
--- /dev/null
+++ b/tests/gnu/test-setenv.c
@@ -0,0 +1,56 @@
+/* Tests of setenv.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (setenv, int, (char const *, char const *, int));
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+int
+main (void)
+{
+ /* Test overwriting. */
+ ASSERT (setenv ("a", "==", -1) == 0);
+ ASSERT (setenv ("a", "2", 0) == 0);
+ ASSERT (strcmp (getenv ("a"), "==") == 0);
+
+ /* Required to fail with EINVAL. */
+ errno = 0;
+ ASSERT (setenv ("", "", 1) == -1);
+ ASSERT (errno == EINVAL);
+ errno = 0;
+ ASSERT (setenv ("a=b", "", 0) == -1);
+ ASSERT (errno == EINVAL);
+#if 0
+ /* glibc and gnulib's implementation guarantee this, but POSIX no
+ longer requires it: http://austingroupbugs.net/view.php?id=185 */
+ errno = 0;
+ ASSERT (setenv (NULL, "", 0) == -1);
+ ASSERT (errno == EINVAL);
+#endif
+
+ return 0;
+}
diff --git a/tests/gnu/test-sigaction.c b/tests/gnu/test-sigaction.c
new file mode 100755
index 00000000..73579d96
--- /dev/null
+++ b/tests/gnu/test-sigaction.c
@@ -0,0 +1,116 @@
+/* Test of sigaction() function.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2008. */
+
+#include <config.h>
+
+#include <signal.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (sigaction, int, (int, struct sigaction const *,
+ struct sigaction *));
+
+#include <stddef.h>
+
+#include "macros.h"
+
+#ifndef SA_NOCLDSTOP
+# define SA_NOCLDSTOP 0
+#endif
+#ifndef SA_ONSTACK
+# define SA_ONSTACK 0
+#endif
+#ifndef SA_SIGINFO
+# define SA_SIGINFO 0
+#endif
+#ifndef SA_NOCLDWAIT
+# define SA_NOCLDWAIT 0
+#endif
+
+/* Define a mask of flags required by POSIX. Some implementations
+ provide other flags as extensions, such as SA_RESTORER, that we
+ must ignore in this test. */
+#define MASK_SA_FLAGS (SA_NOCLDSTOP | SA_ONSTACK | SA_RESETHAND | SA_RESTART \
+ | SA_SIGINFO | SA_NOCLDWAIT | SA_NODEFER)
+
+/* This test is unsafe in the presence of an asynchronous SIGABRT,
+ because we install a signal-handler that is intentionally not
+ async-safe. Hopefully, this does not lead to too many reports of
+ false failures, since people don't generally use 'kill -s SIGABRT'
+ to end a runaway program. */
+
+static void
+handler (int sig)
+{
+ static int entry_count;
+ struct sigaction sa;
+ ASSERT (sig == SIGABRT);
+ ASSERT (sigaction (SIGABRT, NULL, &sa) == 0);
+ ASSERT ((sa.sa_flags & SA_SIGINFO) == 0);
+ switch (entry_count++)
+ {
+ case 0:
+ ASSERT ((sa.sa_flags & SA_RESETHAND) == 0);
+ ASSERT (sa.sa_handler == handler);
+ break;
+ case 1:
+ /* This assertion fails on glibc-2.3.6 systems with LinuxThreads,
+ when this program is linked with -lpthread, due to the sigaction()
+ override in libpthread.so. */
+#if !defined __GLIBC__
+ ASSERT (sa.sa_handler == SIG_DFL);
+#endif
+ break;
+ default:
+ ASSERT (0);
+ }
+}
+
+int
+main (void)
+{
+ struct sigaction sa;
+ struct sigaction old_sa;
+ sa.sa_handler = handler;
+
+ sa.sa_flags = 0;
+ ASSERT (sigemptyset (&sa.sa_mask) == 0);
+ ASSERT (sigaction (SIGABRT, &sa, NULL) == 0);
+ ASSERT (raise (SIGABRT) == 0);
+
+ sa.sa_flags = SA_RESETHAND | SA_NODEFER;
+ ASSERT (sigaction (SIGABRT, &sa, &old_sa) == 0);
+ ASSERT ((old_sa.sa_flags & MASK_SA_FLAGS) == 0);
+ ASSERT (old_sa.sa_handler == handler);
+ ASSERT (raise (SIGABRT) == 0);
+
+ sa.sa_handler = SIG_DFL;
+ ASSERT (sigaction (SIGABRT, &sa, &old_sa) == 0);
+ ASSERT ((old_sa.sa_flags & SA_SIGINFO) == 0);
+#if !defined __GLIBC__ /* see above */
+ ASSERT (old_sa.sa_handler == SIG_DFL);
+#endif
+
+ sa.sa_handler = SIG_IGN;
+ ASSERT (sigaction (SIGABRT, &sa, NULL) == 0);
+ ASSERT (raise (SIGABRT) == 0);
+ ASSERT (sigaction (SIGABRT, NULL, &old_sa) == 0);
+ ASSERT (old_sa.sa_handler == SIG_IGN);
+ ASSERT (raise (SIGABRT) == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-signal.c b/tests/gnu/test-signal.c
new file mode 100755
index 00000000..e4258d3b
--- /dev/null
+++ b/tests/gnu/test-signal.c
@@ -0,0 +1,125 @@
+/* Test of <signal.h> substitute.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <signal.h>
+
+/* Check for required types. */
+struct
+{
+ size_t a;
+ uid_t b;
+ volatile sig_atomic_t c;
+ sigset_t d;
+ pid_t e;
+#if 0
+ /* Not guaranteed by gnulib. */
+ pthread_t f;
+ struct timespec g;
+#endif
+} s;
+
+int
+main (void)
+{
+ switch (0)
+ {
+ /* The following are guaranteed by C. */
+ case 0:
+ case SIGABRT:
+ case SIGFPE:
+ case SIGILL:
+ case SIGINT:
+ case SIGSEGV:
+ case SIGTERM:
+ /* The following is guaranteed by gnulib. */
+#if GNULIB_SIGPIPE || defined SIGPIPE
+ case SIGPIPE:
+#endif
+ /* Ensure no conflict with other standardized names. */
+#ifdef SIGALRM
+ case SIGALRM:
+#endif
+#ifdef SIGBUS
+ case SIGBUS:
+#endif
+#ifdef SIGCHLD
+ case SIGCHLD:
+#endif
+#ifdef SIGCONT
+ case SIGCONT:
+#endif
+#ifdef SIGHUP
+ case SIGHUP:
+#endif
+#ifdef SIGKILL
+ case SIGKILL:
+#endif
+#ifdef SIGQUIT
+ case SIGQUIT:
+#endif
+#ifdef SIGSTOP
+ case SIGSTOP:
+#endif
+#ifdef SIGTSTP
+ case SIGTSTP:
+#endif
+#ifdef SIGTTIN
+ case SIGTTIN:
+#endif
+#ifdef SIGTTOU
+ case SIGTTOU:
+#endif
+#ifdef SIGUSR1
+ case SIGUSR1:
+#endif
+#ifdef SIGUSR2
+ case SIGUSR2:
+#endif
+#ifdef SIGSYS
+ case SIGSYS:
+#endif
+#ifdef SIGTRAP
+ case SIGTRAP:
+#endif
+#ifdef SIGURG
+ case SIGURG:
+#endif
+#ifdef SIGVTALRM
+ case SIGVTALRM:
+#endif
+#ifdef SIGXCPU
+ case SIGXCPU:
+#endif
+#ifdef SIGXFSZ
+ case SIGXFSZ:
+#endif
+ /* SIGRTMIN and SIGRTMAX need not be compile-time constants. */
+#if 0
+# ifdef SIGRTMIN
+ case SIGRTMIN:
+# endif
+# ifdef SIGRTMAX
+ case SIGRTMAX:
+# endif
+#endif
+ ;
+ }
+ return s.a + s.b + s.c + s.e;
+}
diff --git a/tests/gnu/test-signbit.c b/tests/gnu/test-signbit.c
new file mode 100755
index 00000000..9581190c
--- /dev/null
+++ b/tests/gnu/test-signbit.c
@@ -0,0 +1,197 @@
+/* Test of signbit() substitute.
+ Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <math.h>
+
+/* signbit must be a macro. */
+#ifndef signbit
+# error missing declaration
+#endif
+
+#include <float.h>
+#include <limits.h>
+
+#include "macros.h"
+
+float zerof = 0.0f;
+double zerod = 0.0;
+long double zerol = 0.0L;
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0f.
+ So we use -zerof instead. */
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ So we use -zerod instead. */
+
+/* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
+ So we use minus_zerol instead.
+ IRIX cc can't put -0.0L into .data, but can compute at runtime.
+ Note that the expression -LDBL_MIN * LDBL_MIN does not work on other
+ platforms, such as when cross-compiling to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi
+static long double
+compute_minus_zerol (void)
+{
+ return -LDBL_MIN * LDBL_MIN;
+}
+# define minus_zerol compute_minus_zerol ()
+#else
+long double minus_zerol = -0.0L;
+#endif
+
+static void
+test_signbitf ()
+{
+ /* Finite values. */
+ ASSERT (!signbit (3.141f));
+ ASSERT (!signbit (3.141e30f));
+ ASSERT (!signbit (3.141e-30f));
+ ASSERT (signbit (-2.718f));
+ ASSERT (signbit (-2.718e30f));
+ ASSERT (signbit (-2.718e-30f));
+ /* Zeros. */
+ ASSERT (!signbit (0.0f));
+ if (1.0f / -zerof < 0)
+ ASSERT (signbit (-zerof));
+ else
+ ASSERT (!signbit (-zerof));
+ /* Infinite values. */
+ ASSERT (!signbit (1.0f / 0.0f));
+ ASSERT (signbit (-1.0f / 0.0f));
+ /* Quiet NaN. */
+ (void) signbit (zerof / zerof);
+#if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
+ /* Signalling NaN. */
+ {
+ #define NWORDS \
+ ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ typedef union { float value; unsigned int word[NWORDS]; } memory_float;
+ memory_float m;
+ m.value = zerof / zerof;
+# if FLT_EXPBIT0_BIT > 0
+ m.word[FLT_EXPBIT0_WORD] ^= (unsigned int) 1 << (FLT_EXPBIT0_BIT - 1);
+# else
+ m.word[FLT_EXPBIT0_WORD + (FLT_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+ if (FLT_EXPBIT0_WORD < NWORDS / 2)
+ m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT;
+ else
+ m.word[0] |= (unsigned int) 1;
+ (void) signbit (m.value);
+ #undef NWORDS
+ }
+#endif
+}
+
+static void
+test_signbitd ()
+{
+ /* Finite values. */
+ ASSERT (!signbit (3.141));
+ ASSERT (!signbit (3.141e30));
+ ASSERT (!signbit (3.141e-30));
+ ASSERT (signbit (-2.718));
+ ASSERT (signbit (-2.718e30));
+ ASSERT (signbit (-2.718e-30));
+ /* Zeros. */
+ ASSERT (!signbit (0.0));
+ if (1.0 / -zerod < 0)
+ ASSERT (signbit (-zerod));
+ else
+ ASSERT (!signbit (-zerod));
+ /* Infinite values. */
+ ASSERT (!signbit (1.0 / 0.0));
+ ASSERT (signbit (-1.0 / 0.0));
+ /* Quiet NaN. */
+ (void) signbit (zerod / zerod);
+#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
+ /* Signalling NaN. */
+ {
+ #define NWORDS \
+ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ typedef union { double value; unsigned int word[NWORDS]; } memory_double;
+ memory_double m;
+ m.value = zerod / zerod;
+# if DBL_EXPBIT0_BIT > 0
+ m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1);
+# else
+ m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+ m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ |= (unsigned int) 1 << DBL_EXPBIT0_BIT;
+ (void) signbit (m.value);
+ #undef NWORDS
+ }
+#endif
+}
+
+static void
+test_signbitl ()
+{
+ /* Finite values. */
+ ASSERT (!signbit (3.141L));
+ ASSERT (!signbit (3.141e30L));
+ ASSERT (!signbit (3.141e-30L));
+ ASSERT (signbit (-2.718L));
+ ASSERT (signbit (-2.718e30L));
+ ASSERT (signbit (-2.718e-30L));
+ /* Zeros. */
+ ASSERT (!signbit (0.0L));
+ if (1.0L / minus_zerol < 0)
+ ASSERT (signbit (minus_zerol));
+ else
+ ASSERT (!signbit (minus_zerol));
+ /* Infinite values. */
+ ASSERT (!signbit (1.0L / 0.0L));
+ ASSERT (signbit (-1.0L / 0.0L));
+ /* Quiet NaN. */
+ (void) signbit (zerol / zerol);
+#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
+ /* Signalling NaN. */
+ {
+ #define NWORDS \
+ ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ typedef union { long double value; unsigned int word[NWORDS]; } memory_long_double;
+ memory_long_double m;
+ m.value = zerol / zerol;
+# if LDBL_EXPBIT0_BIT > 0
+ m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1);
+# else
+ m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+ m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
+ |= (unsigned int) 1 << LDBL_EXPBIT0_BIT;
+ (void) signbit (m.value);
+ #undef NWORDS
+ }
+#endif
+}
+
+int
+main ()
+{
+ test_signbitf ();
+ test_signbitd ();
+ test_signbitl ();
+ return 0;
+}
diff --git a/tests/gnu/test-snprintf-posix.c b/tests/gnu/test-snprintf-posix.c
new file mode 100755
index 00000000..452e90ce
--- /dev/null
+++ b/tests/gnu/test-snprintf-posix.c
@@ -0,0 +1,38 @@
+/* Test of POSIX compatible snprintf() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <float.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-snprintf-posix.h"
+
+int
+main (int argc, char *argv[])
+{
+ test_function (snprintf);
+ return 0;
+}
diff --git a/tests/gnu/test-snprintf-posix.h b/tests/gnu/test-snprintf-posix.h
new file mode 100755
index 00000000..b796d5ba
--- /dev/null
+++ b/tests/gnu/test-snprintf-posix.h
@@ -0,0 +1,3113 @@
+/* Test of POSIX compatible vsnprintf() and snprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include "nan.h"
+
+/* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0. */
+static int
+have_minus_zero ()
+{
+ static double plus_zero = 0.0;
+ double minus_zero = - plus_zero;
+ return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
+}
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ So we use -zerod instead. */
+double zerod = 0.0;
+
+/* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
+ So we use minus_zerol instead.
+ IRIX cc can't put -0.0L into .data, but can compute at runtime.
+ Note that the expression -LDBL_MIN * LDBL_MIN does not work on other
+ platforms, such as when cross-compiling to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi
+static long double
+compute_minus_zerol (void)
+{
+ return -LDBL_MIN * LDBL_MIN;
+}
+# define minus_zerol compute_minus_zerol ()
+#else
+long double minus_zerol = -0.0L;
+#endif
+
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+ of 'unsigned int' words. */
+#ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+ ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
+ (unsigned int) (mantlo) << 16 \
+ }
+#else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { mantlo, manthi, exponent }
+#endif
+
+static int
+strmatch (const char *pattern, const char *string)
+{
+ if (strlen (pattern) != strlen (string))
+ return 0;
+ for (; *pattern != '\0'; pattern++, string++)
+ if (*pattern != '*' && *string != *pattern)
+ return 0;
+ return 1;
+}
+
+/* Test whether string[start_index..end_index-1] is a valid textual
+ representation of NaN. */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
+{
+ char buf[8];
+ int size;
+
+ /* Test return value convention. */
+
+ for (size = 0; size <= 8; size++)
+ {
+ int retval;
+
+ memcpy (buf, "DEADBEEF", 8);
+ retval = my_snprintf (buf, size, "%d", 12345);
+ ASSERT (retval == 5);
+ if (size < 6)
+ {
+ if (size > 0)
+ {
+ ASSERT (memcmp (buf, "12345", size - 1) == 0);
+ ASSERT (buf[size - 1] == '\0');
+ }
+ ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
+ }
+ else
+ {
+ ASSERT (memcmp (buf, "12345\0EF", 8) == 0);
+ }
+ }
+
+ /* Test support of size specifiers as in C99. */
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
+ ASSERT (strcmp (result, "12345671 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%zu %d", (size_t) 12345672, 33, 44, 55);
+ ASSERT (strcmp (result, "12345672 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
+ ASSERT (strcmp (result, "12345673 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", (long double) 1.5, 33, 44, 55);
+ ASSERT (strcmp (result, "1.5 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
+ output of floating-point numbers. */
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%a %d", 3.1416015625, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.922p+1 33") == 0
+ || strcmp (result, "0x3.244p+0 33") == 0
+ || strcmp (result, "0x6.488p-1 33") == 0
+ || strcmp (result, "0xc.91p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%A %d", -3.1416015625, 33, 44, 55);
+ ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
+ || strcmp (result, "-0X3.244P+0 33") == 0
+ || strcmp (result, "-0X6.488P-1 33") == 0
+ || strcmp (result, "-0XC.91P-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%a %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%a %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%a %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%a %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%a %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding near the decimal point. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0a %d", 1.5, 33, 44, 55);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 0. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0a %d", 1.51, 33, 44, 55);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 1. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.1a %d", 1.51, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.8p+0 33") == 0
+ || strcmp (result, "0x3.0p-1 33") == 0
+ || strcmp (result, "0x6.1p-2 33") == 0
+ || strcmp (result, "0xc.1p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 2. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2a %d", 1.51, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.83p+0 33") == 0
+ || strcmp (result, "0x3.05p-1 33") == 0
+ || strcmp (result, "0x6.0ap-2 33") == 0
+ || strcmp (result, "0xc.14p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 3. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.3a %d", 1.51, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.829p+0 33") == 0
+ || strcmp (result, "0x3.052p-1 33") == 0
+ || strcmp (result, "0x6.0a4p-2 33") == 0
+ || strcmp (result, "0xc.148p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.3a %d", 1.49999, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.800p+0 33") == 0
+ || strcmp (result, "0x3.000p-1 33") == 0
+ || strcmp (result, "0x6.000p-2 33") == 0
+ || strcmp (result, "0xc.000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.1a %d", 1.999, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%10a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.10a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
+ || strcmp (result, "0x3.8000000000p-1 33") == 0
+ || strcmp (result, "0x7.0000000000p-2 33") == 0
+ || strcmp (result, "0xe.0000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Large precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.50a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
+ || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
+ || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
+ || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%-10a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7p-2 33") == 0
+ || strcmp (result, "0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%+a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
+ || strcmp (result, "+0x3.8p-1 33") == 0
+ || strcmp (result, "+0x7p-2 33") == 0
+ || strcmp (result, "+0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "% a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7.p-2 33") == 0
+ || strcmp (result, "0xe.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#a %d", 1.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.p+0 33") == 0
+ || strcmp (result, "0x2.p-1 33") == 0
+ || strcmp (result, "0x4.p-2 33") == 0
+ || strcmp (result, "0x8.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%010a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x001.cp+0 33") == 0
+ || strcmp (result, "0x003.8p-1 33") == 0
+ || strcmp (result, "0x00007p-2 33") == 0
+ || strcmp (result, "0x0000ep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%010a %d", 1.0 / 0.0, 33, 44, 55);
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strcmp (result, " inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%050a %d", NaNd (), 33, 44, 55);
+ /* "0000000nan 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", 3.1416015625L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.922p+1 33") == 0
+ || strcmp (result, "0x3.244p+0 33") == 0
+ || strcmp (result, "0x6.488p-1 33") == 0
+ || strcmp (result, "0xc.91p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LA %d", -3.1416015625L, 33, 44, 55);
+ ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
+ || strcmp (result, "-0X3.244P+0 33") == 0
+ || strcmp (result, "-0X6.488P-1 33") == 0
+ || strcmp (result, "-0XC.91P-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#endif
+
+ { /* Rounding near the decimal point. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0La %d", 1.5L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 0. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0La %d", 1.51L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 1. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.1La %d", 1.51L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.8p+0 33") == 0
+ || strcmp (result, "0x3.0p-1 33") == 0
+ || strcmp (result, "0x6.1p-2 33") == 0
+ || strcmp (result, "0xc.1p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 2. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2La %d", 1.51L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.83p+0 33") == 0
+ || strcmp (result, "0x3.05p-1 33") == 0
+ || strcmp (result, "0x6.0ap-2 33") == 0
+ || strcmp (result, "0xc.14p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 3. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.3La %d", 1.51L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.829p+0 33") == 0
+ || strcmp (result, "0x3.052p-1 33") == 0
+ || strcmp (result, "0x6.0a4p-2 33") == 0
+ || strcmp (result, "0xc.148p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.3La %d", 1.49999L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.800p+0 33") == 0
+ || strcmp (result, "0x3.000p-1 33") == 0
+ || strcmp (result, "0x6.000p-2 33") == 0
+ || strcmp (result, "0xc.000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
+ glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.1La %d", 1.999L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%10La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.10La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
+ || strcmp (result, "0x3.8000000000p-1 33") == 0
+ || strcmp (result, "0x7.0000000000p-2 33") == 0
+ || strcmp (result, "0xe.0000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Large precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.50La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
+ || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
+ || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
+ || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%-10La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7p-2 33") == 0
+ || strcmp (result, "0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%+La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
+ || strcmp (result, "+0x3.8p-1 33") == 0
+ || strcmp (result, "+0x7p-2 33") == 0
+ || strcmp (result, "+0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "% La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7.p-2 33") == 0
+ || strcmp (result, "0xe.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#La %d", 1.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.p+0 33") == 0
+ || strcmp (result, "0x2.p-1 33") == 0
+ || strcmp (result, "0x4.p-2 33") == 0
+ || strcmp (result, "0x8.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%010La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x001.cp+0 33") == 0
+ || strcmp (result, "0x003.8p-1 33") == 0
+ || strcmp (result, "0x00007p-2 33") == 0
+ || strcmp (result, "0x0000ep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%010La %d", 1.0L / 0.0L, 33, 44, 55);
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strcmp (result, " inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%050La %d", NaNl (), 33, 44, 55);
+ /* "0000000nan 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %f format directive. */
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f %d", 12.75, 33, 44, 55);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f %d", 1234567.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "0.000000" },
+ { 1.234321234321234e-36, "0.000000" },
+ { 1.234321234321234e-35, "0.000000" },
+ { 1.234321234321234e-34, "0.000000" },
+ { 1.234321234321234e-33, "0.000000" },
+ { 1.234321234321234e-32, "0.000000" },
+ { 1.234321234321234e-31, "0.000000" },
+ { 1.234321234321234e-30, "0.000000" },
+ { 1.234321234321234e-29, "0.000000" },
+ { 1.234321234321234e-28, "0.000000" },
+ { 1.234321234321234e-27, "0.000000" },
+ { 1.234321234321234e-26, "0.000000" },
+ { 1.234321234321234e-25, "0.000000" },
+ { 1.234321234321234e-24, "0.000000" },
+ { 1.234321234321234e-23, "0.000000" },
+ { 1.234321234321234e-22, "0.000000" },
+ { 1.234321234321234e-21, "0.000000" },
+ { 1.234321234321234e-20, "0.000000" },
+ { 1.234321234321234e-19, "0.000000" },
+ { 1.234321234321234e-18, "0.000000" },
+ { 1.234321234321234e-17, "0.000000" },
+ { 1.234321234321234e-16, "0.000000" },
+ { 1.234321234321234e-15, "0.000000" },
+ { 1.234321234321234e-14, "0.000000" },
+ { 1.234321234321234e-13, "0.000000" },
+ { 1.234321234321234e-12, "0.000000" },
+ { 1.234321234321234e-11, "0.000000" },
+ { 1.234321234321234e-10, "0.000000" },
+ { 1.234321234321234e-9, "0.000000" },
+ { 1.234321234321234e-8, "0.000000" },
+ { 1.234321234321234e-7, "0.000000" },
+ { 1.234321234321234e-6, "0.000001" },
+ { 1.234321234321234e-5, "0.000012" },
+ { 1.234321234321234e-4, "0.000123" },
+ { 1.234321234321234e-3, "0.001234" },
+ { 1.234321234321234e-2, "0.012343" },
+ { 1.234321234321234e-1, "0.123432" },
+ { 1.234321234321234, "1.234321" },
+ { 1.234321234321234e1, "12.343212" },
+ { 1.234321234321234e2, "123.432123" },
+ { 1.234321234321234e3, "1234.321234" },
+ { 1.234321234321234e4, "12343.212343" },
+ { 1.234321234321234e5, "123432.123432" },
+ { 1.234321234321234e6, "1234321.234321" },
+ { 1.234321234321234e7, "12343212.343212" },
+ { 1.234321234321234e8, "123432123.432123" },
+ { 1.234321234321234e9, "1234321234.321234" },
+ { 1.234321234321234e10, "12343212343.2123**" },
+ { 1.234321234321234e11, "123432123432.123***" },
+ { 1.234321234321234e12, "1234321234321.23****" },
+ { 1.234321234321234e13, "12343212343212.3*****" },
+ { 1.234321234321234e14, "123432123432123.******" },
+ { 1.234321234321234e15, "1234321234321234.000000" },
+ { 1.234321234321234e16, "123432123432123**.000000" },
+ { 1.234321234321234e17, "123432123432123***.000000" },
+ { 1.234321234321234e18, "123432123432123****.000000" },
+ { 1.234321234321234e19, "123432123432123*****.000000" },
+ { 1.234321234321234e20, "123432123432123******.000000" },
+ { 1.234321234321234e21, "123432123432123*******.000000" },
+ { 1.234321234321234e22, "123432123432123********.000000" },
+ { 1.234321234321234e23, "123432123432123*********.000000" },
+ { 1.234321234321234e24, "123432123432123**********.000000" },
+ { 1.234321234321234e25, "123432123432123***********.000000" },
+ { 1.234321234321234e26, "123432123432123************.000000" },
+ { 1.234321234321234e27, "123432123432123*************.000000" },
+ { 1.234321234321234e28, "123432123432123**************.000000" },
+ { 1.234321234321234e29, "123432123432123***************.000000" },
+ { 1.234321234321234e30, "123432123432123****************.000000" },
+ { 1.234321234321234e31, "123432123432123*****************.000000" },
+ { 1.234321234321234e32, "123432123432123******************.000000" },
+ { 1.234321234321234e33, "123432123432123*******************.000000" },
+ { 1.234321234321234e34, "123432123432123********************.000000" },
+ { 1.234321234321234e35, "123432123432123*********************.000000" },
+ { 1.234321234321234e36, "123432123432123**********************.000000" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f", data[k].value);
+ ASSERT (strmatch (data[k].string, result));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f %d", -0.03125, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%f %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%10f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%-10f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%+f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "% f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015f %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015f %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%050f %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.f %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2f %d", 999.951, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2f %d", 999.996, 33, 44, 55);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", 12.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", 1234567.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "0.000000" },
+ { 1.234321234321234e-36L, "0.000000" },
+ { 1.234321234321234e-35L, "0.000000" },
+ { 1.234321234321234e-34L, "0.000000" },
+ { 1.234321234321234e-33L, "0.000000" },
+ { 1.234321234321234e-32L, "0.000000" },
+ { 1.234321234321234e-31L, "0.000000" },
+ { 1.234321234321234e-30L, "0.000000" },
+ { 1.234321234321234e-29L, "0.000000" },
+ { 1.234321234321234e-28L, "0.000000" },
+ { 1.234321234321234e-27L, "0.000000" },
+ { 1.234321234321234e-26L, "0.000000" },
+ { 1.234321234321234e-25L, "0.000000" },
+ { 1.234321234321234e-24L, "0.000000" },
+ { 1.234321234321234e-23L, "0.000000" },
+ { 1.234321234321234e-22L, "0.000000" },
+ { 1.234321234321234e-21L, "0.000000" },
+ { 1.234321234321234e-20L, "0.000000" },
+ { 1.234321234321234e-19L, "0.000000" },
+ { 1.234321234321234e-18L, "0.000000" },
+ { 1.234321234321234e-17L, "0.000000" },
+ { 1.234321234321234e-16L, "0.000000" },
+ { 1.234321234321234e-15L, "0.000000" },
+ { 1.234321234321234e-14L, "0.000000" },
+ { 1.234321234321234e-13L, "0.000000" },
+ { 1.234321234321234e-12L, "0.000000" },
+ { 1.234321234321234e-11L, "0.000000" },
+ { 1.234321234321234e-10L, "0.000000" },
+ { 1.234321234321234e-9L, "0.000000" },
+ { 1.234321234321234e-8L, "0.000000" },
+ { 1.234321234321234e-7L, "0.000000" },
+ { 1.234321234321234e-6L, "0.000001" },
+ { 1.234321234321234e-5L, "0.000012" },
+ { 1.234321234321234e-4L, "0.000123" },
+ { 1.234321234321234e-3L, "0.001234" },
+ { 1.234321234321234e-2L, "0.012343" },
+ { 1.234321234321234e-1L, "0.123432" },
+ { 1.234321234321234L, "1.234321" },
+ { 1.234321234321234e1L, "12.343212" },
+ { 1.234321234321234e2L, "123.432123" },
+ { 1.234321234321234e3L, "1234.321234" },
+ { 1.234321234321234e4L, "12343.212343" },
+ { 1.234321234321234e5L, "123432.123432" },
+ { 1.234321234321234e6L, "1234321.234321" },
+ { 1.234321234321234e7L, "12343212.343212" },
+ { 1.234321234321234e8L, "123432123.432123" },
+ { 1.234321234321234e9L, "1234321234.321234" },
+ { 1.234321234321234e10L, "12343212343.2123**" },
+ { 1.234321234321234e11L, "123432123432.123***" },
+ { 1.234321234321234e12L, "1234321234321.23****" },
+ { 1.234321234321234e13L, "12343212343212.3*****" },
+ { 1.234321234321234e14L, "123432123432123.******" },
+ { 1.234321234321234e15L, "1234321234321234.000000" },
+ { 1.234321234321234e16L, "123432123432123**.000000" },
+ { 1.234321234321234e17L, "123432123432123***.000000" },
+ { 1.234321234321234e18L, "123432123432123****.000000" },
+ { 1.234321234321234e19L, "123432123432123*****.000000" },
+ { 1.234321234321234e20L, "123432123432123******.000000" },
+ { 1.234321234321234e21L, "123432123432123*******.000000" },
+ { 1.234321234321234e22L, "123432123432123********.000000" },
+ { 1.234321234321234e23L, "123432123432123*********.000000" },
+ { 1.234321234321234e24L, "123432123432123**********.000000" },
+ { 1.234321234321234e25L, "123432123432123***********.000000" },
+ { 1.234321234321234e26L, "123432123432123************.000000" },
+ { 1.234321234321234e27L, "123432123432123*************.000000" },
+ { 1.234321234321234e28L, "123432123432123**************.000000" },
+ { 1.234321234321234e29L, "123432123432123***************.000000" },
+ { 1.234321234321234e30L, "123432123432123****************.000000" },
+ { 1.234321234321234e31L, "123432123432123*****************.000000" },
+ { 1.234321234321234e32L, "123432123432123******************.000000" },
+ { 1.234321234321234e33L, "123432123432123*******************.000000" },
+ { 1.234321234321234e34L, "123432123432123********************.000000" },
+ { 1.234321234321234e35L, "123432123432123*********************.000000" },
+ { 1.234321234321234e36L, "123432123432123**********************.000000" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf", data[k].value);
+ ASSERT (strmatch (data[k].string, result));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", -0.03125L, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#endif
+
+ { /* Width. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%10Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%-10Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%+Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "% Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015Lf %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%050Lf %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.Lf %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2Lf %d", 999.951L, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2Lf %d", 999.996L, 33, 44, 55);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %F format directive. */
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%F %d", 12.75, 33, 44, 55);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%F %d", 1234567.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%F %d", -0.03125, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%F %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%F %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%F %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "INF 33") == 0
+ || strcmp (result, "INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%F %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-INF 33") == 0
+ || strcmp (result, "-INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%F %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 1)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015F %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015F %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, " -INF 33") == 0
+ || strcmp (result, " -INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.F %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2F %d", 999.951, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2F %d", 999.996, 33, 44, 55);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LF %d", 12.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LF %d", 1234567.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LF %d", -0.03125L, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LF %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LF %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LF %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "INF 33") == 0
+ || strcmp (result, "INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LF %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-INF 33") == 0
+ || strcmp (result, "-INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%LF %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 1)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015LF %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, " -INF 33") == 0
+ || strcmp (result, " -INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.LF %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2LF %d", 999.951L, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.2LF %d", 999.996L, 33, 44, 55);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %e format directive. */
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e %d", 12.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.275000e+01 33") == 0
+ || strcmp (result, "1.275000e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e %d", 1234567.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1.234567e+06 33") == 0
+ || strcmp (result, "1.234567e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "1.234321e-37" },
+ { 1.234321234321234e-36, "1.234321e-36" },
+ { 1.234321234321234e-35, "1.234321e-35" },
+ { 1.234321234321234e-34, "1.234321e-34" },
+ { 1.234321234321234e-33, "1.234321e-33" },
+ { 1.234321234321234e-32, "1.234321e-32" },
+ { 1.234321234321234e-31, "1.234321e-31" },
+ { 1.234321234321234e-30, "1.234321e-30" },
+ { 1.234321234321234e-29, "1.234321e-29" },
+ { 1.234321234321234e-28, "1.234321e-28" },
+ { 1.234321234321234e-27, "1.234321e-27" },
+ { 1.234321234321234e-26, "1.234321e-26" },
+ { 1.234321234321234e-25, "1.234321e-25" },
+ { 1.234321234321234e-24, "1.234321e-24" },
+ { 1.234321234321234e-23, "1.234321e-23" },
+ { 1.234321234321234e-22, "1.234321e-22" },
+ { 1.234321234321234e-21, "1.234321e-21" },
+ { 1.234321234321234e-20, "1.234321e-20" },
+ { 1.234321234321234e-19, "1.234321e-19" },
+ { 1.234321234321234e-18, "1.234321e-18" },
+ { 1.234321234321234e-17, "1.234321e-17" },
+ { 1.234321234321234e-16, "1.234321e-16" },
+ { 1.234321234321234e-15, "1.234321e-15" },
+ { 1.234321234321234e-14, "1.234321e-14" },
+ { 1.234321234321234e-13, "1.234321e-13" },
+ { 1.234321234321234e-12, "1.234321e-12" },
+ { 1.234321234321234e-11, "1.234321e-11" },
+ { 1.234321234321234e-10, "1.234321e-10" },
+ { 1.234321234321234e-9, "1.234321e-09" },
+ { 1.234321234321234e-8, "1.234321e-08" },
+ { 1.234321234321234e-7, "1.234321e-07" },
+ { 1.234321234321234e-6, "1.234321e-06" },
+ { 1.234321234321234e-5, "1.234321e-05" },
+ { 1.234321234321234e-4, "1.234321e-04" },
+ { 1.234321234321234e-3, "1.234321e-03" },
+ { 1.234321234321234e-2, "1.234321e-02" },
+ { 1.234321234321234e-1, "1.234321e-01" },
+ { 1.234321234321234, "1.234321e+00" },
+ { 1.234321234321234e1, "1.234321e+01" },
+ { 1.234321234321234e2, "1.234321e+02" },
+ { 1.234321234321234e3, "1.234321e+03" },
+ { 1.234321234321234e4, "1.234321e+04" },
+ { 1.234321234321234e5, "1.234321e+05" },
+ { 1.234321234321234e6, "1.234321e+06" },
+ { 1.234321234321234e7, "1.234321e+07" },
+ { 1.234321234321234e8, "1.234321e+08" },
+ { 1.234321234321234e9, "1.234321e+09" },
+ { 1.234321234321234e10, "1.234321e+10" },
+ { 1.234321234321234e11, "1.234321e+11" },
+ { 1.234321234321234e12, "1.234321e+12" },
+ { 1.234321234321234e13, "1.234321e+13" },
+ { 1.234321234321234e14, "1.234321e+14" },
+ { 1.234321234321234e15, "1.234321e+15" },
+ { 1.234321234321234e16, "1.234321e+16" },
+ { 1.234321234321234e17, "1.234321e+17" },
+ { 1.234321234321234e18, "1.234321e+18" },
+ { 1.234321234321234e19, "1.234321e+19" },
+ { 1.234321234321234e20, "1.234321e+20" },
+ { 1.234321234321234e21, "1.234321e+21" },
+ { 1.234321234321234e22, "1.234321e+22" },
+ { 1.234321234321234e23, "1.234321e+23" },
+ { 1.234321234321234e24, "1.234321e+24" },
+ { 1.234321234321234e25, "1.234321e+25" },
+ { 1.234321234321234e26, "1.234321e+26" },
+ { 1.234321234321234e27, "1.234321e+27" },
+ { 1.234321234321234e28, "1.234321e+28" },
+ { 1.234321234321234e29, "1.234321e+29" },
+ { 1.234321234321234e30, "1.234321e+30" },
+ { 1.234321234321234e31, "1.234321e+31" },
+ { 1.234321234321234e32, "1.234321e+32" },
+ { 1.234321234321234e33, "1.234321e+33" },
+ { 1.234321234321234e34, "1.234321e+34" },
+ { 1.234321234321234e35, "1.234321e+35" },
+ { 1.234321234321234e36, "1.234321e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e %d", -0.03125, 33, 44, 55);
+ ASSERT (strcmp (result, "-3.125000e-02 33") == 0
+ || strcmp (result, "-3.125000e-002 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000e+00 33") == 0
+ || strcmp (result, "0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000e+00 33") == 0
+ || strcmp (result, "-0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%e %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%15e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%-15e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%+e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.750000e+00 33") == 0
+ || strcmp (result, "+1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "% e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "2.e+00 33") == 0
+ || strcmp (result, "2.e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.e %d", 9.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015e %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0001.234000e+03 33") == 0
+ || strcmp (result, "001.234000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015e %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%050e %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.e %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4e %d", 999.951, 33, 44, 55);
+ ASSERT (strcmp (result, "9.9995e+02 33") == 0
+ || strcmp (result, "9.9995e+002 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4e %d", 999.996, 33, 44, 55);
+ ASSERT (strcmp (result, "1.0000e+03 33") == 0
+ || strcmp (result, "1.0000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", 12.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.275000e+01 33") == 0
+ || strcmp (result, "1.275000e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", 1234567.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.234567e+06 33") == 0
+ || strcmp (result, "1.234567e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "1.234321e-37" },
+ { 1.234321234321234e-36L, "1.234321e-36" },
+ { 1.234321234321234e-35L, "1.234321e-35" },
+ { 1.234321234321234e-34L, "1.234321e-34" },
+ { 1.234321234321234e-33L, "1.234321e-33" },
+ { 1.234321234321234e-32L, "1.234321e-32" },
+ { 1.234321234321234e-31L, "1.234321e-31" },
+ { 1.234321234321234e-30L, "1.234321e-30" },
+ { 1.234321234321234e-29L, "1.234321e-29" },
+ { 1.234321234321234e-28L, "1.234321e-28" },
+ { 1.234321234321234e-27L, "1.234321e-27" },
+ { 1.234321234321234e-26L, "1.234321e-26" },
+ { 1.234321234321234e-25L, "1.234321e-25" },
+ { 1.234321234321234e-24L, "1.234321e-24" },
+ { 1.234321234321234e-23L, "1.234321e-23" },
+ { 1.234321234321234e-22L, "1.234321e-22" },
+ { 1.234321234321234e-21L, "1.234321e-21" },
+ { 1.234321234321234e-20L, "1.234321e-20" },
+ { 1.234321234321234e-19L, "1.234321e-19" },
+ { 1.234321234321234e-18L, "1.234321e-18" },
+ { 1.234321234321234e-17L, "1.234321e-17" },
+ { 1.234321234321234e-16L, "1.234321e-16" },
+ { 1.234321234321234e-15L, "1.234321e-15" },
+ { 1.234321234321234e-14L, "1.234321e-14" },
+ { 1.234321234321234e-13L, "1.234321e-13" },
+ { 1.234321234321234e-12L, "1.234321e-12" },
+ { 1.234321234321234e-11L, "1.234321e-11" },
+ { 1.234321234321234e-10L, "1.234321e-10" },
+ { 1.234321234321234e-9L, "1.234321e-09" },
+ { 1.234321234321234e-8L, "1.234321e-08" },
+ { 1.234321234321234e-7L, "1.234321e-07" },
+ { 1.234321234321234e-6L, "1.234321e-06" },
+ { 1.234321234321234e-5L, "1.234321e-05" },
+ { 1.234321234321234e-4L, "1.234321e-04" },
+ { 1.234321234321234e-3L, "1.234321e-03" },
+ { 1.234321234321234e-2L, "1.234321e-02" },
+ { 1.234321234321234e-1L, "1.234321e-01" },
+ { 1.234321234321234L, "1.234321e+00" },
+ { 1.234321234321234e1L, "1.234321e+01" },
+ { 1.234321234321234e2L, "1.234321e+02" },
+ { 1.234321234321234e3L, "1.234321e+03" },
+ { 1.234321234321234e4L, "1.234321e+04" },
+ { 1.234321234321234e5L, "1.234321e+05" },
+ { 1.234321234321234e6L, "1.234321e+06" },
+ { 1.234321234321234e7L, "1.234321e+07" },
+ { 1.234321234321234e8L, "1.234321e+08" },
+ { 1.234321234321234e9L, "1.234321e+09" },
+ { 1.234321234321234e10L, "1.234321e+10" },
+ { 1.234321234321234e11L, "1.234321e+11" },
+ { 1.234321234321234e12L, "1.234321e+12" },
+ { 1.234321234321234e13L, "1.234321e+13" },
+ { 1.234321234321234e14L, "1.234321e+14" },
+ { 1.234321234321234e15L, "1.234321e+15" },
+ { 1.234321234321234e16L, "1.234321e+16" },
+ { 1.234321234321234e17L, "1.234321e+17" },
+ { 1.234321234321234e18L, "1.234321e+18" },
+ { 1.234321234321234e19L, "1.234321e+19" },
+ { 1.234321234321234e20L, "1.234321e+20" },
+ { 1.234321234321234e21L, "1.234321e+21" },
+ { 1.234321234321234e22L, "1.234321e+22" },
+ { 1.234321234321234e23L, "1.234321e+23" },
+ { 1.234321234321234e24L, "1.234321e+24" },
+ { 1.234321234321234e25L, "1.234321e+25" },
+ { 1.234321234321234e26L, "1.234321e+26" },
+ { 1.234321234321234e27L, "1.234321e+27" },
+ { 1.234321234321234e28L, "1.234321e+28" },
+ { 1.234321234321234e29L, "1.234321e+29" },
+ { 1.234321234321234e30L, "1.234321e+30" },
+ { 1.234321234321234e31L, "1.234321e+31" },
+ { 1.234321234321234e32L, "1.234321e+32" },
+ { 1.234321234321234e33L, "1.234321e+33" },
+ { 1.234321234321234e34L, "1.234321e+34" },
+ { 1.234321234321234e35L, "1.234321e+35" },
+ { 1.234321234321234e36L, "1.234321e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", -0.03125L, 33, 44, 55);
+ ASSERT (strcmp (result, "-3.125000e-02 33") == 0
+ || strcmp (result, "-3.125000e-002 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000e+00 33") == 0
+ || strcmp (result, "0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000e+00 33") == 0
+ || strcmp (result, "-0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#endif
+
+ { /* Width. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%15Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%-15Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%+Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.750000e+00 33") == 0
+ || strcmp (result, "+1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "% Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "2.e+00 33") == 0
+ || strcmp (result, "2.e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.Le %d", 9.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015Le %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0001.234000e+03 33") == 0
+ || strcmp (result, "001.234000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015Le %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%050Le %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.Le %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4Le %d", 999.951L, 33, 44, 55);
+ ASSERT (strcmp (result, "9.9995e+02 33") == 0
+ || strcmp (result, "9.9995e+002 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4Le %d", 999.996L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.0000e+03 33") == 0
+ || strcmp (result, "1.0000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %g format directive. */
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g %d", 12.75, 33, 44, 55);
+ ASSERT (strcmp (result, "12.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g %d", 1234567.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1.23457e+06 33") == 0
+ || strcmp (result, "1.23457e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "1.23432e-37" },
+ { 1.234321234321234e-36, "1.23432e-36" },
+ { 1.234321234321234e-35, "1.23432e-35" },
+ { 1.234321234321234e-34, "1.23432e-34" },
+ { 1.234321234321234e-33, "1.23432e-33" },
+ { 1.234321234321234e-32, "1.23432e-32" },
+ { 1.234321234321234e-31, "1.23432e-31" },
+ { 1.234321234321234e-30, "1.23432e-30" },
+ { 1.234321234321234e-29, "1.23432e-29" },
+ { 1.234321234321234e-28, "1.23432e-28" },
+ { 1.234321234321234e-27, "1.23432e-27" },
+ { 1.234321234321234e-26, "1.23432e-26" },
+ { 1.234321234321234e-25, "1.23432e-25" },
+ { 1.234321234321234e-24, "1.23432e-24" },
+ { 1.234321234321234e-23, "1.23432e-23" },
+ { 1.234321234321234e-22, "1.23432e-22" },
+ { 1.234321234321234e-21, "1.23432e-21" },
+ { 1.234321234321234e-20, "1.23432e-20" },
+ { 1.234321234321234e-19, "1.23432e-19" },
+ { 1.234321234321234e-18, "1.23432e-18" },
+ { 1.234321234321234e-17, "1.23432e-17" },
+ { 1.234321234321234e-16, "1.23432e-16" },
+ { 1.234321234321234e-15, "1.23432e-15" },
+ { 1.234321234321234e-14, "1.23432e-14" },
+ { 1.234321234321234e-13, "1.23432e-13" },
+ { 1.234321234321234e-12, "1.23432e-12" },
+ { 1.234321234321234e-11, "1.23432e-11" },
+ { 1.234321234321234e-10, "1.23432e-10" },
+ { 1.234321234321234e-9, "1.23432e-09" },
+ { 1.234321234321234e-8, "1.23432e-08" },
+ { 1.234321234321234e-7, "1.23432e-07" },
+ { 1.234321234321234e-6, "1.23432e-06" },
+ { 1.234321234321234e-5, "1.23432e-05" },
+ { 1.234321234321234e-4, "0.000123432" },
+ { 1.234321234321234e-3, "0.00123432" },
+ { 1.234321234321234e-2, "0.0123432" },
+ { 1.234321234321234e-1, "0.123432" },
+ { 1.234321234321234, "1.23432" },
+ { 1.234321234321234e1, "12.3432" },
+ { 1.234321234321234e2, "123.432" },
+ { 1.234321234321234e3, "1234.32" },
+ { 1.234321234321234e4, "12343.2" },
+ { 1.234321234321234e5, "123432" },
+ { 1.234321234321234e6, "1.23432e+06" },
+ { 1.234321234321234e7, "1.23432e+07" },
+ { 1.234321234321234e8, "1.23432e+08" },
+ { 1.234321234321234e9, "1.23432e+09" },
+ { 1.234321234321234e10, "1.23432e+10" },
+ { 1.234321234321234e11, "1.23432e+11" },
+ { 1.234321234321234e12, "1.23432e+12" },
+ { 1.234321234321234e13, "1.23432e+13" },
+ { 1.234321234321234e14, "1.23432e+14" },
+ { 1.234321234321234e15, "1.23432e+15" },
+ { 1.234321234321234e16, "1.23432e+16" },
+ { 1.234321234321234e17, "1.23432e+17" },
+ { 1.234321234321234e18, "1.23432e+18" },
+ { 1.234321234321234e19, "1.23432e+19" },
+ { 1.234321234321234e20, "1.23432e+20" },
+ { 1.234321234321234e21, "1.23432e+21" },
+ { 1.234321234321234e22, "1.23432e+22" },
+ { 1.234321234321234e23, "1.23432e+23" },
+ { 1.234321234321234e24, "1.23432e+24" },
+ { 1.234321234321234e25, "1.23432e+25" },
+ { 1.234321234321234e26, "1.23432e+26" },
+ { 1.234321234321234e27, "1.23432e+27" },
+ { 1.234321234321234e28, "1.23432e+28" },
+ { 1.234321234321234e29, "1.23432e+29" },
+ { 1.234321234321234e30, "1.23432e+30" },
+ { 1.234321234321234e31, "1.23432e+31" },
+ { 1.234321234321234e32, "1.23432e+32" },
+ { 1.234321234321234e33, "1.23432e+33" },
+ { 1.234321234321234e34, "1.23432e+34" },
+ { 1.234321234321234e35, "1.23432e+35" },
+ { 1.234321234321234e36, "1.23432e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (expected[strlen (expected) - 4] == 'e'
+ && strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g %d", -0.03125, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.03125 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%g %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%10g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%-10g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%+g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "% g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.75000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.g %d", 9.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%010g %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0000001234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015g %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%050g %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.g %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.5g %d", 999.951, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.5g %d", 999.996, 33, 44, 55);
+ ASSERT (strcmp (result, "1000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", 12.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "12.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", 1234567.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.23457e+06 33") == 0
+ || strcmp (result, "1.23457e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "1.23432e-37" },
+ { 1.234321234321234e-36L, "1.23432e-36" },
+ { 1.234321234321234e-35L, "1.23432e-35" },
+ { 1.234321234321234e-34L, "1.23432e-34" },
+ { 1.234321234321234e-33L, "1.23432e-33" },
+ { 1.234321234321234e-32L, "1.23432e-32" },
+ { 1.234321234321234e-31L, "1.23432e-31" },
+ { 1.234321234321234e-30L, "1.23432e-30" },
+ { 1.234321234321234e-29L, "1.23432e-29" },
+ { 1.234321234321234e-28L, "1.23432e-28" },
+ { 1.234321234321234e-27L, "1.23432e-27" },
+ { 1.234321234321234e-26L, "1.23432e-26" },
+ { 1.234321234321234e-25L, "1.23432e-25" },
+ { 1.234321234321234e-24L, "1.23432e-24" },
+ { 1.234321234321234e-23L, "1.23432e-23" },
+ { 1.234321234321234e-22L, "1.23432e-22" },
+ { 1.234321234321234e-21L, "1.23432e-21" },
+ { 1.234321234321234e-20L, "1.23432e-20" },
+ { 1.234321234321234e-19L, "1.23432e-19" },
+ { 1.234321234321234e-18L, "1.23432e-18" },
+ { 1.234321234321234e-17L, "1.23432e-17" },
+ { 1.234321234321234e-16L, "1.23432e-16" },
+ { 1.234321234321234e-15L, "1.23432e-15" },
+ { 1.234321234321234e-14L, "1.23432e-14" },
+ { 1.234321234321234e-13L, "1.23432e-13" },
+ { 1.234321234321234e-12L, "1.23432e-12" },
+ { 1.234321234321234e-11L, "1.23432e-11" },
+ { 1.234321234321234e-10L, "1.23432e-10" },
+ { 1.234321234321234e-9L, "1.23432e-09" },
+ { 1.234321234321234e-8L, "1.23432e-08" },
+ { 1.234321234321234e-7L, "1.23432e-07" },
+ { 1.234321234321234e-6L, "1.23432e-06" },
+ { 1.234321234321234e-5L, "1.23432e-05" },
+ { 1.234321234321234e-4L, "0.000123432" },
+ { 1.234321234321234e-3L, "0.00123432" },
+ { 1.234321234321234e-2L, "0.0123432" },
+ { 1.234321234321234e-1L, "0.123432" },
+ { 1.234321234321234L, "1.23432" },
+ { 1.234321234321234e1L, "12.3432" },
+ { 1.234321234321234e2L, "123.432" },
+ { 1.234321234321234e3L, "1234.32" },
+ { 1.234321234321234e4L, "12343.2" },
+ { 1.234321234321234e5L, "123432" },
+ { 1.234321234321234e6L, "1.23432e+06" },
+ { 1.234321234321234e7L, "1.23432e+07" },
+ { 1.234321234321234e8L, "1.23432e+08" },
+ { 1.234321234321234e9L, "1.23432e+09" },
+ { 1.234321234321234e10L, "1.23432e+10" },
+ { 1.234321234321234e11L, "1.23432e+11" },
+ { 1.234321234321234e12L, "1.23432e+12" },
+ { 1.234321234321234e13L, "1.23432e+13" },
+ { 1.234321234321234e14L, "1.23432e+14" },
+ { 1.234321234321234e15L, "1.23432e+15" },
+ { 1.234321234321234e16L, "1.23432e+16" },
+ { 1.234321234321234e17L, "1.23432e+17" },
+ { 1.234321234321234e18L, "1.23432e+18" },
+ { 1.234321234321234e19L, "1.23432e+19" },
+ { 1.234321234321234e20L, "1.23432e+20" },
+ { 1.234321234321234e21L, "1.23432e+21" },
+ { 1.234321234321234e22L, "1.23432e+22" },
+ { 1.234321234321234e23L, "1.23432e+23" },
+ { 1.234321234321234e24L, "1.23432e+24" },
+ { 1.234321234321234e25L, "1.23432e+25" },
+ { 1.234321234321234e26L, "1.23432e+26" },
+ { 1.234321234321234e27L, "1.23432e+27" },
+ { 1.234321234321234e28L, "1.23432e+28" },
+ { 1.234321234321234e29L, "1.23432e+29" },
+ { 1.234321234321234e30L, "1.23432e+30" },
+ { 1.234321234321234e31L, "1.23432e+31" },
+ { 1.234321234321234e32L, "1.23432e+32" },
+ { 1.234321234321234e33L, "1.23432e+33" },
+ { 1.234321234321234e34L, "1.23432e+34" },
+ { 1.234321234321234e35L, "1.23432e+35" },
+ { 1.234321234321234e36L, "1.23432e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (expected[strlen (expected) - 4] == 'e'
+ && strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", -0.03125L, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.03125 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#endif
+
+ { /* Width. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%10Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%-10Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%+Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "% Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.75000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.Lg %d", 9.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%010Lg %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0000001234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%015Lg %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%050Lg %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.Lg %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.5Lg %d", 999.951L, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.5Lg %d", 999.996L, 33, 44, 55);
+ ASSERT (strcmp (result, "1000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %n format directive. */
+
+ {
+ int count = -1;
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%d %n", 123, &count, 33, 44, 55);
+ ASSERT (strcmp (result, "123 ") == 0);
+ ASSERT (retval == strlen (result));
+ ASSERT (count == 4);
+ }
+
+ /* Test the support of the POSIX/XSI format strings with positions. */
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%2$d %1$d", 33, 55);
+ ASSERT (strcmp (result, "55 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the grouping flag. */
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "%'d %d", 1234567, 99);
+ ASSERT (result[strlen (result) - 1] == '9');
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the left-adjust flag. */
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "a%*sc", -3, "b");
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "a%-*sc", 3, "b");
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[100];
+ int retval =
+ my_snprintf (result, sizeof (result), "a%-*sc", -3, "b");
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of large precision. */
+
+ {
+ char result[5000];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4000d %d", 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.*d %d", 4000, 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4000d %d", -1234567, 99);
+ size_t i;
+ ASSERT (result[0] == '-');
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[1 + i] == '0');
+ ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4000u %d", 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4000o %d", 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_snprintf (result, sizeof (result), "%.4000x %d", 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 6; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.4000x %d", 1234567, 99);
+ size_t i;
+ ASSERT (result[0] == '0');
+ ASSERT (result[1] == 'x');
+ for (i = 0; i < 4000 - 6; i++)
+ ASSERT (result[2 + i] == '0');
+ ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char input[5000];
+ char result[5000];
+ int retval;
+ size_t i;
+
+ for (i = 0; i < sizeof (input) - 1; i++)
+ input[i] = 'a' + ((1000000 / (i + 1)) % 26);
+ input[i] = '\0';
+ retval = my_snprintf (result, sizeof (result), "%.4000s %d", input, 99);
+ ASSERT (memcmp (result, input, 4000) == 0);
+ ASSERT (strcmp (result + 4000, " 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %s format directive. */
+
+ /* To verify that these tests succeed, it is necessary to run them under
+ a tool that checks against invalid memory accesses, such as ElectricFence
+ or "valgrind --tool=memcheck". */
+ {
+ size_t i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ char *block;
+ char result[5000];
+ int retval;
+
+ block = (char *) malloc (i);
+ memcpy (block, "abcdefgh", i);
+ retval = my_snprintf (result, sizeof (result), "%.*s", (int) i, block);
+ ASSERT (memcmp (result, block, i) == 0);
+ ASSERT (result[i] == '\0');
+ ASSERT (retval == strlen (result));
+ free (block);
+ }
+ }
+#if HAVE_WCHAR_T
+ {
+ size_t i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ wchar_t *block;
+ size_t j;
+ char result[5000];
+ int retval;
+
+ block = (wchar_t *) malloc (i * sizeof (wchar_t));
+ for (j = 0; j < i; j++)
+ block[j] = "abcdefgh"[j];
+ retval = my_snprintf (result, sizeof (result), "%.*ls", (int) i, block);
+ ASSERT (memcmp (result, "abcdefgh", i) == 0);
+ ASSERT (result[i] == '\0');
+ ASSERT (retval == strlen (result));
+ free (block);
+ }
+ }
+#endif
+}
diff --git a/tests/gnu/test-snprintf.c b/tests/gnu/test-snprintf.c
new file mode 100755
index 00000000..62a411bf
--- /dev/null
+++ b/tests/gnu/test-snprintf.c
@@ -0,0 +1,64 @@
+/* Test of snprintf() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (snprintf, int, (char *, size_t, char const *, ...));
+
+#include <string.h>
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ char buf[8];
+ int size;
+ int retval;
+
+ for (size = 0; size <= 8; size++)
+ {
+ memcpy (buf, "DEADBEEF", 8);
+ retval = snprintf (buf, size, "%d", 12345);
+ if (size < 6)
+ {
+#if CHECK_SNPRINTF_POSIX
+ ASSERT (retval < 0 || retval >= size);
+#endif
+ if (size > 0)
+ {
+ ASSERT (memcmp (buf, "12345", size - 1) == 0);
+ ASSERT (buf[size - 1] == '\0' || buf[size - 1] == '0' + size);
+ }
+#if !CHECK_SNPRINTF_POSIX
+ if (size > 0)
+#endif
+ ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
+ }
+ else
+ {
+ ASSERT (retval == 5);
+ ASSERT (memcmp (buf, "12345\0EF", 8) == 0);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-spawn.c b/tests/gnu/test-spawn.c
new file mode 100755
index 00000000..dc6b0a8e
--- /dev/null
+++ b/tests/gnu/test-spawn.c
@@ -0,0 +1,54 @@
+/* Test of <spawn.h> substitute.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <spawn.h>
+
+/* Check for existence of required types. */
+struct check
+{
+ posix_spawnattr_t a;
+ posix_spawn_file_actions_t b;
+ mode_t c;
+ pid_t d;
+ sigset_t e;
+} s;
+
+/* struct sched_param is allowed to be an incomplete type without
+ <sched.h>, but must have a forward declaration to avoid a
+ compilation error in the following usage. */
+extern void f (struct sched_param *g);
+#include <sched.h>
+extern void f (struct sched_param *g);
+
+int
+main (void)
+{
+ switch (0)
+ {
+ case POSIX_SPAWN_RESETIDS:
+ case POSIX_SPAWN_SETPGROUP:
+ case POSIX_SPAWN_SETSIGDEF:
+ case POSIX_SPAWN_SETSIGMASK:
+ case POSIX_SPAWN_SETSCHEDPARAM:
+ case POSIX_SPAWN_SETSCHEDULER:
+ ;
+ }
+ return s.c + s.d;
+}
diff --git a/tests/gnu/test-sprintf-posix.c b/tests/gnu/test-sprintf-posix.c
new file mode 100755
index 00000000..db943da2
--- /dev/null
+++ b/tests/gnu/test-sprintf-posix.c
@@ -0,0 +1,41 @@
+/* Test of POSIX compatible sprintf() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (sprintf, int, (char *, char const *, ...));
+
+#include <float.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-sprintf-posix.h"
+
+int
+main (int argc, char *argv[])
+{
+ test_function (sprintf);
+ return 0;
+}
diff --git a/tests/gnu/test-sprintf-posix.h b/tests/gnu/test-sprintf-posix.h
new file mode 100755
index 00000000..a50e57ca
--- /dev/null
+++ b/tests/gnu/test-sprintf-posix.h
@@ -0,0 +1,3099 @@
+/* Test of POSIX compatible vsprintf() and sprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include "nan.h"
+
+/* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0. */
+static int
+have_minus_zero ()
+{
+ static double plus_zero = 0.0;
+ double minus_zero = - plus_zero;
+ return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
+}
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ So we use -zerod instead. */
+double zerod = 0.0;
+
+/* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
+ So we use minus_zerol instead.
+ IRIX cc can't put -0.0L into .data, but can compute at runtime.
+ Note that the expression -LDBL_MIN * LDBL_MIN does not work on other
+ platforms, such as when cross-compiling to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi
+static long double
+compute_minus_zerol (void)
+{
+ return -LDBL_MIN * LDBL_MIN;
+}
+# define minus_zerol compute_minus_zerol ()
+#else
+long double minus_zerol = -0.0L;
+#endif
+
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+ of 'unsigned int' words. */
+#ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+ ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
+ (unsigned int) (mantlo) << 16 \
+ }
+#else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { mantlo, manthi, exponent }
+#endif
+
+static int
+strmatch (const char *pattern, const char *string)
+{
+ if (strlen (pattern) != strlen (string))
+ return 0;
+ for (; *pattern != '\0'; pattern++, string++)
+ if (*pattern != '*' && *string != *pattern)
+ return 0;
+ return 1;
+}
+
+/* Test whether string[start_index..end_index-1] is a valid textual
+ representation of NaN. */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+test_function (int (*my_sprintf) (char *, const char *, ...))
+{
+ char buf[8];
+
+ /* Test return value convention. */
+
+ {
+ int retval;
+
+ memcpy (buf, "DEADBEEF", 8);
+ retval = my_sprintf (buf, "%d", 12345);
+ ASSERT (retval == 5);
+ ASSERT (memcmp (buf, "12345\0EF", 8) == 0);
+ }
+
+ /* Test support of size specifiers as in C99. */
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
+ ASSERT (strcmp (result, "12345671 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%zu %d", (size_t) 12345672, 33, 44, 55);
+ ASSERT (strcmp (result, "12345672 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
+ ASSERT (strcmp (result, "12345673 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", (long double) 1.5, 33, 44, 55);
+ ASSERT (strcmp (result, "1.5 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
+ output of floating-point numbers. */
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%a %d", 3.1416015625, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.922p+1 33") == 0
+ || strcmp (result, "0x3.244p+0 33") == 0
+ || strcmp (result, "0x6.488p-1 33") == 0
+ || strcmp (result, "0xc.91p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%A %d", -3.1416015625, 33, 44, 55);
+ ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
+ || strcmp (result, "-0X3.244P+0 33") == 0
+ || strcmp (result, "-0X6.488P-1 33") == 0
+ || strcmp (result, "-0XC.91P-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%a %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%a %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%a %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%a %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%a %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding near the decimal point. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.0a %d", 1.5, 33, 44, 55);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 0. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.0a %d", 1.51, 33, 44, 55);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 1. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.1a %d", 1.51, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.8p+0 33") == 0
+ || strcmp (result, "0x3.0p-1 33") == 0
+ || strcmp (result, "0x6.1p-2 33") == 0
+ || strcmp (result, "0xc.1p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 2. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.2a %d", 1.51, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.83p+0 33") == 0
+ || strcmp (result, "0x3.05p-1 33") == 0
+ || strcmp (result, "0x6.0ap-2 33") == 0
+ || strcmp (result, "0xc.14p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 3. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.3a %d", 1.51, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.829p+0 33") == 0
+ || strcmp (result, "0x3.052p-1 33") == 0
+ || strcmp (result, "0x6.0a4p-2 33") == 0
+ || strcmp (result, "0xc.148p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.3a %d", 1.49999, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.800p+0 33") == 0
+ || strcmp (result, "0x3.000p-1 33") == 0
+ || strcmp (result, "0x6.000p-2 33") == 0
+ || strcmp (result, "0xc.000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.1a %d", 1.999, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%10a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.10a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
+ || strcmp (result, "0x3.8000000000p-1 33") == 0
+ || strcmp (result, "0x7.0000000000p-2 33") == 0
+ || strcmp (result, "0xe.0000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Large precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.50a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
+ || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
+ || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
+ || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%-10a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7p-2 33") == 0
+ || strcmp (result, "0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%+a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
+ || strcmp (result, "+0x3.8p-1 33") == 0
+ || strcmp (result, "+0x7p-2 33") == 0
+ || strcmp (result, "+0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "% a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7.p-2 33") == 0
+ || strcmp (result, "0xe.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#a %d", 1.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.p+0 33") == 0
+ || strcmp (result, "0x2.p-1 33") == 0
+ || strcmp (result, "0x4.p-2 33") == 0
+ || strcmp (result, "0x8.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%010a %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "0x001.cp+0 33") == 0
+ || strcmp (result, "0x003.8p-1 33") == 0
+ || strcmp (result, "0x00007p-2 33") == 0
+ || strcmp (result, "0x0000ep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%010a %d", 1.0 / 0.0, 33, 44, 55);
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strcmp (result, " inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%050a %d", NaNd (), 33, 44, 55);
+ /* "0000000nan 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", 3.1416015625L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.922p+1 33") == 0
+ || strcmp (result, "0x3.244p+0 33") == 0
+ || strcmp (result, "0x6.488p-1 33") == 0
+ || strcmp (result, "0xc.91p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LA %d", -3.1416015625L, 33, 44, 55);
+ ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
+ || strcmp (result, "-0X3.244P+0 33") == 0
+ || strcmp (result, "-0X6.488P-1 33") == 0
+ || strcmp (result, "-0XC.91P-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#endif
+
+ { /* Rounding near the decimal point. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.0La %d", 1.5L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 0. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.0La %d", 1.51L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 1. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.1La %d", 1.51L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.8p+0 33") == 0
+ || strcmp (result, "0x3.0p-1 33") == 0
+ || strcmp (result, "0x6.1p-2 33") == 0
+ || strcmp (result, "0xc.1p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 2. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.2La %d", 1.51L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.83p+0 33") == 0
+ || strcmp (result, "0x3.05p-1 33") == 0
+ || strcmp (result, "0x6.0ap-2 33") == 0
+ || strcmp (result, "0xc.14p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding with precision 3. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.3La %d", 1.51L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.829p+0 33") == 0
+ || strcmp (result, "0x3.052p-1 33") == 0
+ || strcmp (result, "0x6.0a4p-2 33") == 0
+ || strcmp (result, "0xc.148p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.3La %d", 1.49999L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.800p+0 33") == 0
+ || strcmp (result, "0x3.000p-1 33") == 0
+ || strcmp (result, "0x6.000p-2 33") == 0
+ || strcmp (result, "0xc.000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
+ glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.1La %d", 1.999L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%10La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.10La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
+ || strcmp (result, "0x3.8000000000p-1 33") == 0
+ || strcmp (result, "0x7.0000000000p-2 33") == 0
+ || strcmp (result, "0xe.0000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Large precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.50La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
+ || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
+ || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
+ || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%-10La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7p-2 33") == 0
+ || strcmp (result, "0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%+La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
+ || strcmp (result, "+0x3.8p-1 33") == 0
+ || strcmp (result, "+0x7p-2 33") == 0
+ || strcmp (result, "+0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "% La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7.p-2 33") == 0
+ || strcmp (result, "0xe.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#La %d", 1.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x1.p+0 33") == 0
+ || strcmp (result, "0x2.p-1 33") == 0
+ || strcmp (result, "0x4.p-2 33") == 0
+ || strcmp (result, "0x8.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%010La %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "0x001.cp+0 33") == 0
+ || strcmp (result, "0x003.8p-1 33") == 0
+ || strcmp (result, "0x00007p-2 33") == 0
+ || strcmp (result, "0x0000ep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strcmp (result, " inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%050La %d", NaNl (), 33, 44, 55);
+ /* "0000000nan 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %f format directive. */
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f %d", 12.75, 33, 44, 55);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f %d", 1234567.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "0.000000" },
+ { 1.234321234321234e-36, "0.000000" },
+ { 1.234321234321234e-35, "0.000000" },
+ { 1.234321234321234e-34, "0.000000" },
+ { 1.234321234321234e-33, "0.000000" },
+ { 1.234321234321234e-32, "0.000000" },
+ { 1.234321234321234e-31, "0.000000" },
+ { 1.234321234321234e-30, "0.000000" },
+ { 1.234321234321234e-29, "0.000000" },
+ { 1.234321234321234e-28, "0.000000" },
+ { 1.234321234321234e-27, "0.000000" },
+ { 1.234321234321234e-26, "0.000000" },
+ { 1.234321234321234e-25, "0.000000" },
+ { 1.234321234321234e-24, "0.000000" },
+ { 1.234321234321234e-23, "0.000000" },
+ { 1.234321234321234e-22, "0.000000" },
+ { 1.234321234321234e-21, "0.000000" },
+ { 1.234321234321234e-20, "0.000000" },
+ { 1.234321234321234e-19, "0.000000" },
+ { 1.234321234321234e-18, "0.000000" },
+ { 1.234321234321234e-17, "0.000000" },
+ { 1.234321234321234e-16, "0.000000" },
+ { 1.234321234321234e-15, "0.000000" },
+ { 1.234321234321234e-14, "0.000000" },
+ { 1.234321234321234e-13, "0.000000" },
+ { 1.234321234321234e-12, "0.000000" },
+ { 1.234321234321234e-11, "0.000000" },
+ { 1.234321234321234e-10, "0.000000" },
+ { 1.234321234321234e-9, "0.000000" },
+ { 1.234321234321234e-8, "0.000000" },
+ { 1.234321234321234e-7, "0.000000" },
+ { 1.234321234321234e-6, "0.000001" },
+ { 1.234321234321234e-5, "0.000012" },
+ { 1.234321234321234e-4, "0.000123" },
+ { 1.234321234321234e-3, "0.001234" },
+ { 1.234321234321234e-2, "0.012343" },
+ { 1.234321234321234e-1, "0.123432" },
+ { 1.234321234321234, "1.234321" },
+ { 1.234321234321234e1, "12.343212" },
+ { 1.234321234321234e2, "123.432123" },
+ { 1.234321234321234e3, "1234.321234" },
+ { 1.234321234321234e4, "12343.212343" },
+ { 1.234321234321234e5, "123432.123432" },
+ { 1.234321234321234e6, "1234321.234321" },
+ { 1.234321234321234e7, "12343212.343212" },
+ { 1.234321234321234e8, "123432123.432123" },
+ { 1.234321234321234e9, "1234321234.321234" },
+ { 1.234321234321234e10, "12343212343.2123**" },
+ { 1.234321234321234e11, "123432123432.123***" },
+ { 1.234321234321234e12, "1234321234321.23****" },
+ { 1.234321234321234e13, "12343212343212.3*****" },
+ { 1.234321234321234e14, "123432123432123.******" },
+ { 1.234321234321234e15, "1234321234321234.000000" },
+ { 1.234321234321234e16, "123432123432123**.000000" },
+ { 1.234321234321234e17, "123432123432123***.000000" },
+ { 1.234321234321234e18, "123432123432123****.000000" },
+ { 1.234321234321234e19, "123432123432123*****.000000" },
+ { 1.234321234321234e20, "123432123432123******.000000" },
+ { 1.234321234321234e21, "123432123432123*******.000000" },
+ { 1.234321234321234e22, "123432123432123********.000000" },
+ { 1.234321234321234e23, "123432123432123*********.000000" },
+ { 1.234321234321234e24, "123432123432123**********.000000" },
+ { 1.234321234321234e25, "123432123432123***********.000000" },
+ { 1.234321234321234e26, "123432123432123************.000000" },
+ { 1.234321234321234e27, "123432123432123*************.000000" },
+ { 1.234321234321234e28, "123432123432123**************.000000" },
+ { 1.234321234321234e29, "123432123432123***************.000000" },
+ { 1.234321234321234e30, "123432123432123****************.000000" },
+ { 1.234321234321234e31, "123432123432123*****************.000000" },
+ { 1.234321234321234e32, "123432123432123******************.000000" },
+ { 1.234321234321234e33, "123432123432123*******************.000000" },
+ { 1.234321234321234e34, "123432123432123********************.000000" },
+ { 1.234321234321234e35, "123432123432123*********************.000000" },
+ { 1.234321234321234e36, "123432123432123**********************.000000" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f", data[k].value);
+ ASSERT (strmatch (data[k].string, result));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f %d", -0.03125, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%f %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%10f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%-10f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%+f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "% f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.f %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015f %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015f %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%050f %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.f %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.2f %d", 999.951, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.2f %d", 999.996, 33, 44, 55);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", 12.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", 1234567.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "0.000000" },
+ { 1.234321234321234e-36L, "0.000000" },
+ { 1.234321234321234e-35L, "0.000000" },
+ { 1.234321234321234e-34L, "0.000000" },
+ { 1.234321234321234e-33L, "0.000000" },
+ { 1.234321234321234e-32L, "0.000000" },
+ { 1.234321234321234e-31L, "0.000000" },
+ { 1.234321234321234e-30L, "0.000000" },
+ { 1.234321234321234e-29L, "0.000000" },
+ { 1.234321234321234e-28L, "0.000000" },
+ { 1.234321234321234e-27L, "0.000000" },
+ { 1.234321234321234e-26L, "0.000000" },
+ { 1.234321234321234e-25L, "0.000000" },
+ { 1.234321234321234e-24L, "0.000000" },
+ { 1.234321234321234e-23L, "0.000000" },
+ { 1.234321234321234e-22L, "0.000000" },
+ { 1.234321234321234e-21L, "0.000000" },
+ { 1.234321234321234e-20L, "0.000000" },
+ { 1.234321234321234e-19L, "0.000000" },
+ { 1.234321234321234e-18L, "0.000000" },
+ { 1.234321234321234e-17L, "0.000000" },
+ { 1.234321234321234e-16L, "0.000000" },
+ { 1.234321234321234e-15L, "0.000000" },
+ { 1.234321234321234e-14L, "0.000000" },
+ { 1.234321234321234e-13L, "0.000000" },
+ { 1.234321234321234e-12L, "0.000000" },
+ { 1.234321234321234e-11L, "0.000000" },
+ { 1.234321234321234e-10L, "0.000000" },
+ { 1.234321234321234e-9L, "0.000000" },
+ { 1.234321234321234e-8L, "0.000000" },
+ { 1.234321234321234e-7L, "0.000000" },
+ { 1.234321234321234e-6L, "0.000001" },
+ { 1.234321234321234e-5L, "0.000012" },
+ { 1.234321234321234e-4L, "0.000123" },
+ { 1.234321234321234e-3L, "0.001234" },
+ { 1.234321234321234e-2L, "0.012343" },
+ { 1.234321234321234e-1L, "0.123432" },
+ { 1.234321234321234L, "1.234321" },
+ { 1.234321234321234e1L, "12.343212" },
+ { 1.234321234321234e2L, "123.432123" },
+ { 1.234321234321234e3L, "1234.321234" },
+ { 1.234321234321234e4L, "12343.212343" },
+ { 1.234321234321234e5L, "123432.123432" },
+ { 1.234321234321234e6L, "1234321.234321" },
+ { 1.234321234321234e7L, "12343212.343212" },
+ { 1.234321234321234e8L, "123432123.432123" },
+ { 1.234321234321234e9L, "1234321234.321234" },
+ { 1.234321234321234e10L, "12343212343.2123**" },
+ { 1.234321234321234e11L, "123432123432.123***" },
+ { 1.234321234321234e12L, "1234321234321.23****" },
+ { 1.234321234321234e13L, "12343212343212.3*****" },
+ { 1.234321234321234e14L, "123432123432123.******" },
+ { 1.234321234321234e15L, "1234321234321234.000000" },
+ { 1.234321234321234e16L, "123432123432123**.000000" },
+ { 1.234321234321234e17L, "123432123432123***.000000" },
+ { 1.234321234321234e18L, "123432123432123****.000000" },
+ { 1.234321234321234e19L, "123432123432123*****.000000" },
+ { 1.234321234321234e20L, "123432123432123******.000000" },
+ { 1.234321234321234e21L, "123432123432123*******.000000" },
+ { 1.234321234321234e22L, "123432123432123********.000000" },
+ { 1.234321234321234e23L, "123432123432123*********.000000" },
+ { 1.234321234321234e24L, "123432123432123**********.000000" },
+ { 1.234321234321234e25L, "123432123432123***********.000000" },
+ { 1.234321234321234e26L, "123432123432123************.000000" },
+ { 1.234321234321234e27L, "123432123432123*************.000000" },
+ { 1.234321234321234e28L, "123432123432123**************.000000" },
+ { 1.234321234321234e29L, "123432123432123***************.000000" },
+ { 1.234321234321234e30L, "123432123432123****************.000000" },
+ { 1.234321234321234e31L, "123432123432123*****************.000000" },
+ { 1.234321234321234e32L, "123432123432123******************.000000" },
+ { 1.234321234321234e33L, "123432123432123*******************.000000" },
+ { 1.234321234321234e34L, "123432123432123********************.000000" },
+ { 1.234321234321234e35L, "123432123432123*********************.000000" },
+ { 1.234321234321234e36L, "123432123432123**********************.000000" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf", data[k].value);
+ ASSERT (strmatch (data[k].string, result));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", -0.03125L, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#endif
+
+ { /* Width. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%10Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%-10Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%+Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "% Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015Lf %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%050Lf %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.Lf %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.2Lf %d", 999.951L, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.2Lf %d", 999.996L, 33, 44, 55);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %F format directive. */
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%F %d", 12.75, 33, 44, 55);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%F %d", 1234567.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%F %d", -0.03125, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%F %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%F %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%F %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "INF 33") == 0
+ || strcmp (result, "INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%F %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-INF 33") == 0
+ || strcmp (result, "-INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%F %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 1)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015F %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015F %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, " -INF 33") == 0
+ || strcmp (result, " -INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.F %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.2F %d", 999.951, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.2F %d", 999.996, 33, 44, 55);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LF %d", 12.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LF %d", 1234567.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LF %d", -0.03125L, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LF %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LF %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LF %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "INF 33") == 0
+ || strcmp (result, "INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LF %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-INF 33") == 0
+ || strcmp (result, "-INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%LF %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 1)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015LF %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, " -INF 33") == 0
+ || strcmp (result, " -INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.LF %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.2LF %d", 999.951L, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.2LF %d", 999.996L, 33, 44, 55);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %e format directive. */
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e %d", 12.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.275000e+01 33") == 0
+ || strcmp (result, "1.275000e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e %d", 1234567.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1.234567e+06 33") == 0
+ || strcmp (result, "1.234567e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "1.234321e-37" },
+ { 1.234321234321234e-36, "1.234321e-36" },
+ { 1.234321234321234e-35, "1.234321e-35" },
+ { 1.234321234321234e-34, "1.234321e-34" },
+ { 1.234321234321234e-33, "1.234321e-33" },
+ { 1.234321234321234e-32, "1.234321e-32" },
+ { 1.234321234321234e-31, "1.234321e-31" },
+ { 1.234321234321234e-30, "1.234321e-30" },
+ { 1.234321234321234e-29, "1.234321e-29" },
+ { 1.234321234321234e-28, "1.234321e-28" },
+ { 1.234321234321234e-27, "1.234321e-27" },
+ { 1.234321234321234e-26, "1.234321e-26" },
+ { 1.234321234321234e-25, "1.234321e-25" },
+ { 1.234321234321234e-24, "1.234321e-24" },
+ { 1.234321234321234e-23, "1.234321e-23" },
+ { 1.234321234321234e-22, "1.234321e-22" },
+ { 1.234321234321234e-21, "1.234321e-21" },
+ { 1.234321234321234e-20, "1.234321e-20" },
+ { 1.234321234321234e-19, "1.234321e-19" },
+ { 1.234321234321234e-18, "1.234321e-18" },
+ { 1.234321234321234e-17, "1.234321e-17" },
+ { 1.234321234321234e-16, "1.234321e-16" },
+ { 1.234321234321234e-15, "1.234321e-15" },
+ { 1.234321234321234e-14, "1.234321e-14" },
+ { 1.234321234321234e-13, "1.234321e-13" },
+ { 1.234321234321234e-12, "1.234321e-12" },
+ { 1.234321234321234e-11, "1.234321e-11" },
+ { 1.234321234321234e-10, "1.234321e-10" },
+ { 1.234321234321234e-9, "1.234321e-09" },
+ { 1.234321234321234e-8, "1.234321e-08" },
+ { 1.234321234321234e-7, "1.234321e-07" },
+ { 1.234321234321234e-6, "1.234321e-06" },
+ { 1.234321234321234e-5, "1.234321e-05" },
+ { 1.234321234321234e-4, "1.234321e-04" },
+ { 1.234321234321234e-3, "1.234321e-03" },
+ { 1.234321234321234e-2, "1.234321e-02" },
+ { 1.234321234321234e-1, "1.234321e-01" },
+ { 1.234321234321234, "1.234321e+00" },
+ { 1.234321234321234e1, "1.234321e+01" },
+ { 1.234321234321234e2, "1.234321e+02" },
+ { 1.234321234321234e3, "1.234321e+03" },
+ { 1.234321234321234e4, "1.234321e+04" },
+ { 1.234321234321234e5, "1.234321e+05" },
+ { 1.234321234321234e6, "1.234321e+06" },
+ { 1.234321234321234e7, "1.234321e+07" },
+ { 1.234321234321234e8, "1.234321e+08" },
+ { 1.234321234321234e9, "1.234321e+09" },
+ { 1.234321234321234e10, "1.234321e+10" },
+ { 1.234321234321234e11, "1.234321e+11" },
+ { 1.234321234321234e12, "1.234321e+12" },
+ { 1.234321234321234e13, "1.234321e+13" },
+ { 1.234321234321234e14, "1.234321e+14" },
+ { 1.234321234321234e15, "1.234321e+15" },
+ { 1.234321234321234e16, "1.234321e+16" },
+ { 1.234321234321234e17, "1.234321e+17" },
+ { 1.234321234321234e18, "1.234321e+18" },
+ { 1.234321234321234e19, "1.234321e+19" },
+ { 1.234321234321234e20, "1.234321e+20" },
+ { 1.234321234321234e21, "1.234321e+21" },
+ { 1.234321234321234e22, "1.234321e+22" },
+ { 1.234321234321234e23, "1.234321e+23" },
+ { 1.234321234321234e24, "1.234321e+24" },
+ { 1.234321234321234e25, "1.234321e+25" },
+ { 1.234321234321234e26, "1.234321e+26" },
+ { 1.234321234321234e27, "1.234321e+27" },
+ { 1.234321234321234e28, "1.234321e+28" },
+ { 1.234321234321234e29, "1.234321e+29" },
+ { 1.234321234321234e30, "1.234321e+30" },
+ { 1.234321234321234e31, "1.234321e+31" },
+ { 1.234321234321234e32, "1.234321e+32" },
+ { 1.234321234321234e33, "1.234321e+33" },
+ { 1.234321234321234e34, "1.234321e+34" },
+ { 1.234321234321234e35, "1.234321e+35" },
+ { 1.234321234321234e36, "1.234321e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e %d", -0.03125, 33, 44, 55);
+ ASSERT (strcmp (result, "-3.125000e-02 33") == 0
+ || strcmp (result, "-3.125000e-002 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000e+00 33") == 0
+ || strcmp (result, "0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000e+00 33") == 0
+ || strcmp (result, "-0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%e %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%15e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%-15e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%+e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.750000e+00 33") == 0
+ || strcmp (result, "+1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "% e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.e %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "2.e+00 33") == 0
+ || strcmp (result, "2.e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.e %d", 9.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015e %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0001.234000e+03 33") == 0
+ || strcmp (result, "001.234000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015e %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%050e %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.e %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.4e %d", 999.951, 33, 44, 55);
+ ASSERT (strcmp (result, "9.9995e+02 33") == 0
+ || strcmp (result, "9.9995e+002 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.4e %d", 999.996, 33, 44, 55);
+ ASSERT (strcmp (result, "1.0000e+03 33") == 0
+ || strcmp (result, "1.0000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", 12.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.275000e+01 33") == 0
+ || strcmp (result, "1.275000e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", 1234567.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.234567e+06 33") == 0
+ || strcmp (result, "1.234567e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "1.234321e-37" },
+ { 1.234321234321234e-36L, "1.234321e-36" },
+ { 1.234321234321234e-35L, "1.234321e-35" },
+ { 1.234321234321234e-34L, "1.234321e-34" },
+ { 1.234321234321234e-33L, "1.234321e-33" },
+ { 1.234321234321234e-32L, "1.234321e-32" },
+ { 1.234321234321234e-31L, "1.234321e-31" },
+ { 1.234321234321234e-30L, "1.234321e-30" },
+ { 1.234321234321234e-29L, "1.234321e-29" },
+ { 1.234321234321234e-28L, "1.234321e-28" },
+ { 1.234321234321234e-27L, "1.234321e-27" },
+ { 1.234321234321234e-26L, "1.234321e-26" },
+ { 1.234321234321234e-25L, "1.234321e-25" },
+ { 1.234321234321234e-24L, "1.234321e-24" },
+ { 1.234321234321234e-23L, "1.234321e-23" },
+ { 1.234321234321234e-22L, "1.234321e-22" },
+ { 1.234321234321234e-21L, "1.234321e-21" },
+ { 1.234321234321234e-20L, "1.234321e-20" },
+ { 1.234321234321234e-19L, "1.234321e-19" },
+ { 1.234321234321234e-18L, "1.234321e-18" },
+ { 1.234321234321234e-17L, "1.234321e-17" },
+ { 1.234321234321234e-16L, "1.234321e-16" },
+ { 1.234321234321234e-15L, "1.234321e-15" },
+ { 1.234321234321234e-14L, "1.234321e-14" },
+ { 1.234321234321234e-13L, "1.234321e-13" },
+ { 1.234321234321234e-12L, "1.234321e-12" },
+ { 1.234321234321234e-11L, "1.234321e-11" },
+ { 1.234321234321234e-10L, "1.234321e-10" },
+ { 1.234321234321234e-9L, "1.234321e-09" },
+ { 1.234321234321234e-8L, "1.234321e-08" },
+ { 1.234321234321234e-7L, "1.234321e-07" },
+ { 1.234321234321234e-6L, "1.234321e-06" },
+ { 1.234321234321234e-5L, "1.234321e-05" },
+ { 1.234321234321234e-4L, "1.234321e-04" },
+ { 1.234321234321234e-3L, "1.234321e-03" },
+ { 1.234321234321234e-2L, "1.234321e-02" },
+ { 1.234321234321234e-1L, "1.234321e-01" },
+ { 1.234321234321234L, "1.234321e+00" },
+ { 1.234321234321234e1L, "1.234321e+01" },
+ { 1.234321234321234e2L, "1.234321e+02" },
+ { 1.234321234321234e3L, "1.234321e+03" },
+ { 1.234321234321234e4L, "1.234321e+04" },
+ { 1.234321234321234e5L, "1.234321e+05" },
+ { 1.234321234321234e6L, "1.234321e+06" },
+ { 1.234321234321234e7L, "1.234321e+07" },
+ { 1.234321234321234e8L, "1.234321e+08" },
+ { 1.234321234321234e9L, "1.234321e+09" },
+ { 1.234321234321234e10L, "1.234321e+10" },
+ { 1.234321234321234e11L, "1.234321e+11" },
+ { 1.234321234321234e12L, "1.234321e+12" },
+ { 1.234321234321234e13L, "1.234321e+13" },
+ { 1.234321234321234e14L, "1.234321e+14" },
+ { 1.234321234321234e15L, "1.234321e+15" },
+ { 1.234321234321234e16L, "1.234321e+16" },
+ { 1.234321234321234e17L, "1.234321e+17" },
+ { 1.234321234321234e18L, "1.234321e+18" },
+ { 1.234321234321234e19L, "1.234321e+19" },
+ { 1.234321234321234e20L, "1.234321e+20" },
+ { 1.234321234321234e21L, "1.234321e+21" },
+ { 1.234321234321234e22L, "1.234321e+22" },
+ { 1.234321234321234e23L, "1.234321e+23" },
+ { 1.234321234321234e24L, "1.234321e+24" },
+ { 1.234321234321234e25L, "1.234321e+25" },
+ { 1.234321234321234e26L, "1.234321e+26" },
+ { 1.234321234321234e27L, "1.234321e+27" },
+ { 1.234321234321234e28L, "1.234321e+28" },
+ { 1.234321234321234e29L, "1.234321e+29" },
+ { 1.234321234321234e30L, "1.234321e+30" },
+ { 1.234321234321234e31L, "1.234321e+31" },
+ { 1.234321234321234e32L, "1.234321e+32" },
+ { 1.234321234321234e33L, "1.234321e+33" },
+ { 1.234321234321234e34L, "1.234321e+34" },
+ { 1.234321234321234e35L, "1.234321e+35" },
+ { 1.234321234321234e36L, "1.234321e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", -0.03125L, 33, 44, 55);
+ ASSERT (strcmp (result, "-3.125000e-02 33") == 0
+ || strcmp (result, "-3.125000e-002 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0.000000e+00 33") == 0
+ || strcmp (result, "0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000e+00 33") == 0
+ || strcmp (result, "-0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#endif
+
+ { /* Width. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%15Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%-15Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%+Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.750000e+00 33") == 0
+ || strcmp (result, "+1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "% Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.Le %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "2.e+00 33") == 0
+ || strcmp (result, "2.e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.Le %d", 9.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015Le %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0001.234000e+03 33") == 0
+ || strcmp (result, "001.234000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015Le %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%050Le %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.Le %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.4Le %d", 999.951L, 33, 44, 55);
+ ASSERT (strcmp (result, "9.9995e+02 33") == 0
+ || strcmp (result, "9.9995e+002 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.4Le %d", 999.996L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.0000e+03 33") == 0
+ || strcmp (result, "1.0000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %g format directive. */
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g %d", 12.75, 33, 44, 55);
+ ASSERT (strcmp (result, "12.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g %d", 1234567.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1.23457e+06 33") == 0
+ || strcmp (result, "1.23457e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "1.23432e-37" },
+ { 1.234321234321234e-36, "1.23432e-36" },
+ { 1.234321234321234e-35, "1.23432e-35" },
+ { 1.234321234321234e-34, "1.23432e-34" },
+ { 1.234321234321234e-33, "1.23432e-33" },
+ { 1.234321234321234e-32, "1.23432e-32" },
+ { 1.234321234321234e-31, "1.23432e-31" },
+ { 1.234321234321234e-30, "1.23432e-30" },
+ { 1.234321234321234e-29, "1.23432e-29" },
+ { 1.234321234321234e-28, "1.23432e-28" },
+ { 1.234321234321234e-27, "1.23432e-27" },
+ { 1.234321234321234e-26, "1.23432e-26" },
+ { 1.234321234321234e-25, "1.23432e-25" },
+ { 1.234321234321234e-24, "1.23432e-24" },
+ { 1.234321234321234e-23, "1.23432e-23" },
+ { 1.234321234321234e-22, "1.23432e-22" },
+ { 1.234321234321234e-21, "1.23432e-21" },
+ { 1.234321234321234e-20, "1.23432e-20" },
+ { 1.234321234321234e-19, "1.23432e-19" },
+ { 1.234321234321234e-18, "1.23432e-18" },
+ { 1.234321234321234e-17, "1.23432e-17" },
+ { 1.234321234321234e-16, "1.23432e-16" },
+ { 1.234321234321234e-15, "1.23432e-15" },
+ { 1.234321234321234e-14, "1.23432e-14" },
+ { 1.234321234321234e-13, "1.23432e-13" },
+ { 1.234321234321234e-12, "1.23432e-12" },
+ { 1.234321234321234e-11, "1.23432e-11" },
+ { 1.234321234321234e-10, "1.23432e-10" },
+ { 1.234321234321234e-9, "1.23432e-09" },
+ { 1.234321234321234e-8, "1.23432e-08" },
+ { 1.234321234321234e-7, "1.23432e-07" },
+ { 1.234321234321234e-6, "1.23432e-06" },
+ { 1.234321234321234e-5, "1.23432e-05" },
+ { 1.234321234321234e-4, "0.000123432" },
+ { 1.234321234321234e-3, "0.00123432" },
+ { 1.234321234321234e-2, "0.0123432" },
+ { 1.234321234321234e-1, "0.123432" },
+ { 1.234321234321234, "1.23432" },
+ { 1.234321234321234e1, "12.3432" },
+ { 1.234321234321234e2, "123.432" },
+ { 1.234321234321234e3, "1234.32" },
+ { 1.234321234321234e4, "12343.2" },
+ { 1.234321234321234e5, "123432" },
+ { 1.234321234321234e6, "1.23432e+06" },
+ { 1.234321234321234e7, "1.23432e+07" },
+ { 1.234321234321234e8, "1.23432e+08" },
+ { 1.234321234321234e9, "1.23432e+09" },
+ { 1.234321234321234e10, "1.23432e+10" },
+ { 1.234321234321234e11, "1.23432e+11" },
+ { 1.234321234321234e12, "1.23432e+12" },
+ { 1.234321234321234e13, "1.23432e+13" },
+ { 1.234321234321234e14, "1.23432e+14" },
+ { 1.234321234321234e15, "1.23432e+15" },
+ { 1.234321234321234e16, "1.23432e+16" },
+ { 1.234321234321234e17, "1.23432e+17" },
+ { 1.234321234321234e18, "1.23432e+18" },
+ { 1.234321234321234e19, "1.23432e+19" },
+ { 1.234321234321234e20, "1.23432e+20" },
+ { 1.234321234321234e21, "1.23432e+21" },
+ { 1.234321234321234e22, "1.23432e+22" },
+ { 1.234321234321234e23, "1.23432e+23" },
+ { 1.234321234321234e24, "1.23432e+24" },
+ { 1.234321234321234e25, "1.23432e+25" },
+ { 1.234321234321234e26, "1.23432e+26" },
+ { 1.234321234321234e27, "1.23432e+27" },
+ { 1.234321234321234e28, "1.23432e+28" },
+ { 1.234321234321234e29, "1.23432e+29" },
+ { 1.234321234321234e30, "1.23432e+30" },
+ { 1.234321234321234e31, "1.23432e+31" },
+ { 1.234321234321234e32, "1.23432e+32" },
+ { 1.234321234321234e33, "1.23432e+33" },
+ { 1.234321234321234e34, "1.23432e+34" },
+ { 1.234321234321234e35, "1.23432e+35" },
+ { 1.234321234321234e36, "1.23432e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (expected[strlen (expected) - 4] == 'e'
+ && strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g %d", -0.03125, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.03125 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g %d", 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g %d", -zerod, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%g %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%10g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%-10g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%+g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "% g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.75000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.g %d", 1.75, 33, 44, 55);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.g %d", 9.75, 33, 44, 55);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%010g %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "0000001234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015g %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%050g %d", NaNd (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.g %d", 1234.0, 33, 44, 55);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.5g %d", 999.951, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.5g %d", 999.996, 33, 44, 55);
+ ASSERT (strcmp (result, "1000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", 12.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "12.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A larger positive number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", 1234567.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.23457e+06 33") == 0
+ || strcmp (result, "1.23457e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "1.23432e-37" },
+ { 1.234321234321234e-36L, "1.23432e-36" },
+ { 1.234321234321234e-35L, "1.23432e-35" },
+ { 1.234321234321234e-34L, "1.23432e-34" },
+ { 1.234321234321234e-33L, "1.23432e-33" },
+ { 1.234321234321234e-32L, "1.23432e-32" },
+ { 1.234321234321234e-31L, "1.23432e-31" },
+ { 1.234321234321234e-30L, "1.23432e-30" },
+ { 1.234321234321234e-29L, "1.23432e-29" },
+ { 1.234321234321234e-28L, "1.23432e-28" },
+ { 1.234321234321234e-27L, "1.23432e-27" },
+ { 1.234321234321234e-26L, "1.23432e-26" },
+ { 1.234321234321234e-25L, "1.23432e-25" },
+ { 1.234321234321234e-24L, "1.23432e-24" },
+ { 1.234321234321234e-23L, "1.23432e-23" },
+ { 1.234321234321234e-22L, "1.23432e-22" },
+ { 1.234321234321234e-21L, "1.23432e-21" },
+ { 1.234321234321234e-20L, "1.23432e-20" },
+ { 1.234321234321234e-19L, "1.23432e-19" },
+ { 1.234321234321234e-18L, "1.23432e-18" },
+ { 1.234321234321234e-17L, "1.23432e-17" },
+ { 1.234321234321234e-16L, "1.23432e-16" },
+ { 1.234321234321234e-15L, "1.23432e-15" },
+ { 1.234321234321234e-14L, "1.23432e-14" },
+ { 1.234321234321234e-13L, "1.23432e-13" },
+ { 1.234321234321234e-12L, "1.23432e-12" },
+ { 1.234321234321234e-11L, "1.23432e-11" },
+ { 1.234321234321234e-10L, "1.23432e-10" },
+ { 1.234321234321234e-9L, "1.23432e-09" },
+ { 1.234321234321234e-8L, "1.23432e-08" },
+ { 1.234321234321234e-7L, "1.23432e-07" },
+ { 1.234321234321234e-6L, "1.23432e-06" },
+ { 1.234321234321234e-5L, "1.23432e-05" },
+ { 1.234321234321234e-4L, "0.000123432" },
+ { 1.234321234321234e-3L, "0.00123432" },
+ { 1.234321234321234e-2L, "0.0123432" },
+ { 1.234321234321234e-1L, "0.123432" },
+ { 1.234321234321234L, "1.23432" },
+ { 1.234321234321234e1L, "12.3432" },
+ { 1.234321234321234e2L, "123.432" },
+ { 1.234321234321234e3L, "1234.32" },
+ { 1.234321234321234e4L, "12343.2" },
+ { 1.234321234321234e5L, "123432" },
+ { 1.234321234321234e6L, "1.23432e+06" },
+ { 1.234321234321234e7L, "1.23432e+07" },
+ { 1.234321234321234e8L, "1.23432e+08" },
+ { 1.234321234321234e9L, "1.23432e+09" },
+ { 1.234321234321234e10L, "1.23432e+10" },
+ { 1.234321234321234e11L, "1.23432e+11" },
+ { 1.234321234321234e12L, "1.23432e+12" },
+ { 1.234321234321234e13L, "1.23432e+13" },
+ { 1.234321234321234e14L, "1.23432e+14" },
+ { 1.234321234321234e15L, "1.23432e+15" },
+ { 1.234321234321234e16L, "1.23432e+16" },
+ { 1.234321234321234e17L, "1.23432e+17" },
+ { 1.234321234321234e18L, "1.23432e+18" },
+ { 1.234321234321234e19L, "1.23432e+19" },
+ { 1.234321234321234e20L, "1.23432e+20" },
+ { 1.234321234321234e21L, "1.23432e+21" },
+ { 1.234321234321234e22L, "1.23432e+22" },
+ { 1.234321234321234e23L, "1.23432e+23" },
+ { 1.234321234321234e24L, "1.23432e+24" },
+ { 1.234321234321234e25L, "1.23432e+25" },
+ { 1.234321234321234e26L, "1.23432e+26" },
+ { 1.234321234321234e27L, "1.23432e+27" },
+ { 1.234321234321234e28L, "1.23432e+28" },
+ { 1.234321234321234e29L, "1.23432e+29" },
+ { 1.234321234321234e30L, "1.23432e+30" },
+ { 1.234321234321234e31L, "1.23432e+31" },
+ { 1.234321234321234e32L, "1.23432e+32" },
+ { 1.234321234321234e33L, "1.23432e+33" },
+ { 1.234321234321234e34L, "1.23432e+34" },
+ { 1.234321234321234e35L, "1.23432e+35" },
+ { 1.234321234321234e36L, "1.23432e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (expected[strlen (expected) - 4] == 'e'
+ && strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ }
+ }
+
+ { /* A negative number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", -0.03125L, 33, 44, 55);
+ ASSERT (strcmp (result, "-0.03125 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative zero. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", minus_zerol, 33, 44, 55);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Positive infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative infinity. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+#endif
+
+ { /* Width. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%10Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%-10Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%+Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "+1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_SPACE. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "% Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.75000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%#.Lg %d", 9.75L, 33, 44, 55);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%010Lg %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "0000001234 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%015Lg %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%050Lg %d", NaNl (), 33, 44, 55);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%.Lg %d", 1234.0L, 33, 44, 55);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with no rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.5Lg %d", 999.951L, 33, 44, 55);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision with rounding. */
+ char result[100];
+ int retval =
+ my_sprintf (result, "%.5Lg %d", 999.996L, 33, 44, 55);
+ ASSERT (strcmp (result, "1000 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %n format directive. */
+
+ {
+ int count = -1;
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%d %n", 123, &count, 33, 44, 55);
+ ASSERT (strcmp (result, "123 ") == 0);
+ ASSERT (retval == strlen (result));
+ ASSERT (count == 4);
+ }
+
+ /* Test the support of the POSIX/XSI format strings with positions. */
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%2$d %1$d", 33, 55);
+ ASSERT (strcmp (result, "55 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the grouping flag. */
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "%'d %d", 1234567, 99);
+ ASSERT (result[strlen (result) - 1] == '9');
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the left-adjust flag. */
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "a%*sc", -3, "b");
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "a%-*sc", 3, "b");
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[1000];
+ int retval =
+ my_sprintf (result, "a%-*sc", -3, "b");
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of large precision. */
+
+ {
+ char result[5000];
+ int retval =
+ my_sprintf (result, "%.4000d %d", 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_sprintf (result, "%.*d %d", 4000, 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_sprintf (result, "%.4000d %d", -1234567, 99);
+ size_t i;
+ ASSERT (result[0] == '-');
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[1 + i] == '0');
+ ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_sprintf (result, "%.4000u %d", 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_sprintf (result, "%.4000o %d", 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_sprintf (result, "%.4000x %d", 1234567, 99);
+ size_t i;
+ for (i = 0; i < 4000 - 6; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char result[5000];
+ int retval =
+ my_sprintf (result, "%#.4000x %d", 1234567, 99);
+ size_t i;
+ ASSERT (result[0] == '0');
+ ASSERT (result[1] == 'x');
+ for (i = 0; i < 4000 - 6; i++)
+ ASSERT (result[2 + i] == '0');
+ ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ {
+ char input[5000];
+ char result[5000];
+ int retval;
+ size_t i;
+
+ for (i = 0; i < sizeof (input) - 1; i++)
+ input[i] = 'a' + ((1000000 / (i + 1)) % 26);
+ input[i] = '\0';
+ retval = my_sprintf (result, "%.4000s %d", input, 99);
+ ASSERT (memcmp (result, input, 4000) == 0);
+ ASSERT (strcmp (result + 4000, " 99") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ /* Test the support of the %s format directive. */
+
+ /* To verify that these tests succeed, it is necessary to run them under
+ a tool that checks against invalid memory accesses, such as ElectricFence
+ or "valgrind --tool=memcheck". */
+ {
+ size_t i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ char *block;
+ char result[5000];
+ int retval;
+
+ block = (char *) malloc (i);
+ memcpy (block, "abcdefgh", i);
+ retval = my_sprintf (result, "%.*s", (int) i, block);
+ ASSERT (memcmp (result, block, i) == 0);
+ ASSERT (result[i] == '\0');
+ ASSERT (retval == strlen (result));
+ free (block);
+ }
+ }
+#if HAVE_WCHAR_T
+ {
+ size_t i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ wchar_t *block;
+ size_t j;
+ char result[5000];
+ int retval;
+
+ block = (wchar_t *) malloc (i * sizeof (wchar_t));
+ for (j = 0; j < i; j++)
+ block[j] = "abcdefgh"[j];
+ retval = my_sprintf (result, "%.*ls", (int) i, block);
+ ASSERT (memcmp (result, "abcdefgh", i) == 0);
+ ASSERT (result[i] == '\0');
+ ASSERT (retval == strlen (result));
+ free (block);
+ }
+ }
+#endif
+}
diff --git a/tests/gnu/test-stat.c b/tests/gnu/test-stat.c
new file mode 100755
index 00000000..05dd3759
--- /dev/null
+++ b/tests/gnu/test-stat.c
@@ -0,0 +1,56 @@
+/* Tests of stat.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+/* Caution: stat may be a function-like macro. Although this
+ signature check must pass, it may be the signature of the real (and
+ broken) stat rather than rpl_stat. Most code should not use the
+ address of stat. */
+#include "signature.h"
+SIGNATURE_CHECK (stat, int, (char const *, struct stat *));
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "pathmax.h"
+#include "same-inode.h"
+#include "macros.h"
+
+#define BASE "test-stat.t"
+
+#include "test-stat.h"
+
+/* Wrapper around stat, which works even if stat is a function-like
+ macro, where test_stat_func(stat) would do the wrong thing. */
+static int
+do_stat (char const *name, struct stat *st)
+{
+ return stat (name, st);
+}
+
+int
+main (void)
+{
+ return test_stat_func (do_stat, true);
+}
diff --git a/tests/gnu/test-stat.h b/tests/gnu/test-stat.h
new file mode 100755
index 00000000..f0904204
--- /dev/null
+++ b/tests/gnu/test-stat.h
@@ -0,0 +1,100 @@
+/* Tests of stat.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+/* This file is designed to test both stat(n,buf) and
+ fstatat(AT_FDCWD,n,buf,0). FUNC is the function to test. Assumes
+ that BASE and ASSERT are already defined, and that appropriate
+ headers are already included. If PRINT, warn before skipping
+ symlink tests with status 77. */
+
+static int
+test_stat_func (int (*func) (char const *, struct stat *), bool print)
+{
+ struct stat st1;
+ struct stat st2;
+ char cwd[PATH_MAX];
+
+ ASSERT (getcwd (cwd, PATH_MAX) == cwd);
+ ASSERT (func (".", &st1) == 0);
+ ASSERT (func ("./", &st2) == 0);
+ ASSERT (SAME_INODE (st1, st2));
+ ASSERT (func (cwd, &st2) == 0);
+ ASSERT (SAME_INODE (st1, st2));
+ ASSERT (func ("/", &st1) == 0);
+ ASSERT (func ("///", &st2) == 0);
+ ASSERT (SAME_INODE (st1, st2));
+
+ errno = 0;
+ ASSERT (func ("", &st1) == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func ("nosuch", &st1) == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func ("nosuch/", &st1) == -1);
+ ASSERT (errno == ENOENT);
+
+ ASSERT (close (creat (BASE "file", 0600)) == 0);
+ ASSERT (func (BASE "file", &st1) == 0);
+ errno = 0;
+ ASSERT (func (BASE "file/", &st1) == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Now for some symlink tests, where supported. We set up:
+ link1 -> directory
+ link2 -> file
+ link3 -> dangling
+ link4 -> loop
+ then test behavior with trailing slash.
+ */
+ if (symlink (".", BASE "link1") != 0)
+ {
+ ASSERT (unlink (BASE "file") == 0);
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+ ASSERT (symlink (BASE "file", BASE "link2") == 0);
+ ASSERT (symlink (BASE "nosuch", BASE "link3") == 0);
+ ASSERT (symlink (BASE "link4", BASE "link4") == 0);
+
+ ASSERT (func (BASE "link1/", &st1) == 0);
+ ASSERT (S_ISDIR (st1.st_mode));
+
+ errno = 0;
+ ASSERT (func (BASE "link2/", &st1) == -1);
+ ASSERT (errno == ENOTDIR);
+
+ errno = 0;
+ ASSERT (func (BASE "link3/", &st1) == -1);
+ ASSERT (errno == ENOENT);
+
+ errno = 0;
+ ASSERT (func (BASE "link4/", &st1) == -1);
+ ASSERT (errno == ELOOP);
+
+ /* Cleanup. */
+ ASSERT (unlink (BASE "file") == 0);
+ ASSERT (unlink (BASE "link1") == 0);
+ ASSERT (unlink (BASE "link2") == 0);
+ ASSERT (unlink (BASE "link3") == 0);
+ ASSERT (unlink (BASE "link4") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-stdbool.c b/tests/gnu/test-stdbool.c
new file mode 100755
index 00000000..560e0e53
--- /dev/null
+++ b/tests/gnu/test-stdbool.c
@@ -0,0 +1,95 @@
+/* Test of <stdbool.h> substitute.
+ Copyright (C) 2002-2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdbool.h>
+
+#ifndef bool
+ "error: bool is not defined"
+#endif
+#ifndef false
+ "error: false is not defined"
+#endif
+#if false
+ "error: false is not 0"
+#endif
+#ifndef true
+ "error: true is not defined"
+#endif
+#if true != 1
+ "error: true is not 1"
+#endif
+#ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+#endif
+
+#if 0 /* Cannot be guaranteed with gnulib's <stdbool.h>. */
+struct s { _Bool s: 1; _Bool t; } s;
+#endif
+
+char a[true == 1 ? 1 : -1];
+char b[false == 0 ? 1 : -1];
+char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+#if 0 /* Cannot be guaranteed with gnulib's <stdbool.h>. */
+char d[(bool) 0.5 == true ? 1 : -1];
+bool e = &s;
+#endif
+char f[(_Bool) 0.0 == false ? 1 : -1];
+char g[true];
+char h[sizeof (_Bool)];
+#if 0 /* See above. */
+char i[sizeof s.t];
+#endif
+enum { j = false, k = true, l = false * true, m = true * 256 };
+_Bool n[m];
+char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+#if 0 /* Cannot be guaranteed with gnulib's <stdbool.h>. */
+#if defined __xlc__ || defined __GNUC__
+ /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0
+ reported by James Lemley on 2005-10-05; see
+ http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
+ This test is not quite right, since xlc is allowed to
+ reject this program, as the initializer for xlcbug is
+ not one of the forms that C requires support for.
+ However, doing the test right would require a run-time
+ test, and that would make cross-compilation harder.
+ Let us hope that IBM fixes the xlc bug, and also adds
+ support for this kind of constant expression. In the
+ meantime, this test will reject xlc, which is OK, since
+ our stdbool.h substitute should suffice. We also test
+ this with GCC, where it should work, to detect more
+ quickly whether someone messes up the test in the
+ future. */
+ char digs[] = "0123456789";
+ int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1);
+#endif
+#endif
+/* Catch a bug in an HP-UX C compiler. See
+ http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+ http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+ */
+_Bool q = true;
+_Bool *pq = &q;
+
+int
+main ()
+{
+ return 0;
+}
diff --git a/tests/gnu/test-stddef.c b/tests/gnu/test-stddef.c
new file mode 100755
index 00000000..d047e57b
--- /dev/null
+++ b/tests/gnu/test-stddef.c
@@ -0,0 +1,38 @@
+/* Test of <stddef.h> substitute.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include "verify.h"
+
+/* Check that appropriate types are defined. */
+wchar_t a = 'c';
+ptrdiff_t b = 1;
+size_t c = 2;
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-stdint.c b/tests/gnu/test-stdint.c
new file mode 100755
index 00000000..9cec2e2f
--- /dev/null
+++ b/tests/gnu/test-stdint.c
@@ -0,0 +1,360 @@
+/* Test of <stdint.h> substitute.
+ Copyright (C) 2006-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2006. */
+
+#include <config.h>
+
+/* Whether to enable pedantic checks. */
+#define DO_PEDANTIC 0
+
+#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */
+#include <stdint.h>
+
+#include "verify.h"
+#include "intprops.h"
+
+#if __GNUC__ >= 2 && DO_PEDANTIC
+# define verify_same_types(expr1,expr2) \
+ extern void _verify_func(__LINE__) (__typeof__ (expr1) *); \
+ extern void _verify_func(__LINE__) (__typeof__ (expr2) *);
+# define _verify_func(line) _verify_func2(line)
+# define _verify_func2(line) verify_func_ ## line
+#else
+# define verify_same_types(expr1,expr2) extern void verify_func (int)
+#endif
+
+/* 7.18.1.1. Exact-width integer types */
+/* 7.18.2.1. Limits of exact-width integer types */
+
+int8_t a1[3] = { INT8_C (17), INT8_MIN, INT8_MAX };
+verify (TYPE_MINIMUM (int8_t) == INT8_MIN);
+verify (TYPE_MAXIMUM (int8_t) == INT8_MAX);
+verify_same_types (INT8_MIN, (int8_t) 0 + 0);
+verify_same_types (INT8_MAX, (int8_t) 0 + 0);
+
+int16_t a2[3] = { INT16_C (17), INT16_MIN, INT16_MAX };
+verify (TYPE_MINIMUM (int16_t) == INT16_MIN);
+verify (TYPE_MAXIMUM (int16_t) == INT16_MAX);
+verify_same_types (INT16_MIN, (int16_t) 0 + 0);
+verify_same_types (INT16_MAX, (int16_t) 0 + 0);
+
+int32_t a3[3] = { INT32_C (17), INT32_MIN, INT32_MAX };
+verify (TYPE_MINIMUM (int32_t) == INT32_MIN);
+verify (TYPE_MAXIMUM (int32_t) == INT32_MAX);
+verify_same_types (INT32_MIN, (int32_t) 0 + 0);
+verify_same_types (INT32_MAX, (int32_t) 0 + 0);
+
+#ifdef INT64_MAX
+int64_t a4[3] = { INT64_C (17), INT64_MIN, INT64_MAX };
+verify (TYPE_MINIMUM (int64_t) == INT64_MIN);
+verify (TYPE_MAXIMUM (int64_t) == INT64_MAX);
+verify_same_types (INT64_MIN, (int64_t) 0 + 0);
+verify_same_types (INT64_MAX, (int64_t) 0 + 0);
+#endif
+
+uint8_t b1[2] = { UINT8_C (17), UINT8_MAX };
+verify (TYPE_MAXIMUM (uint8_t) == UINT8_MAX);
+verify_same_types (UINT8_MAX, (uint8_t) 0 + 0);
+
+uint16_t b2[2] = { UINT16_C (17), UINT16_MAX };
+verify (TYPE_MAXIMUM (uint16_t) == UINT16_MAX);
+verify_same_types (UINT16_MAX, (uint16_t) 0 + 0);
+
+uint32_t b3[2] = { UINT32_C (17), UINT32_MAX };
+verify (TYPE_MAXIMUM (uint32_t) == UINT32_MAX);
+verify_same_types (UINT32_MAX, (uint32_t) 0 + 0);
+
+#ifdef UINT64_MAX
+uint64_t b4[2] = { UINT64_C (17), UINT64_MAX };
+verify (TYPE_MAXIMUM (uint64_t) == UINT64_MAX);
+verify_same_types (UINT64_MAX, (uint64_t) 0 + 0);
+#endif
+
+#if INT8_MIN && INT8_MAX && INT16_MIN && INT16_MAX && INT32_MIN && INT32_MAX
+/* ok */
+#else
+err or;
+#endif
+
+#if UINT8_MAX && UINT16_MAX && UINT32_MAX
+/* ok */
+#else
+err or;
+#endif
+
+/* 7.18.1.2. Minimum-width integer types */
+/* 7.18.2.2. Limits of minimum-width integer types */
+
+int_least8_t c1[3] = { 17, INT_LEAST8_MIN, INT_LEAST8_MAX };
+verify (TYPE_MINIMUM (int_least8_t) == INT_LEAST8_MIN);
+verify (TYPE_MAXIMUM (int_least8_t) == INT_LEAST8_MAX);
+verify_same_types (INT_LEAST8_MIN, (int_least8_t) 0 + 0);
+verify_same_types (INT_LEAST8_MAX, (int_least8_t) 0 + 0);
+
+int_least16_t c2[3] = { 17, INT_LEAST16_MIN, INT_LEAST16_MAX };
+verify (TYPE_MINIMUM (int_least16_t) == INT_LEAST16_MIN);
+verify (TYPE_MAXIMUM (int_least16_t) == INT_LEAST16_MAX);
+verify_same_types (INT_LEAST16_MIN, (int_least16_t) 0 + 0);
+verify_same_types (INT_LEAST16_MAX, (int_least16_t) 0 + 0);
+
+int_least32_t c3[3] = { 17, INT_LEAST32_MIN, INT_LEAST32_MAX };
+verify (TYPE_MINIMUM (int_least32_t) == INT_LEAST32_MIN);
+verify (TYPE_MAXIMUM (int_least32_t) == INT_LEAST32_MAX);
+verify_same_types (INT_LEAST32_MIN, (int_least32_t) 0 + 0);
+verify_same_types (INT_LEAST32_MAX, (int_least32_t) 0 + 0);
+
+#ifdef INT_LEAST64_MAX
+int_least64_t c4[3] = { 17, INT_LEAST64_MIN, INT_LEAST64_MAX };
+verify (TYPE_MINIMUM (int_least64_t) == INT_LEAST64_MIN);
+verify (TYPE_MAXIMUM (int_least64_t) == INT_LEAST64_MAX);
+verify_same_types (INT_LEAST64_MIN, (int_least64_t) 0 + 0);
+verify_same_types (INT_LEAST64_MAX, (int_least64_t) 0 + 0);
+#endif
+
+uint_least8_t d1[2] = { 17, UINT_LEAST8_MAX };
+verify (TYPE_MAXIMUM (uint_least8_t) == UINT_LEAST8_MAX);
+verify_same_types (UINT_LEAST8_MAX, (uint_least8_t) 0 + 0);
+
+uint_least16_t d2[2] = { 17, UINT_LEAST16_MAX };
+verify (TYPE_MAXIMUM (uint_least16_t) == UINT_LEAST16_MAX);
+verify_same_types (UINT_LEAST16_MAX, (uint_least16_t) 0 + 0);
+
+uint_least32_t d3[2] = { 17, UINT_LEAST32_MAX };
+verify (TYPE_MAXIMUM (uint_least32_t) == UINT_LEAST32_MAX);
+verify_same_types (UINT_LEAST32_MAX, (uint_least32_t) 0 + 0);
+
+#ifdef UINT_LEAST64_MAX
+uint_least64_t d4[2] = { 17, UINT_LEAST64_MAX };
+verify (TYPE_MAXIMUM (uint_least64_t) == UINT_LEAST64_MAX);
+verify_same_types (UINT_LEAST64_MAX, (uint_least64_t) 0 + 0);
+#endif
+
+#if INT_LEAST8_MIN && INT_LEAST8_MAX && INT_LEAST16_MIN && INT_LEAST16_MAX && INT_LEAST32_MIN && INT_LEAST32_MAX
+/* ok */
+#else
+err or;
+#endif
+
+#if UINT_LEAST8_MAX && UINT_LEAST16_MAX && UINT_LEAST32_MAX
+/* ok */
+#else
+err or;
+#endif
+
+/* 7.18.1.3. Fastest minimum-width integer types */
+/* 7.18.2.3. Limits of fastest minimum-width integer types */
+
+int_fast8_t e1[3] = { 17, INT_FAST8_MIN, INT_FAST8_MAX };
+verify (TYPE_MINIMUM (int_fast8_t) == INT_FAST8_MIN);
+verify (TYPE_MAXIMUM (int_fast8_t) == INT_FAST8_MAX);
+verify_same_types (INT_FAST8_MIN, (int_fast8_t) 0 + 0);
+verify_same_types (INT_FAST8_MAX, (int_fast8_t) 0 + 0);
+
+int_fast16_t e2[3] = { 17, INT_FAST16_MIN, INT_FAST16_MAX };
+verify (TYPE_MINIMUM (int_fast16_t) == INT_FAST16_MIN);
+verify (TYPE_MAXIMUM (int_fast16_t) == INT_FAST16_MAX);
+verify_same_types (INT_FAST16_MIN, (int_fast16_t) 0 + 0);
+verify_same_types (INT_FAST16_MAX, (int_fast16_t) 0 + 0);
+
+int_fast32_t e3[3] = { 17, INT_FAST32_MIN, INT_FAST32_MAX };
+verify (TYPE_MINIMUM (int_fast32_t) == INT_FAST32_MIN);
+verify (TYPE_MAXIMUM (int_fast32_t) == INT_FAST32_MAX);
+verify_same_types (INT_FAST32_MIN, (int_fast32_t) 0 + 0);
+verify_same_types (INT_FAST32_MAX, (int_fast32_t) 0 + 0);
+
+#ifdef INT_FAST64_MAX
+int_fast64_t e4[3] = { 17, INT_FAST64_MIN, INT_FAST64_MAX };
+verify (TYPE_MINIMUM (int_fast64_t) == INT_FAST64_MIN);
+verify (TYPE_MAXIMUM (int_fast64_t) == INT_FAST64_MAX);
+verify_same_types (INT_FAST64_MIN, (int_fast64_t) 0 + 0);
+verify_same_types (INT_FAST64_MAX, (int_fast64_t) 0 + 0);
+#endif
+
+uint_fast8_t f1[2] = { 17, UINT_FAST8_MAX };
+verify (TYPE_MAXIMUM (uint_fast8_t) == UINT_FAST8_MAX);
+verify_same_types (UINT_FAST8_MAX, (uint_fast8_t) 0 + 0);
+
+uint_fast16_t f2[2] = { 17, UINT_FAST16_MAX };
+verify (TYPE_MAXIMUM (uint_fast16_t) == UINT_FAST16_MAX);
+verify_same_types (UINT_FAST16_MAX, (uint_fast16_t) 0 + 0);
+
+uint_fast32_t f3[2] = { 17, UINT_FAST32_MAX };
+verify (TYPE_MAXIMUM (uint_fast32_t) == UINT_FAST32_MAX);
+verify_same_types (UINT_FAST32_MAX, (uint_fast32_t) 0 + 0);
+
+#ifdef UINT_FAST64_MAX
+uint_fast64_t f4[2] = { 17, UINT_FAST64_MAX };
+verify (TYPE_MAXIMUM (uint_fast64_t) == UINT_FAST64_MAX);
+verify_same_types (UINT_FAST64_MAX, (uint_fast64_t) 0 + 0);
+#endif
+
+#if INT_FAST8_MIN && INT_FAST8_MAX && INT_FAST16_MIN && INT_FAST16_MAX && INT_FAST32_MIN && INT_FAST32_MAX
+/* ok */
+#else
+err or;
+#endif
+
+#if UINT_FAST8_MAX && UINT_FAST16_MAX && UINT_FAST32_MAX
+/* ok */
+#else
+err or;
+#endif
+
+/* 7.18.1.4. Integer types capable of holding object pointers */
+/* 7.18.2.4. Limits of integer types capable of holding object pointers */
+
+intptr_t g[3] = { 17, INTPTR_MIN, INTPTR_MAX };
+verify (TYPE_MINIMUM (intptr_t) == INTPTR_MIN);
+verify (TYPE_MAXIMUM (intptr_t) == INTPTR_MAX);
+verify_same_types (INTPTR_MIN, (intptr_t) 0 + 0);
+verify_same_types (INTPTR_MAX, (intptr_t) 0 + 0);
+
+uintptr_t h[2] = { 17, UINTPTR_MAX };
+verify (TYPE_MAXIMUM (uintptr_t) == UINTPTR_MAX);
+verify_same_types (UINTPTR_MAX, (uintptr_t) 0 + 0);
+
+#if INTPTR_MIN && INTPTR_MAX && UINTPTR_MAX
+/* ok */
+#else
+err or;
+#endif
+
+/* 7.18.1.5. Greatest-width integer types */
+/* 7.18.2.5. Limits of greatest-width integer types */
+
+intmax_t i[3] = { INTMAX_C (17), INTMAX_MIN, INTMAX_MAX };
+verify (TYPE_MINIMUM (intmax_t) == INTMAX_MIN);
+verify (TYPE_MAXIMUM (intmax_t) == INTMAX_MAX);
+verify_same_types (INTMAX_MIN, (intmax_t) 0 + 0);
+verify_same_types (INTMAX_MAX, (intmax_t) 0 + 0);
+
+uintmax_t j[2] = { UINTMAX_C (17), UINTMAX_MAX };
+verify (TYPE_MAXIMUM (uintmax_t) == UINTMAX_MAX);
+verify_same_types (UINTMAX_MAX, (uintmax_t) 0 + 0);
+
+/* As of 2007, Sun C and HP-UX 10.20 cc don't support 'long long' constants in
+ the preprocessor. */
+#if !(defined __SUNPRO_C || (defined __hpux && !defined __GNUC__))
+#if INTMAX_MIN && INTMAX_MAX && UINTMAX_MAX
+/* ok */
+#else
+err or;
+#endif
+#endif
+
+/* 7.18.3. Limits of other integer types */
+
+#include <stddef.h>
+
+verify (TYPE_MINIMUM (ptrdiff_t) == PTRDIFF_MIN);
+verify (TYPE_MAXIMUM (ptrdiff_t) == PTRDIFF_MAX);
+verify_same_types (PTRDIFF_MIN, (ptrdiff_t) 0 + 0);
+verify_same_types (PTRDIFF_MAX, (ptrdiff_t) 0 + 0);
+
+#if PTRDIFF_MIN && PTRDIFF_MAX
+/* ok */
+#else
+err or;
+#endif
+
+#include <signal.h>
+
+verify (TYPE_MINIMUM (sig_atomic_t) == SIG_ATOMIC_MIN);
+verify (TYPE_MAXIMUM (sig_atomic_t) == SIG_ATOMIC_MAX);
+verify_same_types (SIG_ATOMIC_MIN, (sig_atomic_t) 0 + 0);
+verify_same_types (SIG_ATOMIC_MAX, (sig_atomic_t) 0 + 0);
+
+#if SIG_ATOMIC_MIN != 17 && SIG_ATOMIC_MAX
+/* ok */
+#else
+err or;
+#endif
+
+verify (TYPE_MAXIMUM (size_t) == SIZE_MAX);
+verify_same_types (SIZE_MAX, (size_t) 0 + 0);
+
+#if SIZE_MAX
+/* ok */
+#else
+err or;
+#endif
+
+#if HAVE_WCHAR_T
+verify (TYPE_MINIMUM (wchar_t) == WCHAR_MIN);
+verify (TYPE_MAXIMUM (wchar_t) == WCHAR_MAX);
+verify_same_types (WCHAR_MIN, (wchar_t) 0 + 0);
+verify_same_types (WCHAR_MAX, (wchar_t) 0 + 0);
+
+# if WCHAR_MIN != 17 && WCHAR_MAX
+/* ok */
+# else
+err or;
+# endif
+#endif
+
+#if HAVE_WINT_T
+# include <wchar.h>
+
+verify (TYPE_MINIMUM (wint_t) == WINT_MIN);
+verify (TYPE_MAXIMUM (wint_t) == WINT_MAX);
+verify_same_types (WINT_MIN, (wint_t) 0 + 0);
+verify_same_types (WINT_MAX, (wint_t) 0 + 0);
+
+# if WINT_MIN != 17 && WINT_MAX
+/* ok */
+# else
+err or;
+# endif
+#endif
+
+/* 7.18.4. Macros for integer constants */
+
+verify (INT8_C (17) == 17);
+verify_same_types (INT8_C (17), (int_least8_t)0 + 0);
+verify (UINT8_C (17) == 17);
+verify_same_types (UINT8_C (17), (uint_least8_t)0 + 0);
+
+verify (INT16_C (17) == 17);
+verify_same_types (INT16_C (17), (int_least16_t)0 + 0);
+verify (UINT16_C (17) == 17);
+verify_same_types (UINT16_C (17), (uint_least16_t)0 + 0);
+
+verify (INT32_C (17) == 17);
+verify_same_types (INT32_C (17), (int_least32_t)0 + 0);
+verify (UINT32_C (17) == 17);
+verify_same_types (UINT32_C (17), (uint_least32_t)0 + 0);
+
+#ifdef INT64_C
+verify (INT64_C (17) == 17);
+verify_same_types (INT64_C (17), (int_least64_t)0 + 0);
+#endif
+#ifdef UINT64_C
+verify (UINT64_C (17) == 17);
+verify_same_types (UINT64_C (17), (uint_least64_t)0 + 0);
+#endif
+
+verify (INTMAX_C (17) == 17);
+verify_same_types (INTMAX_C (17), (intmax_t)0 + 0);
+verify (UINTMAX_C (17) == 17);
+verify_same_types (UINTMAX_C (17), (uintmax_t)0 + 0);
+
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-stdio.c b/tests/gnu/test-stdio.c
new file mode 100755
index 00000000..87100576
--- /dev/null
+++ b/tests/gnu/test-stdio.c
@@ -0,0 +1,43 @@
+/* Test of <stdio.h> substitute.
+ Copyright (C) 2007, 2009-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "verify.h"
+
+/* Check that the various SEEK_* macros are defined. */
+int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+/* Check that the types are all defined. */
+fpos_t t1;
+off_t t2;
+size_t t3;
+ssize_t t4;
+va_list t5;
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-stdlib.c b/tests/gnu/test-stdlib.c
new file mode 100755
index 00000000..4bd8715f
--- /dev/null
+++ b/tests/gnu/test-stdlib.c
@@ -0,0 +1,43 @@
+/* Test of <stdlib.h> substitute.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "verify.h"
+
+int exitcode;
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+int
+main (void)
+{
+ /* Check that some macros are defined and different integer constants. */
+ switch (exitcode)
+ {
+ case EXIT_SUCCESS:
+ case EXIT_FAILURE:
+ break;
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-strchrnul.c b/tests/gnu/test-strchrnul.c
new file mode 100755
index 00000000..49d8278c
--- /dev/null
+++ b/tests/gnu/test-strchrnul.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+ * Written by Eric Blake and Bruno Haible
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (strchrnul, char *, (char const *, int));
+
+#include <stdlib.h>
+
+#include "macros.h"
+
+int
+main (void)
+{
+ size_t n = 0x100000;
+ char *input = malloc (n + 1);
+ ASSERT (input);
+
+ input[0] = 'a';
+ input[1] = 'b';
+ memset (input + 2, 'c', 1024);
+ memset (input + 1026, 'd', n - 1028);
+ input[n - 2] = 'e';
+ input[n - 1] = 'a';
+ input[n] = '\0';
+
+ /* Basic behavior tests. */
+ ASSERT (strchrnul (input, 'a') == input);
+ ASSERT (strchrnul (input, 'b') == input + 1);
+ ASSERT (strchrnul (input, 'c') == input + 2);
+ ASSERT (strchrnul (input, 'd') == input + 1026);
+
+ ASSERT (strchrnul (input + 1, 'a') == input + n - 1);
+ ASSERT (strchrnul (input + 1, 'e') == input + n - 2);
+
+ ASSERT (strchrnul (input, 'f') == input + n);
+ ASSERT (strchrnul (input, '\0') == input + n);
+
+ /* Check that a very long haystack is handled quickly if the byte is
+ found near the beginning. */
+ {
+ size_t repeat = 10000;
+ for (; repeat > 0; repeat--)
+ {
+ ASSERT (strchrnul (input, 'c') == input + 2);
+ }
+ }
+
+ /* Alignment tests. */
+ {
+ int i, j;
+ for (i = 0; i < 32; i++)
+ {
+ for (j = 0; j < 256; j++)
+ input[i + j] = (j + 1) & 0xff;
+ for (j = 1; j < 256; j++)
+ {
+ ASSERT (strchrnul (input + i, j) == input + i + j - 1);
+ input[i + j - 1] = (j == 1 ? 2 : 1);
+ ASSERT (strchrnul (input + i, j) == input + i + 255);
+ input[i + j - 1] = j;
+ }
+ }
+ }
+
+ free (input);
+
+ return 0;
+}
diff --git a/tests/gnu/test-strerror.c b/tests/gnu/test-strerror.c
new file mode 100755
index 00000000..11ab7e39
--- /dev/null
+++ b/tests/gnu/test-strerror.c
@@ -0,0 +1,57 @@
+/* Test of strerror() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2007. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (strerror, char *, (int));
+
+#include <errno.h>
+
+#include "macros.h"
+
+int
+main (void)
+{
+ char *str;
+
+ str = strerror (EACCES);
+ ASSERT (str);
+ ASSERT (*str);
+
+ str = strerror (ETIMEDOUT);
+ ASSERT (str);
+ ASSERT (*str);
+
+ str = strerror (EOVERFLOW);
+ ASSERT (str);
+ ASSERT (*str);
+
+ str = strerror (0);
+ ASSERT (str);
+ ASSERT (*str);
+
+ str = strerror (-3);
+ ASSERT (str);
+ ASSERT (*str);
+
+ return 0;
+}
diff --git a/tests/gnu/test-striconv.c b/tests/gnu/test-striconv.c
new file mode 100755
index 00000000..d0f249da
--- /dev/null
+++ b/tests/gnu/test-striconv.c
@@ -0,0 +1,180 @@
+/* Test of character set conversion.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "striconv.h"
+
+#if HAVE_ICONV
+# include <iconv.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+int
+main ()
+{
+#if HAVE_ICONV
+ /* Assume that iconv() supports at least the encodings ASCII, ISO-8859-1,
+ and UTF-8. */
+ iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
+ iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8");
+
+ ASSERT (cd_88591_to_utf8 != (iconv_t)(-1));
+ ASSERT (cd_utf8_to_88591 != (iconv_t)(-1));
+
+ /* ------------------------- Test mem_cd_iconv() ------------------------- */
+
+ /* Test conversion from ISO-8859-1 to UTF-8 with no errors. */
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ static const char expected[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
+ char *result = NULL;
+ size_t length = 0;
+ int retval = mem_cd_iconv (input, strlen (input), cd_88591_to_utf8,
+ &result, &length);
+ ASSERT (retval == 0);
+ ASSERT (length == strlen (expected));
+ ASSERT (result != NULL && memcmp (result, expected, strlen (expected)) == 0);
+ free (result);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with no errors. */
+ {
+ static const char input[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
+ static const char expected[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ char *result = NULL;
+ size_t length = 0;
+ int retval = mem_cd_iconv (input, strlen (input), cd_utf8_to_88591,
+ &result, &length);
+ ASSERT (retval == 0);
+ ASSERT (length == strlen (expected));
+ ASSERT (result != NULL && memcmp (result, expected, strlen (expected)) == 0);
+ free (result);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with EILSEQ. */
+ {
+ static const char input[] = "\342\202\254"; /* EURO SIGN */
+ char *result = NULL;
+ size_t length = 0;
+ int retval = mem_cd_iconv (input, strlen (input), cd_utf8_to_88591,
+ &result, &length);
+ ASSERT (retval == -1 && errno == EILSEQ);
+ ASSERT (result == NULL);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with EINVAL. */
+ {
+ static const char input[] = "\342";
+ char *result = NULL;
+ size_t length = 0;
+ int retval = mem_cd_iconv (input, strlen (input), cd_utf8_to_88591,
+ &result, &length);
+ ASSERT (retval == 0);
+ ASSERT (length == 0);
+ free (result);
+ }
+
+ /* ------------------------- Test str_cd_iconv() ------------------------- */
+
+ /* Test conversion from ISO-8859-1 to UTF-8 with no errors. */
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ static const char expected[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
+ char *result = str_cd_iconv (input, cd_88591_to_utf8);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0);
+ free (result);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with no errors. */
+ {
+ static const char input[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
+ static const char expected[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ char *result = str_cd_iconv (input, cd_utf8_to_88591);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0);
+ free (result);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with EILSEQ. */
+ {
+ static const char input[] = "Costs: 27 \342\202\254"; /* EURO SIGN */
+ char *result = str_cd_iconv (input, cd_utf8_to_88591);
+ ASSERT (result == NULL && errno == EILSEQ);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with EINVAL. */
+ {
+ static const char input[] = "\342";
+ char *result = str_cd_iconv (input, cd_utf8_to_88591);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "") == 0);
+ free (result);
+ }
+
+ iconv_close (cd_88591_to_utf8);
+ iconv_close (cd_utf8_to_88591);
+
+ /* -------------------------- Test str_iconv() -------------------------- */
+
+ /* Test conversion from ISO-8859-1 to UTF-8 with no errors. */
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ static const char expected[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
+ char *result = str_iconv (input, "ISO-8859-1", "UTF-8");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0);
+ free (result);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with no errors. */
+ {
+ static const char input[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
+ static const char expected[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ char *result = str_iconv (input, "UTF-8", "ISO-8859-1");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0);
+ free (result);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with EILSEQ. */
+ {
+ static const char input[] = "Costs: 27 \342\202\254"; /* EURO SIGN */
+ char *result = str_iconv (input, "UTF-8", "ISO-8859-1");
+ ASSERT (result == NULL && errno == EILSEQ);
+ }
+
+ /* Test conversion from UTF-8 to ISO-8859-1 with EINVAL. */
+ {
+ static const char input[] = "\342";
+ char *result = str_iconv (input, "UTF-8", "ISO-8859-1");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "") == 0);
+ free (result);
+ }
+
+#endif
+
+ return 0;
+}
diff --git a/tests/gnu/test-string.c b/tests/gnu/test-string.c
new file mode 100755
index 00000000..019a8174
--- /dev/null
+++ b/tests/gnu/test-string.c
@@ -0,0 +1,33 @@
+/* Test of <string.h> substitute.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "verify.h"
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-strtod.c b/tests/gnu/test-strtod.c
new file mode 100755
index 00000000..cdb57b22
--- /dev/null
+++ b/tests/gnu/test-strtod.c
@@ -0,0 +1,918 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+ * Written by Eric Blake
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (strtod, double, (char const *, char **));
+
+#include <errno.h>
+#include <float.h>
+#include <math.h>
+#include <string.h>
+
+#include "isnand-nolibm.h"
+#include "macros.h"
+
+/* Avoid requiring -lm just for fabs. */
+#define FABS(d) ((d) < 0.0 ? -(d) : (d))
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ So we use -zero instead. */
+double zero = 0.0;
+
+int
+main (void)
+{
+ int status = 0;
+ /* Subject sequence empty or invalid. */
+ {
+ const char input[] = "";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input);
+ ASSERT (errno == 0 || errno == EINVAL);
+ }
+ {
+ const char input[] = " ";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input);
+ ASSERT (errno == 0 || errno == EINVAL);
+ }
+ {
+ const char input[] = " +";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input);
+ ASSERT (errno == 0 || errno == EINVAL);
+ }
+ {
+ const char input[] = " .";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input);
+ ASSERT (errno == 0 || errno == EINVAL);
+ }
+ {
+ const char input[] = " .e0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input); /* IRIX 6.5, OSF/1 5.1 */
+ ASSERT (errno == 0 || errno == EINVAL);
+ }
+ {
+ const char input[] = " +.e-0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input); /* IRIX 6.5, OSF/1 5.1 */
+ ASSERT (errno == 0 || errno == EINVAL);
+ }
+ {
+ const char input[] = " in";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input);
+ ASSERT (errno == 0 || errno == EINVAL);
+ }
+ {
+ const char input[] = " na";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input);
+ ASSERT (errno == 0 || errno == EINVAL);
+ }
+
+ /* Simple floating point values. */
+ {
+ const char input[] = "1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1.";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = ".5";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ /* FIXME - gnulib's version is rather inaccurate. It would be
+ nice to guarantee an exact result, but for now, we settle for a
+ 1-ulp error. */
+ ASSERT (FABS (result - 0.5) < DBL_EPSILON);
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = " 1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "+1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "-1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == -1.0);
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1e0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 3);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1e+0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 4);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1e-0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 4);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1e1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 10.0);
+ ASSERT (ptr == input + 3);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "5e-1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ /* FIXME - gnulib's version is rather inaccurate. It would be
+ nice to guarantee an exact result, but for now, we settle for a
+ 1-ulp error. */
+ ASSERT (FABS (result - 0.5) < DBL_EPSILON);
+ ASSERT (ptr == input + 4);
+ ASSERT (errno == 0);
+ }
+
+ /* Zero. */
+ {
+ const char input[] = "0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = ".0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0e0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 3);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0e+9999999";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 10);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0e-9999999";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 10);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "-0";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!!signbit (result) == !!signbit (-zero)); /* IRIX 6.5, OSF/1 4.0 */
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+
+ /* Suffixes. */
+ {
+ const char input[] = "1f";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1.f";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1e";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1e+";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1e-";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1E 2";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0); /* HP-UX 11.11, IRIX 6.5, OSF/1 4.0 */
+ ASSERT (ptr == input + 1); /* HP-UX 11.11, IRIX 6.5 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "00x1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 2);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "-0x";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!!signbit (result) == !!signbit (-zero)); /* MacOS X 10.3, FreeBSD 6.2, IRIX 6.5, OSF/1 4.0 */
+ ASSERT (ptr == input + 2); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0xg";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0xp";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x.";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0xp+";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0xp+1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x.p+1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "1p+1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+
+ /* Overflow/underflow. */
+ {
+ const char input[] = "1E1000000";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == HUGE_VAL);
+ ASSERT (ptr == input + 9); /* OSF/1 5.1 */
+ ASSERT (errno == ERANGE);
+ }
+ {
+ const char input[] = "-1E1000000";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == -HUGE_VAL);
+ ASSERT (ptr == input + 10);
+ ASSERT (errno == ERANGE);
+ }
+ {
+ const char input[] = "1E-100000";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (0.0 <= result && result <= DBL_MIN);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 9);
+ ASSERT (errno == ERANGE);
+ }
+ {
+ const char input[] = "-1E-100000";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (-DBL_MIN <= result && result <= 0.0);
+#if 0
+ /* FIXME - this is glibc bug 5995; POSIX allows returning positive
+ 0 on negative underflow, even though quality of implementation
+ demands preserving the sign. Disable this test until fixed
+ glibc is more prevalent. */
+ ASSERT (!!signbit (result) == !!signbit (-zero)); /* glibc-2.3.6, mingw */
+#endif
+ ASSERT (ptr == input + 10);
+ ASSERT (errno == ERANGE);
+ }
+
+ /* Infinity. */
+ {
+ const char input[] = "iNf";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == HUGE_VAL); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr == input + 3); /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
+ ASSERT (errno == 0); /* HP-UX 11.11, OSF/1 4.0 */
+ }
+ {
+ const char input[] = "-InF";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == -HUGE_VAL); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr == input + 4); /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 4.0, Solaris 9, mingw */
+ ASSERT (errno == 0); /* HP-UX 11.11, OSF/1 4.0 */
+ }
+ {
+ const char input[] = "infinite";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == HUGE_VAL); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr == input + 3); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (errno == 0); /* OSF/1 4.0 */
+ }
+ {
+ const char input[] = "infinitY";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == HUGE_VAL); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr == input + 8); /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
+ ASSERT (errno == 0); /* HP-UX 11.11, OSF/1 4.0 */
+ }
+ {
+ const char input[] = "infinitY.";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == HUGE_VAL); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr == input + 8); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (errno == 0); /* OSF/1 4.0 */
+ }
+
+ /* NaN. Some processors set the sign bit of the default NaN, so all
+ we check is that using a sign changes the result. */
+ {
+ const char input[] = "-nan";
+ char *ptr1;
+ char *ptr2;
+ double result1;
+ double result2;
+ errno = 0;
+ result1 = strtod (input, &ptr1);
+ result2 = strtod (input + 1, &ptr2);
+#if 1 /* All known CPUs support NaNs. */
+ ASSERT (isnand (result1)); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (isnand (result2)); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+# if 0
+ /* Sign bits of NaN is a portability sticking point, not worth
+ worrying about. */
+ ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
+# endif
+ ASSERT (ptr1 == input + 4); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
+ ASSERT (ptr2 == input + 4); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
+ ASSERT (errno == 0); /* HP-UX 11.11 */
+#else
+ ASSERT (result1 == 0.0);
+ ASSERT (result2 == 0.0);
+ ASSERT (!signbit (result1));
+ ASSERT (!signbit (result2));
+ ASSERT (ptr1 == input);
+ ASSERT (ptr2 == input + 1);
+ ASSERT (errno == 0 || errno == EINVAL);
+#endif
+ }
+ {
+ const char input[] = "+nan(";
+ char *ptr1;
+ char *ptr2;
+ double result1;
+ double result2;
+ errno = 0;
+ result1 = strtod (input, &ptr1);
+ result2 = strtod (input + 1, &ptr2);
+#if 1 /* All known CPUs support NaNs. */
+ ASSERT (isnand (result1)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (isnand (result2)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (!!signbit (result1) == !!signbit (result2));
+ ASSERT (ptr1 == input + 4); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
+ ASSERT (ptr2 == input + 4); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
+ ASSERT (errno == 0);
+#else
+ ASSERT (result1 == 0.0);
+ ASSERT (result2 == 0.0);
+ ASSERT (!signbit (result1));
+ ASSERT (!signbit (result2));
+ ASSERT (ptr1 == input);
+ ASSERT (ptr2 == input + 1);
+ ASSERT (errno == 0 || errno == EINVAL);
+#endif
+ }
+ {
+ const char input[] = "-nan()";
+ char *ptr1;
+ char *ptr2;
+ double result1;
+ double result2;
+ errno = 0;
+ result1 = strtod (input, &ptr1);
+ result2 = strtod (input + 1, &ptr2);
+#if 1 /* All known CPUs support NaNs. */
+ ASSERT (isnand (result1)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (isnand (result2)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+# if 0
+ /* Sign bits of NaN is a portability sticking point, not worth
+ worrying about. */
+ ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
+# endif
+ ASSERT (ptr1 == input + 6); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr2 == input + 6); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (errno == 0);
+#else
+ ASSERT (result1 == 0.0);
+ ASSERT (result2 == 0.0);
+ ASSERT (!signbit (result1));
+ ASSERT (!signbit (result2));
+ ASSERT (ptr1 == input);
+ ASSERT (ptr2 == input + 1);
+ ASSERT (errno == 0 || errno == EINVAL);
+#endif
+ }
+ {
+ const char input[] = " nan().";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+#if 1 /* All known CPUs support NaNs. */
+ ASSERT (isnand (result)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr == input + 6); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (errno == 0);
+#else
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input);
+ ASSERT (errno == 0 || errno == EINVAL);
+#endif
+ }
+ {
+ /* The behavior of nan(0) is implementation-defined, but all
+ implementations we know of which handle optional
+ n-char-sequences handle nan(0) the same as nan(). */
+ const char input[] = "-nan(0).";
+ char *ptr1;
+ char *ptr2;
+ double result1;
+ double result2;
+ errno = 0;
+ result1 = strtod (input, &ptr1);
+ result2 = strtod (input + 1, &ptr2);
+#if 1 /* All known CPUs support NaNs. */
+ ASSERT (isnand (result1)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (isnand (result2)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+# if 0
+ /* Sign bits of NaN is a portability sticking point, not worth
+ worrying about. */
+ ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
+# endif
+ ASSERT (ptr1 == input + 7); /* glibc-2.3.6, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr2 == input + 7); /* glibc-2.3.6, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (errno == 0);
+#else
+ ASSERT (result1 == 0.0);
+ ASSERT (result2 == 0.0);
+ ASSERT (!signbit (result1));
+ ASSERT (!signbit (result2));
+ ASSERT (ptr1 == input);
+ ASSERT (ptr2 == input + 1);
+ ASSERT (errno == 0 || errno == EINVAL);
+#endif
+ }
+
+ /* Hex. */
+ {
+ const char input[] = "0xa";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 10.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0XA";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 10.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x1p";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x1p+";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x1p+1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 2.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (ptr == input + 6); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x1p+1a";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 2.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (ptr == input + 6); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+
+ /* Large buffers. */
+ {
+ size_t m = 1000000;
+ char *input = malloc (m + 1);
+ if (input)
+ {
+ char *ptr;
+ double result;
+ memset (input, '\t', m - 1);
+ input[m - 1] = '1';
+ input[m] = '\0';
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + m);
+ ASSERT (errno == 0);
+ }
+ free (input);
+ }
+ {
+ size_t m = 1000000;
+ char *input = malloc (m + 1);
+ if (input)
+ {
+ char *ptr;
+ double result;
+ memset (input, '0', m - 1);
+ input[m - 1] = '1';
+ input[m] = '\0';
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + m);
+ ASSERT (errno == 0);
+ }
+ free (input);
+ }
+#if 0
+ /* Newlib has an artificial limit of 20000 for the exponent. TODO -
+ gnulib should fix this. */
+ {
+ size_t m = 1000000;
+ char *input = malloc (m + 1);
+ if (input)
+ {
+ char *ptr;
+ double result;
+ input[0] = '.';
+ memset (input + 1, '0', m - 10);
+ input[m - 9] = '1';
+ input[m - 8] = 'e';
+ input[m - 7] = '+';
+ input[m - 6] = '9';
+ input[m - 5] = '9';
+ input[m - 4] = '9';
+ input[m - 3] = '9';
+ input[m - 2] = '9';
+ input[m - 1] = '1';
+ input[m] = '\0';
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0); /* MacOS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr == input + m); /* OSF/1 5.1 */
+ ASSERT (errno == 0); /* MacOS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+ }
+ free (input);
+ }
+ {
+ size_t m = 1000000;
+ char *input = malloc (m + 1);
+ if (input)
+ {
+ char *ptr;
+ double result;
+ input[0] = '1';
+ memset (input + 1, '0', m - 9);
+ input[m - 8] = 'e';
+ input[m - 7] = '-';
+ input[m - 6] = '9';
+ input[m - 5] = '9';
+ input[m - 4] = '9';
+ input[m - 3] = '9';
+ input[m - 2] = '9';
+ input[m - 1] = '1';
+ input[m] = '\0';
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0); /* MacOS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+ ASSERT (ptr == input + m);
+ ASSERT (errno == 0); /* MacOS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
+ }
+ free (input);
+ }
+#endif
+ {
+ size_t m = 1000000;
+ char *input = malloc (m + 1);
+ if (input)
+ {
+ char *ptr;
+ double result;
+ input[0] = '-';
+ input[1] = '0';
+ input[2] = 'e';
+ input[3] = '1';
+ memset (input + 4, '0', m - 3);
+ input[m] = '\0';
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!!signbit (result) == !!signbit (-zero)); /* IRIX 6.5, OSF/1 4.0 */
+ ASSERT (ptr == input + m);
+ ASSERT (errno == 0);
+ }
+ free (input);
+ }
+
+ /* Rounding. */
+ /* TODO - is it worth some tests of rounding for typical IEEE corner
+ cases, such as .5 ULP rounding up to the smallest denormal and
+ not causing underflow, or DBL_MIN - .5 ULP not causing an
+ infinite loop? */
+
+ return status;
+}
diff --git a/tests/gnu/test-symlink.c b/tests/gnu/test-symlink.c
new file mode 100755
index 00000000..d2df54c4
--- /dev/null
+++ b/tests/gnu/test-symlink.c
@@ -0,0 +1,47 @@
+/* Tests of symlink.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (symlink, int, (char const *, char const *));
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "test-symlink.t"
+
+#include "test-symlink.h"
+
+int
+main (void)
+{
+ /* Remove any leftovers from a previous partial run. */
+ ignore_value (system ("rm -rf " BASE "*"));
+
+ return test_symlink (symlink, true);
+}
diff --git a/tests/gnu/test-symlink.h b/tests/gnu/test-symlink.h
new file mode 100755
index 00000000..0c92bd40
--- /dev/null
+++ b/tests/gnu/test-symlink.h
@@ -0,0 +1,95 @@
+/* Tests of symlink.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+/* This file is designed to test both symlink(a,b) and
+ symlinkat(a,AT_FDCWD,b). FUNC is the function to test. Assumes
+ that BASE and ASSERT are already defined, and that appropriate
+ headers are already included. If PRINT, warn before skipping
+ symlink tests with status 77. */
+
+static int
+test_symlink (int (*func) (char const *, char const *), bool print)
+{
+ if (func ("nowhere", BASE "link1"))
+ {
+ if (print)
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
+ return 77;
+ }
+
+ /* Some systems allow the creation of 0-length symlinks as a synonym
+ for "."; but most reject it. */
+ {
+ int status;
+ errno = 0;
+ status = func ("", BASE "link2");
+ if (status == -1)
+ ASSERT (errno == ENOENT || errno == EINVAL);
+ else
+ {
+ ASSERT (status == 0);
+ ASSERT (unlink (BASE "link2") == 0);
+ }
+ }
+
+ /* Sanity checks of failures. */
+ errno = 0;
+ ASSERT (func ("nowhere", "") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func ("nowhere", ".") == -1);
+ ASSERT (errno == EEXIST || errno == EINVAL);
+ errno = 0;
+ ASSERT (func ("somewhere", BASE "link1") == -1);
+ ASSERT (errno == EEXIST);
+ errno = 0;
+ ASSERT (func ("nowhere", BASE "link2/") == -1);
+ ASSERT (errno == ENOTDIR || errno == ENOENT);
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ errno = 0;
+ ASSERT (func ("nowhere", BASE "dir") == -1);
+ ASSERT (errno == EEXIST);
+ errno = 0;
+ ASSERT (func ("nowhere", BASE "dir/") == -1);
+ ASSERT (errno == EEXIST || errno == EINVAL);
+ ASSERT (close (creat (BASE "file", 0600)) == 0);
+ errno = 0;
+ ASSERT (func ("nowhere", BASE "file") == -1);
+ ASSERT (errno == EEXIST);
+ errno = 0;
+ ASSERT (func ("nowhere", BASE "file/") == -1);
+ ASSERT (errno == EEXIST || errno == ENOTDIR || errno == ENOENT);
+
+ /* Trailing slash must always be rejected. */
+ ASSERT (unlink (BASE "link1") == 0);
+ ASSERT (func (BASE "link2", BASE "link1") == 0);
+ errno = 0;
+ ASSERT (func (BASE "nowhere", BASE "link1/") == -1);
+ ASSERT (errno == EEXIST || errno == ENOTDIR || errno == ENOENT);
+ errno = 0;
+ ASSERT (unlink (BASE "link2") == -1);
+ ASSERT (errno == ENOENT);
+
+ /* Cleanup. */
+ ASSERT (rmdir (BASE "dir") == 0);
+ ASSERT (unlink (BASE "file") == 0);
+ ASSERT (unlink (BASE "link1") == 0);
+
+ return 0;
+}
diff --git a/tests/gnu/test-sys_stat.c b/tests/gnu/test-sys_stat.c
new file mode 100755
index 00000000..5f1aacd1
--- /dev/null
+++ b/tests/gnu/test-sys_stat.c
@@ -0,0 +1,288 @@
+/* Test of <sys/stat.h> substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+#include "verify.h"
+
+/* Check the existence of some macros. */
+int a[] =
+ {
+ S_IFMT,
+ S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFREG,
+#ifdef S_IFLNK /* missing on mingw and djgpp */
+ S_IFLNK,
+#endif
+#ifdef S_IFSOCK /* missing on mingw and djgpp */
+ S_IFSOCK,
+#endif
+ S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR,
+ S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP,
+ S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH,
+ S_ISUID, S_ISGID, S_ISVTX,
+ S_ISBLK (S_IFREG),
+ S_ISCHR (S_IFREG),
+ S_ISDIR (S_IFREG),
+ S_ISFIFO (S_IFREG),
+ S_ISREG (S_IFREG),
+ S_ISLNK (S_IFREG),
+ S_ISSOCK (S_IFREG),
+ S_ISDOOR (S_IFREG),
+ S_ISMPB (S_IFREG),
+ S_ISNAM (S_IFREG),
+ S_ISNWK (S_IFREG),
+ S_ISPORT (S_IFREG),
+ S_ISCTG (S_IFREG),
+ S_ISOFD (S_IFREG),
+ S_ISOFL (S_IFREG),
+ S_ISWHT (S_IFREG)
+ };
+
+/* Sanity checks. */
+
+verify (S_IRWXU == (S_IRUSR | S_IWUSR | S_IXUSR));
+verify (S_IRWXG == (S_IRGRP | S_IWGRP | S_IXGRP));
+verify (S_IRWXO == (S_IROTH | S_IWOTH | S_IXOTH));
+
+verify (S_ISBLK (S_IFBLK));
+verify (!S_ISBLK (S_IFCHR));
+verify (!S_ISBLK (S_IFDIR));
+verify (!S_ISBLK (S_IFIFO));
+verify (!S_ISBLK (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISBLK (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISBLK (S_IFSOCK));
+#endif
+
+verify (!S_ISCHR (S_IFBLK));
+verify (S_ISCHR (S_IFCHR));
+verify (!S_ISCHR (S_IFDIR));
+verify (!S_ISCHR (S_IFIFO));
+verify (!S_ISCHR (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISCHR (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISCHR (S_IFSOCK));
+#endif
+
+verify (!S_ISDIR (S_IFBLK));
+verify (!S_ISDIR (S_IFCHR));
+verify (S_ISDIR (S_IFDIR));
+verify (!S_ISDIR (S_IFIFO));
+verify (!S_ISDIR (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISDIR (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISDIR (S_IFSOCK));
+#endif
+
+verify (!S_ISFIFO (S_IFBLK));
+verify (!S_ISFIFO (S_IFCHR));
+verify (!S_ISFIFO (S_IFDIR));
+verify (S_ISFIFO (S_IFIFO));
+verify (!S_ISFIFO (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISFIFO (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISFIFO (S_IFSOCK));
+#endif
+
+verify (!S_ISREG (S_IFBLK));
+verify (!S_ISREG (S_IFCHR));
+verify (!S_ISREG (S_IFDIR));
+verify (!S_ISREG (S_IFIFO));
+verify (S_ISREG (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISREG (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISREG (S_IFSOCK));
+#endif
+
+verify (!S_ISLNK (S_IFBLK));
+verify (!S_ISLNK (S_IFCHR));
+verify (!S_ISLNK (S_IFDIR));
+verify (!S_ISLNK (S_IFIFO));
+verify (!S_ISLNK (S_IFREG));
+#ifdef S_IFLNK
+verify (S_ISLNK (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISLNK (S_IFSOCK));
+#endif
+
+verify (!S_ISSOCK (S_IFBLK));
+verify (!S_ISSOCK (S_IFCHR));
+verify (!S_ISSOCK (S_IFDIR));
+verify (!S_ISSOCK (S_IFIFO));
+verify (!S_ISSOCK (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISSOCK (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (S_ISSOCK (S_IFSOCK));
+#endif
+
+verify (!S_ISDOOR (S_IFBLK));
+verify (!S_ISDOOR (S_IFCHR));
+verify (!S_ISDOOR (S_IFDIR));
+verify (!S_ISDOOR (S_IFIFO));
+verify (!S_ISDOOR (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISDOOR (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISDOOR (S_IFSOCK));
+#endif
+
+verify (!S_ISMPB (S_IFBLK));
+verify (!S_ISMPB (S_IFCHR));
+verify (!S_ISMPB (S_IFDIR));
+verify (!S_ISMPB (S_IFIFO));
+verify (!S_ISMPB (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISMPB (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISMPB (S_IFSOCK));
+#endif
+
+verify (!S_ISNAM (S_IFBLK));
+verify (!S_ISNAM (S_IFCHR));
+verify (!S_ISNAM (S_IFDIR));
+verify (!S_ISNAM (S_IFIFO));
+verify (!S_ISNAM (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISNAM (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISNAM (S_IFSOCK));
+#endif
+
+verify (!S_ISNWK (S_IFBLK));
+verify (!S_ISNWK (S_IFCHR));
+verify (!S_ISNWK (S_IFDIR));
+verify (!S_ISNWK (S_IFIFO));
+verify (!S_ISNWK (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISNWK (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISNWK (S_IFSOCK));
+#endif
+
+verify (!S_ISPORT (S_IFBLK));
+verify (!S_ISPORT (S_IFCHR));
+verify (!S_ISPORT (S_IFDIR));
+verify (!S_ISPORT (S_IFIFO));
+verify (!S_ISPORT (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISPORT (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISPORT (S_IFSOCK));
+#endif
+
+verify (!S_ISCTG (S_IFBLK));
+verify (!S_ISCTG (S_IFCHR));
+verify (!S_ISCTG (S_IFDIR));
+verify (!S_ISCTG (S_IFIFO));
+verify (!S_ISCTG (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISCTG (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISCTG (S_IFSOCK));
+#endif
+
+verify (!S_ISOFD (S_IFBLK));
+verify (!S_ISOFD (S_IFCHR));
+verify (!S_ISOFD (S_IFDIR));
+verify (!S_ISOFD (S_IFIFO));
+verify (!S_ISOFD (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISOFD (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISOFD (S_IFSOCK));
+#endif
+
+verify (!S_ISOFL (S_IFBLK));
+verify (!S_ISOFL (S_IFCHR));
+verify (!S_ISOFL (S_IFDIR));
+verify (!S_ISOFL (S_IFIFO));
+verify (!S_ISOFL (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISOFL (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISOFL (S_IFSOCK));
+#endif
+
+verify (!S_ISWHT (S_IFBLK));
+verify (!S_ISWHT (S_IFCHR));
+verify (!S_ISWHT (S_IFDIR));
+verify (!S_ISWHT (S_IFIFO));
+verify (!S_ISWHT (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISWHT (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISWHT (S_IFSOCK));
+#endif
+
+/* POSIX 2008 requires traditional encoding of permission constants. */
+verify (S_IRWXU == 00700);
+verify (S_IRUSR == 00400);
+verify (S_IWUSR == 00200);
+verify (S_IXUSR == 00100);
+verify (S_IRWXG == 00070);
+verify (S_IRGRP == 00040);
+verify (S_IWGRP == 00020);
+verify (S_IXGRP == 00010);
+verify (S_IRWXO == 00007);
+verify (S_IROTH == 00004);
+verify (S_IWOTH == 00002);
+verify (S_IXOTH == 00001);
+verify (S_ISUID == 04000);
+verify (S_ISGID == 02000);
+verify (S_ISVTX == 01000);
+
+#if ((0 <= UTIME_NOW && UTIME_NOW < 1000000000) \
+ || (0 <= UTIME_OMIT && UTIME_OMIT < 1000000000) \
+ || UTIME_NOW == UTIME_OMIT)
+invalid UTIME macros
+#endif
+
+/* Check the existence of some types. */
+nlink_t t1;
+
+struct timespec t2;
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-sys_time.c b/tests/gnu/test-sys_time.c
new file mode 100755
index 00000000..2ab849e9
--- /dev/null
+++ b/tests/gnu/test-sys_time.c
@@ -0,0 +1,29 @@
+/* Test of <sys/time.h> substitute.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <sys/time.h>
+
+struct timeval a;
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-sys_wait.c b/tests/gnu/test-sys_wait.c
new file mode 100755
index 00000000..8c0170ed
--- /dev/null
+++ b/tests/gnu/test-sys_wait.c
@@ -0,0 +1,30 @@
+/* Test of <sys/wait.h> substitute.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <sys/wait.h>
+
+/* Check for existence of required types. */
+static pid_t a;
+
+int
+main (void)
+{
+ return a;
+}
diff --git a/tests/gnu/test-time.c b/tests/gnu/test-time.c
new file mode 100755
index 00000000..8e250bd2
--- /dev/null
+++ b/tests/gnu/test-time.c
@@ -0,0 +1,35 @@
+/* Test of <time.h> substitute.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <time.h>
+
+#include "verify.h"
+
+struct timespec a;
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-unistd.c b/tests/gnu/test-unistd.c
new file mode 100755
index 00000000..ec02eeef
--- /dev/null
+++ b/tests/gnu/test-unistd.c
@@ -0,0 +1,56 @@
+/* Test of <unistd.h> substitute.
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "verify.h"
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+/* Check that the various SEEK_* macros are defined. */
+int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
+
+/* Check that the various *_FILENO macros are defined. */
+#if ! (defined STDIN_FILENO \
+ && (STDIN_FILENO + STDOUT_FILENO + STDERR_FILENO == 3))
+missing or broken *_FILENO macros
+#endif
+
+/* Check that the types are all defined. */
+size_t t1;
+ssize_t t2;
+#ifdef TODO /* Not implemented in gnulib yet */
+uid_t t3;
+gid_t t4;
+#endif
+off_t t5;
+pid_t t6;
+#ifdef TODO
+useconds_t t7;
+intptr_t t8;
+#endif
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-unsetenv.c b/tests/gnu/test-unsetenv.c
new file mode 100755
index 00000000..7b92ff37
--- /dev/null
+++ b/tests/gnu/test-unsetenv.c
@@ -0,0 +1,61 @@
+/* Tests of unsetenv.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (unsetenv, int, (char const *));
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+int
+main (void)
+{
+ char entry[] = "b=2";
+
+ /* Test removal when multiple entries present. */
+ ASSERT (putenv ((char *) "a=1") == 0);
+ ASSERT (putenv (entry) == 0);
+ entry[0] = 'a'; /* Unspecified what getenv("a") would be at this point. */
+ ASSERT (unsetenv ("a") == 0); /* Both entries will be removed. */
+ ASSERT (getenv ("a") == NULL);
+ ASSERT (unsetenv ("a") == 0);
+
+ /* Required to fail with EINVAL. */
+ errno = 0;
+ ASSERT (unsetenv ("") == -1);
+ ASSERT (errno == EINVAL);
+ errno = 0;
+ ASSERT (unsetenv ("a=b") == -1);
+ ASSERT (errno == EINVAL);
+#if 0
+ /* glibc and gnulib's implementation guarantee this, but POSIX no
+ longer requires it: http://austingroupbugs.net/view.php?id=185 */
+ errno = 0;
+ ASSERT (unsetenv (NULL) == -1);
+ ASSERT (errno == EINVAL);
+#endif
+
+ return 0;
+}
diff --git a/tests/gnu/test-update-copyright.sh b/tests/gnu/test-update-copyright.sh
new file mode 100755
index 00000000..2d1022a9
--- /dev/null
+++ b/tests/gnu/test-update-copyright.sh
@@ -0,0 +1,526 @@
+#!/bin/sh
+# Test suite for update-copyright.
+# Copyright (C) 2009-2010 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+diffout=`diff -u /dev/null /dev/null 2>&1`
+if test x"$diffout" = x"" && test $? -eq 0; then
+ compare() { diff -u "$@"; }
+else
+ compare() { cmp "$@"; }
+fi
+
+TMP_BASE=update-copyright.test
+trap 'rm -f $TMP_BASE*' 0 1 2 3 15
+
+## --------------------------------- ##
+## Skip if user does not have perl. ##
+## --------------------------------- ##
+
+TMP=$TMP_BASE
+s=$TMP-script
+cat <<\EOF > $s
+eval '(exit $?0)' && eval 'exec perl -wS -0777 -pi "$0" ${1+"$@"}'
+ & eval 'exec perl -wS -0777 -pi "$0" $argv:q'
+ if 0;
+s/a/b/
+EOF
+chmod a+x $s
+echo a > $TMP-in
+./$s $TMP-in 2>/dev/null && test b = "`cat $TMP-in 2>/dev/null`" ||
+ {
+ printf '%s\n' "$0: skipping this test;" \
+ 'your system has insufficient support for Perl' 1>&2
+ exit 77
+ }
+
+# Do not let a different envvar setting perturb results.
+UPDATE_COPYRIGHT_MAX_LINE_LENGTH=72
+export UPDATE_COPYRIGHT_MAX_LINE_LENGTH
+
+## ----------------------------- ##
+## Examples from documentation. ##
+## ----------------------------- ##
+
+TMP=$TMP_BASE-ex
+cat > $TMP.1 <<EOF
+Copyright @copyright{} 1990-2005, 2007-2009 Free Software
+Foundation, Inc.
+EOF
+cat > $TMP.2 <<EOF
+# Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+EOF
+cat > $TMP.3 <<EOF
+/*
+ * Copyright &copy; 90,2005,2007-2009
+ * Free Software Foundation, Inc.
+ */
+EOF
+cat > $TMP.4 <<EOF
+## Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+EOF
+cat > $TMP.5 <<EOF
+Copyright (C) 1990-2005, 2007-2009 Acme, Inc.
+EOF
+cat > $TMP.6 <<EOF
+## Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+
+Copyright (C) 1990-2005, 2007-2009 Free Software Foundation,
+Inc.
+EOF
+cat > $TMP.7 <<EOF
+Copyright (C) 1990-2005, 2007-2009 Acme, Inc.
+
+# Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+EOF
+
+rm -f $TMP.*.bak
+UPDATE_COPYRIGHT_YEAR=2009 \
+ update-copyright $TMP.* 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare - $TMP-stderr <<EOF || exit 1
+$TMP.4: warning: FSF copyright statement not found
+$TMP.5: warning: FSF copyright statement not found
+EOF
+compare - $TMP.1 <<EOF || exit 1
+Copyright @copyright{} 1990-2005, 2007-2009 Free Software
+Foundation, Inc.
+EOF
+compare - $TMP.2 <<EOF || exit 1
+# Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+EOF
+compare - $TMP.3 <<EOF || exit 1
+/*
+ * Copyright &copy; 90,2005,2007-2009
+ * Free Software Foundation, Inc.
+ */
+EOF
+compare - $TMP.4 <<EOF || exit 1
+## Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+EOF
+compare - $TMP.5 <<EOF || exit 1
+Copyright (C) 1990-2005, 2007-2009 Acme, Inc.
+EOF
+compare - $TMP.6 <<EOF || exit 1
+## Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+
+Copyright (C) 1990-2005, 2007-2009 Free Software Foundation,
+Inc.
+EOF
+compare - $TMP.7 <<EOF || exit 1
+Copyright (C) 1990-2005, 2007-2009 Acme, Inc.
+
+# Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+EOF
+
+rm -f $TMP.*.bak
+UPDATE_COPYRIGHT_YEAR=2010 UPDATE_COPYRIGHT_USE_INTERVALS=1 \
+ update-copyright $TMP.* 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare - $TMP-stderr <<EOF || exit 1
+$TMP.4: warning: FSF copyright statement not found
+$TMP.5: warning: FSF copyright statement not found
+EOF
+compare - $TMP.1 <<EOF || exit 1
+Copyright @copyright{} 1990-2005, 2007-2010 Free Software Foundation,
+Inc.
+EOF
+compare - $TMP.2 <<EOF || exit 1
+# Copyright (C) 1990-2005, 2007-2010 Free Software Foundation, Inc.
+EOF
+compare - $TMP.3 <<EOF || exit 1
+/*
+ * Copyright &copy; 1990, 2005, 2007-2010 Free Software Foundation, Inc.
+ */
+EOF
+compare - $TMP.4 <<EOF || exit 1
+## Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+EOF
+compare - $TMP.5 <<EOF || exit 1
+Copyright (C) 1990-2005, 2007-2009 Acme, Inc.
+EOF
+compare - $TMP.6 <<EOF || exit 1
+## Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+
+Copyright (C) 1990-2005, 2007-2010 Free Software Foundation, Inc.
+EOF
+compare - $TMP.7 <<EOF || exit 1
+Copyright (C) 1990-2005, 2007-2009 Acme, Inc.
+
+# Copyright (C) 1990-2005, 2007-2010 Free Software Foundation, Inc.
+EOF
+
+rm -f $TMP.*.bak
+UPDATE_COPYRIGHT_YEAR=2010 UPDATE_COPYRIGHT_FORCE=1 \
+ update-copyright $TMP.* 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare - $TMP-stderr <<EOF || exit 1
+$TMP.4: warning: FSF copyright statement not found
+$TMP.5: warning: FSF copyright statement not found
+EOF
+compare - $TMP.1 <<EOF || exit 1
+Copyright @copyright{} 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+Free Software Foundation, Inc.
+EOF
+compare - $TMP.2 <<EOF || exit 1
+# Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+# 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free
+# Software Foundation, Inc.
+EOF
+compare - $TMP.3 <<EOF || exit 1
+/*
+ * Copyright &copy; 1990, 2005, 2007, 2008, 2009, 2010 Free Software
+ * Foundation, Inc.
+ */
+EOF
+compare - $TMP.4 <<EOF || exit 1
+## Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+EOF
+compare - $TMP.5 <<EOF || exit 1
+Copyright (C) 1990-2005, 2007-2009 Acme, Inc.
+EOF
+compare - $TMP.6 <<EOF || exit 1
+## Copyright (C) 1990-2005, 2007-2009 Free Software
+# Foundation, Inc.
+
+Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free
+Software Foundation, Inc.
+EOF
+compare - $TMP.7 <<EOF || exit 1
+Copyright (C) 1990-2005, 2007-2009 Acme, Inc.
+
+# Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+# 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free
+# Software Foundation, Inc.
+EOF
+
+rm $TMP*
+
+## -------------- ##
+## Current year. ##
+## -------------- ##
+
+TMP=$TMP_BASE-current-year
+YEAR=`date +%Y`
+cat > $TMP <<EOF
+'\" Copyright (C) 2006
+'\" Free Software Foundation,
+'\" Inc.
+EOF
+update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+'\" Copyright (C) 2006, $YEAR Free Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_USE_INTERVALS=1 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+'\" Copyright (C) 2006, $YEAR Free Software Foundation, Inc.
+EOF
+rm $TMP*
+
+## ------------------ ##
+## Surrounding text. ##
+## ------------------ ##
+
+TMP=$TMP_BASE-surrounding-text
+cat > $TMP <<EOF
+ Undisturbed text.
+dnl Undisturbed text.
+dnl Copyright (C) 89
+dnl Free Software Foundation, Inc.
+dnl Undisturbed text.
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+ Undisturbed text.
+dnl Undisturbed text.
+dnl Copyright (C) 1989, 2010 Free Software Foundation, Inc.
+dnl Undisturbed text.
+EOF
+rm $TMP*
+
+## --------------- ##
+## Widest prefix. ##
+## --------------- ##
+
+TMP=$TMP_BASE-widest-prefix
+cat > $TMP <<EOF
+#### Copyright (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
+#### 1986, 1987, 1988, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+#### 2008 Free Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+#### Copyright (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984,
+#### 1985, 1986, 1987, 1988, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+#### 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2011 UPDATE_COPYRIGHT_USE_INTERVALS=1 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+#### Copyright (C) 1976-1988, 1999-2008, 2010-2011 Free Software
+#### Foundation, Inc.
+EOF
+rm $TMP*
+
+## ------------------- ##
+## Prefix too large. ##
+## ------------------- ##
+
+TMP=$TMP_BASE-prefix-too-large
+cat > $TMP <<EOF
+#### Copyright (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
+#### 1986, 1987, 1988, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+#### 2008 Free Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare - $TMP-stderr <<EOF || exit 1
+$TMP: warning: FSF copyright statement not found
+EOF
+compare - $TMP <<EOF || exit 1
+#### Copyright (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
+#### 1986, 1987, 1988, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+#### 2008 Free Software Foundation, Inc.
+EOF
+rm $TMP*
+
+## ------------- ##
+## Blank lines. ##
+## ------------- ##
+
+TMP=$TMP_BASE-blank-lines
+cat > $TMP <<EOF
+#Copyright (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
+#
+#1986, 1987, 1988, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+#2008 Free Software Foundation, Inc.
+
+Copyright (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
+
+1986, 1987, 1988, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+2008 Free Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare - $TMP-stderr <<EOF || exit 1
+$TMP: warning: FSF copyright statement not found
+EOF
+compare - $TMP <<EOF || exit 1
+#Copyright (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
+#
+#1986, 1987, 1988, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+#2008 Free Software Foundation, Inc.
+
+Copyright (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
+
+1986, 1987, 1988, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+2008 Free Software Foundation, Inc.
+EOF
+rm $TMP*
+
+## -------------- ##
+## Leading tabs. ##
+## -------------- ##
+
+TMP=$TMP_BASE-leading-tabs
+cat > $TMP <<EOF
+ Copyright (C) 87, 88, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 98,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free
+ Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+ Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2011 UPDATE_COPYRIGHT_USE_INTERVALS=1 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+ Copyright (C) 1987-1988, 1991-2011 Free Software Foundation,
+ Inc.
+EOF
+rm $TMP*
+
+## -------------------- ##
+## Unusual whitespace. ##
+## -------------------- ##
+
+TMP=$TMP_BASE-unusual-ws
+cat > $TMP <<EOF
+ # Copyright (C) 87-88, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ # 98, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ # 2009 Free Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+ # Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994,
+ # 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ # 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+ # Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2011 UPDATE_COPYRIGHT_USE_INTERVALS=1 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+ # Copyright (C) 1987-1988, 1991-2011 Free Software
+ # Foundation, Inc.
+EOF
+rm $TMP*
+
+## --------- ##
+## DOS EOL. ##
+## --------- ##
+
+TMP=$TMP_BASE-dos-eol
+tr @ '\015' > $TMP <<\EOF
+Rem Copyright (C) 87, 88, 1991, 1992, 1993, 1994, 1995, 1996, 1997,@
+Rem 98, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,@
+Rem 2009 Free Software Foundation, Inc.@
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+tr @ '\015' > $TMP-exp <<\EOF
+Rem Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,@
+Rem 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,@
+Rem 2009, 2010 Free Software Foundation, Inc.@
+EOF
+compare $TMP-exp $TMP || exit 1
+rm $TMP*
+
+## --------------- ##
+## Omitted "(C)". ##
+## --------------- ##
+
+TMP=$TMP_BASE-omitted-circle-c
+cat > $TMP <<EOF
+ Copyright 87, 88, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 98, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009 Free Software Foundation, Inc.
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP <<EOF || exit 1
+ Copyright 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
+EOF
+rm $TMP*
+
+## ------------------ ##
+## C-style comments. ##
+## ------------------ ##
+
+TMP=$TMP_BASE-c-style-comments
+cat > $TMP.star <<EOF
+/* Copyright 87, 88, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ * 98, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ * 2009 Free Software Foundation, Inc. */
+EOF
+cat > $TMP.space <<EOF
+ /*Copyright 87, 88, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 98, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009 Free Software Foundation, Inc. */
+EOF
+cat > $TMP.single-line <<EOF
+/* Copyright 87, 1991, 1992 Free Software Foundation, Inc. */
+EOF
+cat > $TMP.single-line-wrapped <<EOF
+ /* Copyright 1988, 1991, 1992, 1993 Free Software Foundation, Inc. */
+EOF
+cat > $TMP.extra-text-star <<EOF
+ /* Copyright 1987, 1988, 1991, 1992 Free Software Foundation, Inc. End
+ * More comments. */
+EOF
+cat > $TMP.extra-text-space <<EOF
+ /* Copyright 1987, 1988, 1991, 1992 Free Software Foundation, Inc. ***
+ * End of comments. */
+EOF
+UPDATE_COPYRIGHT_YEAR=2010 \
+ update-copyright $TMP.* 1> $TMP-stdout 2> $TMP-stderr
+compare /dev/null $TMP-stdout || exit 1
+compare /dev/null $TMP-stderr || exit 1
+compare - $TMP.star <<EOF || exit 1
+/* Copyright 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ * 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ * 2009, 2010 Free Software Foundation, Inc. */
+EOF
+compare - $TMP.space <<EOF || exit 1
+ /*Copyright 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009, 2010 Free Software Foundation, Inc. */
+EOF
+compare - $TMP.single-line <<EOF || exit 1
+/* Copyright 1987, 1991, 1992, 2010 Free Software Foundation, Inc. */
+EOF
+compare - $TMP.single-line-wrapped <<EOF || exit 1
+ /* Copyright 1988, 1991, 1992, 1993, 2010 Free Software Foundation,
+ * Inc. */
+EOF
+compare - $TMP.extra-text-star <<EOF || exit 1
+ /* Copyright 1987, 1988, 1991, 1992, 2010 Free Software Foundation,
+ * Inc. End
+ * More comments. */
+EOF
+compare - $TMP.extra-text-space <<EOF || exit 1
+ /* Copyright 1987, 1988, 1991, 1992, 2010 Free Software Foundation,
+ Inc. ***
+ * End of comments. */
+EOF
+rm $TMP*
+
+exit 0
diff --git a/tests/gnu/test-vasnprintf-posix.c b/tests/gnu/test-vasnprintf-posix.c
new file mode 100755
index 00000000..74ba1653
--- /dev/null
+++ b/tests/gnu/test-vasnprintf-posix.c
@@ -0,0 +1,3671 @@
+/* Test of POSIX compatible vasnprintf() and asnprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "vasnprintf.h"
+
+#include <float.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+#include "nan.h"
+
+/* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0. */
+static int
+have_minus_zero ()
+{
+ static double plus_zero = 0.0;
+ double minus_zero = - plus_zero;
+ return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
+}
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ So we use -zerod instead. */
+double zerod = 0.0;
+
+/* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
+ So we use minus_zerol instead.
+ IRIX cc can't put -0.0L into .data, but can compute at runtime.
+ Note that the expression -LDBL_MIN * LDBL_MIN does not work on other
+ platforms, such as when cross-compiling to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi
+static long double
+compute_minus_zerol (void)
+{
+ return -LDBL_MIN * LDBL_MIN;
+}
+# define minus_zerol compute_minus_zerol ()
+#else
+long double minus_zerol = -0.0L;
+#endif
+
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+ of 'unsigned int' words. */
+#ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+ ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
+ (unsigned int) (mantlo) << 16 \
+ }
+#else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { mantlo, manthi, exponent }
+#endif
+
+static int
+strmatch (const char *pattern, const char *string)
+{
+ if (strlen (pattern) != strlen (string))
+ return 0;
+ for (; *pattern != '\0'; pattern++, string++)
+ if (*pattern != '*' && *string != *pattern)
+ return 0;
+ return 1;
+}
+
+/* Test whether string[start_index..end_index-1] is a valid textual
+ representation of NaN. */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
+{
+ char buf[8];
+ int size;
+
+ /* Test return value convention. */
+
+ for (size = 0; size <= 8; size++)
+ {
+ size_t length = size;
+ char *result = my_asnprintf (NULL, &length, "%d", 12345);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ ASSERT (length == 5);
+ free (result);
+ }
+
+ for (size = 0; size <= 8; size++)
+ {
+ size_t length;
+ char *result;
+
+ memcpy (buf, "DEADBEEF", 8);
+ length = size;
+ result = my_asnprintf (buf, &length, "%d", 12345);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ ASSERT (length == 5);
+ if (size < 6)
+ ASSERT (result != buf);
+ ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
+ if (result != buf)
+ free (result);
+ }
+
+ /* Test support of size specifiers as in C99. */
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345671 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%zu %d", (size_t) 12345672, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345672 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345673 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", (long double) 1.5, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.5 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
+ output of floating-point numbers. */
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%a %d", 3.1416015625, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.922p+1 33") == 0
+ || strcmp (result, "0x3.244p+0 33") == 0
+ || strcmp (result, "0x6.488p-1 33") == 0
+ || strcmp (result, "0xc.91p-2 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%A %d", -3.1416015625, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
+ || strcmp (result, "-0X3.244P+0 33") == 0
+ || strcmp (result, "-0X6.488P-1 33") == 0
+ || strcmp (result, "-0XC.91P-2 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%a %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x0p+0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%a %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0x0p+0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%a %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%a %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%a %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding near the decimal point. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0a %d", 1.5, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 0. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0a %d", 1.51, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 1. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.1a %d", 1.51, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.8p+0 33") == 0
+ || strcmp (result, "0x3.0p-1 33") == 0
+ || strcmp (result, "0x6.1p-2 33") == 0
+ || strcmp (result, "0xc.1p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 2. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2a %d", 1.51, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.83p+0 33") == 0
+ || strcmp (result, "0x3.05p-1 33") == 0
+ || strcmp (result, "0x6.0ap-2 33") == 0
+ || strcmp (result, "0xc.14p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 3. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.3a %d", 1.51, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.829p+0 33") == 0
+ || strcmp (result, "0x3.052p-1 33") == 0
+ || strcmp (result, "0x6.0a4p-2 33") == 0
+ || strcmp (result, "0xc.148p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.3a %d", 1.49999, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.800p+0 33") == 0
+ || strcmp (result, "0x3.000p-1 33") == 0
+ || strcmp (result, "0x6.000p-2 33") == 0
+ || strcmp (result, "0xc.000p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.1a %d", 1.999, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%10a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Small precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.10a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
+ || strcmp (result, "0x3.8000000000p-1 33") == 0
+ || strcmp (result, "0x7.0000000000p-2 33") == 0
+ || strcmp (result, "0xe.0000000000p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Large precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.50a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
+ || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
+ || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
+ || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-10a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7p-2 33") == 0
+ || strcmp (result, "0xep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%+a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
+ || strcmp (result, "+0x3.8p-1 33") == 0
+ || strcmp (result, "+0x7p-2 33") == 0
+ || strcmp (result, "+0xep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "% a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7.p-2 33") == 0
+ || strcmp (result, "0xe.p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#a %d", 1.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.p+0 33") == 0
+ || strcmp (result, "0x2.p-1 33") == 0
+ || strcmp (result, "0x4.p-2 33") == 0
+ || strcmp (result, "0x8.p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%010a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x001.cp+0 33") == 0
+ || strcmp (result, "0x003.8p-1 33") == 0
+ || strcmp (result, "0x00007p-2 33") == 0
+ || strcmp (result, "0x0000ep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%010a %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strcmp (result, " inf 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%050a %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ /* "0000000nan 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", 3.1416015625L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.922p+1 33") == 0
+ || strcmp (result, "0x3.244p+0 33") == 0
+ || strcmp (result, "0x6.488p-1 33") == 0
+ || strcmp (result, "0xc.91p-2 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LA %d", -3.1416015625L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
+ || strcmp (result, "-0X3.244P+0 33") == 0
+ || strcmp (result, "-0X6.488P-1 33") == 0
+ || strcmp (result, "-0XC.91P-2 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x0p+0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0x0p+0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+#endif
+
+ { /* Rounding near the decimal point. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0La %d", 1.5L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 0. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0La %d", 1.51L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 1. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.1La %d", 1.51L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.8p+0 33") == 0
+ || strcmp (result, "0x3.0p-1 33") == 0
+ || strcmp (result, "0x6.1p-2 33") == 0
+ || strcmp (result, "0xc.1p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 2. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2La %d", 1.51L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.83p+0 33") == 0
+ || strcmp (result, "0x3.05p-1 33") == 0
+ || strcmp (result, "0x6.0ap-2 33") == 0
+ || strcmp (result, "0xc.14p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 3. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.3La %d", 1.51L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.829p+0 33") == 0
+ || strcmp (result, "0x3.052p-1 33") == 0
+ || strcmp (result, "0x6.0a4p-2 33") == 0
+ || strcmp (result, "0xc.148p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.3La %d", 1.49999L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.800p+0 33") == 0
+ || strcmp (result, "0x3.000p-1 33") == 0
+ || strcmp (result, "0x6.000p-2 33") == 0
+ || strcmp (result, "0xc.000p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
+ glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.1La %d", 1.999L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%10La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Small precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.10La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
+ || strcmp (result, "0x3.8000000000p-1 33") == 0
+ || strcmp (result, "0x7.0000000000p-2 33") == 0
+ || strcmp (result, "0xe.0000000000p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Large precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.50La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
+ || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
+ || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
+ || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-10La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7p-2 33") == 0
+ || strcmp (result, "0xep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%+La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
+ || strcmp (result, "+0x3.8p-1 33") == 0
+ || strcmp (result, "+0x7p-2 33") == 0
+ || strcmp (result, "+0xep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "% La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7.p-2 33") == 0
+ || strcmp (result, "0xe.p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#La %d", 1.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.p+0 33") == 0
+ || strcmp (result, "0x2.p-1 33") == 0
+ || strcmp (result, "0x4.p-2 33") == 0
+ || strcmp (result, "0x8.p-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%010La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x001.cp+0 33") == 0
+ || strcmp (result, "0x003.8p-1 33") == 0
+ || strcmp (result, "0x00007p-2 33") == 0
+ || strcmp (result, "0x0000ep-3 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strcmp (result, " inf 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%050La %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ /* "0000000nan 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %f format directive. */
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f %d", 12.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f %d", 1234567.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "0.000000" },
+ { 1.234321234321234e-36, "0.000000" },
+ { 1.234321234321234e-35, "0.000000" },
+ { 1.234321234321234e-34, "0.000000" },
+ { 1.234321234321234e-33, "0.000000" },
+ { 1.234321234321234e-32, "0.000000" },
+ { 1.234321234321234e-31, "0.000000" },
+ { 1.234321234321234e-30, "0.000000" },
+ { 1.234321234321234e-29, "0.000000" },
+ { 1.234321234321234e-28, "0.000000" },
+ { 1.234321234321234e-27, "0.000000" },
+ { 1.234321234321234e-26, "0.000000" },
+ { 1.234321234321234e-25, "0.000000" },
+ { 1.234321234321234e-24, "0.000000" },
+ { 1.234321234321234e-23, "0.000000" },
+ { 1.234321234321234e-22, "0.000000" },
+ { 1.234321234321234e-21, "0.000000" },
+ { 1.234321234321234e-20, "0.000000" },
+ { 1.234321234321234e-19, "0.000000" },
+ { 1.234321234321234e-18, "0.000000" },
+ { 1.234321234321234e-17, "0.000000" },
+ { 1.234321234321234e-16, "0.000000" },
+ { 1.234321234321234e-15, "0.000000" },
+ { 1.234321234321234e-14, "0.000000" },
+ { 1.234321234321234e-13, "0.000000" },
+ { 1.234321234321234e-12, "0.000000" },
+ { 1.234321234321234e-11, "0.000000" },
+ { 1.234321234321234e-10, "0.000000" },
+ { 1.234321234321234e-9, "0.000000" },
+ { 1.234321234321234e-8, "0.000000" },
+ { 1.234321234321234e-7, "0.000000" },
+ { 1.234321234321234e-6, "0.000001" },
+ { 1.234321234321234e-5, "0.000012" },
+ { 1.234321234321234e-4, "0.000123" },
+ { 1.234321234321234e-3, "0.001234" },
+ { 1.234321234321234e-2, "0.012343" },
+ { 1.234321234321234e-1, "0.123432" },
+ { 1.234321234321234, "1.234321" },
+ { 1.234321234321234e1, "12.343212" },
+ { 1.234321234321234e2, "123.432123" },
+ { 1.234321234321234e3, "1234.321234" },
+ { 1.234321234321234e4, "12343.212343" },
+ { 1.234321234321234e5, "123432.123432" },
+ { 1.234321234321234e6, "1234321.234321" },
+ { 1.234321234321234e7, "12343212.343212" },
+ { 1.234321234321234e8, "123432123.432123" },
+ { 1.234321234321234e9, "1234321234.321234" },
+ { 1.234321234321234e10, "12343212343.2123**" },
+ { 1.234321234321234e11, "123432123432.123***" },
+ { 1.234321234321234e12, "1234321234321.23****" },
+ { 1.234321234321234e13, "12343212343212.3*****" },
+ { 1.234321234321234e14, "123432123432123.******" },
+ { 1.234321234321234e15, "1234321234321234.000000" },
+ { 1.234321234321234e16, "123432123432123**.000000" },
+ { 1.234321234321234e17, "123432123432123***.000000" },
+ { 1.234321234321234e18, "123432123432123****.000000" },
+ { 1.234321234321234e19, "123432123432123*****.000000" },
+ { 1.234321234321234e20, "123432123432123******.000000" },
+ { 1.234321234321234e21, "123432123432123*******.000000" },
+ { 1.234321234321234e22, "123432123432123********.000000" },
+ { 1.234321234321234e23, "123432123432123*********.000000" },
+ { 1.234321234321234e24, "123432123432123**********.000000" },
+ { 1.234321234321234e25, "123432123432123***********.000000" },
+ { 1.234321234321234e26, "123432123432123************.000000" },
+ { 1.234321234321234e27, "123432123432123*************.000000" },
+ { 1.234321234321234e28, "123432123432123**************.000000" },
+ { 1.234321234321234e29, "123432123432123***************.000000" },
+ { 1.234321234321234e30, "123432123432123****************.000000" },
+ { 1.234321234321234e31, "123432123432123*****************.000000" },
+ { 1.234321234321234e32, "123432123432123******************.000000" },
+ { 1.234321234321234e33, "123432123432123*******************.000000" },
+ { 1.234321234321234e34, "123432123432123********************.000000" },
+ { 1.234321234321234e35, "123432123432123*********************.000000" },
+ { 1.234321234321234e36, "123432123432123**********************.000000" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f", data[k].value);
+ ASSERT (result != NULL);
+ ASSERT (strmatch (data[k].string, result));
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f %d", -0.03125, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%f %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%10f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-10f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%+f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "% f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015f %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015f %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%050f %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.f %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2f %d", 999.951, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2f %d", 999.996, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", 12.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", 1234567.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "0.000000" },
+ { 1.234321234321234e-36L, "0.000000" },
+ { 1.234321234321234e-35L, "0.000000" },
+ { 1.234321234321234e-34L, "0.000000" },
+ { 1.234321234321234e-33L, "0.000000" },
+ { 1.234321234321234e-32L, "0.000000" },
+ { 1.234321234321234e-31L, "0.000000" },
+ { 1.234321234321234e-30L, "0.000000" },
+ { 1.234321234321234e-29L, "0.000000" },
+ { 1.234321234321234e-28L, "0.000000" },
+ { 1.234321234321234e-27L, "0.000000" },
+ { 1.234321234321234e-26L, "0.000000" },
+ { 1.234321234321234e-25L, "0.000000" },
+ { 1.234321234321234e-24L, "0.000000" },
+ { 1.234321234321234e-23L, "0.000000" },
+ { 1.234321234321234e-22L, "0.000000" },
+ { 1.234321234321234e-21L, "0.000000" },
+ { 1.234321234321234e-20L, "0.000000" },
+ { 1.234321234321234e-19L, "0.000000" },
+ { 1.234321234321234e-18L, "0.000000" },
+ { 1.234321234321234e-17L, "0.000000" },
+ { 1.234321234321234e-16L, "0.000000" },
+ { 1.234321234321234e-15L, "0.000000" },
+ { 1.234321234321234e-14L, "0.000000" },
+ { 1.234321234321234e-13L, "0.000000" },
+ { 1.234321234321234e-12L, "0.000000" },
+ { 1.234321234321234e-11L, "0.000000" },
+ { 1.234321234321234e-10L, "0.000000" },
+ { 1.234321234321234e-9L, "0.000000" },
+ { 1.234321234321234e-8L, "0.000000" },
+ { 1.234321234321234e-7L, "0.000000" },
+ { 1.234321234321234e-6L, "0.000001" },
+ { 1.234321234321234e-5L, "0.000012" },
+ { 1.234321234321234e-4L, "0.000123" },
+ { 1.234321234321234e-3L, "0.001234" },
+ { 1.234321234321234e-2L, "0.012343" },
+ { 1.234321234321234e-1L, "0.123432" },
+ { 1.234321234321234L, "1.234321" },
+ { 1.234321234321234e1L, "12.343212" },
+ { 1.234321234321234e2L, "123.432123" },
+ { 1.234321234321234e3L, "1234.321234" },
+ { 1.234321234321234e4L, "12343.212343" },
+ { 1.234321234321234e5L, "123432.123432" },
+ { 1.234321234321234e6L, "1234321.234321" },
+ { 1.234321234321234e7L, "12343212.343212" },
+ { 1.234321234321234e8L, "123432123.432123" },
+ { 1.234321234321234e9L, "1234321234.321234" },
+ { 1.234321234321234e10L, "12343212343.2123**" },
+ { 1.234321234321234e11L, "123432123432.123***" },
+ { 1.234321234321234e12L, "1234321234321.23****" },
+ { 1.234321234321234e13L, "12343212343212.3*****" },
+ { 1.234321234321234e14L, "123432123432123.******" },
+ { 1.234321234321234e15L, "1234321234321234.000000" },
+ { 1.234321234321234e16L, "123432123432123**.000000" },
+ { 1.234321234321234e17L, "123432123432123***.000000" },
+ { 1.234321234321234e18L, "123432123432123****.000000" },
+ { 1.234321234321234e19L, "123432123432123*****.000000" },
+ { 1.234321234321234e20L, "123432123432123******.000000" },
+ { 1.234321234321234e21L, "123432123432123*******.000000" },
+ { 1.234321234321234e22L, "123432123432123********.000000" },
+ { 1.234321234321234e23L, "123432123432123*********.000000" },
+ { 1.234321234321234e24L, "123432123432123**********.000000" },
+ { 1.234321234321234e25L, "123432123432123***********.000000" },
+ { 1.234321234321234e26L, "123432123432123************.000000" },
+ { 1.234321234321234e27L, "123432123432123*************.000000" },
+ { 1.234321234321234e28L, "123432123432123**************.000000" },
+ { 1.234321234321234e29L, "123432123432123***************.000000" },
+ { 1.234321234321234e30L, "123432123432123****************.000000" },
+ { 1.234321234321234e31L, "123432123432123*****************.000000" },
+ { 1.234321234321234e32L, "123432123432123******************.000000" },
+ { 1.234321234321234e33L, "123432123432123*******************.000000" },
+ { 1.234321234321234e34L, "123432123432123********************.000000" },
+ { 1.234321234321234e35L, "123432123432123*********************.000000" },
+ { 1.234321234321234e36L, "123432123432123**********************.000000" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf", data[k].value);
+ ASSERT (result != NULL);
+ ASSERT (strmatch (data[k].string, result));
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", -0.03125L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+#endif
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%10Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-10Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%+Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "% Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015Lf %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%050Lf %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.Lf %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2Lf %d", 999.951L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2Lf %d", 999.996L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %F format directive. */
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%F %d", 12.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%F %d", 1234567.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%F %d", -0.03125, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%F %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%F %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%F %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "INF 33") == 0
+ || strcmp (result, "INFINITY 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%F %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-INF 33") == 0
+ || strcmp (result, "-INFINITY 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%F %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 1)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015F %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015F %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -INF 33") == 0
+ || strcmp (result, " -INFINITY 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.F %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2F %d", 999.951, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2F %d", 999.996, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LF %d", 12.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LF %d", 1234567.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LF %d", -0.03125L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LF %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LF %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LF %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "INF 33") == 0
+ || strcmp (result, "INFINITY 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LF %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-INF 33") == 0
+ || strcmp (result, "-INFINITY 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%LF %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 1)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015LF %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -INF 33") == 0
+ || strcmp (result, " -INFINITY 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.LF %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2LF %d", 999.951L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.2LF %d", 999.996L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %e format directive. */
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e %d", 12.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.275000e+01 33") == 0
+ || strcmp (result, "1.275000e+001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e %d", 1234567.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.234567e+06 33") == 0
+ || strcmp (result, "1.234567e+006 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "1.234321e-37" },
+ { 1.234321234321234e-36, "1.234321e-36" },
+ { 1.234321234321234e-35, "1.234321e-35" },
+ { 1.234321234321234e-34, "1.234321e-34" },
+ { 1.234321234321234e-33, "1.234321e-33" },
+ { 1.234321234321234e-32, "1.234321e-32" },
+ { 1.234321234321234e-31, "1.234321e-31" },
+ { 1.234321234321234e-30, "1.234321e-30" },
+ { 1.234321234321234e-29, "1.234321e-29" },
+ { 1.234321234321234e-28, "1.234321e-28" },
+ { 1.234321234321234e-27, "1.234321e-27" },
+ { 1.234321234321234e-26, "1.234321e-26" },
+ { 1.234321234321234e-25, "1.234321e-25" },
+ { 1.234321234321234e-24, "1.234321e-24" },
+ { 1.234321234321234e-23, "1.234321e-23" },
+ { 1.234321234321234e-22, "1.234321e-22" },
+ { 1.234321234321234e-21, "1.234321e-21" },
+ { 1.234321234321234e-20, "1.234321e-20" },
+ { 1.234321234321234e-19, "1.234321e-19" },
+ { 1.234321234321234e-18, "1.234321e-18" },
+ { 1.234321234321234e-17, "1.234321e-17" },
+ { 1.234321234321234e-16, "1.234321e-16" },
+ { 1.234321234321234e-15, "1.234321e-15" },
+ { 1.234321234321234e-14, "1.234321e-14" },
+ { 1.234321234321234e-13, "1.234321e-13" },
+ { 1.234321234321234e-12, "1.234321e-12" },
+ { 1.234321234321234e-11, "1.234321e-11" },
+ { 1.234321234321234e-10, "1.234321e-10" },
+ { 1.234321234321234e-9, "1.234321e-09" },
+ { 1.234321234321234e-8, "1.234321e-08" },
+ { 1.234321234321234e-7, "1.234321e-07" },
+ { 1.234321234321234e-6, "1.234321e-06" },
+ { 1.234321234321234e-5, "1.234321e-05" },
+ { 1.234321234321234e-4, "1.234321e-04" },
+ { 1.234321234321234e-3, "1.234321e-03" },
+ { 1.234321234321234e-2, "1.234321e-02" },
+ { 1.234321234321234e-1, "1.234321e-01" },
+ { 1.234321234321234, "1.234321e+00" },
+ { 1.234321234321234e1, "1.234321e+01" },
+ { 1.234321234321234e2, "1.234321e+02" },
+ { 1.234321234321234e3, "1.234321e+03" },
+ { 1.234321234321234e4, "1.234321e+04" },
+ { 1.234321234321234e5, "1.234321e+05" },
+ { 1.234321234321234e6, "1.234321e+06" },
+ { 1.234321234321234e7, "1.234321e+07" },
+ { 1.234321234321234e8, "1.234321e+08" },
+ { 1.234321234321234e9, "1.234321e+09" },
+ { 1.234321234321234e10, "1.234321e+10" },
+ { 1.234321234321234e11, "1.234321e+11" },
+ { 1.234321234321234e12, "1.234321e+12" },
+ { 1.234321234321234e13, "1.234321e+13" },
+ { 1.234321234321234e14, "1.234321e+14" },
+ { 1.234321234321234e15, "1.234321e+15" },
+ { 1.234321234321234e16, "1.234321e+16" },
+ { 1.234321234321234e17, "1.234321e+17" },
+ { 1.234321234321234e18, "1.234321e+18" },
+ { 1.234321234321234e19, "1.234321e+19" },
+ { 1.234321234321234e20, "1.234321e+20" },
+ { 1.234321234321234e21, "1.234321e+21" },
+ { 1.234321234321234e22, "1.234321e+22" },
+ { 1.234321234321234e23, "1.234321e+23" },
+ { 1.234321234321234e24, "1.234321e+24" },
+ { 1.234321234321234e25, "1.234321e+25" },
+ { 1.234321234321234e26, "1.234321e+26" },
+ { 1.234321234321234e27, "1.234321e+27" },
+ { 1.234321234321234e28, "1.234321e+28" },
+ { 1.234321234321234e29, "1.234321e+29" },
+ { 1.234321234321234e30, "1.234321e+30" },
+ { 1.234321234321234e31, "1.234321e+31" },
+ { 1.234321234321234e32, "1.234321e+32" },
+ { 1.234321234321234e33, "1.234321e+33" },
+ { 1.234321234321234e34, "1.234321e+34" },
+ { 1.234321234321234e35, "1.234321e+35" },
+ { 1.234321234321234e36, "1.234321e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e %d", -0.03125, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-3.125000e-02 33") == 0
+ || strcmp (result, "-3.125000e-002 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000e+00 33") == 0
+ || strcmp (result, "0.000000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000e+00 33") == 0
+ || strcmp (result, "-0.000000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%e %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%15e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-15e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%+e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.750000e+00 33") == 0
+ || strcmp (result, "+1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "% e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2.e+00 33") == 0
+ || strcmp (result, "2.e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.e %d", 9.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015e %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0001.234000e+03 33") == 0
+ || strcmp (result, "001.234000e+003 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015e %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%050e %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.e %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4e %d", 999.951, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "9.9995e+02 33") == 0
+ || strcmp (result, "9.9995e+002 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4e %d", 999.996, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.0000e+03 33") == 0
+ || strcmp (result, "1.0000e+003 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", 12.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.275000e+01 33") == 0
+ || strcmp (result, "1.275000e+001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", 1234567.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.234567e+06 33") == 0
+ || strcmp (result, "1.234567e+006 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "1.234321e-37" },
+ { 1.234321234321234e-36L, "1.234321e-36" },
+ { 1.234321234321234e-35L, "1.234321e-35" },
+ { 1.234321234321234e-34L, "1.234321e-34" },
+ { 1.234321234321234e-33L, "1.234321e-33" },
+ { 1.234321234321234e-32L, "1.234321e-32" },
+ { 1.234321234321234e-31L, "1.234321e-31" },
+ { 1.234321234321234e-30L, "1.234321e-30" },
+ { 1.234321234321234e-29L, "1.234321e-29" },
+ { 1.234321234321234e-28L, "1.234321e-28" },
+ { 1.234321234321234e-27L, "1.234321e-27" },
+ { 1.234321234321234e-26L, "1.234321e-26" },
+ { 1.234321234321234e-25L, "1.234321e-25" },
+ { 1.234321234321234e-24L, "1.234321e-24" },
+ { 1.234321234321234e-23L, "1.234321e-23" },
+ { 1.234321234321234e-22L, "1.234321e-22" },
+ { 1.234321234321234e-21L, "1.234321e-21" },
+ { 1.234321234321234e-20L, "1.234321e-20" },
+ { 1.234321234321234e-19L, "1.234321e-19" },
+ { 1.234321234321234e-18L, "1.234321e-18" },
+ { 1.234321234321234e-17L, "1.234321e-17" },
+ { 1.234321234321234e-16L, "1.234321e-16" },
+ { 1.234321234321234e-15L, "1.234321e-15" },
+ { 1.234321234321234e-14L, "1.234321e-14" },
+ { 1.234321234321234e-13L, "1.234321e-13" },
+ { 1.234321234321234e-12L, "1.234321e-12" },
+ { 1.234321234321234e-11L, "1.234321e-11" },
+ { 1.234321234321234e-10L, "1.234321e-10" },
+ { 1.234321234321234e-9L, "1.234321e-09" },
+ { 1.234321234321234e-8L, "1.234321e-08" },
+ { 1.234321234321234e-7L, "1.234321e-07" },
+ { 1.234321234321234e-6L, "1.234321e-06" },
+ { 1.234321234321234e-5L, "1.234321e-05" },
+ { 1.234321234321234e-4L, "1.234321e-04" },
+ { 1.234321234321234e-3L, "1.234321e-03" },
+ { 1.234321234321234e-2L, "1.234321e-02" },
+ { 1.234321234321234e-1L, "1.234321e-01" },
+ { 1.234321234321234L, "1.234321e+00" },
+ { 1.234321234321234e1L, "1.234321e+01" },
+ { 1.234321234321234e2L, "1.234321e+02" },
+ { 1.234321234321234e3L, "1.234321e+03" },
+ { 1.234321234321234e4L, "1.234321e+04" },
+ { 1.234321234321234e5L, "1.234321e+05" },
+ { 1.234321234321234e6L, "1.234321e+06" },
+ { 1.234321234321234e7L, "1.234321e+07" },
+ { 1.234321234321234e8L, "1.234321e+08" },
+ { 1.234321234321234e9L, "1.234321e+09" },
+ { 1.234321234321234e10L, "1.234321e+10" },
+ { 1.234321234321234e11L, "1.234321e+11" },
+ { 1.234321234321234e12L, "1.234321e+12" },
+ { 1.234321234321234e13L, "1.234321e+13" },
+ { 1.234321234321234e14L, "1.234321e+14" },
+ { 1.234321234321234e15L, "1.234321e+15" },
+ { 1.234321234321234e16L, "1.234321e+16" },
+ { 1.234321234321234e17L, "1.234321e+17" },
+ { 1.234321234321234e18L, "1.234321e+18" },
+ { 1.234321234321234e19L, "1.234321e+19" },
+ { 1.234321234321234e20L, "1.234321e+20" },
+ { 1.234321234321234e21L, "1.234321e+21" },
+ { 1.234321234321234e22L, "1.234321e+22" },
+ { 1.234321234321234e23L, "1.234321e+23" },
+ { 1.234321234321234e24L, "1.234321e+24" },
+ { 1.234321234321234e25L, "1.234321e+25" },
+ { 1.234321234321234e26L, "1.234321e+26" },
+ { 1.234321234321234e27L, "1.234321e+27" },
+ { 1.234321234321234e28L, "1.234321e+28" },
+ { 1.234321234321234e29L, "1.234321e+29" },
+ { 1.234321234321234e30L, "1.234321e+30" },
+ { 1.234321234321234e31L, "1.234321e+31" },
+ { 1.234321234321234e32L, "1.234321e+32" },
+ { 1.234321234321234e33L, "1.234321e+33" },
+ { 1.234321234321234e34L, "1.234321e+34" },
+ { 1.234321234321234e35L, "1.234321e+35" },
+ { 1.234321234321234e36L, "1.234321e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", -0.03125L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-3.125000e-02 33") == 0
+ || strcmp (result, "-3.125000e-002 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000e+00 33") == 0
+ || strcmp (result, "0.000000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000e+00 33") == 0
+ || strcmp (result, "-0.000000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+#endif
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%15Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-15Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%+Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.750000e+00 33") == 0
+ || strcmp (result, "+1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "% Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2.e+00 33") == 0
+ || strcmp (result, "2.e+000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.Le %d", 9.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015Le %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0001.234000e+03 33") == 0
+ || strcmp (result, "001.234000e+003 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015Le %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%050Le %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.Le %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4Le %d", 999.951L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "9.9995e+02 33") == 0
+ || strcmp (result, "9.9995e+002 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4Le %d", 999.996L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.0000e+03 33") == 0
+ || strcmp (result, "1.0000e+003 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %g format directive. */
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g %d", 12.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g %d", 1234567.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.23457e+06 33") == 0
+ || strcmp (result, "1.23457e+006 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "1.23432e-37" },
+ { 1.234321234321234e-36, "1.23432e-36" },
+ { 1.234321234321234e-35, "1.23432e-35" },
+ { 1.234321234321234e-34, "1.23432e-34" },
+ { 1.234321234321234e-33, "1.23432e-33" },
+ { 1.234321234321234e-32, "1.23432e-32" },
+ { 1.234321234321234e-31, "1.23432e-31" },
+ { 1.234321234321234e-30, "1.23432e-30" },
+ { 1.234321234321234e-29, "1.23432e-29" },
+ { 1.234321234321234e-28, "1.23432e-28" },
+ { 1.234321234321234e-27, "1.23432e-27" },
+ { 1.234321234321234e-26, "1.23432e-26" },
+ { 1.234321234321234e-25, "1.23432e-25" },
+ { 1.234321234321234e-24, "1.23432e-24" },
+ { 1.234321234321234e-23, "1.23432e-23" },
+ { 1.234321234321234e-22, "1.23432e-22" },
+ { 1.234321234321234e-21, "1.23432e-21" },
+ { 1.234321234321234e-20, "1.23432e-20" },
+ { 1.234321234321234e-19, "1.23432e-19" },
+ { 1.234321234321234e-18, "1.23432e-18" },
+ { 1.234321234321234e-17, "1.23432e-17" },
+ { 1.234321234321234e-16, "1.23432e-16" },
+ { 1.234321234321234e-15, "1.23432e-15" },
+ { 1.234321234321234e-14, "1.23432e-14" },
+ { 1.234321234321234e-13, "1.23432e-13" },
+ { 1.234321234321234e-12, "1.23432e-12" },
+ { 1.234321234321234e-11, "1.23432e-11" },
+ { 1.234321234321234e-10, "1.23432e-10" },
+ { 1.234321234321234e-9, "1.23432e-09" },
+ { 1.234321234321234e-8, "1.23432e-08" },
+ { 1.234321234321234e-7, "1.23432e-07" },
+ { 1.234321234321234e-6, "1.23432e-06" },
+ { 1.234321234321234e-5, "1.23432e-05" },
+ { 1.234321234321234e-4, "0.000123432" },
+ { 1.234321234321234e-3, "0.00123432" },
+ { 1.234321234321234e-2, "0.0123432" },
+ { 1.234321234321234e-1, "0.123432" },
+ { 1.234321234321234, "1.23432" },
+ { 1.234321234321234e1, "12.3432" },
+ { 1.234321234321234e2, "123.432" },
+ { 1.234321234321234e3, "1234.32" },
+ { 1.234321234321234e4, "12343.2" },
+ { 1.234321234321234e5, "123432" },
+ { 1.234321234321234e6, "1.23432e+06" },
+ { 1.234321234321234e7, "1.23432e+07" },
+ { 1.234321234321234e8, "1.23432e+08" },
+ { 1.234321234321234e9, "1.23432e+09" },
+ { 1.234321234321234e10, "1.23432e+10" },
+ { 1.234321234321234e11, "1.23432e+11" },
+ { 1.234321234321234e12, "1.23432e+12" },
+ { 1.234321234321234e13, "1.23432e+13" },
+ { 1.234321234321234e14, "1.23432e+14" },
+ { 1.234321234321234e15, "1.23432e+15" },
+ { 1.234321234321234e16, "1.23432e+16" },
+ { 1.234321234321234e17, "1.23432e+17" },
+ { 1.234321234321234e18, "1.23432e+18" },
+ { 1.234321234321234e19, "1.23432e+19" },
+ { 1.234321234321234e20, "1.23432e+20" },
+ { 1.234321234321234e21, "1.23432e+21" },
+ { 1.234321234321234e22, "1.23432e+22" },
+ { 1.234321234321234e23, "1.23432e+23" },
+ { 1.234321234321234e24, "1.23432e+24" },
+ { 1.234321234321234e25, "1.23432e+25" },
+ { 1.234321234321234e26, "1.23432e+26" },
+ { 1.234321234321234e27, "1.23432e+27" },
+ { 1.234321234321234e28, "1.23432e+28" },
+ { 1.234321234321234e29, "1.23432e+29" },
+ { 1.234321234321234e30, "1.23432e+30" },
+ { 1.234321234321234e31, "1.23432e+31" },
+ { 1.234321234321234e32, "1.23432e+32" },
+ { 1.234321234321234e33, "1.23432e+33" },
+ { 1.234321234321234e34, "1.23432e+34" },
+ { 1.234321234321234e35, "1.23432e+35" },
+ { 1.234321234321234e36, "1.23432e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (expected[strlen (expected) - 4] == 'e'
+ && strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g %d", -0.03125, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.03125 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%g %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%10g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-10g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%+g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "% g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.75000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.g %d", 9.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%010g %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0000001234 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015g %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%050g %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.g %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.5g %d", 999.951, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.5g %d", 999.996, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", 12.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", 1234567.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.23457e+06 33") == 0
+ || strcmp (result, "1.23457e+006 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "1.23432e-37" },
+ { 1.234321234321234e-36L, "1.23432e-36" },
+ { 1.234321234321234e-35L, "1.23432e-35" },
+ { 1.234321234321234e-34L, "1.23432e-34" },
+ { 1.234321234321234e-33L, "1.23432e-33" },
+ { 1.234321234321234e-32L, "1.23432e-32" },
+ { 1.234321234321234e-31L, "1.23432e-31" },
+ { 1.234321234321234e-30L, "1.23432e-30" },
+ { 1.234321234321234e-29L, "1.23432e-29" },
+ { 1.234321234321234e-28L, "1.23432e-28" },
+ { 1.234321234321234e-27L, "1.23432e-27" },
+ { 1.234321234321234e-26L, "1.23432e-26" },
+ { 1.234321234321234e-25L, "1.23432e-25" },
+ { 1.234321234321234e-24L, "1.23432e-24" },
+ { 1.234321234321234e-23L, "1.23432e-23" },
+ { 1.234321234321234e-22L, "1.23432e-22" },
+ { 1.234321234321234e-21L, "1.23432e-21" },
+ { 1.234321234321234e-20L, "1.23432e-20" },
+ { 1.234321234321234e-19L, "1.23432e-19" },
+ { 1.234321234321234e-18L, "1.23432e-18" },
+ { 1.234321234321234e-17L, "1.23432e-17" },
+ { 1.234321234321234e-16L, "1.23432e-16" },
+ { 1.234321234321234e-15L, "1.23432e-15" },
+ { 1.234321234321234e-14L, "1.23432e-14" },
+ { 1.234321234321234e-13L, "1.23432e-13" },
+ { 1.234321234321234e-12L, "1.23432e-12" },
+ { 1.234321234321234e-11L, "1.23432e-11" },
+ { 1.234321234321234e-10L, "1.23432e-10" },
+ { 1.234321234321234e-9L, "1.23432e-09" },
+ { 1.234321234321234e-8L, "1.23432e-08" },
+ { 1.234321234321234e-7L, "1.23432e-07" },
+ { 1.234321234321234e-6L, "1.23432e-06" },
+ { 1.234321234321234e-5L, "1.23432e-05" },
+ { 1.234321234321234e-4L, "0.000123432" },
+ { 1.234321234321234e-3L, "0.00123432" },
+ { 1.234321234321234e-2L, "0.0123432" },
+ { 1.234321234321234e-1L, "0.123432" },
+ { 1.234321234321234L, "1.23432" },
+ { 1.234321234321234e1L, "12.3432" },
+ { 1.234321234321234e2L, "123.432" },
+ { 1.234321234321234e3L, "1234.32" },
+ { 1.234321234321234e4L, "12343.2" },
+ { 1.234321234321234e5L, "123432" },
+ { 1.234321234321234e6L, "1.23432e+06" },
+ { 1.234321234321234e7L, "1.23432e+07" },
+ { 1.234321234321234e8L, "1.23432e+08" },
+ { 1.234321234321234e9L, "1.23432e+09" },
+ { 1.234321234321234e10L, "1.23432e+10" },
+ { 1.234321234321234e11L, "1.23432e+11" },
+ { 1.234321234321234e12L, "1.23432e+12" },
+ { 1.234321234321234e13L, "1.23432e+13" },
+ { 1.234321234321234e14L, "1.23432e+14" },
+ { 1.234321234321234e15L, "1.23432e+15" },
+ { 1.234321234321234e16L, "1.23432e+16" },
+ { 1.234321234321234e17L, "1.23432e+17" },
+ { 1.234321234321234e18L, "1.23432e+18" },
+ { 1.234321234321234e19L, "1.23432e+19" },
+ { 1.234321234321234e20L, "1.23432e+20" },
+ { 1.234321234321234e21L, "1.23432e+21" },
+ { 1.234321234321234e22L, "1.23432e+22" },
+ { 1.234321234321234e23L, "1.23432e+23" },
+ { 1.234321234321234e24L, "1.23432e+24" },
+ { 1.234321234321234e25L, "1.23432e+25" },
+ { 1.234321234321234e26L, "1.23432e+26" },
+ { 1.234321234321234e27L, "1.23432e+27" },
+ { 1.234321234321234e28L, "1.23432e+28" },
+ { 1.234321234321234e29L, "1.23432e+29" },
+ { 1.234321234321234e30L, "1.23432e+30" },
+ { 1.234321234321234e31L, "1.23432e+31" },
+ { 1.234321234321234e32L, "1.23432e+32" },
+ { 1.234321234321234e33L, "1.23432e+33" },
+ { 1.234321234321234e34L, "1.23432e+34" },
+ { 1.234321234321234e35L, "1.23432e+35" },
+ { 1.234321234321234e36L, "1.23432e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (expected[strlen (expected) - 4] == 'e'
+ && strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", -0.03125L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.03125 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+#endif
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%10Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-10Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%+Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "% Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.75000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.Lg %d", 9.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%010Lg %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0000001234 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015Lg %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%050Lg %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.Lg %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.5Lg %d", 999.951L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.5Lg %d", 999.996L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %n format directive. */
+
+ {
+ int count = -1;
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%d %n", 123, &count, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "123 ") == 0);
+ ASSERT (length == strlen (result));
+ ASSERT (count == 4);
+ free (result);
+ }
+
+ /* Test the support of the POSIX/XSI format strings with positions. */
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%2$d %1$d", 33, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "55 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the grouping flag. */
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%'d %d", 1234567, 99);
+ ASSERT (result != NULL);
+ ASSERT (result[strlen (result) - 1] == '9');
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the left-adjust flag. */
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "a%*sc", -3, "b");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "a%-*sc", 3, "b");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "a%-*sc", -3, "b");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of large precision. */
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4000d %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.*d %d", 4000, 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4000d %d", -1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ ASSERT (result[0] == '-');
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[1 + i] == '0');
+ ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4000u %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4000o %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.4000x %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 6; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.4000x %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ ASSERT (result[0] == '0');
+ ASSERT (result[1] == 'x');
+ for (i = 0; i < 4000 - 6; i++)
+ ASSERT (result[2 + i] == '0');
+ ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ {
+ char input[5000];
+ size_t length;
+ char *result;
+ size_t i;
+
+ for (i = 0; i < sizeof (input) - 1; i++)
+ input[i] = 'a' + ((1000000 / (i + 1)) % 26);
+ input[i] = '\0';
+ result = my_asnprintf (NULL, &length, "%.4000s %d", input, 99);
+ ASSERT (result != NULL);
+ ASSERT (memcmp (result, input, 4000) == 0);
+ ASSERT (strcmp (result + 4000, " 99") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %s format directive. */
+
+ /* To verify that these tests succeed, it is necessary to run them under
+ a tool that checks against invalid memory accesses, such as ElectricFence
+ or "valgrind --tool=memcheck". */
+ {
+ size_t i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ char *block;
+ size_t length;
+ char *result;
+
+ block = (char *) malloc (i);
+ memcpy (block, "abcdefgh", i);
+ result = my_asnprintf (NULL, &length, "%.*s", (int) i, block);
+ ASSERT (result != NULL);
+ ASSERT (memcmp (result, block, i) == 0);
+ ASSERT (result[i] == '\0');
+ ASSERT (length == strlen (result));
+ free (result);
+ free (block);
+ }
+ }
+#if HAVE_WCHAR_T
+ {
+ size_t i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ wchar_t *block;
+ size_t j;
+ size_t length;
+ char *result;
+
+ block = (wchar_t *) malloc (i * sizeof (wchar_t));
+ for (j = 0; j < i; j++)
+ block[j] = "abcdefgh"[j];
+ result = my_asnprintf (NULL, &length, "%.*ls", (int) i, block);
+ ASSERT (result != NULL);
+ ASSERT (memcmp (result, "abcdefgh", i) == 0);
+ ASSERT (result[i] == '\0');
+ ASSERT (length == strlen (result));
+ free (result);
+ free (block);
+ }
+ }
+#endif
+}
+
+static char *
+my_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
+{
+ va_list args;
+ char *ret;
+
+ va_start (args, format);
+ ret = vasnprintf (resultbuf, lengthp, format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_vasnprintf ()
+{
+ test_function (my_asnprintf);
+}
+
+static void
+test_asnprintf ()
+{
+ test_function (asnprintf);
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_vasnprintf ();
+ test_asnprintf ();
+ return 0;
+}
diff --git a/tests/gnu/test-vasnprintf-posix2.c b/tests/gnu/test-vasnprintf-posix2.c
new file mode 100755
index 00000000..35b49f86
--- /dev/null
+++ b/tests/gnu/test-vasnprintf-posix2.c
@@ -0,0 +1,63 @@
+/* Test of POSIX compatible vasnprintf() and asnprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "vasnprintf.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ /* Test that a locale dependent decimal point is used. */
+ {
+ size_t length;
+ char *result = asnprintf (NULL, &length, "%.1a", 1.0);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1,0p+0") == 0
+ || strcmp (result, "0x2,0p-1") == 0
+ || strcmp (result, "0x4,0p-2") == 0
+ || strcmp (result, "0x8,0p-3") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ /* Test that a locale dependent decimal point is used. */
+ {
+ size_t length;
+ char *result = asnprintf (NULL, &length, "%.1La", 1.0L);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1,0p+0") == 0
+ || strcmp (result, "0x2,0p-1") == 0
+ || strcmp (result, "0x4,0p-2") == 0
+ || strcmp (result, "0x8,0p-3") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-vasnprintf-posix2.sh b/tests/gnu/test-vasnprintf-posix2.sh
new file mode 100755
index 00000000..5ee5b475
--- /dev/null
+++ b/tests/gnu/test-vasnprintf-posix2.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Test whether a french locale is installed.
+: ${LOCALE_FR=fr_FR}
+: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
+if test $LOCALE_FR != none; then
+ testlocale=$LOCALE_FR
+else
+ if test $LOCALE_FR_UTF8 != none; then
+ testlocale=$LOCALE_FR_UTF8
+ else
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no french locale is installed"
+ else
+ echo "Skipping test: no french locale is supported"
+ fi
+ exit 77
+ fi
+fi
+
+LC_ALL=$testlocale \
+./test-vasnprintf-posix2${EXEEXT}
diff --git a/tests/gnu/test-vasnprintf.c b/tests/gnu/test-vasnprintf.c
new file mode 100755
index 00000000..e2831420
--- /dev/null
+++ b/tests/gnu/test-vasnprintf.c
@@ -0,0 +1,117 @@
+/* Test of vasnprintf() and asnprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "vasnprintf.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+static char *
+my_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
+{
+ va_list args;
+ char *ret;
+
+ va_start (args, format);
+ ret = vasnprintf (resultbuf, lengthp, format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_vasnprintf ()
+{
+ char buf[8];
+ int size;
+
+ for (size = 0; size <= 8; size++)
+ {
+ size_t length = size;
+ char *result = my_asnprintf (NULL, &length, "%d", 12345);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ ASSERT (length == 5);
+ free (result);
+ }
+
+ for (size = 0; size <= 8; size++)
+ {
+ size_t length;
+ char *result;
+
+ memcpy (buf, "DEADBEEF", 8);
+ length = size;
+ result = my_asnprintf (buf, &length, "%d", 12345);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ ASSERT (length == 5);
+ if (size < 6)
+ ASSERT (result != buf);
+ ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
+ if (result != buf)
+ free (result);
+ }
+}
+
+static void
+test_asnprintf ()
+{
+ char buf[8];
+ int size;
+
+ for (size = 0; size <= 8; size++)
+ {
+ size_t length = size;
+ char *result = asnprintf (NULL, &length, "%d", 12345);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ ASSERT (length == 5);
+ free (result);
+ }
+
+ for (size = 0; size <= 8; size++)
+ {
+ size_t length;
+ char *result;
+
+ memcpy (buf, "DEADBEEF", 8);
+ length = size;
+ result = asnprintf (buf, &length, "%d", 12345);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ ASSERT (length == 5);
+ if (size < 6)
+ ASSERT (result != buf);
+ ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
+ if (result != buf)
+ free (result);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_vasnprintf ();
+ test_asnprintf ();
+ return 0;
+}
diff --git a/tests/gnu/test-vasprintf-posix.c b/tests/gnu/test-vasprintf-posix.c
new file mode 100755
index 00000000..ef19df8d
--- /dev/null
+++ b/tests/gnu/test-vasprintf-posix.c
@@ -0,0 +1,3652 @@
+/* Test of POSIX compatible vasprintf() and asprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <float.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+#include "nan.h"
+
+/* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0. */
+static int
+have_minus_zero ()
+{
+ static double plus_zero = 0.0;
+ double minus_zero = - plus_zero;
+ return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
+}
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ So we use -zerod instead. */
+double zerod = 0.0;
+
+/* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
+ So we use minus_zerol instead.
+ IRIX cc can't put -0.0L into .data, but can compute at runtime.
+ Note that the expression -LDBL_MIN * LDBL_MIN does not work on other
+ platforms, such as when cross-compiling to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi
+static long double
+compute_minus_zerol (void)
+{
+ return -LDBL_MIN * LDBL_MIN;
+}
+# define minus_zerol compute_minus_zerol ()
+#else
+long double minus_zerol = -0.0L;
+#endif
+
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+ of 'unsigned int' words. */
+#ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+ ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
+ (unsigned int) (mantlo) << 16 \
+ }
+#else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+ { mantlo, manthi, exponent }
+#endif
+
+static int
+strmatch (const char *pattern, const char *string)
+{
+ if (strlen (pattern) != strlen (string))
+ return 0;
+ for (; *pattern != '\0'; pattern++, string++)
+ if (*pattern != '*' && *string != *pattern)
+ return 0;
+ return 1;
+}
+
+/* Test whether string[start_index..end_index-1] is a valid textual
+ representation of NaN. */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+test_function (int (*my_asprintf) (char **, const char *, ...))
+{
+ int repeat;
+
+ /* Test return value convention. */
+
+ for (repeat = 0; repeat <= 8; repeat++)
+ {
+ char *result;
+ int retval = asprintf (&result, "%d", 12345);
+ ASSERT (retval == 5);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ free (result);
+ }
+
+ /* Test support of size specifiers as in C99. */
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345671 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%zu %d", (size_t) 12345672, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345672 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345673 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", (long double) 1.5, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.5 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
+ output of floating-point numbers. */
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%a %d", 3.1416015625, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.922p+1 33") == 0
+ || strcmp (result, "0x3.244p+0 33") == 0
+ || strcmp (result, "0x6.488p-1 33") == 0
+ || strcmp (result, "0xc.91p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%A %d", -3.1416015625, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
+ || strcmp (result, "-0X3.244P+0 33") == 0
+ || strcmp (result, "-0X6.488P-1 33") == 0
+ || strcmp (result, "-0XC.91P-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%a %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%a %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%a %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%a %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%a %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding near the decimal point. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0a %d", 1.5, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 0. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0a %d", 1.51, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 1. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.1a %d", 1.51, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.8p+0 33") == 0
+ || strcmp (result, "0x3.0p-1 33") == 0
+ || strcmp (result, "0x6.1p-2 33") == 0
+ || strcmp (result, "0xc.1p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 2. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2a %d", 1.51, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.83p+0 33") == 0
+ || strcmp (result, "0x3.05p-1 33") == 0
+ || strcmp (result, "0x6.0ap-2 33") == 0
+ || strcmp (result, "0xc.14p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 3. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.3a %d", 1.51, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.829p+0 33") == 0
+ || strcmp (result, "0x3.052p-1 33") == 0
+ || strcmp (result, "0x6.0a4p-2 33") == 0
+ || strcmp (result, "0xc.148p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.3a %d", 1.49999, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.800p+0 33") == 0
+ || strcmp (result, "0x3.000p-1 33") == 0
+ || strcmp (result, "0x6.000p-2 33") == 0
+ || strcmp (result, "0xc.000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.1a %d", 1.999, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%10a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Small precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.10a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
+ || strcmp (result, "0x3.8000000000p-1 33") == 0
+ || strcmp (result, "0x7.0000000000p-2 33") == 0
+ || strcmp (result, "0xe.0000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Large precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.50a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
+ || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
+ || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
+ || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-10a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7p-2 33") == 0
+ || strcmp (result, "0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%+a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
+ || strcmp (result, "+0x3.8p-1 33") == 0
+ || strcmp (result, "+0x7p-2 33") == 0
+ || strcmp (result, "+0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "% a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7.p-2 33") == 0
+ || strcmp (result, "0xe.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#a %d", 1.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.p+0 33") == 0
+ || strcmp (result, "0x2.p-1 33") == 0
+ || strcmp (result, "0x4.p-2 33") == 0
+ || strcmp (result, "0x8.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%010a %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x001.cp+0 33") == 0
+ || strcmp (result, "0x003.8p-1 33") == 0
+ || strcmp (result, "0x00007p-2 33") == 0
+ || strcmp (result, "0x0000ep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%010a %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strcmp (result, " inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%050a %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ /* "0000000nan 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", 3.1416015625L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.922p+1 33") == 0
+ || strcmp (result, "0x3.244p+0 33") == 0
+ || strcmp (result, "0x6.488p-1 33") == 0
+ || strcmp (result, "0xc.91p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LA %d", -3.1416015625L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
+ || strcmp (result, "-0X3.244P+0 33") == 0
+ || strcmp (result, "-0X6.488P-1 33") == 0
+ || strcmp (result, "-0XC.91P-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0x0p+0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+#endif
+
+ { /* Rounding near the decimal point. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0La %d", 1.5L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 0. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0La %d", 1.51L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x2p+0 33") == 0
+ || strcmp (result, "0x3p-1 33") == 0
+ || strcmp (result, "0x6p-2 33") == 0
+ || strcmp (result, "0xcp-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 1. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.1La %d", 1.51L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.8p+0 33") == 0
+ || strcmp (result, "0x3.0p-1 33") == 0
+ || strcmp (result, "0x6.1p-2 33") == 0
+ || strcmp (result, "0xc.1p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 2. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2La %d", 1.51L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.83p+0 33") == 0
+ || strcmp (result, "0x3.05p-1 33") == 0
+ || strcmp (result, "0x6.0ap-2 33") == 0
+ || strcmp (result, "0xc.14p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding with precision 3. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.3La %d", 1.51L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.829p+0 33") == 0
+ || strcmp (result, "0x3.052p-1 33") == 0
+ || strcmp (result, "0x6.0a4p-2 33") == 0
+ || strcmp (result, "0xc.148p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.3La %d", 1.49999L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.800p+0 33") == 0
+ || strcmp (result, "0x3.000p-1 33") == 0
+ || strcmp (result, "0x6.000p-2 33") == 0
+ || strcmp (result, "0xc.000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
+ glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.1La %d", 1.999L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%10La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Small precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.10La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
+ || strcmp (result, "0x3.8000000000p-1 33") == 0
+ || strcmp (result, "0x7.0000000000p-2 33") == 0
+ || strcmp (result, "0xe.0000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Large precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.50La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
+ || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
+ || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
+ || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-10La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7p-2 33") == 0
+ || strcmp (result, "0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%+La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
+ || strcmp (result, "+0x3.8p-1 33") == 0
+ || strcmp (result, "+0x7p-2 33") == 0
+ || strcmp (result, "+0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "% La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
+ || strcmp (result, " 0x3.8p-1 33") == 0
+ || strcmp (result, " 0x7p-2 33") == 0
+ || strcmp (result, " 0xep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.cp+0 33") == 0
+ || strcmp (result, "0x3.8p-1 33") == 0
+ || strcmp (result, "0x7.p-2 33") == 0
+ || strcmp (result, "0xe.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#La %d", 1.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.p+0 33") == 0
+ || strcmp (result, "0x2.p-1 33") == 0
+ || strcmp (result, "0x4.p-2 33") == 0
+ || strcmp (result, "0x8.p-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%010La %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x001.cp+0 33") == 0
+ || strcmp (result, "0x003.8p-1 33") == 0
+ || strcmp (result, "0x00007p-2 33") == 0
+ || strcmp (result, "0x0000ep-3 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* "0000000inf 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strcmp (result, " inf 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%050La %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ /* "0000000nan 33" is not a valid result; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %f format directive. */
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f %d", 12.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f %d", 1234567.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "0.000000" },
+ { 1.234321234321234e-36, "0.000000" },
+ { 1.234321234321234e-35, "0.000000" },
+ { 1.234321234321234e-34, "0.000000" },
+ { 1.234321234321234e-33, "0.000000" },
+ { 1.234321234321234e-32, "0.000000" },
+ { 1.234321234321234e-31, "0.000000" },
+ { 1.234321234321234e-30, "0.000000" },
+ { 1.234321234321234e-29, "0.000000" },
+ { 1.234321234321234e-28, "0.000000" },
+ { 1.234321234321234e-27, "0.000000" },
+ { 1.234321234321234e-26, "0.000000" },
+ { 1.234321234321234e-25, "0.000000" },
+ { 1.234321234321234e-24, "0.000000" },
+ { 1.234321234321234e-23, "0.000000" },
+ { 1.234321234321234e-22, "0.000000" },
+ { 1.234321234321234e-21, "0.000000" },
+ { 1.234321234321234e-20, "0.000000" },
+ { 1.234321234321234e-19, "0.000000" },
+ { 1.234321234321234e-18, "0.000000" },
+ { 1.234321234321234e-17, "0.000000" },
+ { 1.234321234321234e-16, "0.000000" },
+ { 1.234321234321234e-15, "0.000000" },
+ { 1.234321234321234e-14, "0.000000" },
+ { 1.234321234321234e-13, "0.000000" },
+ { 1.234321234321234e-12, "0.000000" },
+ { 1.234321234321234e-11, "0.000000" },
+ { 1.234321234321234e-10, "0.000000" },
+ { 1.234321234321234e-9, "0.000000" },
+ { 1.234321234321234e-8, "0.000000" },
+ { 1.234321234321234e-7, "0.000000" },
+ { 1.234321234321234e-6, "0.000001" },
+ { 1.234321234321234e-5, "0.000012" },
+ { 1.234321234321234e-4, "0.000123" },
+ { 1.234321234321234e-3, "0.001234" },
+ { 1.234321234321234e-2, "0.012343" },
+ { 1.234321234321234e-1, "0.123432" },
+ { 1.234321234321234, "1.234321" },
+ { 1.234321234321234e1, "12.343212" },
+ { 1.234321234321234e2, "123.432123" },
+ { 1.234321234321234e3, "1234.321234" },
+ { 1.234321234321234e4, "12343.212343" },
+ { 1.234321234321234e5, "123432.123432" },
+ { 1.234321234321234e6, "1234321.234321" },
+ { 1.234321234321234e7, "12343212.343212" },
+ { 1.234321234321234e8, "123432123.432123" },
+ { 1.234321234321234e9, "1234321234.321234" },
+ { 1.234321234321234e10, "12343212343.2123**" },
+ { 1.234321234321234e11, "123432123432.123***" },
+ { 1.234321234321234e12, "1234321234321.23****" },
+ { 1.234321234321234e13, "12343212343212.3*****" },
+ { 1.234321234321234e14, "123432123432123.******" },
+ { 1.234321234321234e15, "1234321234321234.000000" },
+ { 1.234321234321234e16, "123432123432123**.000000" },
+ { 1.234321234321234e17, "123432123432123***.000000" },
+ { 1.234321234321234e18, "123432123432123****.000000" },
+ { 1.234321234321234e19, "123432123432123*****.000000" },
+ { 1.234321234321234e20, "123432123432123******.000000" },
+ { 1.234321234321234e21, "123432123432123*******.000000" },
+ { 1.234321234321234e22, "123432123432123********.000000" },
+ { 1.234321234321234e23, "123432123432123*********.000000" },
+ { 1.234321234321234e24, "123432123432123**********.000000" },
+ { 1.234321234321234e25, "123432123432123***********.000000" },
+ { 1.234321234321234e26, "123432123432123************.000000" },
+ { 1.234321234321234e27, "123432123432123*************.000000" },
+ { 1.234321234321234e28, "123432123432123**************.000000" },
+ { 1.234321234321234e29, "123432123432123***************.000000" },
+ { 1.234321234321234e30, "123432123432123****************.000000" },
+ { 1.234321234321234e31, "123432123432123*****************.000000" },
+ { 1.234321234321234e32, "123432123432123******************.000000" },
+ { 1.234321234321234e33, "123432123432123*******************.000000" },
+ { 1.234321234321234e34, "123432123432123********************.000000" },
+ { 1.234321234321234e35, "123432123432123*********************.000000" },
+ { 1.234321234321234e36, "123432123432123**********************.000000" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f", data[k].value);
+ ASSERT (result != NULL);
+ ASSERT (strmatch (data[k].string, result));
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f %d", -0.03125, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%f %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%10f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-10f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%+f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "% f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.f %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015f %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015f %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%050f %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.f %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2f %d", 999.951, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2f %d", 999.996, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", 12.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", 1234567.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "0.000000" },
+ { 1.234321234321234e-36L, "0.000000" },
+ { 1.234321234321234e-35L, "0.000000" },
+ { 1.234321234321234e-34L, "0.000000" },
+ { 1.234321234321234e-33L, "0.000000" },
+ { 1.234321234321234e-32L, "0.000000" },
+ { 1.234321234321234e-31L, "0.000000" },
+ { 1.234321234321234e-30L, "0.000000" },
+ { 1.234321234321234e-29L, "0.000000" },
+ { 1.234321234321234e-28L, "0.000000" },
+ { 1.234321234321234e-27L, "0.000000" },
+ { 1.234321234321234e-26L, "0.000000" },
+ { 1.234321234321234e-25L, "0.000000" },
+ { 1.234321234321234e-24L, "0.000000" },
+ { 1.234321234321234e-23L, "0.000000" },
+ { 1.234321234321234e-22L, "0.000000" },
+ { 1.234321234321234e-21L, "0.000000" },
+ { 1.234321234321234e-20L, "0.000000" },
+ { 1.234321234321234e-19L, "0.000000" },
+ { 1.234321234321234e-18L, "0.000000" },
+ { 1.234321234321234e-17L, "0.000000" },
+ { 1.234321234321234e-16L, "0.000000" },
+ { 1.234321234321234e-15L, "0.000000" },
+ { 1.234321234321234e-14L, "0.000000" },
+ { 1.234321234321234e-13L, "0.000000" },
+ { 1.234321234321234e-12L, "0.000000" },
+ { 1.234321234321234e-11L, "0.000000" },
+ { 1.234321234321234e-10L, "0.000000" },
+ { 1.234321234321234e-9L, "0.000000" },
+ { 1.234321234321234e-8L, "0.000000" },
+ { 1.234321234321234e-7L, "0.000000" },
+ { 1.234321234321234e-6L, "0.000001" },
+ { 1.234321234321234e-5L, "0.000012" },
+ { 1.234321234321234e-4L, "0.000123" },
+ { 1.234321234321234e-3L, "0.001234" },
+ { 1.234321234321234e-2L, "0.012343" },
+ { 1.234321234321234e-1L, "0.123432" },
+ { 1.234321234321234L, "1.234321" },
+ { 1.234321234321234e1L, "12.343212" },
+ { 1.234321234321234e2L, "123.432123" },
+ { 1.234321234321234e3L, "1234.321234" },
+ { 1.234321234321234e4L, "12343.212343" },
+ { 1.234321234321234e5L, "123432.123432" },
+ { 1.234321234321234e6L, "1234321.234321" },
+ { 1.234321234321234e7L, "12343212.343212" },
+ { 1.234321234321234e8L, "123432123.432123" },
+ { 1.234321234321234e9L, "1234321234.321234" },
+ { 1.234321234321234e10L, "12343212343.2123**" },
+ { 1.234321234321234e11L, "123432123432.123***" },
+ { 1.234321234321234e12L, "1234321234321.23****" },
+ { 1.234321234321234e13L, "12343212343212.3*****" },
+ { 1.234321234321234e14L, "123432123432123.******" },
+ { 1.234321234321234e15L, "1234321234321234.000000" },
+ { 1.234321234321234e16L, "123432123432123**.000000" },
+ { 1.234321234321234e17L, "123432123432123***.000000" },
+ { 1.234321234321234e18L, "123432123432123****.000000" },
+ { 1.234321234321234e19L, "123432123432123*****.000000" },
+ { 1.234321234321234e20L, "123432123432123******.000000" },
+ { 1.234321234321234e21L, "123432123432123*******.000000" },
+ { 1.234321234321234e22L, "123432123432123********.000000" },
+ { 1.234321234321234e23L, "123432123432123*********.000000" },
+ { 1.234321234321234e24L, "123432123432123**********.000000" },
+ { 1.234321234321234e25L, "123432123432123***********.000000" },
+ { 1.234321234321234e26L, "123432123432123************.000000" },
+ { 1.234321234321234e27L, "123432123432123*************.000000" },
+ { 1.234321234321234e28L, "123432123432123**************.000000" },
+ { 1.234321234321234e29L, "123432123432123***************.000000" },
+ { 1.234321234321234e30L, "123432123432123****************.000000" },
+ { 1.234321234321234e31L, "123432123432123*****************.000000" },
+ { 1.234321234321234e32L, "123432123432123******************.000000" },
+ { 1.234321234321234e33L, "123432123432123*******************.000000" },
+ { 1.234321234321234e34L, "123432123432123********************.000000" },
+ { 1.234321234321234e35L, "123432123432123*********************.000000" },
+ { 1.234321234321234e36L, "123432123432123**********************.000000" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf", data[k].value);
+ ASSERT (result != NULL);
+ ASSERT (strmatch (data[k].string, result));
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", -0.03125L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+#endif
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%10Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-10Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%+Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "% Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.Lf %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015Lf %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%050Lf %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.Lf %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2Lf %d", 999.951L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2Lf %d", 999.996L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %F format directive. */
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%F %d", 12.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%F %d", 1234567.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%F %d", -0.03125, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%F %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%F %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%F %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "INF 33") == 0
+ || strcmp (result, "INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%F %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-INF 33") == 0
+ || strcmp (result, "-INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%F %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 1)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015F %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015F %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -INF 33") == 0
+ || strcmp (result, " -INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.F %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2F %d", 999.951, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2F %d", 999.996, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LF %d", 12.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.750000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LF %d", 1234567.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234567.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LF %d", -0.03125L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.031250 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LF %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LF %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LF %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "INF 33") == 0
+ || strcmp (result, "INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LF %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-INF 33") == 0
+ || strcmp (result, "-INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%LF %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 1)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015LF %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00001234.000000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -INF 33") == 0
+ || strcmp (result, " -INFINITY 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.LF %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1234 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2LF %d", 999.951L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.2LF %d", 999.996L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000.00 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %e format directive. */
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e %d", 12.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.275000e+01 33") == 0
+ || strcmp (result, "1.275000e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e %d", 1234567.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.234567e+06 33") == 0
+ || strcmp (result, "1.234567e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "1.234321e-37" },
+ { 1.234321234321234e-36, "1.234321e-36" },
+ { 1.234321234321234e-35, "1.234321e-35" },
+ { 1.234321234321234e-34, "1.234321e-34" },
+ { 1.234321234321234e-33, "1.234321e-33" },
+ { 1.234321234321234e-32, "1.234321e-32" },
+ { 1.234321234321234e-31, "1.234321e-31" },
+ { 1.234321234321234e-30, "1.234321e-30" },
+ { 1.234321234321234e-29, "1.234321e-29" },
+ { 1.234321234321234e-28, "1.234321e-28" },
+ { 1.234321234321234e-27, "1.234321e-27" },
+ { 1.234321234321234e-26, "1.234321e-26" },
+ { 1.234321234321234e-25, "1.234321e-25" },
+ { 1.234321234321234e-24, "1.234321e-24" },
+ { 1.234321234321234e-23, "1.234321e-23" },
+ { 1.234321234321234e-22, "1.234321e-22" },
+ { 1.234321234321234e-21, "1.234321e-21" },
+ { 1.234321234321234e-20, "1.234321e-20" },
+ { 1.234321234321234e-19, "1.234321e-19" },
+ { 1.234321234321234e-18, "1.234321e-18" },
+ { 1.234321234321234e-17, "1.234321e-17" },
+ { 1.234321234321234e-16, "1.234321e-16" },
+ { 1.234321234321234e-15, "1.234321e-15" },
+ { 1.234321234321234e-14, "1.234321e-14" },
+ { 1.234321234321234e-13, "1.234321e-13" },
+ { 1.234321234321234e-12, "1.234321e-12" },
+ { 1.234321234321234e-11, "1.234321e-11" },
+ { 1.234321234321234e-10, "1.234321e-10" },
+ { 1.234321234321234e-9, "1.234321e-09" },
+ { 1.234321234321234e-8, "1.234321e-08" },
+ { 1.234321234321234e-7, "1.234321e-07" },
+ { 1.234321234321234e-6, "1.234321e-06" },
+ { 1.234321234321234e-5, "1.234321e-05" },
+ { 1.234321234321234e-4, "1.234321e-04" },
+ { 1.234321234321234e-3, "1.234321e-03" },
+ { 1.234321234321234e-2, "1.234321e-02" },
+ { 1.234321234321234e-1, "1.234321e-01" },
+ { 1.234321234321234, "1.234321e+00" },
+ { 1.234321234321234e1, "1.234321e+01" },
+ { 1.234321234321234e2, "1.234321e+02" },
+ { 1.234321234321234e3, "1.234321e+03" },
+ { 1.234321234321234e4, "1.234321e+04" },
+ { 1.234321234321234e5, "1.234321e+05" },
+ { 1.234321234321234e6, "1.234321e+06" },
+ { 1.234321234321234e7, "1.234321e+07" },
+ { 1.234321234321234e8, "1.234321e+08" },
+ { 1.234321234321234e9, "1.234321e+09" },
+ { 1.234321234321234e10, "1.234321e+10" },
+ { 1.234321234321234e11, "1.234321e+11" },
+ { 1.234321234321234e12, "1.234321e+12" },
+ { 1.234321234321234e13, "1.234321e+13" },
+ { 1.234321234321234e14, "1.234321e+14" },
+ { 1.234321234321234e15, "1.234321e+15" },
+ { 1.234321234321234e16, "1.234321e+16" },
+ { 1.234321234321234e17, "1.234321e+17" },
+ { 1.234321234321234e18, "1.234321e+18" },
+ { 1.234321234321234e19, "1.234321e+19" },
+ { 1.234321234321234e20, "1.234321e+20" },
+ { 1.234321234321234e21, "1.234321e+21" },
+ { 1.234321234321234e22, "1.234321e+22" },
+ { 1.234321234321234e23, "1.234321e+23" },
+ { 1.234321234321234e24, "1.234321e+24" },
+ { 1.234321234321234e25, "1.234321e+25" },
+ { 1.234321234321234e26, "1.234321e+26" },
+ { 1.234321234321234e27, "1.234321e+27" },
+ { 1.234321234321234e28, "1.234321e+28" },
+ { 1.234321234321234e29, "1.234321e+29" },
+ { 1.234321234321234e30, "1.234321e+30" },
+ { 1.234321234321234e31, "1.234321e+31" },
+ { 1.234321234321234e32, "1.234321e+32" },
+ { 1.234321234321234e33, "1.234321e+33" },
+ { 1.234321234321234e34, "1.234321e+34" },
+ { 1.234321234321234e35, "1.234321e+35" },
+ { 1.234321234321234e36, "1.234321e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e %d", -0.03125, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-3.125000e-02 33") == 0
+ || strcmp (result, "-3.125000e-002 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000e+00 33") == 0
+ || strcmp (result, "0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000e+00 33") == 0
+ || strcmp (result, "-0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%e %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%15e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-15e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%+e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.750000e+00 33") == 0
+ || strcmp (result, "+1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "% e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.e %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2.e+00 33") == 0
+ || strcmp (result, "2.e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.e %d", 9.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015e %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0001.234000e+03 33") == 0
+ || strcmp (result, "001.234000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015e %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%050e %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.e %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4e %d", 999.951, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "9.9995e+02 33") == 0
+ || strcmp (result, "9.9995e+002 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4e %d", 999.996, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.0000e+03 33") == 0
+ || strcmp (result, "1.0000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", 12.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.275000e+01 33") == 0
+ || strcmp (result, "1.275000e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", 1234567.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.234567e+06 33") == 0
+ || strcmp (result, "1.234567e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "1.234321e-37" },
+ { 1.234321234321234e-36L, "1.234321e-36" },
+ { 1.234321234321234e-35L, "1.234321e-35" },
+ { 1.234321234321234e-34L, "1.234321e-34" },
+ { 1.234321234321234e-33L, "1.234321e-33" },
+ { 1.234321234321234e-32L, "1.234321e-32" },
+ { 1.234321234321234e-31L, "1.234321e-31" },
+ { 1.234321234321234e-30L, "1.234321e-30" },
+ { 1.234321234321234e-29L, "1.234321e-29" },
+ { 1.234321234321234e-28L, "1.234321e-28" },
+ { 1.234321234321234e-27L, "1.234321e-27" },
+ { 1.234321234321234e-26L, "1.234321e-26" },
+ { 1.234321234321234e-25L, "1.234321e-25" },
+ { 1.234321234321234e-24L, "1.234321e-24" },
+ { 1.234321234321234e-23L, "1.234321e-23" },
+ { 1.234321234321234e-22L, "1.234321e-22" },
+ { 1.234321234321234e-21L, "1.234321e-21" },
+ { 1.234321234321234e-20L, "1.234321e-20" },
+ { 1.234321234321234e-19L, "1.234321e-19" },
+ { 1.234321234321234e-18L, "1.234321e-18" },
+ { 1.234321234321234e-17L, "1.234321e-17" },
+ { 1.234321234321234e-16L, "1.234321e-16" },
+ { 1.234321234321234e-15L, "1.234321e-15" },
+ { 1.234321234321234e-14L, "1.234321e-14" },
+ { 1.234321234321234e-13L, "1.234321e-13" },
+ { 1.234321234321234e-12L, "1.234321e-12" },
+ { 1.234321234321234e-11L, "1.234321e-11" },
+ { 1.234321234321234e-10L, "1.234321e-10" },
+ { 1.234321234321234e-9L, "1.234321e-09" },
+ { 1.234321234321234e-8L, "1.234321e-08" },
+ { 1.234321234321234e-7L, "1.234321e-07" },
+ { 1.234321234321234e-6L, "1.234321e-06" },
+ { 1.234321234321234e-5L, "1.234321e-05" },
+ { 1.234321234321234e-4L, "1.234321e-04" },
+ { 1.234321234321234e-3L, "1.234321e-03" },
+ { 1.234321234321234e-2L, "1.234321e-02" },
+ { 1.234321234321234e-1L, "1.234321e-01" },
+ { 1.234321234321234L, "1.234321e+00" },
+ { 1.234321234321234e1L, "1.234321e+01" },
+ { 1.234321234321234e2L, "1.234321e+02" },
+ { 1.234321234321234e3L, "1.234321e+03" },
+ { 1.234321234321234e4L, "1.234321e+04" },
+ { 1.234321234321234e5L, "1.234321e+05" },
+ { 1.234321234321234e6L, "1.234321e+06" },
+ { 1.234321234321234e7L, "1.234321e+07" },
+ { 1.234321234321234e8L, "1.234321e+08" },
+ { 1.234321234321234e9L, "1.234321e+09" },
+ { 1.234321234321234e10L, "1.234321e+10" },
+ { 1.234321234321234e11L, "1.234321e+11" },
+ { 1.234321234321234e12L, "1.234321e+12" },
+ { 1.234321234321234e13L, "1.234321e+13" },
+ { 1.234321234321234e14L, "1.234321e+14" },
+ { 1.234321234321234e15L, "1.234321e+15" },
+ { 1.234321234321234e16L, "1.234321e+16" },
+ { 1.234321234321234e17L, "1.234321e+17" },
+ { 1.234321234321234e18L, "1.234321e+18" },
+ { 1.234321234321234e19L, "1.234321e+19" },
+ { 1.234321234321234e20L, "1.234321e+20" },
+ { 1.234321234321234e21L, "1.234321e+21" },
+ { 1.234321234321234e22L, "1.234321e+22" },
+ { 1.234321234321234e23L, "1.234321e+23" },
+ { 1.234321234321234e24L, "1.234321e+24" },
+ { 1.234321234321234e25L, "1.234321e+25" },
+ { 1.234321234321234e26L, "1.234321e+26" },
+ { 1.234321234321234e27L, "1.234321e+27" },
+ { 1.234321234321234e28L, "1.234321e+28" },
+ { 1.234321234321234e29L, "1.234321e+29" },
+ { 1.234321234321234e30L, "1.234321e+30" },
+ { 1.234321234321234e31L, "1.234321e+31" },
+ { 1.234321234321234e32L, "1.234321e+32" },
+ { 1.234321234321234e33L, "1.234321e+33" },
+ { 1.234321234321234e34L, "1.234321e+34" },
+ { 1.234321234321234e35L, "1.234321e+35" },
+ { 1.234321234321234e36L, "1.234321e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", -0.03125L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-3.125000e-02 33") == 0
+ || strcmp (result, "-3.125000e-002 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0.000000e+00 33") == 0
+ || strcmp (result, "0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0.000000e+00 33") == 0
+ || strcmp (result, "-0.000000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+#endif
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%15Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-15Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%+Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.750000e+00 33") == 0
+ || strcmp (result, "+1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "% Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.750000e+00 33") == 0
+ || strcmp (result, " 1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.750000e+00 33") == 0
+ || strcmp (result, "1.750000e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.Le %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2.e+00 33") == 0
+ || strcmp (result, "2.e+000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.Le %d", 9.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015Le %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0001.234000e+03 33") == 0
+ || strcmp (result, "001.234000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015Le %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%050Le %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.Le %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4Le %d", 999.951L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "9.9995e+02 33") == 0
+ || strcmp (result, "9.9995e+002 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4Le %d", 999.996L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.0000e+03 33") == 0
+ || strcmp (result, "1.0000e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %g format directive. */
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g %d", 12.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g %d", 1234567.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.23457e+06 33") == 0
+ || strcmp (result, "1.23457e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37, "1.23432e-37" },
+ { 1.234321234321234e-36, "1.23432e-36" },
+ { 1.234321234321234e-35, "1.23432e-35" },
+ { 1.234321234321234e-34, "1.23432e-34" },
+ { 1.234321234321234e-33, "1.23432e-33" },
+ { 1.234321234321234e-32, "1.23432e-32" },
+ { 1.234321234321234e-31, "1.23432e-31" },
+ { 1.234321234321234e-30, "1.23432e-30" },
+ { 1.234321234321234e-29, "1.23432e-29" },
+ { 1.234321234321234e-28, "1.23432e-28" },
+ { 1.234321234321234e-27, "1.23432e-27" },
+ { 1.234321234321234e-26, "1.23432e-26" },
+ { 1.234321234321234e-25, "1.23432e-25" },
+ { 1.234321234321234e-24, "1.23432e-24" },
+ { 1.234321234321234e-23, "1.23432e-23" },
+ { 1.234321234321234e-22, "1.23432e-22" },
+ { 1.234321234321234e-21, "1.23432e-21" },
+ { 1.234321234321234e-20, "1.23432e-20" },
+ { 1.234321234321234e-19, "1.23432e-19" },
+ { 1.234321234321234e-18, "1.23432e-18" },
+ { 1.234321234321234e-17, "1.23432e-17" },
+ { 1.234321234321234e-16, "1.23432e-16" },
+ { 1.234321234321234e-15, "1.23432e-15" },
+ { 1.234321234321234e-14, "1.23432e-14" },
+ { 1.234321234321234e-13, "1.23432e-13" },
+ { 1.234321234321234e-12, "1.23432e-12" },
+ { 1.234321234321234e-11, "1.23432e-11" },
+ { 1.234321234321234e-10, "1.23432e-10" },
+ { 1.234321234321234e-9, "1.23432e-09" },
+ { 1.234321234321234e-8, "1.23432e-08" },
+ { 1.234321234321234e-7, "1.23432e-07" },
+ { 1.234321234321234e-6, "1.23432e-06" },
+ { 1.234321234321234e-5, "1.23432e-05" },
+ { 1.234321234321234e-4, "0.000123432" },
+ { 1.234321234321234e-3, "0.00123432" },
+ { 1.234321234321234e-2, "0.0123432" },
+ { 1.234321234321234e-1, "0.123432" },
+ { 1.234321234321234, "1.23432" },
+ { 1.234321234321234e1, "12.3432" },
+ { 1.234321234321234e2, "123.432" },
+ { 1.234321234321234e3, "1234.32" },
+ { 1.234321234321234e4, "12343.2" },
+ { 1.234321234321234e5, "123432" },
+ { 1.234321234321234e6, "1.23432e+06" },
+ { 1.234321234321234e7, "1.23432e+07" },
+ { 1.234321234321234e8, "1.23432e+08" },
+ { 1.234321234321234e9, "1.23432e+09" },
+ { 1.234321234321234e10, "1.23432e+10" },
+ { 1.234321234321234e11, "1.23432e+11" },
+ { 1.234321234321234e12, "1.23432e+12" },
+ { 1.234321234321234e13, "1.23432e+13" },
+ { 1.234321234321234e14, "1.23432e+14" },
+ { 1.234321234321234e15, "1.23432e+15" },
+ { 1.234321234321234e16, "1.23432e+16" },
+ { 1.234321234321234e17, "1.23432e+17" },
+ { 1.234321234321234e18, "1.23432e+18" },
+ { 1.234321234321234e19, "1.23432e+19" },
+ { 1.234321234321234e20, "1.23432e+20" },
+ { 1.234321234321234e21, "1.23432e+21" },
+ { 1.234321234321234e22, "1.23432e+22" },
+ { 1.234321234321234e23, "1.23432e+23" },
+ { 1.234321234321234e24, "1.23432e+24" },
+ { 1.234321234321234e25, "1.23432e+25" },
+ { 1.234321234321234e26, "1.23432e+26" },
+ { 1.234321234321234e27, "1.23432e+27" },
+ { 1.234321234321234e28, "1.23432e+28" },
+ { 1.234321234321234e29, "1.23432e+29" },
+ { 1.234321234321234e30, "1.23432e+30" },
+ { 1.234321234321234e31, "1.23432e+31" },
+ { 1.234321234321234e32, "1.23432e+32" },
+ { 1.234321234321234e33, "1.23432e+33" },
+ { 1.234321234321234e34, "1.23432e+34" },
+ { 1.234321234321234e35, "1.23432e+35" },
+ { 1.234321234321234e36, "1.23432e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (expected[strlen (expected) - 4] == 'e'
+ && strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g %d", -0.03125, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.03125 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g %d", 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g %d", -zerod, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g %d", 1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%g %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%10g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-10g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%+g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "% g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.75000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.g %d", 1.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.g %d", 9.75, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%010g %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0000001234 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015g %d", -1.0 / 0.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%050g %d", NaNd (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.g %d", 1234.0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.5g %d", 999.951, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.5g %d", 999.996, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", 12.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A larger positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", 1234567.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.23457e+06 33") == 0
+ || strcmp (result, "1.23457e+006 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Small and large positive numbers. */
+ static struct { long double value; const char *string; } data[] =
+ {
+ { 1.234321234321234e-37L, "1.23432e-37" },
+ { 1.234321234321234e-36L, "1.23432e-36" },
+ { 1.234321234321234e-35L, "1.23432e-35" },
+ { 1.234321234321234e-34L, "1.23432e-34" },
+ { 1.234321234321234e-33L, "1.23432e-33" },
+ { 1.234321234321234e-32L, "1.23432e-32" },
+ { 1.234321234321234e-31L, "1.23432e-31" },
+ { 1.234321234321234e-30L, "1.23432e-30" },
+ { 1.234321234321234e-29L, "1.23432e-29" },
+ { 1.234321234321234e-28L, "1.23432e-28" },
+ { 1.234321234321234e-27L, "1.23432e-27" },
+ { 1.234321234321234e-26L, "1.23432e-26" },
+ { 1.234321234321234e-25L, "1.23432e-25" },
+ { 1.234321234321234e-24L, "1.23432e-24" },
+ { 1.234321234321234e-23L, "1.23432e-23" },
+ { 1.234321234321234e-22L, "1.23432e-22" },
+ { 1.234321234321234e-21L, "1.23432e-21" },
+ { 1.234321234321234e-20L, "1.23432e-20" },
+ { 1.234321234321234e-19L, "1.23432e-19" },
+ { 1.234321234321234e-18L, "1.23432e-18" },
+ { 1.234321234321234e-17L, "1.23432e-17" },
+ { 1.234321234321234e-16L, "1.23432e-16" },
+ { 1.234321234321234e-15L, "1.23432e-15" },
+ { 1.234321234321234e-14L, "1.23432e-14" },
+ { 1.234321234321234e-13L, "1.23432e-13" },
+ { 1.234321234321234e-12L, "1.23432e-12" },
+ { 1.234321234321234e-11L, "1.23432e-11" },
+ { 1.234321234321234e-10L, "1.23432e-10" },
+ { 1.234321234321234e-9L, "1.23432e-09" },
+ { 1.234321234321234e-8L, "1.23432e-08" },
+ { 1.234321234321234e-7L, "1.23432e-07" },
+ { 1.234321234321234e-6L, "1.23432e-06" },
+ { 1.234321234321234e-5L, "1.23432e-05" },
+ { 1.234321234321234e-4L, "0.000123432" },
+ { 1.234321234321234e-3L, "0.00123432" },
+ { 1.234321234321234e-2L, "0.0123432" },
+ { 1.234321234321234e-1L, "0.123432" },
+ { 1.234321234321234L, "1.23432" },
+ { 1.234321234321234e1L, "12.3432" },
+ { 1.234321234321234e2L, "123.432" },
+ { 1.234321234321234e3L, "1234.32" },
+ { 1.234321234321234e4L, "12343.2" },
+ { 1.234321234321234e5L, "123432" },
+ { 1.234321234321234e6L, "1.23432e+06" },
+ { 1.234321234321234e7L, "1.23432e+07" },
+ { 1.234321234321234e8L, "1.23432e+08" },
+ { 1.234321234321234e9L, "1.23432e+09" },
+ { 1.234321234321234e10L, "1.23432e+10" },
+ { 1.234321234321234e11L, "1.23432e+11" },
+ { 1.234321234321234e12L, "1.23432e+12" },
+ { 1.234321234321234e13L, "1.23432e+13" },
+ { 1.234321234321234e14L, "1.23432e+14" },
+ { 1.234321234321234e15L, "1.23432e+15" },
+ { 1.234321234321234e16L, "1.23432e+16" },
+ { 1.234321234321234e17L, "1.23432e+17" },
+ { 1.234321234321234e18L, "1.23432e+18" },
+ { 1.234321234321234e19L, "1.23432e+19" },
+ { 1.234321234321234e20L, "1.23432e+20" },
+ { 1.234321234321234e21L, "1.23432e+21" },
+ { 1.234321234321234e22L, "1.23432e+22" },
+ { 1.234321234321234e23L, "1.23432e+23" },
+ { 1.234321234321234e24L, "1.23432e+24" },
+ { 1.234321234321234e25L, "1.23432e+25" },
+ { 1.234321234321234e26L, "1.23432e+26" },
+ { 1.234321234321234e27L, "1.23432e+27" },
+ { 1.234321234321234e28L, "1.23432e+28" },
+ { 1.234321234321234e29L, "1.23432e+29" },
+ { 1.234321234321234e30L, "1.23432e+30" },
+ { 1.234321234321234e31L, "1.23432e+31" },
+ { 1.234321234321234e32L, "1.23432e+32" },
+ { 1.234321234321234e33L, "1.23432e+33" },
+ { 1.234321234321234e34L, "1.23432e+34" },
+ { 1.234321234321234e35L, "1.23432e+35" },
+ { 1.234321234321234e36L, "1.23432e+36" }
+ };
+ size_t k;
+ for (k = 0; k < SIZEOF (data); k++)
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg", data[k].value);
+ const char *expected = data[k].string;
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, expected) == 0
+ /* Some implementations produce exponents with 3 digits. */
+ || (expected[strlen (expected) - 4] == 'e'
+ && strlen (result) == strlen (expected) + 1
+ && memcmp (result, expected, strlen (expected) - 2) == 0
+ && result[strlen (expected) - 2] == '0'
+ && strcmp (result + strlen (expected) - 1,
+ expected + strlen (expected) - 2)
+ == 0));
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ }
+
+ { /* A negative number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", -0.03125L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-0.03125 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", minus_zerol, 33, 44, 55);
+ ASSERT (result != NULL);
+ if (have_minus_zero ())
+ ASSERT (strcmp (result, "-0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Positive infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", 1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "inf 33") == 0
+ || strcmp (result, "infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative infinity. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "-inf 33") == 0
+ || strcmp (result, "-infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+ { /* Quiet NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ {
+ /* Signalling NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+ Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+ Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+ Application Architecture.
+ Table 5-2 "Floating-Point Register Encodings"
+ Figure 5-6 "Memory to Floating-Point Register Data Translation"
+ */
+ { /* Pseudo-NaN. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Infinity. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Zero. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Unnormalized number. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+ { /* Pseudo-Denormal. */
+ static union { unsigned int word[4]; long double value; } x =
+ { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+ char *result;
+ int retval =
+ my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) >= 3 + 3
+ && strisnan (result, 0, strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+#endif
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%10Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-10Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SHOWSIGN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%+Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "+1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_SPACE. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "% Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 1.75 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.75000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.Lg %d", 1.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "2. 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.Lg %d", 9.75L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1.e+01 33") == 0
+ || strcmp (result, "1.e+001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with finite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%010Lg %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0000001234 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with infinite number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015Lg %d", -1.0L / 0.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " -inf 33") == 0
+ || strcmp (result, " -infinity 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ZERO with NaN. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%050Lg %d", NaNl (), 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strlen (result) == 50 + 3
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
+ && strcmp (result + strlen (result) - 3, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.Lg %d", 1234.0L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1e+03 33") == 0
+ || strcmp (result, "1e+003 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with no rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.5Lg %d", 999.951L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "999.95 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision with rounding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.5Lg %d", 999.996L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "1000 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %n format directive. */
+
+ {
+ int count = -1;
+ char *result;
+ int retval =
+ my_asprintf (&result, "%d %n", 123, &count, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "123 ") == 0);
+ ASSERT (retval == strlen (result));
+ ASSERT (count == 4);
+ free (result);
+ }
+
+ /* Test the support of the POSIX/XSI format strings with positions. */
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%2$d %1$d", 33, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "55 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the grouping flag. */
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%'d %d", 1234567, 99);
+ ASSERT (result != NULL);
+ ASSERT (result[strlen (result) - 1] == '9');
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the left-adjust flag. */
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "a%*sc", -3, "b");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "a%-*sc", 3, "b");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "a%-*sc", -3, "b");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "ab c") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of large precision. */
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4000d %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.*d %d", 4000, 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4000d %d", -1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ ASSERT (result[0] == '-');
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[1 + i] == '0');
+ ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4000u %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4000o %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 7; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.4000x %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ for (i = 0; i < 4000 - 6; i++)
+ ASSERT (result[i] == '0');
+ ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.4000x %d", 1234567, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ ASSERT (result[0] == '0');
+ ASSERT (result[1] == 'x');
+ for (i = 0; i < 4000 - 6; i++)
+ ASSERT (result[2 + i] == '0');
+ ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char input[5000];
+ char *result;
+ int retval;
+ size_t i;
+
+ for (i = 0; i < sizeof (input) - 1; i++)
+ input[i] = 'a' + ((1000000 / (i + 1)) % 26);
+ input[i] = '\0';
+ retval = my_asprintf (&result, "%.4000s %d", input, 99);
+ ASSERT (result != NULL);
+ ASSERT (memcmp (result, input, 4000) == 0);
+ ASSERT (strcmp (result + 4000, " 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ /* Test the support of the %s format directive. */
+
+ /* To verify that these tests succeed, it is necessary to run them under
+ a tool that checks against invalid memory accesses, such as ElectricFence
+ or "valgrind --tool=memcheck". */
+ {
+ size_t i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ char *block;
+ char *result;
+ int retval;
+
+ block = (char *) malloc (i);
+ memcpy (block, "abcdefgh", i);
+ retval = my_asprintf (&result, "%.*s", (int) i, block);
+ ASSERT (result != NULL);
+ ASSERT (memcmp (result, block, i) == 0);
+ ASSERT (result[i] == '\0');
+ ASSERT (retval == strlen (result));
+ free (result);
+ free (block);
+ }
+ }
+#if HAVE_WCHAR_T
+ {
+ size_t i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ wchar_t *block;
+ size_t j;
+ char *result;
+ int retval;
+
+ block = (wchar_t *) malloc (i * sizeof (wchar_t));
+ for (j = 0; j < i; j++)
+ block[j] = "abcdefgh"[j];
+ retval = my_asprintf (&result, "%.*ls", (int) i, block);
+ ASSERT (result != NULL);
+ ASSERT (memcmp (result, "abcdefgh", i) == 0);
+ ASSERT (result[i] == '\0');
+ ASSERT (retval == strlen (result));
+ free (result);
+ free (block);
+ }
+ }
+#endif
+}
+
+static int
+my_asprintf (char **result, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vasprintf (result, format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_vasprintf ()
+{
+ test_function (my_asprintf);
+}
+
+static void
+test_asprintf ()
+{
+ test_function (asprintf);
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_vasprintf ();
+ test_asprintf ();
+ return 0;
+}
diff --git a/tests/gnu/test-vasprintf.c b/tests/gnu/test-vasprintf.c
new file mode 100755
index 00000000..e5dc3cd3
--- /dev/null
+++ b/tests/gnu/test-vasprintf.c
@@ -0,0 +1,83 @@
+/* Test of vasprintf() and asprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (asprintf, int, (char **, char const *, ...));
+SIGNATURE_CHECK (vasprintf, int, (char **, char const *, va_list));
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+static int
+my_asprintf (char **result, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vasprintf (result, format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_vasprintf ()
+{
+ int repeat;
+
+ for (repeat = 0; repeat <= 8; repeat++)
+ {
+ char *result;
+ int retval = my_asprintf (&result, "%d", 12345);
+ ASSERT (retval == 5);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ free (result);
+ }
+}
+
+static void
+test_asprintf ()
+{
+ int repeat;
+
+ for (repeat = 0; repeat <= 8; repeat++)
+ {
+ char *result;
+ int retval = asprintf (&result, "%d", 12345);
+ ASSERT (retval == 5);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ free (result);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_vasprintf ();
+ test_asprintf ();
+ return 0;
+}
diff --git a/tests/gnu/test-vc-list-files-cvs.sh b/tests/gnu/test-vc-list-files-cvs.sh
new file mode 100755
index 00000000..110be03f
--- /dev/null
+++ b/tests/gnu/test-vc-list-files-cvs.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+# Unit tests for vc-list-files
+# Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+tmpdir=vc-cvs-$$
+trap 'st=$?; cd '"`pwd`"' && rm -rf $tmpdir; exit $st' 0
+trap '(exit $?); exit $?' 1 2 13 15
+
+if ( diff --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+ compare() { diff -u "$@"; }
+elif ( cmp --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+ compare() { cmp -s "$@"; }
+else
+ compare() { cmp "$@"; }
+fi
+
+repo=`pwd`/$tmpdir/repo
+
+fail=0
+for i in with-cvsu without; do
+ # On the first iteration, test using cvsu, if it's in your path.
+ # On the second iteration, ensure that cvsu fails, so we'll
+ # exercise the awk-using code.
+ if test $i = without; then
+ printf '%s\n' '#!/bin/sh' 'exit 1' > cvsu
+ chmod a+x cvsu
+ PATH=`pwd`:$PATH
+ export PATH
+ fi
+ ok=0
+ mkdir $tmpdir && cd $tmpdir &&
+ # without cvs, skip the test
+ # The double use of 'exit' is needed for the reference to $? inside the trap.
+ { ( cvs -Q -d "$repo" init ) > /dev/null 2>&1 \
+ || { echo "Skipping test: cvs not found in PATH"; (exit 77); exit 77; }; } &&
+ mkdir w && cd w &&
+ mkdir d &&
+ touch d/a b c &&
+ cvs -Q -d "$repo" import -m imp m M M0 &&
+ cvs -Q -d "$repo" co m && cd m &&
+ printf '%s\n' b c d/a > expected &&
+ vc-list-files | sort > actual &&
+ compare expected actual &&
+ ok=1
+ test $ok = 0 && fail=1
+done
+
+(exit $fail); exit $fail
diff --git a/tests/gnu/test-vc-list-files-git.sh b/tests/gnu/test-vc-list-files-git.sh
new file mode 100755
index 00000000..7b7ff1a5
--- /dev/null
+++ b/tests/gnu/test-vc-list-files-git.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+# Unit tests for vc-list-files
+# Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+if ( diff --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+ compare() { diff -u "$@"; }
+elif ( cmp --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+ compare() { cmp -s "$@"; }
+else
+ compare() { cmp "$@"; }
+fi
+
+tmpdir=vc-git-$$
+trap 'st=$?; cd '"`pwd`"' && rm -rf $tmpdir; exit $st' 0
+trap '(exit $?); exit $?' 1 2 13 15
+
+fail=1
+mkdir $tmpdir && cd $tmpdir &&
+ # without git, skip the test
+ # The double use of 'exit' is needed for the reference to $? inside the trap.
+ { ( git init -q ) > /dev/null 2>&1 \
+ || { echo "Skipping test: git not found in PATH"; (exit 77); exit 77; }; } &&
+ mkdir d &&
+ touch d/a b c &&
+ git config user.email "you@example.com"
+ git config user.name "Your Name"
+ git add . > /dev/null &&
+ git commit -q -a -m log &&
+ printf '%s\n' b c d/a > expected &&
+ vc-list-files > actual &&
+ compare expected actual &&
+ fail=0
+
+(exit $fail); exit $fail
diff --git a/tests/gnu/test-vfprintf-posix.c b/tests/gnu/test-vfprintf-posix.c
new file mode 100755
index 00000000..3c64afef
--- /dev/null
+++ b/tests/gnu/test-vfprintf-posix.c
@@ -0,0 +1,52 @@
+/* Test of POSIX compatible vfprintf() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (vfprintf, int, (FILE *, char const *, va_list));
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-fprintf-posix.h"
+
+static int
+my_fprintf (FILE *fp, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vfprintf (fp, format, args);
+ va_end (args);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_function (my_fprintf);
+ return 0;
+}
diff --git a/tests/gnu/test-vfprintf-posix.sh b/tests/gnu/test-vfprintf-posix.sh
new file mode 100755
index 00000000..74339ba0
--- /dev/null
+++ b/tests/gnu/test-vfprintf-posix.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles t-vfprintf-posix.tmp t-vfprintf-posix.out"
+./test-vfprintf-posix${EXEEXT} > t-vfprintf-posix.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-vfprintf-posix.tmp > t-vfprintf-posix.out || exit 1
+
+: ${DIFF=diff}
+${DIFF} "${srcdir}/test-printf-posix.output" t-vfprintf-posix.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/tests/gnu/test-vprintf-posix.c b/tests/gnu/test-vprintf-posix.c
new file mode 100755
index 00000000..166df533
--- /dev/null
+++ b/tests/gnu/test-vprintf-posix.c
@@ -0,0 +1,52 @@
+/* Test of POSIX compatible vfprintf() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (vprintf, int, (char const *, va_list));
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-printf-posix.h"
+
+static int
+my_printf (const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vprintf (format, args);
+ va_end (args);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_function (my_printf);
+ return 0;
+}
diff --git a/tests/gnu/test-vprintf-posix.sh b/tests/gnu/test-vprintf-posix.sh
new file mode 100755
index 00000000..968a8b2a
--- /dev/null
+++ b/tests/gnu/test-vprintf-posix.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles t-vprintf-posix.tmp t-vprintf-posix.out"
+./test-vprintf-posix${EXEEXT} > t-vprintf-posix.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-vprintf-posix.tmp > t-vprintf-posix.out || exit 1
+
+: ${DIFF=diff}
+${DIFF} "${srcdir}/test-printf-posix.output" t-vprintf-posix.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/tests/gnu/test-wchar.c b/tests/gnu/test-wchar.c
new file mode 100755
index 00000000..2a03d6b6
--- /dev/null
+++ b/tests/gnu/test-wchar.c
@@ -0,0 +1,37 @@
+/* Test of <wchar.h> substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <wchar.h>
+
+#include "verify.h"
+
+/* Check that the types wchar_t and wint_t are defined. */
+wchar_t a = 'c';
+wint_t b = 'x';
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/gnu/test-wcrtomb.c b/tests/gnu/test-wcrtomb.c
new file mode 100755
index 00000000..0e844ef0
--- /dev/null
+++ b/tests/gnu/test-wcrtomb.c
@@ -0,0 +1,154 @@
+/* Test of conversion of wide character to multibyte character.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include <wchar.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (wcrtomb, size_t, (char *, wchar_t, mbstate_t *));
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+/* Check the multibyte character s[0..n-1]. */
+static void
+check_character (const char *s, size_t n)
+{
+ wchar_t wc;
+ char buf[64];
+ int iret;
+ size_t ret;
+
+ wc = (wchar_t) 0xBADFACE;
+ iret = mbtowc (&wc, s, n);
+ ASSERT (iret == n);
+
+ ret = wcrtomb (buf, wc, NULL);
+ ASSERT (ret == n);
+ ASSERT (memcmp (buf, s, n) == 0);
+
+ /* Test special calling convention, passing a NULL pointer. */
+ ret = wcrtomb (NULL, wc, NULL);
+ ASSERT (ret == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ char buf[64];
+ size_t ret;
+
+ /* configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ /* Test NUL character. */
+ {
+ buf[0] = 'x';
+ ret = wcrtomb (buf, 0, NULL);
+ ASSERT (ret == 1);
+ ASSERT (buf[0] == '\0');
+ }
+
+ /* Test single bytes. */
+ {
+ int c;
+
+ for (c = 0; c < 0x100; c++)
+ switch (c)
+ {
+ case '\t': case '\v': case '\f':
+ case ' ': case '!': case '"': case '#': case '%':
+ case '&': case '\'': case '(': case ')': case '*':
+ case '+': case ',': case '-': case '.': case '/':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case ':': case ';': case '<': case '=': case '>':
+ case '?':
+ case 'A': case 'B': case 'C': case 'D': case 'E':
+ case 'F': case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'P': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y':
+ case 'Z':
+ case '[': case '\\': case ']': case '^': case '_':
+ case 'a': case 'b': case 'c': case 'd': case 'e':
+ case 'f': case 'g': case 'h': case 'i': case 'j':
+ case 'k': case 'l': case 'm': case 'n': case 'o':
+ case 'p': case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x': case 'y':
+ case 'z': case '{': case '|': case '}': case '~':
+ /* c is in the ISO C "basic character set". */
+ ret = wcrtomb (buf, btowc (c), NULL);
+ ASSERT (ret == 1);
+ ASSERT (buf[0] == (char) c);
+ break;
+ }
+ }
+
+ if (argc > 1)
+ switch (argv[1][0])
+ {
+ case '1':
+ /* Locale encoding is ISO-8859-1 or ISO-8859-15. */
+ {
+ const char input[] = "B\374\337er"; /* "Büßer" */
+
+ check_character (input + 1, 1);
+ check_character (input + 2, 1);
+ }
+ return 0;
+
+ case '2':
+ /* Locale encoding is UTF-8. */
+ {
+ const char input[] = "B\303\274\303\237er"; /* "Büßer" */
+
+ check_character (input + 1, 2);
+ check_character (input + 3, 2);
+ }
+ return 0;
+
+ case '3':
+ /* Locale encoding is EUC-JP. */
+ {
+ const char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */
+
+ check_character (input + 1, 2);
+ check_character (input + 3, 2);
+ check_character (input + 5, 2);
+ }
+ return 0;
+
+ case '4':
+ /* Locale encoding is GB18030. */
+ {
+ const char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
+
+ check_character (input + 1, 2);
+ check_character (input + 3, 4);
+ }
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/tests/gnu/test-wcrtomb.sh b/tests/gnu/test-wcrtomb.sh
new file mode 100755
index 00000000..3eda8f33
--- /dev/null
+++ b/tests/gnu/test-wcrtomb.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# Test in an ISO-8859-1 or ISO-8859-15 locale.
+: ${LOCALE_FR=fr_FR}
+if test $LOCALE_FR != none; then
+ LC_ALL=$LOCALE_FR \
+ ./test-wcrtomb${EXEEXT} 1 \
+ || exit 1
+fi
+
+# Test whether a specific UTF-8 locale is installed.
+: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
+if test $LOCALE_FR_UTF8 != none; then
+ LC_ALL=$LOCALE_FR_UTF8 \
+ ./test-wcrtomb${EXEEXT} 2 \
+ || exit 1
+fi
+
+# Test whether a specific EUC-JP locale is installed.
+: ${LOCALE_JA=ja_JP}
+if test $LOCALE_JA != none; then
+ LC_ALL=$LOCALE_JA \
+ ./test-wcrtomb${EXEEXT} 3 \
+ || exit 1
+fi
+
+# Test whether a specific GB18030 locale is installed.
+: ${LOCALE_ZH_CN=zh_CN.GB18030}
+if test $LOCALE_ZH_CN != none; then
+ LC_ALL=$LOCALE_ZH_CN \
+ ./test-wcrtomb${EXEEXT} 4 \
+ || exit 1
+fi
+
+exit 0
diff --git a/tests/gnu/test-wctype.c b/tests/gnu/test-wctype.c
new file mode 100755
index 00000000..49d7cfa0
--- /dev/null
+++ b/tests/gnu/test-wctype.c
@@ -0,0 +1,74 @@
+/* Test of <wctype.h> substitute.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <wctype.h>
+
+#include "macros.h"
+
+/* Check that the type wint_t is defined. */
+wint_t a = 'x';
+/* Check that WEOF is defined. */
+wint_t e = WEOF;
+
+int
+main (void)
+{
+ /* Check that the isw* functions exist as functions or as macros. */
+ (void) iswalnum (0);
+ (void) iswalpha (0);
+#if 0 /* not portable: missing on mingw */
+ (void) iswblank (0);
+#endif
+ (void) iswcntrl (0);
+ (void) iswdigit (0);
+ (void) iswgraph (0);
+ (void) iswlower (0);
+ (void) iswprint (0);
+ (void) iswpunct (0);
+ (void) iswspace (0);
+ (void) iswupper (0);
+ (void) iswxdigit (0);
+
+ /* Check that the isw* functions map WEOF to 0. */
+ ASSERT (!iswalnum (e));
+ ASSERT (!iswalpha (e));
+#if 0 /* not portable: missing on mingw */
+ ASSERT (!iswblank (e));
+#endif
+ ASSERT (!iswcntrl (e));
+ ASSERT (!iswdigit (e));
+ ASSERT (!iswgraph (e));
+ ASSERT (!iswlower (e));
+ ASSERT (!iswprint (e));
+ ASSERT (!iswpunct (e));
+ ASSERT (!iswspace (e));
+ ASSERT (!iswupper (e));
+ ASSERT (!iswxdigit (e));
+
+ /* Check that the tow* functions exist as functions or as macros. */
+ (void) towlower (0);
+ (void) towupper (0);
+
+ /* Check that the tow* functions map WEOF to WEOF. */
+ ASSERT (towlower (e) == e);
+ ASSERT (towupper (e) == e);
+
+ return 0;
+}
diff --git a/tests/gnu/test-wcwidth.c b/tests/gnu/test-wcwidth.c
new file mode 100755
index 00000000..f6f97924
--- /dev/null
+++ b/tests/gnu/test-wcwidth.c
@@ -0,0 +1,81 @@
+/* Test of wcwidth() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <wchar.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (wcwidth, int, (wchar_t));
+
+#include <locale.h>
+#include <string.h>
+
+#include "localcharset.h"
+#include "macros.h"
+
+int
+main ()
+{
+ wchar_t wc;
+
+ /* Test width of ASCII characters. */
+ for (wc = 0x20; wc < 0x7F; wc++)
+ ASSERT (wcwidth (wc) == 1);
+
+ /* Switch to an UTF-8 locale. */
+ if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL
+ /* Check whether it's really an UTF-8 locale.
+ On OpenBSD 4.0, the setlocale call succeeds only for the LC_CTYPE
+ category and therefore returns "C/fr_FR.UTF-8/C/C/C/C", but the
+ LC_CTYPE category is effectively set to an ASCII LC_CTYPE category;
+ in particular, locale_charset() returns "ASCII". */
+ && strcmp (locale_charset (), "UTF-8") == 0)
+ {
+ /* Test width of ASCII characters. */
+ for (wc = 0x20; wc < 0x7F; wc++)
+ ASSERT (wcwidth (wc) == 1);
+
+ /* Test width of some non-spacing characters. */
+ ASSERT (wcwidth (0x0301) == 0);
+ ASSERT (wcwidth (0x05B0) == 0);
+
+ /* Test width of some format control characters. */
+ ASSERT (wcwidth (0x200E) <= 0);
+ ASSERT (wcwidth (0x2060) <= 0);
+#if 0 /* wchar_t may be only 16 bits. */
+ ASSERT (wcwidth (0xE0001) <= 0);
+ ASSERT (wcwidth (0xE0044) <= 0);
+#endif
+
+ /* Test width of some zero width characters. */
+ ASSERT (wcwidth (0x200B) == 0);
+ ASSERT (wcwidth (0xFEFF) <= 0);
+
+ /* Test width of some CJK characters. */
+ ASSERT (wcwidth (0x3000) == 2);
+ ASSERT (wcwidth (0xB250) == 2);
+ ASSERT (wcwidth (0xFF1A) == 2);
+#if 0 /* wchar_t may be only 16 bits. */
+ ASSERT (wcwidth (0x20369) == 2);
+ ASSERT (wcwidth (0x2F876) == 2);
+#endif
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-xalloc-die.c b/tests/gnu/test-xalloc-die.c
new file mode 100755
index 00000000..67edd92d
--- /dev/null
+++ b/tests/gnu/test-xalloc-die.c
@@ -0,0 +1,30 @@
+/* Test of xalloc_die() function.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson <simon@josefsson.org>, 2009. */
+
+#include <config.h>
+
+#include "xalloc.h"
+#include "progname.h"
+
+int
+main (int argc _GL_UNUSED, char **argv)
+{
+ set_program_name (argv[0]);
+ xalloc_die ();
+ return 0;
+}
diff --git a/tests/gnu/test-xalloc-die.sh b/tests/gnu/test-xalloc-die.sh
new file mode 100755
index 00000000..80d6208d
--- /dev/null
+++ b/tests/gnu/test-xalloc-die.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# Test suite for xalloc_die.
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ .
+
+test-xalloc-die${EXEEXT} 2> err > out
+case $? in
+ 1) ;;
+ *) Exit 1;;
+esac
+
+tr -d '\015' < err \
+ | sed 's,.*test-xalloc-die[.ex]*:,test-xalloc-die:,' > err2 || Exit 1
+
+compare - err2 <<\EOF || Exit 1
+test-xalloc-die: memory exhausted
+EOF
+
+test -s out && Exit 1
+
+Exit $fail
diff --git a/tests/gnu/test-xfprintf-posix.c b/tests/gnu/test-xfprintf-posix.c
new file mode 100755
index 00000000..b8fc6ed2
--- /dev/null
+++ b/tests/gnu/test-xfprintf-posix.c
@@ -0,0 +1,40 @@
+/* Test of error-checking xfprintf() function with POSIX compatible formatting.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "xprintf.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "progname.h"
+#include "macros.h"
+
+#include "test-fprintf-posix.h"
+
+int
+main (int argc _GL_UNUSED, char *argv[])
+{
+ set_program_name (argv[0]);
+
+ test_function (xfprintf);
+ return 0;
+}
diff --git a/tests/gnu/test-xmemdup0.c b/tests/gnu/test-xmemdup0.c
new file mode 100755
index 00000000..eb93336f
--- /dev/null
+++ b/tests/gnu/test-xmemdup0.c
@@ -0,0 +1,82 @@
+/* Test of xmemdup0() function.
+ Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2008. */
+
+#include <config.h>
+
+#include "xmemdup0.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "progname.h"
+#include "macros.h"
+
+int
+main (int argc, char **argv)
+{
+ char buffer[10] = { 'a', 'b', 'c', 'd', '\0',
+ 'f', 'g', 'h', 'i', 'j' };
+
+ set_program_name (argv[0]);
+
+ /* Empty string. */
+ {
+ char *result = xmemdup0 (NULL, 0);
+ ASSERT (result);
+ ASSERT (!*result);
+ free (result);
+ }
+ {
+ char *result = xmemdup0 ("", 0);
+ ASSERT (result);
+ ASSERT (!*result);
+ free (result);
+ }
+
+ /* Various buffer lengths. */
+ {
+ char *result = xmemdup0 (buffer, 4);
+ ASSERT (result);
+ ASSERT (strcmp (result, buffer) == 0);
+ free (result);
+ }
+ {
+ char *result = xmemdup0 (buffer, 5);
+ ASSERT (result);
+ ASSERT (strcmp (result, buffer) == 0);
+ ASSERT (result[5] == '\0');
+ free (result);
+ }
+ {
+ char *result = xmemdup0 (buffer, 9);
+ ASSERT (result);
+ ASSERT (memcmp (result, buffer, 9) == 0);
+ ASSERT (result[9] == '\0');
+ free (result);
+ }
+ {
+ char *result = xmemdup0 (buffer, 10);
+ ASSERT (result);
+ ASSERT (memcmp (result, buffer, 10) == 0);
+ ASSERT (result[10] == '\0');
+ free (result);
+ }
+
+ return 0;
+}
diff --git a/tests/gnu/test-xprintf-posix.c b/tests/gnu/test-xprintf-posix.c
new file mode 100755
index 00000000..c907356f
--- /dev/null
+++ b/tests/gnu/test-xprintf-posix.c
@@ -0,0 +1,39 @@
+/* Test of error-checking xprintf() function with POSIX compatible formatting.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "xprintf.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "progname.h"
+#include "macros.h"
+
+#include "test-printf-posix.h"
+
+int
+main (int argc _GL_UNUSED, char *argv[])
+{
+ set_program_name (argv[0]);
+
+ test_function (xprintf);
+ return 0;
+}
diff --git a/tests/gnu/test-xprintf-posix.sh b/tests/gnu/test-xprintf-posix.sh
new file mode 100755
index 00000000..0087a9d4
--- /dev/null
+++ b/tests/gnu/test-xprintf-posix.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles t-xprintf-posix.tmp t-xprintf-posix.out"
+./test-xprintf-posix${EXEEXT} > t-xprintf-posix.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-xprintf-posix.tmp > t-xprintf-posix.out || exit 1
+
+: ${DIFF=diff}
+${DIFF} "${srcdir}/test-printf-posix.output" t-xprintf-posix.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+tmpfiles="$tmpfiles t-xfprintf-posix.tmp t-xfprintf-posix.out"
+./test-xfprintf-posix${EXEEXT} > t-xfprintf-posix.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-xfprintf-posix.tmp > t-xfprintf-posix.out || exit 1
+
+: ${DIFF=diff}
+${DIFF} "${srcdir}/test-printf-posix.output" t-xfprintf-posix.out
+test $? = 0 || { rm -fr $tmpfiles; exit 1; }
+
+rm -fr $tmpfiles
+
+exit 0
diff --git a/tests/gnu/test-xvasprintf.c b/tests/gnu/test-xvasprintf.c
new file mode 100755
index 00000000..df6c2009
--- /dev/null
+++ b/tests/gnu/test-xvasprintf.c
@@ -0,0 +1,129 @@
+/* Test of xvasprintf() and xasprintf() functions.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "xvasprintf.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "progname.h"
+#include "macros.h"
+
+static char *
+my_xasprintf (const char *format, ...)
+{
+ va_list args;
+ char *ret;
+
+ va_start (args, format);
+ ret = xvasprintf (format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_xvasprintf (void)
+{
+ int repeat;
+ char *result;
+
+ for (repeat = 0; repeat <= 8; repeat++)
+ {
+ result = my_xasprintf ("%d", 12345);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ free (result);
+ }
+
+ {
+ /* Silence gcc warning about zero-length format string. */
+ char *empty = "";
+ result = my_xasprintf (empty);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "") == 0);
+ free (result);
+ }
+
+ result = my_xasprintf ("%s", "foo");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "foo") == 0);
+ free (result);
+
+ result = my_xasprintf ("%s%s", "foo", "bar");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "foobar") == 0);
+ free (result);
+
+ result = my_xasprintf ("%s%sbaz", "foo", "bar");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "foobarbaz") == 0);
+ free (result);
+}
+
+static void
+test_xasprintf ()
+{
+ int repeat;
+ char *result;
+
+ for (repeat = 0; repeat <= 8; repeat++)
+ {
+ result = xasprintf ("%d", 12345);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "12345") == 0);
+ free (result);
+ }
+
+ {
+ /* Silence gcc warning about zero-length format string. */
+ char *empty = "";
+ result = xasprintf (empty);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "") == 0);
+ free (result);
+ }
+
+ result = xasprintf ("%s", "foo");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "foo") == 0);
+ free (result);
+
+ result = xasprintf ("%s%s", "foo", "bar");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "foobar") == 0);
+ free (result);
+
+ result = my_xasprintf ("%s%sbaz", "foo", "bar");
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "foobarbaz") == 0);
+ free (result);
+}
+
+int
+main (int argc _GL_UNUSED, char *argv[])
+{
+ set_program_name (argv[0]);
+
+ test_xvasprintf ();
+ test_xasprintf ();
+
+ return 0;
+}
diff --git a/tests/gnu/uniwidth/test-uc_width.c b/tests/gnu/uniwidth/test-uc_width.c
new file mode 100755
index 00000000..7cfab614
--- /dev/null
+++ b/tests/gnu/uniwidth/test-uc_width.c
@@ -0,0 +1,56 @@
+/* Test of uc_width() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include "uniwidth.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+ ucs4_t uc;
+
+ /* Test width of ASCII characters. */
+ for (uc = 0x0020; uc < 0x007F; uc++)
+ ASSERT (uc_width (uc, "ISO-8859-2") == 1);
+
+ /* Test width of some non-spacing characters. */
+ ASSERT (uc_width (0x0301, "UTF-8") == 0);
+ ASSERT (uc_width (0x05B0, "UTF-8") == 0);
+
+ /* Test width of some format control characters. */
+ ASSERT (uc_width (0x200E, "UTF-8") == 0);
+ ASSERT (uc_width (0x2060, "UTF-8") == 0);
+ ASSERT (uc_width (0xE0001, "UTF-8") == 0);
+ ASSERT (uc_width (0xE0044, "UTF-8") == 0);
+
+ /* Test width of some zero width characters. */
+ ASSERT (uc_width (0x200B, "UTF-8") == 0);
+ ASSERT (uc_width (0xFEFF, "UTF-8") == 0);
+
+ /* Test width of some CJK characters. */
+ ASSERT (uc_width (0x3000, "UTF-8") == 2);
+ ASSERT (uc_width (0xB250, "UTF-8") == 2);
+ ASSERT (uc_width (0xFF1A, "UTF-8") == 2);
+ ASSERT (uc_width (0x20369, "UTF-8") == 2);
+ ASSERT (uc_width (0x2F876, "UTF-8") == 2);
+
+ return 0;
+}
diff --git a/tests/gnu/uniwidth/test-uc_width2.c b/tests/gnu/uniwidth/test-uc_width2.c
new file mode 100755
index 00000000..3126d4c3
--- /dev/null
+++ b/tests/gnu/uniwidth/test-uc_width2.c
@@ -0,0 +1,86 @@
+/* Test of uc_width() function.
+ Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+
+#include <config.h>
+
+#include "uniwidth.h"
+
+#include <stdio.h>
+
+#include "macros.h"
+
+/* One of 0, '0', '1', 'A', '2'. */
+static char current_width;
+/* The interval for which the current_width holds. */
+static ucs4_t current_start;
+static ucs4_t current_end;
+
+static void
+finish_interval (void)
+{
+ if (current_width != 0)
+ {
+ if (current_start == current_end)
+ printf ("%04X\t\t%c\n", (unsigned) current_start, current_width);
+ else
+ printf ("%04X..%04X\t%c\n", (unsigned) current_start,
+ (unsigned) current_end, current_width);
+ current_width = 0;
+ }
+}
+
+static void
+add_to_interval (ucs4_t uc, char width)
+{
+ if (current_width == width && uc == current_end + 1)
+ current_end = uc;
+ else
+ {
+ finish_interval ();
+ current_width = width;
+ current_start = current_end = uc;
+ }
+}
+
+int
+main ()
+{
+ ucs4_t uc;
+
+ for (uc = 0; uc < 0x110000; uc++)
+ {
+ int w1 = uc_width (uc, "UTF-8");
+ int w2 = uc_width (uc, "GBK");
+ char width =
+ (w1 == 0 && w2 == 0 ? '0' :
+ w1 == 1 && w2 == 1 ? '1' :
+ w1 == 1 && w2 == 2 ? 'A' :
+ w1 == 2 && w2 == 2 ? '2' :
+ 0);
+ if (width == 0)
+ {
+ /* uc must be a control character. */
+ ASSERT (w1 < 0 && w2 < 0);
+ }
+ else
+ add_to_interval (uc, width);
+ }
+ finish_interval ();
+
+ return 0;
+}
diff --git a/tests/gnu/uniwidth/test-uc_width2.sh b/tests/gnu/uniwidth/test-uc_width2.sh
new file mode 100755
index 00000000..484288c9
--- /dev/null
+++ b/tests/gnu/uniwidth/test-uc_width2.sh
@@ -0,0 +1,382 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles uc_width.out"
+./test-uc_width2${EXEEXT} | LC_ALL=C tr -d '\r' > uc_width.out
+
+tmpfiles="$tmpfiles uc_width.ok"
+cat > uc_width.ok <<\EOF
+0000 0
+0020..007E 1
+00A0 1
+00A1..00AC A
+00AD 0
+00AE..02FF A
+0300..036F 0
+0370..0482 A
+0483..0489 0
+048A..0590 A
+0591..05BD 0
+05BE A
+05BF 0
+05C0 A
+05C1..05C2 0
+05C3 A
+05C4..05C5 0
+05C6 A
+05C7 0
+05C8..05FF A
+0600..0603 0
+0604..060F A
+0610..061A 0
+061B..064A A
+064B..065E 0
+065F..066F A
+0670 0
+0671..06D5 A
+06D6..06E4 0
+06E5..06E6 A
+06E7..06E8 0
+06E9 A
+06EA..06ED 0
+06EE..070E A
+070F 0
+0710 A
+0711 0
+0712..072F A
+0730..074A 0
+074B..07A5 A
+07A6..07B0 0
+07B1..07EA A
+07EB..07F3 0
+07F4..0900 A
+0901..0902 0
+0903..093B A
+093C 0
+093D..0940 A
+0941..0948 0
+0949..094C A
+094D 0
+094E..0950 A
+0951..0954 0
+0955..0961 A
+0962..0963 0
+0964..0980 A
+0981 0
+0982..09BB A
+09BC 0
+09BD..09C0 A
+09C1..09C4 0
+09C5..09CC A
+09CD 0
+09CE..09E1 A
+09E2..09E3 0
+09E4..0A00 A
+0A01..0A02 0
+0A03..0A3B A
+0A3C 0
+0A3D..0A40 A
+0A41..0A42 0
+0A43..0A46 A
+0A47..0A48 0
+0A49..0A4A A
+0A4B..0A4D 0
+0A4E..0A50 A
+0A51 0
+0A52..0A6F A
+0A70..0A71 0
+0A72..0A74 A
+0A75 0
+0A76..0A80 A
+0A81..0A82 0
+0A83..0ABB A
+0ABC 0
+0ABD..0AC0 A
+0AC1..0AC5 0
+0AC6 A
+0AC7..0AC8 0
+0AC9..0ACC A
+0ACD 0
+0ACE..0AE1 A
+0AE2..0AE3 0
+0AE4..0B00 A
+0B01 0
+0B02..0B3B A
+0B3C 0
+0B3D..0B3E A
+0B3F 0
+0B40 A
+0B41..0B44 0
+0B45..0B4C A
+0B4D 0
+0B4E..0B55 A
+0B56 0
+0B57..0B61 A
+0B62..0B63 0
+0B64..0B81 A
+0B82 0
+0B83..0BBF A
+0BC0 0
+0BC1..0BCC A
+0BCD 0
+0BCE..0C3D A
+0C3E..0C40 0
+0C41..0C45 A
+0C46..0C48 0
+0C49 A
+0C4A..0C4D 0
+0C4E..0C54 A
+0C55..0C56 0
+0C57..0C61 A
+0C62..0C63 0
+0C64..0CBB A
+0CBC 0
+0CBD..0CCB A
+0CCC..0CCD 0
+0CCE..0CE1 A
+0CE2..0CE3 0
+0CE4..0D40 A
+0D41..0D44 0
+0D45..0D4C A
+0D4D 0
+0D4E..0D61 A
+0D62..0D63 0
+0D64..0DC9 A
+0DCA 0
+0DCB..0DD1 A
+0DD2..0DD4 0
+0DD5 A
+0DD6 0
+0DD7..0E30 A
+0E31 0
+0E32..0E33 A
+0E34..0E3A 0
+0E3B..0E46 A
+0E47..0E4E 0
+0E4F..0EB0 A
+0EB1 0
+0EB2..0EB3 A
+0EB4..0EB9 0
+0EBA A
+0EBB..0EBC 0
+0EBD..0EC7 A
+0EC8..0ECD 0
+0ECE..0F17 A
+0F18..0F19 0
+0F1A..0F34 A
+0F35 0
+0F36 A
+0F37 0
+0F38 A
+0F39 0
+0F3A..0F70 A
+0F71..0F7E 0
+0F7F A
+0F80..0F84 0
+0F85 A
+0F86..0F87 0
+0F88..0F8F A
+0F90..0F97 0
+0F98 A
+0F99..0FBC 0
+0FBD..0FC5 A
+0FC6 0
+0FC7..102C A
+102D..1030 0
+1031 A
+1032..1037 0
+1038 A
+1039..103A 0
+103B..103C A
+103D..103E 0
+103F..1057 A
+1058..1059 0
+105A..105D A
+105E..1060 0
+1061..1070 A
+1071..1074 0
+1075..1081 A
+1082 0
+1083..1084 A
+1085..1086 0
+1087..108C A
+108D 0
+108E..10FF A
+1100..115F 2
+1160..135E A
+135F 0
+1360..1711 A
+1712..1714 0
+1715..1731 A
+1732..1734 0
+1735..1751 A
+1752..1753 0
+1754..1771 A
+1772..1773 0
+1774..17B3 A
+17B4..17B5 0
+17B6 A
+17B7..17BD 0
+17BE..17C5 A
+17C6 0
+17C7..17C8 A
+17C9..17D3 0
+17D4..17DC A
+17DD 0
+17DE..180A A
+180B..180D 0
+180E..18A8 A
+18A9 0
+18AA..191F A
+1920..1922 0
+1923..1926 A
+1927..1928 0
+1929..1931 A
+1932 0
+1933..1938 A
+1939..193B 0
+193C..1A16 A
+1A17..1A18 0
+1A19..1AFF A
+1B00..1B03 0
+1B04..1B33 A
+1B34 0
+1B35 A
+1B36..1B3A 0
+1B3B A
+1B3C 0
+1B3D..1B41 A
+1B42 0
+1B43..1B6A A
+1B6B..1B73 0
+1B74..1B7F A
+1B80..1B81 0
+1B82..1BA1 A
+1BA2..1BA5 0
+1BA6..1BA7 A
+1BA8..1BA9 0
+1BAA..1C2B A
+1C2C..1C33 0
+1C34..1C35 A
+1C36..1C37 0
+1C38..1DBF A
+1DC0..1DE6 0
+1DE7..1DFD A
+1DFE..1DFF 0
+1E00..200A A
+200B..200F 0
+2010..2029 A
+202A..202E 0
+202F..205F A
+2060..2064 0
+2065..2069 A
+206A..206F 0
+2070..20A8 A
+20A9 1
+20AA..20CF A
+20D0..20F0 0
+20F1..2328 A
+2329..232A 2
+232B..2DDF A
+2DE0..2DFF 0
+2E00..2E7F A
+2E80..3029 2
+302A..302F 0
+3030..303E 2
+303F A
+3040..3098 2
+3099..309A 0
+309B..4DBF 2
+4DC0..4DFF A
+4E00..A4CF 2
+A4D0..A66E A
+A66F..A672 0
+A673..A67B A
+A67C..A67D 0
+A67E..A801 A
+A802 0
+A803..A805 A
+A806 0
+A807..A80A A
+A80B 0
+A80C..A824 A
+A825..A826 0
+A827..A8C3 A
+A8C4 0
+A8C5..A925 A
+A926..A92D 0
+A92E..A946 A
+A947..A951 0
+A952..AA28 A
+AA29..AA2E 0
+AA2F..AA30 A
+AA31..AA32 0
+AA33..AA34 A
+AA35..AA36 0
+AA37..AA42 A
+AA43 0
+AA44..AA4B A
+AA4C 0
+AA4D..ABFF A
+AC00..D7A3 2
+D7A4..F8FF A
+F900..FAFF 2
+FB00..FB1D A
+FB1E 0
+FB1F..FDFF A
+FE00..FE0F 0
+FE10..FE1F 2
+FE20..FE26 0
+FE27..FE2F A
+FE30..FE6F 2
+FE70..FEFE A
+FEFF 0
+FF00..FF60 2
+FF61..FFDF 1
+FFE0..FFE6 2
+FFE7..FFF8 1
+FFF9..FFFB 0
+FFFC..101FC 1
+101FD 0
+101FE..10A00 1
+10A01..10A03 0
+10A04 1
+10A05..10A06 0
+10A07..10A0B 1
+10A0C..10A0F 0
+10A10..10A37 1
+10A38..10A3A 0
+10A3B..10A3E 1
+10A3F 0
+10A40..1D166 1
+1D167..1D169 0
+1D16A..1D17A 1
+1D17B..1D182 0
+1D183..1D184 1
+1D185..1D18B 0
+1D18C..1D1A9 1
+1D1AA..1D1AD 0
+1D1AE..1D241 1
+1D242..1D244 0
+1D245..1FFFF 1
+20000..2A6D6 2
+2A6D7..2F7FF 1
+2F800..2FA1D 2
+2FA1E..E0000 1
+E0001 0
+E0002..E001F 1
+E0020..E007F 0
+E0080..E00FF 1
+E0100..E01EF 0
+E01F0..10FFFF 1
+EOF
+
+: ${DIFF=diff}
+${DIFF} uc_width.ok uc_width.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
diff --git a/tests/gnu/wctob.c b/tests/gnu/wctob.c
new file mode 100755
index 00000000..1d1cc7b1
--- /dev/null
+++ b/tests/gnu/wctob.c
@@ -0,0 +1,37 @@
+/* Convert wide character to unibyte character.
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2008.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <wchar.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+wctob (wint_t wc)
+{
+ char buf[64];
+
+ if (!(MB_CUR_MAX <= sizeof (buf)))
+ abort ();
+ if (wctomb (buf, wc) == 1)
+ return (unsigned char) buf[0];
+ else
+ return EOF;
+}
diff --git a/tests/gnu/zerosize-ptr.h b/tests/gnu/zerosize-ptr.h
new file mode 100755
index 00000000..cfab2008
--- /dev/null
+++ b/tests/gnu/zerosize-ptr.h
@@ -0,0 +1,68 @@
+/* Return a pointer to a zero-size object in memory.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* ISO C 99 does not allow memcmp(), memchr() etc. to be invoked with a NULL
+ argument. Therefore this file produces a non-NULL pointer which cannot
+ be dereferenced, if possible. */
+
+#include <stdlib.h>
+
+/* Test whether mmap() and mprotect() are available.
+ We don't use HAVE_MMAP, because AC_FUNC_MMAP would not define it on HP-UX.
+ HAVE_MPROTECT is not enough, because mingw does not have mmap() but has an
+ mprotect() function in libgcc.a. */
+#if HAVE_SYS_MMAN_H && HAVE_MPROTECT
+# include <fcntl.h>
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/mman.h>
+/* Define MAP_FILE when it isn't otherwise. */
+# ifndef MAP_FILE
+# define MAP_FILE 0
+# endif
+#endif
+
+/* Return a pointer to a zero-size object in memory (that is, actually, a
+ pointer to a page boundary where the previous page is readable and writable
+ and the next page is neither readable not writable), if possible.
+ Return NULL otherwise. */
+
+static void *
+zerosize_ptr (void)
+{
+/* Use mmap and mprotect when they exist. Don't test HAVE_MMAP, because it is
+ not defined on HP-UX 11 (since it does not support MAP_FIXED). */
+#if HAVE_SYS_MMAN_H && HAVE_MPROTECT
+# if HAVE_MAP_ANONYMOUS
+ const int flags = MAP_ANONYMOUS | MAP_PRIVATE;
+ const int fd = -1;
+# else /* !HAVE_MAP_ANONYMOUS */
+ const int flags = MAP_FILE | MAP_PRIVATE;
+ int fd = open ("/dev/zero", O_RDONLY, 0666);
+ if (fd >= 0)
+# endif
+ {
+ int pagesize = getpagesize ();
+ char *two_pages =
+ (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,
+ flags, fd, 0);
+ if (two_pages != (char *)(-1)
+ && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)
+ return two_pages + pagesize;
+ }
+#endif
+ return NULL;
+}