summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am20
-rw-r--r--tests/Makefile.in3740
-rw-r--r--tests/c-strcase.h56
-rw-r--r--tests/c-strcasecmp.c57
-rw-r--r--tests/c-strncasecmp.c57
-rw-r--r--tests/ftell.c38
-rw-r--r--tests/getpagesize.c39
-rw-r--r--tests/gl_array_list.c680
-rw-r--r--tests/gl_array_list.h34
-rw-r--r--tests/gl_array_oset.c357
-rw-r--r--tests/gl_array_oset.h34
-rw-r--r--tests/gnulib.mk1400
-rw-r--r--tests/init.sh474
-rw-r--r--tests/link.c203
-rw-r--r--tests/locale.in.h96
-rw-r--r--tests/localename.c2959
-rw-r--r--tests/localename.h97
-rw-r--r--tests/macros.h64
-rw-r--r--tests/minus-zero.h74
-rw-r--r--tests/nan.h60
-rw-r--r--tests/putenv.c132
-rw-r--r--tests/setenv.c390
-rw-r--r--tests/setlocale.c938
-rw-r--r--tests/signature.h48
-rw-r--r--tests/strdup.c55
-rw-r--r--tests/symlink.c57
-rw-r--r--tests/test-alloca-opt.c62
-rw-r--r--tests/test-array_list.c329
-rw-r--r--tests/test-array_oset.c144
-rw-r--r--tests/test-avltree_oset.c136
-rw-r--r--tests/test-binary-io.c64
-rwxr-xr-xtests/test-binary-io.sh11
-rw-r--r--tests/test-btowc.c63
-rwxr-xr-xtests/test-btowc1.sh15
-rwxr-xr-xtests/test-btowc2.sh15
-rw-r--r--tests/test-c-ctype.c386
-rw-r--r--tests/test-c-stack.c76
-rwxr-xr-xtests/test-c-stack.sh21
-rwxr-xr-xtests/test-c-stack2.sh36
-rwxr-xr-xtests/test-c-strcase.sh21
-rw-r--r--tests/test-c-strcasecmp.c65
-rw-r--r--tests/test-c-strncasecmp.c79
-rw-r--r--tests/test-canonicalize-lgpl.c222
-rw-r--r--tests/test-cloexec.c141
-rw-r--r--tests/test-closein.c53
-rwxr-xr-xtests/test-closein.sh38
-rw-r--r--tests/test-dirname.c191
-rw-r--r--tests/test-dup-safer.c172
-rw-r--r--tests/test-dup2.c198
-rw-r--r--tests/test-environ.c44
-rw-r--r--tests/test-errno.c117
-rw-r--r--tests/test-fcntl-h-c++.cc43
-rw-r--r--tests/test-fcntl-h.c38
-rw-r--r--tests/test-fcntl.c341
-rw-r--r--tests/test-fflush.c145
-rw-r--r--tests/test-fflush2.c108
-rwxr-xr-xtests/test-fflush2.sh9
-rw-r--r--tests/test-filenamecat.c66
-rw-r--r--tests/test-fopen-safer.c31
-rw-r--r--tests/test-fopen.c34
-rw-r--r--tests/test-fopen.h73
-rw-r--r--tests/test-fpending.c41
-rwxr-xr-xtests/test-fpending.sh12
-rw-r--r--tests/test-fpurge.c134
-rw-r--r--tests/test-freadahead.c73
-rwxr-xr-xtests/test-freadahead.sh5
-rw-r--r--tests/test-freading.c130
-rw-r--r--tests/test-frexp.c196
-rw-r--r--tests/test-frexpl.c208
-rw-r--r--tests/test-fseeko.c74
-rwxr-xr-xtests/test-fseeko.sh5
-rwxr-xr-xtests/test-fseeko2.sh3
-rw-r--r--tests/test-ftell.c107
-rwxr-xr-xtests/test-ftell.sh5
-rwxr-xr-xtests/test-ftell2.sh3
-rw-r--r--tests/test-ftell3.c78
-rw-r--r--tests/test-ftello.c118
-rwxr-xr-xtests/test-ftello.sh5
-rwxr-xr-xtests/test-ftello2.sh3
-rw-r--r--tests/test-ftello3.c78
-rw-r--r--tests/test-getdtablesize.c34
-rw-r--r--tests/test-getopt.c99
-rw-r--r--tests/test-getopt.h1369
-rw-r--r--tests/test-getopt_long.h2125
-rw-r--r--tests/test-gettimeofday.c47
-rw-r--r--tests/test-ignore-value.c84
-rw-r--r--tests/test-isnand-nolibm.c22
-rw-r--r--tests/test-isnand.h62
-rw-r--r--tests/test-isnanf-nolibm.c21
-rw-r--r--tests/test-isnanf.h64
-rw-r--r--tests/test-isnanl-nolibm.c23
-rw-r--r--tests/test-isnanl.h126
-rw-r--r--tests/test-langinfo-c++.cc35
-rw-r--r--tests/test-langinfo.c92
-rw-r--r--tests/test-link.c47
-rw-r--r--tests/test-link.h176
-rw-r--r--tests/test-linkedhash_list.c441
-rw-r--r--tests/test-locale-c++.cc39
-rw-r--r--tests/test-locale-c++2.cc20
-rw-r--r--tests/test-locale.c49
-rw-r--r--tests/test-localename.c747
-rw-r--r--tests/test-lseek.c96
-rwxr-xr-xtests/test-lseek.sh18
-rw-r--r--tests/test-lstat.c60
-rw-r--r--tests/test-lstat.h116
-rw-r--r--tests/test-malloc-gnu.c29
-rw-r--r--tests/test-malloca.c62
-rw-r--r--tests/test-math-c++.cc163
-rw-r--r--tests/test-math-c++2.cc20
-rw-r--r--tests/test-math.c53
-rwxr-xr-xtests/test-mbrtowc-w32-1.sh4
-rwxr-xr-xtests/test-mbrtowc-w32-2.sh4
-rwxr-xr-xtests/test-mbrtowc-w32-3.sh4
-rwxr-xr-xtests/test-mbrtowc-w32-4.sh4
-rwxr-xr-xtests/test-mbrtowc-w32-5.sh4
-rw-r--r--tests/test-mbrtowc-w32.c735
-rw-r--r--tests/test-mbrtowc.c343
-rwxr-xr-xtests/test-mbrtowc1.sh15
-rwxr-xr-xtests/test-mbrtowc2.sh15
-rwxr-xr-xtests/test-mbrtowc3.sh15
-rwxr-xr-xtests/test-mbrtowc4.sh15
-rw-r--r--tests/test-mbsinit.c55
-rwxr-xr-xtests/test-mbsinit.sh15
-rw-r--r--tests/test-memchr.c132
-rw-r--r--tests/test-memchr2.c100
-rw-r--r--tests/test-nl_langinfo.c126
-rwxr-xr-xtests/test-nl_langinfo.sh17
-rw-r--r--tests/test-open.c41
-rw-r--r--tests/test-open.h87
-rw-r--r--tests/test-pipe2.c145
-rw-r--r--tests/test-posix_spawn1.c166
-rw-r--r--tests/test-posix_spawn1.in.sh2
-rw-r--r--tests/test-posix_spawn2.c139
-rw-r--r--tests/test-posix_spawn2.in.sh3
-rw-r--r--tests/test-printf-frexp.c119
-rw-r--r--tests/test-printf-frexpl.c134
-rw-r--r--tests/test-quotearg-simple.c294
-rw-r--r--tests/test-quotearg.h133
-rw-r--r--tests/test-rawmemchr.c92
-rw-r--r--tests/test-readlink.c48
-rw-r--r--tests/test-readlink.h119
-rw-r--r--tests/test-rename.c47
-rw-r--r--tests/test-rename.h949
-rw-r--r--tests/test-rmdir.c47
-rw-r--r--tests/test-rmdir.h101
-rw-r--r--tests/test-sched.c38
-rw-r--r--tests/test-setenv.c56
-rw-r--r--tests/test-setlocale1.c59
-rwxr-xr-xtests/test-setlocale1.sh34
-rw-r--r--tests/test-setlocale2.c55
-rwxr-xr-xtests/test-setlocale2.sh15
-rw-r--r--tests/test-sigaction.c122
-rw-r--r--tests/test-signal-c++.cc51
-rw-r--r--tests/test-signal-c++2.cc20
-rw-r--r--tests/test-signal.c129
-rw-r--r--tests/test-signbit.c176
-rw-r--r--tests/test-snprintf.c64
-rw-r--r--tests/test-spawn-c++.cc139
-rw-r--r--tests/test-spawn-pipe.c204
-rwxr-xr-xtests/test-spawn-pipe.sh8
-rw-r--r--tests/test-spawn.c54
-rw-r--r--tests/test-stat.c56
-rw-r--r--tests/test-stat.h100
-rw-r--r--tests/test-stdbool.c118
-rw-r--r--tests/test-stddef.c52
-rw-r--r--tests/test-stdint.c361
-rw-r--r--tests/test-stdio-c++.cc191
-rw-r--r--tests/test-stdio-c++2.cc20
-rw-r--r--tests/test-stdio.c43
-rw-r--r--tests/test-stdlib-c++.cc163
-rw-r--r--tests/test-stdlib-c++2.cc20
-rw-r--r--tests/test-stdlib.c54
-rw-r--r--tests/test-strchrnul.c86
-rw-r--r--tests/test-strerror.c57
-rw-r--r--tests/test-string-c++.cc146
-rw-r--r--tests/test-string-c++2.cc20
-rw-r--r--tests/test-string.c33
-rw-r--r--tests/test-strnlen.c68
-rw-r--r--tests/test-strsignal.c78
-rw-r--r--tests/test-strstr.c277
-rw-r--r--tests/test-strtod.c986
-rw-r--r--tests/test-symlink.c47
-rw-r--r--tests/test-symlink.h95
-rw-r--r--tests/test-sys_stat-c++.cc88
-rw-r--r--tests/test-sys_stat.c288
-rw-r--r--tests/test-sys_time-c++.cc36
-rw-r--r--tests/test-sys_time.c29
-rw-r--r--tests/test-sys_wait-c++.cc35
-rw-r--r--tests/test-sys_wait.c47
-rw-r--r--tests/test-sys_wait.h53
-rw-r--r--tests/test-time-c++.cc57
-rw-r--r--tests/test-time-c++2.cc20
-rw-r--r--tests/test-time.c35
-rw-r--r--tests/test-unistd-c++.cc203
-rw-r--r--tests/test-unistd.c56
-rw-r--r--tests/test-unsetenv.c61
-rwxr-xr-xtests/test-update-copyright.sh537
-rw-r--r--tests/test-vasnprintf.c94
-rw-r--r--tests/test-vasprintf-posix.c3663
-rw-r--r--tests/test-vasprintf.c103
-rwxr-xr-xtests/test-vc-list-files-cvs.sh54
-rwxr-xr-xtests/test-vc-list-files-git.sh42
-rw-r--r--tests/test-verify.c69
-rwxr-xr-xtests/test-verify.sh24
-rw-r--r--tests/test-version-etc.c33
-rwxr-xr-xtests/test-version-etc.sh43
-rw-r--r--tests/test-wchar-c++.cc218
-rw-r--r--tests/test-wchar.c37
-rwxr-xr-xtests/test-wcrtomb-w32-1.sh4
-rwxr-xr-xtests/test-wcrtomb-w32-2.sh4
-rwxr-xr-xtests/test-wcrtomb-w32-3.sh4
-rwxr-xr-xtests/test-wcrtomb-w32-4.sh4
-rwxr-xr-xtests/test-wcrtomb-w32-5.sh4
-rw-r--r--tests/test-wcrtomb-w32.c332
-rw-r--r--tests/test-wcrtomb.c162
-rwxr-xr-xtests/test-wcrtomb.sh35
-rw-r--r--tests/test-wctype-h-c++.cc65
-rw-r--r--tests/test-wctype-h.c74
-rw-r--r--tests/test-xalloc-die.c30
-rwxr-xr-xtests/test-xalloc-die.sh36
-rw-r--r--tests/test-xvasprintf.c129
-rw-r--r--tests/unsetenv.c120
-rw-r--r--tests/wctob.c38
-rw-r--r--tests/wctomb-impl.h34
-rw-r--r--tests/wctomb.c25
-rw-r--r--tests/zerosize-ptr.h68
226 files changed, 39020 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..669f296
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,20 @@
+## Makefile.am - template for generating Makefile via Automake
+##
+## Copyright (C) 2009-2011 Free Software Foundation, Inc.
+##
+## This file is part of GNU M4.
+##
+## GNU M4 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.
+##
+## GNU M4 is distributed in the hope that 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 gnulib.mk
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..af0d2b3
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,3740 @@
+# 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-2011 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@
+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@
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/gnulib.mk
+TESTS = test-alloca-opt$(EXEEXT) test-array_list$(EXEEXT) \
+ test-array_oset$(EXEEXT) test-avltree_oset$(EXEEXT) \
+ test-binary-io.sh test-btowc1.sh test-btowc2.sh \
+ test-c-ctype$(EXEEXT) test-c-stack.sh test-c-stack2.sh \
+ 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) \
+ $(am__EXEEXT_1) 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-frexp-nolibm$(EXEEXT) test-frexpl-nolibm$(EXEEXT) \
+ test-fseeko.sh test-fseeko2.sh test-ftell.sh test-ftell2.sh \
+ test-ftell3$(EXEEXT) test-ftello.sh test-ftello2.sh \
+ test-ftello3$(EXEEXT) test-getdtablesize$(EXEEXT) \
+ test-getopt$(EXEEXT) test-gettimeofday$(EXEEXT) \
+ test-ignore-value$(EXEEXT) test-isnand-nolibm$(EXEEXT) \
+ test-isnanf-nolibm$(EXEEXT) test-isnanl-nolibm$(EXEEXT) \
+ $(am__EXEEXT_2) test-langinfo$(EXEEXT) test-link$(EXEEXT) \
+ test-linkedhash_list$(EXEEXT) $(am__EXEEXT_3) \
+ test-locale$(EXEEXT) test-localename$(EXEEXT) test-lseek.sh \
+ test-lstat$(EXEEXT) test-malloc-gnu$(EXEEXT) \
+ test-malloca$(EXEEXT) $(am__EXEEXT_4) test-math$(EXEEXT) \
+ test-mbrtowc1.sh test-mbrtowc2.sh test-mbrtowc3.sh \
+ test-mbrtowc4.sh test-mbrtowc-w32-1.sh test-mbrtowc-w32-2.sh \
+ test-mbrtowc-w32-3.sh test-mbrtowc-w32-4.sh \
+ test-mbrtowc-w32-5.sh test-mbsinit.sh test-memchr$(EXEEXT) \
+ test-memchr2$(EXEEXT) test-nl_langinfo.sh test-open$(EXEEXT) \
+ test-pipe2$(EXEEXT) $(am__EXEEXT_5) test-printf-frexp$(EXEEXT) \
+ test-printf-frexpl$(EXEEXT) test-quotearg-simple$(EXEEXT) \
+ test-rawmemchr$(EXEEXT) test-readlink$(EXEEXT) \
+ test-rename$(EXEEXT) test-rmdir$(EXEEXT) test-sched$(EXEEXT) \
+ test-setenv$(EXEEXT) test-setlocale1.sh test-setlocale2.sh \
+ test-sigaction$(EXEEXT) $(am__EXEEXT_6) test-signal$(EXEEXT) \
+ test-signbit$(EXEEXT) test-snprintf$(EXEEXT) $(am__EXEEXT_7) \
+ test-spawn-pipe.sh test-spawn$(EXEEXT) test-stat$(EXEEXT) \
+ test-stdbool$(EXEEXT) test-stddef$(EXEEXT) \
+ test-stdint$(EXEEXT) $(am__EXEEXT_8) test-stdio$(EXEEXT) \
+ $(am__EXEEXT_9) test-stdlib$(EXEEXT) test-strchrnul$(EXEEXT) \
+ test-strerror$(EXEEXT) $(am__EXEEXT_10) test-string$(EXEEXT) \
+ test-strnlen$(EXEEXT) test-strsignal$(EXEEXT) \
+ test-strstr$(EXEEXT) test-strtod$(EXEEXT) \
+ test-symlink$(EXEEXT) $(am__EXEEXT_11) test-sys_stat$(EXEEXT) \
+ $(am__EXEEXT_12) test-sys_time$(EXEEXT) $(am__EXEEXT_13) \
+ test-sys_wait$(EXEEXT) $(am__EXEEXT_14) test-time$(EXEEXT) \
+ $(am__EXEEXT_15) test-dup-safer$(EXEEXT) test-unistd$(EXEEXT) \
+ test-unsetenv$(EXEEXT) test-update-copyright.sh \
+ test-vasnprintf$(EXEEXT) test-vasprintf-posix$(EXEEXT) \
+ test-vasprintf$(EXEEXT) test-vc-list-files-git.sh \
+ test-vc-list-files-cvs.sh test-verify$(EXEEXT) test-verify.sh \
+ test-version-etc.sh $(am__EXEEXT_16) test-wchar$(EXEEXT) \
+ test-wcrtomb.sh test-wcrtomb-w32-1.sh test-wcrtomb-w32-2.sh \
+ test-wcrtomb-w32-3.sh test-wcrtomb-w32-4.sh \
+ test-wcrtomb-w32-5.sh $(am__EXEEXT_17) test-wctype-h$(EXEEXT) \
+ test-xalloc-die.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-btowc$(EXEEXT) \
+ test-c-ctype$(EXEEXT) test-c-stack$(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) $(am__EXEEXT_1) \
+ 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-frexp-nolibm$(EXEEXT) test-frexpl-nolibm$(EXEEXT) \
+ test-fseeko$(EXEEXT) test-ftell$(EXEEXT) test-ftell3$(EXEEXT) \
+ test-ftello$(EXEEXT) test-ftello3$(EXEEXT) \
+ test-getdtablesize$(EXEEXT) test-getopt$(EXEEXT) \
+ test-gettimeofday$(EXEEXT) test-ignore-value$(EXEEXT) \
+ test-isnand-nolibm$(EXEEXT) test-isnanf-nolibm$(EXEEXT) \
+ test-isnanl-nolibm$(EXEEXT) $(am__EXEEXT_2) \
+ test-langinfo$(EXEEXT) test-link$(EXEEXT) \
+ test-linkedhash_list$(EXEEXT) $(am__EXEEXT_3) \
+ test-locale$(EXEEXT) test-localename$(EXEEXT) \
+ test-lseek$(EXEEXT) test-lstat$(EXEEXT) \
+ test-malloc-gnu$(EXEEXT) test-malloca$(EXEEXT) $(am__EXEEXT_4) \
+ test-math$(EXEEXT) test-mbrtowc$(EXEEXT) \
+ test-mbrtowc-w32$(EXEEXT) test-mbsinit$(EXEEXT) \
+ test-memchr$(EXEEXT) test-memchr2$(EXEEXT) \
+ test-nl_langinfo$(EXEEXT) test-open$(EXEEXT) \
+ test-pipe2$(EXEEXT) $(am__EXEEXT_5) test-printf-frexp$(EXEEXT) \
+ test-printf-frexpl$(EXEEXT) test-quotearg-simple$(EXEEXT) \
+ test-rawmemchr$(EXEEXT) test-readlink$(EXEEXT) \
+ test-rename$(EXEEXT) test-rmdir$(EXEEXT) test-sched$(EXEEXT) \
+ test-setenv$(EXEEXT) test-setlocale1$(EXEEXT) \
+ test-setlocale2$(EXEEXT) test-sigaction$(EXEEXT) \
+ $(am__EXEEXT_6) test-signal$(EXEEXT) test-signbit$(EXEEXT) \
+ test-snprintf$(EXEEXT) $(am__EXEEXT_7) \
+ test-spawn-pipe$(EXEEXT) test-spawn$(EXEEXT) \
+ test-stat$(EXEEXT) test-stdbool$(EXEEXT) test-stddef$(EXEEXT) \
+ test-stdint$(EXEEXT) $(am__EXEEXT_8) test-stdio$(EXEEXT) \
+ $(am__EXEEXT_9) test-stdlib$(EXEEXT) test-strchrnul$(EXEEXT) \
+ test-strerror$(EXEEXT) $(am__EXEEXT_10) test-string$(EXEEXT) \
+ test-strnlen$(EXEEXT) test-strsignal$(EXEEXT) \
+ test-strstr$(EXEEXT) test-strtod$(EXEEXT) \
+ test-symlink$(EXEEXT) $(am__EXEEXT_11) test-sys_stat$(EXEEXT) \
+ $(am__EXEEXT_12) test-sys_time$(EXEEXT) $(am__EXEEXT_13) \
+ test-sys_wait$(EXEEXT) $(am__EXEEXT_14) test-time$(EXEEXT) \
+ $(am__EXEEXT_15) test-dup-safer$(EXEEXT) test-unistd$(EXEEXT) \
+ test-unsetenv$(EXEEXT) test-vasnprintf$(EXEEXT) \
+ test-vasprintf-posix$(EXEEXT) test-vasprintf$(EXEEXT) \
+ test-verify$(EXEEXT) test-version-etc$(EXEEXT) \
+ $(am__EXEEXT_16) test-wchar$(EXEEXT) test-wcrtomb$(EXEEXT) \
+ test-wcrtomb-w32$(EXEEXT) $(am__EXEEXT_17) \
+ test-wctype-h$(EXEEXT) test-xalloc-die$(EXEEXT) \
+ test-xvasprintf$(EXEEXT)
+@ANSICXX_TRUE@am__append_1 = test-fcntl-h-c++
+@ANSICXX_TRUE@am__append_2 = test-fcntl-h-c++
+@ANSICXX_TRUE@am__append_3 = test-langinfo-c++
+@ANSICXX_TRUE@am__append_4 = test-langinfo-c++
+@ANSICXX_TRUE@am__append_5 = test-locale-c++
+@ANSICXX_TRUE@am__append_6 = test-locale-c++
+@ANSICXX_TRUE@am__append_7 = test-math-c++
+@ANSICXX_TRUE@am__append_8 = test-math-c++
+@POSIX_SPAWN_PORTED_TRUE@am__append_9 = test-posix_spawn1 test-posix_spawn2
+@POSIX_SPAWN_PORTED_TRUE@am__append_10 = test-posix_spawn1 test-posix_spawn2
+@POSIX_SPAWN_PORTED_TRUE@am__append_11 = test-posix_spawn1.sh \
+@POSIX_SPAWN_PORTED_TRUE@ test-posix_spawn2.sh
+@POSIX_SPAWN_PORTED_TRUE@am__append_12 = 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
+@ANSICXX_TRUE@am__append_13 = test-signal-c++
+@ANSICXX_TRUE@am__append_14 = test-signal-c++
+@ANSICXX_TRUE@am__append_15 = test-spawn-c++
+@ANSICXX_TRUE@am__append_16 = test-spawn-c++
+@ANSICXX_TRUE@am__append_17 = test-stdio-c++
+@ANSICXX_TRUE@am__append_18 = test-stdio-c++
+@ANSICXX_TRUE@am__append_19 = test-stdlib-c++
+@ANSICXX_TRUE@am__append_20 = test-stdlib-c++
+@ANSICXX_TRUE@am__append_21 = test-string-c++
+@ANSICXX_TRUE@am__append_22 = test-string-c++
+@ANSICXX_TRUE@am__append_23 = test-sys_stat-c++
+@ANSICXX_TRUE@am__append_24 = test-sys_stat-c++
+@ANSICXX_TRUE@am__append_25 = test-sys_time-c++
+@ANSICXX_TRUE@am__append_26 = test-sys_time-c++
+@ANSICXX_TRUE@am__append_27 = test-sys_wait-c++
+@ANSICXX_TRUE@am__append_28 = test-sys_wait-c++
+@ANSICXX_TRUE@am__append_29 = test-time-c++
+@ANSICXX_TRUE@am__append_30 = test-time-c++
+@ANSICXX_TRUE@am__append_31 = test-unistd-c++
+@ANSICXX_TRUE@am__append_32 = test-unistd-c++
+@ANSICXX_TRUE@am__append_33 = test-wchar-c++
+@ANSICXX_TRUE@am__append_34 = test-wchar-c++
+@ANSICXX_TRUE@am__append_35 = test-wctype-h-c++
+@ANSICXX_TRUE@am__append_36 = test-wctype-h-c++
+subdir = tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \
+ $(top_srcdir)/m4/alloca.m4 $(top_srcdir)/m4/ansi-c++.m4 \
+ $(top_srcdir)/m4/assert.m4 $(top_srcdir)/m4/autobuild.m4 \
+ $(top_srcdir)/m4/btowc.m4 $(top_srcdir)/m4/c-stack.m4 \
+ $(top_srcdir)/m4/canonicalize.m4 $(top_srcdir)/m4/cloexec.m4 \
+ $(top_srcdir)/m4/close-stream.m4 $(top_srcdir)/m4/close.m4 \
+ $(top_srcdir)/m4/closein.m4 $(top_srcdir)/m4/closeout.m4 \
+ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/config-h.m4 \
+ $(top_srcdir)/m4/configmake.m4 $(top_srcdir)/m4/dirname.m4 \
+ $(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup2.m4 \
+ $(top_srcdir)/m4/eealloc.m4 $(top_srcdir)/m4/environ.m4 \
+ $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/error.m4 \
+ $(top_srcdir)/m4/execute.m4 $(top_srcdir)/m4/exponentd.m4 \
+ $(top_srcdir)/m4/exponentf.m4 $(top_srcdir)/m4/exponentl.m4 \
+ $(top_srcdir)/m4/extensions.m4 \
+ $(top_srcdir)/m4/fatal-signal.m4 $(top_srcdir)/m4/fclose.m4 \
+ $(top_srcdir)/m4/fcntl-o.m4 $(top_srcdir)/m4/fcntl.m4 \
+ $(top_srcdir)/m4/fcntl_h.m4 $(top_srcdir)/m4/fflush.m4 \
+ $(top_srcdir)/m4/filenamecat.m4 $(top_srcdir)/m4/float_h.m4 \
+ $(top_srcdir)/m4/fopen.m4 $(top_srcdir)/m4/fpending.m4 \
+ $(top_srcdir)/m4/fpieee.m4 $(top_srcdir)/m4/fpurge.m4 \
+ $(top_srcdir)/m4/freading.m4 $(top_srcdir)/m4/frexp.m4 \
+ $(top_srcdir)/m4/frexpl.m4 $(top_srcdir)/m4/fseeko.m4 \
+ $(top_srcdir)/m4/ftell.m4 $(top_srcdir)/m4/ftello.m4 \
+ $(top_srcdir)/m4/getdtablesize.m4 $(top_srcdir)/m4/getopt.m4 \
+ $(top_srcdir)/m4/getpagesize.m4 \
+ $(top_srcdir)/m4/gettimeofday.m4 $(top_srcdir)/m4/gl_list.m4 \
+ $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnulib-common.m4 \
+ $(top_srcdir)/m4/gnulib-comp.m4 \
+ $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/inline.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax_t.m4 \
+ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/isnand.m4 \
+ $(top_srcdir)/m4/isnanf.m4 $(top_srcdir)/m4/isnanl.m4 \
+ $(top_srcdir)/m4/langinfo_h.m4 $(top_srcdir)/m4/lcmessage.m4 \
+ $(top_srcdir)/m4/ldexp.m4 $(top_srcdir)/m4/ldexpl.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libsigsegv.m4 \
+ $(top_srcdir)/m4/link.m4 $(top_srcdir)/m4/localcharset.m4 \
+ $(top_srcdir)/m4/locale-fr.m4 $(top_srcdir)/m4/locale-ja.m4 \
+ $(top_srcdir)/m4/locale-tr.m4 $(top_srcdir)/m4/locale-zh.m4 \
+ $(top_srcdir)/m4/locale_h.m4 $(top_srcdir)/m4/localename.m4 \
+ $(top_srcdir)/m4/lock.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/lseek.m4 $(top_srcdir)/m4/lstat.m4 \
+ $(top_srcdir)/m4/malloc.m4 $(top_srcdir)/m4/malloca.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 $(top_srcdir)/m4/math_h.m4 \
+ $(top_srcdir)/m4/mbrtowc.m4 $(top_srcdir)/m4/mbsinit.m4 \
+ $(top_srcdir)/m4/mbstate_t.m4 $(top_srcdir)/m4/mbtowc.m4 \
+ $(top_srcdir)/m4/memchr.m4 $(top_srcdir)/m4/mkdtemp.m4 \
+ $(top_srcdir)/m4/mkstemp.m4 $(top_srcdir)/m4/mmap-anon.m4 \
+ $(top_srcdir)/m4/mode_t.m4 $(top_srcdir)/m4/multiarch.m4 \
+ $(top_srcdir)/m4/nl_langinfo.m4 $(top_srcdir)/m4/nocrash.m4 \
+ $(top_srcdir)/m4/open.m4 $(top_srcdir)/m4/pathmax.m4 \
+ $(top_srcdir)/m4/pipe2.m4 $(top_srcdir)/m4/posix_spawn.m4 \
+ $(top_srcdir)/m4/printf-frexp.m4 \
+ $(top_srcdir)/m4/printf-frexpl.m4 $(top_srcdir)/m4/printf.m4 \
+ $(top_srcdir)/m4/putenv.m4 $(top_srcdir)/m4/quotearg.m4 \
+ $(top_srcdir)/m4/rawmemchr.m4 $(top_srcdir)/m4/readlink.m4 \
+ $(top_srcdir)/m4/regex.m4 $(top_srcdir)/m4/rename.m4 \
+ $(top_srcdir)/m4/rmdir.m4 $(top_srcdir)/m4/sched_h.m4 \
+ $(top_srcdir)/m4/setenv.m4 $(top_srcdir)/m4/setlocale.m4 \
+ $(top_srcdir)/m4/sig_atomic_t.m4 $(top_srcdir)/m4/sigaction.m4 \
+ $(top_srcdir)/m4/signal_h.m4 \
+ $(top_srcdir)/m4/signalblocking.m4 $(top_srcdir)/m4/signbit.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/snprintf.m4 \
+ $(top_srcdir)/m4/spawn-pipe.m4 $(top_srcdir)/m4/spawn_h.m4 \
+ $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stat.m4 \
+ $(top_srcdir)/m4/stdarg.m4 $(top_srcdir)/m4/stdbool.m4 \
+ $(top_srcdir)/m4/stddef_h.m4 $(top_srcdir)/m4/stdint.m4 \
+ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/stdio-safer.m4 \
+ $(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib-safer.m4 \
+ $(top_srcdir)/m4/stdlib_h.m4 $(top_srcdir)/m4/strchrnul.m4 \
+ $(top_srcdir)/m4/strdup.m4 $(top_srcdir)/m4/strerror.m4 \
+ $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strndup.m4 \
+ $(top_srcdir)/m4/strnlen.m4 $(top_srcdir)/m4/strsignal.m4 \
+ $(top_srcdir)/m4/strstr.m4 $(top_srcdir)/m4/strtod.m4 \
+ $(top_srcdir)/m4/strtol.m4 $(top_srcdir)/m4/symlink.m4 \
+ $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \
+ $(top_srcdir)/m4/sys_wait_h.m4 $(top_srcdir)/m4/tempname.m4 \
+ $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/m4/time_h.m4 \
+ $(top_srcdir)/m4/tls.m4 $(top_srcdir)/m4/tmpdir.m4 \
+ $(top_srcdir)/m4/ungetc.m4 $(top_srcdir)/m4/unistd-safer.m4 \
+ $(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/unlocked-io.m4 \
+ $(top_srcdir)/m4/vasnprintf.m4 \
+ $(top_srcdir)/m4/vasprintf-posix.m4 \
+ $(top_srcdir)/m4/vasprintf.m4 $(top_srcdir)/m4/version-etc.m4 \
+ $(top_srcdir)/m4/wait-process.m4 $(top_srcdir)/m4/waitpid.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/m4/wchar_h.m4 \
+ $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wcrtomb.m4 \
+ $(top_srcdir)/m4/wctob.m4 $(top_srcdir)/m4/wctomb.m4 \
+ $(top_srcdir)/m4/wctype_h.m4 $(top_srcdir)/m4/wint_t.m4 \
+ $(top_srcdir)/m4/xalloc.m4 $(top_srcdir)/m4/xsize.m4 \
+ $(top_srcdir)/m4/xstrndup.m4 $(top_srcdir)/m4/xvasprintf.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/lib/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+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) c-strcasecmp.$(OBJEXT) \
+ c-strncasecmp.$(OBJEXT) localename.$(OBJEXT)
+libtests_a_OBJECTS = $(am_libtests_a_OBJECTS)
+@ANSICXX_TRUE@am__EXEEXT_1 = test-fcntl-h-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_2 = test-langinfo-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_3 = test-locale-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_4 = test-math-c++$(EXEEXT)
+@POSIX_SPAWN_PORTED_TRUE@am__EXEEXT_5 = test-posix_spawn1$(EXEEXT) \
+@POSIX_SPAWN_PORTED_TRUE@ test-posix_spawn2$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_6 = test-signal-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_7 = test-spawn-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_8 = test-stdio-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_9 = test-stdlib-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_10 = test-string-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_11 = test-sys_stat-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_12 = test-sys_time-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_13 = test-sys_wait-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_14 = test-time-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_15 = test-unistd-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_16 = test-wchar-c++$(EXEEXT)
+@ANSICXX_TRUE@am__EXEEXT_17 = test-wctype-h-c++$(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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_c_stack_SOURCES = test-c-stack.c
+test_c_stack_OBJECTS = test-c-stack.$(OBJEXT)
+test_c_stack_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+ $(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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a \
+ 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_fcntl_h_c___SOURCES_DIST = test-fcntl-h-c++.cc
+@ANSICXX_TRUE@am_test_fcntl_h_c___OBJECTS = \
+@ANSICXX_TRUE@ test-fcntl-h-c++.$(OBJEXT)
+test_fcntl_h_c___OBJECTS = $(am_test_fcntl_h_c___OBJECTS)
+@ANSICXX_TRUE@test_fcntl_h_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_fflush_SOURCES = test-fflush.c
+test_fflush_OBJECTS = test-fflush.$(OBJEXT)
+test_fflush_LDADD = $(LDADD)
+test_fflush_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_ftell_SOURCES = test-ftell.c
+test_ftell_OBJECTS = test-ftell.$(OBJEXT)
+test_ftell_LDADD = $(LDADD)
+test_ftell_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_ftell3_SOURCES = test-ftell3.c
+test_ftell3_OBJECTS = test-ftell3.$(OBJEXT)
+test_ftell3_LDADD = $(LDADD)
+test_ftell3_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_ftello3_SOURCES = test-ftello3.c
+test_ftello3_OBJECTS = test-ftello3.$(OBJEXT)
+test_ftello3_LDADD = $(LDADD)
+test_ftello3_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_getopt_SOURCES = test-getopt.c
+test_getopt_OBJECTS = test-getopt.$(OBJEXT)
+test_getopt_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+test_gettimeofday_SOURCES = test-gettimeofday.c
+test_gettimeofday_OBJECTS = test-gettimeofday.$(OBJEXT)
+test_gettimeofday_LDADD = $(LDADD)
+test_gettimeofday_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_ignore_value_SOURCES = test-ignore-value.c
+test_ignore_value_OBJECTS = test-ignore-value.$(OBJEXT)
+test_ignore_value_LDADD = $(LDADD)
+test_ignore_value_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_langinfo_c___SOURCES_DIST = test-langinfo-c++.cc
+@ANSICXX_TRUE@am_test_langinfo_c___OBJECTS = \
+@ANSICXX_TRUE@ test-langinfo-c++.$(OBJEXT)
+test_langinfo_c___OBJECTS = $(am_test_langinfo_c___OBJECTS)
+test_langinfo_c___LDADD = $(LDADD)
+test_langinfo_c___DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a \
+ libtests.a $(am__DEPENDENCIES_1)
+test_locale_SOURCES = test-locale.c
+test_locale_OBJECTS = test-locale.$(OBJEXT)
+test_locale_LDADD = $(LDADD)
+test_locale_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_locale_c___SOURCES_DIST = test-locale-c++.cc \
+ test-locale-c++2.cc
+@ANSICXX_TRUE@am_test_locale_c___OBJECTS = test-locale-c++.$(OBJEXT) \
+@ANSICXX_TRUE@ test-locale-c++2.$(OBJEXT)
+test_locale_c___OBJECTS = $(am_test_locale_c___OBJECTS)
+test_locale_c___LDADD = $(LDADD)
+test_locale_c___DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_localename_SOURCES = test-localename.c
+test_localename_OBJECTS = test-localename.$(OBJEXT)
+test_localename_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_lseek_SOURCES = test-lseek.c
+test_lseek_OBJECTS = test-lseek.$(OBJEXT)
+test_lseek_LDADD = $(LDADD)
+test_lseek_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_malloc_gnu_SOURCES = test-malloc-gnu.c
+test_malloc_gnu_OBJECTS = test-malloc-gnu.$(OBJEXT)
+test_malloc_gnu_LDADD = $(LDADD)
+test_malloc_gnu_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_math_c___SOURCES_DIST = test-math-c++.cc test-math-c++2.cc
+@ANSICXX_TRUE@am_test_math_c___OBJECTS = test-math-c++.$(OBJEXT) \
+@ANSICXX_TRUE@ test-math-c++2.$(OBJEXT)
+test_math_c___OBJECTS = $(am_test_math_c___OBJECTS)
+test_math_c___LDADD = $(LDADD)
+test_math_c___DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_mbrtowc_w32_SOURCES = test-mbrtowc-w32.c
+test_mbrtowc_w32_OBJECTS = test-mbrtowc-w32.$(OBJEXT)
+test_mbrtowc_w32_LDADD = $(LDADD)
+test_mbrtowc_w32_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_open_SOURCES = test-open.c
+test_open_OBJECTS = test-open.$(OBJEXT)
+test_open_LDADD = $(LDADD)
+test_open_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_pipe2_SOURCES = test-pipe2.c
+test_pipe2_OBJECTS = test-pipe2.$(OBJEXT)
+test_pipe2_LDADD = $(LDADD)
+test_pipe2_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_quotearg_simple_SOURCES = test-quotearg-simple.c
+test_quotearg_simple_OBJECTS = test-quotearg-simple.$(OBJEXT)
+test_quotearg_simple_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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_setlocale1_SOURCES = test-setlocale1.c
+test_setlocale1_OBJECTS = test-setlocale1.$(OBJEXT)
+test_setlocale1_LDADD = $(LDADD)
+test_setlocale1_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_setlocale2_SOURCES = test-setlocale2.c
+test_setlocale2_OBJECTS = test-setlocale2.$(OBJEXT)
+test_setlocale2_LDADD = $(LDADD)
+test_setlocale2_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_signal_c___SOURCES_DIST = test-signal-c++.cc \
+ test-signal-c++2.cc
+@ANSICXX_TRUE@am_test_signal_c___OBJECTS = test-signal-c++.$(OBJEXT) \
+@ANSICXX_TRUE@ test-signal-c++2.$(OBJEXT)
+test_signal_c___OBJECTS = $(am_test_signal_c___OBJECTS)
+@ANSICXX_TRUE@test_signal_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_signbit_SOURCES = test-signbit.c
+test_signbit_OBJECTS = test-signbit.$(OBJEXT)
+test_signbit_LDADD = $(LDADD)
+test_signbit_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_spawn_c___SOURCES_DIST = test-spawn-c++.cc
+@ANSICXX_TRUE@am_test_spawn_c___OBJECTS = test-spawn-c++.$(OBJEXT)
+test_spawn_c___OBJECTS = $(am_test_spawn_c___OBJECTS)
+@ANSICXX_TRUE@test_spawn_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_spawn_pipe_SOURCES = test-spawn-pipe.c
+test_spawn_pipe_OBJECTS = test-spawn-pipe.$(OBJEXT)
+test_spawn_pipe_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_stat_SOURCES = test-stat.c
+test_stat_OBJECTS = test-stat.$(OBJEXT)
+test_stat_LDADD = $(LDADD)
+test_stat_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_stdio_c___SOURCES_DIST = test-stdio-c++.cc test-stdio-c++2.cc
+@ANSICXX_TRUE@am_test_stdio_c___OBJECTS = test-stdio-c++.$(OBJEXT) \
+@ANSICXX_TRUE@ test-stdio-c++2.$(OBJEXT)
+test_stdio_c___OBJECTS = $(am_test_stdio_c___OBJECTS)
+@ANSICXX_TRUE@test_stdio_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_stdlib_SOURCES = test-stdlib.c
+test_stdlib_OBJECTS = test-stdlib.$(OBJEXT)
+test_stdlib_LDADD = $(LDADD)
+test_stdlib_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_stdlib_c___SOURCES_DIST = test-stdlib-c++.cc \
+ test-stdlib-c++2.cc
+@ANSICXX_TRUE@am_test_stdlib_c___OBJECTS = test-stdlib-c++.$(OBJEXT) \
+@ANSICXX_TRUE@ test-stdlib-c++2.$(OBJEXT)
+test_stdlib_c___OBJECTS = $(am_test_stdlib_c___OBJECTS)
+@ANSICXX_TRUE@test_stdlib_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_strchrnul_SOURCES = test-strchrnul.c
+test_strchrnul_OBJECTS = test-strchrnul.$(OBJEXT)
+test_strchrnul_LDADD = $(LDADD)
+test_strchrnul_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_string_SOURCES = test-string.c
+test_string_OBJECTS = test-string.$(OBJEXT)
+test_string_LDADD = $(LDADD)
+test_string_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_string_c___SOURCES_DIST = test-string-c++.cc \
+ test-string-c++2.cc
+@ANSICXX_TRUE@am_test_string_c___OBJECTS = test-string-c++.$(OBJEXT) \
+@ANSICXX_TRUE@ test-string-c++2.$(OBJEXT)
+test_string_c___OBJECTS = $(am_test_string_c___OBJECTS)
+@ANSICXX_TRUE@test_string_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_strnlen_SOURCES = test-strnlen.c
+test_strnlen_OBJECTS = test-strnlen.$(OBJEXT)
+test_strnlen_LDADD = $(LDADD)
+test_strnlen_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_strsignal_SOURCES = test-strsignal.c
+test_strsignal_OBJECTS = test-strsignal.$(OBJEXT)
+test_strsignal_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1)
+test_strstr_SOURCES = test-strstr.c
+test_strstr_OBJECTS = test-strstr.$(OBJEXT)
+test_strstr_LDADD = $(LDADD)
+test_strstr_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_sys_stat_c___SOURCES_DIST = test-sys_stat-c++.cc
+@ANSICXX_TRUE@am_test_sys_stat_c___OBJECTS = \
+@ANSICXX_TRUE@ test-sys_stat-c++.$(OBJEXT)
+test_sys_stat_c___OBJECTS = $(am_test_sys_stat_c___OBJECTS)
+@ANSICXX_TRUE@test_sys_stat_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_sys_time_c___SOURCES_DIST = test-sys_time-c++.cc
+@ANSICXX_TRUE@am_test_sys_time_c___OBJECTS = \
+@ANSICXX_TRUE@ test-sys_time-c++.$(OBJEXT)
+test_sys_time_c___OBJECTS = $(am_test_sys_time_c___OBJECTS)
+@ANSICXX_TRUE@test_sys_time_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_sys_wait_c___SOURCES_DIST = test-sys_wait-c++.cc
+@ANSICXX_TRUE@am_test_sys_wait_c___OBJECTS = \
+@ANSICXX_TRUE@ test-sys_wait-c++.$(OBJEXT)
+test_sys_wait_c___OBJECTS = $(am_test_sys_wait_c___OBJECTS)
+test_sys_wait_c___LDADD = $(LDADD)
+test_sys_wait_c___DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_time_c___SOURCES_DIST = test-time-c++.cc test-time-c++2.cc
+@ANSICXX_TRUE@am_test_time_c___OBJECTS = test-time-c++.$(OBJEXT) \
+@ANSICXX_TRUE@ test-time-c++2.$(OBJEXT)
+test_time_c___OBJECTS = $(am_test_time_c___OBJECTS)
+@ANSICXX_TRUE@test_time_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_unistd_SOURCES = test-unistd.c
+test_unistd_OBJECTS = test-unistd.$(OBJEXT)
+test_unistd_LDADD = $(LDADD)
+test_unistd_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_unistd_c___SOURCES_DIST = test-unistd-c++.cc
+@ANSICXX_TRUE@am_test_unistd_c___OBJECTS = test-unistd-c++.$(OBJEXT)
+test_unistd_c___OBJECTS = $(am_test_unistd_c___OBJECTS)
+@ANSICXX_TRUE@test_unistd_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_unsetenv_SOURCES = test-unsetenv.c
+test_unsetenv_OBJECTS = test-unsetenv.$(OBJEXT)
+test_unsetenv_LDADD = $(LDADD)
+test_unsetenv_DEPENDENCIES = libtests.a ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a 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 ../lib/libm4.a \
+ libtests.a $(am__DEPENDENCIES_1)
+test_verify_SOURCES = test-verify.c
+test_verify_OBJECTS = test-verify.$(OBJEXT)
+test_verify_LDADD = $(LDADD)
+test_verify_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_version_etc_SOURCES = test-version-etc.c
+test_version_etc_OBJECTS = test-version-etc.$(OBJEXT)
+test_version_etc_DEPENDENCIES = $(am__DEPENDENCIES_2)
+test_wchar_SOURCES = test-wchar.c
+test_wchar_OBJECTS = test-wchar.$(OBJEXT)
+test_wchar_LDADD = $(LDADD)
+test_wchar_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_wchar_c___SOURCES_DIST = test-wchar-c++.cc
+@ANSICXX_TRUE@am_test_wchar_c___OBJECTS = test-wchar-c++.$(OBJEXT)
+test_wchar_c___OBJECTS = $(am_test_wchar_c___OBJECTS)
+@ANSICXX_TRUE@test_wchar_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(am__DEPENDENCIES_1)
+test_wcrtomb_SOURCES = test-wcrtomb.c
+test_wcrtomb_OBJECTS = test-wcrtomb.$(OBJEXT)
+test_wcrtomb_LDADD = $(LDADD)
+test_wcrtomb_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_wcrtomb_w32_SOURCES = test-wcrtomb-w32.c
+test_wcrtomb_w32_OBJECTS = test-wcrtomb-w32.$(OBJEXT)
+test_wcrtomb_w32_LDADD = $(LDADD)
+test_wcrtomb_w32_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+test_wctype_h_SOURCES = test-wctype-h.c
+test_wctype_h_OBJECTS = test-wctype-h.$(OBJEXT)
+test_wctype_h_LDADD = $(LDADD)
+test_wctype_h_DEPENDENCIES = libtests.a ../lib/libm4.a libtests.a \
+ $(am__DEPENDENCIES_1)
+am__test_wctype_h_c___SOURCES_DIST = test-wctype-h-c++.cc
+@ANSICXX_TRUE@am_test_wctype_h_c___OBJECTS = \
+@ANSICXX_TRUE@ test-wctype-h-c++.$(OBJEXT)
+test_wctype_h_c___OBJECTS = $(am_test_wctype_h_c___OBJECTS)
+@ANSICXX_TRUE@test_wctype_h_c___DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@ANSICXX_TRUE@ $(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_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)/lib
+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)
+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 = $(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 " $@;
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_$(V))
+am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY))
+am__v_CXX_0 = @echo " CXX " $@;
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+AM_V_CXXLD = $(am__v_CXXLD_$(V))
+am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+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-btowc.c \
+ test-c-ctype.c test-c-stack.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_fcntl_h_c___SOURCES) 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_frexp_nolibm_SOURCES) \
+ $(test_frexpl_nolibm_SOURCES) test-fseeko.c test-ftell.c \
+ test-ftell3.c test-ftello.c test-ftello3.c \
+ test-getdtablesize.c test-getopt.c test-gettimeofday.c \
+ test-ignore-value.c test-isnand-nolibm.c test-isnanf-nolibm.c \
+ test-isnanl-nolibm.c test-langinfo.c \
+ $(test_langinfo_c___SOURCES) test-link.c \
+ test-linkedhash_list.c test-locale.c \
+ $(test_locale_c___SOURCES) test-localename.c test-lseek.c \
+ test-lstat.c test-malloc-gnu.c test-malloca.c test-math.c \
+ $(test_math_c___SOURCES) test-mbrtowc.c test-mbrtowc-w32.c \
+ test-mbsinit.c test-memchr.c test-memchr2.c test-nl_langinfo.c \
+ test-open.c test-pipe2.c test-posix_spawn1.c \
+ test-posix_spawn2.c test-printf-frexp.c test-printf-frexpl.c \
+ test-quotearg-simple.c test-rawmemchr.c test-readlink.c \
+ test-rename.c test-rmdir.c test-sched.c test-setenv.c \
+ test-setlocale1.c test-setlocale2.c test-sigaction.c \
+ test-signal.c $(test_signal_c___SOURCES) test-signbit.c \
+ test-snprintf.c test-spawn.c $(test_spawn_c___SOURCES) \
+ test-spawn-pipe.c test-stat.c test-stdbool.c test-stddef.c \
+ test-stdint.c test-stdio.c $(test_stdio_c___SOURCES) \
+ test-stdlib.c $(test_stdlib_c___SOURCES) test-strchrnul.c \
+ test-strerror.c test-string.c $(test_string_c___SOURCES) \
+ test-strnlen.c test-strsignal.c test-strstr.c test-strtod.c \
+ test-symlink.c test-sys_stat.c $(test_sys_stat_c___SOURCES) \
+ test-sys_time.c $(test_sys_time_c___SOURCES) test-sys_wait.c \
+ $(test_sys_wait_c___SOURCES) test-time.c \
+ $(test_time_c___SOURCES) test-unistd.c \
+ $(test_unistd_c___SOURCES) test-unsetenv.c test-vasnprintf.c \
+ test-vasprintf.c test-vasprintf-posix.c test-verify.c \
+ test-version-etc.c test-wchar.c $(test_wchar_c___SOURCES) \
+ test-wcrtomb.c test-wcrtomb-w32.c test-wctype-h.c \
+ $(test_wctype_h_c___SOURCES) test-xalloc-die.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-btowc.c \
+ test-c-ctype.c test-c-stack.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 \
+ $(am__test_fcntl_h_c___SOURCES_DIST) 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_frexp_nolibm_SOURCES) \
+ $(test_frexpl_nolibm_SOURCES) test-fseeko.c test-ftell.c \
+ test-ftell3.c test-ftello.c test-ftello3.c \
+ test-getdtablesize.c test-getopt.c test-gettimeofday.c \
+ test-ignore-value.c test-isnand-nolibm.c test-isnanf-nolibm.c \
+ test-isnanl-nolibm.c test-langinfo.c \
+ $(am__test_langinfo_c___SOURCES_DIST) test-link.c \
+ test-linkedhash_list.c test-locale.c \
+ $(am__test_locale_c___SOURCES_DIST) test-localename.c \
+ test-lseek.c test-lstat.c test-malloc-gnu.c test-malloca.c \
+ test-math.c $(am__test_math_c___SOURCES_DIST) test-mbrtowc.c \
+ test-mbrtowc-w32.c test-mbsinit.c test-memchr.c test-memchr2.c \
+ test-nl_langinfo.c test-open.c test-pipe2.c \
+ test-posix_spawn1.c test-posix_spawn2.c test-printf-frexp.c \
+ test-printf-frexpl.c test-quotearg-simple.c test-rawmemchr.c \
+ test-readlink.c test-rename.c test-rmdir.c test-sched.c \
+ test-setenv.c test-setlocale1.c test-setlocale2.c \
+ test-sigaction.c test-signal.c \
+ $(am__test_signal_c___SOURCES_DIST) test-signbit.c \
+ test-snprintf.c test-spawn.c \
+ $(am__test_spawn_c___SOURCES_DIST) test-spawn-pipe.c \
+ test-stat.c test-stdbool.c test-stddef.c test-stdint.c \
+ test-stdio.c $(am__test_stdio_c___SOURCES_DIST) test-stdlib.c \
+ $(am__test_stdlib_c___SOURCES_DIST) test-strchrnul.c \
+ test-strerror.c test-string.c \
+ $(am__test_string_c___SOURCES_DIST) test-strnlen.c \
+ test-strsignal.c test-strstr.c test-strtod.c test-symlink.c \
+ test-sys_stat.c $(am__test_sys_stat_c___SOURCES_DIST) \
+ test-sys_time.c $(am__test_sys_time_c___SOURCES_DIST) \
+ test-sys_wait.c $(am__test_sys_wait_c___SOURCES_DIST) \
+ test-time.c $(am__test_time_c___SOURCES_DIST) test-unistd.c \
+ $(am__test_unistd_c___SOURCES_DIST) test-unsetenv.c \
+ test-vasnprintf.c test-vasprintf.c test-vasprintf-posix.c \
+ test-verify.c test-version-etc.c test-wchar.c \
+ $(am__test_wchar_c___SOURCES_DIST) test-wcrtomb.c \
+ test-wcrtomb-w32.c test-wctype-h.c \
+ $(am__test_wctype_h_c___SOURCES_DIST) test-xalloc-die.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"
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+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@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXX_CHOICE = @CXX_CHOICE@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+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@
+EXEEXT = @EXEEXT@
+FLOAT_H = @FLOAT_H@
+GETOPT_H = @GETOPT_H@
+GLIBC21 = @GLIBC21@
+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_CEIL = @GNULIB_CEIL@
+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_DUPLOCALE = @GNULIB_DUPLOCALE@
+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_FLOOR = @GNULIB_FLOOR@
+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_GRANTPT = @GNULIB_GRANTPT@
+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_ISWBLANK = @GNULIB_ISWBLANK@
+GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@
+GNULIB_LCHMOD = @GNULIB_LCHMOD@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LDEXPL = @GNULIB_LDEXPL@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LOGB = @GNULIB_LOGB@
+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_MBTOWC = @GNULIB_MBTOWC@
+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_MKTIME = @GNULIB_MKTIME@
+GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
+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_PIPE = @GNULIB_PIPE@
+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_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+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_SETLOCALE = @GNULIB_SETLOCALE@
+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_STRERROR_R = @GNULIB_STRERROR_R@
+GNULIB_STRNCAT = @GNULIB_STRNCAT@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRPTIME = @GNULIB_STRPTIME@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TANL = @GNULIB_TANL@
+GNULIB_TIMEGM = @GNULIB_TIMEGM@
+GNULIB_TIME_R = @GNULIB_TIME_R@
+GNULIB_TMPFILE = @GNULIB_TMPFILE@
+GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@
+GNULIB_TRUNC = @GNULIB_TRUNC@
+GNULIB_TRUNCF = @GNULIB_TRUNCF@
+GNULIB_TRUNCL = @GNULIB_TRUNCL@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+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_UNLOCKPT = @GNULIB_UNLOCKPT@
+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_WAITPID = @GNULIB_WAITPID@
+GNULIB_WCPCPY = @GNULIB_WCPCPY@
+GNULIB_WCPNCPY = @GNULIB_WCPNCPY@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@
+GNULIB_WCSCAT = @GNULIB_WCSCAT@
+GNULIB_WCSCHR = @GNULIB_WCSCHR@
+GNULIB_WCSCMP = @GNULIB_WCSCMP@
+GNULIB_WCSCOLL = @GNULIB_WCSCOLL@
+GNULIB_WCSCPY = @GNULIB_WCSCPY@
+GNULIB_WCSCSPN = @GNULIB_WCSCSPN@
+GNULIB_WCSDUP = @GNULIB_WCSDUP@
+GNULIB_WCSLEN = @GNULIB_WCSLEN@
+GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@
+GNULIB_WCSNCAT = @GNULIB_WCSNCAT@
+GNULIB_WCSNCMP = @GNULIB_WCSNCMP@
+GNULIB_WCSNCPY = @GNULIB_WCSNCPY@
+GNULIB_WCSNLEN = @GNULIB_WCSNLEN@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSPBRK = @GNULIB_WCSPBRK@
+GNULIB_WCSRCHR = @GNULIB_WCSRCHR@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCSSPN = @GNULIB_WCSSPN@
+GNULIB_WCSSTR = @GNULIB_WCSSTR@
+GNULIB_WCSTOK = @GNULIB_WCSTOK@
+GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@
+GNULIB_WCSXFRM = @GNULIB_WCSXFRM@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCTOMB = @GNULIB_WCTOMB@
+GNULIB_WCTRANS = @GNULIB_WCTRANS@
+GNULIB_WCTYPE = @GNULIB_WCTYPE@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WMEMCHR = @GNULIB_WMEMCHR@
+GNULIB_WMEMCMP = @GNULIB_WMEMCMP@
+GNULIB_WMEMCPY = @GNULIB_WMEMCPY@
+GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@
+GNULIB_WMEMSET = @GNULIB_WMEMSET@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ACOSL = @HAVE_ACOSL@
+HAVE_ASINL = @HAVE_ASINL@
+HAVE_ATANL = @HAVE_ATANL@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+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_CEILF = @HAVE_DECL_CEILF@
+HAVE_DECL_CEILL = @HAVE_DECL_CEILL@
+HAVE_DECL_COSL = @HAVE_DECL_COSL@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_EXPL = @HAVE_DECL_EXPL@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_FLOORF = @HAVE_DECL_FLOORF@
+HAVE_DECL_FLOORL = @HAVE_DECL_FLOORL@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_FREXPL = @HAVE_DECL_FREXPL@
+HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@
+HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_LDEXPL = @HAVE_DECL_LDEXPL@
+HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@
+HAVE_DECL_LOGB = @HAVE_DECL_LOGB@
+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_ROUND = @HAVE_DECL_ROUND@
+HAVE_DECL_ROUNDF = @HAVE_DECL_ROUNDF@
+HAVE_DECL_ROUNDL = @HAVE_DECL_ROUNDL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+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_R = @HAVE_DECL_STRERROR_R@
+HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@
+HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@
+HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@
+HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_TANL = @HAVE_DECL_TANL@
+HAVE_DECL_TRUNC = @HAVE_DECL_TRUNC@
+HAVE_DECL_TRUNCF = @HAVE_DECL_TRUNCF@
+HAVE_DECL_TRUNCL = @HAVE_DECL_TRUNCL@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+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_DUPLOCALE = @HAVE_DUPLOCALE@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXPL = @HAVE_EXPL@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHMODAT = @HAVE_FCHMODAT@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FCNTL = @HAVE_FCNTL@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSTATAT = @HAVE_FSTATAT@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_FUTIMENS = @HAVE_FUTIMENS@
+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_GRANTPT = @HAVE_GRANTPT@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISNAND = @HAVE_ISNAND@
+HAVE_ISNANF = @HAVE_ISNANF@
+HAVE_ISNANL = @HAVE_ISNANL@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LIBSIGSEGV = @HAVE_LIBSIGSEGV@
+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_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MEMCHR = @HAVE_MEMCHR@
+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_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE = @HAVE_PIPE@
+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_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
+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_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_STRPTIME = @HAVE_STRPTIME@
+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_TIMEGM = @HAVE_TIMEGM@
+HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+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_WCPCPY = @HAVE_WCPCPY@
+HAVE_WCPNCPY = @HAVE_WCPNCPY@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSCASECMP = @HAVE_WCSCASECMP@
+HAVE_WCSCAT = @HAVE_WCSCAT@
+HAVE_WCSCHR = @HAVE_WCSCHR@
+HAVE_WCSCMP = @HAVE_WCSCMP@
+HAVE_WCSCOLL = @HAVE_WCSCOLL@
+HAVE_WCSCPY = @HAVE_WCSCPY@
+HAVE_WCSCSPN = @HAVE_WCSCSPN@
+HAVE_WCSDUP = @HAVE_WCSDUP@
+HAVE_WCSLEN = @HAVE_WCSLEN@
+HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@
+HAVE_WCSNCAT = @HAVE_WCSNCAT@
+HAVE_WCSNCMP = @HAVE_WCSNCMP@
+HAVE_WCSNCPY = @HAVE_WCSNCPY@
+HAVE_WCSNLEN = @HAVE_WCSNLEN@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSPBRK = @HAVE_WCSPBRK@
+HAVE_WCSRCHR = @HAVE_WCSRCHR@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCSSPN = @HAVE_WCSSPN@
+HAVE_WCSSTR = @HAVE_WCSSTR@
+HAVE_WCSTOK = @HAVE_WCSTOK@
+HAVE_WCSWIDTH = @HAVE_WCSWIDTH@
+HAVE_WCSXFRM = @HAVE_WCSXFRM@
+HAVE_WCTRANS_T = @HAVE_WCTRANS_T@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WCTYPE_T = @HAVE_WCTYPE_T@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE_WMEMCHR = @HAVE_WMEMCHR@
+HAVE_WMEMCMP = @HAVE_WMEMCMP@
+HAVE_WMEMCPY = @HAVE_WMEMCPY@
+HAVE_WMEMMOVE = @HAVE_WMEMMOVE@
+HAVE_WMEMSET = @HAVE_WMEMSET@
+HAVE_XLOCALE_H = @HAVE_XLOCALE_H@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBCSTACK = @LIBCSTACK@
+LIBINTL = @LIBINTL@
+LIBM4_LIBDEPS = @LIBM4_LIBDEPS@
+LIBM4_LTLIBDEPS = @LIBM4_LTLIBDEPS@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
+LIBS = @LIBS@
+LIBSIGSEGV = @LIBSIGSEGV@
+LIBSIGSEGV_PREFIX = @LIBSIGSEGV_PREFIX@
+LIBTESTS_LIBDEPS = @LIBTESTS_LIBDEPS@
+LIBTHREAD = @LIBTHREAD@
+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@
+LTLIBCSTACK = @LTLIBCSTACK@
+LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBSIGSEGV = @LTLIBSIGSEGV@
+LTLIBTHREAD = @LTLIBTHREAD@
+M4_LIBOBJS = @M4_LIBOBJS@
+M4_LTLIBOBJS = @M4_LTLIBOBJS@
+M4tests_LIBOBJS = @M4tests_LIBOBJS@
+M4tests_LTLIBOBJS = @M4tests_LTLIBOBJS@
+M4tests_WITNESS = @M4tests_WITNESS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+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_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_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_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_LOCALE_H = @NEXT_LOCALE_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@
+OBJEXT = @OBJEXT@
+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@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CEIL = @REPLACE_CEIL@
+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_DUPLOCALE = @REPLACE_DUPLOCALE@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FLOOR = @REPLACE_FLOOR@
+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_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
+REPLACE_HUGE_VAL = @REPLACE_HUGE_VAL@
+REPLACE_ISFINITE = @REPLACE_ISFINITE@
+REPLACE_ISINF = @REPLACE_ISINF@
+REPLACE_ISNAN = @REPLACE_ISNAN@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+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_MALLOC = @REPLACE_MALLOC@
+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_MBTOWC = @REPLACE_MBTOWC@
+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_PWRITE = @REPLACE_PWRITE@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+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_SETLOCALE = @REPLACE_SETLOCALE@
+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_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRERROR_R = @REPLACE_STRERROR_R@
+REPLACE_STRNCAT = @REPLACE_STRNCAT@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRNLEN = @REPLACE_STRNLEN@
+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_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TRUNC = @REPLACE_TRUNC@
+REPLACE_TRUNCF = @REPLACE_TRUNCF@
+REPLACE_TRUNCL = @REPLACE_TRUNCL@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+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_WCSWIDTH = @REPLACE_WCSWIDTH@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SCHED_H = @SCHED_H@
+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@
+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@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+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_CXX = @ac_ct_CXX@
+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@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+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@
+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
+SUBDIRS = .
+TESTS_ENVIRONMENT = EXEEXT='@EXEEXT@' srcdir='$(srcdir)' \
+ LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
+ LIBSIGSEGV='@LIBSIGSEGV@' 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='@LOCALE_FR@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' LOCALE_FR='@LOCALE_FR@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' LOCALE_JA='@LOCALE_JA@' \
+ LOCALE_ZH_CN='@LOCALE_ZH_CN@' abs_aux_dir='$(abs_aux_dir)' \
+ abs_aux_dir='$(abs_aux_dir)' MAKE='$(MAKE)' \
+ 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-btowc1.sh test-btowc2.sh \
+ test-btowc.c signature.h macros.h \
+ $(top_srcdir)/build-aux/c++defs.h test-c-ctype.c macros.h \
+ test-c-stack.c test-c-stack.sh test-c-stack2.sh 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++.cc signature.h 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-frexp.c minus-zero.h nan.h signature.h macros.h \
+ test-frexpl.c minus-zero.h nan.h signature.h macros.h \
+ test-fseeko.c test-fseeko.sh test-fseeko2.sh signature.h \
+ macros.h ftell.c test-ftell.c test-ftell.sh test-ftell2.sh \
+ test-ftell3.c signature.h macros.h test-ftello.c \
+ test-ftello.sh test-ftello2.sh test-ftello3.c signature.h \
+ macros.h test-getdtablesize.c signature.h macros.h macros.h \
+ signature.h test-getopt.c test-getopt.h test-getopt_long.h \
+ getpagesize.c signature.h test-gettimeofday.c \
+ test-ignore-value.c test-isnand-nolibm.c test-isnand.h \
+ minus-zero.h nan.h macros.h test-isnanf-nolibm.c test-isnanf.h \
+ minus-zero.h nan.h macros.h test-isnanl-nolibm.c test-isnanl.h \
+ minus-zero.h nan.h macros.h test-langinfo-c++.cc signature.h \
+ test-langinfo.c link.c test-link.h test-link.c signature.h \
+ macros.h test-linkedhash_list.c macros.h locale.in.h \
+ test-locale-c++.cc test-locale-c++2.cc signature.h \
+ test-locale.c localename.h test-localename.c macros.h \
+ test-lseek.c test-lseek.sh signature.h macros.h test-lstat.h \
+ test-lstat.c signature.h macros.h test-malloc-gnu.c \
+ test-malloca.c test-math-c++.cc test-math-c++2.cc signature.h \
+ test-math.c test-mbrtowc1.sh test-mbrtowc2.sh test-mbrtowc3.sh \
+ test-mbrtowc4.sh test-mbrtowc.c test-mbrtowc-w32-1.sh \
+ test-mbrtowc-w32-2.sh test-mbrtowc-w32-3.sh \
+ test-mbrtowc-w32-4.sh test-mbrtowc-w32-5.sh test-mbrtowc-w32.c \
+ signature.h macros.h test-mbsinit.sh test-mbsinit.c \
+ signature.h macros.h test-memchr.c zerosize-ptr.h signature.h \
+ macros.h test-memchr2.c zerosize-ptr.h macros.h \
+ test-nl_langinfo.sh test-nl_langinfo.c signature.h macros.h \
+ test-open.h test-open.c signature.h 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-simple.c test-quotearg.h macros.h \
+ test-rawmemchr.c zerosize-ptr.h 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 setenv.c \
+ test-setenv.c signature.h macros.h setlocale.c \
+ test-setlocale1.sh test-setlocale1.c test-setlocale2.sh \
+ test-setlocale2.c signature.h macros.h test-sigaction.c \
+ signature.h macros.h test-signal-c++.cc test-signal-c++2.cc \
+ signature.h test-signal.c test-signbit.c minus-zero.h macros.h \
+ test-snprintf.c signature.h macros.h test-spawn-c++.cc \
+ signature.h test-spawn-pipe.sh test-spawn-pipe.c macros.h \
+ test-spawn.c test-stat.h test-stat.c signature.h macros.h \
+ test-stdbool.c test-stddef.c test-stdint.c test-stdio-c++.cc \
+ test-stdio-c++2.cc signature.h test-stdio.c test-stdlib-c++.cc \
+ test-stdlib-c++2.cc signature.h test-stdlib.c test-sys_wait.h \
+ test-strchrnul.c signature.h macros.h strdup.c test-strerror.c \
+ signature.h macros.h test-string-c++.cc test-string-c++2.cc \
+ signature.h test-string.c test-strnlen.c zerosize-ptr.h \
+ signature.h macros.h test-strsignal.c signature.h macros.h \
+ test-strstr.c zerosize-ptr.h signature.h macros.h \
+ test-strtod.c signature.h minus-zero.h macros.h symlink.c \
+ test-symlink.h test-symlink.c signature.h macros.h \
+ test-sys_stat-c++.cc signature.h test-sys_stat.c \
+ test-sys_time-c++.cc signature.h test-sys_time.c \
+ test-sys_wait-c++.cc signature.h test-sys_wait.c \
+ test-sys_wait.h test-time-c++.cc test-time-c++2.cc signature.h \
+ test-time.c test-unistd-c++.cc signature.h test-dup-safer.c \
+ macros.h test-unistd.c unsetenv.c test-unsetenv.c signature.h \
+ macros.h test-update-copyright.sh test-vasnprintf.c macros.h \
+ test-vasprintf-posix.c minus-zero.h nan.h macros.h \
+ test-vasprintf.c signature.h macros.h \
+ test-vc-list-files-git.sh test-vc-list-files-cvs.sh init.sh \
+ test-verify.c test-verify.sh init.sh test-version-etc.c \
+ test-version-etc.sh $(top_srcdir)/build-aux/warn-on-use.h \
+ test-wchar-c++.cc signature.h test-wchar.c test-wcrtomb.sh \
+ test-wcrtomb.c test-wcrtomb-w32-1.sh test-wcrtomb-w32-2.sh \
+ test-wcrtomb-w32-3.sh test-wcrtomb-w32-4.sh \
+ test-wcrtomb-w32-5.sh test-wcrtomb-w32.c signature.h macros.h \
+ wctob.c wctomb-impl.h wctomb.c test-wctype-h-c++.cc \
+ signature.h test-wctype-h.c macros.h test-xalloc-die.c \
+ test-xalloc-die.sh init.sh 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.
+
+# 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 c++defs.h locale.h $(am__append_11) \
+ warn-on-use.h
+SUFFIXES =
+MOSTLYCLEANFILES = core *.stackdump arg-nonnull.h arg-nonnull.h-t \
+ c++defs.h c++defs.h-t t-c-stack.tmp t-c-stack2.tmp \
+ test-fflush.txt test-fpending.t t-fpurge.tmp t-freading.tmp \
+ t-ftell3.tmp t-ftello3.tmp locale.h locale.h-t \
+ $(am__append_12) warn-on-use.h warn-on-use.h-t
+MOSTLYCLEANDIRS =
+CLEANFILES =
+DISTCLEANFILES =
+MAINTAINERCLEANFILES =
+AM_CPPFLAGS = \
+ -D@M4tests_WITNESS@=1 \
+ -I. -I$(srcdir) \
+ -I.. -I$(srcdir)/.. \
+ -I../lib -I$(srcdir)/../lib
+
+LDADD = libtests.a ../lib/libm4.a libtests.a $(LIBTESTS_LIBDEPS)
+libtests_a_SOURCES = gl_array_list.h gl_array_list.c gl_array_oset.h \
+ gl_array_oset.c c-strcase.h c-strcasecmp.c c-strncasecmp.c \
+ localename.c
+libtests_a_LIBADD = $(M4tests_LIBOBJS)
+libtests_a_DEPENDENCIES = $(M4tests_LIBOBJS)
+EXTRA_libtests_a_SOURCES = ftell.c getpagesize.c link.c putenv.c \
+ setenv.c setlocale.c strdup.c symlink.c unsetenv.c wctob.c \
+ wctomb.c
+AM_LIBTOOLFLAGS = --preserve-dup-deps
+ARG_NONNULL_H = arg-nonnull.h
+test_array_oset_LDADD = $(LDADD) @LIBINTL@
+CXXDEFS_H = c++defs.h
+test_c_stack_LDADD = $(LDADD) $(LIBCSTACK) @LIBINTL@
+test_closein_LDADD = $(LDADD) @LIBINTL@
+test_dirname_LDADD = $(LDADD) @LIBINTL@
+@ANSICXX_TRUE@test_fcntl_h_c___SOURCES = test-fcntl-h-c++.cc
+@ANSICXX_TRUE@test_fcntl_h_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIBSOCKET)
+test_filenamecat_LDADD = $(LDADD) @LIBINTL@
+test_frexp_nolibm_SOURCES = test-frexp.c
+test_frexpl_nolibm_SOURCES = test-frexpl.c
+test_getopt_LDADD = $(LDADD) $(LIBINTL)
+@ANSICXX_TRUE@test_langinfo_c___SOURCES = test-langinfo-c++.cc
+@ANSICXX_TRUE@test_locale_c___SOURCES = test-locale-c++.cc test-locale-c++2.cc
+test_localename_LDADD = $(LDADD) @INTL_MACOSX_LIBS@
+@ANSICXX_TRUE@test_math_c___SOURCES = test-math-c++.cc test-math-c++2.cc
+test_quotearg_simple_LDADD = $(LDADD) @LIBINTL@
+@ANSICXX_TRUE@test_signal_c___SOURCES = test-signal-c++.cc test-signal-c++2.cc
+@ANSICXX_TRUE@test_signal_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP)
+@ANSICXX_TRUE@test_spawn_c___SOURCES = test-spawn-c++.cc
+@ANSICXX_TRUE@test_spawn_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP)
+test_spawn_pipe_LDADD = $(LDADD) @LIBINTL@
+@ANSICXX_TRUE@test_stdio_c___SOURCES = test-stdio-c++.cc test-stdio-c++2.cc
+@ANSICXX_TRUE@test_stdio_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP) $(LIB_EACCESS)
+@ANSICXX_TRUE@test_stdlib_c___SOURCES = test-stdlib-c++.cc test-stdlib-c++2.cc
+@ANSICXX_TRUE@test_stdlib_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)
+@ANSICXX_TRUE@test_string_c___SOURCES = test-string-c++.cc test-string-c++2.cc
+@ANSICXX_TRUE@test_string_c___LDADD = $(LDADD) $(LIBINTL)
+test_strsignal_LDADD = $(LDADD) @LIBINTL@ $(LIBTHREAD)
+@ANSICXX_TRUE@test_sys_stat_c___SOURCES = test-sys_stat-c++.cc
+@ANSICXX_TRUE@test_sys_stat_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_CLOCK_GETTIME)
+@ANSICXX_TRUE@test_sys_time_c___SOURCES = test-sys_time-c++.cc
+@ANSICXX_TRUE@test_sys_time_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP)
+@ANSICXX_TRUE@test_sys_wait_c___SOURCES = test-sys_wait-c++.cc
+@ANSICXX_TRUE@test_time_c___SOURCES = test-time-c++.cc test-time-c++2.cc
+@ANSICXX_TRUE@test_time_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP)
+@ANSICXX_TRUE@test_unistd_c___SOURCES = test-unistd-c++.cc
+@ANSICXX_TRUE@test_unistd_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIBSOCKET)
+test_version_etc_LDADD = $(LDADD) @LIBINTL@
+WARN_ON_USE_H = warn-on-use.h
+@ANSICXX_TRUE@test_wchar_c___SOURCES = test-wchar-c++.cc
+@ANSICXX_TRUE@test_wchar_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP) $(LIB_EACCESS)
+@ANSICXX_TRUE@test_wctype_h_c___SOURCES = test-wctype-h-c++.cc
+@ANSICXX_TRUE@test_wctype_h_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP) $(LIB_EACCESS)
+test_xalloc_die_LDADD = $(LDADD) @LIBINTL@
+test_xvasprintf_LDADD = $(LDADD) @LIBINTL@
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .html .log .o .obj .test .test$(EXEEXT)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/gnulib.mk $(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/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/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:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+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-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-stack$(EXEEXT): $(test_c_stack_OBJECTS) $(test_c_stack_DEPENDENCIES)
+ @rm -f test-c-stack$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_c_stack_OBJECTS) $(test_c_stack_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-fcntl-h-c++$(EXEEXT): $(test_fcntl_h_c___OBJECTS) $(test_fcntl_h_c___DEPENDENCIES)
+ @rm -f test-fcntl-h-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_fcntl_h_c___OBJECTS) $(test_fcntl_h_c___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-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-ftell$(EXEEXT): $(test_ftell_OBJECTS) $(test_ftell_DEPENDENCIES)
+ @rm -f test-ftell$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ftell_OBJECTS) $(test_ftell_LDADD) $(LIBS)
+test-ftell3$(EXEEXT): $(test_ftell3_OBJECTS) $(test_ftell3_DEPENDENCIES)
+ @rm -f test-ftell3$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ftell3_OBJECTS) $(test_ftell3_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-ftello3$(EXEEXT): $(test_ftello3_OBJECTS) $(test_ftello3_DEPENDENCIES)
+ @rm -f test-ftello3$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ftello3_OBJECTS) $(test_ftello3_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-getopt$(EXEEXT): $(test_getopt_OBJECTS) $(test_getopt_DEPENDENCIES)
+ @rm -f test-getopt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_getopt_OBJECTS) $(test_getopt_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-ignore-value$(EXEEXT): $(test_ignore_value_OBJECTS) $(test_ignore_value_DEPENDENCIES)
+ @rm -f test-ignore-value$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ignore_value_OBJECTS) $(test_ignore_value_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-langinfo-c++$(EXEEXT): $(test_langinfo_c___OBJECTS) $(test_langinfo_c___DEPENDENCIES)
+ @rm -f test-langinfo-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_langinfo_c___OBJECTS) $(test_langinfo_c___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-locale$(EXEEXT): $(test_locale_OBJECTS) $(test_locale_DEPENDENCIES)
+ @rm -f test-locale$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_locale_OBJECTS) $(test_locale_LDADD) $(LIBS)
+test-locale-c++$(EXEEXT): $(test_locale_c___OBJECTS) $(test_locale_c___DEPENDENCIES)
+ @rm -f test-locale-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_locale_c___OBJECTS) $(test_locale_c___LDADD) $(LIBS)
+test-localename$(EXEEXT): $(test_localename_OBJECTS) $(test_localename_DEPENDENCIES)
+ @rm -f test-localename$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_localename_OBJECTS) $(test_localename_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-malloc-gnu$(EXEEXT): $(test_malloc_gnu_OBJECTS) $(test_malloc_gnu_DEPENDENCIES)
+ @rm -f test-malloc-gnu$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_malloc_gnu_OBJECTS) $(test_malloc_gnu_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-math-c++$(EXEEXT): $(test_math_c___OBJECTS) $(test_math_c___DEPENDENCIES)
+ @rm -f test-math-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_math_c___OBJECTS) $(test_math_c___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-mbrtowc-w32$(EXEEXT): $(test_mbrtowc_w32_OBJECTS) $(test_mbrtowc_w32_DEPENDENCIES)
+ @rm -f test-mbrtowc-w32$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_mbrtowc_w32_OBJECTS) $(test_mbrtowc_w32_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-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-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-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-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-simple$(EXEEXT): $(test_quotearg_simple_OBJECTS) $(test_quotearg_simple_DEPENDENCIES)
+ @rm -f test-quotearg-simple$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_quotearg_simple_OBJECTS) $(test_quotearg_simple_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-setlocale1$(EXEEXT): $(test_setlocale1_OBJECTS) $(test_setlocale1_DEPENDENCIES)
+ @rm -f test-setlocale1$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_setlocale1_OBJECTS) $(test_setlocale1_LDADD) $(LIBS)
+test-setlocale2$(EXEEXT): $(test_setlocale2_OBJECTS) $(test_setlocale2_DEPENDENCIES)
+ @rm -f test-setlocale2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_setlocale2_OBJECTS) $(test_setlocale2_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-signal-c++$(EXEEXT): $(test_signal_c___OBJECTS) $(test_signal_c___DEPENDENCIES)
+ @rm -f test-signal-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_signal_c___OBJECTS) $(test_signal_c___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-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-spawn-c++$(EXEEXT): $(test_spawn_c___OBJECTS) $(test_spawn_c___DEPENDENCIES)
+ @rm -f test-spawn-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_spawn_c___OBJECTS) $(test_spawn_c___LDADD) $(LIBS)
+test-spawn-pipe$(EXEEXT): $(test_spawn_pipe_OBJECTS) $(test_spawn_pipe_DEPENDENCIES)
+ @rm -f test-spawn-pipe$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_spawn_pipe_OBJECTS) $(test_spawn_pipe_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-stdio-c++$(EXEEXT): $(test_stdio_c___OBJECTS) $(test_stdio_c___DEPENDENCIES)
+ @rm -f test-stdio-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_stdio_c___OBJECTS) $(test_stdio_c___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-stdlib-c++$(EXEEXT): $(test_stdlib_c___OBJECTS) $(test_stdlib_c___DEPENDENCIES)
+ @rm -f test-stdlib-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_stdlib_c___OBJECTS) $(test_stdlib_c___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-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-string-c++$(EXEEXT): $(test_string_c___OBJECTS) $(test_string_c___DEPENDENCIES)
+ @rm -f test-string-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_string_c___OBJECTS) $(test_string_c___LDADD) $(LIBS)
+test-strnlen$(EXEEXT): $(test_strnlen_OBJECTS) $(test_strnlen_DEPENDENCIES)
+ @rm -f test-strnlen$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_strnlen_OBJECTS) $(test_strnlen_LDADD) $(LIBS)
+test-strsignal$(EXEEXT): $(test_strsignal_OBJECTS) $(test_strsignal_DEPENDENCIES)
+ @rm -f test-strsignal$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_strsignal_OBJECTS) $(test_strsignal_LDADD) $(LIBS)
+test-strstr$(EXEEXT): $(test_strstr_OBJECTS) $(test_strstr_DEPENDENCIES)
+ @rm -f test-strstr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_strstr_OBJECTS) $(test_strstr_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_stat-c++$(EXEEXT): $(test_sys_stat_c___OBJECTS) $(test_sys_stat_c___DEPENDENCIES)
+ @rm -f test-sys_stat-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_sys_stat_c___OBJECTS) $(test_sys_stat_c___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_time-c++$(EXEEXT): $(test_sys_time_c___OBJECTS) $(test_sys_time_c___DEPENDENCIES)
+ @rm -f test-sys_time-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_sys_time_c___OBJECTS) $(test_sys_time_c___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-sys_wait-c++$(EXEEXT): $(test_sys_wait_c___OBJECTS) $(test_sys_wait_c___DEPENDENCIES)
+ @rm -f test-sys_wait-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_sys_wait_c___OBJECTS) $(test_sys_wait_c___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)
+test-time-c++$(EXEEXT): $(test_time_c___OBJECTS) $(test_time_c___DEPENDENCIES)
+ @rm -f test-time-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_time_c___OBJECTS) $(test_time_c___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-unistd-c++$(EXEEXT): $(test_unistd_c___OBJECTS) $(test_unistd_c___DEPENDENCIES)
+ @rm -f test-unistd-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_unistd_c___OBJECTS) $(test_unistd_c___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-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-verify$(EXEEXT): $(test_verify_OBJECTS) $(test_verify_DEPENDENCIES)
+ @rm -f test-verify$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_verify_OBJECTS) $(test_verify_LDADD) $(LIBS)
+test-version-etc$(EXEEXT): $(test_version_etc_OBJECTS) $(test_version_etc_DEPENDENCIES)
+ @rm -f test-version-etc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_version_etc_OBJECTS) $(test_version_etc_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-wchar-c++$(EXEEXT): $(test_wchar_c___OBJECTS) $(test_wchar_c___DEPENDENCIES)
+ @rm -f test-wchar-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_wchar_c___OBJECTS) $(test_wchar_c___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-wcrtomb-w32$(EXEEXT): $(test_wcrtomb_w32_OBJECTS) $(test_wcrtomb_w32_DEPENDENCIES)
+ @rm -f test-wcrtomb-w32$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_wcrtomb_w32_OBJECTS) $(test_wcrtomb_w32_LDADD) $(LIBS)
+test-wctype-h$(EXEEXT): $(test_wctype_h_OBJECTS) $(test_wctype_h_DEPENDENCIES)
+ @rm -f test-wctype-h$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_wctype_h_OBJECTS) $(test_wctype_h_LDADD) $(LIBS)
+test-wctype-h-c++$(EXEEXT): $(test_wctype_h_c___OBJECTS) $(test_wctype_h_c___DEPENDENCIES)
+ @rm -f test-wctype-h-c++$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(test_wctype_h_c___OBJECTS) $(test_wctype_h_c___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-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)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-strcasecmp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-strncasecmp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftell.Po@am__quote@
+@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)/localename.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putenv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setenv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setlocale.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-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-stack.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-c++.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-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-ftell.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ftell3.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ftello.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ftello3.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-getdtablesize.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-getopt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-gettimeofday.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ignore-value.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-c++.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-locale-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-locale-c++2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-locale.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-localename.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-malloc-gnu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-malloca.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-math-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-math-c++2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-math.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-mbrtowc-w32.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-memchr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-memchr2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nl_langinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-open.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-simple.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-setlocale1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-setlocale2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sigaction.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-signal-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-signal-c++2.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.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-spawn-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-spawn-pipe.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-spawn.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-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stdio-c++2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stdio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stdlib-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-stdlib-c++2.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-string-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-string-c++2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-string.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-strnlen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-strsignal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-strstr.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-c++.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-c++.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-c++.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-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-time-c++2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-time.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-unistd-c++.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.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-verify.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-version-etc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wchar-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wchar.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wcrtomb-w32.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wcrtomb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wctype-h-c++.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wctype-h.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-xalloc-die.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-xvasprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unsetenv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wctob.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wctomb.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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 $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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 `$(CYGPATH_W) '$<'`
+
+.cc.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+# 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-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-stack.sh.log: test-c-stack.sh
+ @p='test-c-stack.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-c-stack2.sh.log: test-c-stack2.sh
+ @p='test-c-stack2.sh'; $(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-c++.log: test-fcntl-h-c++$(EXEEXT)
+ @p='test-fcntl-h-c++$(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-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-ftell.sh.log: test-ftell.sh
+ @p='test-ftell.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-ftell2.sh.log: test-ftell2.sh
+ @p='test-ftell2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-ftell3.log: test-ftell3$(EXEEXT)
+ @p='test-ftell3$(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-ftello3.log: test-ftello3$(EXEEXT)
+ @p='test-ftello3$(EXEEXT)'; $(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-getopt.log: test-getopt$(EXEEXT)
+ @p='test-getopt$(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-ignore-value.log: test-ignore-value$(EXEEXT)
+ @p='test-ignore-value$(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-c++.log: test-langinfo-c++$(EXEEXT)
+ @p='test-langinfo-c++$(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-locale-c++.log: test-locale-c++$(EXEEXT)
+ @p='test-locale-c++$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-locale.log: test-locale$(EXEEXT)
+ @p='test-locale$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-localename.log: test-localename$(EXEEXT)
+ @p='test-localename$(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-malloc-gnu.log: test-malloc-gnu$(EXEEXT)
+ @p='test-malloc-gnu$(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-c++.log: test-math-c++$(EXEEXT)
+ @p='test-math-c++$(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-mbrtowc-w32-1.sh.log: test-mbrtowc-w32-1.sh
+ @p='test-mbrtowc-w32-1.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbrtowc-w32-2.sh.log: test-mbrtowc-w32-2.sh
+ @p='test-mbrtowc-w32-2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbrtowc-w32-3.sh.log: test-mbrtowc-w32-3.sh
+ @p='test-mbrtowc-w32-3.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbrtowc-w32-4.sh.log: test-mbrtowc-w32-4.sh
+ @p='test-mbrtowc-w32-4.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-mbrtowc-w32-5.sh.log: test-mbrtowc-w32-5.sh
+ @p='test-mbrtowc-w32-5.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-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-nl_langinfo.sh.log: test-nl_langinfo.sh
+ @p='test-nl_langinfo.sh'; $(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-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-simple.log: test-quotearg-simple$(EXEEXT)
+ @p='test-quotearg-simple$(EXEEXT)'; $(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-setlocale1.sh.log: test-setlocale1.sh
+ @p='test-setlocale1.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-setlocale2.sh.log: test-setlocale2.sh
+ @p='test-setlocale2.sh'; $(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-c++.log: test-signal-c++$(EXEEXT)
+ @p='test-signal-c++$(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.log: test-snprintf$(EXEEXT)
+ @p='test-snprintf$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-spawn-c++.log: test-spawn-c++$(EXEEXT)
+ @p='test-spawn-c++$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-spawn-pipe.sh.log: test-spawn-pipe.sh
+ @p='test-spawn-pipe.sh'; $(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-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-c++.log: test-stdio-c++$(EXEEXT)
+ @p='test-stdio-c++$(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-c++.log: test-stdlib-c++$(EXEEXT)
+ @p='test-stdlib-c++$(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-string-c++.log: test-string-c++$(EXEEXT)
+ @p='test-string-c++$(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-strnlen.log: test-strnlen$(EXEEXT)
+ @p='test-strnlen$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-strsignal.log: test-strsignal$(EXEEXT)
+ @p='test-strsignal$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-strstr.log: test-strstr$(EXEEXT)
+ @p='test-strstr$(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-c++.log: test-sys_stat-c++$(EXEEXT)
+ @p='test-sys_stat-c++$(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-c++.log: test-sys_time-c++$(EXEEXT)
+ @p='test-sys_time-c++$(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-c++.log: test-sys_wait-c++$(EXEEXT)
+ @p='test-sys_wait-c++$(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-c++.log: test-time-c++$(EXEEXT)
+ @p='test-time-c++$(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-unistd-c++.log: test-unistd-c++$(EXEEXT)
+ @p='test-unistd-c++$(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-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.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-verify.log: test-verify$(EXEEXT)
+ @p='test-verify$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-verify.sh.log: test-verify.sh
+ @p='test-verify.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-version-etc.sh.log: test-version-etc.sh
+ @p='test-version-etc.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wchar-c++.log: test-wchar-c++$(EXEEXT)
+ @p='test-wchar-c++$(EXEEXT)'; $(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-wcrtomb-w32-1.sh.log: test-wcrtomb-w32-1.sh
+ @p='test-wcrtomb-w32-1.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wcrtomb-w32-2.sh.log: test-wcrtomb-w32-2.sh
+ @p='test-wcrtomb-w32-2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wcrtomb-w32-3.sh.log: test-wcrtomb-w32-3.sh
+ @p='test-wcrtomb-w32-3.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wcrtomb-w32-4.sh.log: test-wcrtomb-w32-4.sh
+ @p='test-wcrtomb-w32-4.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wcrtomb-w32-5.sh.log: test-wcrtomb-w32-5.sh
+ @p='test-wcrtomb-w32-5.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wctype-h-c++.log: test-wctype-h-c++$(EXEEXT)
+ @p='test-wctype-h-c++$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+test-wctype-h.log: test-wctype-h$(EXEEXT)
+ @p='test-wctype-h$(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-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)
+ -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-local clean-noinstLIBRARIES clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(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)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ 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-local clean-noinstLIBRARIES clean-noinstPROGRAMS ctags \
+ ctags-recursive distclean distclean-compile distclean-generic \
+ 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-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 $@
+# The c++defs.h that gets inserted into generated .h files is the same as
+# build-aux/c++defs.h, except that it has the copyright header cut off.
+c++defs.h: $(top_srcdir)/build-aux/c++defs.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/_GL_CXXDEFS/,$$p' \
+ < $(top_srcdir)/build-aux/c++defs.h \
+ > $@-t && \
+ mv $@-t $@
+
+# We need the following in order to create <locale.h> when the system
+# doesn't have one that provides all definitions.
+locale.h: locale.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_LOCALE_H''@|$(NEXT_LOCALE_H)|g' \
+ -e 's|@''GNULIB_SETLOCALE''@|$(GNULIB_SETLOCALE)|g' \
+ -e 's|@''GNULIB_DUPLOCALE''@|$(GNULIB_DUPLOCALE)|g' \
+ -e 's|@''HAVE_DUPLOCALE''@|$(HAVE_DUPLOCALE)|g' \
+ -e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \
+ -e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \
+ -e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+ < $(srcdir)/locale.in.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/c-strcase.h b/tests/c-strcase.h
new file mode 100644
index 0000000..4148c34
--- /dev/null
+++ b/tests/c-strcase.h
@@ -0,0 +1,56 @@
+/* Case-insensitive string comparison functions in C locale.
+ Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2011 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. */
+
+#ifndef C_STRCASE_H
+#define C_STRCASE_H
+
+#include <stddef.h>
+
+
+/* The functions defined in this file assume the "C" locale and a character
+ set without diacritics (ASCII-US or EBCDIC-US or something like that).
+ Even if the "C" locale on a particular system is an extension of the ASCII
+ character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
+ is ISO-8859-1), the functions in this file recognize only the ASCII
+ characters. More precisely, one of the string arguments must be an ASCII
+ string; the other one can also contain non-ASCII characters (but then
+ the comparison result will be nonzero). */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
+ greater than zero if S1 is lexicographically less than, equal to or greater
+ than S2. */
+extern int c_strcasecmp (const char *s1, const char *s2);
+
+/* Compare no more than N characters of strings S1 and S2, ignoring case,
+ returning less than, equal to or greater than zero if S1 is
+ lexicographically less than, equal to or greater than S2. */
+extern int c_strncasecmp (const char *s1, const char *s2, size_t n);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* C_STRCASE_H */
diff --git a/tests/c-strcasecmp.c b/tests/c-strcasecmp.c
new file mode 100644
index 0000000..4c4e106
--- /dev/null
+++ b/tests/c-strcasecmp.c
@@ -0,0 +1,57 @@
+/* c-strcasecmp.c -- case insensitive string comparator in C locale
+ Copyright (C) 1998-1999, 2005-2006, 2009-2011 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 "c-strcase.h"
+
+#include <limits.h>
+
+#include "c-ctype.h"
+
+int
+c_strcasecmp (const char *s1, const char *s2)
+{
+ register const unsigned char *p1 = (const unsigned char *) s1;
+ register const unsigned char *p2 = (const unsigned char *) s2;
+ unsigned char c1, c2;
+
+ if (p1 == p2)
+ return 0;
+
+ do
+ {
+ c1 = c_tolower (*p1);
+ c2 = c_tolower (*p2);
+
+ if (c1 == '\0')
+ break;
+
+ ++p1;
+ ++p2;
+ }
+ while (c1 == c2);
+
+ if (UCHAR_MAX <= INT_MAX)
+ return c1 - c2;
+ else
+ /* On machines where 'char' and 'int' are types of the same size, the
+ difference of two 'unsigned char' values - including the sign bit -
+ doesn't fit in an 'int'. */
+ return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
+}
diff --git a/tests/c-strncasecmp.c b/tests/c-strncasecmp.c
new file mode 100644
index 0000000..0c433b9
--- /dev/null
+++ b/tests/c-strncasecmp.c
@@ -0,0 +1,57 @@
+/* c-strncasecmp.c -- case insensitive string comparator in C locale
+ Copyright (C) 1998-1999, 2005-2006, 2009-2011 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 "c-strcase.h"
+
+#include <limits.h>
+
+#include "c-ctype.h"
+
+int
+c_strncasecmp (const char *s1, const char *s2, size_t n)
+{
+ register const unsigned char *p1 = (const unsigned char *) s1;
+ register const unsigned char *p2 = (const unsigned char *) s2;
+ unsigned char c1, c2;
+
+ if (p1 == p2 || n == 0)
+ return 0;
+
+ do
+ {
+ c1 = c_tolower (*p1);
+ c2 = c_tolower (*p2);
+
+ if (--n == 0 || c1 == '\0')
+ break;
+
+ ++p1;
+ ++p2;
+ }
+ while (c1 == c2);
+
+ if (UCHAR_MAX <= INT_MAX)
+ return c1 - c2;
+ else
+ /* On machines where 'char' and 'int' are types of the same size, the
+ difference of two 'unsigned char' values - including the sign bit -
+ doesn't fit in an 'int'. */
+ return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
+}
diff --git a/tests/ftell.c b/tests/ftell.c
new file mode 100644
index 0000000..79083fb
--- /dev/null
+++ b/tests/ftell.c
@@ -0,0 +1,38 @@
+/* An ftell() function that works around platform bugs.
+ Copyright (C) 2007-2011 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 <stdio.h>
+
+#include <errno.h>
+/* Get off_t. */
+#include <unistd.h>
+
+long
+ftell (FILE *fp)
+{
+ /* Use the replacement ftello function with all its workarounds. */
+ off_t offset = ftello (fp);
+ if (offset == (long)offset)
+ return (long)offset;
+ else
+ {
+ errno = EOVERFLOW;
+ return -1;
+ }
+}
diff --git a/tests/getpagesize.c b/tests/getpagesize.c
new file mode 100644
index 0000000..d7c1ba8
--- /dev/null
+++ b/tests/getpagesize.c
@@ -0,0 +1,39 @@
+/* getpagesize emulation for systems where it cannot be done in a C macro.
+
+ Copyright (C) 2007, 2009-2011 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/gl_array_list.c b/tests/gl_array_list.c
new file mode 100644
index 0000000..d0e2336
--- /dev/null
+++ b/tests/gl_array_list.c
@@ -0,0 +1,680 @@
+/* Sequential list data type implemented by an array.
+ Copyright (C) 2006-2011 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/gl_array_list.h b/tests/gl_array_list.h
new file mode 100644
index 0000000..72e8062
--- /dev/null
+++ b/tests/gl_array_list.h
@@ -0,0 +1,34 @@
+/* Sequential list data type implemented by an array.
+ Copyright (C) 2006, 2009-2011 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/gl_array_oset.c b/tests/gl_array_oset.c
new file mode 100644
index 0000000..ca2419c
--- /dev/null
+++ b/tests/gl_array_oset.c
@@ -0,0 +1,357 @@
+/* Ordered set data type implemented by an array.
+ Copyright (C) 2006-2007, 2009-2011 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/gl_array_oset.h b/tests/gl_array_oset.h
new file mode 100644
index 0000000..79a6404
--- /dev/null
+++ b/tests/gl_array_oset.h
@@ -0,0 +1,34 @@
+/* Ordered set data type implemented by an array.
+ Copyright (C) 2006, 2009-2011 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/gnulib.mk b/tests/gnulib.mk
new file mode 100644
index 0000000..f05a797
--- /dev/null
+++ b/tests/gnulib.mk
@@ -0,0 +1,1400 @@
+## DO NOT EDIT! GENERATED AUTOMATICALLY!
+## Process this file with automake to produce Makefile.in.
+# Copyright (C) 2002-2011 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
+
+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 = \
+ -D@M4tests_WITNESS@=1 \
+ -I. -I$(srcdir) \
+ -I.. -I$(srcdir)/.. \
+ -I../lib -I$(srcdir)/../lib
+
+LDADD = libtests.a ../lib/libm4.a 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 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++defs
+
+# 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 += c++defs.h
+# The c++defs.h that gets inserted into generated .h files is the same as
+# build-aux/c++defs.h, except that it has the copyright header cut off.
+c++defs.h: $(top_srcdir)/build-aux/c++defs.h
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed -n -e '/_GL_CXXDEFS/,$$p' \
+ < $(top_srcdir)/build-aux/c++defs.h \
+ > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += c++defs.h c++defs.h-t
+
+CXXDEFS_H=c++defs.h
+
+EXTRA_DIST += $(top_srcdir)/build-aux/c++defs.h
+
+## end gnulib module c++defs
+
+## 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-stack-tests
+
+TESTS += test-c-stack.sh test-c-stack2.sh
+TESTS_ENVIRONMENT += LIBSIGSEGV='@LIBSIGSEGV@'
+check_PROGRAMS += test-c-stack
+test_c_stack_LDADD = $(LDADD) $(LIBCSTACK) @LIBINTL@
+MOSTLYCLEANFILES += t-c-stack.tmp t-c-stack2.tmp
+EXTRA_DIST += test-c-stack.c test-c-stack.sh test-c-stack2.sh macros.h
+
+## end gnulib module c-stack-tests
+
+## begin gnulib module c-strcase
+
+libtests_a_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c
+
+## end gnulib module c-strcase
+
+## 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-c++-tests
+
+if ANSICXX
+TESTS += test-fcntl-h-c++
+check_PROGRAMS += test-fcntl-h-c++
+test_fcntl_h_c___SOURCES = test-fcntl-h-c++.cc
+test_fcntl_h_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIBSOCKET)
+endif
+EXTRA_DIST += test-fcntl-h-c++.cc signature.h
+
+## end gnulib module fcntl-h-c++-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 frexp-nolibm-tests
+
+TESTS += test-frexp-nolibm
+check_PROGRAMS += test-frexp-nolibm
+test_frexp_nolibm_SOURCES = test-frexp.c
+EXTRA_DIST += test-frexp.c minus-zero.h nan.h 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 minus-zero.h nan.h 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 ftell
+
+
+EXTRA_DIST += ftell.c
+
+EXTRA_libtests_a_SOURCES += ftell.c
+
+## end gnulib module ftell
+
+## begin gnulib module ftell-tests
+
+TESTS += test-ftell.sh test-ftell2.sh test-ftell3
+check_PROGRAMS += test-ftell test-ftell3
+MOSTLYCLEANFILES += t-ftell3.tmp
+EXTRA_DIST += test-ftell.c test-ftell.sh test-ftell2.sh test-ftell3.c signature.h macros.h
+
+## end gnulib module ftell-tests
+
+## begin gnulib module ftello-tests
+
+TESTS += test-ftello.sh test-ftello2.sh test-ftello3
+check_PROGRAMS += test-ftello test-ftello3
+MOSTLYCLEANFILES += t-ftello3.tmp
+EXTRA_DIST += test-ftello.c test-ftello.sh test-ftello2.sh test-ftello3.c 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 getopt-posix-tests
+
+TESTS += test-getopt
+check_PROGRAMS += test-getopt
+test_getopt_LDADD = $(LDADD) $(LIBINTL)
+EXTRA_DIST += macros.h signature.h test-getopt.c test-getopt.h test-getopt_long.h
+
+## end gnulib module getopt-posix-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 ignore-value-tests
+
+TESTS += test-ignore-value
+check_PROGRAMS += test-ignore-value
+EXTRA_DIST += test-ignore-value.c
+
+## end gnulib module ignore-value-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 minus-zero.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 minus-zero.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 minus-zero.h nan.h macros.h
+
+## end gnulib module isnanl-nolibm-tests
+
+## begin gnulib module langinfo-c++-tests
+
+if ANSICXX
+TESTS += test-langinfo-c++
+check_PROGRAMS += test-langinfo-c++
+test_langinfo_c___SOURCES = test-langinfo-c++.cc
+endif
+EXTRA_DIST += test-langinfo-c++.cc signature.h
+
+## end gnulib module langinfo-c++-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 locale
+
+BUILT_SOURCES += locale.h
+
+# We need the following in order to create <locale.h> when the system
+# doesn't have one that provides all definitions.
+locale.h: locale.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_LOCALE_H''@|$(NEXT_LOCALE_H)|g' \
+ -e 's|@''GNULIB_SETLOCALE''@|$(GNULIB_SETLOCALE)|g' \
+ -e 's|@''GNULIB_DUPLOCALE''@|$(GNULIB_DUPLOCALE)|g' \
+ -e 's|@''HAVE_DUPLOCALE''@|$(HAVE_DUPLOCALE)|g' \
+ -e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \
+ -e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \
+ -e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+ < $(srcdir)/locale.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += locale.h locale.h-t
+
+EXTRA_DIST += locale.in.h
+
+## end gnulib module locale
+
+## begin gnulib module locale-c++-tests
+
+if ANSICXX
+TESTS += test-locale-c++
+check_PROGRAMS += test-locale-c++
+test_locale_c___SOURCES = test-locale-c++.cc test-locale-c++2.cc
+endif
+EXTRA_DIST += test-locale-c++.cc test-locale-c++2.cc signature.h
+
+## end gnulib module locale-c++-tests
+
+## begin gnulib module locale-tests
+
+TESTS += test-locale
+check_PROGRAMS += test-locale
+EXTRA_DIST += test-locale.c
+
+## end gnulib module locale-tests
+
+## begin gnulib module localename
+
+libtests_a_SOURCES += localename.c
+
+EXTRA_DIST += localename.h
+
+## end gnulib module localename
+
+## begin gnulib module localename-tests
+
+TESTS += test-localename
+check_PROGRAMS += test-localename
+test_localename_LDADD = $(LDADD) @INTL_MACOSX_LIBS@
+
+EXTRA_DIST += test-localename.c macros.h
+
+## end gnulib module localename-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 malloc-gnu-tests
+
+TESTS += test-malloc-gnu
+check_PROGRAMS += test-malloc-gnu
+EXTRA_DIST += test-malloc-gnu.c
+
+## end gnulib module malloc-gnu-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-c++-tests
+
+if ANSICXX
+TESTS += test-math-c++
+check_PROGRAMS += test-math-c++
+test_math_c___SOURCES = test-math-c++.cc test-math-c++2.cc
+endif
+EXTRA_DIST += test-math-c++.cc test-math-c++2.cc signature.h
+
+## end gnulib module math-c++-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 \
+ test-mbrtowc-w32-1.sh test-mbrtowc-w32-2.sh test-mbrtowc-w32-3.sh \
+ test-mbrtowc-w32-4.sh test-mbrtowc-w32-5.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 test-mbrtowc-w32
+
+EXTRA_DIST += test-mbrtowc1.sh test-mbrtowc2.sh test-mbrtowc3.sh test-mbrtowc4.sh test-mbrtowc.c test-mbrtowc-w32-1.sh test-mbrtowc-w32-2.sh test-mbrtowc-w32-3.sh test-mbrtowc-w32-4.sh test-mbrtowc-w32-5.sh test-mbrtowc-w32.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 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 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 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 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-simple-tests
+
+TESTS += test-quotearg-simple
+check_PROGRAMS += test-quotearg-simple
+test_quotearg_simple_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-quotearg-simple.c test-quotearg.h macros.h
+
+## end gnulib module quotearg-simple-tests
+
+## begin gnulib module rawmemchr-tests
+
+TESTS += test-rawmemchr
+check_PROGRAMS += test-rawmemchr
+EXTRA_DIST += test-rawmemchr.c zerosize-ptr.h 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
+
+
+EXTRA_DIST += setenv.c
+
+EXTRA_libtests_a_SOURCES += setenv.c
+
+## end gnulib module setenv
+
+## 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 setlocale
+
+
+EXTRA_DIST += setlocale.c
+
+EXTRA_libtests_a_SOURCES += setlocale.c
+
+## end gnulib module setlocale
+
+## begin gnulib module setlocale-tests
+
+TESTS += test-setlocale1.sh test-setlocale2.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-setlocale1 test-setlocale2
+EXTRA_DIST += test-setlocale1.sh test-setlocale1.c test-setlocale2.sh test-setlocale2.c signature.h macros.h
+
+## end gnulib module setlocale-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-c++-tests
+
+if ANSICXX
+TESTS += test-signal-c++
+check_PROGRAMS += test-signal-c++
+test_signal_c___SOURCES = test-signal-c++.cc test-signal-c++2.cc
+test_signal_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP)
+endif
+EXTRA_DIST += test-signal-c++.cc test-signal-c++2.cc signature.h
+
+## end gnulib module signal-c++-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 minus-zero.h macros.h
+
+## end gnulib module signbit-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-c++-tests
+
+if ANSICXX
+TESTS += test-spawn-c++
+check_PROGRAMS += test-spawn-c++
+test_spawn_c___SOURCES = test-spawn-c++.cc
+test_spawn_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP)
+endif
+EXTRA_DIST += test-spawn-c++.cc signature.h
+
+## end gnulib module spawn-c++-tests
+
+## begin gnulib module spawn-pipe-tests
+
+TESTS += test-spawn-pipe.sh
+check_PROGRAMS += test-spawn-pipe
+test_spawn_pipe_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-spawn-pipe.sh test-spawn-pipe.c macros.h
+
+## end gnulib module spawn-pipe-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 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-c++-tests
+
+if ANSICXX
+TESTS += test-stdio-c++
+check_PROGRAMS += test-stdio-c++
+test_stdio_c___SOURCES = test-stdio-c++.cc test-stdio-c++2.cc
+test_stdio_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP) $(LIB_EACCESS)
+endif
+EXTRA_DIST += test-stdio-c++.cc test-stdio-c++2.cc signature.h
+
+## end gnulib module stdio-c++-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-c++-tests
+
+if ANSICXX
+TESTS += test-stdlib-c++
+check_PROGRAMS += test-stdlib-c++
+test_stdlib_c___SOURCES = test-stdlib-c++.cc test-stdlib-c++2.cc
+test_stdlib_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)
+endif
+EXTRA_DIST += test-stdlib-c++.cc test-stdlib-c++2.cc signature.h
+
+## end gnulib module stdlib-c++-tests
+
+## begin gnulib module stdlib-tests
+
+TESTS += test-stdlib
+check_PROGRAMS += test-stdlib
+EXTRA_DIST += test-stdlib.c test-sys_wait.h
+
+## 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 string-c++-tests
+
+if ANSICXX
+TESTS += test-string-c++
+check_PROGRAMS += test-string-c++
+test_string_c___SOURCES = test-string-c++.cc test-string-c++2.cc
+test_string_c___LDADD = $(LDADD) $(LIBINTL)
+endif
+EXTRA_DIST += test-string-c++.cc test-string-c++2.cc signature.h
+
+## end gnulib module string-c++-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 strnlen-tests
+
+TESTS += test-strnlen
+check_PROGRAMS += test-strnlen
+EXTRA_DIST += test-strnlen.c zerosize-ptr.h signature.h macros.h
+
+## end gnulib module strnlen-tests
+
+## begin gnulib module strsignal-tests
+
+TESTS += test-strsignal
+check_PROGRAMS += test-strsignal
+test_strsignal_LDADD = $(LDADD) @LIBINTL@ $(LIBTHREAD)
+EXTRA_DIST += test-strsignal.c signature.h macros.h
+
+## end gnulib module strsignal-tests
+
+## begin gnulib module strstr-tests
+
+TESTS += test-strstr
+check_PROGRAMS += test-strstr
+EXTRA_DIST += test-strstr.c zerosize-ptr.h signature.h macros.h
+
+## end gnulib module strstr-tests
+
+## begin gnulib module strtod-tests
+
+TESTS += test-strtod
+check_PROGRAMS += test-strtod
+EXTRA_DIST += test-strtod.c signature.h minus-zero.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-c++-tests
+
+if ANSICXX
+TESTS += test-sys_stat-c++
+check_PROGRAMS += test-sys_stat-c++
+test_sys_stat_c___SOURCES = test-sys_stat-c++.cc
+test_sys_stat_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_CLOCK_GETTIME)
+endif
+EXTRA_DIST += test-sys_stat-c++.cc signature.h
+
+## end gnulib module sys_stat-c++-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-c++-tests
+
+if ANSICXX
+TESTS += test-sys_time-c++
+check_PROGRAMS += test-sys_time-c++
+test_sys_time_c___SOURCES = test-sys_time-c++.cc
+test_sys_time_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP)
+endif
+EXTRA_DIST += test-sys_time-c++.cc signature.h
+
+## end gnulib module sys_time-c++-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-c++-tests
+
+if ANSICXX
+TESTS += test-sys_wait-c++
+check_PROGRAMS += test-sys_wait-c++
+test_sys_wait_c___SOURCES = test-sys_wait-c++.cc
+endif
+EXTRA_DIST += test-sys_wait-c++.cc signature.h
+
+## end gnulib module sys_wait-c++-tests
+
+## begin gnulib module sys_wait-tests
+
+TESTS += test-sys_wait
+check_PROGRAMS += test-sys_wait
+EXTRA_DIST += test-sys_wait.c test-sys_wait.h
+
+## end gnulib module sys_wait-tests
+
+## begin gnulib module time-c++-tests
+
+if ANSICXX
+TESTS += test-time-c++
+check_PROGRAMS += test-time-c++
+test_time_c___SOURCES = test-time-c++.cc test-time-c++2.cc
+test_time_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP)
+endif
+EXTRA_DIST += test-time-c++.cc test-time-c++2.cc signature.h
+
+## end gnulib module time-c++-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-c++-tests
+
+if ANSICXX
+TESTS += test-unistd-c++
+check_PROGRAMS += test-unistd-c++
+test_unistd_c___SOURCES = test-unistd-c++.cc
+test_unistd_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIBSOCKET)
+endif
+EXTRA_DIST += test-unistd-c++.cc signature.h
+
+## end gnulib module unistd-c++-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 unsetenv
+
+
+EXTRA_DIST += unsetenv.c
+
+EXTRA_libtests_a_SOURCES += unsetenv.c
+
+## end gnulib module unsetenv
+
+## 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 += abs_aux_dir='$(abs_aux_dir)'
+EXTRA_DIST += test-update-copyright.sh
+
+## end gnulib module update-copyright-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 minus-zero.h 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 += abs_aux_dir='$(abs_aux_dir)'
+EXTRA_DIST += test-vc-list-files-git.sh test-vc-list-files-cvs.sh init.sh
+
+## end gnulib module vc-list-files-tests
+
+## begin gnulib module verify-tests
+
+TESTS_ENVIRONMENT += MAKE='$(MAKE)'
+TESTS += test-verify test-verify.sh
+check_PROGRAMS += test-verify
+EXTRA_DIST += test-verify.c test-verify.sh init.sh
+
+## end gnulib module verify-tests
+
+## begin gnulib module version-etc-tests
+
+TESTS += test-version-etc.sh
+check_PROGRAMS += test-version-etc
+test_version_etc_LDADD = $(LDADD) @LIBINTL@
+EXTRA_DIST += test-version-etc.c test-version-etc.sh
+
+## end gnulib module version-etc-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-c++-tests
+
+if ANSICXX
+TESTS += test-wchar-c++
+check_PROGRAMS += test-wchar-c++
+test_wchar_c___SOURCES = test-wchar-c++.cc
+test_wchar_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP) $(LIB_EACCESS)
+endif
+EXTRA_DIST += test-wchar-c++.cc signature.h
+
+## end gnulib module wchar-c++-tests
+
+## 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 \
+ test-wcrtomb-w32-1.sh test-wcrtomb-w32-2.sh test-wcrtomb-w32-3.sh \
+ test-wcrtomb-w32-4.sh test-wcrtomb-w32-5.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 test-wcrtomb-w32
+
+EXTRA_DIST += test-wcrtomb.sh test-wcrtomb.c test-wcrtomb-w32-1.sh test-wcrtomb-w32-2.sh test-wcrtomb-w32-3.sh test-wcrtomb-w32-4.sh test-wcrtomb-w32-5.sh test-wcrtomb-w32.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 wctomb
+
+
+EXTRA_DIST += wctomb-impl.h wctomb.c
+
+EXTRA_libtests_a_SOURCES += wctomb.c
+
+## end gnulib module wctomb
+
+## begin gnulib module wctype-h-c++-tests
+
+if ANSICXX
+TESTS += test-wctype-h-c++
+check_PROGRAMS += test-wctype-h-c++
+test_wctype_h_c___SOURCES = test-wctype-h-c++.cc
+test_wctype_h_c___LDADD = $(LDADD) $(LIBINTL) $(LIB_NANOSLEEP) $(LIB_EACCESS)
+endif
+EXTRA_DIST += test-wctype-h-c++.cc signature.h
+
+## end gnulib module wctype-h-c++-tests
+
+## begin gnulib module wctype-h-tests
+
+TESTS += test-wctype-h
+check_PROGRAMS += test-wctype-h
+EXTRA_DIST += test-wctype-h.c macros.h
+
+## end gnulib module wctype-h-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 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/init.sh b/tests/init.sh
new file mode 100644
index 0000000..71c6516
--- /dev/null
+++ b/tests/init.sh
@@ -0,0 +1,474 @@
+# source this file; set up for tests
+
+# Copyright (C) 2009-2011 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=.}/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.
+# Note that the "path_prepend_ ." is useful only if the body of your
+# test invokes programs residing in the initial directory.
+# For example, if the programs you want to test are in src/, and this test
+# script is named tests/test-1, then you would use "path_prepend_ ../src",
+# or perhaps export PATH='$(abs_top_builddir)/src$(PATH_SEPARATOR)'"$$PATH"
+# to all tests via automake's TESTS_ENVIRONMENT.
+# 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
+
+ME_=`expr "./$0" : '.*/\(.*\)$'`
+
+# 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; }
+
+# Print warnings (e.g., about skipped and failed tests) to this file number.
+# Override by defining to say, 9, in init.cfg, and putting say,
+# "export ...ENVVAR_SETTINGS...; exec 9>&2; $(SHELL)" in the definition
+# of TESTS_ENVIRONMENT in your tests/Makefile.am file.
+# This is useful when using automake's parallel tests mode, to print
+# the reason for skip/failure to console, rather than to the .log files.
+: ${stderr_fileno_=2}
+
+warn_ () { echo "$@" 1>&$stderr_fileno_; }
+fail_ () { warn_ "$ME_: failed test: $@"; Exit 1; }
+skip_ () { warn_ "$ME_: skipped test: $@"; Exit 77; }
+framework_failure_ () { warn_ "$ME_: set-up failure: $@"; Exit 99; }
+
+# Sanitize this shell to POSIX mode, if possible.
+DUALCASE=1; export DUALCASE
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+ esac
+fi
+
+# 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.
+# If the current shell passes the test, we're done. Otherwise, test other
+# shells until we find one that passes. If one is found, re-exec it.
+# If no acceptable shell is found, skip the current test.
+#
+# The "...set -x; P=1 true 2>err..." test is to disqualify any shell that
+# emits "P=1" into err, as /bin/sh from SunOS 5.11 and OpenBSD 4.7 do.
+#
+# Use "9" to indicate success (rather than 0), in case some shell acts
+# like Solaris 10's /bin/sh but exits successfully instead of with status 2.
+
+# Eval this code in a subshell to determine a shell's suitability.
+# 10 - passes all tests; ok to use
+# 9 - ok, but enabling "set -x" corrupts app stderr; prefer higher score
+# ? - not ok
+gl_shell_test_script_='
+test $(echo y) = y || exit 1
+score_=10
+if test "$VERBOSE" = yes; then
+ test -n "$( (exec 3>&1; set -x; P=1 true 2>&3) 2> /dev/null)" && score_=9
+fi
+test -z "$EXEEXT" && exit $score_
+shopt -s expand_aliases
+alias a-b="echo zoo"
+v=abx
+ test ${v%x} = ab \
+ && test ${v#a} = bx \
+ && test $(a-b) = zoo \
+ && exit $score_
+'
+
+if test "x$1" = "x--no-reexec"; then
+ shift
+else
+ # Assume a working shell. Export to subshells (setup_ needs this).
+ gl_set_x_corrupts_stderr_=false
+ export gl_set_x_corrupts_stderr_
+
+ # Record the first marginally acceptable shell.
+ marginal_=
+
+ # Search for a shell that meets our requirements.
+ for re_shell_ in __current__ "${CONFIG_SHELL:-no_shell}" \
+ /bin/sh bash dash zsh pdksh fail
+ do
+ test "$re_shell_" = no_shell && continue
+
+ # If we've made it all the way to the sentinel, "fail" without
+ # finding even a marginal shell, skip this test.
+ if test "$re_shell_" = fail; then
+ test -z "$marginal_" && skip_ failed to find an adequate shell
+ re_shell_=$marginal_
+ break
+ fi
+
+ # When testing the current shell, simply "eval" the test code.
+ # Otherwise, run it via $re_shell_ -c ...
+ if test "$re_shell_" = __current__; then
+ # 'eval'ing this code makes Solaris 10's /bin/sh exit with
+ # $? set to 2. It does not evaluate any of the code after the
+ # "unexpected" first `('. Thus, we must run it in a subshell.
+ ( eval "$gl_shell_test_script_" ) > /dev/null 2>&1
+ else
+ "$re_shell_" -c "$gl_shell_test_script_" 2>/dev/null
+ fi
+
+ st_=$?
+
+ # $re_shell_ works just fine. Use it.
+ test $st_ = 10 && break
+
+ # If this is our first marginally acceptable shell, remember it.
+ if test "$st_:$marginal_" = 9: ; then
+ marginal_="$re_shell_"
+ gl_set_x_corrupts_stderr_=true
+ fi
+ done
+
+ if test "$re_shell_" != __current__; then
+ # Found a usable shell. Preserve -v and -x.
+ case $- in
+ *v*x* | *x*v*) opts_=-vx ;;
+ *v*) opts_=-v ;;
+ *x*) opts_=-x ;;
+ *) opts_= ;;
+ esac
+ exec "$re_shell_" $opts_ "$0" --no-reexec "$@"
+ echo "$ME_: exec failed" 1>&2
+ exit 127
+ fi
+fi
+
+test -n "$EXEEXT" && shopt -s expand_aliases
+
+# Enable glibc's malloc-perturbing option.
+# This is useful for exposing code that depends on the fact that
+# malloc-related functions often return memory that is mostly zeroed.
+# If you have the time and cycles, use valgrind to do an even better job.
+: ${MALLOC_PERTURB_=87}
+export MALLOC_PERTURB_
+
+# 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 ) > /dev/null 2>&1; then
+ compare () { diff -u "$@"; }
+elif ( cmp --version < /dev/null 2>&1 | grep GNU ) > /dev/null 2>&1; 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
+ # If there was no *.exe file, or there existed a file named "*.exe" that
+ # was deleted between the above glob expansion and the existence test
+ # below, just skip it.
+ test "x$feb_file_" = "x$feb_dir_/*.exe" && test ! -f "$feb_file_" \
+ && continue
+ # Exempt [.exe, since we can't create a function by that name, yet
+ # we can't invoke [ by PATH search anyways due to shell builtins.
+ test "x$feb_file_" = "x$feb_dir_/[.exe" && continue
+ 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 alias 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 0; }
+
+ 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_ ()
+{
+ if test "$VERBOSE" = yes; then
+ # Test whether set -x may cause the selected shell to corrupt an
+ # application's stderr. Many do, including zsh-4.3.10 and the /bin/sh
+ # from SunOS 5.11, OpenBSD 4.7 and Irix 5.x and 6.5.
+ # If enabling verbose output this way would cause trouble, simply
+ # issue a warning and refrain.
+ if $gl_set_x_corrupts_stderr_; then
+ warn_ "using SHELL=$SHELL with 'set -x' corrupts stderr"
+ else
+ set -x
+ fi
+ fi
+
+ initial_cwd_=$PWD
+ fail=0
+
+ pfx_=`testdir_prefix_`
+ test_dir_=`mktempd_ "$initial_cwd_" "$pfx_-$ME_.XXXX"` \
+ || fail_ "failed to create temporary directory in $initial_cwd_"
+ cd "$test_dir_"
+
+ # As autoconf-generated configure scripts do, ensure that IFS
+ # is defined initially, so that saving and restoring $IFS works.
+ gl_init_sh_nl_='
+'
+ IFS=" "" $gl_init_sh_nl_"
+
+ # This trap statement, along with a trap on 0 below, ensure that the
+ # temporary directory, $test_dir_, is removed upon exit as well as
+ # upon receipt of any of the listed signals.
+ for sig_ in 1 2 3 13 15; do
+ eval "trap 'Exit $(expr $sig_ + 128)' $sig_"
+ done
+}
+
+# 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 \
+ | LC_ALL=C 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 \
+ | LC_ALL=C 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
+
+ # First, try to use mktemp.
+ d=`unset 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_ "$@"
+# This trap is here, rather than in the setup_ function, because some
+# shells run the exit trap at shell function exit, rather than script exit.
+trap remove_tmp_ 0
diff --git a/tests/link.c b/tests/link.c
new file mode 100644
index 0000000..60cf708
--- /dev/null
+++ b/tests/link.c
@@ -0,0 +1,203 @@
+/* Emulate link on platforms that lack it, namely native Windows platforms.
+
+ Copyright (C) 2009-2011 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/locale.in.h b/tests/locale.in.h
new file mode 100644
index 0000000..1f9bafd
--- /dev/null
+++ b/tests/locale.in.h
@@ -0,0 +1,96 @@
+/* A POSIX <locale.h>.
+ Copyright (C) 2007-2011 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 _GL_LOCALE_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_LOCALE_H@
+
+#ifndef _GL_LOCALE_H
+#define _GL_LOCALE_H
+
+/* NetBSD 5.0 mis-defines NULL. */
+#include <stddef.h>
+
+/* MacOS X 10.5 defines the locale_t type in <xlocale.h>. */
+#if @HAVE_XLOCALE_H@
+# include <xlocale.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+/* The LC_MESSAGES locale category is specified in POSIX, but not in ISO C.
+ On systems that don't define it, use the same value as GNU libintl. */
+#if !defined LC_MESSAGES
+# define LC_MESSAGES 1729
+#endif
+
+#if @GNULIB_SETLOCALE@
+# if @REPLACE_SETLOCALE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef setlocale
+# define setlocale rpl_setlocale
+# define GNULIB_defined_setlocale 1
+# endif
+_GL_FUNCDECL_RPL (setlocale, char *, (int category, const char *locale));
+_GL_CXXALIAS_RPL (setlocale, char *, (int category, const char *locale));
+# else
+_GL_CXXALIAS_SYS (setlocale, char *, (int category, const char *locale));
+# endif
+_GL_CXXALIASWARN (setlocale);
+#elif defined GNULIB_POSIXCHECK
+# undef setlocale
+# if HAVE_RAW_DECL_SETLOCALE
+_GL_WARN_ON_USE (setlocale, "setlocale works differently on native Windows - "
+ "use gnulib module setlocale for portability");
+# endif
+#endif
+
+#if @GNULIB_DUPLOCALE@
+# if @REPLACE_DUPLOCALE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef duplocale
+# define duplocale rpl_duplocale
+# endif
+_GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale));
+# else
+# if @HAVE_DUPLOCALE@
+_GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale));
+# endif
+# endif
+# if @HAVE_DUPLOCALE@
+_GL_CXXALIASWARN (duplocale);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef duplocale
+# if HAVE_RAW_DECL_DUPLOCALE
+_GL_WARN_ON_USE (duplocale, "duplocale is buggy on some glibc systems - "
+ "use gnulib module duplocale for portability");
+# endif
+#endif
+
+#endif /* _GL_LOCALE_H */
+#endif /* _GL_LOCALE_H */
diff --git a/tests/localename.c b/tests/localename.c
new file mode 100644
index 0000000..a5bfea7
--- /dev/null
+++ b/tests/localename.c
@@ -0,0 +1,2959 @@
+/* Determine name of the currently selected locale.
+ Copyright (C) 1995-2011 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 Ulrich Drepper <drepper@gnu.org>, 1995. */
+/* Win32 code written by Tor Lillqvist <tml@iki.fi>. */
+/* MacOS X code written by Bruno Haible <bruno@clisp.org>. */
+
+#include <config.h>
+
+/* Specification. */
+#ifdef IN_LIBINTL
+# include "gettextP.h"
+#else
+# include "localename.h"
+#endif
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <string.h>
+
+#if HAVE_USELOCALE
+/* MacOS X 10.5 defines the locale_t type in <xlocale.h>. */
+# if defined __APPLE__ && defined __MACH__
+# include <xlocale.h>
+# endif
+# include <langinfo.h>
+# if !defined IN_LIBINTL
+# include "glthread/lock.h"
+# endif
+#endif
+
+#if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
+# include <CoreFoundation/CFString.h>
+# if HAVE_CFLOCALECOPYCURRENT
+# include <CoreFoundation/CFLocale.h>
+# elif HAVE_CFPREFERENCESCOPYAPPVALUE
+# include <CoreFoundation/CFPreferences.h>
+# endif
+#endif
+
+#if defined _WIN32 || defined __WIN32__
+# define WIN32_NATIVE
+#endif
+
+#if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+/* List of language codes, sorted by value:
+ 0x01 LANG_ARABIC
+ 0x02 LANG_BULGARIAN
+ 0x03 LANG_CATALAN
+ 0x04 LANG_CHINESE
+ 0x05 LANG_CZECH
+ 0x06 LANG_DANISH
+ 0x07 LANG_GERMAN
+ 0x08 LANG_GREEK
+ 0x09 LANG_ENGLISH
+ 0x0a LANG_SPANISH
+ 0x0b LANG_FINNISH
+ 0x0c LANG_FRENCH
+ 0x0d LANG_HEBREW
+ 0x0e LANG_HUNGARIAN
+ 0x0f LANG_ICELANDIC
+ 0x10 LANG_ITALIAN
+ 0x11 LANG_JAPANESE
+ 0x12 LANG_KOREAN
+ 0x13 LANG_DUTCH
+ 0x14 LANG_NORWEGIAN
+ 0x15 LANG_POLISH
+ 0x16 LANG_PORTUGUESE
+ 0x17 LANG_ROMANSH
+ 0x18 LANG_ROMANIAN
+ 0x19 LANG_RUSSIAN
+ 0x1a LANG_CROATIAN == LANG_SERBIAN
+ 0x1b LANG_SLOVAK
+ 0x1c LANG_ALBANIAN
+ 0x1d LANG_SWEDISH
+ 0x1e LANG_THAI
+ 0x1f LANG_TURKISH
+ 0x20 LANG_URDU
+ 0x21 LANG_INDONESIAN
+ 0x22 LANG_UKRAINIAN
+ 0x23 LANG_BELARUSIAN
+ 0x24 LANG_SLOVENIAN
+ 0x25 LANG_ESTONIAN
+ 0x26 LANG_LATVIAN
+ 0x27 LANG_LITHUANIAN
+ 0x28 LANG_TAJIK
+ 0x29 LANG_FARSI
+ 0x2a LANG_VIETNAMESE
+ 0x2b LANG_ARMENIAN
+ 0x2c LANG_AZERI
+ 0x2d LANG_BASQUE
+ 0x2e LANG_SORBIAN
+ 0x2f LANG_MACEDONIAN
+ 0x30 LANG_SUTU
+ 0x31 LANG_TSONGA
+ 0x32 LANG_TSWANA
+ 0x33 LANG_VENDA
+ 0x34 LANG_XHOSA
+ 0x35 LANG_ZULU
+ 0x36 LANG_AFRIKAANS
+ 0x37 LANG_GEORGIAN
+ 0x38 LANG_FAEROESE
+ 0x39 LANG_HINDI
+ 0x3a LANG_MALTESE
+ 0x3b LANG_SAMI
+ 0x3c LANG_GAELIC
+ 0x3d LANG_YIDDISH
+ 0x3e LANG_MALAY
+ 0x3f LANG_KAZAK
+ 0x40 LANG_KYRGYZ
+ 0x41 LANG_SWAHILI
+ 0x42 LANG_TURKMEN
+ 0x43 LANG_UZBEK
+ 0x44 LANG_TATAR
+ 0x45 LANG_BENGALI
+ 0x46 LANG_PUNJABI
+ 0x47 LANG_GUJARATI
+ 0x48 LANG_ORIYA
+ 0x49 LANG_TAMIL
+ 0x4a LANG_TELUGU
+ 0x4b LANG_KANNADA
+ 0x4c LANG_MALAYALAM
+ 0x4d LANG_ASSAMESE
+ 0x4e LANG_MARATHI
+ 0x4f LANG_SANSKRIT
+ 0x50 LANG_MONGOLIAN
+ 0x51 LANG_TIBETAN
+ 0x52 LANG_WELSH
+ 0x53 LANG_CAMBODIAN
+ 0x54 LANG_LAO
+ 0x55 LANG_BURMESE
+ 0x56 LANG_GALICIAN
+ 0x57 LANG_KONKANI
+ 0x58 LANG_MANIPURI
+ 0x59 LANG_SINDHI
+ 0x5a LANG_SYRIAC
+ 0x5b LANG_SINHALESE
+ 0x5c LANG_CHEROKEE
+ 0x5d LANG_INUKTITUT
+ 0x5e LANG_AMHARIC
+ 0x5f LANG_TAMAZIGHT
+ 0x60 LANG_KASHMIRI
+ 0x61 LANG_NEPALI
+ 0x62 LANG_FRISIAN
+ 0x63 LANG_PASHTO
+ 0x64 LANG_TAGALOG
+ 0x65 LANG_DIVEHI
+ 0x66 LANG_EDO
+ 0x67 LANG_FULFULDE
+ 0x68 LANG_HAUSA
+ 0x69 LANG_IBIBIO
+ 0x6a LANG_YORUBA
+ 0x6d LANG_BASHKIR
+ 0x6e LANG_LUXEMBOURGISH
+ 0x6f LANG_GREENLANDIC
+ 0x70 LANG_IGBO
+ 0x71 LANG_KANURI
+ 0x72 LANG_OROMO
+ 0x73 LANG_TIGRINYA
+ 0x74 LANG_GUARANI
+ 0x75 LANG_HAWAIIAN
+ 0x76 LANG_LATIN
+ 0x77 LANG_SOMALI
+ 0x78 LANG_YI
+ 0x79 LANG_PAPIAMENTU
+ 0x7a LANG_MAPUDUNGUN
+ 0x7c LANG_MOHAWK
+ 0x7e LANG_BRETON
+ 0x82 LANG_OCCITAN
+ 0x83 LANG_CORSICAN
+ 0x84 LANG_ALSATIAN
+ 0x85 LANG_YAKUT
+ 0x86 LANG_KICHE
+ 0x87 LANG_KINYARWANDA
+ 0x88 LANG_WOLOF
+ 0x8c LANG_DARI
+ 0x91 LANG_SCOTTISH_GAELIC
+*/
+/* Mingw headers don't have latest language and sublanguage codes. */
+# ifndef LANG_AFRIKAANS
+# define LANG_AFRIKAANS 0x36
+# endif
+# ifndef LANG_ALBANIAN
+# define LANG_ALBANIAN 0x1c
+# endif
+# ifndef LANG_ALSATIAN
+# define LANG_ALSATIAN 0x84
+# endif
+# ifndef LANG_AMHARIC
+# define LANG_AMHARIC 0x5e
+# endif
+# ifndef LANG_ARABIC
+# define LANG_ARABIC 0x01
+# endif
+# ifndef LANG_ARMENIAN
+# define LANG_ARMENIAN 0x2b
+# endif
+# ifndef LANG_ASSAMESE
+# define LANG_ASSAMESE 0x4d
+# endif
+# ifndef LANG_AZERI
+# define LANG_AZERI 0x2c
+# endif
+# ifndef LANG_BASHKIR
+# define LANG_BASHKIR 0x6d
+# endif
+# ifndef LANG_BASQUE
+# define LANG_BASQUE 0x2d
+# endif
+# ifndef LANG_BELARUSIAN
+# define LANG_BELARUSIAN 0x23
+# endif
+# ifndef LANG_BENGALI
+# define LANG_BENGALI 0x45
+# endif
+# ifndef LANG_BRETON
+# define LANG_BRETON 0x7e
+# endif
+# ifndef LANG_BURMESE
+# define LANG_BURMESE 0x55
+# endif
+# ifndef LANG_CAMBODIAN
+# define LANG_CAMBODIAN 0x53
+# endif
+# ifndef LANG_CATALAN
+# define LANG_CATALAN 0x03
+# endif
+# ifndef LANG_CHEROKEE
+# define LANG_CHEROKEE 0x5c
+# endif
+# ifndef LANG_CORSICAN
+# define LANG_CORSICAN 0x83
+# endif
+# ifndef LANG_DARI
+# define LANG_DARI 0x8c
+# endif
+# ifndef LANG_DIVEHI
+# define LANG_DIVEHI 0x65
+# endif
+# ifndef LANG_EDO
+# define LANG_EDO 0x66
+# endif
+# ifndef LANG_ESTONIAN
+# define LANG_ESTONIAN 0x25
+# endif
+# ifndef LANG_FAEROESE
+# define LANG_FAEROESE 0x38
+# endif
+# ifndef LANG_FARSI
+# define LANG_FARSI 0x29
+# endif
+# ifndef LANG_FRISIAN
+# define LANG_FRISIAN 0x62
+# endif
+# ifndef LANG_FULFULDE
+# define LANG_FULFULDE 0x67
+# endif
+# ifndef LANG_GAELIC
+# define LANG_GAELIC 0x3c
+# endif
+# ifndef LANG_GALICIAN
+# define LANG_GALICIAN 0x56
+# endif
+# ifndef LANG_GEORGIAN
+# define LANG_GEORGIAN 0x37
+# endif
+# ifndef LANG_GREENLANDIC
+# define LANG_GREENLANDIC 0x6f
+# endif
+# ifndef LANG_GUARANI
+# define LANG_GUARANI 0x74
+# endif
+# ifndef LANG_GUJARATI
+# define LANG_GUJARATI 0x47
+# endif
+# ifndef LANG_HAUSA
+# define LANG_HAUSA 0x68
+# endif
+# ifndef LANG_HAWAIIAN
+# define LANG_HAWAIIAN 0x75
+# endif
+# ifndef LANG_HEBREW
+# define LANG_HEBREW 0x0d
+# endif
+# ifndef LANG_HINDI
+# define LANG_HINDI 0x39
+# endif
+# ifndef LANG_IBIBIO
+# define LANG_IBIBIO 0x69
+# endif
+# ifndef LANG_IGBO
+# define LANG_IGBO 0x70
+# endif
+# ifndef LANG_INDONESIAN
+# define LANG_INDONESIAN 0x21
+# endif
+# ifndef LANG_INUKTITUT
+# define LANG_INUKTITUT 0x5d
+# endif
+# ifndef LANG_KANNADA
+# define LANG_KANNADA 0x4b
+# endif
+# ifndef LANG_KANURI
+# define LANG_KANURI 0x71
+# endif
+# ifndef LANG_KASHMIRI
+# define LANG_KASHMIRI 0x60
+# endif
+# ifndef LANG_KAZAK
+# define LANG_KAZAK 0x3f
+# endif
+# ifndef LANG_KICHE
+# define LANG_KICHE 0x86
+# endif
+# ifndef LANG_KINYARWANDA
+# define LANG_KINYARWANDA 0x87
+# endif
+# ifndef LANG_KONKANI
+# define LANG_KONKANI 0x57
+# endif
+# ifndef LANG_KYRGYZ
+# define LANG_KYRGYZ 0x40
+# endif
+# ifndef LANG_LAO
+# define LANG_LAO 0x54
+# endif
+# ifndef LANG_LATIN
+# define LANG_LATIN 0x76
+# endif
+# ifndef LANG_LATVIAN
+# define LANG_LATVIAN 0x26
+# endif
+# ifndef LANG_LITHUANIAN
+# define LANG_LITHUANIAN 0x27
+# endif
+# ifndef LANG_LUXEMBOURGISH
+# define LANG_LUXEMBOURGISH 0x6e
+# endif
+# ifndef LANG_MACEDONIAN
+# define LANG_MACEDONIAN 0x2f
+# endif
+# ifndef LANG_MALAY
+# define LANG_MALAY 0x3e
+# endif
+# ifndef LANG_MALAYALAM
+# define LANG_MALAYALAM 0x4c
+# endif
+# ifndef LANG_MALTESE
+# define LANG_MALTESE 0x3a
+# endif
+# ifndef LANG_MANIPURI
+# define LANG_MANIPURI 0x58
+# endif
+# ifndef LANG_MAORI
+# define LANG_MAORI 0x81
+# endif
+# ifndef LANG_MAPUDUNGUN
+# define LANG_MAPUDUNGUN 0x7a
+# endif
+# ifndef LANG_MARATHI
+# define LANG_MARATHI 0x4e
+# endif
+# ifndef LANG_MOHAWK
+# define LANG_MOHAWK 0x7c
+# endif
+# ifndef LANG_MONGOLIAN
+# define LANG_MONGOLIAN 0x50
+# endif
+# ifndef LANG_NEPALI
+# define LANG_NEPALI 0x61
+# endif
+# ifndef LANG_OCCITAN
+# define LANG_OCCITAN 0x82
+# endif
+# ifndef LANG_ORIYA
+# define LANG_ORIYA 0x48
+# endif
+# ifndef LANG_OROMO
+# define LANG_OROMO 0x72
+# endif
+# ifndef LANG_PAPIAMENTU
+# define LANG_PAPIAMENTU 0x79
+# endif
+# ifndef LANG_PASHTO
+# define LANG_PASHTO 0x63
+# endif
+# ifndef LANG_PUNJABI
+# define LANG_PUNJABI 0x46
+# endif
+# ifndef LANG_QUECHUA
+# define LANG_QUECHUA 0x6b
+# endif
+# ifndef LANG_ROMANSH
+# define LANG_ROMANSH 0x17
+# endif
+# ifndef LANG_SAMI
+# define LANG_SAMI 0x3b
+# endif
+# ifndef LANG_SANSKRIT
+# define LANG_SANSKRIT 0x4f
+# endif
+# ifndef LANG_SCOTTISH_GAELIC
+# define LANG_SCOTTISH_GAELIC 0x91
+# endif
+# ifndef LANG_SERBIAN
+# define LANG_SERBIAN 0x1a
+# endif
+# ifndef LANG_SINDHI
+# define LANG_SINDHI 0x59
+# endif
+# ifndef LANG_SINHALESE
+# define LANG_SINHALESE 0x5b
+# endif
+# ifndef LANG_SLOVAK
+# define LANG_SLOVAK 0x1b
+# endif
+# ifndef LANG_SOMALI
+# define LANG_SOMALI 0x77
+# endif
+# ifndef LANG_SORBIAN
+# define LANG_SORBIAN 0x2e
+# endif
+# ifndef LANG_SOTHO
+# define LANG_SOTHO 0x6c
+# endif
+# ifndef LANG_SUTU
+# define LANG_SUTU 0x30
+# endif
+# ifndef LANG_SWAHILI
+# define LANG_SWAHILI 0x41
+# endif
+# ifndef LANG_SYRIAC
+# define LANG_SYRIAC 0x5a
+# endif
+# ifndef LANG_TAGALOG
+# define LANG_TAGALOG 0x64
+# endif
+# ifndef LANG_TAJIK
+# define LANG_TAJIK 0x28
+# endif
+# ifndef LANG_TAMAZIGHT
+# define LANG_TAMAZIGHT 0x5f
+# endif
+# ifndef LANG_TAMIL
+# define LANG_TAMIL 0x49
+# endif
+# ifndef LANG_TATAR
+# define LANG_TATAR 0x44
+# endif
+# ifndef LANG_TELUGU
+# define LANG_TELUGU 0x4a
+# endif
+# ifndef LANG_THAI
+# define LANG_THAI 0x1e
+# endif
+# ifndef LANG_TIBETAN
+# define LANG_TIBETAN 0x51
+# endif
+# ifndef LANG_TIGRINYA
+# define LANG_TIGRINYA 0x73
+# endif
+# ifndef LANG_TSONGA
+# define LANG_TSONGA 0x31
+# endif
+# ifndef LANG_TSWANA
+# define LANG_TSWANA 0x32
+# endif
+# ifndef LANG_TURKMEN
+# define LANG_TURKMEN 0x42
+# endif
+# ifndef LANG_UIGHUR
+# define LANG_UIGHUR 0x80
+# endif
+# ifndef LANG_UKRAINIAN
+# define LANG_UKRAINIAN 0x22
+# endif
+# ifndef LANG_URDU
+# define LANG_URDU 0x20
+# endif
+# ifndef LANG_UZBEK
+# define LANG_UZBEK 0x43
+# endif
+# ifndef LANG_VENDA
+# define LANG_VENDA 0x33
+# endif
+# ifndef LANG_VIETNAMESE
+# define LANG_VIETNAMESE 0x2a
+# endif
+# ifndef LANG_WELSH
+# define LANG_WELSH 0x52
+# endif
+# ifndef LANG_WOLOF
+# define LANG_WOLOF 0x88
+# endif
+# ifndef LANG_XHOSA
+# define LANG_XHOSA 0x34
+# endif
+# ifndef LANG_YAKUT
+# define LANG_YAKUT 0x85
+# endif
+# ifndef LANG_YI
+# define LANG_YI 0x78
+# endif
+# ifndef LANG_YIDDISH
+# define LANG_YIDDISH 0x3d
+# endif
+# ifndef LANG_YORUBA
+# define LANG_YORUBA 0x6a
+# endif
+# ifndef LANG_ZULU
+# define LANG_ZULU 0x35
+# endif
+# ifndef SUBLANG_AFRIKAANS_SOUTH_AFRICA
+# define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01
+# endif
+# ifndef SUBLANG_ALBANIAN_ALBANIA
+# define SUBLANG_ALBANIAN_ALBANIA 0x01
+# endif
+# ifndef SUBLANG_ALSATIAN_FRANCE
+# define SUBLANG_ALSATIAN_FRANCE 0x01
+# endif
+# ifndef SUBLANG_AMHARIC_ETHIOPIA
+# define SUBLANG_AMHARIC_ETHIOPIA 0x01
+# endif
+# ifndef SUBLANG_ARABIC_SAUDI_ARABIA
+# define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
+# endif
+# ifndef SUBLANG_ARABIC_IRAQ
+# define SUBLANG_ARABIC_IRAQ 0x02
+# endif
+# ifndef SUBLANG_ARABIC_EGYPT
+# define SUBLANG_ARABIC_EGYPT 0x03
+# endif
+# ifndef SUBLANG_ARABIC_LIBYA
+# define SUBLANG_ARABIC_LIBYA 0x04
+# endif
+# ifndef SUBLANG_ARABIC_ALGERIA
+# define SUBLANG_ARABIC_ALGERIA 0x05
+# endif
+# ifndef SUBLANG_ARABIC_MOROCCO
+# define SUBLANG_ARABIC_MOROCCO 0x06
+# endif
+# ifndef SUBLANG_ARABIC_TUNISIA
+# define SUBLANG_ARABIC_TUNISIA 0x07
+# endif
+# ifndef SUBLANG_ARABIC_OMAN
+# define SUBLANG_ARABIC_OMAN 0x08
+# endif
+# ifndef SUBLANG_ARABIC_YEMEN
+# define SUBLANG_ARABIC_YEMEN 0x09
+# endif
+# ifndef SUBLANG_ARABIC_SYRIA
+# define SUBLANG_ARABIC_SYRIA 0x0a
+# endif
+# ifndef SUBLANG_ARABIC_JORDAN
+# define SUBLANG_ARABIC_JORDAN 0x0b
+# endif
+# ifndef SUBLANG_ARABIC_LEBANON
+# define SUBLANG_ARABIC_LEBANON 0x0c
+# endif
+# ifndef SUBLANG_ARABIC_KUWAIT
+# define SUBLANG_ARABIC_KUWAIT 0x0d
+# endif
+# ifndef SUBLANG_ARABIC_UAE
+# define SUBLANG_ARABIC_UAE 0x0e
+# endif
+# ifndef SUBLANG_ARABIC_BAHRAIN
+# define SUBLANG_ARABIC_BAHRAIN 0x0f
+# endif
+# ifndef SUBLANG_ARABIC_QATAR
+# define SUBLANG_ARABIC_QATAR 0x10
+# endif
+# ifndef SUBLANG_ARMENIAN_ARMENIA
+# define SUBLANG_ARMENIAN_ARMENIA 0x01
+# endif
+# ifndef SUBLANG_ASSAMESE_INDIA
+# define SUBLANG_ASSAMESE_INDIA 0x01
+# endif
+# ifndef SUBLANG_AZERI_LATIN
+# define SUBLANG_AZERI_LATIN 0x01
+# endif
+# ifndef SUBLANG_AZERI_CYRILLIC
+# define SUBLANG_AZERI_CYRILLIC 0x02
+# endif
+# ifndef SUBLANG_BASHKIR_RUSSIA
+# define SUBLANG_BASHKIR_RUSSIA 0x01
+# endif
+# ifndef SUBLANG_BASQUE_BASQUE
+# define SUBLANG_BASQUE_BASQUE 0x01
+# endif
+# ifndef SUBLANG_BELARUSIAN_BELARUS
+# define SUBLANG_BELARUSIAN_BELARUS 0x01
+# endif
+# ifndef SUBLANG_BENGALI_INDIA
+# define SUBLANG_BENGALI_INDIA 0x01
+# endif
+# ifndef SUBLANG_BENGALI_BANGLADESH
+# define SUBLANG_BENGALI_BANGLADESH 0x02
+# endif
+# ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN
+# define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05
+# endif
+# ifndef SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC
+# define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08
+# endif
+# ifndef SUBLANG_BRETON_FRANCE
+# define SUBLANG_BRETON_FRANCE 0x01
+# endif
+# ifndef SUBLANG_BULGARIAN_BULGARIA
+# define SUBLANG_BULGARIAN_BULGARIA 0x01
+# endif
+# ifndef SUBLANG_CAMBODIAN_CAMBODIA
+# define SUBLANG_CAMBODIAN_CAMBODIA 0x01
+# endif
+# ifndef SUBLANG_CATALAN_SPAIN
+# define SUBLANG_CATALAN_SPAIN 0x01
+# endif
+# ifndef SUBLANG_CORSICAN_FRANCE
+# define SUBLANG_CORSICAN_FRANCE 0x01
+# endif
+# ifndef SUBLANG_CROATIAN_CROATIA
+# define SUBLANG_CROATIAN_CROATIA 0x01
+# endif
+# ifndef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN
+# define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04
+# endif
+# ifndef SUBLANG_CHINESE_MACAU
+# define SUBLANG_CHINESE_MACAU 0x05
+# endif
+# ifndef SUBLANG_CZECH_CZECH_REPUBLIC
+# define SUBLANG_CZECH_CZECH_REPUBLIC 0x01
+# endif
+# ifndef SUBLANG_DANISH_DENMARK
+# define SUBLANG_DANISH_DENMARK 0x01
+# endif
+# ifndef SUBLANG_DARI_AFGHANISTAN
+# define SUBLANG_DARI_AFGHANISTAN 0x01
+# endif
+# ifndef SUBLANG_DIVEHI_MALDIVES
+# define SUBLANG_DIVEHI_MALDIVES 0x01
+# endif
+# ifndef SUBLANG_DUTCH_SURINAM
+# define SUBLANG_DUTCH_SURINAM 0x03
+# endif
+# ifndef SUBLANG_ENGLISH_SOUTH_AFRICA
+# define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
+# endif
+# ifndef SUBLANG_ENGLISH_JAMAICA
+# define SUBLANG_ENGLISH_JAMAICA 0x08
+# endif
+# ifndef SUBLANG_ENGLISH_CARIBBEAN
+# define SUBLANG_ENGLISH_CARIBBEAN 0x09
+# endif
+# ifndef SUBLANG_ENGLISH_BELIZE
+# define SUBLANG_ENGLISH_BELIZE 0x0a
+# endif
+# ifndef SUBLANG_ENGLISH_TRINIDAD
+# define SUBLANG_ENGLISH_TRINIDAD 0x0b
+# endif
+# ifndef SUBLANG_ENGLISH_ZIMBABWE
+# define SUBLANG_ENGLISH_ZIMBABWE 0x0c
+# endif
+# ifndef SUBLANG_ENGLISH_PHILIPPINES
+# define SUBLANG_ENGLISH_PHILIPPINES 0x0d
+# endif
+# ifndef SUBLANG_ENGLISH_INDONESIA
+# define SUBLANG_ENGLISH_INDONESIA 0x0e
+# endif
+# ifndef SUBLANG_ENGLISH_HONGKONG
+# define SUBLANG_ENGLISH_HONGKONG 0x0f
+# endif
+# ifndef SUBLANG_ENGLISH_INDIA
+# define SUBLANG_ENGLISH_INDIA 0x10
+# endif
+# ifndef SUBLANG_ENGLISH_MALAYSIA
+# define SUBLANG_ENGLISH_MALAYSIA 0x11
+# endif
+# ifndef SUBLANG_ENGLISH_SINGAPORE
+# define SUBLANG_ENGLISH_SINGAPORE 0x12
+# endif
+# ifndef SUBLANG_ESTONIAN_ESTONIA
+# define SUBLANG_ESTONIAN_ESTONIA 0x01
+# endif
+# ifndef SUBLANG_FAEROESE_FAROE_ISLANDS
+# define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01
+# endif
+# ifndef SUBLANG_FARSI_IRAN
+# define SUBLANG_FARSI_IRAN 0x01
+# endif
+# ifndef SUBLANG_FINNISH_FINLAND
+# define SUBLANG_FINNISH_FINLAND 0x01
+# endif
+# ifndef SUBLANG_FRENCH_LUXEMBOURG
+# define SUBLANG_FRENCH_LUXEMBOURG 0x05
+# endif
+# ifndef SUBLANG_FRENCH_MONACO
+# define SUBLANG_FRENCH_MONACO 0x06
+# endif
+# ifndef SUBLANG_FRENCH_WESTINDIES
+# define SUBLANG_FRENCH_WESTINDIES 0x07
+# endif
+# ifndef SUBLANG_FRENCH_REUNION
+# define SUBLANG_FRENCH_REUNION 0x08
+# endif
+# ifndef SUBLANG_FRENCH_CONGO
+# define SUBLANG_FRENCH_CONGO 0x09
+# endif
+# ifndef SUBLANG_FRENCH_SENEGAL
+# define SUBLANG_FRENCH_SENEGAL 0x0a
+# endif
+# ifndef SUBLANG_FRENCH_CAMEROON
+# define SUBLANG_FRENCH_CAMEROON 0x0b
+# endif
+# ifndef SUBLANG_FRENCH_COTEDIVOIRE
+# define SUBLANG_FRENCH_COTEDIVOIRE 0x0c
+# endif
+# ifndef SUBLANG_FRENCH_MALI
+# define SUBLANG_FRENCH_MALI 0x0d
+# endif
+# ifndef SUBLANG_FRENCH_MOROCCO
+# define SUBLANG_FRENCH_MOROCCO 0x0e
+# endif
+# ifndef SUBLANG_FRENCH_HAITI
+# define SUBLANG_FRENCH_HAITI 0x0f
+# endif
+# ifndef SUBLANG_FRISIAN_NETHERLANDS
+# define SUBLANG_FRISIAN_NETHERLANDS 0x01
+# endif
+# ifndef SUBLANG_GALICIAN_SPAIN
+# define SUBLANG_GALICIAN_SPAIN 0x01
+# endif
+# ifndef SUBLANG_GEORGIAN_GEORGIA
+# define SUBLANG_GEORGIAN_GEORGIA 0x01
+# endif
+# ifndef SUBLANG_GERMAN_LUXEMBOURG
+# define SUBLANG_GERMAN_LUXEMBOURG 0x04
+# endif
+# ifndef SUBLANG_GERMAN_LIECHTENSTEIN
+# define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
+# endif
+# ifndef SUBLANG_GREEK_GREECE
+# define SUBLANG_GREEK_GREECE 0x01
+# endif
+# ifndef SUBLANG_GREENLANDIC_GREENLAND
+# define SUBLANG_GREENLANDIC_GREENLAND 0x01
+# endif
+# ifndef SUBLANG_GUJARATI_INDIA
+# define SUBLANG_GUJARATI_INDIA 0x01
+# endif
+# ifndef SUBLANG_HAUSA_NIGERIA_LATIN
+# define SUBLANG_HAUSA_NIGERIA_LATIN 0x01
+# endif
+# ifndef SUBLANG_HEBREW_ISRAEL
+# define SUBLANG_HEBREW_ISRAEL 0x01
+# endif
+# ifndef SUBLANG_HINDI_INDIA
+# define SUBLANG_HINDI_INDIA 0x01
+# endif
+# ifndef SUBLANG_HUNGARIAN_HUNGARY
+# define SUBLANG_HUNGARIAN_HUNGARY 0x01
+# endif
+# ifndef SUBLANG_ICELANDIC_ICELAND
+# define SUBLANG_ICELANDIC_ICELAND 0x01
+# endif
+# ifndef SUBLANG_IGBO_NIGERIA
+# define SUBLANG_IGBO_NIGERIA 0x01
+# endif
+# ifndef SUBLANG_INDONESIAN_INDONESIA
+# define SUBLANG_INDONESIAN_INDONESIA 0x01
+# endif
+# ifndef SUBLANG_INUKTITUT_CANADA
+# define SUBLANG_INUKTITUT_CANADA 0x01
+# endif
+# undef SUBLANG_INUKTITUT_CANADA_LATIN
+# define SUBLANG_INUKTITUT_CANADA_LATIN 0x02
+# undef SUBLANG_IRISH_IRELAND
+# define SUBLANG_IRISH_IRELAND 0x02
+# ifndef SUBLANG_JAPANESE_JAPAN
+# define SUBLANG_JAPANESE_JAPAN 0x01
+# endif
+# ifndef SUBLANG_KANNADA_INDIA
+# define SUBLANG_KANNADA_INDIA 0x01
+# endif
+# ifndef SUBLANG_KASHMIRI_INDIA
+# define SUBLANG_KASHMIRI_INDIA 0x02
+# endif
+# ifndef SUBLANG_KAZAK_KAZAKHSTAN
+# define SUBLANG_KAZAK_KAZAKHSTAN 0x01
+# endif
+# ifndef SUBLANG_KICHE_GUATEMALA
+# define SUBLANG_KICHE_GUATEMALA 0x01
+# endif
+# ifndef SUBLANG_KINYARWANDA_RWANDA
+# define SUBLANG_KINYARWANDA_RWANDA 0x01
+# endif
+# ifndef SUBLANG_KONKANI_INDIA
+# define SUBLANG_KONKANI_INDIA 0x01
+# endif
+# ifndef SUBLANG_KYRGYZ_KYRGYZSTAN
+# define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01
+# endif
+# ifndef SUBLANG_LAO_LAOS
+# define SUBLANG_LAO_LAOS 0x01
+# endif
+# ifndef SUBLANG_LATVIAN_LATVIA
+# define SUBLANG_LATVIAN_LATVIA 0x01
+# endif
+# ifndef SUBLANG_LITHUANIAN_LITHUANIA
+# define SUBLANG_LITHUANIAN_LITHUANIA 0x01
+# endif
+# undef SUBLANG_LOWER_SORBIAN_GERMANY
+# define SUBLANG_LOWER_SORBIAN_GERMANY 0x02
+# ifndef SUBLANG_LUXEMBOURGISH_LUXEMBOURG
+# define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01
+# endif
+# ifndef SUBLANG_MACEDONIAN_MACEDONIA
+# define SUBLANG_MACEDONIAN_MACEDONIA 0x01
+# endif
+# ifndef SUBLANG_MALAY_MALAYSIA
+# define SUBLANG_MALAY_MALAYSIA 0x01
+# endif
+# ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM
+# define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
+# endif
+# ifndef SUBLANG_MALAYALAM_INDIA
+# define SUBLANG_MALAYALAM_INDIA 0x01
+# endif
+# ifndef SUBLANG_MALTESE_MALTA
+# define SUBLANG_MALTESE_MALTA 0x01
+# endif
+# ifndef SUBLANG_MAORI_NEW_ZEALAND
+# define SUBLANG_MAORI_NEW_ZEALAND 0x01
+# endif
+# ifndef SUBLANG_MAPUDUNGUN_CHILE
+# define SUBLANG_MAPUDUNGUN_CHILE 0x01
+# endif
+# ifndef SUBLANG_MARATHI_INDIA
+# define SUBLANG_MARATHI_INDIA 0x01
+# endif
+# ifndef SUBLANG_MOHAWK_CANADA
+# define SUBLANG_MOHAWK_CANADA 0x01
+# endif
+# ifndef SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA
+# define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01
+# endif
+# ifndef SUBLANG_MONGOLIAN_PRC
+# define SUBLANG_MONGOLIAN_PRC 0x02
+# endif
+# ifndef SUBLANG_NEPALI_NEPAL
+# define SUBLANG_NEPALI_NEPAL 0x01
+# endif
+# ifndef SUBLANG_NEPALI_INDIA
+# define SUBLANG_NEPALI_INDIA 0x02
+# endif
+# ifndef SUBLANG_OCCITAN_FRANCE
+# define SUBLANG_OCCITAN_FRANCE 0x01
+# endif
+# ifndef SUBLANG_ORIYA_INDIA
+# define SUBLANG_ORIYA_INDIA 0x01
+# endif
+# ifndef SUBLANG_PASHTO_AFGHANISTAN
+# define SUBLANG_PASHTO_AFGHANISTAN 0x01
+# endif
+# ifndef SUBLANG_POLISH_POLAND
+# define SUBLANG_POLISH_POLAND 0x01
+# endif
+# ifndef SUBLANG_PUNJABI_INDIA
+# define SUBLANG_PUNJABI_INDIA 0x01
+# endif
+# ifndef SUBLANG_PUNJABI_PAKISTAN
+# define SUBLANG_PUNJABI_PAKISTAN 0x02
+# endif
+# ifndef SUBLANG_QUECHUA_BOLIVIA
+# define SUBLANG_QUECHUA_BOLIVIA 0x01
+# endif
+# ifndef SUBLANG_QUECHUA_ECUADOR
+# define SUBLANG_QUECHUA_ECUADOR 0x02
+# endif
+# ifndef SUBLANG_QUECHUA_PERU
+# define SUBLANG_QUECHUA_PERU 0x03
+# endif
+# ifndef SUBLANG_ROMANIAN_ROMANIA
+# define SUBLANG_ROMANIAN_ROMANIA 0x01
+# endif
+# ifndef SUBLANG_ROMANIAN_MOLDOVA
+# define SUBLANG_ROMANIAN_MOLDOVA 0x02
+# endif
+# ifndef SUBLANG_ROMANSH_SWITZERLAND
+# define SUBLANG_ROMANSH_SWITZERLAND 0x01
+# endif
+# ifndef SUBLANG_RUSSIAN_RUSSIA
+# define SUBLANG_RUSSIAN_RUSSIA 0x01
+# endif
+# ifndef SUBLANG_RUSSIAN_MOLDAVIA
+# define SUBLANG_RUSSIAN_MOLDAVIA 0x02
+# endif
+# ifndef SUBLANG_SAMI_NORTHERN_NORWAY
+# define SUBLANG_SAMI_NORTHERN_NORWAY 0x01
+# endif
+# ifndef SUBLANG_SAMI_NORTHERN_SWEDEN
+# define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02
+# endif
+# ifndef SUBLANG_SAMI_NORTHERN_FINLAND
+# define SUBLANG_SAMI_NORTHERN_FINLAND 0x03
+# endif
+# ifndef SUBLANG_SAMI_LULE_NORWAY
+# define SUBLANG_SAMI_LULE_NORWAY 0x04
+# endif
+# ifndef SUBLANG_SAMI_LULE_SWEDEN
+# define SUBLANG_SAMI_LULE_SWEDEN 0x05
+# endif
+# ifndef SUBLANG_SAMI_SOUTHERN_NORWAY
+# define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06
+# endif
+# ifndef SUBLANG_SAMI_SOUTHERN_SWEDEN
+# define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07
+# endif
+# undef SUBLANG_SAMI_SKOLT_FINLAND
+# define SUBLANG_SAMI_SKOLT_FINLAND 0x08
+# undef SUBLANG_SAMI_INARI_FINLAND
+# define SUBLANG_SAMI_INARI_FINLAND 0x09
+# ifndef SUBLANG_SANSKRIT_INDIA
+# define SUBLANG_SANSKRIT_INDIA 0x01
+# endif
+# ifndef SUBLANG_SERBIAN_LATIN
+# define SUBLANG_SERBIAN_LATIN 0x02
+# endif
+# ifndef SUBLANG_SERBIAN_CYRILLIC
+# define SUBLANG_SERBIAN_CYRILLIC 0x03
+# endif
+# ifndef SUBLANG_SINDHI_INDIA
+# define SUBLANG_SINDHI_INDIA 0x01
+# endif
+# undef SUBLANG_SINDHI_PAKISTAN
+# define SUBLANG_SINDHI_PAKISTAN 0x02
+# ifndef SUBLANG_SINDHI_AFGHANISTAN
+# define SUBLANG_SINDHI_AFGHANISTAN 0x02
+# endif
+# ifndef SUBLANG_SINHALESE_SRI_LANKA
+# define SUBLANG_SINHALESE_SRI_LANKA 0x01
+# endif
+# ifndef SUBLANG_SLOVAK_SLOVAKIA
+# define SUBLANG_SLOVAK_SLOVAKIA 0x01
+# endif
+# ifndef SUBLANG_SLOVENIAN_SLOVENIA
+# define SUBLANG_SLOVENIAN_SLOVENIA 0x01
+# endif
+# ifndef SUBLANG_SOTHO_SOUTH_AFRICA
+# define SUBLANG_SOTHO_SOUTH_AFRICA 0x01
+# endif
+# ifndef SUBLANG_SPANISH_GUATEMALA
+# define SUBLANG_SPANISH_GUATEMALA 0x04
+# endif
+# ifndef SUBLANG_SPANISH_COSTA_RICA
+# define SUBLANG_SPANISH_COSTA_RICA 0x05
+# endif
+# ifndef SUBLANG_SPANISH_PANAMA
+# define SUBLANG_SPANISH_PANAMA 0x06
+# endif
+# ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
+# define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
+# endif
+# ifndef SUBLANG_SPANISH_VENEZUELA
+# define SUBLANG_SPANISH_VENEZUELA 0x08
+# endif
+# ifndef SUBLANG_SPANISH_COLOMBIA
+# define SUBLANG_SPANISH_COLOMBIA 0x09
+# endif
+# ifndef SUBLANG_SPANISH_PERU
+# define SUBLANG_SPANISH_PERU 0x0a
+# endif
+# ifndef SUBLANG_SPANISH_ARGENTINA
+# define SUBLANG_SPANISH_ARGENTINA 0x0b
+# endif
+# ifndef SUBLANG_SPANISH_ECUADOR
+# define SUBLANG_SPANISH_ECUADOR 0x0c
+# endif
+# ifndef SUBLANG_SPANISH_CHILE
+# define SUBLANG_SPANISH_CHILE 0x0d
+# endif
+# ifndef SUBLANG_SPANISH_URUGUAY
+# define SUBLANG_SPANISH_URUGUAY 0x0e
+# endif
+# ifndef SUBLANG_SPANISH_PARAGUAY
+# define SUBLANG_SPANISH_PARAGUAY 0x0f
+# endif
+# ifndef SUBLANG_SPANISH_BOLIVIA
+# define SUBLANG_SPANISH_BOLIVIA 0x10
+# endif
+# ifndef SUBLANG_SPANISH_EL_SALVADOR
+# define SUBLANG_SPANISH_EL_SALVADOR 0x11
+# endif
+# ifndef SUBLANG_SPANISH_HONDURAS
+# define SUBLANG_SPANISH_HONDURAS 0x12
+# endif
+# ifndef SUBLANG_SPANISH_NICARAGUA
+# define SUBLANG_SPANISH_NICARAGUA 0x13
+# endif
+# ifndef SUBLANG_SPANISH_PUERTO_RICO
+# define SUBLANG_SPANISH_PUERTO_RICO 0x14
+# endif
+# ifndef SUBLANG_SPANISH_US
+# define SUBLANG_SPANISH_US 0x15
+# endif
+# ifndef SUBLANG_SWAHILI_KENYA
+# define SUBLANG_SWAHILI_KENYA 0x01
+# endif
+# ifndef SUBLANG_SWEDISH_SWEDEN
+# define SUBLANG_SWEDISH_SWEDEN 0x01
+# endif
+# ifndef SUBLANG_SWEDISH_FINLAND
+# define SUBLANG_SWEDISH_FINLAND 0x02
+# endif
+# ifndef SUBLANG_SYRIAC_SYRIA
+# define SUBLANG_SYRIAC_SYRIA 0x01
+# endif
+# ifndef SUBLANG_TAGALOG_PHILIPPINES
+# define SUBLANG_TAGALOG_PHILIPPINES 0x01
+# endif
+# ifndef SUBLANG_TAJIK_TAJIKISTAN
+# define SUBLANG_TAJIK_TAJIKISTAN 0x01
+# endif
+# ifndef SUBLANG_TAMAZIGHT_ARABIC
+# define SUBLANG_TAMAZIGHT_ARABIC 0x01
+# endif
+# ifndef SUBLANG_TAMAZIGHT_ALGERIA_LATIN
+# define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02
+# endif
+# ifndef SUBLANG_TAMIL_INDIA
+# define SUBLANG_TAMIL_INDIA 0x01
+# endif
+# ifndef SUBLANG_TATAR_RUSSIA
+# define SUBLANG_TATAR_RUSSIA 0x01
+# endif
+# ifndef SUBLANG_TELUGU_INDIA
+# define SUBLANG_TELUGU_INDIA 0x01
+# endif
+# ifndef SUBLANG_THAI_THAILAND
+# define SUBLANG_THAI_THAILAND 0x01
+# endif
+# ifndef SUBLANG_TIBETAN_PRC
+# define SUBLANG_TIBETAN_PRC 0x01
+# endif
+# undef SUBLANG_TIBETAN_BHUTAN
+# define SUBLANG_TIBETAN_BHUTAN 0x02
+# ifndef SUBLANG_TIGRINYA_ETHIOPIA
+# define SUBLANG_TIGRINYA_ETHIOPIA 0x01
+# endif
+# ifndef SUBLANG_TIGRINYA_ERITREA
+# define SUBLANG_TIGRINYA_ERITREA 0x02
+# endif
+# ifndef SUBLANG_TSWANA_SOUTH_AFRICA
+# define SUBLANG_TSWANA_SOUTH_AFRICA 0x01
+# endif
+# ifndef SUBLANG_TURKISH_TURKEY
+# define SUBLANG_TURKISH_TURKEY 0x01
+# endif
+# ifndef SUBLANG_TURKMEN_TURKMENISTAN
+# define SUBLANG_TURKMEN_TURKMENISTAN 0x01
+# endif
+# ifndef SUBLANG_UIGHUR_PRC
+# define SUBLANG_UIGHUR_PRC 0x01
+# endif
+# ifndef SUBLANG_UKRAINIAN_UKRAINE
+# define SUBLANG_UKRAINIAN_UKRAINE 0x01
+# endif
+# ifndef SUBLANG_UPPER_SORBIAN_GERMANY
+# define SUBLANG_UPPER_SORBIAN_GERMANY 0x01
+# endif
+# ifndef SUBLANG_URDU_PAKISTAN
+# define SUBLANG_URDU_PAKISTAN 0x01
+# endif
+# ifndef SUBLANG_URDU_INDIA
+# define SUBLANG_URDU_INDIA 0x02
+# endif
+# ifndef SUBLANG_UZBEK_LATIN
+# define SUBLANG_UZBEK_LATIN 0x01
+# endif
+# ifndef SUBLANG_UZBEK_CYRILLIC
+# define SUBLANG_UZBEK_CYRILLIC 0x02
+# endif
+# ifndef SUBLANG_VIETNAMESE_VIETNAM
+# define SUBLANG_VIETNAMESE_VIETNAM 0x01
+# endif
+# ifndef SUBLANG_WELSH_UNITED_KINGDOM
+# define SUBLANG_WELSH_UNITED_KINGDOM 0x01
+# endif
+# ifndef SUBLANG_WOLOF_SENEGAL
+# define SUBLANG_WOLOF_SENEGAL 0x01
+# endif
+# ifndef SUBLANG_XHOSA_SOUTH_AFRICA
+# define SUBLANG_XHOSA_SOUTH_AFRICA 0x01
+# endif
+# ifndef SUBLANG_YAKUT_RUSSIA
+# define SUBLANG_YAKUT_RUSSIA 0x01
+# endif
+# ifndef SUBLANG_YI_PRC
+# define SUBLANG_YI_PRC 0x01
+# endif
+# ifndef SUBLANG_YORUBA_NIGERIA
+# define SUBLANG_YORUBA_NIGERIA 0x01
+# endif
+# ifndef SUBLANG_ZULU_SOUTH_AFRICA
+# define SUBLANG_ZULU_SOUTH_AFRICA 0x01
+# endif
+/* GetLocaleInfoA operations. */
+# ifndef LOCALE_SNAME
+# define LOCALE_SNAME 0x5c
+# endif
+#endif
+
+
+#if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
+/* MacOS X 10.2 or newer */
+
+/* Canonicalize a MacOS X locale name to a Unix locale name.
+ NAME is a sufficiently large buffer.
+ On input, it contains the MacOS X locale name.
+ On output, it contains the Unix locale name. */
+# if !defined IN_LIBINTL
+static
+# endif
+void
+gl_locale_name_canonicalize (char *name)
+{
+ /* This conversion is based on a posting by
+ Deborah GoldSmith <goldsmit@apple.com> on 2005-03-08,
+ http://lists.apple.com/archives/carbon-dev/2005/Mar/msg00293.html */
+
+ /* Convert legacy (NeXTstep inherited) English names to Unix (ISO 639 and
+ ISO 3166) names. Prior to MacOS X 10.3, there is no API for doing this.
+ Therefore we do it ourselves, using a table based on the results of the
+ MacOS X 10.3.8 function
+ CFLocaleCreateCanonicalLocaleIdentifierFromString(). */
+ typedef struct { const char legacy[21+1]; const char unixy[5+1]; }
+ legacy_entry;
+ static const legacy_entry legacy_table[] = {
+ { "Afrikaans", "af" },
+ { "Albanian", "sq" },
+ { "Amharic", "am" },
+ { "Arabic", "ar" },
+ { "Armenian", "hy" },
+ { "Assamese", "as" },
+ { "Aymara", "ay" },
+ { "Azerbaijani", "az" },
+ { "Basque", "eu" },
+ { "Belarusian", "be" },
+ { "Belorussian", "be" },
+ { "Bengali", "bn" },
+ { "Brazilian Portugese", "pt_BR" },
+ { "Brazilian Portuguese", "pt_BR" },
+ { "Breton", "br" },
+ { "Bulgarian", "bg" },
+ { "Burmese", "my" },
+ { "Byelorussian", "be" },
+ { "Catalan", "ca" },
+ { "Chewa", "ny" },
+ { "Chichewa", "ny" },
+ { "Chinese", "zh" },
+ { "Chinese, Simplified", "zh_CN" },
+ { "Chinese, Traditional", "zh_TW" },
+ { "Chinese, Tradtional", "zh_TW" },
+ { "Croatian", "hr" },
+ { "Czech", "cs" },
+ { "Danish", "da" },
+ { "Dutch", "nl" },
+ { "Dzongkha", "dz" },
+ { "English", "en" },
+ { "Esperanto", "eo" },
+ { "Estonian", "et" },
+ { "Faroese", "fo" },
+ { "Farsi", "fa" },
+ { "Finnish", "fi" },
+ { "Flemish", "nl_BE" },
+ { "French", "fr" },
+ { "Galician", "gl" },
+ { "Gallegan", "gl" },
+ { "Georgian", "ka" },
+ { "German", "de" },
+ { "Greek", "el" },
+ { "Greenlandic", "kl" },
+ { "Guarani", "gn" },
+ { "Gujarati", "gu" },
+ { "Hawaiian", "haw" }, /* Yes, "haw", not "cpe". */
+ { "Hebrew", "he" },
+ { "Hindi", "hi" },
+ { "Hungarian", "hu" },
+ { "Icelandic", "is" },
+ { "Indonesian", "id" },
+ { "Inuktitut", "iu" },
+ { "Irish", "ga" },
+ { "Italian", "it" },
+ { "Japanese", "ja" },
+ { "Javanese", "jv" },
+ { "Kalaallisut", "kl" },
+ { "Kannada", "kn" },
+ { "Kashmiri", "ks" },
+ { "Kazakh", "kk" },
+ { "Khmer", "km" },
+ { "Kinyarwanda", "rw" },
+ { "Kirghiz", "ky" },
+ { "Korean", "ko" },
+ { "Kurdish", "ku" },
+ { "Latin", "la" },
+ { "Latvian", "lv" },
+ { "Lithuanian", "lt" },
+ { "Macedonian", "mk" },
+ { "Malagasy", "mg" },
+ { "Malay", "ms" },
+ { "Malayalam", "ml" },
+ { "Maltese", "mt" },
+ { "Manx", "gv" },
+ { "Marathi", "mr" },
+ { "Moldavian", "mo" },
+ { "Mongolian", "mn" },
+ { "Nepali", "ne" },
+ { "Norwegian", "nb" }, /* Yes, "nb", not the obsolete "no". */
+ { "Nyanja", "ny" },
+ { "Nynorsk", "nn" },
+ { "Oriya", "or" },
+ { "Oromo", "om" },
+ { "Panjabi", "pa" },
+ { "Pashto", "ps" },
+ { "Persian", "fa" },
+ { "Polish", "pl" },
+ { "Portuguese", "pt" },
+ { "Portuguese, Brazilian", "pt_BR" },
+ { "Punjabi", "pa" },
+ { "Pushto", "ps" },
+ { "Quechua", "qu" },
+ { "Romanian", "ro" },
+ { "Ruanda", "rw" },
+ { "Rundi", "rn" },
+ { "Russian", "ru" },
+ { "Sami", "se_NO" }, /* Not just "se". */
+ { "Sanskrit", "sa" },
+ { "Scottish", "gd" },
+ { "Serbian", "sr" },
+ { "Simplified Chinese", "zh_CN" },
+ { "Sindhi", "sd" },
+ { "Sinhalese", "si" },
+ { "Slovak", "sk" },
+ { "Slovenian", "sl" },
+ { "Somali", "so" },
+ { "Spanish", "es" },
+ { "Sundanese", "su" },
+ { "Swahili", "sw" },
+ { "Swedish", "sv" },
+ { "Tagalog", "tl" },
+ { "Tajik", "tg" },
+ { "Tajiki", "tg" },
+ { "Tamil", "ta" },
+ { "Tatar", "tt" },
+ { "Telugu", "te" },
+ { "Thai", "th" },
+ { "Tibetan", "bo" },
+ { "Tigrinya", "ti" },
+ { "Tongan", "to" },
+ { "Traditional Chinese", "zh_TW" },
+ { "Turkish", "tr" },
+ { "Turkmen", "tk" },
+ { "Uighur", "ug" },
+ { "Ukrainian", "uk" },
+ { "Urdu", "ur" },
+ { "Uzbek", "uz" },
+ { "Vietnamese", "vi" },
+ { "Welsh", "cy" },
+ { "Yiddish", "yi" }
+ };
+
+ /* Convert new-style locale names with language tags (ISO 639 and ISO 15924)
+ to Unix (ISO 639 and ISO 3166) names. */
+ typedef struct { const char langtag[7+1]; const char unixy[12+1]; }
+ langtag_entry;
+ static const langtag_entry langtag_table[] = {
+ /* MacOS X has "az-Arab", "az-Cyrl", "az-Latn".
+ The default script for az on Unix is Latin. */
+ { "az-Latn", "az" },
+ /* MacOS X has "ga-dots". Does not yet exist on Unix. */
+ { "ga-dots", "ga" },
+ /* MacOS X has "kk-Cyrl". Does not yet exist on Unix. */
+ /* MacOS X has "mn-Cyrl", "mn-Mong".
+ The default script for mn on Unix is Cyrillic. */
+ { "mn-Cyrl", "mn" },
+ /* MacOS X has "ms-Arab", "ms-Latn".
+ The default script for ms on Unix is Latin. */
+ { "ms-Latn", "ms" },
+ /* MacOS X has "tg-Cyrl".
+ The default script for tg on Unix is Cyrillic. */
+ { "tg-Cyrl", "tg" },
+ /* MacOS X has "tk-Cyrl". Does not yet exist on Unix. */
+ /* MacOS X has "tt-Cyrl".
+ The default script for tt on Unix is Cyrillic. */
+ { "tt-Cyrl", "tt" },
+ /* MacOS X has "zh-Hans", "zh-Hant".
+ Country codes are used to distinguish these on Unix. */
+ { "zh-Hans", "zh_CN" },
+ { "zh-Hant", "zh_TW" }
+ };
+
+ /* Convert script names (ISO 15924) to Unix conventions.
+ See http://www.unicode.org/iso15924/iso15924-codes.html */
+ typedef struct { const char script[4+1]; const char unixy[9+1]; }
+ script_entry;
+ static const script_entry script_table[] = {
+ { "Arab", "arabic" },
+ { "Cyrl", "cyrillic" },
+ { "Mong", "mongolian" }
+ };
+
+ /* Step 1: Convert using legacy_table. */
+ if (name[0] >= 'A' && name[0] <= 'Z')
+ {
+ unsigned int i1, i2;
+ i1 = 0;
+ i2 = sizeof (legacy_table) / sizeof (legacy_entry);
+ while (i2 - i1 > 1)
+ {
+ /* At this point we know that if name occurs in legacy_table,
+ its index must be >= i1 and < i2. */
+ unsigned int i = (i1 + i2) >> 1;
+ const legacy_entry *p = &legacy_table[i];
+ if (strcmp (name, p->legacy) < 0)
+ i2 = i;
+ else
+ i1 = i;
+ }
+ if (strcmp (name, legacy_table[i1].legacy) == 0)
+ {
+ strcpy (name, legacy_table[i1].unixy);
+ return;
+ }
+ }
+
+ /* Step 2: Convert using langtag_table and script_table. */
+ if (strlen (name) == 7 && name[2] == '-')
+ {
+ unsigned int i1, i2;
+ i1 = 0;
+ i2 = sizeof (langtag_table) / sizeof (langtag_entry);
+ while (i2 - i1 > 1)
+ {
+ /* At this point we know that if name occurs in langtag_table,
+ its index must be >= i1 and < i2. */
+ unsigned int i = (i1 + i2) >> 1;
+ const langtag_entry *p = &langtag_table[i];
+ if (strcmp (name, p->langtag) < 0)
+ i2 = i;
+ else
+ i1 = i;
+ }
+ if (strcmp (name, langtag_table[i1].langtag) == 0)
+ {
+ strcpy (name, langtag_table[i1].unixy);
+ return;
+ }
+
+ i1 = 0;
+ i2 = sizeof (script_table) / sizeof (script_entry);
+ while (i2 - i1 > 1)
+ {
+ /* At this point we know that if (name + 3) occurs in script_table,
+ its index must be >= i1 and < i2. */
+ unsigned int i = (i1 + i2) >> 1;
+ const script_entry *p = &script_table[i];
+ if (strcmp (name + 3, p->script) < 0)
+ i2 = i;
+ else
+ i1 = i;
+ }
+ if (strcmp (name + 3, script_table[i1].script) == 0)
+ {
+ name[2] = '@';
+ strcpy (name + 3, script_table[i1].unixy);
+ return;
+ }
+ }
+
+ /* Step 3: Convert new-style dash to Unix underscore. */
+ {
+ char *p;
+ for (p = name; *p != '\0'; p++)
+ if (*p == '-')
+ *p = '_';
+ }
+}
+
+#endif
+
+
+#if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
+
+/* Canonicalize a Win32 native locale name to a Unix locale name.
+ NAME is a sufficiently large buffer.
+ On input, it contains the Win32 locale name.
+ On output, it contains the Unix locale name. */
+# if !defined IN_LIBINTL
+static
+# endif
+void
+gl_locale_name_canonicalize (char *name)
+{
+ /* FIXME: This is probably incomplete: it does not handle "zh-Hans" and
+ "zh-Hant". */
+ char *p;
+
+ for (p = name; *p != '\0'; p++)
+ if (*p == '-')
+ {
+ *p = '_';
+ p++;
+ for (; *p != '\0'; p++)
+ {
+ if (*p >= 'a' && *p <= 'z')
+ *p += 'A' - 'a';
+ if (*p == '-')
+ {
+ *p = '\0';
+ return;
+ }
+ }
+ return;
+ }
+}
+
+# if !defined IN_LIBINTL
+static
+# endif
+const char *
+gl_locale_name_from_win32_LANGID (LANGID langid)
+{
+ /* Activate the new code only when the GETTEXT_MUI environment variable is
+ set, for the time being, since the new code is not well tested. */
+ if (getenv ("GETTEXT_MUI") != NULL)
+ {
+ static char namebuf[256];
+
+ /* Query the system's notion of locale name.
+ On Windows95/98/ME, GetLocaleInfoA returns some incorrect results.
+ But we don't need to support systems that are so old. */
+ if (GetLocaleInfoA (MAKELCID (langid, SORT_DEFAULT), LOCALE_SNAME,
+ namebuf, sizeof (namebuf) - 1))
+ {
+ /* Convert it to a Unix locale name. */
+ gl_locale_name_canonicalize (namebuf);
+ return namebuf;
+ }
+ }
+ /* Internet Explorer has an LCID to RFC3066 name mapping stored in
+ HKEY_CLASSES_ROOT\Mime\Database\Rfc1766. But we better don't use that
+ since IE's i18n subsystem is known to be inconsistent with the Win32 base
+ (e.g. they have different character conversion facilities that produce
+ different results). */
+ /* Use our own table. */
+ {
+ int primary, sub;
+
+ /* Split into language and territory part. */
+ primary = PRIMARYLANGID (langid);
+ sub = SUBLANGID (langid);
+
+ /* Dispatch on language.
+ See also http://www.unicode.org/unicode/onlinedat/languages.html .
+ For details about languages, see http://www.ethnologue.com/ . */
+ switch (primary)
+ {
+ case LANG_AFRIKAANS:
+ switch (sub)
+ {
+ case SUBLANG_AFRIKAANS_SOUTH_AFRICA: return "af_ZA";
+ }
+ return "af";
+ case LANG_ALBANIAN:
+ switch (sub)
+ {
+ case SUBLANG_ALBANIAN_ALBANIA: return "sq_AL";
+ }
+ return "sq";
+ case LANG_ALSATIAN:
+ switch (sub)
+ {
+ case SUBLANG_ALSATIAN_FRANCE: return "gsw_FR";
+ }
+ return "gsw";
+ case LANG_AMHARIC:
+ switch (sub)
+ {
+ case SUBLANG_AMHARIC_ETHIOPIA: return "am_ET";
+ }
+ return "am";
+ case LANG_ARABIC:
+ switch (sub)
+ {
+ case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
+ case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
+ case SUBLANG_ARABIC_EGYPT: return "ar_EG";
+ case SUBLANG_ARABIC_LIBYA: return "ar_LY";
+ case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
+ case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
+ case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
+ case SUBLANG_ARABIC_OMAN: return "ar_OM";
+ case SUBLANG_ARABIC_YEMEN: return "ar_YE";
+ case SUBLANG_ARABIC_SYRIA: return "ar_SY";
+ case SUBLANG_ARABIC_JORDAN: return "ar_JO";
+ case SUBLANG_ARABIC_LEBANON: return "ar_LB";
+ case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
+ case SUBLANG_ARABIC_UAE: return "ar_AE";
+ case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
+ case SUBLANG_ARABIC_QATAR: return "ar_QA";
+ }
+ return "ar";
+ case LANG_ARMENIAN:
+ switch (sub)
+ {
+ case SUBLANG_ARMENIAN_ARMENIA: return "hy_AM";
+ }
+ return "hy";
+ case LANG_ASSAMESE:
+ switch (sub)
+ {
+ case SUBLANG_ASSAMESE_INDIA: return "as_IN";
+ }
+ return "as";
+ case LANG_AZERI:
+ switch (sub)
+ {
+ /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */
+ case 0x1e: return "az@latin";
+ case SUBLANG_AZERI_LATIN: return "az_AZ@latin";
+ case 0x1d: return "az@cyrillic";
+ case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic";
+ }
+ return "az";
+ case LANG_BASHKIR:
+ switch (sub)
+ {
+ case SUBLANG_BASHKIR_RUSSIA: return "ba_RU";
+ }
+ return "ba";
+ case LANG_BASQUE:
+ switch (sub)
+ {
+ case SUBLANG_BASQUE_BASQUE: return "eu_ES";
+ }
+ return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */
+ case LANG_BELARUSIAN:
+ switch (sub)
+ {
+ case SUBLANG_BELARUSIAN_BELARUS: return "be_BY";
+ }
+ return "be";
+ case LANG_BENGALI:
+ switch (sub)
+ {
+ case SUBLANG_BENGALI_INDIA: return "bn_IN";
+ case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
+ }
+ return "bn";
+ case LANG_BRETON:
+ switch (sub)
+ {
+ case SUBLANG_BRETON_FRANCE: return "br_FR";
+ }
+ return "br";
+ case LANG_BULGARIAN:
+ switch (sub)
+ {
+ case SUBLANG_BULGARIAN_BULGARIA: return "bg_BG";
+ }
+ return "bg";
+ case LANG_BURMESE:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "my_MM";
+ }
+ return "my";
+ case LANG_CAMBODIAN:
+ switch (sub)
+ {
+ case SUBLANG_CAMBODIAN_CAMBODIA: return "km_KH";
+ }
+ return "km";
+ case LANG_CATALAN:
+ switch (sub)
+ {
+ case SUBLANG_CATALAN_SPAIN: return "ca_ES";
+ }
+ return "ca";
+ case LANG_CHEROKEE:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "chr_US";
+ }
+ return "chr";
+ case LANG_CHINESE:
+ switch (sub)
+ {
+ case SUBLANG_CHINESE_TRADITIONAL: case 0x1f: return "zh_TW";
+ case SUBLANG_CHINESE_SIMPLIFIED: case 0x00: return "zh_CN";
+ case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; /* traditional */
+ case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; /* simplified */
+ case SUBLANG_CHINESE_MACAU: return "zh_MO"; /* traditional */
+ }
+ return "zh";
+ case LANG_CORSICAN:
+ switch (sub)
+ {
+ case SUBLANG_CORSICAN_FRANCE: return "co_FR";
+ }
+ return "co";
+ case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN
+ * What used to be called Serbo-Croatian
+ * should really now be two separate
+ * languages because of political reasons.
+ * (Says tml, who knows nothing about Serbian
+ * or Croatian.)
+ * (I can feel those flames coming already.)
+ */
+ switch (sub)
+ {
+ /* Croatian */
+ case 0x00: return "hr";
+ case SUBLANG_CROATIAN_CROATIA: return "hr_HR";
+ case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN: return "hr_BA";
+ /* Serbian */
+ case 0x1f: return "sr";
+ case 0x1c: return "sr"; /* latin */
+ case SUBLANG_SERBIAN_LATIN: return "sr_CS"; /* latin */
+ case 0x09: return "sr_RS"; /* latin */
+ case 0x0b: return "sr_ME"; /* latin */
+ case 0x06: return "sr_BA"; /* latin */
+ case 0x1b: return "sr@cyrillic";
+ case SUBLANG_SERBIAN_CYRILLIC: return "sr_CS@cyrillic";
+ case 0x0a: return "sr_RS@cyrillic";
+ case 0x0c: return "sr_ME@cyrillic";
+ case 0x07: return "sr_BA@cyrillic";
+ /* Bosnian */
+ case 0x1e: return "bs";
+ case 0x1a: return "bs"; /* latin */
+ case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN: return "bs_BA"; /* latin */
+ case 0x19: return "bs@cyrillic";
+ case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC: return "bs_BA@cyrillic";
+ }
+ return "hr";
+ case LANG_CZECH:
+ switch (sub)
+ {
+ case SUBLANG_CZECH_CZECH_REPUBLIC: return "cs_CZ";
+ }
+ return "cs";
+ case LANG_DANISH:
+ switch (sub)
+ {
+ case SUBLANG_DANISH_DENMARK: return "da_DK";
+ }
+ return "da";
+ case LANG_DARI:
+ /* FIXME: Adjust this when such locales appear on Unix. */
+ switch (sub)
+ {
+ case SUBLANG_DARI_AFGHANISTAN: return "prs_AF";
+ }
+ return "prs";
+ case LANG_DIVEHI:
+ switch (sub)
+ {
+ case SUBLANG_DIVEHI_MALDIVES: return "dv_MV";
+ }
+ return "dv";
+ case LANG_DUTCH:
+ switch (sub)
+ {
+ case SUBLANG_DUTCH: return "nl_NL";
+ case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
+ case SUBLANG_DUTCH_SURINAM: return "nl_SR";
+ }
+ return "nl";
+ case LANG_EDO:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "bin_NG";
+ }
+ return "bin";
+ case LANG_ENGLISH:
+ switch (sub)
+ {
+ /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
+ * English was the language spoken in England.
+ * Oh well.
+ */
+ case SUBLANG_ENGLISH_US: return "en_US";
+ case SUBLANG_ENGLISH_UK: return "en_GB";
+ case SUBLANG_ENGLISH_AUS: return "en_AU";
+ case SUBLANG_ENGLISH_CAN: return "en_CA";
+ case SUBLANG_ENGLISH_NZ: return "en_NZ";
+ case SUBLANG_ENGLISH_EIRE: return "en_IE";
+ case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
+ case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
+ case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
+ case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
+ case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
+ case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
+ case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
+ case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
+ case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
+ case SUBLANG_ENGLISH_INDIA: return "en_IN";
+ case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
+ case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
+ }
+ return "en";
+ case LANG_ESTONIAN:
+ switch (sub)
+ {
+ case SUBLANG_ESTONIAN_ESTONIA: return "et_EE";
+ }
+ return "et";
+ case LANG_FAEROESE:
+ switch (sub)
+ {
+ case SUBLANG_FAEROESE_FAROE_ISLANDS: return "fo_FO";
+ }
+ return "fo";
+ case LANG_FARSI:
+ switch (sub)
+ {
+ case SUBLANG_FARSI_IRAN: return "fa_IR";
+ }
+ return "fa";
+ case LANG_FINNISH:
+ switch (sub)
+ {
+ case SUBLANG_FINNISH_FINLAND: return "fi_FI";
+ }
+ return "fi";
+ case LANG_FRENCH:
+ switch (sub)
+ {
+ case SUBLANG_FRENCH: return "fr_FR";
+ case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
+ case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
+ case SUBLANG_FRENCH_SWISS: return "fr_CH";
+ case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
+ case SUBLANG_FRENCH_MONACO: return "fr_MC";
+ case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
+ case SUBLANG_FRENCH_REUNION: return "fr_RE";
+ case SUBLANG_FRENCH_CONGO: return "fr_CG";
+ case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
+ case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
+ case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
+ case SUBLANG_FRENCH_MALI: return "fr_ML";
+ case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
+ case SUBLANG_FRENCH_HAITI: return "fr_HT";
+ }
+ return "fr";
+ case LANG_FRISIAN:
+ switch (sub)
+ {
+ case SUBLANG_FRISIAN_NETHERLANDS: return "fy_NL";
+ }
+ return "fy";
+ case LANG_FULFULDE:
+ /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin. */
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "ff_NG";
+ }
+ return "ff";
+ case LANG_GAELIC:
+ switch (sub)
+ {
+ case 0x01: /* SCOTTISH */
+ /* old, superseded by LANG_SCOTTISH_GAELIC */
+ return "gd_GB";
+ case SUBLANG_IRISH_IRELAND: return "ga_IE";
+ }
+ return "ga";
+ case LANG_GALICIAN:
+ switch (sub)
+ {
+ case SUBLANG_GALICIAN_SPAIN: return "gl_ES";
+ }
+ return "gl";
+ case LANG_GEORGIAN:
+ switch (sub)
+ {
+ case SUBLANG_GEORGIAN_GEORGIA: return "ka_GE";
+ }
+ return "ka";
+ case LANG_GERMAN:
+ switch (sub)
+ {
+ case SUBLANG_GERMAN: return "de_DE";
+ case SUBLANG_GERMAN_SWISS: return "de_CH";
+ case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
+ case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
+ case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
+ }
+ return "de";
+ case LANG_GREEK:
+ switch (sub)
+ {
+ case SUBLANG_GREEK_GREECE: return "el_GR";
+ }
+ return "el";
+ case LANG_GREENLANDIC:
+ switch (sub)
+ {
+ case SUBLANG_GREENLANDIC_GREENLAND: return "kl_GL";
+ }
+ return "kl";
+ case LANG_GUARANI:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "gn_PY";
+ }
+ return "gn";
+ case LANG_GUJARATI:
+ switch (sub)
+ {
+ case SUBLANG_GUJARATI_INDIA: return "gu_IN";
+ }
+ return "gu";
+ case LANG_HAUSA:
+ switch (sub)
+ {
+ case 0x1f: return "ha";
+ case SUBLANG_HAUSA_NIGERIA_LATIN: return "ha_NG";
+ }
+ return "ha";
+ case LANG_HAWAIIAN:
+ /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
+ or Hawaii Creole English ("cpe_US", 600000 speakers)? */
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "cpe_US";
+ }
+ return "cpe";
+ case LANG_HEBREW:
+ switch (sub)
+ {
+ case SUBLANG_HEBREW_ISRAEL: return "he_IL";
+ }
+ return "he";
+ case LANG_HINDI:
+ switch (sub)
+ {
+ case SUBLANG_HINDI_INDIA: return "hi_IN";
+ }
+ return "hi";
+ case LANG_HUNGARIAN:
+ switch (sub)
+ {
+ case SUBLANG_HUNGARIAN_HUNGARY: return "hu_HU";
+ }
+ return "hu";
+ case LANG_IBIBIO:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "nic_NG";
+ }
+ return "nic";
+ case LANG_ICELANDIC:
+ switch (sub)
+ {
+ case SUBLANG_ICELANDIC_ICELAND: return "is_IS";
+ }
+ return "is";
+ case LANG_IGBO:
+ switch (sub)
+ {
+ case SUBLANG_IGBO_NIGERIA: return "ig_NG";
+ }
+ return "ig";
+ case LANG_INDONESIAN:
+ switch (sub)
+ {
+ case SUBLANG_INDONESIAN_INDONESIA: return "id_ID";
+ }
+ return "id";
+ case LANG_INUKTITUT:
+ switch (sub)
+ {
+ case 0x1e: return "iu"; /* syllabic */
+ case SUBLANG_INUKTITUT_CANADA: return "iu_CA"; /* syllabic */
+ case 0x1f: return "iu@latin";
+ case SUBLANG_INUKTITUT_CANADA_LATIN: return "iu_CA@latin";
+ }
+ return "iu";
+ case LANG_ITALIAN:
+ switch (sub)
+ {
+ case SUBLANG_ITALIAN: return "it_IT";
+ case SUBLANG_ITALIAN_SWISS: return "it_CH";
+ }
+ return "it";
+ case LANG_JAPANESE:
+ switch (sub)
+ {
+ case SUBLANG_JAPANESE_JAPAN: return "ja_JP";
+ }
+ return "ja";
+ case LANG_KANNADA:
+ switch (sub)
+ {
+ case SUBLANG_KANNADA_INDIA: return "kn_IN";
+ }
+ return "kn";
+ case LANG_KANURI:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "kr_NG";
+ }
+ return "kr";
+ case LANG_KASHMIRI:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "ks_PK";
+ case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
+ }
+ return "ks";
+ case LANG_KAZAK:
+ switch (sub)
+ {
+ case SUBLANG_KAZAK_KAZAKHSTAN: return "kk_KZ";
+ }
+ return "kk";
+ case LANG_KICHE:
+ /* FIXME: Adjust this when such locales appear on Unix. */
+ switch (sub)
+ {
+ case SUBLANG_KICHE_GUATEMALA: return "qut_GT";
+ }
+ return "qut";
+ case LANG_KINYARWANDA:
+ switch (sub)
+ {
+ case SUBLANG_KINYARWANDA_RWANDA: return "rw_RW";
+ }
+ return "rw";
+ case LANG_KONKANI:
+ /* FIXME: Adjust this when such locales appear on Unix. */
+ switch (sub)
+ {
+ case SUBLANG_KONKANI_INDIA: return "kok_IN";
+ }
+ return "kok";
+ case LANG_KOREAN:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "ko_KR";
+ }
+ return "ko";
+ case LANG_KYRGYZ:
+ switch (sub)
+ {
+ case SUBLANG_KYRGYZ_KYRGYZSTAN: return "ky_KG";
+ }
+ return "ky";
+ case LANG_LAO:
+ switch (sub)
+ {
+ case SUBLANG_LAO_LAOS: return "lo_LA";
+ }
+ return "lo";
+ case LANG_LATIN:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "la_VA";
+ }
+ return "la";
+ case LANG_LATVIAN:
+ switch (sub)
+ {
+ case SUBLANG_LATVIAN_LATVIA: return "lv_LV";
+ }
+ return "lv";
+ case LANG_LITHUANIAN:
+ switch (sub)
+ {
+ case SUBLANG_LITHUANIAN_LITHUANIA: return "lt_LT";
+ }
+ return "lt";
+ case LANG_LUXEMBOURGISH:
+ switch (sub)
+ {
+ case SUBLANG_LUXEMBOURGISH_LUXEMBOURG: return "lb_LU";
+ }
+ return "lb";
+ case LANG_MACEDONIAN:
+ switch (sub)
+ {
+ case SUBLANG_MACEDONIAN_MACEDONIA: return "mk_MK";
+ }
+ return "mk";
+ case LANG_MALAY:
+ switch (sub)
+ {
+ case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
+ case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
+ }
+ return "ms";
+ case LANG_MALAYALAM:
+ switch (sub)
+ {
+ case SUBLANG_MALAYALAM_INDIA: return "ml_IN";
+ }
+ return "ml";
+ case LANG_MALTESE:
+ switch (sub)
+ {
+ case SUBLANG_MALTESE_MALTA: return "mt_MT";
+ }
+ return "mt";
+ case LANG_MANIPURI:
+ /* FIXME: Adjust this when such locales appear on Unix. */
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "mni_IN";
+ }
+ return "mni";
+ case LANG_MAORI:
+ switch (sub)
+ {
+ case SUBLANG_MAORI_NEW_ZEALAND: return "mi_NZ";
+ }
+ return "mi";
+ case LANG_MAPUDUNGUN:
+ switch (sub)
+ {
+ case SUBLANG_MAPUDUNGUN_CHILE: return "arn_CL";
+ }
+ return "arn";
+ case LANG_MARATHI:
+ switch (sub)
+ {
+ case SUBLANG_MARATHI_INDIA: return "mr_IN";
+ }
+ return "mr";
+ case LANG_MOHAWK:
+ switch (sub)
+ {
+ case SUBLANG_MOHAWK_CANADA: return "moh_CA";
+ }
+ return "moh";
+ case LANG_MONGOLIAN:
+ switch (sub)
+ {
+ case SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA: case 0x1e: return "mn_MN";
+ case SUBLANG_MONGOLIAN_PRC: case 0x1f: return "mn_CN";
+ }
+ return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */
+ case LANG_NEPALI:
+ switch (sub)
+ {
+ case SUBLANG_NEPALI_NEPAL: return "ne_NP";
+ case SUBLANG_NEPALI_INDIA: return "ne_IN";
+ }
+ return "ne";
+ case LANG_NORWEGIAN:
+ switch (sub)
+ {
+ case 0x1f: return "nb";
+ case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
+ case 0x1e: return "nn";
+ case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
+ }
+ return "no";
+ case LANG_OCCITAN:
+ switch (sub)
+ {
+ case SUBLANG_OCCITAN_FRANCE: return "oc_FR";
+ }
+ return "oc";
+ case LANG_ORIYA:
+ switch (sub)
+ {
+ case SUBLANG_ORIYA_INDIA: return "or_IN";
+ }
+ return "or";
+ case LANG_OROMO:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "om_ET";
+ }
+ return "om";
+ case LANG_PAPIAMENTU:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "pap_AN";
+ }
+ return "pap";
+ case LANG_PASHTO:
+ switch (sub)
+ {
+ case SUBLANG_PASHTO_AFGHANISTAN: return "ps_AF";
+ }
+ return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */
+ case LANG_POLISH:
+ switch (sub)
+ {
+ case SUBLANG_POLISH_POLAND: return "pl_PL";
+ }
+ return "pl";
+ case LANG_PORTUGUESE:
+ switch (sub)
+ {
+ /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
+ Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
+ case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
+ case SUBLANG_PORTUGUESE: return "pt_PT";
+ }
+ return "pt";
+ case LANG_PUNJABI:
+ switch (sub)
+ {
+ case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
+ case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
+ }
+ return "pa";
+ case LANG_QUECHUA:
+ /* Note: Microsoft uses the non-ISO language code "quz". */
+ switch (sub)
+ {
+ case SUBLANG_QUECHUA_BOLIVIA: return "qu_BO";
+ case SUBLANG_QUECHUA_ECUADOR: return "qu_EC";
+ case SUBLANG_QUECHUA_PERU: return "qu_PE";
+ }
+ return "qu";
+ case LANG_ROMANIAN:
+ switch (sub)
+ {
+ case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
+ case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
+ }
+ return "ro";
+ case LANG_ROMANSH:
+ switch (sub)
+ {
+ case SUBLANG_ROMANSH_SWITZERLAND: return "rm_CH";
+ }
+ return "rm";
+ case LANG_RUSSIAN:
+ switch (sub)
+ {
+ case SUBLANG_RUSSIAN_RUSSIA: return "ru_RU";
+ case SUBLANG_RUSSIAN_MOLDAVIA: return "ru_MD";
+ }
+ return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD". */
+ case LANG_SAMI:
+ switch (sub)
+ {
+ /* Northern Sami */
+ case 0x00: return "se";
+ case SUBLANG_SAMI_NORTHERN_NORWAY: return "se_NO";
+ case SUBLANG_SAMI_NORTHERN_SWEDEN: return "se_SE";
+ case SUBLANG_SAMI_NORTHERN_FINLAND: return "se_FI";
+ /* Lule Sami */
+ case 0x1f: return "smj";
+ case SUBLANG_SAMI_LULE_NORWAY: return "smj_NO";
+ case SUBLANG_SAMI_LULE_SWEDEN: return "smj_SE";
+ /* Southern Sami */
+ case 0x1e: return "sma";
+ case SUBLANG_SAMI_SOUTHERN_NORWAY: return "sma_NO";
+ case SUBLANG_SAMI_SOUTHERN_SWEDEN: return "sma_SE";
+ /* Skolt Sami */
+ case 0x1d: return "sms";
+ case SUBLANG_SAMI_SKOLT_FINLAND: return "sms_FI";
+ /* Inari Sami */
+ case 0x1c: return "smn";
+ case SUBLANG_SAMI_INARI_FINLAND: return "smn_FI";
+ }
+ return "se"; /* or "smi"? */
+ case LANG_SANSKRIT:
+ switch (sub)
+ {
+ case SUBLANG_SANSKRIT_INDIA: return "sa_IN";
+ }
+ return "sa";
+ case LANG_SCOTTISH_GAELIC:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "gd_GB";
+ }
+ return "gd";
+ case LANG_SINDHI:
+ switch (sub)
+ {
+ case SUBLANG_SINDHI_INDIA: return "sd_IN";
+ case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
+ /*case SUBLANG_SINDHI_AFGHANISTAN: return "sd_AF";*/
+ }
+ return "sd";
+ case LANG_SINHALESE:
+ switch (sub)
+ {
+ case SUBLANG_SINHALESE_SRI_LANKA: return "si_LK";
+ }
+ return "si";
+ case LANG_SLOVAK:
+ switch (sub)
+ {
+ case SUBLANG_SLOVAK_SLOVAKIA: return "sk_SK";
+ }
+ return "sk";
+ case LANG_SLOVENIAN:
+ switch (sub)
+ {
+ case SUBLANG_SLOVENIAN_SLOVENIA: return "sl_SI";
+ }
+ return "sl";
+ case LANG_SOMALI:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "so_SO";
+ }
+ return "so";
+ case LANG_SORBIAN:
+ /* FIXME: Adjust this when such locales appear on Unix. */
+ switch (sub)
+ {
+ /* Upper Sorbian */
+ case 0x00: return "hsb";
+ case SUBLANG_UPPER_SORBIAN_GERMANY: return "hsb_DE";
+ /* Lower Sorbian */
+ case 0x1f: return "dsb";
+ case SUBLANG_LOWER_SORBIAN_GERMANY: return "dsb_DE";
+ }
+ return "wen";
+ case LANG_SOTHO:
+ /* <http://www.microsoft.com/globaldev/reference/lcid-all.mspx> calls
+ it "Sepedi"; according to
+ <http://www.ethnologue.com/show_language.asp?code=nso>
+ <http://www.ethnologue.com/show_language.asp?code=sot>
+ it's the same as Northern Sotho. */
+ switch (sub)
+ {
+ case SUBLANG_SOTHO_SOUTH_AFRICA: return "nso_ZA";
+ }
+ return "nso";
+ case LANG_SPANISH:
+ switch (sub)
+ {
+ case SUBLANG_SPANISH: return "es_ES";
+ case SUBLANG_SPANISH_MEXICAN: return "es_MX";
+ case SUBLANG_SPANISH_MODERN:
+ return "es_ES@modern"; /* not seen on Unix */
+ case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
+ case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
+ case SUBLANG_SPANISH_PANAMA: return "es_PA";
+ case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
+ case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
+ case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
+ case SUBLANG_SPANISH_PERU: return "es_PE";
+ case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
+ case SUBLANG_SPANISH_ECUADOR: return "es_EC";
+ case SUBLANG_SPANISH_CHILE: return "es_CL";
+ case SUBLANG_SPANISH_URUGUAY: return "es_UY";
+ case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
+ case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
+ case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
+ case SUBLANG_SPANISH_HONDURAS: return "es_HN";
+ case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
+ case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
+ case SUBLANG_SPANISH_US: return "es_US";
+ }
+ return "es";
+ case LANG_SUTU:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
+ }
+ return "bnt";
+ case LANG_SWAHILI:
+ switch (sub)
+ {
+ case SUBLANG_SWAHILI_KENYA: return "sw_KE";
+ }
+ return "sw";
+ case LANG_SWEDISH:
+ switch (sub)
+ {
+ case SUBLANG_SWEDISH_SWEDEN: return "sv_SE";
+ case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
+ }
+ return "sv";
+ case LANG_SYRIAC:
+ switch (sub)
+ {
+ case SUBLANG_SYRIAC_SYRIA: return "syr_SY"; /* An extinct language. */
+ }
+ return "syr";
+ case LANG_TAGALOG:
+ switch (sub)
+ {
+ case SUBLANG_TAGALOG_PHILIPPINES: return "tl_PH"; /* or "fil_PH"? */
+ }
+ return "tl"; /* or "fil"? */
+ case LANG_TAJIK:
+ switch (sub)
+ {
+ case 0x1f: return "tg";
+ case SUBLANG_TAJIK_TAJIKISTAN: return "tg_TJ";
+ }
+ return "tg";
+ case LANG_TAMAZIGHT:
+ /* Note: Microsoft uses the non-ISO language code "tmz". */
+ switch (sub)
+ {
+ /* FIXME: Adjust this when Tamazight locales appear on Unix. */
+ case SUBLANG_TAMAZIGHT_ARABIC: return "ber_MA@arabic";
+ case 0x1f: return "ber@latin";
+ case SUBLANG_TAMAZIGHT_ALGERIA_LATIN: return "ber_DZ@latin";
+ }
+ return "ber";
+ case LANG_TAMIL:
+ switch (sub)
+ {
+ case SUBLANG_TAMIL_INDIA: return "ta_IN";
+ }
+ return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */
+ case LANG_TATAR:
+ switch (sub)
+ {
+ case SUBLANG_TATAR_RUSSIA: return "tt_RU";
+ }
+ return "tt";
+ case LANG_TELUGU:
+ switch (sub)
+ {
+ case SUBLANG_TELUGU_INDIA: return "te_IN";
+ }
+ return "te";
+ case LANG_THAI:
+ switch (sub)
+ {
+ case SUBLANG_THAI_THAILAND: return "th_TH";
+ }
+ return "th";
+ case LANG_TIBETAN:
+ switch (sub)
+ {
+ case SUBLANG_TIBETAN_PRC:
+ /* Most Tibetans would not like "bo_CN". But Tibet does not yet
+ have a country code of its own. */
+ return "bo";
+ case SUBLANG_TIBETAN_BHUTAN: return "bo_BT";
+ }
+ return "bo";
+ case LANG_TIGRINYA:
+ switch (sub)
+ {
+ case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
+ case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
+ }
+ return "ti";
+ case LANG_TSONGA:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "ts_ZA";
+ }
+ return "ts";
+ case LANG_TSWANA:
+ /* Spoken in South Africa, Botswana. */
+ switch (sub)
+ {
+ case SUBLANG_TSWANA_SOUTH_AFRICA: return "tn_ZA";
+ }
+ return "tn";
+ case LANG_TURKISH:
+ switch (sub)
+ {
+ case SUBLANG_TURKISH_TURKEY: return "tr_TR";
+ }
+ return "tr";
+ case LANG_TURKMEN:
+ switch (sub)
+ {
+ case SUBLANG_TURKMEN_TURKMENISTAN: return "tk_TM";
+ }
+ return "tk";
+ case LANG_UIGHUR:
+ switch (sub)
+ {
+ case SUBLANG_UIGHUR_PRC: return "ug_CN";
+ }
+ return "ug";
+ case LANG_UKRAINIAN:
+ switch (sub)
+ {
+ case SUBLANG_UKRAINIAN_UKRAINE: return "uk_UA";
+ }
+ return "uk";
+ case LANG_URDU:
+ switch (sub)
+ {
+ case SUBLANG_URDU_PAKISTAN: return "ur_PK";
+ case SUBLANG_URDU_INDIA: return "ur_IN";
+ }
+ return "ur";
+ case LANG_UZBEK:
+ switch (sub)
+ {
+ case 0x1f: return "uz";
+ case SUBLANG_UZBEK_LATIN: return "uz_UZ";
+ case 0x1e: return "uz@cyrillic";
+ case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic";
+ }
+ return "uz";
+ case LANG_VENDA:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "ve_ZA";
+ }
+ return "ve";
+ case LANG_VIETNAMESE:
+ switch (sub)
+ {
+ case SUBLANG_VIETNAMESE_VIETNAM: return "vi_VN";
+ }
+ return "vi";
+ case LANG_WELSH:
+ switch (sub)
+ {
+ case SUBLANG_WELSH_UNITED_KINGDOM: return "cy_GB";
+ }
+ return "cy";
+ case LANG_WOLOF:
+ switch (sub)
+ {
+ case SUBLANG_WOLOF_SENEGAL: return "wo_SN";
+ }
+ return "wo";
+ case LANG_XHOSA:
+ switch (sub)
+ {
+ case SUBLANG_XHOSA_SOUTH_AFRICA: return "xh_ZA";
+ }
+ return "xh";
+ case LANG_YAKUT:
+ switch (sub)
+ {
+ case SUBLANG_YAKUT_RUSSIA: return "sah_RU";
+ }
+ return "sah";
+ case LANG_YI:
+ switch (sub)
+ {
+ case SUBLANG_YI_PRC: return "ii_CN";
+ }
+ return "ii";
+ case LANG_YIDDISH:
+ switch (sub)
+ {
+ case SUBLANG_DEFAULT: return "yi_IL";
+ }
+ return "yi";
+ case LANG_YORUBA:
+ switch (sub)
+ {
+ case SUBLANG_YORUBA_NIGERIA: return "yo_NG";
+ }
+ return "yo";
+ case LANG_ZULU:
+ switch (sub)
+ {
+ case SUBLANG_ZULU_SOUTH_AFRICA: return "zu_ZA";
+ }
+ return "zu";
+ default: return "C";
+ }
+ }
+}
+
+# if !defined IN_LIBINTL
+static
+# endif
+const char *
+gl_locale_name_from_win32_LCID (LCID lcid)
+{
+ LANGID langid;
+
+ /* Strip off the sorting rules, keep only the language part. */
+ langid = LANGIDFROMLCID (lcid);
+
+ return gl_locale_name_from_win32_LANGID (langid);
+}
+
+#endif
+
+
+#if HAVE_USELOCALE /* glibc or MacOS X */
+
+/* Simple hash set of strings. We don't want to drag in lots of hash table
+ code here. */
+
+# define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
+
+/* 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 = (const char *) x;
+ size_t h = 0;
+
+ for (; *s; s++)
+ h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
+
+ return h;
+}
+
+/* A hash table of fixed size. Multiple threads can access it read-only
+ simultaneously, but only one thread can insert into it at the same time. */
+
+/* A node in a hash bucket collision list. */
+struct hash_node
+ {
+ struct hash_node * volatile next;
+ char contents[100]; /* has variable size */
+ };
+
+# define HASH_TABLE_SIZE 257
+static struct hash_node * volatile struniq_hash_table[HASH_TABLE_SIZE]
+ /* = { NULL, ..., NULL } */;
+
+/* This lock protects the struniq_hash_table against multiple simultaneous
+ insertions. */
+gl_lock_define_initialized(static, struniq_lock)
+
+/* Store a copy of the given string in a string pool with indefinite extent.
+ Return a pointer to this copy. */
+static const char *
+struniq (const char *string)
+{
+ size_t hashcode = string_hash (string);
+ size_t slot = hashcode % HASH_TABLE_SIZE;
+ size_t size;
+ struct hash_node *new_node;
+ struct hash_node *p;
+ for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
+ if (strcmp (p->contents, string) == 0)
+ return p->contents;
+ size = strlen (string) + 1;
+ new_node =
+ (struct hash_node *)
+ malloc (offsetof (struct hash_node, contents[0]) + size);
+ if (new_node == NULL)
+ /* Out of memory. Return a statically allocated string. */
+ return "C";
+ memcpy (new_node->contents, string, size);
+ /* Lock while inserting new_node. */
+ gl_lock_lock (struniq_lock);
+ /* Check whether another thread already added the string while we were
+ waiting on the lock. */
+ for (p = struniq_hash_table[slot]; p != NULL; p = p->next)
+ if (strcmp (p->contents, string) == 0)
+ {
+ free (new_node);
+ new_node = p;
+ goto done;
+ }
+ /* Really insert new_node into the hash table. Fill new_node entirely first,
+ because other threads may be iterating over the linked list. */
+ new_node->next = struniq_hash_table[slot];
+ struniq_hash_table[slot] = new_node;
+ done:
+ /* Unlock after new_node is inserted. */
+ gl_lock_unlock (struniq_lock);
+ return new_node->contents;
+}
+
+#endif
+
+
+#if defined IN_LIBINTL || HAVE_USELOCALE
+
+/* Like gl_locale_name_thread, except that the result is not in storage of
+ indefinite extent. */
+# if !defined IN_LIBINTL
+static
+# endif
+const char *
+gl_locale_name_thread_unsafe (int category, const char *categoryname)
+{
+# if HAVE_USELOCALE
+ {
+ locale_t thread_locale = uselocale (NULL);
+ if (thread_locale != LC_GLOBAL_LOCALE)
+ {
+# if __GLIBC__ >= 2 && !defined __UCLIBC__
+ /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in
+ glibc < 2.12.
+ See <http://sourceware.org/bugzilla/show_bug.cgi?id=10968>. */
+ const char *name =
+ nl_langinfo (_NL_ITEM ((category), _NL_ITEM_INDEX (-1)));
+ if (name[0] == '\0')
+ /* Fallback code for glibc < 2.4, which did not implement
+ nl_langinfo (_NL_LOCALE_NAME (category)). */
+ name = thread_locale->__names[category];
+ return name;
+# endif
+# if defined __APPLE__ && defined __MACH__ /* MacOS X */
+ /* The locale name is found deep in an undocumented data structure.
+ Since it's stored in a buffer of size 32 and newlocale() rejects
+ locale names of length > 31, we can assume that it is NUL terminated
+ in this buffer. But we need to make a copy of the locale name, of
+ indefinite extent. */
+ struct _xlocale_part1_v0 /* used in MacOS X 10.5 */
+ {
+ int32_t __refcount;
+ void (*__free_extra)(void *);
+ __darwin_mbstate_t __mbs[10];
+ int64_t __magic;
+ };
+ struct _xlocale_part1_v1 /* used in MacOS X >= 10.6.0 */
+ {
+ int32_t __refcount;
+ void (*__free_extra)(void *);
+ __darwin_mbstate_t __mbs[10];
+ /*pthread_lock_t*/ int __lock;
+ int64_t __magic;
+ };
+ struct _xlocale_part2
+ {
+ int64_t __magic;
+ unsigned char __collate_load_error;
+ unsigned char __collate_substitute_nontrivial;
+ unsigned char _messages_using_locale;
+ unsigned char _monetary_using_locale;
+ unsigned char _numeric_using_locale;
+ unsigned char _time_using_locale;
+ unsigned char __mlocale_changed;
+ unsigned char __nlocale_changed;
+ unsigned char __numeric_fp_cvt;
+ struct __xlocale_st_collate *__lc_collate;
+ struct __xlocale_st_runelocale *__lc_ctype;
+ struct __xlocale_st_messages *__lc_messages;
+ struct __xlocale_st_monetary *__lc_monetary;
+ struct __xlocale_st_numeric *__lc_numeric;
+ struct _xlocale *__lc_numeric_loc;
+ struct __xlocale_st_time *__lc_time;
+ /* more */
+ };
+ struct __xlocale_st_collate
+ {
+ int32_t __refcount;
+ void (*__free_extra)(void *);
+ char __encoding[32];
+ /* more */
+ };
+ struct __xlocale_st_runelocale
+ {
+ int32_t __refcount;
+ void (*__free_extra)(void *);
+ char __ctype_encoding[32];
+ /* more */
+ };
+ struct __xlocale_st_messages
+ {
+ int32_t __refcount;
+ void (*__free_extra)(void *);
+ char *_messages_locale_buf;
+ /* more */
+ };
+ struct __xlocale_st_monetary
+ {
+ int32_t __refcount;
+ void (*__free_extra)(void *);
+ char *_monetary_locale_buf;
+ /* more */
+ };
+ struct __xlocale_st_numeric {
+ int32_t __refcount;
+ void (*__free_extra)(void *);
+ char *_numeric_locale_buf;
+ /* more */
+ };
+ struct __xlocale_st_time {
+ int32_t __refcount;
+ void (*__free_extra)(void *);
+ char *_time_locale_buf;
+ /* more */
+ };
+ struct _xlocale_part2 *tlp;
+ if (((struct _xlocale_part1_v0 *) thread_locale)->__magic
+ == 0x786C6F63616C6530LL)
+ /* MacOS X 10.5 */
+ tlp =
+ (struct _xlocale_part2 *)
+ &((struct _xlocale_part1_v0 *) thread_locale)->__magic;
+ else if (((struct _xlocale_part1_v1 *) thread_locale)->__magic
+ == 0x786C6F63616C6530LL)
+ /* MacOS X >= 10.6.0 */
+ tlp =
+ (struct _xlocale_part2 *)
+ &((struct _xlocale_part1_v1 *) thread_locale)->__magic;
+ else
+ /* Unsupported version of MacOS X: The internals of 'struct _xlocale'
+ have changed again. */
+ return "";
+ switch (category)
+ {
+ case LC_CTYPE:
+ return tlp->__lc_ctype->__ctype_encoding;
+ case LC_NUMERIC:
+ return tlp->_numeric_using_locale
+ ? tlp->__lc_numeric->_numeric_locale_buf
+ : "C";
+ case LC_TIME:
+ return tlp->_time_using_locale
+ ? tlp->__lc_time->_time_locale_buf
+ : "C";
+ case LC_COLLATE:
+ return !tlp->__collate_load_error
+ ? tlp->__lc_collate->__encoding
+ : "C";
+ case LC_MONETARY:
+ return tlp->_monetary_using_locale
+ ? tlp->__lc_monetary->_monetary_locale_buf
+ : "C";
+ case LC_MESSAGES:
+ return tlp->_messages_using_locale
+ ? tlp->__lc_messages->_messages_locale_buf
+ : "C";
+ default: /* We shouldn't get here. */
+ return "";
+ }
+# endif
+ }
+ }
+# endif
+ return NULL;
+}
+
+#endif
+
+const char *
+gl_locale_name_thread (int category, const char *categoryname)
+{
+#if HAVE_USELOCALE
+ const char *name = gl_locale_name_thread_unsafe (category, categoryname);
+ if (name != NULL)
+ return struniq (name);
+#endif
+ return NULL;
+}
+
+/* XPG3 defines the result of 'setlocale (category, NULL)' as:
+ "Directs 'setlocale()' to query 'category' and return the current
+ setting of 'local'."
+ However it does not specify the exact format. Neither do SUSV2 and
+ ISO C 99. So we can use this feature only on selected systems (e.g.
+ those using GNU C Library). */
+#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
+# define HAVE_LOCALE_NULL
+#endif
+
+const char *
+gl_locale_name_posix (int category, const char *categoryname)
+{
+ /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
+ On some systems this can be done by the 'setlocale' function itself. */
+#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
+ return setlocale (category, NULL);
+#else
+ /* On other systems we ignore what setlocale reports and instead look at the
+ environment variables directly. This is necessary
+ 1. on systems which have a facility for customizing the default locale
+ (MacOS X, native Windows, Cygwin) and where the system's setlocale()
+ function ignores this default locale (MacOS X, Cygwin), in two cases:
+ a. when the user missed to use the setlocale() override from libintl
+ (for example by not including <libintl.h>),
+ b. when setlocale supports only the "C" locale, such as on Cygwin
+ 1.5.x. In this case even the override from libintl cannot help.
+ 2. on all systems where setlocale supports only the "C" locale. */
+ /* Strictly speaking, it is a POSIX violation to look at the environment
+ variables regardless whether setlocale has been called or not. POSIX
+ says:
+ "For C-language programs, the POSIX locale shall be the
+ default locale when the setlocale() function is not called."
+ But we assume that all programs that use internationalized APIs call
+ setlocale (LC_ALL, ""). */
+ return gl_locale_name_environ (category, categoryname);
+#endif
+}
+
+const char *
+gl_locale_name_environ (int category, const char *categoryname)
+{
+ const char *retval;
+
+ /* Setting of LC_ALL overrides all other. */
+ retval = getenv ("LC_ALL");
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+ /* Next comes the name of the desired category. */
+ retval = getenv (categoryname);
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+ /* Last possibility is the LANG environment variable. */
+ retval = getenv ("LANG");
+ if (retval != NULL && retval[0] != '\0')
+ {
+#if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
+ /* MacOS X 10.2 or newer.
+ Ignore invalid LANG value set by the Terminal application. */
+ if (strcmp (retval, "UTF-8") != 0)
+#endif
+#if defined __CYGWIN__
+ /* Cygwin.
+ Ignore dummy LANG value set by ~/.profile. */
+ if (strcmp (retval, "C.UTF-8") != 0)
+#endif
+ return retval;
+ }
+
+ return NULL;
+}
+
+const char *
+gl_locale_name_default (void)
+{
+ /* POSIX:2001 says:
+ "All implementations shall define a locale as the default locale, to be
+ invoked when no environment variables are set, or set to the empty
+ string. This default locale can be the POSIX locale or any other
+ implementation-defined locale. Some implementations may provide
+ facilities for local installation administrators to set the default
+ locale, customizing it for each location. POSIX:2001 does not require
+ such a facility.
+
+ The systems with such a facility are MacOS X and Windows: They provide a
+ GUI that allows the user to choose a locale.
+ - On MacOS X, by default, none of LC_* or LANG are set. Starting with
+ MacOS X 10.4 or 10.5, LANG is set for processes launched by the
+ 'Terminal' application (but sometimes to an incorrect value "UTF-8").
+ When no environment variable is set, setlocale (LC_ALL, "") uses the
+ "C" locale.
+ - On native Windows, by default, none of LC_* or LANG are set.
+ When no environment variable is set, setlocale (LC_ALL, "") uses the
+ locale chosen by the user.
+ - On Cygwin 1.5.x, by default, none of LC_* or LANG are set.
+ When no environment variable is set, setlocale (LC_ALL, "") uses the
+ "C" locale.
+ - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default
+ ~/.profile is executed.
+ When no environment variable is set, setlocale (LC_ALL, "") uses the
+ "C.UTF-8" locale, which operates in the same way as the "C" locale.
+ */
+
+#if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined WIN32_NATIVE || defined __CYGWIN__)
+
+ /* The system does not have a way of setting the locale, other than the
+ POSIX specified environment variables. We use C as default locale. */
+ return "C";
+
+#else
+
+ /* Return an XPG style locale name language[_territory][@modifier].
+ Don't even bother determining the codeset; it's not useful in this
+ context, because message catalogs are not specific to a single
+ codeset. */
+
+# if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
+ /* MacOS X 10.2 or newer */
+ {
+ /* Cache the locale name, since CoreFoundation calls are expensive. */
+ static const char *cached_localename;
+
+ if (cached_localename == NULL)
+ {
+ char namebuf[256];
+# if HAVE_CFLOCALECOPYCURRENT /* MacOS X 10.3 or newer */
+ CFLocaleRef locale = CFLocaleCopyCurrent ();
+ CFStringRef name = CFLocaleGetIdentifier (locale);
+
+ if (CFStringGetCString (name, namebuf, sizeof (namebuf),
+ kCFStringEncodingASCII))
+ {
+ gl_locale_name_canonicalize (namebuf);
+ cached_localename = strdup (namebuf);
+ }
+ CFRelease (locale);
+# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
+ CFTypeRef value =
+ CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
+ kCFPreferencesCurrentApplication);
+ if (value != NULL
+ && CFGetTypeID (value) == CFStringGetTypeID ()
+ && CFStringGetCString ((CFStringRef)value,
+ namebuf, sizeof (namebuf),
+ kCFStringEncodingASCII))
+ {
+ gl_locale_name_canonicalize (namebuf);
+ cached_localename = strdup (namebuf);
+ }
+# endif
+ if (cached_localename == NULL)
+ cached_localename = "C";
+ }
+ return cached_localename;
+ }
+
+# endif
+
+# if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
+ {
+ LCID lcid;
+
+ /* Use native Win32 API locale ID. */
+ lcid = GetThreadLocale ();
+
+ return gl_locale_name_from_win32_LCID (lcid);
+ }
+# endif
+#endif
+}
+
+/* Determine the current locale's name, and canonicalize it into XPG syntax
+ language[_territory][.codeset][@modifier]
+ The codeset part in the result is not reliable; the locale_charset()
+ should be used for codeset information instead.
+ The result must not be freed; it is statically allocated. */
+
+const char *
+gl_locale_name (int category, const char *categoryname)
+{
+ const char *retval;
+
+ retval = gl_locale_name_thread (category, categoryname);
+ if (retval != NULL)
+ return retval;
+
+ retval = gl_locale_name_posix (category, categoryname);
+ if (retval != NULL)
+ return retval;
+
+ return gl_locale_name_default ();
+}
diff --git a/tests/localename.h b/tests/localename.h
new file mode 100644
index 0000000..e754853
--- /dev/null
+++ b/tests/localename.h
@@ -0,0 +1,97 @@
+/* Determine name of the currently selected locale.
+ Copyright (C) 2007, 2009-2011 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. */
+
+#ifndef _GL_LOCALENAME_H
+#define _GL_LOCALENAME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Determine the current locale's name.
+ It considers both the POSIX notion of locale name (see functions
+ gl_locale_name_thread and gl_locale_name_posix) and the system notion
+ of locale name (see function gl_locale_name_default).
+ CATEGORY is a locale category abbreviation, as defined in <locale.h>,
+ but not LC_ALL. E.g. LC_MESSAGES.
+ CATEGORYNAME is the name of CATEGORY as a string, e.g. "LC_MESSAGES".
+ Return the locale category's name, canonicalized into XPG syntax
+ language[_territory][.codeset][@modifier]
+ The codeset part in the result is not reliable; the locale_charset()
+ should be used for codeset information instead.
+ The result must not be freed; it is statically allocated. */
+extern const char * gl_locale_name (int category, const char *categoryname);
+
+/* Determine the current per-thread locale's name, as specified by uselocale()
+ calls.
+ CATEGORY is a locale category abbreviation, as defined in <locale.h>,
+ but not LC_ALL. E.g. LC_MESSAGES.
+ CATEGORYNAME is the name of CATEGORY as a string, e.g. "LC_MESSAGES".
+ Return the locale category's name, canonicalized into XPG syntax
+ language[_territory][.codeset][@modifier]
+ or NULL if no locale has been specified for the current thread.
+ The codeset part in the result is not reliable; the locale_charset()
+ should be used for codeset information instead.
+ The result must not be freed; it is statically allocated. */
+extern const char * gl_locale_name_thread (int category, const char *categoryname);
+
+/* Determine the thread-independent current locale's name, as specified by
+ setlocale() calls or by environment variables.
+ CATEGORY is a locale category abbreviation, as defined in <locale.h>,
+ but not LC_ALL. E.g. LC_MESSAGES.
+ CATEGORYNAME is the name of CATEGORY as a string, e.g. "LC_MESSAGES".
+ Return the locale category's name, canonicalized into XPG syntax
+ language[_territory][.codeset][@modifier]
+ or NULL if no locale has been specified to setlocale() or by environment
+ variables.
+ The codeset part in the result is not reliable; the locale_charset()
+ should be used for codeset information instead.
+ The result must not be freed; it is statically allocated. */
+extern const char * gl_locale_name_posix (int category, const char *categoryname);
+
+/* Determine the default locale's name, as specified by environment
+ variables.
+ Return the locale category's name, or NULL if no locale has been specified
+ by environment variables.
+ The result must not be freed; it is statically allocated. */
+extern const char * gl_locale_name_environ (int category, const char *categoryname);
+
+/* Determine the default locale's name. This is the current locale's name,
+ if not specified by uselocale() calls, by setlocale() calls, or by
+ environment variables. This locale name is usually determined by systems
+ settings that the user can manipulate through a GUI.
+
+ Quoting POSIX:2001:
+ "All implementations shall define a locale as the default locale,
+ to be invoked when no environment variables are set, or set to the
+ empty string. This default locale can be the C locale or any other
+ implementation-defined locale. Some implementations may provide
+ facilities for local installation administrators to set the default
+ locale, customizing it for each location. IEEE Std 1003.1-2001 does
+ not require such a facility."
+
+ The result must not be freed; it is statically allocated. */
+extern const char * gl_locale_name_default (void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GL_LOCALENAME_H */
diff --git a/tests/macros.h b/tests/macros.h
new file mode 100644
index 0000000..8922675
--- /dev/null
+++ b/tests/macros.h
@@ -0,0 +1,64 @@
+/* Common macros used by gnulib tests.
+ Copyright (C) 2006-2011 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/minus-zero.h b/tests/minus-zero.h
new file mode 100644
index 0000000..9429781
--- /dev/null
+++ b/tests/minus-zero.h
@@ -0,0 +1,74 @@
+/* Macros for floating-point negative zero.
+ Copyright (C) 2010-2011 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/>. */
+
+/* Keep in sync with m4/minus-zero.m4! */
+
+#include <float.h>
+
+
+/* minus_zerof represents the value -0.0f. */
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0f.
+ ICC 10.0 has a bug when optimizing the expression -zero.
+ The expression -FLT_MIN * FLT_MIN does not work when cross-compiling
+ to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi || defined __ICC
+static float
+compute_minus_zerof (void)
+{
+ return -FLT_MIN * FLT_MIN;
+}
+# define minus_zerof compute_minus_zerof ()
+#else
+float minus_zerof = -0.0f;
+#endif
+
+
+/* minus_zerod represents the value -0.0. */
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+ ICC 10.0 has a bug when optimizing the expression -zero.
+ The expression -DBL_MIN * DBL_MIN does not work when cross-compiling
+ to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi || defined __ICC
+static double
+compute_minus_zerod (void)
+{
+ return -DBL_MIN * DBL_MIN;
+}
+# define minus_zerod compute_minus_zerod ()
+#else
+double minus_zerod = -0.0;
+#endif
+
+
+/* minus_zerol represents the value -0.0L. */
+
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0L.
+ IRIX cc can't put -0.0L into .data, but can compute at runtime.
+ ICC 10.0 has a bug when optimizing the expression -zero.
+ The expression -LDBL_MIN * LDBL_MIN does not work when cross-compiling
+ to PowerPC on MacOS X 10.5. */
+#if defined __hpux || defined __sgi || defined __ICC
+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
diff --git a/tests/nan.h b/tests/nan.h
new file mode 100644
index 0000000..5e1c0c3
--- /dev/null
+++ b/tests/nan.h
@@ -0,0 +1,60 @@
+/* Macros for not-a-number.
+ Copyright (C) 2007-2011 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/putenv.c b/tests/putenv.c
new file mode 100644
index 0000000..68e5fec
--- /dev/null
+++ b/tests/putenv.c
@@ -0,0 +1,132 @@
+/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2011 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/setenv.c b/tests/setenv.c
new file mode 100644
index 0000000..7c06192
--- /dev/null
+++ b/tests/setenv.c
@@ -0,0 +1,390 @@
+/* Copyright (C) 1992, 1995-2003, 2005-2011 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 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 !_LIBC
+# include <config.h>
+#endif
+
+/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
+ optimizes away the name == NULL test below. */
+#define _GL_ARG_NONNULL(params)
+
+#include <alloca.h>
+
+/* Specification. */
+#include <stdlib.h>
+
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(ev) ((errno) = (ev))
+#endif
+
+#include <string.h>
+#if _LIBC || HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if !_LIBC
+# include "malloca.h"
+#endif
+
+#if _LIBC || !HAVE_SETENV
+
+#if !_LIBC
+# define __environ 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
+
+/* In the GNU C library we must keep the namespace clean. */
+#ifdef _LIBC
+# define setenv __setenv
+# define clearenv __clearenv
+# define tfind __tfind
+# define tsearch __tsearch
+#else
+/* Use the system functions, not the gnulib overrides in this file. */
+# undef malloc
+# undef realloc
+#endif
+
+/* In the GNU C library implementation we try to be more clever and
+ allow arbitrarily many changes of the environment given that the used
+ values are from a small set. Outside glibc this will eat up all
+ memory after a while. */
+#if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \
+ && defined __GNUC__)
+# define USE_TSEARCH 1
+# include <search.h>
+typedef int (*compar_fn_t) (const void *, const void *);
+
+/* This is a pointer to the root of the search tree with the known
+ values. */
+static void *known_values;
+
+# define KNOWN_VALUE(Str) \
+ ({ \
+ void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \
+ value != NULL ? *(char **) value : NULL; \
+ })
+# define STORE_VALUE(Str) \
+ tsearch (Str, &known_values, (compar_fn_t) strcmp)
+
+#else
+# undef USE_TSEARCH
+
+# define KNOWN_VALUE(Str) NULL
+# define STORE_VALUE(Str) do { } while (0)
+
+#endif
+
+
+/* If this variable is not a null pointer we allocated the current
+ environment. */
+static char **last_environ;
+
+
+/* This function is used by `setenv' and `putenv'. The difference between
+ the two functions is that for the former must create a new string which
+ is then placed in the environment, while the argument of `putenv'
+ must be used directly. This is all complicated by the fact that we try
+ to reuse values once generated for a `setenv' call since we can never
+ free the strings. */
+int
+__add_to_environ (const char *name, const char *value, const char *combined,
+ int replace)
+{
+ char **ep;
+ size_t size;
+ const size_t namelen = strlen (name);
+ const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
+
+ LOCK;
+
+ /* We have to get the pointer now that we have the lock and not earlier
+ since another thread might have created a new environment. */
+ ep = __environ;
+
+ size = 0;
+ if (ep != NULL)
+ {
+ for (; *ep != NULL; ++ep)
+ if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
+ break;
+ else
+ ++size;
+ }
+
+ if (ep == NULL || *ep == NULL)
+ {
+ char **new_environ;
+#ifdef USE_TSEARCH
+ char *new_value;
+#endif
+
+ /* We allocated this space; we can extend it. */
+ new_environ =
+ (char **) (last_environ == NULL
+ ? malloc ((size + 2) * sizeof (char *))
+ : realloc (last_environ, (size + 2) * sizeof (char *)));
+ if (new_environ == NULL)
+ {
+ /* It's easier to set errno to ENOMEM than to rely on the
+ 'malloc-posix' and 'realloc-posix' gnulib modules. */
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+
+ /* If the whole entry is given add it. */
+ if (combined != NULL)
+ /* We must not add the string to the search tree since it belongs
+ to the user. */
+ new_environ[size] = (char *) combined;
+ else
+ {
+ /* See whether the value is already known. */
+#ifdef USE_TSEARCH
+# ifdef _LIBC
+ new_value = (char *) alloca (namelen + 1 + vallen);
+ __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
+ value, vallen);
+# else
+ new_value = (char *) malloca (namelen + 1 + vallen);
+ if (new_value == NULL)
+ {
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+ memcpy (new_value, name, namelen);
+ new_value[namelen] = '=';
+ memcpy (&new_value[namelen + 1], value, vallen);
+# endif
+
+ new_environ[size] = KNOWN_VALUE (new_value);
+ if (new_environ[size] == NULL)
+#endif
+ {
+ new_environ[size] = (char *) malloc (namelen + 1 + vallen);
+ if (new_environ[size] == NULL)
+ {
+#if defined USE_TSEARCH && !defined _LIBC
+ freea (new_value);
+#endif
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+
+#ifdef USE_TSEARCH
+ memcpy (new_environ[size], new_value, namelen + 1 + vallen);
+#else
+ memcpy (new_environ[size], name, namelen);
+ new_environ[size][namelen] = '=';
+ memcpy (&new_environ[size][namelen + 1], value, vallen);
+#endif
+ /* And save the value now. We cannot do this when we remove
+ the string since then we cannot decide whether it is a
+ user string or not. */
+ STORE_VALUE (new_environ[size]);
+ }
+#if defined USE_TSEARCH && !defined _LIBC
+ freea (new_value);
+#endif
+ }
+
+ if (__environ != last_environ)
+ memcpy ((char *) new_environ, (char *) __environ,
+ size * sizeof (char *));
+
+ new_environ[size + 1] = NULL;
+
+ last_environ = __environ = new_environ;
+ }
+ else if (replace)
+ {
+ char *np;
+
+ /* Use the user string if given. */
+ if (combined != NULL)
+ np = (char *) combined;
+ else
+ {
+#ifdef USE_TSEARCH
+ char *new_value;
+# ifdef _LIBC
+ new_value = alloca (namelen + 1 + vallen);
+ __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
+ value, vallen);
+# else
+ new_value = malloca (namelen + 1 + vallen);
+ if (new_value == NULL)
+ {
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+ memcpy (new_value, name, namelen);
+ new_value[namelen] = '=';
+ memcpy (&new_value[namelen + 1], value, vallen);
+# endif
+
+ np = KNOWN_VALUE (new_value);
+ if (np == NULL)
+#endif
+ {
+ np = (char *) malloc (namelen + 1 + vallen);
+ if (np == NULL)
+ {
+#if defined USE_TSEARCH && !defined _LIBC
+ freea (new_value);
+#endif
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+
+#ifdef USE_TSEARCH
+ memcpy (np, new_value, namelen + 1 + vallen);
+#else
+ memcpy (np, name, namelen);
+ np[namelen] = '=';
+ memcpy (&np[namelen + 1], value, vallen);
+#endif
+ /* And remember the value. */
+ STORE_VALUE (np);
+ }
+#if defined USE_TSEARCH && !defined _LIBC
+ freea (new_value);
+#endif
+ }
+
+ *ep = np;
+ }
+
+ UNLOCK;
+
+ return 0;
+}
+
+int
+setenv (const char *name, const char *value, int replace)
+{
+ if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __add_to_environ (name, value, NULL, replace);
+}
+
+/* The `clearenv' was planned to be added to POSIX.1 but probably
+ never made it. Nevertheless the POSIX.9 standard (POSIX bindings
+ for Fortran 77) requires this function. */
+int
+clearenv (void)
+{
+ LOCK;
+
+ if (__environ == last_environ && __environ != NULL)
+ {
+ /* We allocated this environment so we can free it. */
+ free (__environ);
+ last_environ = NULL;
+ }
+
+ /* Clear the environment pointer removes the whole environment. */
+ __environ = NULL;
+
+ UNLOCK;
+
+ return 0;
+}
+
+#ifdef _LIBC
+static void
+free_mem (void)
+{
+ /* Remove all traces. */
+ clearenv ();
+
+ /* Now remove the search tree. */
+ __tdestroy (known_values, free);
+ known_values = NULL;
+}
+text_set_element (__libc_subfreeres, free_mem);
+
+
+# undef setenv
+# undef clearenv
+weak_alias (__setenv, setenv)
+weak_alias (__clearenv, clearenv)
+#endif
+
+#endif /* _LIBC || !HAVE_SETENV */
+
+/* The rest of this file is called into use when replacing an existing
+ but buggy setenv. Known bugs include failure to diagnose invalid
+ name, and consuming a leading '=' from value. */
+#if HAVE_SETENV
+
+# undef setenv
+# define STREQ(a, b) (strcmp (a, b) == 0)
+
+int
+rpl_setenv (const char *name, const char *value, int replace)
+{
+ int result;
+ if (!name || !*name || strchr (name, '='))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ /* Call the real setenv even if replace is 0, in case implementation
+ has underlying data to update, such as when environ changes. */
+ result = setenv (name, value, replace);
+ if (result == 0 && replace && *value == '=')
+ {
+ char *tmp = getenv (name);
+ if (!STREQ (tmp, value))
+ {
+ int saved_errno;
+ size_t len = strlen (value);
+ tmp = malloca (len + 2);
+ /* Since leading '=' is eaten, double it up. */
+ *tmp = '=';
+ memcpy (tmp + 1, value, len + 1);
+ result = setenv (name, tmp, replace);
+ saved_errno = errno;
+ freea (tmp);
+ errno = saved_errno;
+ }
+ }
+ return result;
+}
+
+#endif /* HAVE_SETENV */
diff --git a/tests/setlocale.c b/tests/setlocale.c
new file mode 100644
index 0000000..0cef00f
--- /dev/null
+++ b/tests/setlocale.c
@@ -0,0 +1,938 @@
+/* Set the current locale.
+ Copyright (C) 2009, 2011 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>
+
+/* Override setlocale() so that when the default locale is requested
+ (locale = ""), the environment variables LC_ALL, LC_*, and LANG are
+ considered.
+ Also include all the functionality from libintl's setlocale() override. */
+
+/* Please keep this file in sync with
+ gettext/gettext-runtime/intl/setlocale.c ! */
+
+/* Specification. */
+#include <locale.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "localename.h"
+
+#if 1
+
+# undef setlocale
+
+/* Return string representation of locale category CATEGORY. */
+static const char *
+category_to_name (int category)
+{
+ const char *retval;
+
+ switch (category)
+ {
+ case LC_COLLATE:
+ retval = "LC_COLLATE";
+ break;
+ case LC_CTYPE:
+ retval = "LC_CTYPE";
+ break;
+ case LC_MONETARY:
+ retval = "LC_MONETARY";
+ break;
+ case LC_NUMERIC:
+ retval = "LC_NUMERIC";
+ break;
+ case LC_TIME:
+ retval = "LC_TIME";
+ break;
+ case LC_MESSAGES:
+ retval = "LC_MESSAGES";
+ break;
+ default:
+ /* If you have a better idea for a default value let me know. */
+ retval = "LC_XXX";
+ }
+
+ return retval;
+}
+
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+/* The native Win32 setlocale() function expects locale names of the form
+ "German" or "German_Germany" or "DEU", but not "de" or "de_DE". We need
+ to convert the names from the form with ISO 639 language code and ISO 3166
+ country code to the form with English names or with three-letter identifier.
+ The three-letter identifiers known by a Windows XP SP2 or SP3 are:
+ AFK Afrikaans_South Africa.1252
+ ARA Arabic_Saudi Arabia.1256
+ ARB Arabic_Lebanon.1256
+ ARE Arabic_Egypt.1256
+ ARG Arabic_Algeria.1256
+ ARH Arabic_Bahrain.1256
+ ARI Arabic_Iraq.1256
+ ARJ Arabic_Jordan.1256
+ ARK Arabic_Kuwait.1256
+ ARL Arabic_Libya.1256
+ ARM Arabic_Morocco.1256
+ ARO Arabic_Oman.1256
+ ARQ Arabic_Qatar.1256
+ ARS Arabic_Syria.1256
+ ART Arabic_Tunisia.1256
+ ARU Arabic_U.A.E..1256
+ ARY Arabic_Yemen.1256
+ AZE Azeri (Latin)_Azerbaijan.1254
+ BEL Belarusian_Belarus.1251
+ BGR Bulgarian_Bulgaria.1251
+ BSB Bosnian_Bosnia and Herzegovina.1250
+ BSC Bosnian (Cyrillic)_Bosnia and Herzegovina.1250 (wrong encoding!)
+ CAT Catalan_Spain.1252
+ CHH Chinese_Hong Kong S.A.R..950
+ CHI Chinese_Singapore.936
+ CHS Chinese_People's Republic of China.936
+ CHT Chinese_Taiwan.950
+ CSY Czech_Czech Republic.1250
+ CYM Welsh_United Kingdom.1252
+ DAN Danish_Denmark.1252
+ DEA German_Austria.1252
+ DEC German_Liechtenstein.1252
+ DEL German_Luxembourg.1252
+ DES German_Switzerland.1252
+ DEU German_Germany.1252
+ ELL Greek_Greece.1253
+ ENA English_Australia.1252
+ ENB English_Caribbean.1252
+ ENC English_Canada.1252
+ ENG English_United Kingdom.1252
+ ENI English_Ireland.1252
+ ENJ English_Jamaica.1252
+ ENL English_Belize.1252
+ ENP English_Republic of the Philippines.1252
+ ENS English_South Africa.1252
+ ENT English_Trinidad and Tobago.1252
+ ENU English_United States.1252
+ ENW English_Zimbabwe.1252
+ ENZ English_New Zealand.1252
+ ESA Spanish_Panama.1252
+ ESB Spanish_Bolivia.1252
+ ESC Spanish_Costa Rica.1252
+ ESD Spanish_Dominican Republic.1252
+ ESE Spanish_El Salvador.1252
+ ESF Spanish_Ecuador.1252
+ ESG Spanish_Guatemala.1252
+ ESH Spanish_Honduras.1252
+ ESI Spanish_Nicaragua.1252
+ ESL Spanish_Chile.1252
+ ESM Spanish_Mexico.1252
+ ESN Spanish_Spain.1252
+ ESO Spanish_Colombia.1252
+ ESP Spanish_Spain.1252
+ ESR Spanish_Peru.1252
+ ESS Spanish_Argentina.1252
+ ESU Spanish_Puerto Rico.1252
+ ESV Spanish_Venezuela.1252
+ ESY Spanish_Uruguay.1252
+ ESZ Spanish_Paraguay.1252
+ ETI Estonian_Estonia.1257
+ EUQ Basque_Spain.1252
+ FAR Farsi_Iran.1256
+ FIN Finnish_Finland.1252
+ FOS Faroese_Faroe Islands.1252
+ FPO Filipino_Philippines.1252
+ FRA French_France.1252
+ FRB French_Belgium.1252
+ FRC French_Canada.1252
+ FRL French_Luxembourg.1252
+ FRM French_Principality of Monaco.1252
+ FRS French_Switzerland.1252
+ FYN Frisian_Netherlands.1252
+ GLC Galician_Spain.1252
+ HEB Hebrew_Israel.1255
+ HRB Croatian_Bosnia and Herzegovina.1250
+ HRV Croatian_Croatia.1250
+ HUN Hungarian_Hungary.1250
+ IND Indonesian_Indonesia.1252
+ IRE Irish_Ireland.1252
+ ISL Icelandic_Iceland.1252
+ ITA Italian_Italy.1252
+ ITS Italian_Switzerland.1252
+ IUK Inuktitut (Latin)_Canada.1252
+ JPN Japanese_Japan.932
+ KKZ Kazakh_Kazakhstan.1251
+ KOR Korean_Korea.949
+ KYR Kyrgyz_Kyrgyzstan.1251
+ LBX Luxembourgish_Luxembourg.1252
+ LTH Lithuanian_Lithuania.1257
+ LVI Latvian_Latvia.1257
+ MKI FYRO Macedonian_Former Yugoslav Republic of Macedonia.1251
+ MON Mongolian_Mongolia.1251
+ MPD Mapudungun_Chile.1252
+ MSB Malay_Brunei Darussalam.1252
+ MSL Malay_Malaysia.1252
+ MWK Mohawk_Canada.1252
+ NLB Dutch_Belgium.1252
+ NLD Dutch_Netherlands.1252
+ NON Norwegian-Nynorsk_Norway.1252
+ NOR Norwegian (Bokmål)_Norway.1252
+ NSO Northern Sotho_South Africa.1252
+ PLK Polish_Poland.1250
+ PTB Portuguese_Brazil.1252
+ PTG Portuguese_Portugal.1252
+ QUB Quechua_Bolivia.1252
+ QUE Quechua_Ecuador.1252
+ QUP Quechua_Peru.1252
+ RMC Romansh_Switzerland.1252
+ ROM Romanian_Romania.1250
+ RUS Russian_Russia.1251
+ SKY Slovak_Slovakia.1250
+ SLV Slovenian_Slovenia.1250
+ SMA Sami (Southern)_Norway.1252
+ SMB Sami (Southern)_Sweden.1252
+ SME Sami (Northern)_Norway.1252
+ SMF Sami (Northern)_Sweden.1252
+ SMG Sami (Northern)_Finland.1252
+ SMJ Sami (Lule)_Norway.1252
+ SMK Sami (Lule)_Sweden.1252
+ SMN Sami (Inari)_Finland.1252
+ SMS Sami (Skolt)_Finland.1252
+ SQI Albanian_Albania.1250
+ SRB Serbian (Cyrillic)_Serbia and Montenegro.1251
+ SRL Serbian (Latin)_Serbia and Montenegro.1250
+ SRN Serbian (Cyrillic)_Bosnia and Herzegovina.1251
+ SRS Serbian (Latin)_Bosnia and Herzegovina.1250
+ SVE Swedish_Sweden.1252
+ SVF Swedish_Finland.1252
+ SWK Swahili_Kenya.1252
+ THA Thai_Thailand.874
+ TRK Turkish_Turkey.1254
+ TSN Tswana_South Africa.1252
+ TTT Tatar_Russia.1251
+ UKR Ukrainian_Ukraine.1251
+ URD Urdu_Islamic Republic of Pakistan.1256
+ USA English_United States.1252
+ UZB Uzbek (Latin)_Uzbekistan.1254
+ VIT Vietnamese_Viet Nam.1258
+ XHO Xhosa_South Africa.1252
+ ZHH Chinese_Hong Kong S.A.R..950
+ ZHI Chinese_Singapore.936
+ ZHM Chinese_Macau S.A.R..950
+ ZUL Zulu_South Africa.1252
+ */
+
+/* Table from ISO 639 language code, optionally with country or script suffix,
+ to English name.
+ Keep in sync with the gl_locale_name_from_win32_LANGID function in
+ localename.c! */
+struct table_entry
+{
+ const char *code;
+ const char *english;
+};
+static const struct table_entry language_table[] =
+ {
+ { "af", "Afrikaans" },
+ { "am", "Amharic" },
+ { "ar", "Arabic" },
+ { "arn", "Mapudungun" },
+ { "as", "Assamese" },
+ { "az@cyrillic", "Azeri (Cyrillic)" },
+ { "az@latin", "Azeri (Latin)" },
+ { "ba", "Bashkir" },
+ { "be", "Belarusian" },
+ { "ber", "Tamazight" },
+ { "ber@arabic", "Tamazight (Arabic)" },
+ { "ber@latin", "Tamazight (Latin)" },
+ { "bg", "Bulgarian" },
+ { "bin", "Edo" },
+ { "bn", "Bengali" },
+ { "bn_BD", "Bengali (Bangladesh)" },
+ { "bn_IN", "Bengali (India)" },
+ { "bnt", "Sutu" },
+ { "bo", "Tibetan" },
+ { "br", "Breton" },
+ { "bs", "BSB" }, /* "Bosnian (Latin)" */
+ { "bs@cyrillic", "BSC" }, /* Bosnian (Cyrillic) */
+ { "ca", "Catalan" },
+ { "chr", "Cherokee" },
+ { "co", "Corsican" },
+ { "cpe", "Hawaiian" },
+ { "cs", "Czech" },
+ { "cy", "Welsh" },
+ { "da", "Danish" },
+ { "de", "German" },
+ { "dsb", "Lower Sorbian" },
+ { "dv", "Divehi" },
+ { "el", "Greek" },
+ { "en", "English" },
+ { "es", "Spanish" },
+ { "et", "Estonian" },
+ { "eu", "Basque" },
+ { "fa", "Farsi" },
+ { "ff", "Fulfulde" },
+ { "fi", "Finnish" },
+ { "fo", "Faroese" }, /* "Faeroese" does not work */
+ { "fr", "French" },
+ { "fy", "Frisian" },
+ { "ga", "IRE" }, /* Gaelic (Ireland) */
+ { "gd", "Gaelic (Scotland)" },
+ { "gd", "Scottish Gaelic" },
+ { "gl", "Galician" },
+ { "gn", "Guarani" },
+ { "gsw", "Alsatian" },
+ { "gu", "Gujarati" },
+ { "ha", "Hausa" },
+ { "he", "Hebrew" },
+ { "hi", "Hindi" },
+ { "hr", "Croatian" },
+ { "hsb", "Upper Sorbian" },
+ { "hu", "Hungarian" },
+ { "hy", "Armenian" },
+ { "id", "Indonesian" },
+ { "ig", "Igbo" },
+ { "ii", "Yi" },
+ { "is", "Icelandic" },
+ { "it", "Italian" },
+ { "iu", "IUK" }, /* Inuktitut */
+ { "ja", "Japanese" },
+ { "ka", "Georgian" },
+ { "kk", "Kazakh" },
+ { "kl", "Greenlandic" },
+ { "km", "Cambodian" },
+ { "km", "Khmer" },
+ { "kn", "Kannada" },
+ { "ko", "Korean" },
+ { "kok", "Konkani" },
+ { "kr", "Kanuri" },
+ { "ks", "Kashmiri" },
+ { "ks_IN", "Kashmiri_India" },
+ { "ks_PK", "Kashmiri (Arabic)_Pakistan" },
+ { "ky", "Kyrgyz" },
+ { "la", "Latin" },
+ { "lb", "Luxembourgish" },
+ { "lo", "Lao" },
+ { "lt", "Lithuanian" },
+ { "lv", "Latvian" },
+ { "mi", "Maori" },
+ { "mk", "FYRO Macedonian" },
+ { "mk", "Macedonian" },
+ { "ml", "Malayalam" },
+ { "mn", "Mongolian" },
+ { "mni", "Manipuri" },
+ { "moh", "Mohawk" },
+ { "mr", "Marathi" },
+ { "ms", "Malay" },
+ { "mt", "Maltese" },
+ { "my", "Burmese" },
+ { "nb", "NOR" }, /* Norwegian Bokmål */
+ { "ne", "Nepali" },
+ { "nic", "Ibibio" },
+ { "nl", "Dutch" },
+ { "nn", "NON" }, /* Norwegian Nynorsk */
+ { "no", "Norwegian" },
+ { "nso", "Northern Sotho" },
+ { "nso", "Sepedi" },
+ { "oc", "Occitan" },
+ { "om", "Oromo" },
+ { "or", "Oriya" },
+ { "pa", "Punjabi" },
+ { "pap", "Papiamentu" },
+ { "pl", "Polish" },
+ { "prs", "Dari" },
+ { "ps", "Pashto" },
+ { "pt", "Portuguese" },
+ { "qu", "Quechua" },
+ { "qut", "K'iche'" },
+ { "rm", "Romansh" },
+ { "ro", "Romanian" },
+ { "ru", "Russian" },
+ { "rw", "Kinyarwanda" },
+ { "sa", "Sanskrit" },
+ { "sah", "Yakut" },
+ { "sd", "Sindhi" },
+ { "se", "Sami (Northern)" },
+ { "se", "Northern Sami" },
+ { "si", "Sinhalese" },
+ { "sk", "Slovak" },
+ { "sl", "Slovenian" },
+ { "sma", "Sami (Southern)" },
+ { "sma", "Southern Sami" },
+ { "smj", "Sami (Lule)" },
+ { "smj", "Lule Sami" },
+ { "smn", "Sami (Inari)" },
+ { "smn", "Inari Sami" },
+ { "sms", "Sami (Skolt)" },
+ { "sms", "Skolt Sami" },
+ { "so", "Somali" },
+ { "sq", "Albanian" },
+ { "sr", "Serbian (Latin)" },
+ { "sr@cyrillic", "SRB" }, /* Serbian (Cyrillic) */
+ { "sw", "Swahili" },
+ { "syr", "Syriac" },
+ { "ta", "Tamil" },
+ { "te", "Telugu" },
+ { "tg", "Tajik" },
+ { "th", "Thai" },
+ { "ti", "Tigrinya" },
+ { "tk", "Turkmen" },
+ { "tl", "Filipino" },
+ { "tn", "Tswana" },
+ { "tr", "Turkish" },
+ { "ts", "Tsonga" },
+ { "tt", "Tatar" },
+ { "ug", "Uighur" },
+ { "uk", "Ukrainian" },
+ { "ur", "Urdu" },
+ { "uz", "Uzbek" },
+ { "uz", "Uzbek (Latin)" },
+ { "uz@cyrillic", "Uzbek (Cyrillic)" },
+ { "ve", "Venda" },
+ { "vi", "Vietnamese" },
+ { "wen", "Sorbian" },
+ { "wo", "Wolof" },
+ { "xh", "Xhosa" },
+ { "yi", "Yiddish" },
+ { "yo", "Yoruba" },
+ { "zh", "Chinese" },
+ { "zu", "Zulu" }
+ };
+
+/* Table from ISO 3166 country code to English name.
+ Keep in sync with the gl_locale_name_from_win32_LANGID function in
+ localename.c! */
+static const struct table_entry country_table[] =
+ {
+ { "AE", "U.A.E." },
+ { "AF", "Afghanistan" },
+ { "AL", "Albania" },
+ { "AM", "Armenia" },
+ { "AN", "Netherlands Antilles" },
+ { "AR", "Argentina" },
+ { "AT", "Austria" },
+ { "AU", "Australia" },
+ { "AZ", "Azerbaijan" },
+ { "BA", "Bosnia and Herzegovina" },
+ { "BD", "Bangladesh" },
+ { "BE", "Belgium" },
+ { "BG", "Bulgaria" },
+ { "BH", "Bahrain" },
+ { "BN", "Brunei Darussalam" },
+ { "BO", "Bolivia" },
+ { "BR", "Brazil" },
+ { "BT", "Bhutan" },
+ { "BY", "Belarus" },
+ { "BZ", "Belize" },
+ { "CA", "Canada" },
+ { "CG", "Congo" },
+ { "CH", "Switzerland" },
+ { "CI", "Cote d'Ivoire" },
+ { "CL", "Chile" },
+ { "CM", "Cameroon" },
+ { "CN", "People's Republic of China" },
+ { "CO", "Colombia" },
+ { "CR", "Costa Rica" },
+ { "CS", "Serbia and Montenegro" },
+ { "CZ", "Czech Republic" },
+ { "DE", "Germany" },
+ { "DK", "Denmark" },
+ { "DO", "Dominican Republic" },
+ { "DZ", "Algeria" },
+ { "EC", "Ecuador" },
+ { "EE", "Estonia" },
+ { "EG", "Egypt" },
+ { "ER", "Eritrea" },
+ { "ES", "Spain" },
+ { "ET", "Ethiopia" },
+ { "FI", "Finland" },
+ { "FO", "Faroe Islands" },
+ { "FR", "France" },
+ { "GB", "United Kingdom" },
+ { "GD", "Caribbean" },
+ { "GE", "Georgia" },
+ { "GL", "Greenland" },
+ { "GR", "Greece" },
+ { "GT", "Guatemala" },
+ { "HK", "Hong Kong" },
+ { "HK", "Hong Kong S.A.R." },
+ { "HN", "Honduras" },
+ { "HR", "Croatia" },
+ { "HT", "Haiti" },
+ { "HU", "Hungary" },
+ { "ID", "Indonesia" },
+ { "IE", "Ireland" },
+ { "IL", "Israel" },
+ { "IN", "India" },
+ { "IQ", "Iraq" },
+ { "IR", "Iran" },
+ { "IS", "Iceland" },
+ { "IT", "Italy" },
+ { "JM", "Jamaica" },
+ { "JO", "Jordan" },
+ { "JP", "Japan" },
+ { "KE", "Kenya" },
+ { "KG", "Kyrgyzstan" },
+ { "KH", "Cambodia" },
+ { "KR", "South Korea" },
+ { "KW", "Kuwait" },
+ { "KZ", "Kazakhstan" },
+ { "LA", "Laos" },
+ { "LB", "Lebanon" },
+ { "LI", "Liechtenstein" },
+ { "LK", "Sri Lanka" },
+ { "LT", "Lithuania" },
+ { "LU", "Luxembourg" },
+ { "LV", "Latvia" },
+ { "LY", "Libya" },
+ { "MA", "Morocco" },
+ { "MC", "Principality of Monaco" },
+ { "MD", "Moldava" },
+ { "MD", "Moldova" },
+ { "ME", "Montenegro" },
+ { "MK", "Former Yugoslav Republic of Macedonia" },
+ { "ML", "Mali" },
+ { "MM", "Myanmar" },
+ { "MN", "Mongolia" },
+ { "MO", "Macau S.A.R." },
+ { "MT", "Malta" },
+ { "MV", "Maldives" },
+ { "MX", "Mexico" },
+ { "MY", "Malaysia" },
+ { "NG", "Nigeria" },
+ { "NI", "Nicaragua" },
+ { "NL", "Netherlands" },
+ { "NO", "Norway" },
+ { "NP", "Nepal" },
+ { "NZ", "New Zealand" },
+ { "OM", "Oman" },
+ { "PA", "Panama" },
+ { "PE", "Peru" },
+ { "PH", "Philippines" },
+ { "PK", "Islamic Republic of Pakistan" },
+ { "PL", "Poland" },
+ { "PR", "Puerto Rico" },
+ { "PT", "Portugal" },
+ { "PY", "Paraguay" },
+ { "QA", "Qatar" },
+ { "RE", "Reunion" },
+ { "RO", "Romania" },
+ { "RS", "Serbia" },
+ { "RU", "Russia" },
+ { "RW", "Rwanda" },
+ { "SA", "Saudi Arabia" },
+ { "SE", "Sweden" },
+ { "SG", "Singapore" },
+ { "SI", "Slovenia" },
+ { "SK", "Slovak" },
+ { "SN", "Senegal" },
+ { "SO", "Somalia" },
+ { "SR", "Suriname" },
+ { "SV", "El Salvador" },
+ { "SY", "Syria" },
+ { "TH", "Thailand" },
+ { "TJ", "Tajikistan" },
+ { "TM", "Turkmenistan" },
+ { "TN", "Tunisia" },
+ { "TR", "Turkey" },
+ { "TT", "Trinidad and Tobago" },
+ { "TW", "Taiwan" },
+ { "TZ", "Tanzania" },
+ { "UA", "Ukraine" },
+ { "US", "United States" },
+ { "UY", "Uruguay" },
+ { "VA", "Vatican" },
+ { "VE", "Venezuela" },
+ { "VN", "Viet Nam" },
+ { "YE", "Yemen" },
+ { "ZA", "South Africa" },
+ { "ZW", "Zimbabwe" }
+ };
+
+/* Given a string STRING, find the set of indices i such that TABLE[i].code is
+ the given STRING. It is a range [lo,hi-1]. */
+typedef struct { size_t lo; size_t hi; } range_t;
+static void
+search (const struct table_entry *table, size_t table_size, const char *string,
+ range_t *result)
+{
+ /* The table is sorted. Perform a binary search. */
+ size_t hi = table_size;
+ size_t lo = 0;
+ while (lo < hi)
+ {
+ /* Invariant:
+ for i < lo, strcmp (table[i].code, string) < 0,
+ for i >= hi, strcmp (table[i].code, string) > 0. */
+ size_t mid = (hi + lo) >> 1; /* >= lo, < hi */
+ int cmp = strcmp (table[mid].code, string);
+ if (cmp < 0)
+ lo = mid + 1;
+ else if (cmp > 0)
+ hi = mid;
+ else
+ {
+ /* Found an i with
+ strcmp (language_table[i].code, string) == 0.
+ Find the entire interval of such i. */
+ {
+ size_t i;
+
+ for (i = mid; i > lo; )
+ {
+ i--;
+ if (strcmp (table[i].code, string) < 0)
+ {
+ lo = i + 1;
+ break;
+ }
+ }
+ }
+ {
+ size_t i;
+
+ for (i = mid; i < hi; i++)
+ {
+ if (strcmp (table[i].code, string) > 0)
+ {
+ hi = i;
+ break;
+ }
+ }
+ }
+ /* The set of i with
+ strcmp (language_table[i].code, string) == 0
+ is the interval [lo, hi-1]. */
+ break;
+ }
+ }
+ result->lo = lo;
+ result->hi = hi;
+}
+
+/* Like setlocale, but accept also locale names in the form ll or ll_CC,
+ where ll is an ISO 639 language code and CC is an ISO 3166 country code. */
+static char *
+setlocale_unixlike (int category, const char *locale)
+{
+ char *result;
+ char llCC_buf[64];
+ char ll_buf[64];
+ char CC_buf[64];
+
+ /* First, try setlocale with the original argument unchanged. */
+ result = setlocale (category, locale);
+ if (result != NULL)
+ return result;
+
+ /* Otherwise, assume the argument is in the form
+ language[_territory][.codeset][@modifier]
+ and try to map it using the tables. */
+ if (strlen (locale) < sizeof (llCC_buf))
+ {
+ /* Second try: Remove the codeset part. */
+ {
+ const char *p = locale;
+ char *q = llCC_buf;
+
+ /* Copy the part before the dot. */
+ for (; *p != '\0' && *p != '.'; p++, q++)
+ *q = *p;
+ if (*p == '.')
+ /* Skip the part up to the '@', if any. */
+ for (; *p != '\0' && *p != '@'; p++)
+ ;
+ /* Copy the part starting with '@', if any. */
+ for (; *p != '\0'; p++, q++)
+ *q = *p;
+ *q = '\0';
+ }
+ /* llCC_buf now contains
+ language[_territory][@modifier]
+ */
+ if (strcmp (llCC_buf, locale) != 0)
+ {
+ result = setlocale (category, llCC_buf);
+ if (result != NULL)
+ return result;
+ }
+ /* Look it up in language_table. */
+ {
+ range_t range;
+ size_t i;
+
+ search (language_table,
+ sizeof (language_table) / sizeof (language_table[0]),
+ llCC_buf,
+ &range);
+
+ for (i = range.lo; i < range.hi; i++)
+ {
+ /* Try the replacement in language_table[i]. */
+ result = setlocale (category, language_table[i].english);
+ if (result != NULL)
+ return result;
+ }
+ }
+ /* Split language[_territory][@modifier]
+ into ll_buf = language[@modifier]
+ and CC_buf = territory
+ */
+ {
+ const char *underscore = strchr (llCC_buf, '_');
+ if (underscore != NULL)
+ {
+ const char *territory_start = underscore + 1;
+ const char *territory_end = strchr (territory_start, '@');
+ if (territory_end == NULL)
+ territory_end = territory_start + strlen (territory_start);
+
+ memcpy (ll_buf, llCC_buf, underscore - llCC_buf);
+ strcpy (ll_buf + (underscore - llCC_buf), territory_end);
+
+ memcpy (CC_buf, territory_start, territory_end - territory_start);
+ CC_buf[territory_end - territory_start] = '\0';
+
+ {
+ /* Look up ll_buf in language_table
+ and CC_buf in country_table. */
+ range_t language_range;
+
+ search (language_table,
+ sizeof (language_table) / sizeof (language_table[0]),
+ ll_buf,
+ &language_range);
+ if (language_range.lo < language_range.hi)
+ {
+ range_t country_range;
+
+ search (country_table,
+ sizeof (country_table) / sizeof (country_table[0]),
+ CC_buf,
+ &country_range);
+ if (country_range.lo < country_range.hi)
+ {
+ size_t i;
+ size_t j;
+
+ for (i = language_range.lo; i < language_range.hi; i++)
+ for (j = country_range.lo; j < country_range.hi; j++)
+ {
+ /* Concatenate the replacements. */
+ const char *part1 = language_table[i].english;
+ size_t part1_len = strlen (part1);
+ const char *part2 = country_table[j].english;
+ size_t part2_len = strlen (part2) + 1;
+ char buf[64+64];
+
+ if (!(part1_len + 1 + part2_len <= sizeof (buf)))
+ abort ();
+ memcpy (buf, part1, part1_len);
+ buf[part1_len] = '_';
+ memcpy (buf + part1_len + 1, part2, part2_len);
+
+ /* Try the concatenated replacements. */
+ result = setlocale (category, buf);
+ if (result != NULL)
+ return result;
+ }
+ }
+
+ /* Try omitting the country entirely. This may set a locale
+ corresponding to the wrong country, but is better than
+ failing entirely. */
+ {
+ size_t i;
+
+ for (i = language_range.lo; i < language_range.hi; i++)
+ {
+ /* Try only the language replacement. */
+ result =
+ setlocale (category, language_table[i].english);
+ if (result != NULL)
+ return result;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Failed. */
+ return NULL;
+}
+
+# else
+# define setlocale_unixlike setlocale
+# endif
+
+# if LC_MESSAGES == 1729
+
+/* The system does not store an LC_MESSAGES locale category. Do it here. */
+static char lc_messages_name[64] = "C";
+
+/* Like setlocale, but support also LC_MESSAGES. */
+static char *
+setlocale_single (int category, const char *locale)
+{
+ if (category == LC_MESSAGES)
+ {
+ if (locale != NULL)
+ {
+ lc_messages_name[sizeof (lc_messages_name) - 1] = '\0';
+ strncpy (lc_messages_name, locale, sizeof (lc_messages_name) - 1);
+ }
+ return lc_messages_name;
+ }
+ else
+ return setlocale_unixlike (category, locale);
+}
+
+# else
+# define setlocale_single setlocale_unixlike
+# endif
+
+char *
+rpl_setlocale (int category, const char *locale)
+{
+ if (locale != NULL && locale[0] == '\0')
+ {
+ /* A request to the set the current locale to the default locale. */
+ if (category == LC_ALL)
+ {
+ /* Set LC_CTYPE first. Then the other categories. */
+ static int const categories[] =
+ {
+ LC_NUMERIC,
+ LC_TIME,
+ LC_COLLATE,
+ LC_MONETARY,
+ LC_MESSAGES
+ };
+ char *saved_locale;
+ const char *base_name;
+ unsigned int i;
+
+ /* Back up the old locale, in case one of the steps fails. */
+ saved_locale = setlocale (LC_ALL, NULL);
+ if (saved_locale == NULL)
+ return NULL;
+ saved_locale = strdup (saved_locale);
+ if (saved_locale == NULL)
+ return NULL;
+
+ /* Set LC_CTYPE category. Set all other categories (except possibly
+ LC_MESSAGES) to the same value in the same call; this is likely to
+ save calls. */
+ base_name =
+ gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
+ if (base_name == NULL)
+ base_name = gl_locale_name_default ();
+
+ if (setlocale_unixlike (LC_ALL, base_name) == NULL)
+ goto fail;
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On native Windows, setlocale(LC_ALL,...) may succeed but set the
+ LC_CTYPE category to an invalid value ("C") when it does not
+ support the specified encoding. Report a failure instead. */
+ if (strchr (base_name, '.') != NULL
+ && strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
+ goto fail;
+# endif
+
+ for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++)
+ {
+ int cat = categories[i];
+ const char *name;
+
+ name = gl_locale_name_environ (cat, category_to_name (cat));
+ if (name == NULL)
+ name = gl_locale_name_default ();
+
+ /* If name is the same as base_name, it has already been set
+ through the setlocale call before the loop. */
+ if (strcmp (name, base_name) != 0
+# if LC_MESSAGES == 1729
+ || cat == LC_MESSAGES
+# endif
+ )
+ if (setlocale_single (cat, name) == NULL)
+ goto fail;
+ }
+
+ /* All steps were successful. */
+ free (saved_locale);
+ return setlocale (LC_ALL, NULL);
+
+ fail:
+ if (saved_locale[0] != '\0') /* don't risk an endless recursion */
+ setlocale (LC_ALL, saved_locale);
+ free (saved_locale);
+ return NULL;
+ }
+ else
+ {
+ const char *name =
+ gl_locale_name_environ (category, category_to_name (category));
+ if (name == NULL)
+ name = gl_locale_name_default ();
+
+ return setlocale_single (category, name);
+ }
+ }
+ else
+ {
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ if (category == LC_ALL && locale != NULL && strchr (locale, '.') != NULL)
+ {
+ char *saved_locale;
+
+ /* Back up the old locale. */
+ saved_locale = setlocale (LC_ALL, NULL);
+ if (saved_locale == NULL)
+ return NULL;
+ saved_locale = strdup (saved_locale);
+ if (saved_locale == NULL)
+ return NULL;
+
+ if (setlocale_unixlike (LC_ALL, locale) == NULL)
+ {
+ free (saved_locale);
+ return NULL;
+ }
+
+ /* On native Windows, setlocale(LC_ALL,...) may succeed but set the
+ LC_CTYPE category to an invalid value ("C") when it does not
+ support the specified encoding. Report a failure instead. */
+ if (strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
+ {
+ if (saved_locale[0] != '\0') /* don't risk an endless recursion */
+ setlocale (LC_ALL, saved_locale);
+ free (saved_locale);
+ return NULL;
+ }
+
+ /* It was really successful. */
+ free (saved_locale);
+ return setlocale (LC_ALL, NULL);
+ }
+ else
+# endif
+ return setlocale_single (category, locale);
+ }
+}
+
+#endif
diff --git a/tests/signature.h b/tests/signature.h
new file mode 100644
index 0000000..8256989
--- /dev/null
+++ b/tests/signature.h
@@ -0,0 +1,48 @@
+/* Macro for checking that a function declaration is compliant.
+ Copyright (C) 2009-2011 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/strdup.c b/tests/strdup.c
new file mode 100644
index 0000000..ba7e76b
--- /dev/null
+++ b/tests/strdup.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1991, 1996-1998, 2002-2004, 2006-2007, 2009-2011 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/symlink.c b/tests/symlink.c
new file mode 100644
index 0000000..2896cc9
--- /dev/null
+++ b/tests/symlink.c
@@ -0,0 +1,57 @@
+/* Stub for symlink().
+ Copyright (C) 2009-2011 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/test-alloca-opt.c b/tests/test-alloca-opt.c
new file mode 100644
index 0000000..5aa1645
--- /dev/null
+++ b/tests/test-alloca-opt.c
@@ -0,0 +1,62 @@
+/* Test of optional automatic memory allocation.
+ Copyright (C) 2005, 2007, 2009-2011 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/test-array_list.c b/tests/test-array_list.c
new file mode 100644
index 0000000..27f2ee0
--- /dev/null
+++ b/tests/test-array_list.c
@@ -0,0 +1,329 @@
+/* Test of sequential list data type implementation.
+ Copyright (C) 2006-2011 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/test-array_oset.c b/tests/test-array_oset.c
new file mode 100644
index 0000000..2d069d6
--- /dev/null
+++ b/tests/test-array_oset.c
@@ -0,0 +1,144 @@
+/* Test of ordered set data type implementation.
+ Copyright (C) 2006-2011 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/test-avltree_oset.c b/tests/test-avltree_oset.c
new file mode 100644
index 0000000..084b629
--- /dev/null
+++ b/tests/test-avltree_oset.c
@@ -0,0 +1,136 @@
+/* Test of ordered set data type implementation.
+ Copyright (C) 2006-2011 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/test-binary-io.c b/tests/test-binary-io.c
new file mode 100644
index 0000000..8e5d193
--- /dev/null
+++ b/tests/test-binary-io.c
@@ -0,0 +1,64 @@
+/* Test of binary mode I/O.
+ Copyright (C) 2005, 2007-2011 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/test-binary-io.sh b/tests/test-binary-io.sh
new file mode 100755
index 0000000..33e128c
--- /dev/null
+++ b/tests/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/test-btowc.c b/tests/test-btowc.c
new file mode 100644
index 0000000..7907cbe
--- /dev/null
+++ b/tests/test-btowc.c
@@ -0,0 +1,63 @@
+/* Test of conversion of unibyte character to wide character.
+ Copyright (C) 2008-2011 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/test-btowc1.sh b/tests/test-btowc1.sh
new file mode 100755
index 0000000..aaef48d
--- /dev/null
+++ b/tests/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/test-btowc2.sh b/tests/test-btowc2.sh
new file mode 100755
index 0000000..2e06038
--- /dev/null
+++ b/tests/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/test-c-ctype.c b/tests/test-c-ctype.c
new file mode 100644
index 0000000..9d748ff
--- /dev/null
+++ b/tests/test-c-ctype.c
@@ -0,0 +1,386 @@
+/* Test of character handling in C locale.
+ Copyright (C) 2005, 2007-2011 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/test-c-stack.c b/tests/test-c-stack.c
new file mode 100644
index 0000000..cc27b43
--- /dev/null
+++ b/tests/test-c-stack.c
@@ -0,0 +1,76 @@
+/* Test of c-stack module.
+ Copyright (C) 2002, 2004, 2006, 2008-2011 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 "c-stack.h"
+
+#include "exitfail.h"
+#include <stdio.h>
+#if HAVE_SETRLIMIT
+/* At least FreeBSD 5.0 needs extra headers before <sys/resource.h>
+ will compile. */
+# include <sys/types.h>
+# include <sys/time.h>
+# include <sys/resource.h>
+#endif
+
+#include "macros.h"
+
+char *program_name;
+
+static volatile int *
+recurse_1 (volatile int n, volatile int *p)
+{
+ if (n >= 0)
+ *recurse_1 (n + 1, p) += n;
+ return p;
+}
+
+static int
+recurse (volatile int n)
+{
+ int sum = 0;
+ return *recurse_1 (n, &sum);
+}
+
+int
+main (int argc, char **argv)
+{
+#if HAVE_SETRLIMIT && defined RLIMIT_STACK
+ /* Before starting the endless recursion, try to be friendly to the
+ user's machine. On some Linux 2.2.x systems, there is no stack
+ limit for user processes at all. We don't want to kill such
+ systems. */
+ struct rlimit rl;
+ rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
+ setrlimit (RLIMIT_STACK, &rl);
+#endif
+
+ program_name = argv[0];
+ if (c_stack_action (NULL) == 0)
+ {
+ if (1 < argc)
+ {
+ exit_failure = 77;
+ ++*argv[argc]; /* Intentionally dereference NULL. */
+ }
+ return recurse (0);
+ }
+ fputs ("skipping test: ", stderr);
+ perror ("c_stack_action");
+ return 77;
+}
diff --git a/tests/test-c-stack.sh b/tests/test-c-stack.sh
new file mode 100755
index 0000000..f979065
--- /dev/null
+++ b/tests/test-c-stack.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="t-c-stack.tmp"
+./test-c-stack${EXEEXT} 2> t-c-stack.tmp
+case $? in
+ 77) cat t-c-stack.tmp >&2; (exit 77); exit 77 ;;
+ 1) ;;
+ *) (exit 1); exit 1 ;;
+esac
+if grep 'stack overflow' t-c-stack.tmp >/dev/null ; then
+ :
+else
+ (exit 1); exit 1
+fi
+
+rm -fr $tmpfiles
+
+exit 0
diff --git a/tests/test-c-stack2.sh b/tests/test-c-stack2.sh
new file mode 100755
index 0000000..a80373d
--- /dev/null
+++ b/tests/test-c-stack2.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="t-c-stack2.tmp"
+
+# Sanitize exit status within a subshell, since some shells fail to
+# redirect stderr on their message about death due to signal.
+(./test-c-stack${EXEEXT} 1; exit $?) 2> t-c-stack2.tmp
+
+case $? in
+ 77) if grep 'stack overflow' t-c-stack2.tmp >/dev/null ; then
+ if test -z "$LIBSIGSEGV"; then
+ echo 'cannot tell stack overflow from crash; consider installing libsigsegv' >&2
+ exit 77
+ else
+ echo 'cannot tell stack overflow from crash, in spite of libsigsegv' >&2
+ exit 1
+ fi
+ else
+ cat t-c-stack2.tmp >&2
+ exit 77
+ fi
+ ;;
+ 0) (exit 1); exit 1 ;;
+esac
+if grep 'program error' t-c-stack2.tmp >/dev/null ; then
+ :
+else
+ (exit 1); exit 1
+fi
+
+rm -fr $tmpfiles
+
+exit 0
diff --git a/tests/test-c-strcase.sh b/tests/test-c-strcase.sh
new file mode 100755
index 0000000..5fcf906
--- /dev/null
+++ b/tests/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/test-c-strcasecmp.c b/tests/test-c-strcasecmp.c
new file mode 100644
index 0000000..faa3001
--- /dev/null
+++ b/tests/test-c-strcasecmp.c
@@ -0,0 +1,65 @@
+/* Test of case-insensitive string comparison function.
+ Copyright (C) 2007-2011 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/test-c-strncasecmp.c b/tests/test-c-strncasecmp.c
new file mode 100644
index 0000000..6a225c7
--- /dev/null
+++ b/tests/test-c-strncasecmp.c
@@ -0,0 +1,79 @@
+/* Test of case-insensitive string comparison function.
+ Copyright (C) 2007-2011 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/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
new file mode 100644
index 0000000..17cdff0
--- /dev/null
+++ b/tests/test-canonicalize-lgpl.c
@@ -0,0 +1,222 @@
+/* Test of execution of program termination handlers.
+ Copyright (C) 2007-2011 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)
+{
+#if GNULIB_TEST_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/test-cloexec.c b/tests/test-cloexec.c
new file mode 100644
index 0000000..374de30
--- /dev/null
+++ b/tests/test-cloexec.c
@@ -0,0 +1,141 @@
+/* Test duplicating non-inheritable file descriptors.
+ Copyright (C) 2009-2011 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/test-closein.c b/tests/test-closein.c
new file mode 100644
index 0000000..0c29a6b
--- /dev/null
+++ b/tests/test-closein.c
@@ -0,0 +1,53 @@
+/* Test of closein module.
+ Copyright (C) 2007-2011 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/test-closein.sh b/tests/test-closein.sh
new file mode 100755
index 0000000..a75929a
--- /dev/null
+++ b/tests/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/test-dirname.c b/tests/test-dirname.c
new file mode 100644
index 0000000..1ddf229
--- /dev/null
+++ b/tests/test-dirname.c
@@ -0,0 +1,191 @@
+/* Test the gnulib dirname module.
+ Copyright (C) 2005-2007, 2009-2011 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 ISSLASH ('\\')
+ {"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 ISSLASH ('\\')
+# 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 /* ! ISSLASH ('\\') */
+ {"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/test-dup-safer.c b/tests/test-dup-safer.c
new file mode 100644
index 0000000..14cfaff
--- /dev/null
+++ b/tests/test-dup-safer.c
@@ -0,0 +1,172 @@
+/* Test that dup_safer leaves standard fds alone.
+ Copyright (C) 2009-2011 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
+
+/* 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/test-dup2.c b/tests/test-dup2.c
new file mode 100644
index 0000000..e2ad88b
--- /dev/null
+++ b/tests/test-dup2.c
@@ -0,0 +1,198 @@
+/* Test duplicating file descriptors.
+ Copyright (C) 2009-2011 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_TEST_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_TEST_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_TEST_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_TEST_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 + 1));
+ ASSERT (is_inheritable (fd + 2));
+ errno = 0;
+ ASSERT (dup2 (fd + 1, -1) == -1);
+ ASSERT (errno == EBADF);
+ ASSERT (!is_inheritable (fd + 1));
+#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/test-environ.c b/tests/test-environ.c
new file mode 100644
index 0000000..11df789
--- /dev/null
+++ b/tests/test-environ.c
@@ -0,0 +1,44 @@
+/* Test of environ variable.
+ Copyright (C) 2008-2011 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/test-errno.c b/tests/test-errno.c
new file mode 100644
index 0000000..7851c22
--- /dev/null
+++ b/tests/test-errno.c
@@ -0,0 +1,117 @@
+/* Test of <errno.h> substitute.
+ Copyright (C) 2008-2011 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/test-fcntl-h-c++.cc b/tests/test-fcntl-h-c++.cc
new file mode 100644
index 0000000..4de411c
--- /dev/null
+++ b/tests/test-fcntl-h-c++.cc
@@ -0,0 +1,43 @@
+/* Test of <fcntl.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <fcntl.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_FCNTL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fcntl, int, (int, int, ...));
+#endif
+
+#if GNULIB_TEST_OPEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::open, int, (const char *, int, ...));
+#endif
+
+#if GNULIB_TEST_OPENAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::openat, int, (int, char const *, int, ...));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-fcntl-h.c b/tests/test-fcntl-h.c
new file mode 100644
index 0000000..dd20fbb
--- /dev/null
+++ b/tests/test-fcntl-h.c
@@ -0,0 +1,38 @@
+/* Test of <fcntl.h> substitute.
+ Copyright (C) 2007, 2009-2011 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/test-fcntl.c b/tests/test-fcntl.c
new file mode 100644
index 0000000..23a0dba
--- /dev/null
+++ b/tests/test-fcntl.c
@@ -0,0 +1,341 @@
+/* Test of fcntl(2).
+ Copyright (C) 2009-2011 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"
+
+#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/test-fflush.c b/tests/test-fflush.c
new file mode 100644
index 0000000..3c36ed9
--- /dev/null
+++ b/tests/test-fflush.c
@@ -0,0 +1,145 @@
+/* Test of POSIX compatible fflush() function.
+ Copyright (C) 2007, 2009-2011 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/test-fflush2.c b/tests/test-fflush2.c
new file mode 100644
index 0000000..ac2217d
--- /dev/null
+++ b/tests/test-fflush2.c
@@ -0,0 +1,108 @@
+/* Test of POSIX compatible fflush() function.
+ Copyright (C) 2008-2011 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/test-fflush2.sh b/tests/test-fflush2.sh
new file mode 100755
index 0000000..ef77fa4
--- /dev/null
+++ b/tests/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/test-filenamecat.c b/tests/test-filenamecat.c
new file mode 100644
index 0000000..795b6df
--- /dev/null
+++ b/tests/test-filenamecat.c
@@ -0,0 +1,66 @@
+/* Test of concatenation of two arbitrary file names.
+
+ Copyright (C) 1996-2007, 2009-2011 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/test-fopen-safer.c b/tests/test-fopen-safer.c
new file mode 100644
index 0000000..20a0c13
--- /dev/null
+++ b/tests/test-fopen-safer.c
@@ -0,0 +1,31 @@
+/* Test of opening a file stream.
+ Copyright (C) 2007-2011 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/test-fopen.c b/tests/test-fopen.c
new file mode 100644
index 0000000..c36006a
--- /dev/null
+++ b/tests/test-fopen.c
@@ -0,0 +1,34 @@
+/* Test of opening a file stream.
+ Copyright (C) 2007-2011 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/test-fopen.h b/tests/test-fopen.h
new file mode 100644
index 0000000..49cbac1
--- /dev/null
+++ b/tests/test-fopen.h
@@ -0,0 +1,73 @@
+/* Test of opening a file stream.
+ Copyright (C) 2007-2011 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/test-fpending.c b/tests/test-fpending.c
new file mode 100644
index 0000000..edf1aa2
--- /dev/null
+++ b/tests/test-fpending.c
@@ -0,0 +1,41 @@
+/* Ensure that __fpending works.
+
+ Copyright (C) 2004, 2007-2011 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/test-fpending.sh b/tests/test-fpending.sh
new file mode 100755
index 0000000..636af25
--- /dev/null
+++ b/tests/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/test-fpurge.c b/tests/test-fpurge.c
new file mode 100644
index 0000000..0f36221
--- /dev/null
+++ b/tests/test-fpurge.c
@@ -0,0 +1,134 @@
+/* Test of fpurge() function.
+ Copyright (C) 2007-2011 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) == '!');
+ if (check_filepos)
+ ASSERT (ftell (fp) == 9);
+ 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/test-freadahead.c b/tests/test-freadahead.c
new file mode 100644
index 0000000..23dd21c
--- /dev/null
+++ b/tests/test-freadahead.c
@@ -0,0 +1,73 @@
+/* Test of freadahead() function.
+ Copyright (C) 2007-2011 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/test-freadahead.sh b/tests/test-freadahead.sh
new file mode 100755
index 0000000..27cf550
--- /dev/null
+++ b/tests/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/test-freading.c b/tests/test-freading.c
new file mode 100644
index 0000000..723de4d
--- /dev/null
+++ b/tests/test-freading.c
@@ -0,0 +1,130 @@
+/* Test of freading() function.
+ Copyright (C) 2007-2011 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/test-frexp.c b/tests/test-frexp.c
new file mode 100644
index 0000000..4ed24d2
--- /dev/null
+++ b/tests/test-frexp.c
@@ -0,0 +1,196 @@
+/* Test of splitting a double into fraction and mantissa.
+ Copyright (C) 2007-2011 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 "minus-zero.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
+
+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 = minus_zerod;
+ 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/test-frexpl.c b/tests/test-frexpl.c
new file mode 100644
index 0000000..ccb547b
--- /dev/null
+++ b/tests/test-frexpl.c
@@ -0,0 +1,208 @@
+/* Test of splitting a 'long double' into fraction and mantissa.
+ Copyright (C) 2007-2011 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 "minus-zero.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
+
+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_zerol;
+ 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/test-fseeko.c b/tests/test-fseeko.c
new file mode 100644
index 0000000..ad5eec8
--- /dev/null
+++ b/tests/test-fseeko.c
@@ -0,0 +1,74 @@
+/* Test of fseeko() function.
+ Copyright (C) 2007-2011 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/test-fseeko.sh b/tests/test-fseeko.sh
new file mode 100755
index 0000000..5c55827
--- /dev/null
+++ b/tests/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/test-fseeko2.sh b/tests/test-fseeko2.sh
new file mode 100755
index 0000000..6e1130c
--- /dev/null
+++ b/tests/test-fseeko2.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./test-fseeko${EXEEXT} 1 2 < "$srcdir/test-fseeko2.sh"
diff --git a/tests/test-ftell.c b/tests/test-ftell.c
new file mode 100644
index 0000000..54ede05
--- /dev/null
+++ b/tests/test-ftell.c
@@ -0,0 +1,107 @@
+/* Test of ftell() function.
+ Copyright (C) 2007-2011 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 (ftell, long, (FILE *));
+
+#include "binary-io.h"
+#include "macros.h"
+
+#ifndef FUNC_UNGETC_BROKEN
+# define FUNC_UNGETC_BROKEN 0
+#endif
+
+int
+main (int argc, char **argv)
+{
+ int ch;
+ /* Assume stdin is seekable iff argc > 1. */
+ if (argc == 1)
+ {
+ ASSERT (ftell (stdin) == -1);
+ return 0;
+ }
+
+ /* mingw ftell is unreliable on text mode input. */
+ SET_BINARY (0);
+
+ /* Simple tests. */
+ ASSERT (ftell (stdin) == 0);
+
+ ch = fgetc (stdin);
+ ASSERT (ch == '#');
+ ASSERT (ftell (stdin) == 1);
+
+ /* Test ftell after ungetc of read input. */
+ ch = ungetc ('#', stdin);
+ ASSERT (ch == '#');
+ ASSERT (ftell (stdin) == 0);
+
+ ch = fgetc (stdin);
+ ASSERT (ch == '#');
+ ASSERT (ftell (stdin) == 1);
+
+ /* Test ftell after fseek. */
+ ASSERT (fseek (stdin, 2, SEEK_SET) == 0);
+ ASSERT (ftell (stdin) == 2);
+
+ /* Test ftell after random ungetc. */
+ ch = fgetc (stdin);
+ ASSERT (ch == '/');
+ ch = ungetc ('@', stdin);
+ ASSERT (ch == '@');
+ ASSERT (ftell (stdin) == 2);
+
+ ch = fgetc (stdin);
+ ASSERT (ch == '@');
+ ASSERT (ftell (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);
+
+ ch = ungetc ('~', stdin);
+ ASSERT (ch == '~');
+ ASSERT (ftell (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 = ftell (stdin);
+ ASSERT (fseek (stdin, 10, SEEK_END) == 0);
+ ASSERT (ftell (stdin) == ch + 10);
+#endif
+
+ return 0;
+}
diff --git a/tests/test-ftell.sh b/tests/test-ftell.sh
new file mode 100755
index 0000000..bf55d2e
--- /dev/null
+++ b/tests/test-ftell.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-ftell${EXEEXT} 1 < "$srcdir/test-ftell.sh" || exit 1
+echo hi | ./test-ftell${EXEEXT} || exit 1
+exit 0
diff --git a/tests/test-ftell2.sh b/tests/test-ftell2.sh
new file mode 100755
index 0000000..3b645b8
--- /dev/null
+++ b/tests/test-ftell2.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./test-ftell${EXEEXT} 1 2 < "$srcdir/test-ftell2.sh"
diff --git a/tests/test-ftell3.c b/tests/test-ftell3.c
new file mode 100644
index 0000000..a5167ef
--- /dev/null
+++ b/tests/test-ftell3.c
@@ -0,0 +1,78 @@
+/* Test of ftell() function.
+ Copyright (C) 2007-2011 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>
+
+/* 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-ftell3.tmp"
+
+int
+main (void)
+{
+ FILE *fp;
+
+ /* Create a file with some contents. */
+ fp = fopen (TESTFILE, "w");
+ if (fp == NULL)
+ goto skip;
+ if (fwrite ("foogarsh", 1, 8, fp) < 8)
+ goto skip;
+ if (fclose (fp))
+ goto skip;
+
+ /* The file's contents is now "foogarsh". */
+
+ /* Try writing after reading to EOF. */
+ 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);
+ ASSERT (ftell (fp) == 8);
+ ASSERT (ftell (fp) == 8);
+ ASSERT (putc ('!', fp) == '!');
+ ASSERT (ftell (fp) == 9);
+ 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/test-ftello.c b/tests/test-ftello.c
new file mode 100644
index 0000000..636da81
--- /dev/null
+++ b/tests/test-ftello.c
@@ -0,0 +1,118 @@
+/* Test of ftello() function.
+ Copyright (C) 2007-2011 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/test-ftello.sh b/tests/test-ftello.sh
new file mode 100755
index 0000000..33d2e83
--- /dev/null
+++ b/tests/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/test-ftello2.sh b/tests/test-ftello2.sh
new file mode 100755
index 0000000..ba750b0
--- /dev/null
+++ b/tests/test-ftello2.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./test-ftello${EXEEXT} 1 2 < "$srcdir/test-ftello2.sh"
diff --git a/tests/test-ftello3.c b/tests/test-ftello3.c
new file mode 100644
index 0000000..50d4b88
--- /dev/null
+++ b/tests/test-ftello3.c
@@ -0,0 +1,78 @@
+/* Test of ftello() function.
+ Copyright (C) 2007-2011 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>
+
+/* 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-ftello3.tmp"
+
+int
+main (void)
+{
+ FILE *fp;
+
+ /* Create a file with some contents. */
+ fp = fopen (TESTFILE, "w");
+ if (fp == NULL)
+ goto skip;
+ if (fwrite ("foogarsh", 1, 8, fp) < 8)
+ goto skip;
+ if (fclose (fp))
+ goto skip;
+
+ /* The file's contents is now "foogarsh". */
+
+ /* Try writing after reading to EOF. */
+ 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);
+ ASSERT (ftello (fp) == 8);
+ ASSERT (ftello (fp) == 8);
+ ASSERT (putc ('!', fp) == '!');
+ ASSERT (ftello (fp) == 9);
+ 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/test-getdtablesize.c b/tests/test-getdtablesize.c
new file mode 100644
index 0000000..ae969a1
--- /dev/null
+++ b/tests/test-getdtablesize.c
@@ -0,0 +1,34 @@
+/* Test of getdtablesize() function.
+ Copyright (C) 2008-2011 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/test-getopt.c b/tests/test-getopt.c
new file mode 100644
index 0000000..69f2cfa
--- /dev/null
+++ b/tests/test-getopt.c
@@ -0,0 +1,99 @@
+/* Test of command line argument processing.
+ Copyright (C) 2009-2011 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>
+
+/* 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
+
+#if GNULIB_TEST_GETOPT_GNU
+# include <getopt.h>
+
+# ifndef __getopt_argv_const
+# define __getopt_argv_const const
+# endif
+# include "signature.h"
+SIGNATURE_CHECK (getopt_long, int, (int, char *__getopt_argv_const *,
+ char const *, struct option const *,
+ int *));
+SIGNATURE_CHECK (getopt_long_only, int, (int, char *__getopt_argv_const *,
+ char const *, struct option const *,
+ int *));
+
+#endif
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (getopt, int, (int, char * const[], char const *));
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* This test intentionally remaps 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;
+
+#include "test-getopt.h"
+#if GNULIB_TEST_GETOPT_GNU
+# include "test-getopt_long.h"
+#endif
+
+int
+main (void)
+{
+ /* This test validates that stderr is used correctly, so move the
+ original into fd 10. */
+ if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
+ || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
+ return 2;
+
+ ASSERT (freopen ("test-getopt.tmp", "w", stderr) == stderr);
+
+ /* These default values are required by POSIX. */
+ ASSERT (optind == 1);
+ ASSERT (opterr != 0);
+
+ setenv ("POSIXLY_CORRECT", "1", 1);
+ test_getopt ();
+
+#if GNULIB_TEST_GETOPT_GNU
+ test_getopt_long_posix ();
+#endif
+
+ unsetenv ("POSIXLY_CORRECT");
+ test_getopt ();
+
+#if GNULIB_TEST_GETOPT_GNU
+ test_getopt_long ();
+ test_getopt_long_only ();
+#endif
+
+ ASSERT (fclose (stderr) == 0);
+ ASSERT (remove ("test-getopt.tmp") == 0);
+
+ return 0;
+}
diff --git a/tests/test-getopt.h b/tests/test-getopt.h
new file mode 100644
index 0000000..9c877b3
--- /dev/null
+++ b/tests/test-getopt.h
@@ -0,0 +1,1369 @@
+/* Test of command line argument processing.
+ Copyright (C) 2009-2011 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 <stdbool.h>
+
+/* The glibc/gnulib implementation of getopt supports setting optind =
+ 0, but not all other implementations do. This matters for getopt.
+ But for getopt_long, we require GNU compatibility. */
+#if defined __GETOPT_PREFIX || (__GLIBC__ >= 2 && !defined __UCLIBC__)
+# define OPTIND_MIN 0
+#elif HAVE_DECL_OPTRESET
+# define OPTIND_MIN (optreset = 1)
+#else
+# define OPTIND_MIN 1
+#endif
+
+static void
+getopt_loop (int argc, const char **argv,
+ const char *options,
+ int *a_seen, int *b_seen,
+ const char **p_value, const char **q_value,
+ int *non_options_count, const char **non_options,
+ int *unrecognized, bool *message_issued)
+{
+ int c;
+ int pos = ftell (stderr);
+
+ while ((c = getopt (argc, (char **) argv, options)) != -1)
+ {
+ switch (c)
+ {
+ case 'a':
+ (*a_seen)++;
+ break;
+ case 'b':
+ (*b_seen)++;
+ break;
+ case 'p':
+ *p_value = optarg;
+ break;
+ case 'q':
+ *q_value = optarg;
+ break;
+ case '\1':
+ /* Must only happen with option '-' at the beginning. */
+ ASSERT (options[0] == '-');
+ non_options[(*non_options_count)++] = optarg;
+ break;
+ case ':':
+ /* Must only happen with option ':' at the beginning. */
+ ASSERT (options[0] == ':'
+ || ((options[0] == '-' || options[0] == '+')
+ && options[1] == ':'));
+ /* fall through */
+ case '?':
+ *unrecognized = optopt;
+ break;
+ default:
+ *unrecognized = c;
+ break;
+ }
+ }
+
+ *message_issued = pos < ftell (stderr);
+}
+
+static void
+test_getopt (void)
+{
+ int start;
+ bool posixly = !!getenv ("POSIXLY_CORRECT");
+ /* See comment in getopt.c:
+ glibc gets a LSB-compliant getopt.
+ Standalone applications get a POSIX-compliant getopt. */
+#if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__)
+ /* Using getopt from gnulib or from a non-glibc system. */
+ posixly = true;
+#endif
+
+ /* Test processing of boolean options. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-a";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "ab",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-b";
+ argv[argc++] = "-a";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "ab",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ba";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "ab",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "-a";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "ab",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 2);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ ASSERT (!output);
+ }
+
+ /* Test processing of options with arguments. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-pfoo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "p:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "p:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "-q";
+ argv[argc++] = "baz";
+ argv[argc++] = "-pfoo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ ASSERT (!output);
+ }
+
+#if GNULIB_TEST_GETOPT_GNU
+ /* Test processing of options with optional arguments. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-pfoo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "p::q::",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "p::q::",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "abp::q::",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ ASSERT (!output);
+ }
+#endif /* GNULIB_TEST_GETOPT_GNU */
+
+ /* Check that invalid options are recognized; and that both opterr
+ and leading ':' can silence output. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-x";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 42;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'x');
+ ASSERT (optind == 5);
+ ASSERT (output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-x";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 0;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'x');
+ ASSERT (optind == 5);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-x";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, ":abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'x');
+ ASSERT (optind == 5);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-:";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 42;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == ':');
+ ASSERT (optind == 5);
+ ASSERT (output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-:";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 0;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == ':');
+ ASSERT (optind == 5);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-:";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, ":abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == ':');
+ ASSERT (optind == 5);
+ ASSERT (!output);
+ }
+
+ /* Check for missing argument behavior. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ap";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'p');
+ ASSERT (optind == 2);
+ ASSERT (output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ap";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 0;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'p');
+ ASSERT (optind == 2);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ap";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, ":abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'p');
+ ASSERT (optind == 2);
+ ASSERT (!output);
+ }
+
+ /* Check that by default, non-options arguments are moved to the end. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ if (posixly)
+ {
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ ASSERT (!output);
+ }
+ else
+ {
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "-p") == 0);
+ ASSERT (strcmp (argv[2], "billy") == 0);
+ ASSERT (strcmp (argv[3], "-a") == 0);
+ ASSERT (strcmp (argv[4], "donald") == 0);
+ ASSERT (strcmp (argv[5], "duck") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ ASSERT (!output);
+ }
+ }
+
+ /* Check that '--' ends the argument processing. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[20];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "--";
+ argv[argc++] = "-b";
+ argv[argc++] = "foo";
+ argv[argc++] = "-q";
+ argv[argc++] = "johnny";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ if (posixly)
+ {
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "--") == 0);
+ ASSERT (strcmp (argv[7], "-b") == 0);
+ ASSERT (strcmp (argv[8], "foo") == 0);
+ ASSERT (strcmp (argv[9], "-q") == 0);
+ ASSERT (strcmp (argv[10], "johnny") == 0);
+ ASSERT (strcmp (argv[11], "bar") == 0);
+ ASSERT (argv[12] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ ASSERT (!output);
+ }
+ else
+ {
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "-p") == 0);
+ ASSERT (strcmp (argv[2], "billy") == 0);
+ ASSERT (strcmp (argv[3], "-a") == 0);
+ ASSERT (strcmp (argv[4], "--") == 0);
+ ASSERT (strcmp (argv[5], "donald") == 0);
+ ASSERT (strcmp (argv[6], "duck") == 0);
+ ASSERT (strcmp (argv[7], "-b") == 0);
+ ASSERT (strcmp (argv[8], "foo") == 0);
+ ASSERT (strcmp (argv[9], "-q") == 0);
+ ASSERT (strcmp (argv[10], "johnny") == 0);
+ ASSERT (strcmp (argv[11], "bar") == 0);
+ ASSERT (argv[12] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ ASSERT (!output);
+ }
+ }
+
+#if GNULIB_TEST_GETOPT_GNU
+ /* Check that the '-' flag causes non-options to be returned in order. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "-abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 3);
+ ASSERT (strcmp (non_options[0], "donald") == 0);
+ ASSERT (strcmp (non_options[1], "duck") == 0);
+ ASSERT (strcmp (non_options[2], "bar") == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 7);
+ ASSERT (!output);
+ }
+
+ /* Check that '--' ends the argument processing. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[20];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "--";
+ argv[argc++] = "-b";
+ argv[argc++] = "foo";
+ argv[argc++] = "-q";
+ argv[argc++] = "johnny";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "-abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "--") == 0);
+ ASSERT (strcmp (argv[7], "-b") == 0);
+ ASSERT (strcmp (argv[8], "foo") == 0);
+ ASSERT (strcmp (argv[9], "-q") == 0);
+ ASSERT (strcmp (argv[10], "johnny") == 0);
+ ASSERT (strcmp (argv[11], "bar") == 0);
+ ASSERT (argv[12] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (!output);
+ if (non_options_count == 2)
+ {
+ /* glibc behaviour. */
+ ASSERT (non_options_count == 2);
+ ASSERT (strcmp (non_options[0], "donald") == 0);
+ ASSERT (strcmp (non_options[1], "duck") == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 7);
+ }
+ else
+ {
+ /* Another valid behaviour. */
+ ASSERT (non_options_count == 7);
+ ASSERT (strcmp (non_options[0], "donald") == 0);
+ ASSERT (strcmp (non_options[1], "duck") == 0);
+ ASSERT (strcmp (non_options[2], "-b") == 0);
+ ASSERT (strcmp (non_options[3], "foo") == 0);
+ ASSERT (strcmp (non_options[4], "-q") == 0);
+ ASSERT (strcmp (non_options[5], "johnny") == 0);
+ ASSERT (strcmp (non_options[6], "bar") == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 12);
+ }
+ }
+
+ /* Check that the '-' flag has to come first. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "abp:q:-",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ if (posixly)
+ {
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ ASSERT (!output);
+ }
+ else
+ {
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "-p") == 0);
+ ASSERT (strcmp (argv[2], "billy") == 0);
+ ASSERT (strcmp (argv[3], "-a") == 0);
+ ASSERT (strcmp (argv[4], "donald") == 0);
+ ASSERT (strcmp (argv[5], "duck") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ ASSERT (!output);
+ }
+ }
+
+ /* Check that the '+' flag causes the first non-option to terminate the
+ loop. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "+abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-+";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_loop (argc, argv, "+abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == '+');
+ ASSERT (optind == 2);
+ ASSERT (output);
+ }
+
+ /* Check that '--' ends the argument processing. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[20];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "--";
+ argv[argc++] = "-b";
+ argv[argc++] = "foo";
+ argv[argc++] = "-q";
+ argv[argc++] = "johnny";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "+abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "--") == 0);
+ ASSERT (strcmp (argv[7], "-b") == 0);
+ ASSERT (strcmp (argv[8], "foo") == 0);
+ ASSERT (strcmp (argv[9], "-q") == 0);
+ ASSERT (strcmp (argv[10], "johnny") == 0);
+ ASSERT (strcmp (argv[11], "bar") == 0);
+ ASSERT (argv[12] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ ASSERT (!output);
+ }
+#endif /* GNULIB_TEST_GETOPT_GNU */
+
+ /* Check that the '+' flag has to come first. */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "abp:q:+",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ if (posixly)
+ {
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ ASSERT (!output);
+ }
+ else
+ {
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "-p") == 0);
+ ASSERT (strcmp (argv[2], "billy") == 0);
+ ASSERT (strcmp (argv[3], "-a") == 0);
+ ASSERT (strcmp (argv[4], "donald") == 0);
+ ASSERT (strcmp (argv[5], "duck") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ ASSERT (!output);
+ }
+ }
+
+#if GNULIB_TEST_GETOPT_GNU
+ /* If GNU extensions are supported, require compliance with POSIX
+ interpretation on leading '+' behavior.
+ http://austingroupbugs.net/view.php?id=191 */
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ opterr = 1;
+ getopt_loop (argc, argv, "+:abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_loop (argc, argv, "+:abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'p');
+ ASSERT (optind == 2);
+ ASSERT (!output);
+ }
+ for (start = OPTIND_MIN; start <= 1; start++)
+ {
+ int a_seen = 0;
+ int b_seen = 0;
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ bool output;
+ int argc = 0;
+ const char *argv[10];
+
+ argv[argc++] = "program";
+ argv[argc++] = "-b";
+ argv[argc++] = "-p";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_loop (argc, argv, "+:abp:q:",
+ &a_seen, &b_seen, &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized, &output);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'p');
+ ASSERT (optind == 3);
+ ASSERT (!output);
+ }
+#endif /* GNULIB_TEST_GETOPT_GNU */
+}
diff --git a/tests/test-getopt_long.h b/tests/test-getopt_long.h
new file mode 100644
index 0000000..7a74867
--- /dev/null
+++ b/tests/test-getopt_long.h
@@ -0,0 +1,2125 @@
+/* Test of command line argument processing.
+ Copyright (C) 2009-2011 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. */
+
+static int a_seen;
+static int b_seen;
+static int q_seen;
+
+static const struct option long_options_required[] =
+ {
+ { "alpha", no_argument, NULL, 'a' },
+ { "beta", no_argument, &b_seen, 1 },
+ { "prune", required_argument, NULL, 'p' },
+ { "quetsche", required_argument, &q_seen, 1 },
+ { "xtremely-",no_argument, NULL, 1003 },
+ { "xtra", no_argument, NULL, 1001 },
+ { "xtreme", no_argument, NULL, 1002 },
+ { "xtremely", no_argument, NULL, 1003 },
+ { NULL, 0, NULL, 0 }
+ };
+
+static const struct option long_options_optional[] =
+ {
+ { "alpha", no_argument, NULL, 'a' },
+ { "beta", no_argument, &b_seen, 1 },
+ { "prune", optional_argument, NULL, 'p' },
+ { "quetsche", optional_argument, &q_seen, 1 },
+ { NULL, 0, NULL, 0 }
+ };
+
+static void
+getopt_long_loop (int argc, const char **argv,
+ const char *options, const struct option *long_options,
+ const char **p_value, const char **q_value,
+ int *non_options_count, const char **non_options,
+ int *unrecognized)
+{
+ int option_index = -1;
+ int c;
+
+ opterr = 0;
+ q_seen = 0;
+ while ((c = getopt_long (argc, (char **) argv, options, long_options,
+ &option_index))
+ != -1)
+ {
+ switch (c)
+ {
+ case 0:
+ /* An option with a non-NULL flag pointer was processed. */
+ if (q_seen)
+ *q_value = optarg;
+ break;
+ case 'a':
+ a_seen++;
+ break;
+ case 'b':
+ b_seen = 1;
+ break;
+ case 'p':
+ *p_value = optarg;
+ break;
+ case 'q':
+ *q_value = optarg;
+ break;
+ case '\1':
+ /* Must only happen with option '-' at the beginning. */
+ ASSERT (options[0] == '-');
+ non_options[(*non_options_count)++] = optarg;
+ break;
+ case ':':
+ /* Must only happen with option ':' at the beginning. */
+ ASSERT (options[0] == ':'
+ || ((options[0] == '-' || options[0] == '+')
+ && options[1] == ':'));
+ /* fall through */
+ case '?':
+ *unrecognized = optopt;
+ break;
+ default:
+ *unrecognized = c;
+ break;
+ }
+ }
+}
+
+/* Reduce casting, so we can use string literals elsewhere.
+ getopt_long takes an array of char*, but luckily does not modify
+ those elements, so we can pass const char*. */
+static int
+do_getopt_long (int argc, const char **argv, const char *shortopts,
+ const struct option *longopts, int *longind)
+{
+ return getopt_long (argc, (char **) argv, shortopts, longopts, longind);
+}
+
+static void
+test_getopt_long (void)
+{
+ int start;
+
+ /* Test disambiguation of options. */
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--x";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--xt";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--xtr";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--xtra";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == 1001);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--xtre";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--xtrem";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--xtreme";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == 1002);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--xtremel";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == 1003);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--xtremely";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
+ ASSERT (c == 1003);
+ }
+
+ /* Check that -W handles unknown options. */
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "W;", long_options_required, &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 'W');
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wunknown";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "W;", long_options_required, &option_index);
+ /* glibc and BSD behave differently here, but for now, we allow
+ both behaviors since W support is not frequently used. */
+ if (c == '?')
+ {
+ ASSERT (optopt == 0);
+ ASSERT (optarg == NULL);
+ }
+ else
+ {
+ ASSERT (c == 'W');
+ ASSERT (strcmp (optarg, "unknown") == 0);
+ }
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc++] = "unknown";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "W;", long_options_required, &option_index);
+ /* glibc and BSD behave differently here, but for now, we allow
+ both behaviors since W support is not frequently used. */
+ if (c == '?')
+ {
+ ASSERT (optopt == 0);
+ ASSERT (optarg == NULL);
+ }
+ else
+ {
+ ASSERT (c == 'W');
+ ASSERT (strcmp (optarg, "unknown") == 0);
+ }
+ }
+
+ /* Test processing of boolean short options. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-a";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-b";
+ argv[argc++] = "-a";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ba";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "-a";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 2);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+
+ /* Test processing of boolean long options. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--alpha";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--beta";
+ argv[argc++] = "--alpha";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--alpha";
+ argv[argc++] = "--beta";
+ argv[argc++] = "--alpha";
+ argv[argc++] = "--beta";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 2);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Test processing of boolean long options via -W. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Walpha";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abW;", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc++] = "beta";
+ argv[argc++] = "-W";
+ argv[argc++] = "alpha";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "aW;b", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Walpha";
+ argv[argc++] = "-Wbeta";
+ argv[argc++] = "-Walpha";
+ argv[argc++] = "-Wbeta";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "W;ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 2);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Test processing of short options with arguments. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-pfoo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "-q";
+ argv[argc++] = "baz";
+ argv[argc++] = "-pfoo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Test processing of long options with arguments. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "--q";
+ argv[argc++] = "baz";
+ argv[argc++] = "--p=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Test processing of long options with arguments via -W. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wp=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:W;", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc++] = "p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:W;q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "-Wq";
+ argv[argc++] = "baz";
+ argv[argc++] = "-W";
+ argv[argc++] = "p=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "W;abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 6);
+ }
+
+ /* Test processing of short options with optional arguments. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-pfoo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+
+ /* Test processing of long options with optional arguments. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p=";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && *p_value == '\0');
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+
+ /* Test processing of long options with optional arguments via -W. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wp=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::W;", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wp";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::W;", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wp=";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "W;p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && *p_value == '\0');
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc++] = "p=";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "W;p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && *p_value == '\0');
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc++] = "p";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "W;abp::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ /* ASSERT (p_value == NULL); */
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ }
+
+ /* Check that invalid options are recognized. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-x";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'x');
+ ASSERT (optind == 5);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-:";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == ':');
+ ASSERT (optind == 5);
+ }
+
+ /* Check that unexpected arguments are recognized. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "--a=";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 'a');
+ ASSERT (optind == 4);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "--b=";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ /* When flag is non-zero, glibc sets optopt anyway, but BSD
+ leaves optopt unchanged. */
+ ASSERT (unrecognized == 1 || unrecognized == 0);
+ ASSERT (optind == 4);
+ }
+
+ /* Check that by default, non-options arguments are moved to the end. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "-p") == 0);
+ ASSERT (strcmp (argv[2], "billy") == 0);
+ ASSERT (strcmp (argv[3], "-a") == 0);
+ ASSERT (strcmp (argv[4], "donald") == 0);
+ ASSERT (strcmp (argv[5], "duck") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ }
+
+ /* Check that '--' ends the argument processing. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[20];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "--";
+ argv[argc++] = "-b";
+ argv[argc++] = "foo";
+ argv[argc++] = "-q";
+ argv[argc++] = "johnny";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "-p") == 0);
+ ASSERT (strcmp (argv[2], "billy") == 0);
+ ASSERT (strcmp (argv[3], "-a") == 0);
+ ASSERT (strcmp (argv[4], "--") == 0);
+ ASSERT (strcmp (argv[5], "donald") == 0);
+ ASSERT (strcmp (argv[6], "duck") == 0);
+ ASSERT (strcmp (argv[7], "-b") == 0);
+ ASSERT (strcmp (argv[8], "foo") == 0);
+ ASSERT (strcmp (argv[9], "-q") == 0);
+ ASSERT (strcmp (argv[10], "johnny") == 0);
+ ASSERT (strcmp (argv[11], "bar") == 0);
+ ASSERT (argv[12] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Check that the '-' flag causes non-options to be returned in order. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "-abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 3);
+ ASSERT (strcmp (non_options[0], "donald") == 0);
+ ASSERT (strcmp (non_options[1], "duck") == 0);
+ ASSERT (strcmp (non_options[2], "bar") == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 7);
+ }
+
+ /* Check that '--' ends the argument processing. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[20];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "--";
+ argv[argc++] = "-b";
+ argv[argc++] = "foo";
+ argv[argc++] = "-q";
+ argv[argc++] = "johnny";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "-abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "--") == 0);
+ ASSERT (strcmp (argv[7], "-b") == 0);
+ ASSERT (strcmp (argv[8], "foo") == 0);
+ ASSERT (strcmp (argv[9], "-q") == 0);
+ ASSERT (strcmp (argv[10], "johnny") == 0);
+ ASSERT (strcmp (argv[11], "bar") == 0);
+ ASSERT (argv[12] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ if (non_options_count == 2)
+ {
+ /* glibc behaviour. */
+ ASSERT (non_options_count == 2);
+ ASSERT (strcmp (non_options[0], "donald") == 0);
+ ASSERT (strcmp (non_options[1], "duck") == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 7);
+ }
+ else
+ {
+ /* Another valid behaviour. */
+ ASSERT (non_options_count == 7);
+ ASSERT (strcmp (non_options[0], "donald") == 0);
+ ASSERT (strcmp (non_options[1], "duck") == 0);
+ ASSERT (strcmp (non_options[2], "-b") == 0);
+ ASSERT (strcmp (non_options[3], "foo") == 0);
+ ASSERT (strcmp (non_options[4], "-q") == 0);
+ ASSERT (strcmp (non_options[5], "johnny") == 0);
+ ASSERT (strcmp (non_options[6], "bar") == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 12);
+ }
+ }
+
+ /* Check that the '-' flag has to come first. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:-", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "-p") == 0);
+ ASSERT (strcmp (argv[2], "billy") == 0);
+ ASSERT (strcmp (argv[3], "-a") == 0);
+ ASSERT (strcmp (argv[4], "donald") == 0);
+ ASSERT (strcmp (argv[5], "duck") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ }
+
+ /* Check that the '+' flag causes the first non-option to terminate the
+ loop. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "+abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-+";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "+abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == '+');
+ ASSERT (optind == 2);
+ }
+
+ /* Check that '--' ends the argument processing. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[20];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "--";
+ argv[argc++] = "-b";
+ argv[argc++] = "foo";
+ argv[argc++] = "-q";
+ argv[argc++] = "johnny";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "+abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "--") == 0);
+ ASSERT (strcmp (argv[7], "-b") == 0);
+ ASSERT (strcmp (argv[8], "foo") == 0);
+ ASSERT (strcmp (argv[9], "-q") == 0);
+ ASSERT (strcmp (argv[10], "johnny") == 0);
+ ASSERT (strcmp (argv[11], "bar") == 0);
+ ASSERT (argv[12] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ }
+
+ /* Check that the '+' flag has to come first. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:+", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "-p") == 0);
+ ASSERT (strcmp (argv[2], "billy") == 0);
+ ASSERT (strcmp (argv[3], "-a") == 0);
+ ASSERT (strcmp (argv[4], "donald") == 0);
+ ASSERT (strcmp (argv[5], "duck") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ }
+}
+
+/* Test behavior of getopt_long when POSIXLY_CORRECT is set in the
+ environment. Options with optional arguments should not change
+ behavior just because of an environment variable.
+ http://lists.gnu.org/archive/html/bug-m4/2006-09/msg00028.html */
+static void
+test_getopt_long_posix (void)
+{
+ int start;
+
+ /* Check that POSIXLY_CORRECT stops parsing the same as leading '+'. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ }
+
+ /* Check that POSIXLY_CORRECT doesn't change optional arguments. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+
+ /* Check that leading - still sees options after non-options. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-a";
+ argv[argc++] = "billy";
+ argv[argc++] = "-b";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "-ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 1);
+ ASSERT (strcmp (non_options[0], "billy") == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ }
+}
+
+/* Reduce casting, so we can use string literals elsewhere.
+ getopt_long_only takes an array of char*, but luckily does not
+ modify those elements, so we can pass const char*. */
+static int
+do_getopt_long_only (int argc, const char **argv, const char *shortopts,
+ const struct option *longopts, int *longind)
+{
+ return getopt_long_only (argc, (char **) argv, shortopts, longopts, longind);
+}
+
+static void
+test_getopt_long_only (void)
+{
+ /* Test disambiguation of options. */
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-x";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "ab", long_options_required,
+ &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-x";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == 'x');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--x";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-b";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ b_seen = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == 'b');
+ ASSERT (b_seen == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--b";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ b_seen = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == 0);
+ ASSERT (b_seen == 1);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xt";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "ab", long_options_required,
+ &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xt";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtra";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "ab", long_options_required,
+ &option_index);
+ ASSERT (c == 1001);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtreme";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx:", long_options_required,
+ &option_index);
+ ASSERT (c == 1002);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtremel";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "ab", long_options_required,
+ &option_index);
+ /* glibc getopt_long_only is intentionally different from
+ getopt_long when handling a prefix that is common to two
+ spellings, when both spellings have the same option directives.
+ BSD getopt_long_only treats both cases the same. */
+ ASSERT (c == 1003 || c == '?');
+ ASSERT (optind == 2);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtremel";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx::", long_options_required,
+ &option_index);
+ /* glibc getopt_long_only is intentionally different from
+ getopt_long when handling a prefix that is common to two
+ spellings, when both spellings have the same option directives.
+ BSD getopt_long_only treats both cases the same. */
+ ASSERT (c == 1003 || c == '?');
+ ASSERT (optind == 2);
+ ASSERT (optarg == NULL);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtras";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx::", long_options_required,
+ &option_index);
+ ASSERT (c == 'x');
+ ASSERT (strcmp (optarg, "tras") == 0);
+ }
+}
diff --git a/tests/test-gettimeofday.c b/tests/test-gettimeofday.c
new file mode 100644
index 0000000..7d09fc3
--- /dev/null
+++ b/tests/test-gettimeofday.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005, 2007, 2009-2011 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/test-ignore-value.c b/tests/test-ignore-value.c
new file mode 100644
index 0000000..501f79c
--- /dev/null
+++ b/tests/test-ignore-value.c
@@ -0,0 +1,84 @@
+/* Test the "ignore-value" module.
+
+ Copyright (C) 2011 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. */
+
+#include <config.h>
+
+#include "ignore-value.h"
+
+#include <stdio.h>
+
+#ifndef _GL_ATTRIBUTE_RETURN_CHECK
+# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 1)
+# define _GL_ATTRIBUTE_RETURN_CHECK
+# else
+# define _GL_ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__))
+# endif
+#endif
+
+struct s { int i; };
+static char doChar (void) _GL_ATTRIBUTE_RETURN_CHECK;
+static int doInt (void) _GL_ATTRIBUTE_RETURN_CHECK;
+static off_t doOff (void) _GL_ATTRIBUTE_RETURN_CHECK;
+static void *doPtr (void) _GL_ATTRIBUTE_RETURN_CHECK;
+static struct s doStruct (void) _GL_ATTRIBUTE_RETURN_CHECK;
+
+static char
+doChar (void)
+{
+ return 0;
+}
+
+static int
+doInt (void)
+{
+ return 0;
+}
+
+static off_t
+doOff (void)
+{
+ return 0;
+}
+
+static void *
+doPtr (void)
+{
+ return NULL;
+}
+
+static struct s
+doStruct (void)
+{
+ static struct s s1;
+ return s1;
+}
+
+int
+main (void)
+{
+ /* If this test can compile with -Werror and the same warnings as
+ the rest of the project, then we are properly silencing warnings
+ about ignored return values. */
+ ignore_value (doChar ());
+ ignore_value (doInt ());
+ ignore_value (doOff ());
+ ignore_value (doPtr ());
+ ignore_value (doStruct ());
+ return 0;
+}
diff --git a/tests/test-isnand-nolibm.c b/tests/test-isnand-nolibm.c
new file mode 100644
index 0000000..d120459
--- /dev/null
+++ b/tests/test-isnand-nolibm.c
@@ -0,0 +1,22 @@
+/* Test of isnand() substitute.
+ Copyright (C) 2007-2011 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/test-isnand.h b/tests/test-isnand.h
new file mode 100644
index 0000000..de69331
--- /dev/null
+++ b/tests/test-isnand.h
@@ -0,0 +1,62 @@
+/* Test of isnand() substitute.
+ Copyright (C) 2007-2011 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 "minus-zero.h"
+#include "nan.h"
+#include "macros.h"
+
+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 (minus_zerod));
+ /* 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/test-isnanf-nolibm.c b/tests/test-isnanf-nolibm.c
new file mode 100644
index 0000000..6d720be
--- /dev/null
+++ b/tests/test-isnanf-nolibm.c
@@ -0,0 +1,21 @@
+/* Test of isnanf() substitute.
+ Copyright (C) 2007-2011 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/test-isnanf.h b/tests/test-isnanf.h
new file mode 100644
index 0000000..f4b0e86
--- /dev/null
+++ b/tests/test-isnanf.h
@@ -0,0 +1,64 @@
+/* Test of isnanf() substitute.
+ Copyright (C) 2007-2011 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 "minus-zero.h"
+#include "nan.h"
+#include "macros.h"
+
+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 (minus_zerof));
+ /* 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/test-isnanl-nolibm.c b/tests/test-isnanl-nolibm.c
new file mode 100644
index 0000000..5322087
--- /dev/null
+++ b/tests/test-isnanl-nolibm.c
@@ -0,0 +1,23 @@
+/* Test of isnanl() substitute.
+ Copyright (C) 2007, 2009-2011 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/test-isnanl.h b/tests/test-isnanl.h
new file mode 100644
index 0000000..c07f3a9
--- /dev/null
+++ b/tests/test-isnanl.h
@@ -0,0 +1,126 @@
+/* Test of isnanl() substitute.
+ Copyright (C) 2007-2011 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 "minus-zero.h"
+#include "nan.h"
+#include "macros.h"
+
+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_zerol));
+ /* 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/test-langinfo-c++.cc b/tests/test-langinfo-c++.cc
new file mode 100644
index 0000000..8d0af71
--- /dev/null
+++ b/tests/test-langinfo-c++.cc
@@ -0,0 +1,35 @@
+/* Test of <langinfo.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <langinfo.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_NL_LANGINFO
+SIGNATURE_CHECK (GNULIB_NAMESPACE::nl_langinfo, char *, (nl_item));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-langinfo.c b/tests/test-langinfo.c
new file mode 100644
index 0000000..ade807c
--- /dev/null
+++ b/tests/test-langinfo.c
@@ -0,0 +1,92 @@
+/* Test of <langinfo.h> substitute.
+ Copyright (C) 2009-2011 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/test-link.c b/tests/test-link.c
new file mode 100644
index 0000000..cbb4e0b
--- /dev/null
+++ b/tests/test-link.c
@@ -0,0 +1,47 @@
+/* Test of link() function.
+ Copyright (C) 2009-2011 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/test-link.h b/tests/test-link.h
new file mode 100644
index 0000000..5898285
--- /dev/null
+++ b/tests/test-link.h
@@ -0,0 +1,176 @@
+/* Test of link() function.
+ Copyright (C) 2009-2011 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/test-linkedhash_list.c b/tests/test-linkedhash_list.c
new file mode 100644
index 0000000..b462ca6
--- /dev/null
+++ b/tests/test-linkedhash_list.c
@@ -0,0 +1,441 @@
+/* Test of sequential list data type implementation.
+ Copyright (C) 2006-2011 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/test-locale-c++.cc b/tests/test-locale-c++.cc
new file mode 100644
index 0000000..06b9a32
--- /dev/null
+++ b/tests/test-locale-c++.cc
@@ -0,0 +1,39 @@
+/* Test of <locale.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <locale.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_SETLOCALE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::setlocale, char *, (int, const char *));
+#endif
+
+#if GNULIB_TEST_DUPLOCALE && HAVE_DUPLOCALE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::duplocale, locale_t, (locale_t));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-locale-c++2.cc b/tests/test-locale-c++2.cc
new file mode 100644
index 0000000..cdc31e8
--- /dev/null
+++ b/tests/test-locale-c++2.cc
@@ -0,0 +1,20 @@
+/* Test of <locale.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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/>. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <clocale>
diff --git a/tests/test-locale.c b/tests/test-locale.c
new file mode 100644
index 0000000..9b55e37
--- /dev/null
+++ b/tests/test-locale.c
@@ -0,0 +1,49 @@
+/* Test of <locale.h> substitute.
+ Copyright (C) 2007, 2009-2011 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 <locale.h>
+
+#include "verify.h"
+
+int a[] =
+ {
+ LC_ALL,
+ LC_COLLATE,
+ LC_CTYPE,
+ LC_MESSAGES,
+ LC_MONETARY,
+ LC_NUMERIC,
+ LC_TIME
+ };
+
+#if HAVE_NEWLOCALE
+/* Check that the locale_t type and the LC_GLOBAL_LOCALE macro are defined. */
+locale_t b = LC_GLOBAL_LOCALE;
+#endif
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+int
+main ()
+{
+ return 0;
+}
diff --git a/tests/test-localename.c b/tests/test-localename.c
new file mode 100644
index 0000000..09f002c
--- /dev/null
+++ b/tests/test-localename.c
@@ -0,0 +1,747 @@
+/* Test of gl_locale_name function and its variants.
+ Copyright (C) 2007-2011 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 "localename.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+
+#if HAVE_NEWLOCALE
+
+static struct { int cat; int mask; const char *string; } const categories[] =
+ {
+ { LC_CTYPE, LC_CTYPE_MASK, "LC_CTYPE" },
+ { LC_NUMERIC, LC_NUMERIC_MASK, "LC_NUMERIC" },
+ { LC_TIME, LC_TIME_MASK, "LC_TIME" },
+ { LC_COLLATE, LC_COLLATE_MASK, "LC_COLLATE" },
+ { LC_MONETARY, LC_MONETARY_MASK, "LC_MONETARY" },
+ { LC_MESSAGES, LC_MESSAGES_MASK, "LC_MESSAGES" }
+# ifdef LC_PAPER
+ , { LC_PAPER, LC_PAPER_MASK, "LC_PAPER" }
+# endif
+# ifdef LC_NAME
+ , { LC_NAME, LC_NAME_MASK, "LC_NAME" }
+# endif
+# ifdef LC_ADDRESS
+ , { LC_ADDRESS, LC_ADDRESS_MASK, "LC_ADDRESS" }
+# endif
+# ifdef LC_TELEPHONE
+ , { LC_TELEPHONE, LC_TELEPHONE_MASK, "LC_TELEPHONE" }
+# endif
+# ifdef LC_MEASUREMENT
+ , { LC_MEASUREMENT, LC_MEASUREMENT_MASK, "LC_MEASUREMENT" }
+# endif
+# ifdef LC_IDENTIFICATION
+ , { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK, "LC_IDENTIFICATION" }
+# endif
+ };
+
+#endif
+
+/* Test the gl_locale_name() function. */
+static void
+test_locale_name (void)
+{
+ const char *name;
+
+ /* Check that gl_locale_name returns non-NULL. */
+ ASSERT (gl_locale_name (LC_MESSAGES, "LC_MESSAGES") != NULL);
+
+ /* Get into a defined state, */
+ setlocale (LC_ALL, "en_US.UTF-8");
+#if HAVE_NEWLOCALE
+ uselocale (LC_GLOBAL_LOCALE);
+#endif
+
+ /* Check that when all environment variables are unset,
+ gl_locale_name returns the default locale. */
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LC_NUMERIC");
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
+ gl_locale_name_default ()) == 0);
+ ASSERT (strcmp (gl_locale_name (LC_NUMERIC, "LC_NUMERIC"),
+ gl_locale_name_default ()) == 0);
+
+ /* Check that an empty environment variable is treated like an unset
+ environment variable. */
+
+ setenv ("LC_ALL", "", 1);
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
+ gl_locale_name_default ()) == 0);
+
+ unsetenv ("LC_ALL");
+ setenv ("LC_CTYPE", "", 1);
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
+ gl_locale_name_default ()) == 0);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "", 1);
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
+ gl_locale_name_default ()) == 0);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ setenv ("LANG", "", 1);
+ setlocale (LC_ALL, "");
+ ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
+ gl_locale_name_default ()) == 0);
+
+ /* Check that LC_ALL overrides the others, and LANG is overridden by the
+ others. */
+
+ setenv ("LC_ALL", "C", 1);
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
+
+ unsetenv ("LC_ALL");
+ setenv ("LC_CTYPE", "C", 1);
+ setenv ("LC_MESSAGES", "C", 1);
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ setenv ("LANG", "C", 1);
+ setlocale (LC_ALL, "");
+ ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
+
+ /* Check mixed situations. */
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
+ setenv ("LANG", "de_DE.UTF-8", 1);
+ if (setlocale (LC_ALL, "") != NULL)
+ {
+ name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
+ ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
+ name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+ }
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
+ unsetenv ("LANG");
+ if (setlocale (LC_ALL, "") != NULL)
+ {
+ name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
+ ASSERT (strcmp (name, gl_locale_name_default ()) == 0);
+ name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+ }
+
+#if HAVE_NEWLOCALE
+ /* Check that gl_locale_name considers the thread locale. */
+ {
+ locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
+ if (locale != NULL)
+ {
+ uselocale (locale);
+ name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+ name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+ }
+ }
+
+ /* Check that gl_locale_name distinguishes different categories of the
+ thread locale, and that the name is the right one for each. */
+ {
+ unsigned int i;
+
+ for (i = 0; i < SIZEOF (categories); i++)
+ {
+ int category_mask = categories[i].mask;
+ locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
+ if (locale != NULL)
+ {
+ locale = newlocale (category_mask, "de_DE.UTF-8", locale);
+ if (locale != NULL)
+ {
+ unsigned int j;
+
+ uselocale (locale);
+ for (j = 0; j < SIZEOF (categories); j++)
+ {
+ const char *name_j =
+ gl_locale_name (categories[j].cat, categories[j].string);
+ if (j == i)
+ ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
+ else
+ ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+/* Test the gl_locale_name_thread() function. */
+static void
+test_locale_name_thread (void)
+{
+ /* Get into a defined state, */
+ setlocale (LC_ALL, "en_US.UTF-8");
+
+#if HAVE_NEWLOCALE
+ /* Check that gl_locale_name_thread returns NULL when no thread locale is
+ set. */
+ uselocale (LC_GLOBAL_LOCALE);
+ ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
+ ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
+
+ /* Check that gl_locale_name_thread considers the thread locale. */
+ {
+ locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
+ if (locale != NULL)
+ {
+ const char *name;
+
+ uselocale (locale);
+ name = gl_locale_name_thread (LC_CTYPE, "LC_CTYPE");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+ name = gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+ }
+ }
+
+ /* Check that gl_locale_name_thread distinguishes different categories of the
+ thread locale, and that the name is the right one for each. */
+ {
+ unsigned int i;
+
+ for (i = 0; i < SIZEOF (categories); i++)
+ {
+ int category_mask = categories[i].mask;
+ locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
+ if (locale != NULL)
+ {
+ locale = newlocale (category_mask, "de_DE.UTF-8", locale);
+ if (locale != NULL)
+ {
+ unsigned int j;
+
+ uselocale (locale);
+ for (j = 0; j < SIZEOF (categories); j++)
+ {
+ const char *name_j =
+ gl_locale_name_thread (categories[j].cat,
+ categories[j].string);
+ if (j == i)
+ ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0);
+ else
+ ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0);
+ }
+ }
+ }
+ }
+ }
+
+ /* Check that gl_locale_name_thread returns a string that is allocated with
+ indefinite extent. */
+ {
+ /* Try many locale names in turn, in order to defeat possible caches. */
+ static const char * const choices[] =
+ {
+ "C",
+ "POSIX",
+ "af_ZA",
+ "af_ZA.UTF-8",
+ "am_ET",
+ "am_ET.UTF-8",
+ "be_BY",
+ "be_BY.UTF-8",
+ "bg_BG",
+ "bg_BG.UTF-8",
+ "ca_ES",
+ "ca_ES.UTF-8",
+ "cs_CZ",
+ "cs_CZ.UTF-8",
+ "da_DK",
+ "da_DK.UTF-8",
+ "de_AT",
+ "de_AT.UTF-8",
+ "de_CH",
+ "de_CH.UTF-8",
+ "de_DE",
+ "de_DE.UTF-8",
+ "el_GR",
+ "el_GR.UTF-8",
+ "en_AU",
+ "en_AU.UTF-8",
+ "en_CA",
+ "en_CA.UTF-8",
+ "en_GB",
+ "en_GB.UTF-8",
+ "en_IE",
+ "en_IE.UTF-8",
+ "en_NZ",
+ "en_NZ.UTF-8",
+ "en_US",
+ "en_US.UTF-8",
+ "es_ES",
+ "es_ES.UTF-8",
+ "et_EE",
+ "et_EE.UTF-8",
+ "eu_ES",
+ "eu_ES.UTF-8",
+ "fi_FI",
+ "fi_FI.UTF-8",
+ "fr_BE",
+ "fr_BE.UTF-8",
+ "fr_CA",
+ "fr_CA.UTF-8",
+ "fr_CH",
+ "fr_CH.UTF-8",
+ "fr_FR",
+ "fr_FR.UTF-8",
+ "he_IL",
+ "he_IL.UTF-8",
+ "hr_HR",
+ "hr_HR.UTF-8",
+ "hu_HU",
+ "hu_HU.UTF-8",
+ "hy_AM",
+ "is_IS",
+ "is_IS.UTF-8",
+ "it_CH",
+ "it_CH.UTF-8",
+ "it_IT",
+ "it_IT.UTF-8",
+ "ja_JP.UTF-8",
+ "kk_KZ",
+ "kk_KZ.UTF-8",
+ "ko_KR.UTF-8",
+ "lt_LT",
+ "lt_LT.UTF-8",
+ "nl_BE",
+ "nl_BE.UTF-8",
+ "nl_NL",
+ "nl_NL.UTF-8",
+ "no_NO",
+ "no_NO.UTF-8",
+ "pl_PL",
+ "pl_PL.UTF-8",
+ "pt_BR",
+ "pt_BR.UTF-8",
+ "pt_PT",
+ "pt_PT.UTF-8",
+ "ro_RO",
+ "ro_RO.UTF-8",
+ "ru_RU",
+ "ru_RU.UTF-8",
+ "sk_SK",
+ "sk_SK.UTF-8",
+ "sl_SI",
+ "sl_SI.UTF-8",
+ "sv_SE",
+ "sv_SE.UTF-8",
+ "tr_TR",
+ "tr_TR.UTF-8",
+ "uk_UA",
+ "uk_UA.UTF-8",
+ "zh_CN",
+ "zh_CN.UTF-8",
+ "zh_HK",
+ "zh_HK.UTF-8",
+ "zh_TW",
+ "zh_TW.UTF-8"
+ };
+ /* Remember which locales are available. */
+ unsigned char /* bool */ available[SIZEOF (choices)];
+ /* Array of remembered results of gl_locale_name_thread. */
+ const char *unsaved_names[SIZEOF (choices)][SIZEOF (categories)];
+ /* Array of remembered results of gl_locale_name_thread, stored in safe
+ memory. */
+ char *saved_names[SIZEOF (choices)][SIZEOF (categories)];
+ unsigned int j;
+
+ for (j = 0; j < SIZEOF (choices); j++)
+ {
+ locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
+ available[j] = (locale != NULL);
+ if (locale != NULL)
+ {
+ unsigned int i;
+
+ uselocale (locale);
+ for (i = 0; i < SIZEOF (categories); i++)
+ {
+ unsaved_names[j][i] = gl_locale_name_thread (categories[i].cat, categories[i].string);
+ saved_names[j][i] = strdup (unsaved_names[j][i]);
+ }
+ uselocale (LC_GLOBAL_LOCALE);
+ freelocale (locale);
+ }
+ }
+ /* Verify the unsaved_names are still valid. */
+ for (j = 0; j < SIZEOF (choices); j++)
+ if (available[j])
+ {
+ unsigned int i;
+
+ for (i = 0; i < SIZEOF (categories); i++)
+ ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
+ }
+ /* Allocate many locales, without freeing them. This is an attempt at
+ overwriting as much of the previously allocated memory as possible. */
+ for (j = SIZEOF (choices); j > 0; )
+ {
+ j--;
+ if (available[j])
+ {
+ locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL);
+ unsigned int i;
+
+ ASSERT (locale != NULL);
+ uselocale (locale);
+ for (i = 0; i < SIZEOF (categories); i++)
+ {
+ const char *name = gl_locale_name_thread (categories[i].cat, categories[i].string);
+ ASSERT (strcmp (unsaved_names[j][i], name) == 0);
+ }
+ uselocale (LC_GLOBAL_LOCALE);
+ }
+ }
+ /* Verify the unsaved_names are still valid. */
+ for (j = 0; j < SIZEOF (choices); j++)
+ if (available[j])
+ {
+ unsigned int i;
+
+ for (i = 0; i < SIZEOF (categories); i++)
+ ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
+ }
+ }
+#else
+ /* Check that gl_locale_name_thread always returns NULL. */
+ ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
+ ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
+#endif
+}
+
+/* Test the gl_locale_name_posix() function. */
+static void
+test_locale_name_posix (void)
+{
+ const char *name;
+
+ /* Get into a defined state, */
+ setlocale (LC_ALL, "en_US.UTF-8");
+#if HAVE_NEWLOCALE
+ uselocale (LC_GLOBAL_LOCALE);
+#endif
+
+ /* Check that when all environment variables are unset,
+ gl_locale_name_posix returns either NULL or the default locale. */
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LC_NUMERIC");
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+ name = gl_locale_name_posix (LC_NUMERIC, "LC_NUMERIC");
+ ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+
+ /* Check that an empty environment variable is treated like an unset
+ environment variable. */
+
+ setenv ("LC_ALL", "", 1);
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+
+ unsetenv ("LC_ALL");
+ setenv ("LC_CTYPE", "", 1);
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "", 1);
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ setenv ("LANG", "", 1);
+ setlocale (LC_ALL, "");
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+
+ /* Check that LC_ALL overrides the others, and LANG is overridden by the
+ others. */
+
+ setenv ("LC_ALL", "C", 1);
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "C") == 0);
+
+ unsetenv ("LC_ALL");
+ setenv ("LC_CTYPE", "C", 1);
+ setenv ("LC_MESSAGES", "C", 1);
+ unsetenv ("LANG");
+ setlocale (LC_ALL, "");
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "C") == 0);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ setenv ("LANG", "C", 1);
+ setlocale (LC_ALL, "");
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "C") == 0);
+
+ /* Check mixed situations. */
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
+ setenv ("LANG", "de_DE.UTF-8", 1);
+ if (setlocale (LC_ALL, "") != NULL)
+ {
+ name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
+ ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+ }
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
+ unsetenv ("LANG");
+ if (setlocale (LC_ALL, "") != NULL)
+ {
+ name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
+ ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+ }
+
+#if HAVE_NEWLOCALE
+ /* Check that gl_locale_name_posix ignores the thread locale. */
+ {
+ locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
+ if (locale != NULL)
+ {
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ setenv ("LANG", "C", 1);
+ setlocale (LC_ALL, "");
+ uselocale (locale);
+ name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "C") == 0);
+ }
+ }
+#endif
+}
+
+/* Test the gl_locale_name_environ() function. */
+static void
+test_locale_name_environ (void)
+{
+ const char *name;
+
+ /* Get into a defined state, */
+ setlocale (LC_ALL, "en_US.UTF-8");
+#if HAVE_NEWLOCALE
+ uselocale (LC_GLOBAL_LOCALE);
+#endif
+
+ /* Check that when all environment variables are unset,
+ gl_locale_name_environ returns NULL. */
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LC_NUMERIC");
+ unsetenv ("LANG");
+ ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
+ ASSERT (gl_locale_name_environ (LC_NUMERIC, "LC_NUMERIC") == NULL);
+
+ /* Check that an empty environment variable is treated like an unset
+ environment variable. */
+
+ setenv ("LC_ALL", "", 1);
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
+
+ unsetenv ("LC_ALL");
+ setenv ("LC_CTYPE", "", 1);
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "", 1);
+ unsetenv ("LANG");
+ ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ setenv ("LANG", "", 1);
+ ASSERT (gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES") == NULL);
+
+ /* Check that LC_ALL overrides the others, and LANG is overridden by the
+ others. */
+
+ setenv ("LC_ALL", "C", 1);
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ unsetenv ("LANG");
+ name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "C") == 0);
+
+ unsetenv ("LC_ALL");
+ setenv ("LC_CTYPE", "C", 1);
+ setenv ("LC_MESSAGES", "C", 1);
+ unsetenv ("LANG");
+ name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "C") == 0);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ setenv ("LANG", "C", 1);
+ name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "C") == 0);
+
+ /* Check mixed situations. */
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
+ setenv ("LANG", "de_DE.UTF-8", 1);
+ name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
+ ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
+ name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
+ unsetenv ("LANG");
+ name = gl_locale_name_environ (LC_CTYPE, "LC_CTYPE");
+ ASSERT (name == NULL);
+ name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
+
+#if HAVE_NEWLOCALE
+ /* Check that gl_locale_name_environ ignores the thread locale. */
+ {
+ locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
+ if (locale != NULL)
+ {
+ unsetenv ("LC_ALL");
+ unsetenv ("LC_CTYPE");
+ unsetenv ("LC_MESSAGES");
+ setenv ("LANG", "C", 1);
+ setlocale (LC_ALL, "");
+ uselocale (locale);
+ name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
+ ASSERT (strcmp (name, "C") == 0);
+ }
+ }
+#endif
+}
+
+/* Test the gl_locale_name_default() function. */
+static void
+test_locale_name_default (void)
+{
+ const char *name = gl_locale_name_default ();
+
+ ASSERT (name != NULL);
+
+ /* Only MacOS X and Windows have a facility for the user to set the default
+ locale. */
+#if !((defined __APPLE__ && defined __MACH__) || (defined _WIN32 || defined __WIN32__ || defined __CYGWIN__))
+ ASSERT (strcmp (name, "C") == 0);
+#endif
+
+#if HAVE_NEWLOCALE
+ /* Check that gl_locale_name_default ignores the thread locale. */
+ {
+ locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
+ if (locale != NULL)
+ {
+ uselocale (locale);
+ ASSERT (strcmp (gl_locale_name_default (), name) == 0);
+ }
+ }
+#endif
+}
+
+int
+main ()
+{
+ test_locale_name ();
+ test_locale_name_thread ();
+ test_locale_name_posix ();
+ test_locale_name_environ ();
+ test_locale_name_default ();
+
+ return 0;
+}
diff --git a/tests/test-lseek.c b/tests/test-lseek.c
new file mode 100644
index 0000000..ce2263c
--- /dev/null
+++ b/tests/test-lseek.c
@@ -0,0 +1,96 @@
+/* Test of lseek() function.
+ Copyright (C) 2007-2011 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/test-lseek.sh b/tests/test-lseek.sh
new file mode 100755
index 0000000..47237b5
--- /dev/null
+++ b/tests/test-lseek.sh
@@ -0,0 +1,18 @@
+#!/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; echo $? > t-lseek.tmp; cat > /dev/null; } | cat
+test "`cat t-lseek.tmp`" = "0" || exit 1
+
+# closed descriptors
+./test-lseek${EXEEXT} 2 <&- >&- || exit 1
+
+rm -rf $tmpfiles
+exit 0
diff --git a/tests/test-lstat.c b/tests/test-lstat.c
new file mode 100644
index 0000000..372e056
--- /dev/null
+++ b/tests/test-lstat.c
@@ -0,0 +1,60 @@
+/* Test of lstat() function.
+ Copyright (C) 2008-2011 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/test-lstat.h b/tests/test-lstat.h
new file mode 100644
index 0000000..883c4e8
--- /dev/null
+++ b/tests/test-lstat.h
@@ -0,0 +1,116 @@
+/* Test of lstat() function.
+ Copyright (C) 2008-2011 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/test-malloc-gnu.c b/tests/test-malloc-gnu.c
new file mode 100644
index 0000000..c2a3d6b
--- /dev/null
+++ b/tests/test-malloc-gnu.c
@@ -0,0 +1,29 @@
+/* Test of malloc function.
+ Copyright (C) 2010-2011 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 <stdlib.h>
+
+int
+main ()
+{
+ /* Check that malloc (0) is not a NULL pointer. */
+ if (malloc (0) == NULL)
+ return 1;
+
+ return 0;
+}
diff --git a/tests/test-malloca.c b/tests/test-malloca.c
new file mode 100644
index 0000000..92c86f2
--- /dev/null
+++ b/tests/test-malloca.c
@@ -0,0 +1,62 @@
+/* Test of safe automatic memory allocation.
+ Copyright (C) 2005, 2007, 2009-2011 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);
+ safe_alloca (n);
+}
+
+void (*func) (int) = do_allocation;
+
+int
+main ()
+{
+ int i;
+
+ /* This slows down malloc a lot. */
+ unsetenv ("MALLOC_PERTURB_");
+
+ /* 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/test-math-c++.cc b/tests/test-math-c++.cc
new file mode 100644
index 0000000..2a3acff
--- /dev/null
+++ b/tests/test-math-c++.cc
@@ -0,0 +1,163 @@
+/* Test of <math.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <math.h>
+
+#include "signature.h"
+
+
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::acos, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::asin, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::atan, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::atan2, double, (double, double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::cbrt, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::copysign, double, (double, double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::cos, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::cosh, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::erf, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::erfc, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::exp, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::fabs, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::fmod, double, (double, double));
+#if GNULIB_TEST_FREXP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::frexp, double, (double, int *));
+#endif
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::hypot, double, (double, double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::j0, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::j1, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::jn, double, (int, double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::ldexp, double, (double, int));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::lgamma, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::log10, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::log1p, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::logb, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::log, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::modf, double, (double, double *));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::nextafter, double, (double, double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::pow, double, (double, double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::remainder, double, (double, double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::rint, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::sin, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::sinh, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::sqrt, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::tan, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::tanh, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::y0, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::y1, double, (double));
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::yn, double, (int, double));
+
+#if GNULIB_TEST_ACOSL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::acosl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_ASINL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::asinl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_ATANL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::atanl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_CEILF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ceilf, float, (float));
+#endif
+
+#if GNULIB_TEST_CEIL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ceil, double, (double));
+#endif
+
+#if GNULIB_TEST_CEILL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ceill, long double, (long double));
+#endif
+
+#if GNULIB_TEST_COSL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::cosl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_EXPL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::expl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_FLOORF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::floorf, float, (float));
+#endif
+
+#if GNULIB_TEST_FLOOR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::floor, double, (double));
+#endif
+
+#if GNULIB_TEST_FLOORL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::floorl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_FREXPL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::frexpl, long double, (long double, int *));
+#endif
+
+#if GNULIB_TEST_LDEXPL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ldexpl, long double, (long double, int));
+#endif
+
+#if GNULIB_TEST_LOGL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::logl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_ROUNDF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::roundf, float, (float));
+#endif
+
+#if GNULIB_TEST_ROUND
+SIGNATURE_CHECK (GNULIB_NAMESPACE::round, double, (double));
+#endif
+
+#if GNULIB_TEST_ROUNDL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::roundl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_SINL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sinl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_SQRTL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sqrtl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_TANL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::tanl, long double, (long double));
+#endif
+
+#if GNULIB_TEST_TRUNCF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::truncf, float, (float));
+#endif
+
+#if GNULIB_TEST_TRUNC
+SIGNATURE_CHECK (GNULIB_NAMESPACE::trunc, double, (double));
+#endif
+
+#if GNULIB_TEST_TRUNCL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::truncl, long double, (long double));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-math-c++2.cc b/tests/test-math-c++2.cc
new file mode 100644
index 0000000..1ab022f
--- /dev/null
+++ b/tests/test-math-c++2.cc
@@ -0,0 +1,20 @@
+/* Test of <math.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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/>. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <cmath>
diff --git a/tests/test-math.c b/tests/test-math.c
new file mode 100644
index 0000000..8565925
--- /dev/null
+++ b/tests/test-math.c
@@ -0,0 +1,53 @@
+/* Test of <math.h> substitute.
+ Copyright (C) 2007-2011 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/test-mbrtowc-w32-1.sh b/tests/test-mbrtowc-w32-1.sh
new file mode 100755
index 0000000..3f12e44
--- /dev/null
+++ b/tests/test-mbrtowc-w32-1.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP1252 locale.
+./test-mbrtowc-w32${EXEEXT} French_France 1252
diff --git a/tests/test-mbrtowc-w32-2.sh b/tests/test-mbrtowc-w32-2.sh
new file mode 100755
index 0000000..9e1a765
--- /dev/null
+++ b/tests/test-mbrtowc-w32-2.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP1256 locale.
+./test-mbrtowc-w32${EXEEXT} "Arabic_Saudi Arabia" 1256
diff --git a/tests/test-mbrtowc-w32-3.sh b/tests/test-mbrtowc-w32-3.sh
new file mode 100755
index 0000000..782c2d0
--- /dev/null
+++ b/tests/test-mbrtowc-w32-3.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP932 locale.
+./test-mbrtowc-w32${EXEEXT} Japanese_Japan 932
diff --git a/tests/test-mbrtowc-w32-4.sh b/tests/test-mbrtowc-w32-4.sh
new file mode 100755
index 0000000..0630f30
--- /dev/null
+++ b/tests/test-mbrtowc-w32-4.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP950 locale.
+./test-mbrtowc-w32${EXEEXT} Chinese_Taiwan 950
diff --git a/tests/test-mbrtowc-w32-5.sh b/tests/test-mbrtowc-w32-5.sh
new file mode 100755
index 0000000..7d7faa9
--- /dev/null
+++ b/tests/test-mbrtowc-w32-5.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP936 locale.
+./test-mbrtowc-w32${EXEEXT} Chinese_China 936
diff --git a/tests/test-mbrtowc-w32.c b/tests/test-mbrtowc-w32.c
new file mode 100644
index 0000000..ee8caf9
--- /dev/null
+++ b/tests/test-mbrtowc-w32.c
@@ -0,0 +1,735 @@
+/* Test of conversion of multibyte character to wide character.
+ Copyright (C) 2008-2011 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 <wchar.h>
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
+
+static int
+test_one_locale (const char *name, int codepage)
+{
+ mbstate_t state;
+ wchar_t wc;
+ size_t ret;
+
+# if 1
+ /* Portable code to set the locale. */
+ {
+ char name_with_codepage[1024];
+
+ sprintf (name_with_codepage, "%s.%d", name, codepage);
+
+ /* Set the locale. */
+ if (setlocale (LC_ALL, name_with_codepage) == NULL)
+ return 77;
+ }
+# else
+ /* Hacky way to set a locale.codepage combination that setlocale() refuses
+ to set. */
+ {
+ /* Codepage of the current locale, set with setlocale().
+ Not necessarily the same as GetACP(). */
+ extern __declspec(dllimport) unsigned int __lc_codepage;
+
+ /* Set the locale. */
+ if (setlocale (LC_ALL, name) == NULL)
+ return 77;
+
+ /* Clobber the codepage and MB_CUR_MAX, both set by setlocale(). */
+ __lc_codepage = codepage;
+ switch (codepage)
+ {
+ case 1252:
+ case 1256:
+ MB_CUR_MAX = 1;
+ break;
+ case 932:
+ case 950:
+ case 936:
+ MB_CUR_MAX = 2;
+ break;
+ case 54936:
+ case 65001:
+ MB_CUR_MAX = 4;
+ break;
+ }
+
+ /* Test whether the codepage is really available. */
+ memset (&state, '\0', sizeof (mbstate_t));
+ if (mbrtowc (&wc, " ", 1, &state) == (size_t)(-1))
+ return 77;
+ }
+# endif
+
+ /* 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));
+ }
+
+ switch (codepage)
+ {
+ case 1252:
+ /* Locale encoding is CP1252, an extension of ISO-8859-1. */
+ {
+ 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 (wc == 0x00FC);
+ ASSERT (mbsinit (&state));
+ input[1] = '\0';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 2, 3, &state);
+ ASSERT (ret == 1);
+ ASSERT (mbsinit (&state));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 2, 3, &state);
+ ASSERT (ret == 1);
+ ASSERT (wctob (wc) == (unsigned char) '\337');
+ ASSERT (wc == 0x00DF);
+ 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 1256:
+ /* Locale encoding is CP1256, not the same as ISO-8859-6. */
+ {
+ char input[] = "x\302\341\346y"; /* "xآلوy" */
+ memset (&state, '\0', sizeof (mbstate_t));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'x');
+ 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) '\302');
+ ASSERT (wc == 0x0622);
+ ASSERT (mbsinit (&state));
+ input[1] = '\0';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 2, 3, &state);
+ ASSERT (ret == 1);
+ ASSERT (mbsinit (&state));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 2, 3, &state);
+ ASSERT (ret == 1);
+ ASSERT (wctob (wc) == (unsigned char) '\341');
+ ASSERT (wc == 0x0644);
+ ASSERT (mbsinit (&state));
+ input[2] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 3, 2, &state);
+ ASSERT (ret == 1);
+ ASSERT (wctob (wc) == (unsigned char) '\346');
+ ASSERT (wc == 0x0648);
+ ASSERT (mbsinit (&state));
+ input[3] = '\0';
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 4, 1, &state);
+ ASSERT (ret == 1);
+ ASSERT (wc == 'y');
+ ASSERT (mbsinit (&state));
+ }
+ return 0;
+
+ case 932:
+ /* Locale encoding is CP932, similar to Shift_JIS. */
+ {
+ char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */
+ 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 (wc == 0x65E5);
+ 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 (wc == 0x672C);
+ ASSERT (mbsinit (&state));
+ input[4] = '\0';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 5, 3, &state);
+ ASSERT (ret == 2);
+ ASSERT (mbsinit (&state));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 5, 3, &state);
+ ASSERT (ret == 2);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (wc == 0x8A9E);
+ 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));
+
+ /* Test some invalid input. */
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+ }
+ return 0;
+
+ case 950:
+ /* Locale encoding is CP950, similar to Big5. */
+ {
+ char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */
+ 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 (wc == 0x65E5);
+ 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 (wc == 0x672C);
+ ASSERT (mbsinit (&state));
+ input[4] = '\0';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 5, 3, &state);
+ ASSERT (ret == 2);
+ ASSERT (mbsinit (&state));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 5, 3, &state);
+ ASSERT (ret == 2);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (wc == 0x8A9E);
+ 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));
+
+ /* Test some invalid input. */
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+ }
+ return 0;
+
+ case 936:
+ /* Locale encoding is CP936 = GBK, an extension of GB2312. */
+ {
+ char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */
+ 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 (wc == 0x65E5);
+ 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 (wc == 0x672C);
+ ASSERT (mbsinit (&state));
+ input[4] = '\0';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 5, 3, &state);
+ ASSERT (ret == 2);
+ ASSERT (mbsinit (&state));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 5, 3, &state);
+ ASSERT (ret == 2);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (wc == 0x8A9E);
+ 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));
+
+ /* Test some invalid input. */
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+ }
+ return 0;
+
+ case 54936:
+ /* Locale encoding is CP54936 = 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 (wc == 0x00FC);
+ ASSERT (mbsinit (&state));
+ input[2] = '\0';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 3, 6, &state);
+ ASSERT (ret == 4);
+ ASSERT (mbsinit (&state));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 3, 6, &state);
+ ASSERT (ret == 4);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (wc == 0x00DF);
+ 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));
+
+ /* Test some invalid input. */
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\201\045", 2, &state); /* 0x81 0x25 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\201\060\377", 3, &state); /* 0x81 0x30 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\201\060\377\064", 4, &state); /* 0x81 0x30 0xFF 0x34 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\201\060\211\072", 4, &state); /* 0x81 0x30 0x89 0x3A */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+ }
+ return 0;
+
+ case 65001:
+ /* Locale encoding is CP65001 = 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 (wc == 0x00FC);
+ ASSERT (mbsinit (&state));
+ input[2] = '\0';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 3, 4, &state);
+ ASSERT (ret == 2);
+ ASSERT (mbsinit (&state));
+
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, input + 3, 4, &state);
+ ASSERT (ret == 2);
+ ASSERT (wctob (wc) == EOF);
+ ASSERT (wc == 0x00DF);
+ 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));
+
+ /* Test some invalid input. */
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\303\300", 2, &state); /* 0xC3 0xC0 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\343\300", 2, &state); /* 0xE3 0xC0 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\343\300\200", 3, &state); /* 0xE3 0xC0 0x80 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\343\200\300", 3, &state); /* 0xE3 0x80 0xC0 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\363\300", 2, &state); /* 0xF3 0xC0 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\363\300\200\200", 4, &state); /* 0xF3 0xC0 0x80 0x80 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\363\200\300", 3, &state); /* 0xF3 0x80 0xC0 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\363\200\300\200", 4, &state); /* 0xF3 0x80 0xC0 0x80 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ wc = (wchar_t) 0xBADFACE;
+ ret = mbrtowc (&wc, "\363\200\200\300", 4, &state); /* 0xF3 0x80 0x80 0xC0 */
+ ASSERT (ret == (size_t)-1);
+ ASSERT (errno == EILSEQ);
+ }
+ return 0;
+
+ default:
+ return 1;
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int codepage = atoi (argv[argc - 1]);
+ int result;
+ int i;
+
+ result = 77;
+ for (i = 1; i < argc - 1; i++)
+ {
+ int ret = test_one_locale (argv[i], codepage);
+
+ if (ret != 77)
+ result = ret;
+ }
+
+ if (result == 77)
+ {
+ fprintf (stderr, "Skipping test: found no locale with codepage %d\n",
+ codepage);
+ }
+ return result;
+}
+
+#else
+
+int
+main (int argc, char *argv[])
+{
+ fputs ("Skipping test: not a native Windows system\n", stderr);
+ return 77;
+}
+
+#endif
diff --git a/tests/test-mbrtowc.c b/tests/test-mbrtowc.c
new file mode 100644
index 0000000..727016a
--- /dev/null
+++ b/tests/test-mbrtowc.c
@@ -0,0 +1,343 @@
+/* Test of conversion of multibyte character to wide character.
+ Copyright (C) 2008-2011 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';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 2, 3, &state);
+ ASSERT (ret == 1);
+ ASSERT (mbsinit (&state));
+
+ 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';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 3, 4, &state);
+ ASSERT (ret == 2);
+ ASSERT (mbsinit (&state));
+
+ 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';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 5, 3, &state);
+ ASSERT (ret == 2);
+ ASSERT (mbsinit (&state));
+
+ 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';
+
+ /* Test support of NULL first argument. */
+ ret = mbrtowc (NULL, input + 3, 6, &state);
+ ASSERT (ret == 4);
+ ASSERT (mbsinit (&state));
+
+ 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/test-mbrtowc1.sh b/tests/test-mbrtowc1.sh
new file mode 100755
index 0000000..3becba3
--- /dev/null
+++ b/tests/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/test-mbrtowc2.sh b/tests/test-mbrtowc2.sh
new file mode 100755
index 0000000..0405aba
--- /dev/null
+++ b/tests/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/test-mbrtowc3.sh b/tests/test-mbrtowc3.sh
new file mode 100755
index 0000000..63a89a2
--- /dev/null
+++ b/tests/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/test-mbrtowc4.sh b/tests/test-mbrtowc4.sh
new file mode 100755
index 0000000..b299a2c
--- /dev/null
+++ b/tests/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/test-mbsinit.c b/tests/test-mbsinit.c
new file mode 100644
index 0000000..2cc2924
--- /dev/null
+++ b/tests/test-mbsinit.c
@@ -0,0 +1,55 @@
+/* Test of test for initial conversion state.
+ Copyright (C) 2008-2011 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 (NULL));
+
+ 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/test-mbsinit.sh b/tests/test-mbsinit.sh
new file mode 100755
index 0000000..bbda48d
--- /dev/null
+++ b/tests/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/test-memchr.c b/tests/test-memchr.c
new file mode 100644
index 0000000..a11f6cd
--- /dev/null
+++ b/tests/test-memchr.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2008-2011 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 + 1, 0x789abc00 | '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>.
+ Test both '\0' and something else, since some implementations
+ special-case searching for NUL.
+ */
+ {
+ char *page_boundary = (char *) zerosize_ptr ();
+ /* Too small, and we miss cache line boundary tests; too large,
+ and the test takes cubically longer to complete. */
+ int limit = 257;
+
+ if (page_boundary != NULL)
+ {
+ for (n = 1; n <= limit; n++)
+ {
+ char *mem = page_boundary - n;
+ memset (mem, 'X', n);
+ ASSERT (MEMCHR (mem, 'U', n) == NULL);
+ ASSERT (MEMCHR (mem, 0, n) == NULL);
+
+ {
+ size_t i;
+ size_t k;
+
+ for (i = 0; i < n; i++)
+ {
+ mem[i] = 'U';
+ for (k = i + 1; k < n + limit; k++)
+ ASSERT (MEMCHR (mem, 'U', k) == mem + i);
+ mem[i] = 0;
+ for (k = i + 1; k < n + limit; k++)
+ ASSERT (MEMCHR (mem, 0, k) == mem + i);
+ mem[i] = 'X';
+ }
+ }
+ }
+ }
+ }
+
+ free (input);
+
+ return 0;
+}
diff --git a/tests/test-memchr2.c b/tests/test-memchr2.c
new file mode 100644
index 0000000..c94352f
--- /dev/null
+++ b/tests/test-memchr2.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008-2011 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/test-nl_langinfo.c b/tests/test-nl_langinfo.c
new file mode 100644
index 0000000..964ea8d
--- /dev/null
+++ b/tests/test-nl_langinfo.c
@@ -0,0 +1,126 @@
+/* Test of nl_langinfo replacement.
+ Copyright (C) 2009-2011 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"
+
+/* For GCC >= 4.3, silence the warnings
+ "comparison of unsigned expression >= 0 is always true"
+ in this file. */
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+# pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
+
+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) >= 0);
+#if !defined __NetBSD__
+ if (pass > 0)
+ ASSERT (strlen (currency) >= 1);
+#endif
+ }
+ /* 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/test-nl_langinfo.sh b/tests/test-nl_langinfo.sh
new file mode 100755
index 0000000..3168f42
--- /dev/null
+++ b/tests/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/test-open.c b/tests/test-open.c
new file mode 100644
index 0000000..3c5b2ab
--- /dev/null
+++ b/tests/test-open.c
@@ -0,0 +1,41 @@
+/* Test of opening a file descriptor.
+ Copyright (C) 2007-2011 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/test-open.h b/tests/test-open.h
new file mode 100644
index 0000000..3e5c5e1
--- /dev/null
+++ b/tests/test-open.h
@@ -0,0 +1,87 @@
+/* Test of opening a file descriptor.
+ Copyright (C) 2007-2011 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/test-pipe2.c b/tests/test-pipe2.c
new file mode 100644
index 0000000..ddfb819
--- /dev/null
+++ b/tests/test-pipe2.c
@@ -0,0 +1,145 @@
+/* Test of pipe2.
+ Copyright (C) 2009-2011 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 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 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]));
+ ASSERT (is_open (fd[1]));
+ 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/test-posix_spawn1.c b/tests/test-posix_spawn1.c
new file mode 100644
index 0000000..f0ba3bd
--- /dev/null
+++ b/tests/test-posix_spawn1.c
@@ -0,0 +1,166 @@
+/* Test of posix_spawn() function.
+ Copyright (C) 2008-2011 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/test-posix_spawn1.in.sh b/tests/test-posix_spawn1.in.sh
new file mode 100644
index 0000000..b370856
--- /dev/null
+++ b/tests/test-posix_spawn1.in.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Halle Potta"
diff --git a/tests/test-posix_spawn2.c b/tests/test-posix_spawn2.c
new file mode 100644
index 0000000..92f5d4a
--- /dev/null
+++ b/tests/test-posix_spawn2.c
@@ -0,0 +1,139 @@
+/* Test of posix_spawn() function.
+ Copyright (C) 2008-2011 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/test-posix_spawn2.in.sh b/tests/test-posix_spawn2.in.sh
new file mode 100644
index 0000000..29a9b28
--- /dev/null
+++ b/tests/test-posix_spawn2.in.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+read line
+test "$line" = "Halle Potta"
diff --git a/tests/test-printf-frexp.c b/tests/test-printf-frexp.c
new file mode 100644
index 0000000..d1b0d84
--- /dev/null
+++ b/tests/test-printf-frexp.c
@@ -0,0 +1,119 @@
+/* Test of splitting a double into fraction and mantissa.
+ Copyright (C) 2007-2011 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/test-printf-frexpl.c b/tests/test-printf-frexpl.c
new file mode 100644
index 0000000..4e9704f
--- /dev/null
+++ b/tests/test-printf-frexpl.c
@@ -0,0 +1,134 @@
+/* Test of splitting a 'long double' into fraction and mantissa.
+ Copyright (C) 2007-2011 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/test-quotearg-simple.c b/tests/test-quotearg-simple.c
new file mode 100644
index 0000000..4d9c87c
--- /dev/null
+++ b/tests/test-quotearg-simple.c
@@ -0,0 +1,294 @@
+/* Test of quotearg family of functions.
+ Copyright (C) 2008-2011 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 <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "progname.h"
+#include "macros.h"
+
+#include "test-quotearg.h"
+
+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 "\"" } }
+};
+
+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 "'\"" } }
+};
+
+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, (enum quoting_style) 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);
+ }
+
+ quotearg_free ();
+ return 0;
+}
diff --git a/tests/test-quotearg.h b/tests/test-quotearg.h
new file mode 100644
index 0000000..f2e9558
--- /dev/null
+++ b/tests/test-quotearg.h
@@ -0,0 +1,133 @@
+/* Test of quotearg family of functions.
+ Copyright (C) 2008-2011 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. */
+
+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 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;
+}
diff --git a/tests/test-rawmemchr.c b/tests/test-rawmemchr.c
new file mode 100644
index 0000000..be8feac
--- /dev/null
+++ b/tests/test-rawmemchr.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008-2011 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 "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 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 + 1, 0x789abc00 | '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);
+ }
+ }
+ }
+
+ /* Ensure that no unaligned oversized reads occur. */
+ {
+ char *page_boundary = (char *) zerosize_ptr ();
+ size_t i;
+
+ if (!page_boundary)
+ page_boundary = input + 4096;
+ memset (page_boundary - 512, '1', 511);
+ page_boundary[-1] = '2';
+ for (i = 1; i <= 512; i++)
+ ASSERT (RAWMEMCHR (page_boundary - i, (i * 0x01010100) | '2')
+ == page_boundary - 1);
+ }
+
+ free (input);
+
+ return 0;
+}
diff --git a/tests/test-readlink.c b/tests/test-readlink.c
new file mode 100644
index 0000000..3da5fbf
--- /dev/null
+++ b/tests/test-readlink.c
@@ -0,0 +1,48 @@
+/* Tests of readlink.
+ Copyright (C) 2009-2011 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/test-readlink.h b/tests/test-readlink.h
new file mode 100644
index 0000000..08d5662
--- /dev/null
+++ b/tests/test-readlink.h
@@ -0,0 +1,119 @@
+/* Tests of readlink.
+ Copyright (C) 2009-2011 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 || errno == EINVAL); /* AIX yields EINVAL */
+
+ /* 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 || errno == EINVAL); /* AIX yields EINVAL */
+ 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/test-rename.c b/tests/test-rename.c
new file mode 100644
index 0000000..5ac83ca
--- /dev/null
+++ b/tests/test-rename.c
@@ -0,0 +1,47 @@
+/* Test of rename() function.
+ Copyright (C) 2009-2011 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 <dirent.h>
+#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/test-rename.h b/tests/test-rename.h
new file mode 100644
index 0000000..64bab09
--- /dev/null
+++ b/tests/test-rename.h
@@ -0,0 +1,949 @@
+/* Test of rename() function.
+ Copyright (C) 2009-2011 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. */
+
+/* Tests whether a file, given by a file name without slashes, exists in
+ the current directory, by scanning the directory entries. */
+static bool
+dentry_exists (const char *filename)
+{
+ bool exists = false;
+ DIR *dir = opendir (".");
+
+ ASSERT (dir != NULL);
+ for (;;)
+ {
+ struct dirent *d = readdir (dir);
+ if (d == NULL)
+ break;
+ if (strcmp (d->d_name, filename) == 0)
+ {
+ exists = true;
+ break;
+ }
+ }
+ ASSERT (closedir (dir) == 0);
+ return exists;
+}
+
+/* Asserts that a specific file, given by a file name without slashes, does
+ not exist in the current directory. */
+static void
+assert_nonexistent (const char *filename)
+{
+ struct stat st;
+
+ /* The usual way to test the presence of a file is via stat() or lstat(). */
+ errno = 0;
+ if (stat (filename, &st) == -1)
+ ASSERT (errno == ENOENT);
+ else
+ {
+ /* But after renaming a directory over an empty directory on an NFS-
+ mounted file system, on Linux 2.6.18, for a period of 30 seconds the
+ old directory name is "present" according to stat() but "nonexistent"
+ according to dentry_exists(). */
+ ASSERT (!dentry_exists (filename));
+ /* Remove the old directory name, so that subsequent mkdir calls
+ succeed. */
+ (void) rmdir (filename);
+ }
+}
+
+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);
+
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+
+ /* Obvious errors. */
+
+ { /* Missing source. */
+ {
+ 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;
+ ASSERT (func (BASE "missing", BASE "missing/") == -1);
+ ASSERT (errno == ENOENT);
+ }
+ }
+ { /* Empty operand. */
+ {
+ errno = 0;
+ 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. */
+
+ { /* Trailing slash. */
+ {
+ errno = 0;
+ 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);
+ }
+ }
+ { /* Simple rename. */
+ ASSERT (func (BASE "file", BASE "file2") == 0);
+ 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);
+ }
+ /* Files present here:
+ {BASE}file2
+ {BASE}dir/
+ */
+ { /* Overwrite. */
+ ASSERT (close (creat (BASE "file", 0600)) == 0);
+ 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);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+
+ /* Directories. */
+
+ { /* Simple rename. */
+ {
+ ASSERT (func (BASE "dir", BASE "dir2/") == 0);
+ errno = 0;
+ ASSERT (stat (BASE "dir", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (stat (BASE "dir2", &st) == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir2/
+ */
+ {
+ ASSERT (func (BASE "dir2/", BASE "dir") == 0);
+ ASSERT (stat (BASE "dir", &st) == 0);
+ errno = 0;
+ ASSERT (stat (BASE "dir2", &st) == -1);
+ ASSERT (errno == ENOENT);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+ {
+ ASSERT (func (BASE "dir", BASE "dir2") == 0);
+ errno = 0;
+ ASSERT (stat (BASE "dir", &st) == -1);
+ ASSERT (errno == ENOENT);
+ ASSERT (stat (BASE "dir2", &st) == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir2/
+ */
+ { /* Empty onto empty. */
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir2/
+ */
+ ASSERT (func (BASE "dir2", BASE "dir") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+ ASSERT (mkdir (BASE "dir2", 0700) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir2/
+ */
+ ASSERT (func (BASE "dir2", BASE "dir/") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+ ASSERT (mkdir (BASE "dir2", 0700) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir2/
+ */
+ ASSERT (func (BASE "dir2/", BASE "dir") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+ ASSERT (mkdir (BASE "dir2", 0700) == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir2/
+ */
+ { /* Empty onto full. */
+ ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir/file
+ {BASE}dir2/
+ */
+ {
+ 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);
+ }
+ }
+ { /* Full onto empty. */
+ ASSERT (func (BASE "dir", BASE "dir2") == 0);
+ assert_nonexistent (BASE "dir");
+ ASSERT (stat (BASE "dir2/file", &st) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir2/
+ {BASE}dir2/file
+ */
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir2/
+ {BASE}dir2/file
+ */
+ {
+ 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);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir/file
+ */
+ ASSERT (mkdir (BASE "dir2", 0700) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir/file
+ {BASE}dir2/
+ */
+ {
+ ASSERT (func (BASE "dir", BASE "dir2/") == 0);
+ assert_nonexistent (BASE "dir");
+ ASSERT (stat (BASE "dir2/file", &st) == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir2/
+ {BASE}dir2/file
+ */
+ ASSERT (unlink (BASE "dir2/file") == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir2/
+ */
+ { /* Reject trailing dot. */
+ {
+ errno = 0;
+ ASSERT (func (BASE "dir2", BASE "dir/.") == -1);
+ ASSERT (errno == EINVAL || errno == ENOENT);
+ }
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir2/
+ */
+ {
+ 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 || errno == EEXIST);
+ }
+ ASSERT (rmdir (BASE "dir") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir2/
+ */
+ {
+ errno = 0;
+ ASSERT (func (BASE "dir2", BASE "dir/.//") == -1);
+ ASSERT (errno == EINVAL || errno == ENOENT);
+ }
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir2/
+ */
+ {
+ 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 || errno == EEXIST);
+ }
+ ASSERT (rmdir (BASE "dir2") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+ }
+ { /* Move into subdir. */
+ {
+ errno = 0;
+ 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);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir/sub/
+ */
+ {
+ 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);
+ }
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+
+ /* Mixing file and directory. */
+
+ {
+ { /* File onto dir. */
+ {
+ errno = 0;
+ 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);
+ }
+ }
+ { /* Dir onto file. */
+ {
+ errno = 0;
+ ASSERT (func (BASE "dir", BASE "file") == -1);
+ ASSERT (errno == ENOTDIR);
+ }
+ {
+ errno = 0;
+ ASSERT (func (BASE "dir/", BASE "file") == -1);
+ ASSERT (errno == ENOTDIR);
+ }
+ }
+ }
+
+ /* Hard links. */
+
+ { /* File onto self. */
+ ASSERT (func (BASE "file", BASE "file") == 0);
+ memset (&st, 0, sizeof st);
+ ASSERT (stat (BASE "file", &st) == 0);
+ ASSERT (st.st_size == 2);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+ { /* Empty dir onto self. */
+ ASSERT (func (BASE "dir", BASE "dir") == 0);
+ ASSERT (stat (BASE "dir", &st) == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+ ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ {BASE}dir/file
+ */
+ { /* Full dir onto self. */
+ ASSERT (func (BASE "dir", BASE "dir") == 0);
+ }
+ ASSERT (unlink (BASE "dir/file") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+ {
+ /* 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);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}file2 (hard link to file)
+ {BASE}dir/
+ */
+ { /* File onto hard link. */
+ ASSERT (func (BASE "file", BASE "file2") == 0);
+ 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);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}file2
+ {BASE}dir/
+ */
+ ASSERT (unlink (BASE "file2") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}dir/
+ */
+
+ /* 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;
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}dir/
+ */
+ { /* Simple rename. */
+ ASSERT (func (BASE "link1", BASE "link2") == 0);
+ 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));
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link2 -> {BASE}file
+ {BASE}dir/
+ */
+ { /* Overwrite. */
+ ASSERT (symlink (BASE "nowhere", BASE "link1") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}nowhere
+ {BASE}link2 -> {BASE}file
+ {BASE}dir/
+ */
+ {
+ 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);
+ }
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}dir/
+ */
+ { /* Symlink loop. */
+ ASSERT (symlink (BASE "link2", BASE "link2") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link2 -> {BASE}link2
+ {BASE}dir/
+ */
+ {
+ 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);
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link3 -> {BASE}link2
+ {BASE}dir/
+ */
+ ASSERT (unlink (BASE "link3") == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}dir/
+ */
+ { /* Dangling link. */
+ ASSERT (symlink (BASE "nowhere", BASE "link2") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link2 -> {BASE}nowhere
+ {BASE}dir/
+ */
+ {
+ 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);
+ }
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link3 -> {BASE}nowhere
+ {BASE}dir/
+ */
+ { /* Trailing slash on dangling. */
+ {
+ errno = 0;
+ 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);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link3 -> {BASE}nowhere
+ {BASE}dir/
+ */
+ { /* Trailing slash on link to file. */
+ {
+ errno = 0;
+ ASSERT (func (BASE "link1/", BASE "link2") == -1);
+ ASSERT (errno == ENOTDIR);
+ }
+ {
+ errno = 0;
+ ASSERT (func (BASE "link1", BASE "link3/") == -1);
+ ASSERT (errno == ENOENT || errno == ENOTDIR);
+ }
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link3 -> {BASE}nowhere
+ {BASE}dir/
+ */
+
+ /* Mixing symlink and file. */
+
+ { /* File onto link. */
+ ASSERT (close (creat (BASE "file2", 0600)) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}file2
+ {BASE}link1 -> {BASE}file
+ {BASE}link3 -> {BASE}nowhere
+ {BASE}dir/
+ */
+ {
+ 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));
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link3
+ {BASE}dir/
+ */
+ ASSERT (unlink (BASE "link3") == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}dir/
+ */
+ { /* Link onto file. */
+ ASSERT (symlink (BASE "nowhere", BASE "link2") == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link2 -> {BASE}nowhere
+ {BASE}dir/
+ */
+ ASSERT (close (creat (BASE "file2", 0600)) == 0);
+ /* Files present here:
+ {BASE}file
+ {BASE}file2
+ {BASE}link1 -> {BASE}file
+ {BASE}link2 -> {BASE}nowhere
+ {BASE}dir/
+ */
+ {
+ 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));
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}file2 -> {BASE}nowhere
+ {BASE}link1 -> {BASE}file
+ {BASE}dir/
+ */
+ ASSERT (unlink (BASE "file2") == 0);
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}dir/
+ */
+ { /* Trailing slash. */
+ {
+ errno = 0;
+ 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));
+ }
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}dir/
+ */
+
+ /* Mixing symlink and directory. */
+
+ { /* Directory onto link. */
+ {
+ 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;
+ ASSERT (func (BASE "dir", BASE "link1/") == -1);
+ ASSERT (errno == ENOTDIR);
+ }
+ }
+ { /* Link onto directory. */
+ {
+ 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 == 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));
+ }
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}dir/
+ */
+
+ /* 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);
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link2 -> {BASE}dir2
+ {BASE}dir/
+ */
+ 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));
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link2 -> {BASE}dir2
+ {BASE}dir2/
+ */
+ {
+ 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);
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link2 -> {BASE}dir
+ {BASE}dir/
+ */
+ 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 || errno == EISDIR);
+ }
+ 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));
+ }
+ }
+ /* Files present here:
+ {BASE}file
+ {BASE}link1 -> {BASE}file
+ {BASE}link2 -> {BASE}dir or {BASE}dir2
+ {BASE}dir/
+ */
+
+ /* 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/test-rmdir.c b/tests/test-rmdir.c
new file mode 100644
index 0000000..6957efe
--- /dev/null
+++ b/tests/test-rmdir.c
@@ -0,0 +1,47 @@
+/* Tests of rmdir.
+ Copyright (C) 2009-2011 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/test-rmdir.h b/tests/test-rmdir.h
new file mode 100644
index 0000000..757d030
--- /dev/null
+++ b/tests/test-rmdir.h
@@ -0,0 +1,101 @@
+/* Tests of rmdir.
+ Copyright (C) 2009-2011 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 || errno == EEXIST);
+ 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/test-sched.c b/tests/test-sched.c
new file mode 100644
index 0000000..8d0c8cd
--- /dev/null
+++ b/tests/test-sched.c
@@ -0,0 +1,38 @@
+/* Test of <sched.h> substitute.
+ Copyright (C) 2008-2011 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/test-setenv.c b/tests/test-setenv.c
new file mode 100644
index 0000000..50eb71b
--- /dev/null
+++ b/tests/test-setenv.c
@@ -0,0 +1,56 @@
+/* Tests of setenv.
+ Copyright (C) 2009-2011 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/test-setlocale1.c b/tests/test-setlocale1.c
new file mode 100644
index 0000000..ea7945c
--- /dev/null
+++ b/tests/test-setlocale1.c
@@ -0,0 +1,59 @@
+/* Test of setting the current locale.
+ Copyright (C) 2011 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 <locale.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (setlocale, char *, (int, const char *));
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+ char *name1;
+ char *name2;
+
+ /* Try to set the locale by implicitly looking at the LC_ALL environment
+ variable.
+ configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ name1 = strdup (setlocale (LC_ALL, NULL));
+
+ /* Reset the locale. */
+ if (setlocale (LC_ALL, "C") == NULL)
+ return 1;
+
+ /* Try to set the locale by explicitly looking at the LC_ALL environment
+ variable.
+ configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL)
+ return 1;
+
+ name2 = strdup (setlocale (LC_ALL, NULL));
+
+ /* Test that the two results are the same. */
+ ASSERT (strcmp (name1, name2) == 0);
+
+ return 0;
+}
diff --git a/tests/test-setlocale1.sh b/tests/test-setlocale1.sh
new file mode 100755
index 0000000..59a0532
--- /dev/null
+++ b/tests/test-setlocale1.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+: ${LOCALE_FR=fr_FR}
+: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
+: ${LOCALE_JA=ja_JP}
+: ${LOCALE_ZH_CN=zh_CN.GB18030}
+
+if test $LOCALE_FR = none && test $LOCALE_FR_UTF8 = none \
+ && test $LOCALE_JA = none && test $LOCALE_ZH_CN = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no locale for testing is installed"
+ else
+ echo "Skipping test: no locale for testing is supported"
+ fi
+ exit 77
+fi
+
+if test $LOCALE_FR != none; then
+ LC_ALL=$LOCALE_FR ./test-setlocale1${EXEEXT} || exit 1
+fi
+
+if test $LOCALE_FR_UTF8 != none; then
+ LC_ALL=$LOCALE_FR_UTF8 ./test-setlocale1${EXEEXT} || exit 1
+fi
+
+if test $LOCALE_JA != none; then
+ LC_ALL=$LOCALE_JA ./test-setlocale1${EXEEXT} || exit 1
+fi
+
+if test $LOCALE_ZH_CN != none; then
+ LC_ALL=$LOCALE_ZH_CN ./test-setlocale1${EXEEXT} || exit 1
+fi
+
+exit 0
diff --git a/tests/test-setlocale2.c b/tests/test-setlocale2.c
new file mode 100644
index 0000000..7bfc42a
--- /dev/null
+++ b/tests/test-setlocale2.c
@@ -0,0 +1,55 @@
+/* Test of setting the current locale.
+ Copyright (C) 2011 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 <locale.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main ()
+{
+ /* Try to set the locale by implicitly looking at the LC_ALL environment
+ variable. */
+ if (setlocale (LC_ALL, "") != NULL)
+ /* It was successful. Check whether LC_CTYPE is non-trivial. */
+ if (strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
+ {
+ fprintf (stderr, "setlocale did not fail for implicit %s\n",
+ getenv ("LC_ALL"));
+ return 1;
+ }
+
+ /* Reset the locale. */
+ if (setlocale (LC_ALL, "C") == NULL)
+ return 1;
+
+ /* Try to set the locale by explicitly looking at the LC_ALL environment
+ variable. */
+ if (setlocale (LC_ALL, getenv ("LC_ALL")) != NULL)
+ /* It was successful. Check whether LC_CTYPE is non-trivial. */
+ if (strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
+ {
+ fprintf (stderr, "setlocale did not fail for explicit %s\n",
+ getenv ("LC_ALL"));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/tests/test-setlocale2.sh b/tests/test-setlocale2.sh
new file mode 100755
index 0000000..723e74e
--- /dev/null
+++ b/tests/test-setlocale2.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test locale names with likely unsupported encoding in Unix syntax.
+for name in ar_SA.ISO-8859-1 fr_FR.CP1251 zh_TW.GB18030 zh_CN.BIG5; do
+ LC_ALL=$name ./test-setlocale2${EXEEXT} 1 || exit 1
+done
+
+# Test locale names with likely unsupported encoding in native Windows syntax.
+for name in "Arabic_Saudi Arabia.1252" "Arabic_Saudi Arabia.65001" \
+ French_France.65001 Japanese_Japan.65001 Turkish_Turkey.65001 \
+ Chinese_Taiwan.65001 Chinese_China.54936 Chinese_China.65001; do
+ LC_ALL=$name ./test-setlocale2${EXEEXT} 1 || exit 1
+done
+
+exit 0
diff --git a/tests/test-sigaction.c b/tests/test-sigaction.c
new file mode 100644
index 0000000..f83b87b
--- /dev/null
+++ b/tests/test-sigaction.c
@@ -0,0 +1,122 @@
+/* Test of sigaction() function.
+ Copyright (C) 2008-2011 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_RESETHAND
+# define SA_RESETHAND 0
+#endif
+#ifndef SA_RESTART
+# define SA_RESTART 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__ || defined __UCLIBC__)
+ 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__ || defined __UCLIBC__) /* 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/test-signal-c++.cc b/tests/test-signal-c++.cc
new file mode 100644
index 0000000..a38d2b5
--- /dev/null
+++ b/tests/test-signal-c++.cc
@@ -0,0 +1,51 @@
+/* Test of <signal.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <signal.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_SIGPROCMASK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sigismember, int, (const sigset_t *, int));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sigemptyset, int, (sigset_t *));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sigaddset, int, (sigset_t *, int));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sigdelset, int, (sigset_t *, int));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sigfillset, int, (sigset_t *));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sigpending, int, (sigset_t *));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sigprocmask, int,
+ (int, const sigset_t *, sigset_t *));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::signal,
+ _gl_function_taking_int_returning_void_t,
+ (int, _gl_function_taking_int_returning_void_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::raise, int, (int));
+#endif
+
+#if GNULIB_TEST_SIGACTION
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sigaction, int,
+ (int, const struct sigaction *, struct sigaction *));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-signal-c++2.cc b/tests/test-signal-c++2.cc
new file mode 100644
index 0000000..744e9a4
--- /dev/null
+++ b/tests/test-signal-c++2.cc
@@ -0,0 +1,20 @@
+/* Test of <signal.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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/>. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <csignal>
diff --git a/tests/test-signal.c b/tests/test-signal.c
new file mode 100644
index 0000000..7103e1f
--- /dev/null
+++ b/tests/test-signal.c
@@ -0,0 +1,129 @@
+/* Test of <signal.h> substitute.
+ Copyright (C) 2009-2011 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;
+
+/* Check that NSIG is defined. */
+int nsig = NSIG;
+
+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
+ /* On Haiku, SIGBUS is mistakenly equal to SIGSEGV. */
+#if defined SIGBUS && SIGBUS != SIGSEGV
+ 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/test-signbit.c b/tests/test-signbit.c
new file mode 100644
index 0000000..c898149
--- /dev/null
+++ b/tests/test-signbit.c
@@ -0,0 +1,176 @@
+/* Test of signbit() substitute.
+ Copyright (C) 2007-2011 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 "minus-zero.h"
+#include "macros.h"
+
+float zerof = 0.0f;
+double zerod = 0.0;
+long double zerol = 0.0L;
+
+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 / minus_zerof < 0)
+ ASSERT (signbit (minus_zerof));
+ else
+ ASSERT (!signbit (minus_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 / minus_zerod < 0)
+ ASSERT (signbit (minus_zerod));
+ else
+ ASSERT (!signbit (minus_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/test-snprintf.c b/tests/test-snprintf.c
new file mode 100644
index 0000000..95a352d
--- /dev/null
+++ b/tests/test-snprintf.c
@@ -0,0 +1,64 @@
+/* Test of snprintf() function.
+ Copyright (C) 2007-2011 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;
+
+ retval = snprintf (NULL, 0, "%d", 12345);
+ ASSERT (retval == 5);
+
+ for (size = 0; size <= 8; size++)
+ {
+ memcpy (buf, "DEADBEEF", 8);
+ retval = 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' || buf[size - 1] == '0' + size);
+ }
+#if !CHECK_SNPRINTF_POSIX
+ if (size > 0)
+#endif
+ ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
+ }
+ else
+ {
+ ASSERT (memcmp (buf, "12345\0EF", 8) == 0);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/test-spawn-c++.cc b/tests/test-spawn-c++.cc
new file mode 100644
index 0000000..fb54c2e
--- /dev/null
+++ b/tests/test-spawn-c++.cc
@@ -0,0 +1,139 @@
+/* Test of <spawn.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <spawn.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_POSIX_SPAWN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn, int,
+ (pid_t *, const char *, const posix_spawn_file_actions_t *,
+ const posix_spawnattr_t *, char *const[], char *const[]));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnp, int,
+ (pid_t *, const char *, const posix_spawn_file_actions_t *,
+ const posix_spawnattr_t *, char *const[], char *const[]));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_INIT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_init, int,
+ (posix_spawnattr_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_DESTROY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_destroy, int,
+ (posix_spawnattr_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_GETSIGDEFAULT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_getsigdefault, int,
+ (const posix_spawnattr_t *, sigset_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_SETSIGDEFAULT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_setsigdefault, int,
+ (posix_spawnattr_t *, const sigset_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_GETSIGMASK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_getsigmask, int,
+ (const posix_spawnattr_t *, sigset_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_SETSIGMASK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_setsigmask, int,
+ (posix_spawnattr_t *, const sigset_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_GETFLAGS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_getflags, int,
+ (const posix_spawnattr_t *, short int *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_SETFLAGS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_setflags, int,
+ (posix_spawnattr_t *, short int));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_GETPGROUP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_getpgroup, int,
+ (const posix_spawnattr_t *, pid_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_SETPGROUP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_setpgroup, int,
+ (posix_spawnattr_t *, pid_t));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_GETSCHEDPOLICY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_getschedpolicy, int,
+ (const posix_spawnattr_t *, int *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_SETSCHEDPOLICY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_setschedpolicy, int,
+ (posix_spawnattr_t *, int));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_GETSCHEDPARAM
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_getschedparam, int,
+ (const posix_spawnattr_t *, struct sched_param *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWNATTR_SETSCHEDPARAM
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawnattr_setschedparam, int,
+ (posix_spawnattr_t *, const struct sched_param *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_INIT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_init, int,
+ (posix_spawn_file_actions_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_DESTROY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_destroy, int,
+ (posix_spawn_file_actions_t *));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_addopen, int,
+ (posix_spawn_file_actions_t *, int, const char *, int,
+ mode_t));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_addclose, int,
+ (posix_spawn_file_actions_t *, int));
+#endif
+
+#if GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_adddup2, int,
+ (posix_spawn_file_actions_t *, int, int));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-spawn-pipe.c b/tests/test-spawn-pipe.c
new file mode 100644
index 0000000..5653150
--- /dev/null
+++ b/tests/test-spawn-pipe.c
@@ -0,0 +1,204 @@
+/* Test of create_pipe_bidi/wait_subprocess.
+ Copyright (C) 2009-2011 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 "spawn-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/test-spawn-pipe.sh b/tests/test-spawn-pipe.sh
new file mode 100755
index 0000000..2e4ea12
--- /dev/null
+++ b/tests/test-spawn-pipe.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+st=0
+for i in 0 1 2 3 4 5 6 7 ; do
+ ./test-spawn-pipe${EXEEXT} $i \
+ || { echo test-spawn-pipe.sh: iteration $i failed >&2; st=1; }
+done
+exit $st
diff --git a/tests/test-spawn.c b/tests/test-spawn.c
new file mode 100644
index 0000000..01d4503
--- /dev/null
+++ b/tests/test-spawn.c
@@ -0,0 +1,54 @@
+/* Test of <spawn.h> substitute.
+ Copyright (C) 2009-2011 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 != 0 ? POSIX_SPAWN_SETSCHEDPARAM : -1):
+ case (POSIX_SPAWN_SETSCHEDULER != 0 ? POSIX_SPAWN_SETSCHEDULER : -2):
+ ;
+ }
+ return s.c + s.d;
+}
diff --git a/tests/test-stat.c b/tests/test-stat.c
new file mode 100644
index 0000000..4cda089
--- /dev/null
+++ b/tests/test-stat.c
@@ -0,0 +1,56 @@
+/* Tests of stat.
+ Copyright (C) 2009-2011 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/test-stat.h b/tests/test-stat.h
new file mode 100644
index 0000000..22552dc
--- /dev/null
+++ b/tests/test-stat.h
@@ -0,0 +1,100 @@
+/* Tests of stat.
+ Copyright (C) 2009-2011 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/test-stdbool.c b/tests/test-stdbool.c
new file mode 100644
index 0000000..e115ba2
--- /dev/null
+++ b/tests/test-stdbool.c
@@ -0,0 +1,118 @@
+/* Test of <stdbool.h> substitute.
+ Copyright (C) 2002-2007, 2009-2011 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. */
+
+/* We want this test to succeed even when using gcc's -Werror; but to
+ do that requires a pragma that didn't exist before 4.3.0. */
+#ifndef __GNUC__
+# define ADDRESS_CHECK_OKAY
+#elif __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
+/* No way to silence -Waddress. */
+#else
+# pragma GCC diagnostic ignored "-Waddress"
+# define ADDRESS_CHECK_OKAY
+#endif
+
+#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
+
+/* Several tests cannot be guaranteed with gnulib's <stdbool.h>, at
+ least, not for all compilers and compiler options. */
+#if HAVE_STDBOOL_H || 3 <= __GNUC__
+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 HAVE_STDBOOL_H || 3 <= __GNUC__ /* See above. */
+char d[(bool) 0.5 == true ? 1 : -1];
+# ifdef ADDRESS_CHECK_OKAY /* Avoid gcc warning. */
+/* C99 may plausibly be interpreted as not requiring support for a cast from
+ a variable's address to bool in a static initializer. So treat it like a
+ GCC extension. */
+# ifdef __GNUC__
+bool e = &s;
+# endif
+# endif
+char f[(_Bool) 0.0 == false ? 1 : -1];
+#endif
+char g[true];
+char h[sizeof (_Bool)];
+#if HAVE_STDBOOL_H || 3 <= __GNUC__ /* 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];
+/* 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 ()
+{
+ int error = 0;
+
+#if HAVE_STDBOOL_H || 3 <= __GNUC__ /* See above. */
+# ifdef ADDRESS_CHECK_OKAY /* Avoid gcc warning. */
+ /* A cast from a variable's address to bool is valid in expressions. */
+ {
+ bool e1 = &s;
+ if (!e1)
+ error = 1;
+ }
+# endif
+#endif
+
+ /* 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 is a runtime test, since a corresponding compile-time
+ test would rely on initializer extensions. */
+ {
+ char digs[] = "0123456789";
+ if (&(digs + 5)[-2 + (bool) 1] != &digs[4])
+ error = 1;
+ }
+
+ return error;
+}
diff --git a/tests/test-stddef.c b/tests/test-stddef.c
new file mode 100644
index 0000000..c929af8
--- /dev/null
+++ b/tests/test-stddef.c
@@ -0,0 +1,52 @@
+/* Test of <stddef.h> substitute.
+ Copyright (C) 2009-2011 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 *));
+
+/* Check that offsetof produces integer constants with correct type. */
+struct d
+{
+ char e;
+ char f;
+};
+/* Solaris 10 has a bug where offsetof is under-parenthesized, and
+ cannot be used as an arbitrary expression. However, since it is
+ unlikely to bite real code, we ignore that short-coming. */
+/* verify (sizeof offsetof (struct d, e) == sizeof (size_t)); */
+verify (sizeof (offsetof (struct d, e)) == sizeof (size_t));
+verify (offsetof (struct d, e) < -1); /* Must be unsigned. */
+verify (offsetof (struct d, f) == 1);
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/tests/test-stdint.c b/tests/test-stdint.c
new file mode 100644
index 0000000..f606cc3
--- /dev/null
+++ b/tests/test-stdint.c
@@ -0,0 +1,361 @@
+/* Test of <stdint.h> substitute.
+ Copyright (C) 2006-2011 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 */
+#define __STDC_CONSTANT_MACROS 1 /* likewise */
+#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/test-stdio-c++.cc b/tests/test-stdio-c++.cc
new file mode 100644
index 0000000..a9d00a3
--- /dev/null
+++ b/tests/test-stdio-c++.cc
@@ -0,0 +1,191 @@
+/* Test of <stdio.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <stdio.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_DPRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::dprintf, int, (int, const char *, ...));
+#endif
+
+#if GNULIB_TEST_FCLOSE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fclose, int, (FILE *));
+#endif
+
+#if GNULIB_TEST_FFLUSH
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fflush, int, (FILE *));
+#endif
+
+#if GNULIB_TEST_FOPEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fopen, FILE *,
+ (const char *, const char *));
+#endif
+
+#if GNULIB_TEST_FPRINTF_POSIX || GNULIB_TEST_FPRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fprintf, int, (FILE *, const char *, ...));
+#endif
+
+#if GNULIB_TEST_FPURGE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fpurge, int, (FILE *));
+#endif
+
+#if GNULIB_TEST_FPUTC
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fputc, int, (int, FILE *));
+#endif
+
+#if GNULIB_TEST_FPUTS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fputs, int, (const char *, FILE *));
+#endif
+
+#if GNULIB_TEST_FREOPEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::freopen, FILE *,
+ (const char *, const char *, FILE *));
+#endif
+
+#if GNULIB_TEST_FSEEK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fseek, int, (FILE *, long, int));
+#endif
+
+#if GNULIB_TEST_FSEEKO
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fseeko, int, (FILE *, off_t, int));
+#endif
+
+#if GNULIB_TEST_FTELL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ftell, long, (FILE *));
+#endif
+
+#if GNULIB_TEST_FTELLO
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ftello, off_t, (FILE *));
+#endif
+
+#if GNULIB_TEST_FWRITE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fwrite, size_t,
+ (const void *, size_t, size_t, FILE *));
+#endif
+
+#if GNULIB_TEST_GETDELIM
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getdelim, ssize_t,
+ (char **, size_t *, int, FILE *));
+#endif
+
+#if GNULIB_TEST_GETLINE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getline, ssize_t,
+ (char **, size_t *, FILE *));
+#endif
+
+#if GNULIB_TEST_OBSTACK_PRINTF || GNULIB_TEST_OBSTACK_PRINTF_POSIX
+SIGNATURE_CHECK (GNULIB_NAMESPACE::obstack_printf, int,
+ (struct obstack *, const char *, ...));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::obstack_vprintf, int,
+ (struct obstack *, const char *, va_list));
+#endif
+
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::pclose, int, (FILE *));
+
+#if GNULIB_TEST_PERROR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::perror, void, (const char *));
+#endif
+
+#if GNULIB_TEST_POPEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::popen, FILE *,
+ (const char *, const char *));
+#endif
+
+#if GNULIB_TEST_PRINTF_POSIX || GNULIB_TEST_PRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::printf, int, (const char *, ...));
+#endif
+
+#if GNULIB_TEST_PUTC
+SIGNATURE_CHECK (GNULIB_NAMESPACE::putc, int, (int, FILE *));
+#endif
+
+#if GNULIB_TEST_PUTCHAR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::putchar, int, (int));
+#endif
+
+#if GNULIB_TEST_PUTS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::puts, int, (const char *));
+#endif
+
+#if GNULIB_TEST_REMOVE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::remove, int, (const char *));
+#endif
+
+#if GNULIB_TEST_RENAME
+SIGNATURE_CHECK (GNULIB_NAMESPACE::rename, int, (const char *, const char *));
+#endif
+
+#if GNULIB_TEST_RENAMEAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::renameat, int,
+ (int, char const *, int, char const *));
+#endif
+
+#if GNULIB_TEST_SNPRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::snprintf, int,
+ (char *, size_t, const char *, ...));
+#endif
+
+#if GNULIB_TEST_SPRINTF_POSIX
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sprintf, int, (char *, const char *, ...));
+#endif
+
+#if GNULIB_TEST_TMPFILE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::tmpfile, FILE *, (void));
+#endif
+
+#if GNULIB_TEST_VASPRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::asprintf, int,
+ (char **, const char *, ...));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::vasprintf, int,
+ (char **, const char *, va_list));
+#endif
+
+#if GNULIB_TEST_VDPRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::vdprintf, int,
+ (int, const char *, va_list));
+#endif
+
+#if GNULIB_TEST_VFPRINTF_POSIX || GNULIB_TEST_VFPRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::vfprintf, int,
+ (FILE *, const char *, va_list));
+#endif
+
+#if GNULIB_TEST_VPRINTF_POSIX || GNULIB_TEST_VPRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::vprintf, int, (const char *, va_list));
+#endif
+
+#if GNULIB_TEST_VSNPRINTF
+SIGNATURE_CHECK (GNULIB_NAMESPACE::vsnprintf, int,
+ (char *, size_t, const char *, va_list));
+#endif
+
+#if GNULIB_TEST_VSPRINTF_POSIX
+SIGNATURE_CHECK (GNULIB_NAMESPACE::vsprintf, int,
+ (char *, const char *, va_list));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-stdio-c++2.cc b/tests/test-stdio-c++2.cc
new file mode 100644
index 0000000..4e41627
--- /dev/null
+++ b/tests/test-stdio-c++2.cc
@@ -0,0 +1,20 @@
+/* Test of <stdio.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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/>. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <cstdio>
diff --git a/tests/test-stdio.c b/tests/test-stdio.c
new file mode 100644
index 0000000..7e7a206
--- /dev/null
+++ b/tests/test-stdio.c
@@ -0,0 +1,43 @@
+/* Test of <stdio.h> substitute.
+ Copyright (C) 2007, 2009-2011 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/test-stdlib-c++.cc b/tests/test-stdlib-c++.cc
new file mode 100644
index 0000000..9010c1c
--- /dev/null
+++ b/tests/test-stdlib-c++.cc
@@ -0,0 +1,163 @@
+/* Test of <stdlib.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST__EXIT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::_Exit, void, (int));
+#endif
+
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::atexit, int, (void (*) (void)));
+
+#if GNULIB_TEST_ATOLL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::atoll, long long, (const char *));
+#endif
+
+#if GNULIB_TEST_CALLOC_POSIX
+SIGNATURE_CHECK (GNULIB_NAMESPACE::calloc, void *, (size_t, size_t));
+#endif
+
+#if GNULIB_TEST_CANONICALIZE_FILE_NAME
+SIGNATURE_CHECK (GNULIB_NAMESPACE::canonicalize_file_name, char *,
+ (const char *));
+#endif
+
+#if GNULIB_TEST_GETLOADAVG
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getloadavg, int, (double[], int));
+#endif
+
+#if GNULIB_TEST_GETSUBOPT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getsubopt, int,
+ (char **, char *const *, char **));
+#endif
+
+#if GNULIB_TEST_GRANTPT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::grantpt, int, (int));
+#endif
+
+#if GNULIB_TEST_MALLOC_POSIX
+SIGNATURE_CHECK (GNULIB_NAMESPACE::malloc, void *, (size_t));
+#endif
+
+#if GNULIB_TEST_MBTOWC
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbtowc, int,
+ (wchar_t *, const char *, size_t));
+#endif
+
+#if GNULIB_TEST_MKDTEMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkdtemp, char *, (char *));
+#endif
+
+#if GNULIB_TEST_MKOSTEMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkostemp, int, (char *, int));
+#endif
+
+#if GNULIB_TEST_MKOSTEMPS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkostemps, int, (char *, int, int));
+#endif
+
+#if GNULIB_TEST_MKSTEMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkstemp, int, (char *));
+#endif
+
+#if GNULIB_TEST_MKSTEMPS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkstemps, int, (char *, int));
+#endif
+
+#if GNULIB_TEST_PTSNAME
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ptsname, char *, (int));
+#endif
+
+#if GNULIB_TEST_PUTENV
+SIGNATURE_CHECK (GNULIB_NAMESPACE::putenv, int, (char *));
+#endif
+
+#if GNULIB_TEST_RANDOM_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::random_r, int,
+ (struct random_data *, int32_t *));
+#endif
+
+#if GNULIB_TEST_RANDOM_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::srandom_r, int,
+ (unsigned int, struct random_data *));
+#endif
+
+#if GNULIB_TEST_RANDOM_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::initstate_r, int,
+ (unsigned int, char *, size_t, struct random_data *));
+#endif
+
+#if GNULIB_TEST_RANDOM_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::setstate_r, int,
+ (char *, struct random_data *));
+#endif
+
+#if GNULIB_TEST_REALLOC_POSIX
+SIGNATURE_CHECK (GNULIB_NAMESPACE::realloc, void *, (void *, size_t));
+#endif
+
+#if GNULIB_TEST_REALPATH
+SIGNATURE_CHECK (GNULIB_NAMESPACE::realpath, char *, (const char *, char *));
+#endif
+
+#if GNULIB_TEST_RPMATCH
+SIGNATURE_CHECK (GNULIB_NAMESPACE::rpmatch, int, (const char *));
+#endif
+
+#if GNULIB_TEST_SETENV
+SIGNATURE_CHECK (GNULIB_NAMESPACE::setenv, int,
+ (const char *, const char *, int));
+#endif
+
+#if GNULIB_TEST_STRTOD
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strtod, double, (const char *, char **));
+#endif
+
+#if GNULIB_TEST_STRTOLL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strtoll, long long,
+ (const char *, char **, int));
+#endif
+
+#if GNULIB_TEST_STRTOULL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strtoull, unsigned long long,
+ (const char *, char **, int));
+#endif
+
+#if GNULIB_TEST_UNLOCKPT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::unlockpt, int, (int));
+#endif
+
+#if GNULIB_TEST_UNSETENV
+SIGNATURE_CHECK (GNULIB_NAMESPACE::unsetenv, int, (const char *));
+#endif
+
+#if GNULIB_TEST_WCTOMB
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wctomb, int, (char *, wchar_t));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-stdlib-c++2.cc b/tests/test-stdlib-c++2.cc
new file mode 100644
index 0000000..f9b8e96
--- /dev/null
+++ b/tests/test-stdlib-c++2.cc
@@ -0,0 +1,20 @@
+/* Test of <stdlib.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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/>. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <cstdlib>
diff --git a/tests/test-stdlib.c b/tests/test-stdlib.c
new file mode 100644
index 0000000..210aab4
--- /dev/null
+++ b/tests/test-stdlib.c
@@ -0,0 +1,54 @@
+/* Test of <stdlib.h> substitute.
+ Copyright (C) 2007, 2009-2011 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"
+
+/* Check that EXIT_SUCCESS is 0, per POSIX. */
+static int exitcode = EXIT_SUCCESS;
+#if EXIT_SUCCESS
+"oops"
+#endif
+
+/* Check for GNU value (not guaranteed by POSIX, but is guaranteed by
+ gnulib). */
+#if EXIT_FAILURE != 1
+"oops"
+#endif
+
+/* Check that NULL can be passed through varargs as a pointer type,
+ per POSIX 2008. */
+verify (sizeof NULL == sizeof (void *));
+
+#if GNULIB_TEST_SYSTEM_POSIX
+# include "test-sys_wait.h"
+#else
+# define test_sys_wait_macros() 0
+#endif
+
+int
+main (void)
+{
+ if (test_sys_wait_macros ())
+ return 1;
+
+ return exitcode;
+}
diff --git a/tests/test-strchrnul.c b/tests/test-strchrnul.c
new file mode 100644
index 0000000..6ea8adc
--- /dev/null
+++ b/tests/test-strchrnul.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008-2011 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/test-strerror.c b/tests/test-strerror.c
new file mode 100644
index 0000000..66dbe82
--- /dev/null
+++ b/tests/test-strerror.c
@@ -0,0 +1,57 @@
+/* Test of strerror() function.
+ Copyright (C) 2007-2011 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/test-string-c++.cc b/tests/test-string-c++.cc
new file mode 100644
index 0000000..df21393
--- /dev/null
+++ b/tests/test-string-c++.cc
@@ -0,0 +1,146 @@
+/* Test of <string.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <string.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_MEMCHR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::memchr, void *,
+ (void const *, int, size_t));
+#endif
+
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::memcmp, int,
+// (void const *, void const *, size_t));
+
+#if GNULIB_TEST_MEMMEM
+SIGNATURE_CHECK (GNULIB_NAMESPACE::memmem, void *,
+ (void const *, size_t, void const *, size_t));
+#endif
+
+#if GNULIB_TEST_MEMPCPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mempcpy, void *,
+ (void *, void const *, size_t));
+#endif
+
+#if GNULIB_TEST_MEMRCHR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::memrchr, void *,
+ (void const *, int, size_t));
+#endif
+
+#if GNULIB_TEST_RAWMEMCHR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::rawmemchr, void *, (void const *, int));
+#endif
+
+#if GNULIB_TEST_STPCPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::stpcpy, char *, (char *, char const *));
+#endif
+
+#if GNULIB_TEST_STPNCPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::stpncpy, char *,
+ (char *, char const *, size_t));
+#endif
+
+#if GNULIB_TEST_STRCHRNUL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strchrnul, char *, (char const *, int));
+#endif
+
+#if GNULIB_TEST_STRDUP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strdup, char *, (char const *));
+#endif
+
+#if GNULIB_TEST_STRNCAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strncat, char *,
+ (char *, const char *, size_t));
+#endif
+
+#if GNULIB_TEST_STRNDUP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strndup, char *, (char const *, size_t));
+#endif
+
+#if GNULIB_TEST_STRNLEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strnlen, size_t, (char const *, size_t));
+#endif
+
+#if GNULIB_TEST_STRPBRK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strpbrk, char *,
+ (char const *, char const *));
+#endif
+
+#if GNULIB_TEST_STRSEP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strsep, char *, (char **, char const *));
+#endif
+
+#if GNULIB_TEST_STRSTR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strstr, char *,
+ (const char *, const char *));
+#endif
+
+#if GNULIB_TEST_STRCASESTR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strcasestr, char *,
+ (const char *, const char *));
+#endif
+
+#if GNULIB_TEST_STRTOK_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strtok_r, char *,
+ (char *, char const *, char **));
+#endif
+
+#if GNULIB_TEST_MBSLEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbslen, size_t, (const char *));
+#endif
+
+#if GNULIB_TEST_MBSCHR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbschr, char *, (const char *, int));
+#endif
+
+#if GNULIB_TEST_MBSRCHR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbsrchr, char *, (const char *, int));
+#endif
+
+#if GNULIB_TEST_MBSPBRK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbspbrk, char *,
+ (const char *, const char *));
+#endif
+
+#if GNULIB_TEST_STRERROR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strerror, char *, (int));
+#endif
+
+#if GNULIB_TEST_STRERROR_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strerror_r, int, (int, char *, size_t));
+#endif
+
+#if GNULIB_TEST_STRSIGNAL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strsignal, char *, (int));
+#endif
+
+#if GNULIB_TEST_STRVERSCMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strverscmp, int,
+ (const char *, const char *));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-string-c++2.cc b/tests/test-string-c++2.cc
new file mode 100644
index 0000000..43103c9
--- /dev/null
+++ b/tests/test-string-c++2.cc
@@ -0,0 +1,20 @@
+/* Test of <string.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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/>. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <cstring>
diff --git a/tests/test-string.c b/tests/test-string.c
new file mode 100644
index 0000000..54c49a9
--- /dev/null
+++ b/tests/test-string.c
@@ -0,0 +1,33 @@
+/* Test of <string.h> substitute.
+ Copyright (C) 2007, 2009-2011 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/test-strnlen.c b/tests/test-strnlen.c
new file mode 100644
index 0000000..18d6fcd
--- /dev/null
+++ b/tests/test-strnlen.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010-2011 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 <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (strnlen, size_t, (char const *, size_t));
+
+#include <stdlib.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+int
+main (void)
+{
+ size_t i;
+ char *page_boundary = (char *) zerosize_ptr ();
+ if (!page_boundary)
+ {
+ page_boundary = malloc (0x1000);
+ ASSERT (page_boundary);
+ page_boundary += 0x1000;
+ }
+
+ /* Basic behavior tests. */
+ ASSERT (strnlen ("a", 0) == 0);
+ ASSERT (strnlen ("a", 1) == 1);
+ ASSERT (strnlen ("a", 2) == 1);
+ ASSERT (strnlen ("", 0x100000) == 0);
+
+ /* Memory fence and alignment testing. */
+ for (i = 0; i < 512; i++)
+ {
+ char *start = page_boundary - i;
+ size_t j = i;
+ memset (start, 'x', i);
+ do
+ {
+ if (i != j)
+ {
+ start[j] = 0;
+ ASSERT (strnlen (start, i + j) == j);
+ }
+ ASSERT (strnlen (start, i) == j);
+ ASSERT (strnlen (start, j) == j);
+ }
+ while (j--);
+ }
+
+ return 0;
+}
diff --git a/tests/test-strsignal.c b/tests/test-strsignal.c
new file mode 100644
index 0000000..6b90cef
--- /dev/null
+++ b/tests/test-strsignal.c
@@ -0,0 +1,78 @@
+/* Test of strsignal() function.
+ Copyright (C) 2008-2011 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 Colin Watson <cjwatson@debian.org>, 2008. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (strsignal, char *, (int));
+
+#include <signal.h>
+
+#include "macros.h"
+
+#if HAVE_DECL_SYS_SIGLIST
+# define ASSERT_DESCRIPTION(got, expect)
+#else
+/* In this case, we can guarantee some signal descriptions. */
+# define ASSERT_DESCRIPTION(got, expect) ASSERT (!strcmp (got, expect))
+#endif
+
+int
+main (void)
+{
+ /* Work around bug in cygwin 1.5.25 <string.h> by declaring str as
+ const char *, even though strsignal is supposed to return char *.
+ At any rate, this doesn't hurt, since POSIX 200x states that "The
+ string pointed to shall not be modified by the application." */
+ const char *str;
+
+ /* We try a couple of signals, since not all signals are supported
+ everywhere. Notwithstanding the #ifdef for neatness, SIGINT should in
+ fact be available on all platforms. */
+
+#ifdef SIGHUP
+ str = strsignal (SIGHUP);
+ ASSERT (str);
+ ASSERT (*str);
+ ASSERT_DESCRIPTION (str, "Hangup");
+#endif
+
+#ifdef SIGINT
+ str = strsignal (SIGINT);
+ ASSERT (str);
+ ASSERT (*str);
+ ASSERT_DESCRIPTION (str, "Interrupt");
+#endif
+
+ /* Test that for out-of-range signal numbers the result is usable. */
+
+ str = strsignal (-1);
+ ASSERT (str);
+ ASSERT (str != (char *) -1);
+ ASSERT (strlen (str));
+
+ str = strsignal (9249234);
+ ASSERT (str);
+ ASSERT (str != (char *) -1);
+ ASSERT (strlen (str));
+
+ return 0;
+}
diff --git a/tests/test-strstr.c b/tests/test-strstr.c
new file mode 100644
index 0000000..d6d6639
--- /dev/null
+++ b/tests/test-strstr.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2004, 2007-2011 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 (strstr, char *, (char const *, char const *));
+
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "zerosize-ptr.h"
+#include "macros.h"
+
+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 have
+ a quadratic strstr, and the replacement strstr is known to not
+ take too long. */
+ signal (SIGALRM, SIG_DFL);
+ alarm (50);
+#endif
+
+ {
+ const char input[] = "foo";
+ const char *result = strstr (input, "");
+ ASSERT (result == input);
+ }
+
+ {
+ const char input[] = "foo";
+ const char *result = strstr (input, "o");
+ ASSERT (result == input + 1);
+ }
+
+ {
+ /* On some platforms, the memchr() functions reads past the first
+ occurrence of the byte to be searched, leading to an out-of-bounds
+ read access for strstr().
+ See <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737>.
+ This is a bug in memchr(), see the Austin Group's clarification
+ <http://www.opengroup.org/austin/docs/austin_454.txt>. */
+ const char *fix = "aBaaaaaaaaaaax";
+ char *page_boundary = (char *) zerosize_ptr ();
+ size_t len = strlen (fix) + 1;
+ char *input = page_boundary ? page_boundary - len : malloc (len);
+ const char *result;
+
+ strcpy (input, fix);
+ result = strstr (input, "B1x");
+ ASSERT (result == NULL);
+ if (!page_boundary)
+ free (input);
+ }
+
+ {
+ const char input[] = "ABC ABCDAB ABCDABCDABDE";
+ const char *result = strstr (input, "ABCDABD");
+ ASSERT (result == input + 15);
+ }
+
+ {
+ const char input[] = "ABC ABCDAB ABCDABCDABDE";
+ const char *result = strstr (input, "ABCDABE");
+ ASSERT (result == NULL);
+ }
+
+ {
+ const char input[] = "ABC ABCDAB ABCDABCDABDE";
+ const char *result = strstr (input, "ABCDABCD");
+ ASSERT (result == input + 11);
+ }
+
+ /* Check that a long periodic needle does not cause false positives. */
+ {
+ const char input[] = "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"
+ "_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD"
+ "_C3_A7_20_EF_BF_BD";
+ const char need[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
+ const char *result = strstr (input, need);
+ ASSERT (result == NULL);
+ }
+ {
+ const char input[] = "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"
+ "_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD"
+ "_C3_A7_20_EF_BF_BD_DA_B5_C2_A6_20"
+ "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
+ const char need[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
+ const char *result = strstr (input, need);
+ ASSERT (result == input + 115);
+ }
+
+ /* 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;
+ const 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 (strstr (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;
+ const 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 (strstr (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 = strstr (haystack, needle);
+ ASSERT (result == haystack + m);
+ }
+ free (needle);
+ free (haystack);
+ }
+
+ /* Sublinear speed is only possible in memmem; strstr must examine
+ every character of haystack to find its length. */
+
+
+ {
+ /* Ensure that with a barely periodic "short" needle, strstr's
+ search does not mistakenly skip just past the match point.
+ This use of strstr would mistakenly return NULL before
+ gnulib v0.0-4927. */
+ const char *haystack =
+ "\n"
+ "with_build_libsubdir\n"
+ "with_local_prefix\n"
+ "with_gxx_include_dir\n"
+ "with_cpp_install_dir\n"
+ "enable_generated_files_in_srcdir\n"
+ "with_gnu_ld\n"
+ "with_ld\n"
+ "with_demangler_in_ld\n"
+ "with_gnu_as\n"
+ "with_as\n"
+ "enable_largefile\n"
+ "enable_werror_always\n"
+ "enable_checking\n"
+ "enable_coverage\n"
+ "enable_gather_detailed_mem_stats\n"
+ "enable_build_with_cxx\n"
+ "with_stabs\n"
+ "enable_multilib\n"
+ "enable___cxa_atexit\n"
+ "enable_decimal_float\n"
+ "enable_fixed_point\n"
+ "enable_threads\n"
+ "enable_tls\n"
+ "enable_objc_gc\n"
+ "with_dwarf2\n"
+ "enable_shared\n"
+ "with_build_sysroot\n"
+ "with_sysroot\n"
+ "with_specs\n"
+ "with_pkgversion\n"
+ "with_bugurl\n"
+ "enable_languages\n"
+ "with_multilib_list\n";
+ const char *needle = "\n"
+ "with_gnu_ld\n";
+ const char* p = strstr (haystack, needle);
+ ASSERT (p - haystack == 114);
+ }
+
+ {
+ /* Same bug, shorter trigger. */
+ const char *haystack = "..wi.d.";
+ const char *needle = ".d.";
+ const char* p = strstr (haystack, needle);
+ ASSERT (p - haystack == 4);
+ }
+
+ {
+ /* Like the above, but trigger the flaw in two_way_long_needle
+ by using a needle of length LONG_NEEDLE_THRESHOLD (32) or greater.
+ Rather than trying to find the right alignment manually, I've
+ arbitrarily chosen the following needle and template for the
+ haystack, and ensure that for each placement of the needle in
+ that haystack, strstr finds it. */
+ const char *needle = "\nwith_gnu_ld-extend-to-len-32-b\n";
+ const char *h =
+ "\n"
+ "with_build_libsubdir\n"
+ "with_local_prefix\n"
+ "with_gxx_include_dir\n"
+ "with_cpp_install_dir\n"
+ "with_e_\n"
+ "..............................\n"
+ "with_FGHIJKLMNOPQRSTUVWXYZ\n"
+ "with_567890123456789\n"
+ "with_multilib_list\n";
+ size_t h_len = strlen (h);
+ char *haystack = malloc (h_len + 1);
+ size_t i;
+ ASSERT (haystack);
+ for (i = 0; i < h_len - strlen (needle); i++)
+ {
+ const char *p;
+ memcpy (haystack, h, h_len + 1);
+ memcpy (haystack + i, needle, strlen (needle) + 1);
+ p = strstr (haystack, needle);
+ ASSERT (p);
+ ASSERT (p - haystack == i);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/test-strtod.c b/tests/test-strtod.c
new file mode 100644
index 0000000..327da4f
--- /dev/null
+++ b/tests/test-strtod.c
@@ -0,0 +1,986 @@
+/*
+ * Copyright (C) 2008-2011 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 "minus-zero.h"
+#include "macros.h"
+
+/* Avoid requiring -lm just for fabs. */
+#define FABS(d) ((d) < 0.0 ? -(d) : (d))
+
+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 (minus_zerod)); /* 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, AIX 7.1 */
+ 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 (minus_zerod)); /* 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, AIX 7.1 */
+ 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, AIX 7.1 */
+ 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, AIX 7.1 */
+ 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, AIX 7.1 */
+ 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, AIX 7.1 */
+ 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, AIX 7.1 */
+ 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, AIX 7.1 */
+ 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, AIX 7.1 */
+ 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);
+ }
+ {
+ 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 (minus_zerod)); /* glibc-2.3.6, mingw */
+#endif
+ ASSERT (ptr == input + 10);
+ ASSERT (errno == ERANGE);
+ }
+ {
+ const char input[] = "1E 1000000";
+ 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[] = "0x1P 1000000";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 7.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 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+
+ /* 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 7.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 7.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 7.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 7.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 7.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 7.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 7.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+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);
+ }
+ {
+ const char input[] = "0x1p 2";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 7.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 7.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 (minus_zerod)); /* 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/test-symlink.c b/tests/test-symlink.c
new file mode 100644
index 0000000..367e045
--- /dev/null
+++ b/tests/test-symlink.c
@@ -0,0 +1,47 @@
+/* Tests of symlink.
+ Copyright (C) 2009-2011 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/test-symlink.h b/tests/test-symlink.h
new file mode 100644
index 0000000..4d93929
--- /dev/null
+++ b/tests/test-symlink.h
@@ -0,0 +1,95 @@
+/* Tests of symlink.
+ Copyright (C) 2009-2011 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/test-sys_stat-c++.cc b/tests/test-sys_stat-c++.cc
new file mode 100644
index 0000000..2efa9b7
--- /dev/null
+++ b/tests/test-sys_stat-c++.cc
@@ -0,0 +1,88 @@
+/* Test of <sys/stat.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <sys/stat.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_FCHMODAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fchmodat, int,
+ (int, char const *, mode_t, int));
+#endif
+
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fstat, int, (int, struct stat *));
+
+#if GNULIB_TEST_FSTATAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fstatat, int,
+ (int, char const *, struct stat *, int));
+#endif
+
+#if GNULIB_TEST_FUTIMENS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::futimens, int,
+ (int, struct timespec const[2]));
+#endif
+
+#if GNULIB_TEST_LCHMOD
+SIGNATURE_CHECK (GNULIB_NAMESPACE::lchmod, int, (const char *, mode_t));
+#endif
+
+#if GNULIB_TEST_LSTAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::lstat, int, (const char *, struct stat *));
+#endif
+
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkdir, int, (char const *, mode_t));
+
+#if GNULIB_TEST_MKDIRAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkdirat, int, (int, char const *, mode_t));
+#endif
+
+#if GNULIB_TEST_MKFIFO
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkfifo, int, (char const *, mode_t));
+#endif
+
+#if GNULIB_TEST_MKFIFOAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mkfifoat, int, (int, char const *, mode_t));
+#endif
+
+#if GNULIB_TEST_MKNOD
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mknod, int, (char const *, mode_t, dev_t));
+#endif
+
+#if GNULIB_TEST_MKNODAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mknodat, int,
+ (int, char const *, mode_t, dev_t));
+#endif
+
+#if GNULIB_TEST_STAT
+//SIGNATURE_CHECK (GNULIB_NAMESPACE::stat, int, (const char *, struct stat *));
+#endif
+
+#if GNULIB_TEST_UTIMENSAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::utimensat, int,
+ (int, char const *, struct timespec const[2], int));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-sys_stat.c b/tests/test-sys_stat.c
new file mode 100644
index 0000000..cd07d86
--- /dev/null
+++ b/tests/test-sys_stat.c
@@ -0,0 +1,288 @@
+/* Test of <sys/stat.h> substitute.
+ Copyright (C) 2007-2011 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/test-sys_time-c++.cc b/tests/test-sys_time-c++.cc
new file mode 100644
index 0000000..6c937fd
--- /dev/null
+++ b/tests/test-sys_time-c++.cc
@@ -0,0 +1,36 @@
+/* Test of <sys/time.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <sys/time.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_GETTIMEOFDAY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::gettimeofday, int,
+ (struct timeval *, void *));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-sys_time.c b/tests/test-sys_time.c
new file mode 100644
index 0000000..da64b85
--- /dev/null
+++ b/tests/test-sys_time.c
@@ -0,0 +1,29 @@
+/* Test of <sys/time.h> substitute.
+ Copyright (C) 2007, 2009-2011 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/test-sys_wait-c++.cc b/tests/test-sys_wait-c++.cc
new file mode 100644
index 0000000..2f6b6ce
--- /dev/null
+++ b/tests/test-sys_wait-c++.cc
@@ -0,0 +1,35 @@
+/* Test of <sys/wait.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <sys/wait.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_WAITPID
+SIGNATURE_CHECK (GNULIB_NAMESPACE::waitpid, pid_t, (pid_t, int *, int));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-sys_wait.c b/tests/test-sys_wait.c
new file mode 100644
index 0000000..dce89c6
--- /dev/null
+++ b/tests/test-sys_wait.c
@@ -0,0 +1,47 @@
+/* Test of <sys/wait.h> substitute.
+ Copyright (C) 2009-2011 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;
+
+#include "test-sys_wait.h"
+
+int
+main (void)
+{
+ if (test_sys_wait_macros ())
+ return 1;
+
+ switch (0)
+ {
+#if 0
+ /* Gnulib doesn't guarantee these, yet. */
+ case WCONTINUED:
+ case WEXITED:
+ case WNOWAIT:
+ case WSTOPPED:
+#endif
+ break;
+ }
+
+ return a ? 1 : 0;
+}
diff --git a/tests/test-sys_wait.h b/tests/test-sys_wait.h
new file mode 100644
index 0000000..3c9b322
--- /dev/null
+++ b/tests/test-sys_wait.h
@@ -0,0 +1,53 @@
+/* Test of macros shared between <sys/wait.h> and <stdlib.h>.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+static int
+test_sys_wait_macros (void)
+{
+ /* Check subset of <sys/wait.h> macros that must be visible here.
+ Note that some of these macros are only portable when operating
+ on an lvalue. */
+ int i;
+ for (i = 0; i < 0x8000; i = (i ? i << 1 : 1))
+ {
+ /* POSIX requires that for all valid process statuses, that
+ exactly one of these three macros is true. But not all
+ possible 16-bit values map to valid process status.
+ Traditionally, 8 of the bits are for WIFEXITED, 7 of the bits
+ to tell between WIFSIGNALED and WIFSTOPPED, and either 0x80
+ or 0x8000 to flag that core was also dumped. Since we don't
+ know which byte is WIFEXITED, we skip the both possible bits
+ that can signal core dump. */
+ if (i == 0x80)
+ continue;
+ if (!!WIFSIGNALED (i) + !!WIFEXITED (i) + !!WIFSTOPPED (i) != 1)
+ return 1;
+ }
+ i = WEXITSTATUS (i) + WSTOPSIG (i) + WTERMSIG (i);
+
+ switch (i)
+ {
+#if 0
+ /* Gnulib doesn't guarantee these, yet. */
+ case WNOHANG:
+ case WUNTRACED:
+#endif
+ break;
+ }
+ return 0;
+}
diff --git a/tests/test-time-c++.cc b/tests/test-time-c++.cc
new file mode 100644
index 0000000..b4ed33b
--- /dev/null
+++ b/tests/test-time-c++.cc
@@ -0,0 +1,57 @@
+/* Test of <time.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <time.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_NANOSLEEP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::nanosleep, int,
+ (struct timespec const *, struct timespec *));
+#endif
+
+#if GNULIB_TEST_MKTIME
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mktime, time_t, (struct tm *));
+#endif
+
+#if GNULIB_TEST_TIME_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::localtime_r, struct tm *,
+ (time_t const *, struct tm *));
+
+SIGNATURE_CHECK (GNULIB_NAMESPACE::gmtime_r, struct tm *,
+ (time_t const *, struct tm *));
+#endif
+
+#if GNULIB_TEST_STRPTIME
+SIGNATURE_CHECK (GNULIB_NAMESPACE::strptime, char *,
+ (char const *, char const *, struct tm *));
+#endif
+
+#if GNULIB_TEST_TIMEGM
+SIGNATURE_CHECK (GNULIB_NAMESPACE::timegm, time_t, (struct tm *));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-time-c++2.cc b/tests/test-time-c++2.cc
new file mode 100644
index 0000000..8c1f53d
--- /dev/null
+++ b/tests/test-time-c++2.cc
@@ -0,0 +1,20 @@
+/* Test of <time.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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/>. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <ctime>
diff --git a/tests/test-time.c b/tests/test-time.c
new file mode 100644
index 0000000..0c78f36
--- /dev/null
+++ b/tests/test-time.c
@@ -0,0 +1,35 @@
+/* Test of <time.h> substitute.
+ Copyright (C) 2007, 2009-2011 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/test-unistd-c++.cc b/tests/test-unistd-c++.cc
new file mode 100644
index 0000000..c63cf3d
--- /dev/null
+++ b/tests/test-unistd-c++.cc
@@ -0,0 +1,203 @@
+/* Test of <unistd.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_CHOWN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::chown, int, (const char *, uid_t, gid_t));
+#endif
+
+#if GNULIB_TEST_CLOSE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::close, int, (int));
+#endif
+
+SIGNATURE_CHECK (GNULIB_NAMESPACE::dup, int, (int));
+
+#if GNULIB_TEST_DUP2
+SIGNATURE_CHECK (GNULIB_NAMESPACE::dup2, int, (int, int));
+#endif
+
+#if GNULIB_TEST_DUP3
+SIGNATURE_CHECK (GNULIB_NAMESPACE::dup3, int, (int, int, int));
+#endif
+
+#if GNULIB_TEST_EUIDACCESS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::euidaccess, int, (const char *, int));
+#endif
+
+#if GNULIB_TEST_FACCESSAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::faccessat, int,
+ (int, char const *, int, int));
+#endif
+
+#if GNULIB_TEST_FCHDIR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fchdir, int, (int));
+#endif
+
+#if GNULIB_TEST_FCHOWNAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fchownat, int,
+ (int, char const *, uid_t, gid_t, int));
+#endif
+
+#if GNULIB_TEST_FSYNC
+SIGNATURE_CHECK (GNULIB_NAMESPACE::fsync, int, (int));
+#endif
+
+#if GNULIB_TEST_FTRUNCATE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ftruncate, int, (int, off_t));
+#endif
+
+#if GNULIB_TEST_GETCWD
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getcwd, char *, (char *, size_t));
+#endif
+
+#if GNULIB_TEST_GETDOMAINNAME
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getdomainname, int, (char *, size_t));
+#endif
+
+#if GNULIB_TEST_GETDTABLESIZE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getdtablesize, int, (void));
+#endif
+
+#if GNULIB_TEST_GETGROUPS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getgroups, int, (int, gid_t *));
+#endif
+
+#if GNULIB_TEST_GETHOSTNAME
+SIGNATURE_CHECK (GNULIB_NAMESPACE::gethostname, int, (char *, size_t));
+#endif
+
+#if GNULIB_TEST_GETLOGIN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getlogin, char *, (void));
+#endif
+
+#if GNULIB_TEST_GETLOGIN_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getlogin_r, int, (char *, size_t));
+#endif
+
+#if GNULIB_TEST_GETPAGESIZE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getpagesize, int, (void));
+#endif
+
+#if GNULIB_TEST_GETUSERSHELL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getusershell, char *, (void));
+#endif
+
+#if GNULIB_TEST_GETUSERSHELL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::setusershell, void, (void));
+#endif
+
+#if GNULIB_TEST_GETUSERSHELL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::endusershell, void, (void));
+#endif
+
+#if GNULIB_TEST_LCHOWN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::lchown, int, (char const *, uid_t, gid_t));
+#endif
+
+#if GNULIB_TEST_LINK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::link, int, (const char *, const char *));
+#endif
+
+#if GNULIB_TEST_LINKAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::linkat, int,
+ (int, const char *, int, const char *, int));
+#endif
+
+#if GNULIB_TEST_LSEEK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::lseek, off_t, (int, off_t, int));
+#endif
+
+#if GNULIB_TEST_PIPE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::pipe, int, (int[2]));
+#endif
+
+#if GNULIB_TEST_PIPE2
+SIGNATURE_CHECK (GNULIB_NAMESPACE::pipe2, int, (int[2], int));
+#endif
+
+#if GNULIB_TEST_PREAD
+SIGNATURE_CHECK (GNULIB_NAMESPACE::pread, ssize_t,
+ (int, void *, size_t, off_t));
+#endif
+
+#if GNULIB_TEST_PWRITE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::pwrite, ssize_t,
+ (int, const void *, size_t, off_t));
+#endif
+
+#if GNULIB_TEST_READLINK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::readlink, ssize_t,
+ (const char *, char *, size_t));
+#endif
+
+#if GNULIB_TEST_READLINKAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::readlinkat, ssize_t,
+ (int, char const *, char *, size_t));
+#endif
+
+#if GNULIB_TEST_RMDIR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::rmdir, int, (char const *));
+#endif
+
+#if GNULIB_TEST_SLEEP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::sleep, unsigned int, (unsigned int));
+#endif
+
+#if GNULIB_TEST_SYMLINK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::symlink, int, (char const *, char const *));
+#endif
+
+#if GNULIB_TEST_SYMLINKAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::symlinkat, int,
+ (char const *, int, char const *));
+#endif
+
+#if GNULIB_TEST_TTYNAME_R
+SIGNATURE_CHECK (GNULIB_NAMESPACE::ttyname_r, int,
+ (int fd, char *buf, size_t buflen));
+#endif
+
+#if GNULIB_TEST_UNLINK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::unlink, int, (char const *));
+#endif
+
+#if GNULIB_TEST_UNLINKAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::unlinkat, int, (int, char const *, int));
+#endif
+
+#if GNULIB_TEST_USLEEP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::usleep, int, (useconds_t));
+#endif
+
+#if GNULIB_TEST_WRITE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::write, ssize_t,
+ (int, const void *, size_t));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-unistd.c b/tests/test-unistd.c
new file mode 100644
index 0000000..be1ae06
--- /dev/null
+++ b/tests/test-unistd.c
@@ -0,0 +1,56 @@
+/* Test of <unistd.h> substitute.
+ Copyright (C) 2007, 2009-2011 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/test-unsetenv.c b/tests/test-unsetenv.c
new file mode 100644
index 0000000..9c9443b
--- /dev/null
+++ b/tests/test-unsetenv.c
@@ -0,0 +1,61 @@
+/* Tests of unsetenv.
+ Copyright (C) 2009-2011 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/test-update-copyright.sh b/tests/test-update-copyright.sh
new file mode 100755
index 0000000..83275ad
--- /dev/null
+++ b/tests/test-update-copyright.sh
@@ -0,0 +1,537 @@
+#!/bin/sh
+# Test suite for update-copyright.
+# Copyright (C) 2009-2011 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
+
+# Ensure the update-copyright program gets found.
+PATH=$abs_aux_dir:$PATH
+export PATH
+
+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
+ }
+
+# Skip this test if Perl is too old. FIXME: 5.8.0 is just a guess.
+# We have a report that 5.6.1 is inadequate and that 5.8.0 works.
+perl -e 'require 5.8.0' || {
+ echo '$0: skipping this test; Perl version is too old' 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: copyright statement not found
+$TMP.5: warning: 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: copyright statement not found
+$TMP.5: warning: 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: copyright statement not found
+$TMP.5: warning: 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: 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: 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/test-vasnprintf.c b/tests/test-vasnprintf.c
new file mode 100644
index 0000000..6b2a0ff
--- /dev/null
+++ b/tests/test-vasnprintf.c
@@ -0,0 +1,94 @@
+/* Test of vasnprintf() and asnprintf() functions.
+ Copyright (C) 2007-2011 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 void
+test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
+{
+ 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 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/test-vasprintf-posix.c b/tests/test-vasprintf-posix.c
new file mode 100644
index 0000000..b819b5b
--- /dev/null
+++ b/tests/test-vasprintf-posix.c
@@ -0,0 +1,3663 @@
+/* Test of POSIX compatible vasprintf() and asprintf() functions.
+ Copyright (C) 2007-2011 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 "minus-zero.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 = minus_zerod;
+ return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
+}
+
+/* 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", minus_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", minus_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", minus_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", minus_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", minus_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 *result;
+ int retval =
+ my_asprintf (&result, "%.4000f %d", 1.0, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ ASSERT (result[0] == '1');
+ ASSERT (result[1] == '.');
+ for (i = 0; i < 4000; i++)
+ ASSERT (result[2 + i] == '0');
+ ASSERT (strcmp (result + 2 + 4000, " 99") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ {
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.511f %d", 1.0, 99);
+ size_t i;
+ ASSERT (result != NULL);
+ ASSERT (result[0] == '1');
+ ASSERT (result[1] == '.');
+ for (i = 0; i < 511; i++)
+ ASSERT (result[2 + i] == '0');
+ ASSERT (strcmp (result + 2 + 511, " 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/test-vasprintf.c b/tests/test-vasprintf.c
new file mode 100644
index 0000000..6882d18
--- /dev/null
+++ b/tests/test-vasprintf.c
@@ -0,0 +1,103 @@
+/* Test of vasprintf() and asprintf() functions.
+ Copyright (C) 2007-2011 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);
+ }
+
+ for (repeat = 0; repeat <= 8; repeat++)
+ {
+ char *result;
+ int retval = my_asprintf (&result, "%08lx", 12345UL);
+ ASSERT (retval == 8);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00003039") == 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);
+ }
+
+ for (repeat = 0; repeat <= 8; repeat++)
+ {
+ char *result;
+ int retval = asprintf (&result, "%08lx", 12345UL);
+ ASSERT (retval == 8);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00003039") == 0);
+ free (result);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_vasprintf ();
+ test_asprintf ();
+ return 0;
+}
diff --git a/tests/test-vc-list-files-cvs.sh b/tests/test-vc-list-files-cvs.sh
new file mode 100755
index 0000000..531b269
--- /dev/null
+++ b/tests/test-vc-list-files-cvs.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# Unit tests for vc-list-files
+# Copyright (C) 2008-2011 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=.}
+. "$srcdir/init.sh"; path_prepend_ "$abs_aux_dir" .
+
+tmpdir=vc-cvs
+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 \
+ || skip_ "cvs not found in PATH"; } &&
+ 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
diff --git a/tests/test-vc-list-files-git.sh b/tests/test-vc-list-files-git.sh
new file mode 100755
index 0000000..523b2a9
--- /dev/null
+++ b/tests/test-vc-list-files-git.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+# Unit tests for vc-list-files
+# Copyright (C) 2008-2011 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=.}
+. "$srcdir/init.sh"; path_prepend_ "$abs_aux_dir" .
+
+tmpdir=vc-git-$$
+GIT_DIR= GIT_WORK_TREE=; unset GIT_DIR GIT_WORK_TREE
+
+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 \
+ || skip_ "git not found in PATH"; } &&
+ 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
diff --git a/tests/test-verify.c b/tests/test-verify.c
new file mode 100644
index 0000000..512c021
--- /dev/null
+++ b/tests/test-verify.c
@@ -0,0 +1,69 @@
+/* Test the "verify" module.
+
+ Copyright (C) 2005, 2009-2011 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. */
+
+#include <config.h>
+
+#include "verify.h"
+
+#ifndef EXP_FAIL
+# define EXP_FAIL 0
+#endif
+
+int x;
+enum { a, b, c };
+
+#if EXP_FAIL == 1
+verify (x >= 0); /* should give ERROR: non-constant expression */
+#endif
+verify (c == 2); /* should be ok */
+#if EXP_FAIL == 2
+verify (1 + 1 == 3); /* should give ERROR */
+#endif
+verify (1 == 1); verify (1 == 1); /* should be ok */
+
+enum
+{
+ item = verify_true (1 == 1) * 0 + 17 /* should be ok */
+};
+
+static int
+function (int n)
+{
+#if EXP_FAIL == 3
+ verify (n >= 0); /* should give ERROR: non-constant expression */
+#endif
+ verify (c == 2); /* should be ok */
+#if EXP_FAIL == 4
+ verify (1 + 1 == 3); /* should give ERROR */
+#endif
+ verify (1 == 1); verify (1 == 1); /* should be ok */
+
+ if (n)
+ return ((void) verify_true (1 == 1), verify_true (1 == 1) + 7); /* should be ok */
+#if EXP_FAIL == 5
+ return (verify_true (1 == 2), 5); /* should give ERROR */
+#endif
+ return 0;
+}
+
+int
+main (void)
+{
+ return !(function (0) == 0 && function (1) == 8);
+}
diff --git a/tests/test-verify.sh b/tests/test-verify.sh
new file mode 100755
index 0000000..3e76761
--- /dev/null
+++ b/tests/test-verify.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+. "${srcdir=.}/init.sh"
+
+# We are not interested in triggering bugs in the compilers and tools
+# (such as gcc 4.3.1 on openSUSE 11.0).
+unset MALLOC_PERTURB_
+
+# Rather than figure out how to invoke the compiler with the right
+# include path ourselves, we let make do it:
+(cd "$initial_cwd_" && rm -f test-verify.o \
+ && $MAKE test-verify.o >/dev/null 2>&1) \
+ || skip_ "cannot compile error-free"
+
+# Now, prove that we encounter all expected compilation failures:
+: >out
+: >err
+for i in 1 2 3 4 5; do
+ (cd "$initial_cwd_"
+ rm -f test-verify.o
+ $MAKE CFLAGS=-DEXP_FAIL=$i test-verify.o) >>out 2>>err \
+ && { warn_ "compiler didn't detect verification failure $i"; fail=1; }
+done
+
+Exit $fail
diff --git a/tests/test-version-etc.c b/tests/test-version-etc.c
new file mode 100644
index 0000000..00a5d7c
--- /dev/null
+++ b/tests/test-version-etc.c
@@ -0,0 +1,33 @@
+/* Test suite for version-etc.
+ Copyright (C) 2009-2011 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/>. */
+
+#include <config.h>
+
+#include "version-etc.h"
+
+#include "progname.h"
+
+#define AUTHORS "Sergey Poznyakoff", "Eric Blake"
+
+int
+main (int argc _GL_UNUSED, char **argv)
+{
+ set_program_name (argv[0]);
+ version_etc (stdout, "test-version-etc", "dummy", "0", AUTHORS,
+ (const char *) NULL);
+ return 0;
+}
diff --git a/tests/test-version-etc.sh b/tests/test-version-etc.sh
new file mode 100755
index 0000000..c1ed827
--- /dev/null
+++ b/tests/test-version-etc.sh
@@ -0,0 +1,43 @@
+#! /bin/sh
+# Test suite for version-etc.
+# Copyright (C) 2009-2011 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/>.
+
+TMP=ve-expected.tmp
+LC_ALL=C
+export LC_ALL
+ERR=0
+
+cat > $TMP <<EOT
+test-version-etc (PROJECT) VERSION
+COPYRIGHT Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+Written by Sergey Poznyakoff and Eric Blake.
+EOT
+
+./test-version-etc${EXEEXT} --version |
+ sed '1s/test-version-etc (.*) .*/test-version-etc (PROJECT) VERSION/
+ /^Packaged by/d
+ 2,3 s/Copyright (C) [0-9]\{4,4\}/COPYRIGHT/' |
+ tr -d '\015' |
+ diff -c $TMP - || ERR=1
+
+rm $TMP
+
+exit $ERR
diff --git a/tests/test-wchar-c++.cc b/tests/test-wchar-c++.cc
new file mode 100644
index 0000000..9b28e31
--- /dev/null
+++ b/tests/test-wchar-c++.cc
@@ -0,0 +1,218 @@
+/* Test of <wchar.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <wchar.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_BTOWC
+SIGNATURE_CHECK (GNULIB_NAMESPACE::btowc, wint_t, (int));
+#endif
+
+#if GNULIB_TEST_WCTOB
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wctob, int, (wint_t));
+#endif
+
+#if GNULIB_TEST_MBSINIT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbsinit, int, (const mbstate_t *));
+#endif
+
+#if GNULIB_TEST_MBRTOWC
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbrtowc, size_t,
+ (wchar_t *, const char *, size_t, mbstate_t *));
+#endif
+
+#if GNULIB_TEST_MBRLEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbrlen, size_t,
+ (const char *, size_t, mbstate_t *));
+#endif
+
+#if GNULIB_TEST_MBSRTOWCS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbsrtowcs, size_t,
+ (wchar_t *, const char **, size_t, mbstate_t *));
+#endif
+
+#if GNULIB_TEST_MBSNRTOWCS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::mbsnrtowcs, size_t,
+ (wchar_t *, const char **, size_t, size_t, mbstate_t *));
+#endif
+
+#if GNULIB_TEST_WCRTOMB
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcrtomb, size_t,
+ (char *, wchar_t, mbstate_t *));
+#endif
+
+#if GNULIB_TEST_WCSRTOMBS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsrtombs, size_t,
+ (char *, const wchar_t **, size_t, mbstate_t *));
+#endif
+
+#if GNULIB_TEST_WCSNRTOMBS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsnrtombs, size_t,
+ (char *, const wchar_t **, size_t, size_t, mbstate_t *));
+#endif
+
+#if GNULIB_TEST_WCWIDTH
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcwidth, int, (wchar_t));
+#endif
+
+#if GNULIB_TEST_WMEMCHR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wmemchr, wchar_t *,
+ (const wchar_t *, wchar_t, size_t));
+#endif
+
+#if GNULIB_TEST_WMEMCMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wmemcmp, int,
+ (const wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WMEMCPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wmemcpy, wchar_t *,
+ (wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WMEMMOVE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wmemmove, wchar_t *,
+ (wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WMEMSET
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wmemset, wchar_t *,
+ (wchar_t *, wchar_t, size_t));
+#endif
+
+#if GNULIB_TEST_WCSLEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcslen, size_t, (const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSNLEN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsnlen, size_t, (const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WCSCPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcscpy, wchar_t *,
+ (wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCPCPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcpcpy, wchar_t *,
+ (wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSNCPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsncpy, wchar_t *,
+ (wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WCPNCPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcpncpy, wchar_t *,
+ (wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WCSCAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcscat, wchar_t *,
+ (wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSNCAT
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsncat, wchar_t *,
+ (wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WCSCMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcscmp, int,
+ (const wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSNCMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsncmp, int,
+ (const wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WCSCASECMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcscasecmp, int,
+ (const wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSNCASECMP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsncasecmp, int,
+ (const wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WCSCOLL
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcscoll, int,
+ (const wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSXFRM
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsxfrm, size_t,
+ (wchar_t *, const wchar_t *, size_t));
+#endif
+
+#if GNULIB_TEST_WCSDUP
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsdup, wchar_t *, (const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSCHR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcschr, wchar_t *,
+ (const wchar_t *, wchar_t));
+#endif
+
+#if GNULIB_TEST_WCSRCHR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsrchr, wchar_t *,
+ (const wchar_t *, wchar_t));
+#endif
+
+#if GNULIB_TEST_WCSCSPN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcscspn, size_t,
+ (const wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSSPN
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsspn, size_t,
+ (const wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSPBRK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcspbrk, wchar_t *,
+ (const wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSSTR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcsstr, wchar_t *,
+ (const wchar_t *, const wchar_t *));
+#endif
+
+#if GNULIB_TEST_WCSTOK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcstok, wchar_t *,
+ (wchar_t *, const wchar_t *, wchar_t **));
+#endif
+
+#if GNULIB_TEST_WCSWIDTH
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wcswidth, int, (const wchar_t *, size_t));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-wchar.c b/tests/test-wchar.c
new file mode 100644
index 0000000..2d3bad7
--- /dev/null
+++ b/tests/test-wchar.c
@@ -0,0 +1,37 @@
+/* Test of <wchar.h> substitute.
+ Copyright (C) 2007-2011 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/test-wcrtomb-w32-1.sh b/tests/test-wcrtomb-w32-1.sh
new file mode 100755
index 0000000..50c82f5
--- /dev/null
+++ b/tests/test-wcrtomb-w32-1.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP1252 locale.
+./test-wcrtomb-w32${EXEEXT} French_France 1252
diff --git a/tests/test-wcrtomb-w32-2.sh b/tests/test-wcrtomb-w32-2.sh
new file mode 100755
index 0000000..783c70c
--- /dev/null
+++ b/tests/test-wcrtomb-w32-2.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP1256 locale.
+./test-wcrtomb-w32${EXEEXT} "Arabic_Saudi Arabia" 1256
diff --git a/tests/test-wcrtomb-w32-3.sh b/tests/test-wcrtomb-w32-3.sh
new file mode 100755
index 0000000..619ea64
--- /dev/null
+++ b/tests/test-wcrtomb-w32-3.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP932 locale.
+./test-wcrtomb-w32${EXEEXT} Japanese_Japan 932
diff --git a/tests/test-wcrtomb-w32-4.sh b/tests/test-wcrtomb-w32-4.sh
new file mode 100755
index 0000000..67b6803
--- /dev/null
+++ b/tests/test-wcrtomb-w32-4.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP950 locale.
+./test-wcrtomb-w32${EXEEXT} Chinese_Taiwan 950
diff --git a/tests/test-wcrtomb-w32-5.sh b/tests/test-wcrtomb-w32-5.sh
new file mode 100755
index 0000000..9841fa9
--- /dev/null
+++ b/tests/test-wcrtomb-w32-5.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Test a CP936 locale.
+./test-wcrtomb-w32${EXEEXT} Chinese_China 936
diff --git a/tests/test-wcrtomb-w32.c b/tests/test-wcrtomb-w32.c
new file mode 100644
index 0000000..0b09498
--- /dev/null
+++ b/tests/test-wcrtomb-w32.c
@@ -0,0 +1,332 @@
+/* Test of conversion of wide character to multibyte character.
+ Copyright (C) 2008-2011 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 <wchar.h>
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
+
+static int
+test_one_locale (const char *name, int codepage)
+{
+ char buf[64];
+ size_t ret;
+
+# if 1
+ /* Portable code to set the locale. */
+ {
+ char name_with_codepage[1024];
+
+ sprintf (name_with_codepage, "%s.%d", name, codepage);
+
+ /* Set the locale. */
+ if (setlocale (LC_ALL, name_with_codepage) == NULL)
+ return 77;
+ }
+# else
+ /* Hacky way to set a locale.codepage combination that setlocale() refuses
+ to set. */
+ {
+ /* Codepage of the current locale, set with setlocale().
+ Not necessarily the same as GetACP(). */
+ extern __declspec(dllimport) unsigned int __lc_codepage;
+
+ /* Set the locale. */
+ if (setlocale (LC_ALL, name) == NULL)
+ return 77;
+
+ /* Clobber the codepage and MB_CUR_MAX, both set by setlocale(). */
+ __lc_codepage = codepage;
+ switch (codepage)
+ {
+ case 1252:
+ case 1256:
+ MB_CUR_MAX = 1;
+ break;
+ case 932:
+ case 950:
+ case 936:
+ MB_CUR_MAX = 2;
+ break;
+ case 54936:
+ case 65001:
+ MB_CUR_MAX = 4;
+ break;
+ }
+
+ /* Test whether the codepage is really available. */
+ {
+ mbstate_t state;
+ wchar_t wc;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ if (mbrtowc (&wc, " ", 1, &state) == (size_t)(-1))
+ return 77;
+ }
+ }
+# endif
+
+ /* 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;
+ }
+ }
+
+ /* Test special calling convention, passing a NULL pointer. */
+ {
+ ret = wcrtomb (NULL, '\0', NULL);
+ ASSERT (ret == 1);
+ ret = wcrtomb (NULL, btowc ('x'), NULL);
+ ASSERT (ret == 1);
+ }
+
+ switch (codepage)
+ {
+ case 1252:
+ /* Locale encoding is CP1252, an extension of ISO-8859-1. */
+ {
+ /* Convert "B\374\337er": "Büßer" */
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x00FC, NULL);
+ ASSERT (ret == 1);
+ ASSERT (memcmp (buf, "\374", 1) == 0);
+ ASSERT (buf[1] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x00DF, NULL);
+ ASSERT (ret == 1);
+ ASSERT (memcmp (buf, "\337", 1) == 0);
+ ASSERT (buf[1] == 'x');
+ }
+ return 0;
+
+ case 1256:
+ /* Locale encoding is CP1256, not the same as ISO-8859-6. */
+ {
+ /* Convert "x\302\341\346y": "xآلوy" */
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x0622, NULL);
+ ASSERT (ret == 1);
+ ASSERT (memcmp (buf, "\302", 1) == 0);
+ ASSERT (buf[1] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x0644, NULL);
+ ASSERT (ret == 1);
+ ASSERT (memcmp (buf, "\341", 1) == 0);
+ ASSERT (buf[1] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x0648, NULL);
+ ASSERT (ret == 1);
+ ASSERT (memcmp (buf, "\346", 1) == 0);
+ ASSERT (buf[1] == 'x');
+ }
+ return 0;
+
+ case 932:
+ /* Locale encoding is CP932, similar to Shift_JIS. */
+ {
+ /* Convert "<\223\372\226\173\214\352>": "<日本語>" */
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x65E5, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\223\372", 2) == 0);
+ ASSERT (buf[2] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x672C, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\226\173", 2) == 0);
+ ASSERT (buf[2] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x8A9E, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\214\352", 2) == 0);
+ ASSERT (buf[2] == 'x');
+ }
+ return 0;
+
+ case 950:
+ /* Locale encoding is CP950, similar to Big5. */
+ {
+ /* Convert "<\244\351\245\273\273\171>": "<日本語>" */
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x65E5, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\244\351", 2) == 0);
+ ASSERT (buf[2] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x672C, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\245\273", 2) == 0);
+ ASSERT (buf[2] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x8A9E, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\273\171", 2) == 0);
+ ASSERT (buf[2] == 'x');
+ }
+ return 0;
+
+ case 936:
+ /* Locale encoding is CP936 = GBK, an extension of GB2312. */
+ {
+ /* Convert "<\310\325\261\276\325\132>": "<日本語>" */
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x65E5, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\310\325", 2) == 0);
+ ASSERT (buf[2] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x672C, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\261\276", 2) == 0);
+ ASSERT (buf[2] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x8A9E, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\325\132", 2) == 0);
+ ASSERT (buf[2] == 'x');
+ }
+ return 0;
+
+ case 54936:
+ /* Locale encoding is CP54936 = GB18030. */
+ {
+ /* Convert "B\250\271\201\060\211\070er": "Büßer" */
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x00FC, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\250\271", 2) == 0);
+ ASSERT (buf[2] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x00DF, NULL);
+ ASSERT (ret == 4);
+ ASSERT (memcmp (buf, "\201\060\211\070", 4) == 0);
+ ASSERT (buf[4] == 'x');
+ }
+ return 0;
+
+ case 65001:
+ /* Locale encoding is CP65001 = UTF-8. */
+ {
+ /* Convert "B\303\274\303\237er": "Büßer" */
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x00FC, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\303\274", 2) == 0);
+ ASSERT (buf[2] == 'x');
+
+ memset (buf, 'x', 8);
+ ret = wcrtomb (buf, 0x00DF, NULL);
+ ASSERT (ret == 2);
+ ASSERT (memcmp (buf, "\303\237", 2) == 0);
+ ASSERT (buf[2] == 'x');
+ }
+ return 0;
+
+ default:
+ return 1;
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int codepage = atoi (argv[argc - 1]);
+ int result;
+ int i;
+
+ result = 77;
+ for (i = 1; i < argc - 1; i++)
+ {
+ int ret = test_one_locale (argv[i], codepage);
+
+ if (ret != 77)
+ result = ret;
+ }
+
+ if (result == 77)
+ {
+ fprintf (stderr, "Skipping test: found no locale with codepage %d\n",
+ codepage);
+ }
+ return result;
+}
+
+#else
+
+int
+main (int argc, char *argv[])
+{
+ fputs ("Skipping test: not a native Windows system\n", stderr);
+ return 77;
+}
+
+#endif
diff --git a/tests/test-wcrtomb.c b/tests/test-wcrtomb.c
new file mode 100644
index 0000000..a50817f
--- /dev/null
+++ b/tests/test-wcrtomb.c
@@ -0,0 +1,162 @@
+/* Test of conversion of wide character to multibyte character.
+ Copyright (C) 2008-2011 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;
+ }
+ }
+
+ /* Test special calling convention, passing a NULL pointer. */
+ {
+ ret = wcrtomb (NULL, '\0', NULL);
+ ASSERT (ret == 1);
+ ret = wcrtomb (NULL, btowc ('x'), NULL);
+ ASSERT (ret == 1);
+ }
+
+ 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/test-wcrtomb.sh b/tests/test-wcrtomb.sh
new file mode 100755
index 0000000..3eda8f3
--- /dev/null
+++ b/tests/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/test-wctype-h-c++.cc b/tests/test-wctype-h-c++.cc
new file mode 100644
index 0000000..7208382
--- /dev/null
+++ b/tests/test-wctype-h-c++.cc
@@ -0,0 +1,65 @@
+/* Test of <wctype.h> substitute in C++ mode.
+ Copyright (C) 2010-2011 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>, 2010. */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <wctype.h>
+
+#include "signature.h"
+
+
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswalnum, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswalpha, int, (wint_t));
+#if GNULIB_TEST_ISWBLANK
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswblank, int, (wint_t));
+#endif
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswcntrl, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswdigit, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswgraph, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswlower, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswprint, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswpunct, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswspace, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswupper, int, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswxdigit, int, (wint_t));
+
+#if GNULIB_TEST_WCTYPE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wctype, wctype_t, (const char *));
+#endif
+
+#if GNULIB_TEST_ISWCTYPE
+SIGNATURE_CHECK (GNULIB_NAMESPACE::iswctype, int, (wint_t, wctype_t));
+#endif
+
+SIGNATURE_CHECK (GNULIB_NAMESPACE::towlower, wint_t, (wint_t));
+SIGNATURE_CHECK (GNULIB_NAMESPACE::towupper, wint_t, (wint_t));
+
+#if GNULIB_TEST_WCTRANS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::wctrans, wctrans_t, (const char *));
+#endif
+
+#if GNULIB_TEST_TOWCTRANS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::towctrans, wint_t, (wint_t, wctrans_t));
+#endif
+
+
+int
+main ()
+{
+}
diff --git a/tests/test-wctype-h.c b/tests/test-wctype-h.c
new file mode 100644
index 0000000..aed3b77
--- /dev/null
+++ b/tests/test-wctype-h.c
@@ -0,0 +1,74 @@
+/* Test of <wctype.h> substitute.
+ Copyright (C) 2007-2011 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;
+
+/* Check that the type wctype_t is defined. */
+wctype_t p;
+
+/* Check that the type wctrans_t is defined. */
+wctrans_t q;
+
+int
+main (void)
+{
+ /* Check that the isw* functions exist as functions or as macros. */
+ (void) iswalnum (0);
+ (void) iswalpha (0);
+ (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));
+ 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/test-xalloc-die.c b/tests/test-xalloc-die.c
new file mode 100644
index 0000000..d33e671
--- /dev/null
+++ b/tests/test-xalloc-die.c
@@ -0,0 +1,30 @@
+/* Test of xalloc_die() function.
+ Copyright (C) 2009-2011 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/test-xalloc-die.sh b/tests/test-xalloc-die.sh
new file mode 100755
index 0000000..399d249
--- /dev/null
+++ b/tests/test-xalloc-die.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# Test suite for xalloc_die.
+# Copyright (C) 2009-2011 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} > out 2> err
+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/test-xvasprintf.c b/tests/test-xvasprintf.c
new file mode 100644
index 0000000..aeeb3e5
--- /dev/null
+++ b/tests/test-xvasprintf.c
@@ -0,0 +1,129 @@
+/* Test of xvasprintf() and xasprintf() functions.
+ Copyright (C) 2007-2011 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. */
+ const 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 (void)
+{
+ 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. */
+ const 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/unsetenv.c b/tests/unsetenv.c
new file mode 100644
index 0000000..215bba0
--- /dev/null
+++ b/tests/unsetenv.c
@@ -0,0 +1,120 @@
+/* Copyright (C) 1992, 1995-2002, 2005-2011 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 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>
+
+/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
+ optimizes away the name == NULL test below. */
+#define _GL_ARG_NONNULL(params)
+
+/* Specification. */
+#include <stdlib.h>
+
+#include <errno.h>
+#if !_LIBC
+# define __set_errno(ev) ((errno) = (ev))
+#endif
+
+#include <string.h>
+#include <unistd.h>
+
+#if !_LIBC
+# define __environ 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
+
+/* In the GNU C library we must keep the namespace clean. */
+#ifdef _LIBC
+# define unsetenv __unsetenv
+#endif
+
+#if _LIBC || !HAVE_UNSETENV
+
+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;
+}
+
+#ifdef _LIBC
+# undef unsetenv
+weak_alias (__unsetenv, unsetenv)
+#endif
+
+#else /* HAVE_UNSETENV */
+
+# undef unsetenv
+
+/* Call the underlying unsetenv, in case there is hidden bookkeeping
+ that needs updating beyond just modifying environ. */
+int
+rpl_unsetenv (const char *name)
+{
+ int result = 0;
+ if (!name || !*name || strchr (name, '='))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ while (getenv (name))
+# if !VOID_UNSETENV
+ result =
+# endif
+ unsetenv (name);
+ return result;
+}
+
+#endif /* HAVE_UNSETENV */
diff --git a/tests/wctob.c b/tests/wctob.c
new file mode 100644
index 0000000..cc26afc
--- /dev/null
+++ b/tests/wctob.c
@@ -0,0 +1,38 @@
+/* Convert wide character to unibyte character.
+ Copyright (C) 2008, 2010-2011 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 ();
+ /* Handle the case where WEOF is a value that does not fit in a wchar_t. */
+ if (wc == (wchar_t)wc)
+ if (wctomb (buf, (wchar_t)wc) == 1)
+ return (unsigned char) buf[0];
+ return EOF;
+}
diff --git a/tests/wctomb-impl.h b/tests/wctomb-impl.h
new file mode 100644
index 0000000..4e95de6
--- /dev/null
+++ b/tests/wctomb-impl.h
@@ -0,0 +1,34 @@
+/* Convert wide character to multibyte character.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2011.
+
+ 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/>. */
+
+int
+wctomb (char *s, wchar_t wc)
+{
+ if (s == NULL)
+ return 0;
+ else
+ {
+ mbstate_t state;
+ size_t result;
+
+ memset (&state, 0, sizeof (mbstate_t));
+ result = wcrtomb (s, wc, &state);
+ if (result == (size_t)-1)
+ return -1;
+ return result;
+ }
+}
diff --git a/tests/wctomb.c b/tests/wctomb.c
new file mode 100644
index 0000000..889a3c6
--- /dev/null
+++ b/tests/wctomb.c
@@ -0,0 +1,25 @@
+/* Convert wide character to multibyte character.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2011.
+
+ 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 <string.h>
+#include <wchar.h>
+
+#include "wctomb-impl.h"
diff --git a/tests/zerosize-ptr.h b/tests/zerosize-ptr.h
new file mode 100644
index 0000000..beeb3da
--- /dev/null
+++ b/tests/zerosize-ptr.h
@@ -0,0 +1,68 @@
+/* Return a pointer to a zero-size object in memory.
+ Copyright (C) 2009-2011 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;
+}