summaryrefslogtreecommitdiff
path: root/gl/tests
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-05-20 12:50:01 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-05-20 12:50:01 +0200
commit5854b4c2557dcb75c6263df32932047688d5c64b (patch)
tree6ec061b102f5811c02e2472310dac347c7fb9f9f /gl/tests
parentf9f404609cd03181eb88cb7d0280b2016c9a8e67 (diff)
downloadgnutls-5854b4c2557dcb75c6263df32932047688d5c64b.tar.gz
Added new gnulib and error.h.
Diffstat (limited to 'gl/tests')
-rw-r--r--gl/tests/Makefile.am105
-rw-r--r--gl/tests/dummy.c42
-rw-r--r--gl/tests/fcntl.in.h21
-rw-r--r--gl/tests/glthread/thread.c218
-rw-r--r--gl/tests/glthread/thread.h376
-rw-r--r--gl/tests/glthread/yield.h121
-rw-r--r--gl/tests/intprops.h86
-rw-r--r--gl/tests/inttypes.in.h1110
-rw-r--r--gl/tests/test-fcntl-h.c82
-rw-r--r--gl/tests/test-intprops.c269
-rw-r--r--gl/tests/test-inttypes.c121
-rw-r--r--gl/tests/test-lock.c601
-rw-r--r--gl/tests/test-strerror.c75
-rw-r--r--gl/tests/test-strerror_r.c112
-rw-r--r--gl/tests/test-sys_socket.c14
-rw-r--r--gl/tests/test-sys_uio.c32
16 files changed, 3241 insertions, 144 deletions
diff --git a/gl/tests/Makefile.am b/gl/tests/Makefile.am
index 3b5778b79b..703b7b45d5 100644
--- a/gl/tests/Makefile.am
+++ b/gl/tests/Makefile.am
@@ -10,7 +10,7 @@
#
# Generated by gnulib-tool.
-AUTOMAKE_OPTIONS = 1.5 foreign
+AUTOMAKE_OPTIONS = 1.5 foreign subdir-objects
SUBDIRS = .
TESTS =
@@ -174,6 +174,7 @@ fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \
-e 's|@''GNULIB_FCNTL''@|$(GNULIB_FCNTL)|g' \
+ -e 's|@''GNULIB_NONBLOCKING''@|$(GNULIB_NONBLOCKING)|g' \
-e 's|@''GNULIB_OPEN''@|$(GNULIB_OPEN)|g' \
-e 's|@''GNULIB_OPENAT''@|$(GNULIB_OPENAT)|g' \
-e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
@@ -262,12 +263,72 @@ EXTRA_DIST += signature.h test-gettimeofday.c
## end gnulib module gettimeofday-tests
-## begin gnulib module intprops
+## begin gnulib module intprops-tests
+TESTS += test-intprops
+check_PROGRAMS += test-intprops
+EXTRA_DIST += test-intprops.c macros.h
-EXTRA_DIST += intprops.h
+## end gnulib module intprops-tests
-## end gnulib module intprops
+## begin gnulib module inttypes-incomplete
+
+BUILT_SOURCES += inttypes.h
+
+# We need the following in order to create <inttypes.h> when the system
+# doesn't have one that works with the given compiler.
+inttypes.h: inttypes.in.h $(top_builddir)/config.status $(WARN_ON_USE_H) $(ARG_NONNULL_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
+ -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_INTTYPES_H''@|$(NEXT_INTTYPES_H)|g' \
+ -e 's/@''PRI_MACROS_BROKEN''@/$(PRI_MACROS_BROKEN)/g' \
+ -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \
+ -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \
+ -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \
+ -e 's/@''PRIPTR_PREFIX''@/$(PRIPTR_PREFIX)/g' \
+ -e 's/@''GNULIB_IMAXABS''@/$(GNULIB_IMAXABS)/g' \
+ -e 's/@''GNULIB_IMAXDIV''@/$(GNULIB_IMAXDIV)/g' \
+ -e 's/@''GNULIB_STRTOIMAX''@/$(GNULIB_STRTOIMAX)/g' \
+ -e 's/@''GNULIB_STRTOUMAX''@/$(GNULIB_STRTOUMAX)/g' \
+ -e 's/@''HAVE_DECL_IMAXABS''@/$(HAVE_DECL_IMAXABS)/g' \
+ -e 's/@''HAVE_DECL_IMAXDIV''@/$(HAVE_DECL_IMAXDIV)/g' \
+ -e 's/@''HAVE_DECL_STRTOIMAX''@/$(HAVE_DECL_STRTOIMAX)/g' \
+ -e 's/@''HAVE_DECL_STRTOUMAX''@/$(HAVE_DECL_STRTOUMAX)/g' \
+ -e 's/@''INT32_MAX_LT_INTMAX_MAX''@/$(INT32_MAX_LT_INTMAX_MAX)/g' \
+ -e 's/@''INT64_MAX_EQ_LONG_MAX''@/$(INT64_MAX_EQ_LONG_MAX)/g' \
+ -e 's/@''UINT32_MAX_LT_UINTMAX_MAX''@/$(UINT32_MAX_LT_UINTMAX_MAX)/g' \
+ -e 's/@''UINT64_MAX_EQ_ULONG_MAX''@/$(UINT64_MAX_EQ_ULONG_MAX)/g' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+ < $(srcdir)/inttypes.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += inttypes.h inttypes.h-t
+
+EXTRA_DIST += inttypes.in.h
+
+## end gnulib module inttypes-incomplete
+
+## begin gnulib module inttypes-tests
+
+TESTS += test-inttypes
+check_PROGRAMS += test-inttypes
+EXTRA_DIST += test-inttypes.c
+
+## end gnulib module inttypes-tests
+
+## begin gnulib module lock-tests
+
+TESTS += test-lock
+check_PROGRAMS += test-lock
+test_lock_LDADD = $(LDADD) @LIBMULTITHREAD@ @YIELD_LIB@
+EXTRA_DIST += test-lock.c
+
+## end gnulib module lock-tests
## begin gnulib module memchr-tests
@@ -359,6 +420,22 @@ EXTRA_DIST += test-stdlib.c test-sys_wait.h
## end gnulib module stdlib-tests
+## 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 strerror_r-posix-tests
+
+TESTS += test-strerror_r
+check_PROGRAMS += test-strerror_r
+EXTRA_DIST += test-strerror_r.c signature.h macros.h
+
+## end gnulib module strerror_r-posix-tests
+
## begin gnulib module string-tests
TESTS += test-string
@@ -407,6 +484,20 @@ EXTRA_DIST += test-sys_time.c
## end gnulib module sys_time-tests
+## begin gnulib module sys_uio-tests
+
+TESTS += test-sys_uio
+check_PROGRAMS += test-sys_uio
+EXTRA_DIST += test-sys_uio.c
+
+## end gnulib module sys_uio-tests
+
+## begin gnulib module thread
+
+libtests_a_SOURCES += glthread/thread.h glthread/thread.c
+
+## end gnulib module thread
+
## begin gnulib module time-tests
TESTS += test-time
@@ -503,11 +594,11 @@ EXTRA_DIST += test-wchar.c
## end gnulib module wchar-tests
-## begin gnulib module dummy
+## begin gnulib module yield
-libtests_a_SOURCES += dummy.c
+libtests_a_SOURCES += glthread/yield.h
-## end gnulib module dummy
+## end gnulib module yield
# Clean up after Solaris cc.
clean-local:
diff --git a/gl/tests/dummy.c b/gl/tests/dummy.c
deleted file mode 100644
index c958ea05d8..0000000000
--- a/gl/tests/dummy.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* A dummy file, to prevent empty libraries from breaking builds.
- Copyright (C) 2004, 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/>. */
-
-/* Some systems, reportedly OpenBSD and Mac OS X, refuse to create
- libraries without any object files. You might get an error like:
-
- > ar cru .libs/libgl.a
- > ar: no archive members specified
-
- Compiling this file, and adding its object file to the library, will
- prevent the library from being empty. */
-
-/* Some systems, such as Solaris with cc 5.0, refuse to work with libraries
- that don't export any symbol. You might get an error like:
-
- > cc ... libgnu.a
- > ild: (bad file) garbled symbol table in archive ../gllib/libgnu.a
-
- Compiling this file, and adding its object file to the library, will
- prevent the library from exporting no symbols. */
-
-#ifdef __sun
-/* This declaration ensures that the library will export at least 1 symbol. */
-int gl_dummy_symbol;
-#else
-/* This declaration is solely to ensure that after preprocessing
- this file is never empty. */
-typedef int dummy;
-#endif
diff --git a/gl/tests/fcntl.in.h b/gl/tests/fcntl.in.h
index 18cac454ab..ce7c8c016c 100644
--- a/gl/tests/fcntl.in.h
+++ b/gl/tests/fcntl.in.h
@@ -182,8 +182,7 @@ _GL_WARN_ON_USE (openat, "openat is not portable - "
#endif
#if !defined O_CLOEXEC && defined O_NOINHERIT
-/* Mingw spells it `O_NOINHERIT'. Intentionally leave it
- undefined if not available. */
+/* Mingw spells it `O_NOINHERIT'. */
# define O_CLOEXEC O_NOINHERIT
#endif
@@ -219,6 +218,19 @@ _GL_WARN_ON_USE (openat, "openat is not portable - "
# define O_NONBLOCK O_NDELAY
#endif
+/* If the gnulib module 'nonblocking' is in use, guarantee a working non-zero
+ value of O_NONBLOCK. Otherwise, O_NONBLOCK is defined (above) to O_NDELAY
+ or to 0 as fallback. */
+#if @GNULIB_NONBLOCKING@
+# if O_NONBLOCK
+# define GNULIB_defined_O_NONBLOCK 0
+# else
+# define GNULIB_defined_O_NONBLOCK 1
+# undef O_NONBLOCK
+# define O_NONBLOCK 0x40000000
+# endif
+#endif
+
#ifndef O_NOCTTY
# define O_NOCTTY 0
#endif
@@ -247,6 +259,11 @@ _GL_WARN_ON_USE (openat, "openat is not portable - "
# define O_TTY_INIT 0
#endif
+#if O_ACCMODE != (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
+# undef O_ACCMODE
+# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
+#endif
+
/* For systems that distinguish between text and binary I/O.
O_BINARY is usually declared in fcntl.h */
#if !defined O_BINARY && defined _O_BINARY
diff --git a/gl/tests/glthread/thread.c b/gl/tests/glthread/thread.c
new file mode 100644
index 0000000000..bb40092fc2
--- /dev/null
+++ b/gl/tests/glthread/thread.c
@@ -0,0 +1,218 @@
+/* Creating and controlling threads.
+ Copyright (C) 2005-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 Bruno Haible <bruno@clisp.org>, 2005.
+ Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
+ gthr-win32.h. */
+
+#include <config.h>
+
+/* Specification. */
+#include "glthread/thread.h"
+
+#include <stdlib.h>
+#include "glthread/lock.h"
+
+/* ========================================================================= */
+
+#if USE_WIN32_THREADS
+
+#include <process.h>
+
+/* -------------------------- gl_thread_t datatype -------------------------- */
+
+/* The Thread-Local Storage (TLS) key that allows to access each thread's
+ 'struct gl_thread_struct *' pointer. */
+static DWORD self_key = (DWORD)-1;
+
+/* Initializes self_key. This function must only be called once. */
+static void
+do_init_self_key (void)
+{
+ self_key = TlsAlloc ();
+ /* If this fails, we're hosed. */
+ if (self_key == (DWORD)-1)
+ abort ();
+}
+
+/* Initializes self_key. */
+static void
+init_self_key (void)
+{
+ gl_once_define(static, once)
+ gl_once (once, do_init_self_key);
+}
+
+/* This structure contains information about a thread.
+ It is stored in TLS under key self_key. */
+struct gl_thread_struct
+{
+ /* Fields for managing the handle. */
+ HANDLE volatile handle;
+ CRITICAL_SECTION handle_lock;
+ /* Fields for managing the exit value. */
+ void * volatile result;
+ /* Fields for managing the thread start. */
+ void * (*func) (void *);
+ void *arg;
+};
+
+/* Return a real HANDLE object for the current thread. */
+static inline HANDLE
+get_current_thread_handle (void)
+{
+ HANDLE this_handle;
+
+ /* GetCurrentThread() returns a pseudo-handle, i.e. only a symbolic
+ identifier, not a real handle. */
+ if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
+ GetCurrentProcess (), &this_handle,
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
+ abort ();
+ return this_handle;
+}
+
+gl_thread_t
+gl_thread_self_func (void)
+{
+ gl_thread_t thread;
+
+ if (self_key == (DWORD)-1)
+ init_self_key ();
+ thread = TlsGetValue (self_key);
+ if (thread == NULL)
+ {
+ /* This happens only in threads that have not been created through
+ glthread_create(), such as the main thread. */
+ for (;;)
+ {
+ thread =
+ (struct gl_thread_struct *)
+ malloc (sizeof (struct gl_thread_struct));
+ if (thread != NULL)
+ break;
+ /* Memory allocation failed. There is not much we can do. Have to
+ busy-loop, waiting for the availability of memory. */
+ Sleep (1);
+ }
+
+ thread->handle = get_current_thread_handle ();
+ InitializeCriticalSection (&thread->handle_lock);
+ thread->result = NULL; /* just to be deterministic */
+ TlsSetValue (self_key, thread);
+ }
+ return thread;
+}
+
+/* The main function of a freshly creating thread. It's a wrapper around
+ the FUNC and ARG arguments passed to glthread_create_func. */
+static unsigned int WINAPI
+wrapper_func (void *varg)
+{
+ struct gl_thread_struct *thread = (struct gl_thread_struct *)varg;
+
+ EnterCriticalSection (&thread->handle_lock);
+ /* Create a new handle for the thread only if the parent thread did not yet
+ fill in the handle. */
+ if (thread->handle == NULL)
+ thread->handle = get_current_thread_handle ();
+ LeaveCriticalSection (&thread->handle_lock);
+
+ if (self_key == (DWORD)-1)
+ init_self_key ();
+ TlsSetValue (self_key, thread);
+
+ /* Run the thread. Store the exit value if the thread was not terminated
+ otherwise. */
+ thread->result = thread->func (thread->arg);
+ return 0;
+}
+
+int
+glthread_create_func (gl_thread_t *threadp, void * (*func) (void *), void *arg)
+{
+ struct gl_thread_struct *thread =
+ (struct gl_thread_struct *) malloc (sizeof (struct gl_thread_struct));
+ if (thread == NULL)
+ return ENOMEM;
+ thread->handle = NULL;
+ InitializeCriticalSection (&thread->handle_lock);
+ thread->result = NULL; /* just to be deterministic */
+ thread->func = func;
+ thread->arg = arg;
+
+ {
+ unsigned int thread_id;
+ HANDLE thread_handle;
+
+ thread_handle = (HANDLE)
+ _beginthreadex (NULL, 100000, wrapper_func, thread, 0, &thread_id);
+ /* calls CreateThread with the same arguments */
+ if (thread_handle == NULL)
+ {
+ DeleteCriticalSection (&thread->handle_lock);
+ free (thread);
+ return EAGAIN;
+ }
+
+ EnterCriticalSection (&thread->handle_lock);
+ if (thread->handle == NULL)
+ thread->handle = thread_handle;
+ else
+ /* thread->handle was already set by the thread itself. */
+ CloseHandle (thread_handle);
+ LeaveCriticalSection (&thread->handle_lock);
+
+ *threadp = thread;
+ return 0;
+ }
+}
+
+int
+glthread_join_func (gl_thread_t thread, void **retvalp)
+{
+ if (thread == NULL)
+ return EINVAL;
+
+ if (thread == gl_thread_self ())
+ return EDEADLK;
+
+ if (WaitForSingleObject (thread->handle, INFINITE) == WAIT_FAILED)
+ return EINVAL;
+
+ if (retvalp != NULL)
+ *retvalp = thread->result;
+
+ DeleteCriticalSection (&thread->handle_lock);
+ CloseHandle (thread->handle);
+ free (thread);
+
+ return 0;
+}
+
+int
+gl_thread_exit_func (void *retval)
+{
+ gl_thread_t thread = gl_thread_self ();
+ thread->result = retval;
+ _endthreadex (0); /* calls ExitThread (0) */
+ abort ();
+}
+
+#endif
+
+/* ========================================================================= */
diff --git a/gl/tests/glthread/thread.h b/gl/tests/glthread/thread.h
new file mode 100644
index 0000000000..370f09a378
--- /dev/null
+++ b/gl/tests/glthread/thread.h
@@ -0,0 +1,376 @@
+/* Creating and controlling threads.
+ Copyright (C) 2005-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 Bruno Haible <bruno@clisp.org>, 2005.
+ Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
+ gthr-win32.h. */
+
+/* This file contains primitives for creating and controlling threads.
+
+ Thread data type: gl_thread_t.
+
+ Creating a thread:
+ thread = gl_thread_create (func, arg);
+ Or with control of error handling:
+ err = glthread_create (&thread, func, arg);
+ extern int glthread_create (gl_thread_t *result,
+ void *(*func) (void *), void *arg);
+
+ Querying and changing the signal mask of a thread (not supported on all
+ platforms):
+ gl_thread_sigmask (how, newmask, oldmask);
+ Or with control of error handling:
+ err = glthread_sigmask (how, newmask, oldmask);
+ extern int glthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask);
+
+ Waiting for termination of another thread:
+ gl_thread_join (thread, &return_value);
+ Or with control of error handling:
+ err = glthread_join (thread, &return_value);
+ extern int glthread_join (gl_thread_t thread, void **return_value_ptr);
+
+ Getting a reference to the current thread:
+ current = gl_thread_self ();
+ extern gl_thread_t gl_thread_self (void);
+
+ Terminating the current thread:
+ gl_thread_exit (return_value);
+ extern void gl_thread_exit (void *return_value) __attribute__ ((noreturn));
+
+ Requesting custom code to be executed at fork() time(not supported on all
+ platforms):
+ gl_thread_atfork (prepare_func, parent_func, child_func);
+ Or with control of error handling:
+ err = glthread_atfork (prepare_func, parent_func, child_func);
+ extern int glthread_atfork (void (*prepare_func) (void),
+ void (*parent_func) (void),
+ void (*child_func) (void));
+ Note that even on platforms where this is supported, use of fork() and
+ threads together is problematic, see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2008-08/msg00062.html>
+ */
+
+
+#ifndef _GLTHREAD_THREAD_H
+#define _GLTHREAD_THREAD_H
+
+#include <errno.h>
+#include <stdlib.h>
+
+/* ========================================================================= */
+
+#if USE_POSIX_THREADS
+
+/* Use the POSIX threads library. */
+
+# include <pthread.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if PTHREAD_IN_USE_DETECTION_HARD
+
+/* The pthread_in_use() detection needs to be done at runtime. */
+# define pthread_in_use() \
+ glthread_in_use ()
+extern int glthread_in_use (void);
+
+# endif
+
+# if USE_POSIX_THREADS_WEAK
+
+/* Use weak references to the POSIX threads library. */
+
+/* Weak references avoid dragging in external libraries if the other parts
+ of the program don't use them. Here we use them, because we don't want
+ every program that uses libintl to depend on libpthread. This assumes
+ that libpthread would not be loaded after libintl; i.e. if libintl is
+ loaded first, by an executable that does not depend on libpthread, and
+ then a module is dynamically loaded that depends on libpthread, libintl
+ will not be multithread-safe. */
+
+/* The way to test at runtime whether libpthread is present is to test
+ whether a function pointer's value, such as &pthread_mutex_init, is
+ non-NULL. However, some versions of GCC have a bug through which, in
+ PIC mode, &foo != NULL always evaluates to true if there is a direct
+ call to foo(...) in the same function. To avoid this, we test the
+ address of a function in libpthread that we don't use. */
+
+# pragma weak pthread_create
+# pragma weak pthread_sigmask
+# pragma weak pthread_join
+# ifndef pthread_self
+# pragma weak pthread_self
+# endif
+# pragma weak pthread_exit
+# if HAVE_PTHREAD_ATFORK
+# pragma weak pthread_atfork
+# endif
+
+# if !PTHREAD_IN_USE_DETECTION_HARD
+# pragma weak pthread_cancel
+# define pthread_in_use() (pthread_cancel != NULL)
+# endif
+
+# else
+
+# if !PTHREAD_IN_USE_DETECTION_HARD
+# define pthread_in_use() 1
+# endif
+
+# endif
+
+/* -------------------------- gl_thread_t datatype -------------------------- */
+
+/* This choice of gl_thread_t assumes that
+ pthread_equal (a, b) is equivalent to ((a) == (b)).
+ This is the case on all platforms in use in 2008. */
+typedef pthread_t gl_thread_t;
+# define glthread_create(THREADP, FUNC, ARG) \
+ (pthread_in_use () ? pthread_create (THREADP, NULL, FUNC, ARG) : ENOSYS)
+# define glthread_sigmask(HOW, SET, OSET) \
+ (pthread_in_use () ? pthread_sigmask (HOW, SET, OSET) : 0)
+# define glthread_join(THREAD, RETVALP) \
+ (pthread_in_use () ? pthread_join (THREAD, RETVALP) : 0)
+# define gl_thread_self() \
+ (pthread_in_use () ? (void *) pthread_self () : NULL)
+# define gl_thread_exit(RETVAL) \
+ (pthread_in_use () ? pthread_exit (RETVAL) : 0)
+
+# if HAVE_PTHREAD_ATFORK
+# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) \
+ (pthread_in_use () ? pthread_atfork (PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) : 0)
+# else
+# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
+# endif
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_PTH_THREADS
+
+/* Use the GNU Pth threads library. */
+
+# include <pth.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if USE_PTH_THREADS_WEAK
+
+/* Use weak references to the GNU Pth threads library. */
+
+# pragma weak pth_spawn
+# pragma weak pth_sigmask
+# pragma weak pth_join
+# pragma weak pth_self
+# pragma weak pth_exit
+
+# pragma weak pth_cancel
+# define pth_in_use() (pth_cancel != NULL)
+
+# else
+
+# define pth_in_use() 1
+
+# endif
+/* -------------------------- gl_thread_t datatype -------------------------- */
+
+typedef pth_t gl_thread_t;
+# define glthread_create(THREADP, FUNC, ARG) \
+ (pth_in_use () ? ((*(THREADP) = pth_spawn (NULL, FUNC, ARG)) ? 0 : errno) : 0)
+# define glthread_sigmask(HOW, SET, OSET) \
+ (pth_in_use () && !pth_sigmask (HOW, SET, OSET) ? errno : 0)
+# define glthread_join(THREAD, RETVALP) \
+ (pth_in_use () && !pth_join (THREAD, RETVALP) ? errno : 0)
+# define gl_thread_self() \
+ (pth_in_use () ? (void *) pth_self () : 0)
+# define gl_thread_exit(RETVAL) \
+ (pth_in_use () ? pth_exit (RETVAL) : 0)
+# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_SOLARIS_THREADS
+
+/* Use the old Solaris threads library. */
+
+# include <thread.h>
+# include <synch.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if USE_SOLARIS_THREADS_WEAK
+
+/* Use weak references to the old Solaris threads library. */
+
+# pragma weak thr_create
+# pragma weak thr_join
+# pragma weak thr_self
+# pragma weak thr_exit
+
+# pragma weak thr_suspend
+# define thread_in_use() (thr_suspend != NULL)
+
+# else
+
+# define thread_in_use() 1
+
+# endif
+
+/* -------------------------- gl_thread_t datatype -------------------------- */
+
+typedef thread_t gl_thread_t;
+# define glthread_create(THREADP, FUNC, ARG) \
+ (thread_in_use () ? thr_create (NULL, 0, FUNC, ARG, 0, THREADP) : 0)
+# define glthread_sigmask(HOW, SET, OSET) \
+ (thread_in_use () ? sigprocmask (HOW, SET, OSET) : 0)
+# define glthread_join(THREAD, RETVALP) \
+ (thread_in_use () ? thr_join (THREAD, NULL, RETVALP) : 0)
+# define gl_thread_self() \
+ (thread_in_use () ? (void *) thr_self () : 0)
+# define gl_thread_exit(RETVAL) \
+ (thread_in_use () ? thr_exit (RETVAL) : 0)
+# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_WIN32_THREADS
+
+# include <windows.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/* -------------------------- gl_thread_t datatype -------------------------- */
+
+/* The gl_thread_t is a pointer to a structure in memory.
+ Why not the thread handle? If it were the thread handle, it would be hard
+ to implement gl_thread_self() (since GetCurrentThread () returns a pseudo-
+ handle, DuplicateHandle (GetCurrentThread ()) returns a handle that must be
+ closed afterwards, and there is no function for quickly retrieving a thread
+ handle from its id).
+ Why not the thread id? I tried it. It did not work: Sometimes ids appeared
+ that did not belong to running threads, and glthread_join failed with ESRCH.
+ */
+typedef struct gl_thread_struct *gl_thread_t;
+# define glthread_create(THREADP, FUNC, ARG) \
+ glthread_create_func (THREADP, FUNC, ARG)
+# define glthread_sigmask(HOW, SET, OSET) \
+ /* unsupported */ 0
+# define glthread_join(THREAD, RETVALP) \
+ glthread_join_func (THREAD, RETVALP)
+# define gl_thread_self() \
+ gl_thread_self_func ()
+# define gl_thread_exit(RETVAL) \
+ gl_thread_exit_func (RETVAL)
+# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
+extern int glthread_create_func (gl_thread_t *threadp, void * (*func) (void *), void *arg);
+extern int glthread_join_func (gl_thread_t thread, void **retvalp);
+extern gl_thread_t gl_thread_self_func (void);
+extern int gl_thread_exit_func (void *retval);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS)
+
+/* Provide dummy implementation if threads are not supported. */
+
+typedef int gl_thread_t;
+# define glthread_create(THREADP, FUNC, ARG) ENOSYS
+# define glthread_sigmask(HOW, SET, OSET) 0
+# define glthread_join(THREAD, RETVALP) 0
+# define gl_thread_self() NULL
+# define gl_thread_exit(RETVAL) 0
+# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
+
+#endif
+
+/* ========================================================================= */
+
+/* Macros with built-in error handling. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline gl_thread_t
+gl_thread_create (void *(*func) (void *arg), void *arg)
+{
+ gl_thread_t thread;
+ int ret;
+
+ ret = glthread_create (&thread, func, arg);
+ if (ret != 0)
+ abort ();
+ return thread;
+}
+#define gl_thread_sigmask(HOW, SET, OSET) \
+ do \
+ { \
+ if (glthread_sigmask (HOW, SET, OSET)) \
+ abort (); \
+ } \
+ while (0)
+#define gl_thread_join(THREAD, RETVAL) \
+ do \
+ { \
+ if (glthread_join (THREAD, RETVAL)) \
+ abort (); \
+ } \
+ while (0)
+#define gl_thread_atfork(PREPARE, PARENT, CHILD) \
+ do \
+ { \
+ if (glthread_atfork (PREPARE, PARENT, CHILD)) \
+ abort (); \
+ } \
+ while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GLTHREAD_THREAD_H */
diff --git a/gl/tests/glthread/yield.h b/gl/tests/glthread/yield.h
new file mode 100644
index 0000000000..4eb1cb845b
--- /dev/null
+++ b/gl/tests/glthread/yield.h
@@ -0,0 +1,121 @@
+/* Yielding the processor to other threads and processes.
+ Copyright (C) 2005-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. */
+
+/* This file contains a primitive for yielding the processor to other threads.
+ extern void gl_thread_yield (void);
+ */
+
+#ifndef _GLTHREAD_YIELD_H
+#define _GLTHREAD_YIELD_H
+
+#include <errno.h>
+
+/* ========================================================================= */
+
+#if USE_POSIX_THREADS
+
+/* Use the POSIX threads library. */
+
+# include <sched.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# define gl_thread_yield() \
+ sched_yield ()
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_PTH_THREADS
+
+/* Use the GNU Pth threads library. */
+
+# include <pth.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# define gl_thread_yield() \
+ pth_yield (NULL)
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_SOLARIS_THREADS
+
+/* Use the old Solaris threads library. */
+
+# include <thread.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# define gl_thread_yield() \
+ thr_yield ()
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_WIN32_THREADS
+
+# include <windows.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# define gl_thread_yield() \
+ Sleep (0)
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS)
+
+/* Provide dummy implementation if threads are not supported. */
+
+# define gl_thread_yield() 0
+
+#endif
+
+/* ========================================================================= */
+
+#endif /* _GLTHREAD_YIELD_H */
diff --git a/gl/tests/intprops.h b/gl/tests/intprops.h
deleted file mode 100644
index 58b1b3fbf4..0000000000
--- a/gl/tests/intprops.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* intprops.h -- properties of integer types
-
- Copyright (C) 2001-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 Paul Eggert. */
-
-#ifndef GL_INTPROPS_H
-# define GL_INTPROPS_H
-
-# include <limits.h>
-
-/* The extra casts in the following macros work around compiler bugs,
- e.g., in Cray C 5.0.3.0. */
-
-/* True if the arithmetic type T is an integer type. bool counts as
- an integer. */
-# define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
-
-/* True if negative values of the signed integer type T use two's
- complement, ones' complement, or signed magnitude representation,
- respectively. Much GNU code assumes two's complement, but some
- people like to be portable to all possible C hosts. */
-# define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
-# define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
-# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
-
-/* True if the arithmetic type T is signed. */
-# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-/* The maximum and minimum values for the integer type T. These
- macros have undefined behavior if T is signed and has padding bits.
- If this is a problem for you, please let us know how to fix it for
- your host. */
-# define TYPE_MINIMUM(t) \
- ((t) (! TYPE_SIGNED (t) \
- ? (t) 0 \
- : TYPE_SIGNED_MAGNITUDE (t) \
- ? ~ (t) 0 \
- : ~ TYPE_MAXIMUM (t)))
-# define TYPE_MAXIMUM(t) \
- ((t) (! TYPE_SIGNED (t) \
- ? (t) -1 \
- : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
-
-/* Return zero if T can be determined to be an unsigned type.
- Otherwise, return 1.
- When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a
- tighter bound. Otherwise, it overestimates the true bound by one byte
- when applied to unsigned types of size 2, 4, 16, ... bytes.
- The symbol signed_type_or_expr__ is private to this header file. */
-# if __GNUC__ >= 2
-# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))
-# else
-# define signed_type_or_expr__(t) 1
-# endif
-
-/* Bound on length of the string representing an unsigned integer
- value representable in B bits. log10 (2.0) < 146/485. The
- smallest value of B where this bound is not tight is 2621. */
-# define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
-
-/* Bound on length of the string representing an integer type or expression T.
- Subtract 1 for the sign bit if T is signed, and then add 1 more for
- a minus sign if needed. */
-# define INT_STRLEN_BOUND(t) \
- (INT_BITS_STRLEN_BOUND (sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) \
- + signed_type_or_expr__ (t))
-
-/* Bound on buffer size needed to represent an integer type or expression T,
- including the terminating null. */
-# define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
-
-#endif /* GL_INTPROPS_H */
diff --git a/gl/tests/inttypes.in.h b/gl/tests/inttypes.in.h
new file mode 100644
index 0000000000..7abf39403f
--- /dev/null
+++ b/gl/tests/inttypes.in.h
@@ -0,0 +1,1110 @@
+/* Copyright (C) 2006-2011 Free Software Foundation, Inc.
+ Written by Paul Eggert, Bruno Haible, Derek Price.
+ This file is part of gnulib.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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 <inttypes.h> for platforms that lack it.
+ * <http://www.opengroup.org/susv3xbd/inttypes.h.html>
+ */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+/* Include the original <inttypes.h> if it exists, and if this file
+ has not been included yet or if this file includes gnulib stdint.h
+ which in turn includes this file.
+ The include_next requires a split double-inclusion guard. */
+#if ! defined INTTYPES_H || defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+# if @HAVE_INTTYPES_H@
+# @INCLUDE_NEXT@ @NEXT_INTTYPES_H@
+# endif
+#endif
+
+#if ! defined INTTYPES_H && ! defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+#define INTTYPES_H
+
+/* Include <stdint.h> or the gnulib replacement.
+ But avoid namespace pollution on glibc systems. */
+#ifndef __GLIBC__
+# include <stdint.h>
+#endif
+/* Get CHAR_BIT. */
+#include <limits.h>
+
+#if !(INT_MIN == INT32_MIN && INT_MAX == INT32_MAX)
+# error "This file assumes that 'int' has exactly 32 bits. Please report your platform and compiler to <bug-gnulib@gnu.org>."
+#endif
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+/* 7.8.1 Macros for format specifiers */
+
+#if ! defined __cplusplus || defined __STDC_FORMAT_MACROS
+
+# if defined _TNS_R_TARGET
+ /* Tandem NonStop R series and compatible platforms released before
+ July 2005 support %Ld but not %lld. */
+# define _LONG_LONG_FORMAT_PREFIX "L"
+# else
+# define _LONG_LONG_FORMAT_PREFIX "ll"
+# endif
+
+# if !defined PRId8 || @PRI_MACROS_BROKEN@
+# undef PRId8
+# ifdef INT8_MAX
+# define PRId8 "d"
+# endif
+# endif
+# if !defined PRIi8 || @PRI_MACROS_BROKEN@
+# undef PRIi8
+# ifdef INT8_MAX
+# define PRIi8 "i"
+# endif
+# endif
+# if !defined PRIo8 || @PRI_MACROS_BROKEN@
+# undef PRIo8
+# ifdef UINT8_MAX
+# define PRIo8 "o"
+# endif
+# endif
+# if !defined PRIu8 || @PRI_MACROS_BROKEN@
+# undef PRIu8
+# ifdef UINT8_MAX
+# define PRIu8 "u"
+# endif
+# endif
+# if !defined PRIx8 || @PRI_MACROS_BROKEN@
+# undef PRIx8
+# ifdef UINT8_MAX
+# define PRIx8 "x"
+# endif
+# endif
+# if !defined PRIX8 || @PRI_MACROS_BROKEN@
+# undef PRIX8
+# ifdef UINT8_MAX
+# define PRIX8 "X"
+# endif
+# endif
+# if !defined PRId16 || @PRI_MACROS_BROKEN@
+# undef PRId16
+# ifdef INT16_MAX
+# define PRId16 "d"
+# endif
+# endif
+# if !defined PRIi16 || @PRI_MACROS_BROKEN@
+# undef PRIi16
+# ifdef INT16_MAX
+# define PRIi16 "i"
+# endif
+# endif
+# if !defined PRIo16 || @PRI_MACROS_BROKEN@
+# undef PRIo16
+# ifdef UINT16_MAX
+# define PRIo16 "o"
+# endif
+# endif
+# if !defined PRIu16 || @PRI_MACROS_BROKEN@
+# undef PRIu16
+# ifdef UINT16_MAX
+# define PRIu16 "u"
+# endif
+# endif
+# if !defined PRIx16 || @PRI_MACROS_BROKEN@
+# undef PRIx16
+# ifdef UINT16_MAX
+# define PRIx16 "x"
+# endif
+# endif
+# if !defined PRIX16 || @PRI_MACROS_BROKEN@
+# undef PRIX16
+# ifdef UINT16_MAX
+# define PRIX16 "X"
+# endif
+# endif
+# if !defined PRId32 || @PRI_MACROS_BROKEN@
+# undef PRId32
+# ifdef INT32_MAX
+# define PRId32 "d"
+# endif
+# endif
+# if !defined PRIi32 || @PRI_MACROS_BROKEN@
+# undef PRIi32
+# ifdef INT32_MAX
+# define PRIi32 "i"
+# endif
+# endif
+# if !defined PRIo32 || @PRI_MACROS_BROKEN@
+# undef PRIo32
+# ifdef UINT32_MAX
+# define PRIo32 "o"
+# endif
+# endif
+# if !defined PRIu32 || @PRI_MACROS_BROKEN@
+# undef PRIu32
+# ifdef UINT32_MAX
+# define PRIu32 "u"
+# endif
+# endif
+# if !defined PRIx32 || @PRI_MACROS_BROKEN@
+# undef PRIx32
+# ifdef UINT32_MAX
+# define PRIx32 "x"
+# endif
+# endif
+# if !defined PRIX32 || @PRI_MACROS_BROKEN@
+# undef PRIX32
+# ifdef UINT32_MAX
+# define PRIX32 "X"
+# endif
+# endif
+# ifdef INT64_MAX
+# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @INT64_MAX_EQ_LONG_MAX@)
+# define _PRI64_PREFIX "l"
+# elif defined _MSC_VER || defined __MINGW32__
+# define _PRI64_PREFIX "I64"
+# elif @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
+# define _PRI64_PREFIX _LONG_LONG_FORMAT_PREFIX
+# endif
+# if !defined PRId64 || @PRI_MACROS_BROKEN@
+# undef PRId64
+# define PRId64 _PRI64_PREFIX "d"
+# endif
+# if !defined PRIi64 || @PRI_MACROS_BROKEN@
+# undef PRIi64
+# define PRIi64 _PRI64_PREFIX "i"
+# endif
+# endif
+# ifdef UINT64_MAX
+# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @UINT64_MAX_EQ_ULONG_MAX@)
+# define _PRIu64_PREFIX "l"
+# elif defined _MSC_VER || defined __MINGW32__
+# define _PRIu64_PREFIX "I64"
+# elif @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
+# define _PRIu64_PREFIX _LONG_LONG_FORMAT_PREFIX
+# endif
+# if !defined PRIo64 || @PRI_MACROS_BROKEN@
+# undef PRIo64
+# define PRIo64 _PRIu64_PREFIX "o"
+# endif
+# if !defined PRIu64 || @PRI_MACROS_BROKEN@
+# undef PRIu64
+# define PRIu64 _PRIu64_PREFIX "u"
+# endif
+# if !defined PRIx64 || @PRI_MACROS_BROKEN@
+# undef PRIx64
+# define PRIx64 _PRIu64_PREFIX "x"
+# endif
+# if !defined PRIX64 || @PRI_MACROS_BROKEN@
+# undef PRIX64
+# define PRIX64 _PRIu64_PREFIX "X"
+# endif
+# endif
+
+# if !defined PRIdLEAST8 || @PRI_MACROS_BROKEN@
+# undef PRIdLEAST8
+# define PRIdLEAST8 "d"
+# endif
+# if !defined PRIiLEAST8 || @PRI_MACROS_BROKEN@
+# undef PRIiLEAST8
+# define PRIiLEAST8 "i"
+# endif
+# if !defined PRIoLEAST8 || @PRI_MACROS_BROKEN@
+# undef PRIoLEAST8
+# define PRIoLEAST8 "o"
+# endif
+# if !defined PRIuLEAST8 || @PRI_MACROS_BROKEN@
+# undef PRIuLEAST8
+# define PRIuLEAST8 "u"
+# endif
+# if !defined PRIxLEAST8 || @PRI_MACROS_BROKEN@
+# undef PRIxLEAST8
+# define PRIxLEAST8 "x"
+# endif
+# if !defined PRIXLEAST8 || @PRI_MACROS_BROKEN@
+# undef PRIXLEAST8
+# define PRIXLEAST8 "X"
+# endif
+# if !defined PRIdLEAST16 || @PRI_MACROS_BROKEN@
+# undef PRIdLEAST16
+# define PRIdLEAST16 "d"
+# endif
+# if !defined PRIiLEAST16 || @PRI_MACROS_BROKEN@
+# undef PRIiLEAST16
+# define PRIiLEAST16 "i"
+# endif
+# if !defined PRIoLEAST16 || @PRI_MACROS_BROKEN@
+# undef PRIoLEAST16
+# define PRIoLEAST16 "o"
+# endif
+# if !defined PRIuLEAST16 || @PRI_MACROS_BROKEN@
+# undef PRIuLEAST16
+# define PRIuLEAST16 "u"
+# endif
+# if !defined PRIxLEAST16 || @PRI_MACROS_BROKEN@
+# undef PRIxLEAST16
+# define PRIxLEAST16 "x"
+# endif
+# if !defined PRIXLEAST16 || @PRI_MACROS_BROKEN@
+# undef PRIXLEAST16
+# define PRIXLEAST16 "X"
+# endif
+# if !defined PRIdLEAST32 || @PRI_MACROS_BROKEN@
+# undef PRIdLEAST32
+# define PRIdLEAST32 "d"
+# endif
+# if !defined PRIiLEAST32 || @PRI_MACROS_BROKEN@
+# undef PRIiLEAST32
+# define PRIiLEAST32 "i"
+# endif
+# if !defined PRIoLEAST32 || @PRI_MACROS_BROKEN@
+# undef PRIoLEAST32
+# define PRIoLEAST32 "o"
+# endif
+# if !defined PRIuLEAST32 || @PRI_MACROS_BROKEN@
+# undef PRIuLEAST32
+# define PRIuLEAST32 "u"
+# endif
+# if !defined PRIxLEAST32 || @PRI_MACROS_BROKEN@
+# undef PRIxLEAST32
+# define PRIxLEAST32 "x"
+# endif
+# if !defined PRIXLEAST32 || @PRI_MACROS_BROKEN@
+# undef PRIXLEAST32
+# define PRIXLEAST32 "X"
+# endif
+# ifdef INT64_MAX
+# if !defined PRIdLEAST64 || @PRI_MACROS_BROKEN@
+# undef PRIdLEAST64
+# define PRIdLEAST64 PRId64
+# endif
+# if !defined PRIiLEAST64 || @PRI_MACROS_BROKEN@
+# undef PRIiLEAST64
+# define PRIiLEAST64 PRIi64
+# endif
+# endif
+# ifdef UINT64_MAX
+# if !defined PRIoLEAST64 || @PRI_MACROS_BROKEN@
+# undef PRIoLEAST64
+# define PRIoLEAST64 PRIo64
+# endif
+# if !defined PRIuLEAST64 || @PRI_MACROS_BROKEN@
+# undef PRIuLEAST64
+# define PRIuLEAST64 PRIu64
+# endif
+# if !defined PRIxLEAST64 || @PRI_MACROS_BROKEN@
+# undef PRIxLEAST64
+# define PRIxLEAST64 PRIx64
+# endif
+# if !defined PRIXLEAST64 || @PRI_MACROS_BROKEN@
+# undef PRIXLEAST64
+# define PRIXLEAST64 PRIX64
+# endif
+# endif
+
+# if !defined PRIdFAST8 || @PRI_MACROS_BROKEN@
+# undef PRIdFAST8
+# if INT_FAST8_MAX > INT32_MAX
+# define PRIdFAST8 PRId64
+# else
+# define PRIdFAST8 "d"
+# endif
+# endif
+# if !defined PRIiFAST8 || @PRI_MACROS_BROKEN@
+# undef PRIiFAST8
+# if INT_FAST8_MAX > INT32_MAX
+# define PRIiFAST8 PRIi64
+# else
+# define PRIiFAST8 "i"
+# endif
+# endif
+# if !defined PRIoFAST8 || @PRI_MACROS_BROKEN@
+# undef PRIoFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+# define PRIoFAST8 PRIo64
+# else
+# define PRIoFAST8 "o"
+# endif
+# endif
+# if !defined PRIuFAST8 || @PRI_MACROS_BROKEN@
+# undef PRIuFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+# define PRIuFAST8 PRIu64
+# else
+# define PRIuFAST8 "u"
+# endif
+# endif
+# if !defined PRIxFAST8 || @PRI_MACROS_BROKEN@
+# undef PRIxFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+# define PRIxFAST8 PRIx64
+# else
+# define PRIxFAST8 "x"
+# endif
+# endif
+# if !defined PRIXFAST8 || @PRI_MACROS_BROKEN@
+# undef PRIXFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+# define PRIXFAST8 PRIX64
+# else
+# define PRIXFAST8 "X"
+# endif
+# endif
+# if !defined PRIdFAST16 || @PRI_MACROS_BROKEN@
+# undef PRIdFAST16
+# if INT_FAST16_MAX > INT32_MAX
+# define PRIdFAST16 PRId64
+# else
+# define PRIdFAST16 "d"
+# endif
+# endif
+# if !defined PRIiFAST16 || @PRI_MACROS_BROKEN@
+# undef PRIiFAST16
+# if INT_FAST16_MAX > INT32_MAX
+# define PRIiFAST16 PRIi64
+# else
+# define PRIiFAST16 "i"
+# endif
+# endif
+# if !defined PRIoFAST16 || @PRI_MACROS_BROKEN@
+# undef PRIoFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+# define PRIoFAST16 PRIo64
+# else
+# define PRIoFAST16 "o"
+# endif
+# endif
+# if !defined PRIuFAST16 || @PRI_MACROS_BROKEN@
+# undef PRIuFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+# define PRIuFAST16 PRIu64
+# else
+# define PRIuFAST16 "u"
+# endif
+# endif
+# if !defined PRIxFAST16 || @PRI_MACROS_BROKEN@
+# undef PRIxFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+# define PRIxFAST16 PRIx64
+# else
+# define PRIxFAST16 "x"
+# endif
+# endif
+# if !defined PRIXFAST16 || @PRI_MACROS_BROKEN@
+# undef PRIXFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+# define PRIXFAST16 PRIX64
+# else
+# define PRIXFAST16 "X"
+# endif
+# endif
+# if !defined PRIdFAST32 || @PRI_MACROS_BROKEN@
+# undef PRIdFAST32
+# if INT_FAST32_MAX > INT32_MAX
+# define PRIdFAST32 PRId64
+# else
+# define PRIdFAST32 "d"
+# endif
+# endif
+# if !defined PRIiFAST32 || @PRI_MACROS_BROKEN@
+# undef PRIiFAST32
+# if INT_FAST32_MAX > INT32_MAX
+# define PRIiFAST32 PRIi64
+# else
+# define PRIiFAST32 "i"
+# endif
+# endif
+# if !defined PRIoFAST32 || @PRI_MACROS_BROKEN@
+# undef PRIoFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+# define PRIoFAST32 PRIo64
+# else
+# define PRIoFAST32 "o"
+# endif
+# endif
+# if !defined PRIuFAST32 || @PRI_MACROS_BROKEN@
+# undef PRIuFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+# define PRIuFAST32 PRIu64
+# else
+# define PRIuFAST32 "u"
+# endif
+# endif
+# if !defined PRIxFAST32 || @PRI_MACROS_BROKEN@
+# undef PRIxFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+# define PRIxFAST32 PRIx64
+# else
+# define PRIxFAST32 "x"
+# endif
+# endif
+# if !defined PRIXFAST32 || @PRI_MACROS_BROKEN@
+# undef PRIXFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+# define PRIXFAST32 PRIX64
+# else
+# define PRIXFAST32 "X"
+# endif
+# endif
+# ifdef INT64_MAX
+# if !defined PRIdFAST64 || @PRI_MACROS_BROKEN@
+# undef PRIdFAST64
+# define PRIdFAST64 PRId64
+# endif
+# if !defined PRIiFAST64 || @PRI_MACROS_BROKEN@
+# undef PRIiFAST64
+# define PRIiFAST64 PRIi64
+# endif
+# endif
+# ifdef UINT64_MAX
+# if !defined PRIoFAST64 || @PRI_MACROS_BROKEN@
+# undef PRIoFAST64
+# define PRIoFAST64 PRIo64
+# endif
+# if !defined PRIuFAST64 || @PRI_MACROS_BROKEN@
+# undef PRIuFAST64
+# define PRIuFAST64 PRIu64
+# endif
+# if !defined PRIxFAST64 || @PRI_MACROS_BROKEN@
+# undef PRIxFAST64
+# define PRIxFAST64 PRIx64
+# endif
+# if !defined PRIXFAST64 || @PRI_MACROS_BROKEN@
+# undef PRIXFAST64
+# define PRIXFAST64 PRIX64
+# endif
+# endif
+
+# if !defined PRIdMAX || @PRI_MACROS_BROKEN@
+# undef PRIdMAX
+# if @INT32_MAX_LT_INTMAX_MAX@
+# define PRIdMAX PRId64
+# else
+# define PRIdMAX "ld"
+# endif
+# endif
+# if !defined PRIiMAX || @PRI_MACROS_BROKEN@
+# undef PRIiMAX
+# if @INT32_MAX_LT_INTMAX_MAX@
+# define PRIiMAX PRIi64
+# else
+# define PRIiMAX "li"
+# endif
+# endif
+# if !defined PRIoMAX || @PRI_MACROS_BROKEN@
+# undef PRIoMAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
+# define PRIoMAX PRIo64
+# else
+# define PRIoMAX "lo"
+# endif
+# endif
+# if !defined PRIuMAX || @PRI_MACROS_BROKEN@
+# undef PRIuMAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
+# define PRIuMAX PRIu64
+# else
+# define PRIuMAX "lu"
+# endif
+# endif
+# if !defined PRIxMAX || @PRI_MACROS_BROKEN@
+# undef PRIxMAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
+# define PRIxMAX PRIx64
+# else
+# define PRIxMAX "lx"
+# endif
+# endif
+# if !defined PRIXMAX || @PRI_MACROS_BROKEN@
+# undef PRIXMAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
+# define PRIXMAX PRIX64
+# else
+# define PRIXMAX "lX"
+# endif
+# endif
+
+# if !defined PRIdPTR || @PRI_MACROS_BROKEN@
+# undef PRIdPTR
+# ifdef INTPTR_MAX
+# define PRIdPTR @PRIPTR_PREFIX@ "d"
+# endif
+# endif
+# if !defined PRIiPTR || @PRI_MACROS_BROKEN@
+# undef PRIiPTR
+# ifdef INTPTR_MAX
+# define PRIiPTR @PRIPTR_PREFIX@ "i"
+# endif
+# endif
+# if !defined PRIoPTR || @PRI_MACROS_BROKEN@
+# undef PRIoPTR
+# ifdef UINTPTR_MAX
+# define PRIoPTR @PRIPTR_PREFIX@ "o"
+# endif
+# endif
+# if !defined PRIuPTR || @PRI_MACROS_BROKEN@
+# undef PRIuPTR
+# ifdef UINTPTR_MAX
+# define PRIuPTR @PRIPTR_PREFIX@ "u"
+# endif
+# endif
+# if !defined PRIxPTR || @PRI_MACROS_BROKEN@
+# undef PRIxPTR
+# ifdef UINTPTR_MAX
+# define PRIxPTR @PRIPTR_PREFIX@ "x"
+# endif
+# endif
+# if !defined PRIXPTR || @PRI_MACROS_BROKEN@
+# undef PRIXPTR
+# ifdef UINTPTR_MAX
+# define PRIXPTR @PRIPTR_PREFIX@ "X"
+# endif
+# endif
+
+# if !defined SCNd8 || @PRI_MACROS_BROKEN@
+# undef SCNd8
+# ifdef INT8_MAX
+# define SCNd8 "hhd"
+# endif
+# endif
+# if !defined SCNi8 || @PRI_MACROS_BROKEN@
+# undef SCNi8
+# ifdef INT8_MAX
+# define SCNi8 "hhi"
+# endif
+# endif
+# if !defined SCNo8 || @PRI_MACROS_BROKEN@
+# undef SCNo8
+# ifdef UINT8_MAX
+# define SCNo8 "hho"
+# endif
+# endif
+# if !defined SCNu8 || @PRI_MACROS_BROKEN@
+# undef SCNu8
+# ifdef UINT8_MAX
+# define SCNu8 "hhu"
+# endif
+# endif
+# if !defined SCNx8 || @PRI_MACROS_BROKEN@
+# undef SCNx8
+# ifdef UINT8_MAX
+# define SCNx8 "hhx"
+# endif
+# endif
+# if !defined SCNd16 || @PRI_MACROS_BROKEN@
+# undef SCNd16
+# ifdef INT16_MAX
+# define SCNd16 "hd"
+# endif
+# endif
+# if !defined SCNi16 || @PRI_MACROS_BROKEN@
+# undef SCNi16
+# ifdef INT16_MAX
+# define SCNi16 "hi"
+# endif
+# endif
+# if !defined SCNo16 || @PRI_MACROS_BROKEN@
+# undef SCNo16
+# ifdef UINT16_MAX
+# define SCNo16 "ho"
+# endif
+# endif
+# if !defined SCNu16 || @PRI_MACROS_BROKEN@
+# undef SCNu16
+# ifdef UINT16_MAX
+# define SCNu16 "hu"
+# endif
+# endif
+# if !defined SCNx16 || @PRI_MACROS_BROKEN@
+# undef SCNx16
+# ifdef UINT16_MAX
+# define SCNx16 "hx"
+# endif
+# endif
+# if !defined SCNd32 || @PRI_MACROS_BROKEN@
+# undef SCNd32
+# ifdef INT32_MAX
+# define SCNd32 "d"
+# endif
+# endif
+# if !defined SCNi32 || @PRI_MACROS_BROKEN@
+# undef SCNi32
+# ifdef INT32_MAX
+# define SCNi32 "i"
+# endif
+# endif
+# if !defined SCNo32 || @PRI_MACROS_BROKEN@
+# undef SCNo32
+# ifdef UINT32_MAX
+# define SCNo32 "o"
+# endif
+# endif
+# if !defined SCNu32 || @PRI_MACROS_BROKEN@
+# undef SCNu32
+# ifdef UINT32_MAX
+# define SCNu32 "u"
+# endif
+# endif
+# if !defined SCNx32 || @PRI_MACROS_BROKEN@
+# undef SCNx32
+# ifdef UINT32_MAX
+# define SCNx32 "x"
+# endif
+# endif
+# ifdef INT64_MAX
+# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @INT64_MAX_EQ_LONG_MAX@)
+# define _SCN64_PREFIX "l"
+# elif defined _MSC_VER || defined __MINGW32__
+# define _SCN64_PREFIX "I64"
+# elif @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
+# define _SCN64_PREFIX _LONG_LONG_FORMAT_PREFIX
+# endif
+# if !defined SCNd64 || @PRI_MACROS_BROKEN@
+# undef SCNd64
+# define SCNd64 _SCN64_PREFIX "d"
+# endif
+# if !defined SCNi64 || @PRI_MACROS_BROKEN@
+# undef SCNi64
+# define SCNi64 _SCN64_PREFIX "i"
+# endif
+# endif
+# ifdef UINT64_MAX
+# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @UINT64_MAX_EQ_ULONG_MAX@)
+# define _SCNu64_PREFIX "l"
+# elif defined _MSC_VER || defined __MINGW32__
+# define _SCNu64_PREFIX "I64"
+# elif @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
+# define _SCNu64_PREFIX _LONG_LONG_FORMAT_PREFIX
+# endif
+# if !defined SCNo64 || @PRI_MACROS_BROKEN@
+# undef SCNo64
+# define SCNo64 _SCNu64_PREFIX "o"
+# endif
+# if !defined SCNu64 || @PRI_MACROS_BROKEN@
+# undef SCNu64
+# define SCNu64 _SCNu64_PREFIX "u"
+# endif
+# if !defined SCNx64 || @PRI_MACROS_BROKEN@
+# undef SCNx64
+# define SCNx64 _SCNu64_PREFIX "x"
+# endif
+# endif
+
+# if !defined SCNdLEAST8 || @PRI_MACROS_BROKEN@
+# undef SCNdLEAST8
+# define SCNdLEAST8 "hhd"
+# endif
+# if !defined SCNiLEAST8 || @PRI_MACROS_BROKEN@
+# undef SCNiLEAST8
+# define SCNiLEAST8 "hhi"
+# endif
+# if !defined SCNoLEAST8 || @PRI_MACROS_BROKEN@
+# undef SCNoLEAST8
+# define SCNoLEAST8 "hho"
+# endif
+# if !defined SCNuLEAST8 || @PRI_MACROS_BROKEN@
+# undef SCNuLEAST8
+# define SCNuLEAST8 "hhu"
+# endif
+# if !defined SCNxLEAST8 || @PRI_MACROS_BROKEN@
+# undef SCNxLEAST8
+# define SCNxLEAST8 "hhx"
+# endif
+# if !defined SCNdLEAST16 || @PRI_MACROS_BROKEN@
+# undef SCNdLEAST16
+# define SCNdLEAST16 "hd"
+# endif
+# if !defined SCNiLEAST16 || @PRI_MACROS_BROKEN@
+# undef SCNiLEAST16
+# define SCNiLEAST16 "hi"
+# endif
+# if !defined SCNoLEAST16 || @PRI_MACROS_BROKEN@
+# undef SCNoLEAST16
+# define SCNoLEAST16 "ho"
+# endif
+# if !defined SCNuLEAST16 || @PRI_MACROS_BROKEN@
+# undef SCNuLEAST16
+# define SCNuLEAST16 "hu"
+# endif
+# if !defined SCNxLEAST16 || @PRI_MACROS_BROKEN@
+# undef SCNxLEAST16
+# define SCNxLEAST16 "hx"
+# endif
+# if !defined SCNdLEAST32 || @PRI_MACROS_BROKEN@
+# undef SCNdLEAST32
+# define SCNdLEAST32 "d"
+# endif
+# if !defined SCNiLEAST32 || @PRI_MACROS_BROKEN@
+# undef SCNiLEAST32
+# define SCNiLEAST32 "i"
+# endif
+# if !defined SCNoLEAST32 || @PRI_MACROS_BROKEN@
+# undef SCNoLEAST32
+# define SCNoLEAST32 "o"
+# endif
+# if !defined SCNuLEAST32 || @PRI_MACROS_BROKEN@
+# undef SCNuLEAST32
+# define SCNuLEAST32 "u"
+# endif
+# if !defined SCNxLEAST32 || @PRI_MACROS_BROKEN@
+# undef SCNxLEAST32
+# define SCNxLEAST32 "x"
+# endif
+# ifdef INT64_MAX
+# if !defined SCNdLEAST64 || @PRI_MACROS_BROKEN@
+# undef SCNdLEAST64
+# define SCNdLEAST64 SCNd64
+# endif
+# if !defined SCNiLEAST64 || @PRI_MACROS_BROKEN@
+# undef SCNiLEAST64
+# define SCNiLEAST64 SCNi64
+# endif
+# endif
+# ifdef UINT64_MAX
+# if !defined SCNoLEAST64 || @PRI_MACROS_BROKEN@
+# undef SCNoLEAST64
+# define SCNoLEAST64 SCNo64
+# endif
+# if !defined SCNuLEAST64 || @PRI_MACROS_BROKEN@
+# undef SCNuLEAST64
+# define SCNuLEAST64 SCNu64
+# endif
+# if !defined SCNxLEAST64 || @PRI_MACROS_BROKEN@
+# undef SCNxLEAST64
+# define SCNxLEAST64 SCNx64
+# endif
+# endif
+
+# if !defined SCNdFAST8 || @PRI_MACROS_BROKEN@
+# undef SCNdFAST8
+# if INT_FAST8_MAX > INT32_MAX
+# define SCNdFAST8 SCNd64
+# elif INT_FAST8_MAX == 0x7fff
+# define SCNdFAST8 "hd"
+# elif INT_FAST8_MAX == 0x7f
+# define SCNdFAST8 "hhd"
+# else
+# define SCNdFAST8 "d"
+# endif
+# endif
+# if !defined SCNiFAST8 || @PRI_MACROS_BROKEN@
+# undef SCNiFAST8
+# if INT_FAST8_MAX > INT32_MAX
+# define SCNiFAST8 SCNi64
+# elif INT_FAST8_MAX == 0x7fff
+# define SCNiFAST8 "hi"
+# elif INT_FAST8_MAX == 0x7f
+# define SCNiFAST8 "hhi"
+# else
+# define SCNiFAST8 "i"
+# endif
+# endif
+# if !defined SCNoFAST8 || @PRI_MACROS_BROKEN@
+# undef SCNoFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+# define SCNoFAST8 SCNo64
+# elif UINT_FAST8_MAX == 0xffff
+# define SCNoFAST8 "ho"
+# elif UINT_FAST8_MAX == 0xff
+# define SCNoFAST8 "hho"
+# else
+# define SCNoFAST8 "o"
+# endif
+# endif
+# if !defined SCNuFAST8 || @PRI_MACROS_BROKEN@
+# undef SCNuFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+# define SCNuFAST8 SCNu64
+# elif UINT_FAST8_MAX == 0xffff
+# define SCNuFAST8 "hu"
+# elif UINT_FAST8_MAX == 0xff
+# define SCNuFAST8 "hhu"
+# else
+# define SCNuFAST8 "u"
+# endif
+# endif
+# if !defined SCNxFAST8 || @PRI_MACROS_BROKEN@
+# undef SCNxFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+# define SCNxFAST8 SCNx64
+# elif UINT_FAST8_MAX == 0xffff
+# define SCNxFAST8 "hx"
+# elif UINT_FAST8_MAX == 0xff
+# define SCNxFAST8 "hhx"
+# else
+# define SCNxFAST8 "x"
+# endif
+# endif
+# if !defined SCNdFAST16 || @PRI_MACROS_BROKEN@
+# undef SCNdFAST16
+# if INT_FAST16_MAX > INT32_MAX
+# define SCNdFAST16 SCNd64
+# elif INT_FAST16_MAX == 0x7fff
+# define SCNdFAST16 "hd"
+# else
+# define SCNdFAST16 "d"
+# endif
+# endif
+# if !defined SCNiFAST16 || @PRI_MACROS_BROKEN@
+# undef SCNiFAST16
+# if INT_FAST16_MAX > INT32_MAX
+# define SCNiFAST16 SCNi64
+# elif INT_FAST16_MAX == 0x7fff
+# define SCNiFAST16 "hi"
+# else
+# define SCNiFAST16 "i"
+# endif
+# endif
+# if !defined SCNoFAST16 || @PRI_MACROS_BROKEN@
+# undef SCNoFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+# define SCNoFAST16 SCNo64
+# elif UINT_FAST16_MAX == 0xffff
+# define SCNoFAST16 "ho"
+# else
+# define SCNoFAST16 "o"
+# endif
+# endif
+# if !defined SCNuFAST16 || @PRI_MACROS_BROKEN@
+# undef SCNuFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+# define SCNuFAST16 SCNu64
+# elif UINT_FAST16_MAX == 0xffff
+# define SCNuFAST16 "hu"
+# else
+# define SCNuFAST16 "u"
+# endif
+# endif
+# if !defined SCNxFAST16 || @PRI_MACROS_BROKEN@
+# undef SCNxFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+# define SCNxFAST16 SCNx64
+# elif UINT_FAST16_MAX == 0xffff
+# define SCNxFAST16 "hx"
+# else
+# define SCNxFAST16 "x"
+# endif
+# endif
+# if !defined SCNdFAST32 || @PRI_MACROS_BROKEN@
+# undef SCNdFAST32
+# if INT_FAST32_MAX > INT32_MAX
+# define SCNdFAST32 SCNd64
+# else
+# define SCNdFAST32 "d"
+# endif
+# endif
+# if !defined SCNiFAST32 || @PRI_MACROS_BROKEN@
+# undef SCNiFAST32
+# if INT_FAST32_MAX > INT32_MAX
+# define SCNiFAST32 SCNi64
+# else
+# define SCNiFAST32 "i"
+# endif
+# endif
+# if !defined SCNoFAST32 || @PRI_MACROS_BROKEN@
+# undef SCNoFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+# define SCNoFAST32 SCNo64
+# else
+# define SCNoFAST32 "o"
+# endif
+# endif
+# if !defined SCNuFAST32 || @PRI_MACROS_BROKEN@
+# undef SCNuFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+# define SCNuFAST32 SCNu64
+# else
+# define SCNuFAST32 "u"
+# endif
+# endif
+# if !defined SCNxFAST32 || @PRI_MACROS_BROKEN@
+# undef SCNxFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+# define SCNxFAST32 SCNx64
+# else
+# define SCNxFAST32 "x"
+# endif
+# endif
+# ifdef INT64_MAX
+# if !defined SCNdFAST64 || @PRI_MACROS_BROKEN@
+# undef SCNdFAST64
+# define SCNdFAST64 SCNd64
+# endif
+# if !defined SCNiFAST64 || @PRI_MACROS_BROKEN@
+# undef SCNiFAST64
+# define SCNiFAST64 SCNi64
+# endif
+# endif
+# ifdef UINT64_MAX
+# if !defined SCNoFAST64 || @PRI_MACROS_BROKEN@
+# undef SCNoFAST64
+# define SCNoFAST64 SCNo64
+# endif
+# if !defined SCNuFAST64 || @PRI_MACROS_BROKEN@
+# undef SCNuFAST64
+# define SCNuFAST64 SCNu64
+# endif
+# if !defined SCNxFAST64 || @PRI_MACROS_BROKEN@
+# undef SCNxFAST64
+# define SCNxFAST64 SCNx64
+# endif
+# endif
+
+# if !defined SCNdMAX || @PRI_MACROS_BROKEN@
+# undef SCNdMAX
+# if @INT32_MAX_LT_INTMAX_MAX@
+# define SCNdMAX SCNd64
+# else
+# define SCNdMAX "ld"
+# endif
+# endif
+# if !defined SCNiMAX || @PRI_MACROS_BROKEN@
+# undef SCNiMAX
+# if @INT32_MAX_LT_INTMAX_MAX@
+# define SCNiMAX SCNi64
+# else
+# define SCNiMAX "li"
+# endif
+# endif
+# if !defined SCNoMAX || @PRI_MACROS_BROKEN@
+# undef SCNoMAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
+# define SCNoMAX SCNo64
+# else
+# define SCNoMAX "lo"
+# endif
+# endif
+# if !defined SCNuMAX || @PRI_MACROS_BROKEN@
+# undef SCNuMAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
+# define SCNuMAX SCNu64
+# else
+# define SCNuMAX "lu"
+# endif
+# endif
+# if !defined SCNxMAX || @PRI_MACROS_BROKEN@
+# undef SCNxMAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
+# define SCNxMAX SCNx64
+# else
+# define SCNxMAX "lx"
+# endif
+# endif
+
+# if !defined SCNdPTR || @PRI_MACROS_BROKEN@
+# undef SCNdPTR
+# ifdef INTPTR_MAX
+# define SCNdPTR @PRIPTR_PREFIX@ "d"
+# endif
+# endif
+# if !defined SCNiPTR || @PRI_MACROS_BROKEN@
+# undef SCNiPTR
+# ifdef INTPTR_MAX
+# define SCNiPTR @PRIPTR_PREFIX@ "i"
+# endif
+# endif
+# if !defined SCNoPTR || @PRI_MACROS_BROKEN@
+# undef SCNoPTR
+# ifdef UINTPTR_MAX
+# define SCNoPTR @PRIPTR_PREFIX@ "o"
+# endif
+# endif
+# if !defined SCNuPTR || @PRI_MACROS_BROKEN@
+# undef SCNuPTR
+# ifdef UINTPTR_MAX
+# define SCNuPTR @PRIPTR_PREFIX@ "u"
+# endif
+# endif
+# if !defined SCNxPTR || @PRI_MACROS_BROKEN@
+# undef SCNxPTR
+# ifdef UINTPTR_MAX
+# define SCNxPTR @PRIPTR_PREFIX@ "x"
+# endif
+# endif
+
+#endif
+
+/* 7.8.2 Functions for greatest-width integer types */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if @GNULIB_IMAXABS@
+# if !@HAVE_DECL_IMAXABS@
+extern intmax_t imaxabs (intmax_t);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef imaxabs
+# if HAVE_RAW_DECL_IMAXABS
+_GL_WARN_ON_USE (imaxabs, "imaxabs is unportable - "
+ "use gnulib module imaxabs for portability");
+# endif
+#endif
+
+#if @GNULIB_IMAXDIV@
+# if !@HAVE_DECL_IMAXDIV@
+# if !GNULIB_defined_imaxdiv_t
+typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t;
+# define GNULIB_defined_imaxdiv_t 1
+# endif
+extern imaxdiv_t imaxdiv (intmax_t, intmax_t);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef imaxdiv
+# if HAVE_RAW_DECL_IMAXDIV
+_GL_WARN_ON_USE (imaxdiv, "imaxdiv is unportable - "
+ "use gnulib module imaxdiv for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOIMAX@
+# if !@HAVE_DECL_STRTOIMAX@
+# undef strtoimax
+extern intmax_t strtoimax (const char *, char **, int) _GL_ARG_NONNULL ((1));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef strtoimax
+# if HAVE_RAW_DECL_STRTOIMAX
+_GL_WARN_ON_USE (strtoimax, "strtoimax is unportable - "
+ "use gnulib module strtoimax for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOUMAX@
+# if !@HAVE_DECL_STRTOUMAX@
+# undef strtoumax
+extern uintmax_t strtoumax (const char *, char **, int) _GL_ARG_NONNULL ((1));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef strtoumax
+# if HAVE_RAW_DECL_STRTOUMAX
+_GL_WARN_ON_USE (strtoumax, "strtoumax is unportable - "
+ "use gnulib module strtoumax for portability");
+# endif
+#endif
+
+/* Don't bother defining or declaring wcstoimax and wcstoumax, since
+ wide-character functions like this are hardly ever useful. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined INTTYPES_H && !defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H */
diff --git a/gl/tests/test-fcntl-h.c b/gl/tests/test-fcntl-h.c
index dd20fbb406..648701ef4b 100644
--- a/gl/tests/test-fcntl-h.c
+++ b/gl/tests/test-fcntl-h.c
@@ -29,10 +29,88 @@ int o = O_DIRECT | O_DIRECTORY | O_DSYNC | O_NDELAY | O_NOATIME | O_NONBLOCK
int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
/* Check that the FD_* macros are defined. */
-int fd = FD_CLOEXEC;
+int i = FD_CLOEXEC;
int
main (void)
{
- return 0;
+ /* Ensure no overlap in SEEK_*. */
+ switch (0)
+ {
+ case SEEK_CUR:
+ case SEEK_END:
+ case SEEK_SET:
+ ;
+ }
+
+ /* Ensure no dangerous overlap in non-zero gnulib-defined replacements. */
+ switch (O_RDONLY)
+ {
+ /* Access modes */
+ case O_RDONLY:
+ case O_WRONLY:
+ case O_RDWR:
+#if O_EXEC && O_EXEC != O_RDONLY
+ case O_EXEC:
+#endif
+#if O_SEARCH && O_EXEC != O_SEARCH && O_SEARCH != O_RDONLY
+ case O_SEARCH:
+#endif
+ i = O_ACCMODE == (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH);
+ break;
+
+ /* Everyone should have these */
+ case O_CREAT:
+ case O_EXCL:
+ case O_TRUNC:
+ case O_APPEND:
+ break;
+
+ /* These might be 0 or O_RDONLY, only test non-zero versions. */
+#if O_CLOEXEC
+ case O_CLOEXEC:
+#endif
+#if O_DIRECT
+ case O_DIRECT:
+#endif
+#if O_DIRECTORY
+ case O_DIRECTORY:
+#endif
+#if O_DSYNC
+ case O_DSYNC:
+#endif
+#if O_NOATIME
+ case O_NOATIME:
+#endif
+#if O_NONBLOCK
+ case O_NONBLOCK:
+#endif
+#if O_NOCTTY
+ case O_NOCTTY:
+#endif
+#if O_NOFOLLOW
+ case O_NOFOLLOW:
+#endif
+#if O_NOLINKS
+ case O_NOLINKS:
+#endif
+#if O_RSYNC && O_RSYNC != O_DSYNC
+ case O_RSYNC:
+#endif
+#if O_SYNC && O_SYNC != O_RSYNC
+ case O_SYNC:
+#endif
+#if O_TTY_INIT
+ case O_TTY_INIT:
+#endif
+#if O_BINARY
+ case O_BINARY:
+#endif
+#if O_TEXT
+ case O_TEXT:
+#endif
+ ;
+ }
+
+ return !i;
}
diff --git a/gl/tests/test-intprops.c b/gl/tests/test-intprops.c
new file mode 100644
index 0000000000..8fc582b90f
--- /dev/null
+++ b/gl/tests/test-intprops.c
@@ -0,0 +1,269 @@
+/* Test intprops.h.
+ 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 Paul Eggert. */
+
+#include <config.h>
+
+#include "intprops.h"
+#include "verify.h"
+
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include "macros.h"
+
+/* VERIFY (X) uses a static assertion for compilers that are known to work,
+ and falls back on a dynamic assertion for other compilers.
+ These tests should be checkable via 'verify' rather than 'ASSERT', but
+ using 'verify' would run into a bug with HP-UX 11.23 cc; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>. */
+#if __GNUC__ || __SUNPRO_C
+# define VERIFY(x) do { verify (x); } while (0)
+#else
+# define VERIFY(x) ASSERT (x)
+#endif
+
+int
+main (void)
+{
+ /* Use VERIFY for tests that must be integer constant expressions,
+ ASSERT otherwise. */
+
+ /* TYPE_IS_INTEGER. */
+ ASSERT (TYPE_IS_INTEGER (bool));
+ ASSERT (TYPE_IS_INTEGER (char));
+ ASSERT (TYPE_IS_INTEGER (signed char));
+ ASSERT (TYPE_IS_INTEGER (unsigned char));
+ ASSERT (TYPE_IS_INTEGER (short int));
+ ASSERT (TYPE_IS_INTEGER (unsigned short int));
+ ASSERT (TYPE_IS_INTEGER (int));
+ ASSERT (TYPE_IS_INTEGER (unsigned int));
+ ASSERT (TYPE_IS_INTEGER (long int));
+ ASSERT (TYPE_IS_INTEGER (unsigned long int));
+ ASSERT (TYPE_IS_INTEGER (intmax_t));
+ ASSERT (TYPE_IS_INTEGER (uintmax_t));
+ ASSERT (! TYPE_IS_INTEGER (float));
+ ASSERT (! TYPE_IS_INTEGER (double));
+ ASSERT (! TYPE_IS_INTEGER (long double));
+
+ /* TYPE_SIGNED. */
+ /* VERIFY (! TYPE_SIGNED (bool)); // not guaranteed by gnulib substitute */
+ VERIFY (TYPE_SIGNED (signed char));
+ VERIFY (! TYPE_SIGNED (unsigned char));
+ VERIFY (TYPE_SIGNED (short int));
+ VERIFY (! TYPE_SIGNED (unsigned short int));
+ VERIFY (TYPE_SIGNED (int));
+ VERIFY (! TYPE_SIGNED (unsigned int));
+ VERIFY (TYPE_SIGNED (long int));
+ VERIFY (! TYPE_SIGNED (unsigned long int));
+ VERIFY (TYPE_SIGNED (intmax_t));
+ VERIFY (! TYPE_SIGNED (uintmax_t));
+ ASSERT (TYPE_SIGNED (float));
+ ASSERT (TYPE_SIGNED (double));
+ ASSERT (TYPE_SIGNED (long double));
+
+ /* Integer representation. */
+ VERIFY (INT_MIN + INT_MAX < 0
+ ? (TYPE_TWOS_COMPLEMENT (int)
+ && ! TYPE_ONES_COMPLEMENT (int) && ! TYPE_SIGNED_MAGNITUDE (int))
+ : (! TYPE_TWOS_COMPLEMENT (int)
+ && (TYPE_ONES_COMPLEMENT (int) || TYPE_SIGNED_MAGNITUDE (int))));
+
+ /* TYPE_MINIMUM, TYPE_MAXIMUM. */
+ VERIFY (TYPE_MINIMUM (char) == CHAR_MIN);
+ VERIFY (TYPE_MAXIMUM (char) == CHAR_MAX);
+ VERIFY (TYPE_MINIMUM (unsigned char) == 0);
+ VERIFY (TYPE_MAXIMUM (unsigned char) == UCHAR_MAX);
+ VERIFY (TYPE_MINIMUM (signed char) == SCHAR_MIN);
+ VERIFY (TYPE_MAXIMUM (signed char) == SCHAR_MAX);
+ VERIFY (TYPE_MINIMUM (short int) == SHRT_MIN);
+ VERIFY (TYPE_MAXIMUM (short int) == SHRT_MAX);
+ VERIFY (TYPE_MINIMUM (unsigned short int) == 0);
+ VERIFY (TYPE_MAXIMUM (unsigned short int) == USHRT_MAX);
+ VERIFY (TYPE_MINIMUM (int) == INT_MIN);
+ VERIFY (TYPE_MAXIMUM (int) == INT_MAX);
+ VERIFY (TYPE_MINIMUM (unsigned int) == 0);
+ VERIFY (TYPE_MAXIMUM (unsigned int) == UINT_MAX);
+ VERIFY (TYPE_MINIMUM (long int) == LONG_MIN);
+ VERIFY (TYPE_MAXIMUM (long int) == LONG_MAX);
+ VERIFY (TYPE_MINIMUM (unsigned long int) == 0);
+ VERIFY (TYPE_MAXIMUM (unsigned long int) == ULONG_MAX);
+ VERIFY (TYPE_MINIMUM (intmax_t) == INTMAX_MIN);
+ VERIFY (TYPE_MAXIMUM (intmax_t) == INTMAX_MAX);
+ VERIFY (TYPE_MINIMUM (uintmax_t) == 0);
+ VERIFY (TYPE_MAXIMUM (uintmax_t) == UINTMAX_MAX);
+
+ /* INT_BITS_STRLEN_BOUND. */
+ VERIFY (INT_BITS_STRLEN_BOUND (1) == 1);
+ VERIFY (INT_BITS_STRLEN_BOUND (2620) == 789);
+
+ /* INT_STRLEN_BOUND, INT_BUFSIZE_BOUND. */
+ #ifdef INT32_MAX /* POSIX guarantees int32_t; this ports to non-POSIX. */
+ VERIFY (INT_STRLEN_BOUND (int32_t) == sizeof ("-2147483648") - 1);
+ VERIFY (INT_BUFSIZE_BOUND (int32_t) == sizeof ("-2147483648"));
+ #endif
+ #ifdef INT64_MAX
+ VERIFY (INT_STRLEN_BOUND (int64_t) == sizeof ("-9223372036854775808") - 1);
+ VERIFY (INT_BUFSIZE_BOUND (int64_t) == sizeof ("-9223372036854775808"));
+ #endif
+
+ /* All the INT_<op>_RANGE_OVERFLOW tests are equally valid as
+ INT_<op>_OVERFLOW tests, so define a single macro to do both. */
+ #define CHECK_BINOP(op, a, b, min, max, overflow) \
+ (INT_##op##_RANGE_OVERFLOW (a, b, min, max) == (overflow) \
+ && INT_##op##_OVERFLOW (a, b) == (overflow))
+ #define CHECK_UNOP(op, a, min, max, overflow) \
+ (INT_##op##_RANGE_OVERFLOW (a, min, max) == (overflow) \
+ && INT_##op##_OVERFLOW (a) == (overflow))
+
+ /* INT_<op>_RANGE_OVERFLOW, INT_<op>_OVERFLOW. */
+ VERIFY (INT_ADD_RANGE_OVERFLOW (INT_MAX, 1, INT_MIN, INT_MAX));
+ VERIFY (INT_ADD_OVERFLOW (INT_MAX, 1));
+ VERIFY (CHECK_BINOP (ADD, INT_MAX, 1, INT_MIN, INT_MAX, true));
+ VERIFY (CHECK_BINOP (ADD, INT_MAX, -1, INT_MIN, INT_MAX, false));
+ VERIFY (CHECK_BINOP (ADD, INT_MIN, 1, INT_MIN, INT_MAX, false));
+ VERIFY (CHECK_BINOP (ADD, INT_MIN, -1, INT_MIN, INT_MAX, true));
+ VERIFY (CHECK_BINOP (ADD, UINT_MAX, 1u, 0u, UINT_MAX, true));
+ VERIFY (CHECK_BINOP (ADD, 0u, 1u, 0u, UINT_MAX, false));
+
+ VERIFY (CHECK_BINOP (SUBTRACT, INT_MAX, 1, INT_MIN, INT_MAX, false));
+ VERIFY (CHECK_BINOP (SUBTRACT, INT_MAX, -1, INT_MIN, INT_MAX, true));
+ VERIFY (CHECK_BINOP (SUBTRACT, INT_MIN, 1, INT_MIN, INT_MAX, true));
+ VERIFY (CHECK_BINOP (SUBTRACT, INT_MIN, -1, INT_MIN, INT_MAX, false));
+ VERIFY (CHECK_BINOP (SUBTRACT, UINT_MAX, 1u, 0u, UINT_MAX, false));
+ VERIFY (CHECK_BINOP (SUBTRACT, 0u, 1u, 0u, UINT_MAX, true));
+
+ VERIFY (CHECK_UNOP (NEGATE, INT_MIN, INT_MIN, INT_MAX,
+ TYPE_TWOS_COMPLEMENT (int)));
+ VERIFY (CHECK_UNOP (NEGATE, 0, INT_MIN, INT_MAX, false));
+ VERIFY (CHECK_UNOP (NEGATE, INT_MAX, INT_MIN, INT_MAX, false));
+ VERIFY (CHECK_UNOP (NEGATE, 0u, 0u, UINT_MAX, false));
+ VERIFY (CHECK_UNOP (NEGATE, 1u, 0u, UINT_MAX, true));
+ VERIFY (CHECK_UNOP (NEGATE, UINT_MAX, 0u, UINT_MAX, true));
+
+ VERIFY (CHECK_BINOP (MULTIPLY, INT_MAX, INT_MAX, INT_MIN, INT_MAX, true));
+ VERIFY (CHECK_BINOP (MULTIPLY, INT_MAX, INT_MIN, INT_MIN, INT_MAX, true));
+ VERIFY (CHECK_BINOP (MULTIPLY, INT_MIN, INT_MAX, INT_MIN, INT_MAX, true));
+ VERIFY (CHECK_BINOP (MULTIPLY, INT_MIN, INT_MIN, INT_MIN, INT_MAX, true));
+ VERIFY (CHECK_BINOP (MULTIPLY, -1, INT_MIN, INT_MIN, INT_MAX,
+ INT_NEGATE_OVERFLOW (INT_MIN)));
+ VERIFY (CHECK_BINOP (MULTIPLY, LONG_MIN / INT_MAX, (long int) INT_MAX,
+ LONG_MIN, LONG_MIN, false));
+
+ VERIFY (CHECK_BINOP (DIVIDE, INT_MIN, -1, INT_MIN, INT_MAX,
+ INT_NEGATE_OVERFLOW (INT_MIN)));
+ VERIFY (CHECK_BINOP (DIVIDE, INT_MAX, 1, INT_MIN, INT_MAX, false));
+ VERIFY (CHECK_BINOP (DIVIDE, (unsigned int) INT_MIN,
+ -1u, 0u, UINT_MAX, false));
+
+ VERIFY (CHECK_BINOP (REMAINDER, INT_MIN, -1, INT_MIN, INT_MAX,
+ INT_NEGATE_OVERFLOW (INT_MIN)));
+ VERIFY (CHECK_BINOP (REMAINDER, INT_MAX, 1, INT_MIN, INT_MAX, false));
+ VERIFY (CHECK_BINOP (REMAINDER, (unsigned int) INT_MIN,
+ -1u, 0u, UINT_MAX, false));
+
+ VERIFY (CHECK_BINOP (LEFT_SHIFT, UINT_MAX, 1, 0u, UINT_MAX, true));
+ VERIFY (CHECK_BINOP (LEFT_SHIFT, UINT_MAX / 2 + 1, 1, 0u, UINT_MAX, true));
+ VERIFY (CHECK_BINOP (LEFT_SHIFT, UINT_MAX / 2, 1, 0u, UINT_MAX, false));
+
+ /* INT_<op>_OVERFLOW with mixed types. */
+ #define CHECK_SUM(a, b, overflow) \
+ VERIFY (INT_ADD_OVERFLOW (a, b) == (overflow)); \
+ VERIFY (INT_ADD_OVERFLOW (b, a) == (overflow))
+ CHECK_SUM (-1, LONG_MIN, true);
+ CHECK_SUM (-1, UINT_MAX, false);
+ CHECK_SUM (-1L, INT_MIN, INT_MIN == LONG_MIN);
+ CHECK_SUM (0u, -1, true);
+ CHECK_SUM (0u, 0, false);
+ CHECK_SUM (0u, 1, false);
+ CHECK_SUM (1, LONG_MAX, true);
+ CHECK_SUM (1, UINT_MAX, true);
+ CHECK_SUM (1L, INT_MAX, INT_MAX == LONG_MAX);
+ CHECK_SUM (1u, INT_MAX, INT_MAX == UINT_MAX);
+ CHECK_SUM (1u, INT_MIN, true);
+
+ VERIFY (! INT_SUBTRACT_OVERFLOW (INT_MAX, 1u));
+ VERIFY (! INT_SUBTRACT_OVERFLOW (UINT_MAX, 1));
+ VERIFY (! INT_SUBTRACT_OVERFLOW (0u, -1));
+ VERIFY (INT_SUBTRACT_OVERFLOW (UINT_MAX, -1));
+ VERIFY (INT_SUBTRACT_OVERFLOW (INT_MIN, 1u));
+ VERIFY (INT_SUBTRACT_OVERFLOW (-1, 0u));
+
+ #define CHECK_PRODUCT(a, b, overflow) \
+ VERIFY (INT_MULTIPLY_OVERFLOW (a, b) == (overflow)); \
+ VERIFY (INT_MULTIPLY_OVERFLOW (b, a) == (overflow))
+
+ CHECK_PRODUCT (-1, 1u, true);
+ CHECK_PRODUCT (-1, INT_MIN, INT_NEGATE_OVERFLOW (INT_MIN));
+ CHECK_PRODUCT (-1, UINT_MAX, true);
+ CHECK_PRODUCT (-12345, LONG_MAX / -12345 - 1, true);
+ CHECK_PRODUCT (-12345, LONG_MAX / -12345, false);
+ CHECK_PRODUCT (0, -1, false);
+ CHECK_PRODUCT (0, 0, false);
+ CHECK_PRODUCT (0, 0u, false);
+ CHECK_PRODUCT (0, 1, false);
+ CHECK_PRODUCT (0, INT_MAX, false);
+ CHECK_PRODUCT (0, INT_MIN, false);
+ CHECK_PRODUCT (0, UINT_MAX, false);
+ CHECK_PRODUCT (0u, -1, false);
+ CHECK_PRODUCT (0u, 0, false);
+ CHECK_PRODUCT (0u, 0u, false);
+ CHECK_PRODUCT (0u, 1, false);
+ CHECK_PRODUCT (0u, INT_MAX, false);
+ CHECK_PRODUCT (0u, INT_MIN, false);
+ CHECK_PRODUCT (0u, UINT_MAX, false);
+ CHECK_PRODUCT (1, INT_MAX, false);
+ CHECK_PRODUCT (1, INT_MIN, false);
+ CHECK_PRODUCT (1, UINT_MAX, false);
+ CHECK_PRODUCT (1u, INT_MIN, true);
+ CHECK_PRODUCT (1u, INT_MAX, UINT_MAX < INT_MAX);
+ CHECK_PRODUCT (INT_MAX, UINT_MAX, true);
+ CHECK_PRODUCT (INT_MAX, ULONG_MAX, true);
+ CHECK_PRODUCT (INT_MIN, LONG_MAX / INT_MIN - 1, true);
+ CHECK_PRODUCT (INT_MIN, LONG_MAX / INT_MIN, false);
+ CHECK_PRODUCT (INT_MIN, UINT_MAX, true);
+ CHECK_PRODUCT (INT_MIN, ULONG_MAX, true);
+
+ VERIFY (INT_DIVIDE_OVERFLOW (INT_MIN, -1L)
+ == (TYPE_TWOS_COMPLEMENT (long int) && INT_MIN == LONG_MIN));
+ VERIFY (! INT_DIVIDE_OVERFLOW (INT_MIN, UINT_MAX));
+ VERIFY (! INT_DIVIDE_OVERFLOW (INTMAX_MIN, UINTMAX_MAX));
+ VERIFY (! INT_DIVIDE_OVERFLOW (INTMAX_MIN, UINT_MAX));
+ VERIFY (INT_DIVIDE_OVERFLOW (-11, 10u));
+ VERIFY (INT_DIVIDE_OVERFLOW (-10, 10u));
+ VERIFY (! INT_DIVIDE_OVERFLOW (-9, 10u));
+ VERIFY (INT_DIVIDE_OVERFLOW (11u, -10));
+ VERIFY (INT_DIVIDE_OVERFLOW (10u, -10));
+ VERIFY (! INT_DIVIDE_OVERFLOW (9u, -10));
+
+ VERIFY (INT_REMAINDER_OVERFLOW (INT_MIN, -1L)
+ == (TYPE_TWOS_COMPLEMENT (long int) && INT_MIN == LONG_MIN));
+ VERIFY (INT_REMAINDER_OVERFLOW (-1, UINT_MAX));
+ VERIFY (INT_REMAINDER_OVERFLOW ((intmax_t) -1, UINTMAX_MAX));
+ VERIFY (INT_REMAINDER_OVERFLOW (INTMAX_MIN, UINT_MAX)
+ == (INTMAX_MAX < UINT_MAX
+ && - (unsigned int) INTMAX_MIN % UINT_MAX != 0));
+ VERIFY (INT_REMAINDER_OVERFLOW (INT_MIN, ULONG_MAX)
+ == (INT_MIN % ULONG_MAX != 1));
+ VERIFY (! INT_REMAINDER_OVERFLOW (1u, -1));
+ VERIFY (! INT_REMAINDER_OVERFLOW (37*39u, -39));
+ VERIFY (INT_REMAINDER_OVERFLOW (37*39u + 1, -39));
+ VERIFY (INT_REMAINDER_OVERFLOW (37*39u - 1, -39));
+ VERIFY (! INT_REMAINDER_OVERFLOW (LONG_MAX, -INT_MAX));
+
+ return 0;
+}
diff --git a/gl/tests/test-inttypes.c b/gl/tests/test-inttypes.c
new file mode 100644
index 0000000000..5bf952c424
--- /dev/null
+++ b/gl/tests/test-inttypes.c
@@ -0,0 +1,121 @@
+/* Test of <inttypes.h> substitute.
+ Copyright (C) 2006-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>
+
+#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */
+#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */
+#define __STDC_FORMAT_MACROS 1 /* to make it work also in C++ mode */
+#include <inttypes.h>
+
+#include <stddef.h>
+
+/* Tests for macros supposed to be defined in inttypes.h. */
+
+const char *k = /* implicit string concatenation */
+#ifdef INT8_MAX
+ PRId8 PRIi8
+#endif
+#ifdef UINT8_MAX
+ PRIo8 PRIu8 PRIx8 PRIX8
+#endif
+#ifdef INT16_MAX
+ PRId16 PRIi16
+#endif
+#ifdef UINT16_MAX
+ PRIo16 PRIu16 PRIx16 PRIX16
+#endif
+#ifdef INT32_MAX
+ PRId32 PRIi32
+#endif
+#ifdef UINT32_MAX
+ PRIo32 PRIu32 PRIx32 PRIX32
+#endif
+#ifdef INT64_MAX
+ PRId64 PRIi64
+#endif
+#ifdef UINT64_MAX
+ PRIo64 PRIu64 PRIx64 PRIX64
+#endif
+ PRIdLEAST8 PRIiLEAST8 PRIoLEAST8 PRIuLEAST8 PRIxLEAST8 PRIXLEAST8
+ PRIdLEAST16 PRIiLEAST16 PRIoLEAST16 PRIuLEAST16 PRIxLEAST16 PRIXLEAST16
+ PRIdLEAST32 PRIiLEAST32 PRIoLEAST32 PRIuLEAST32 PRIxLEAST32 PRIXLEAST32
+ PRIdLEAST64 PRIiLEAST64
+ PRIoLEAST64 PRIuLEAST64 PRIxLEAST64 PRIXLEAST64
+ PRIdFAST8 PRIiFAST8 PRIoFAST8 PRIuFAST8 PRIxFAST8 PRIXFAST8
+ PRIdFAST16 PRIiFAST16 PRIoFAST16 PRIuFAST16 PRIxFAST16 PRIXFAST16
+ PRIdFAST32 PRIiFAST32 PRIoFAST32 PRIuFAST32 PRIxFAST32 PRIXFAST32
+ PRIdFAST64 PRIiFAST64
+ PRIoFAST64 PRIuFAST64 PRIxFAST64 PRIXFAST64
+ PRIdMAX PRIiMAX PRIoMAX PRIuMAX PRIxMAX PRIXMAX
+#ifdef INTPTR_MAX
+ PRIdPTR PRIiPTR
+#endif
+#ifdef UINTPTR_MAX
+ PRIoPTR PRIuPTR PRIxPTR PRIXPTR
+#endif
+ ;
+const char *l = /* implicit string concatenation */
+#ifdef INT8_MAX
+ SCNd8 SCNi8
+#endif
+#ifdef UINT8_MAX
+ SCNo8 SCNu8 SCNx8
+#endif
+#ifdef INT16_MAX
+ SCNd16 SCNi16
+#endif
+#ifdef UINT16_MAX
+ SCNo16 SCNu16 SCNx16
+#endif
+#ifdef INT32_MAX
+ SCNd32 SCNi32
+#endif
+#ifdef UINT32_MAX
+ SCNo32 SCNu32 SCNx32
+#endif
+#ifdef INT64_MAX
+ SCNd64 SCNi64
+#endif
+#ifdef UINT64_MAX
+ SCNo64 SCNu64 SCNx64
+#endif
+ SCNdLEAST8 SCNiLEAST8 SCNoLEAST8 SCNuLEAST8 SCNxLEAST8
+ SCNdLEAST16 SCNiLEAST16 SCNoLEAST16 SCNuLEAST16 SCNxLEAST16
+ SCNdLEAST32 SCNiLEAST32 SCNoLEAST32 SCNuLEAST32 SCNxLEAST32
+ SCNdLEAST64 SCNiLEAST64
+ SCNoLEAST64 SCNuLEAST64 SCNxLEAST64
+ SCNdFAST8 SCNiFAST8 SCNoFAST8 SCNuFAST8 SCNxFAST8
+ SCNdFAST16 SCNiFAST16 SCNoFAST16 SCNuFAST16 SCNxFAST16
+ SCNdFAST32 SCNiFAST32 SCNoFAST32 SCNuFAST32 SCNxFAST32
+ SCNdFAST64 SCNiFAST64
+ SCNoFAST64 SCNuFAST64 SCNxFAST64
+ SCNdMAX SCNiMAX SCNoMAX SCNuMAX SCNxMAX
+#ifdef INTPTR_MAX
+ SCNdPTR SCNiPTR
+#endif
+#ifdef UINTPTR_MAX
+ SCNoPTR SCNuPTR SCNxPTR
+#endif
+ ;
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/gl/tests/test-lock.c b/gl/tests/test-lock.c
new file mode 100644
index 0000000000..04ce0767ff
--- /dev/null
+++ b/gl/tests/test-lock.c
@@ -0,0 +1,601 @@
+/* Test of locking in multithreaded situations.
+ Copyright (C) 2005, 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>, 2005. */
+
+#include <config.h>
+
+#if USE_POSIX_THREADS || USE_SOLARIS_THREADS || USE_PTH_THREADS || USE_WIN32_THREADS
+
+#if USE_POSIX_THREADS
+# define TEST_POSIX_THREADS 1
+#endif
+#if USE_SOLARIS_THREADS
+# define TEST_SOLARIS_THREADS 1
+#endif
+#if USE_PTH_THREADS
+# define TEST_PTH_THREADS 1
+#endif
+#if USE_WIN32_THREADS
+# define TEST_WIN32_THREADS 1
+#endif
+
+/* Whether to enable locking.
+ Uncomment this to get a test program without locking, to verify that
+ it crashes. */
+#define ENABLE_LOCKING 1
+
+/* Which tests to perform.
+ Uncomment some of these, to verify that all tests crash if no locking
+ is enabled. */
+#define DO_TEST_LOCK 1
+#define DO_TEST_RWLOCK 1
+#define DO_TEST_RECURSIVE_LOCK 1
+#define DO_TEST_ONCE 1
+
+/* Whether to help the scheduler through explicit yield().
+ Uncomment this to see if the operating system has a fair scheduler. */
+#define EXPLICIT_YIELD 1
+
+/* Whether to print debugging messages. */
+#define ENABLE_DEBUGGING 0
+
+/* Number of simultaneous threads. */
+#define THREAD_COUNT 10
+
+/* Number of operations performed in each thread.
+ This is quite high, because with a smaller count, say 5000, we often get
+ an "OK" result even without ENABLE_LOCKING (on Linux/x86). */
+#define REPEAT_COUNT 50000
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !ENABLE_LOCKING
+# undef USE_POSIX_THREADS
+# undef USE_SOLARIS_THREADS
+# undef USE_PTH_THREADS
+# undef USE_WIN32_THREADS
+#endif
+#include "glthread/lock.h"
+
+#if !ENABLE_LOCKING
+# if TEST_POSIX_THREADS
+# define USE_POSIX_THREADS 1
+# endif
+# if TEST_SOLARIS_THREADS
+# define USE_SOLARIS_THREADS 1
+# endif
+# if TEST_PTH_THREADS
+# define USE_PTH_THREADS 1
+# endif
+# if TEST_WIN32_THREADS
+# define USE_WIN32_THREADS 1
+# endif
+#endif
+
+#include "glthread/thread.h"
+#include "glthread/yield.h"
+
+#if ENABLE_DEBUGGING
+# define dbgprintf printf
+#else
+# define dbgprintf if (0) printf
+#endif
+
+#if EXPLICIT_YIELD
+# define yield() gl_thread_yield ()
+#else
+# define yield()
+#endif
+
+#define ACCOUNT_COUNT 4
+
+static int account[ACCOUNT_COUNT];
+
+static int
+random_account (void)
+{
+ return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT;
+}
+
+static void
+check_accounts (void)
+{
+ int i, sum;
+
+ sum = 0;
+ for (i = 0; i < ACCOUNT_COUNT; i++)
+ sum += account[i];
+ if (sum != ACCOUNT_COUNT * 1000)
+ abort ();
+}
+
+
+/* ------------------- Test normal (non-recursive) locks ------------------- */
+
+/* Test normal locks by having several bank accounts and several threads
+ which shuffle around money between the accounts and another thread
+ checking that all the money is still there. */
+
+gl_lock_define_initialized(static, my_lock)
+
+static void *
+lock_mutator_thread (void *arg)
+{
+ int repeat;
+
+ for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
+ {
+ int i1, i2, value;
+
+ dbgprintf ("Mutator %p before lock\n", gl_thread_self ());
+ gl_lock_lock (my_lock);
+ dbgprintf ("Mutator %p after lock\n", gl_thread_self ());
+
+ i1 = random_account ();
+ i2 = random_account ();
+ value = ((unsigned int) rand () >> 3) % 10;
+ account[i1] += value;
+ account[i2] -= value;
+
+ dbgprintf ("Mutator %p before unlock\n", gl_thread_self ());
+ gl_lock_unlock (my_lock);
+ dbgprintf ("Mutator %p after unlock\n", gl_thread_self ());
+
+ dbgprintf ("Mutator %p before check lock\n", gl_thread_self ());
+ gl_lock_lock (my_lock);
+ check_accounts ();
+ gl_lock_unlock (my_lock);
+ dbgprintf ("Mutator %p after check unlock\n", gl_thread_self ());
+
+ yield ();
+ }
+
+ dbgprintf ("Mutator %p dying.\n", gl_thread_self ());
+ return NULL;
+}
+
+static volatile int lock_checker_done;
+
+static void *
+lock_checker_thread (void *arg)
+{
+ while (!lock_checker_done)
+ {
+ dbgprintf ("Checker %p before check lock\n", gl_thread_self ());
+ gl_lock_lock (my_lock);
+ check_accounts ();
+ gl_lock_unlock (my_lock);
+ dbgprintf ("Checker %p after check unlock\n", gl_thread_self ());
+
+ yield ();
+ }
+
+ dbgprintf ("Checker %p dying.\n", gl_thread_self ());
+ return NULL;
+}
+
+static void
+test_lock (void)
+{
+ int i;
+ gl_thread_t checkerthread;
+ gl_thread_t threads[THREAD_COUNT];
+
+ /* Initialization. */
+ for (i = 0; i < ACCOUNT_COUNT; i++)
+ account[i] = 1000;
+ lock_checker_done = 0;
+
+ /* Spawn the threads. */
+ checkerthread = gl_thread_create (lock_checker_thread, NULL);
+ for (i = 0; i < THREAD_COUNT; i++)
+ threads[i] = gl_thread_create (lock_mutator_thread, NULL);
+
+ /* Wait for the threads to terminate. */
+ for (i = 0; i < THREAD_COUNT; i++)
+ gl_thread_join (threads[i], NULL);
+ lock_checker_done = 1;
+ gl_thread_join (checkerthread, NULL);
+ check_accounts ();
+}
+
+
+/* ----------------- Test read-write (non-recursive) locks ----------------- */
+
+/* Test read-write locks by having several bank accounts and several threads
+ which shuffle around money between the accounts and several other threads
+ that check that all the money is still there. */
+
+gl_rwlock_define_initialized(static, my_rwlock)
+
+static void *
+rwlock_mutator_thread (void *arg)
+{
+ int repeat;
+
+ for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
+ {
+ int i1, i2, value;
+
+ dbgprintf ("Mutator %p before wrlock\n", gl_thread_self ());
+ gl_rwlock_wrlock (my_rwlock);
+ dbgprintf ("Mutator %p after wrlock\n", gl_thread_self ());
+
+ i1 = random_account ();
+ i2 = random_account ();
+ value = ((unsigned int) rand () >> 3) % 10;
+ account[i1] += value;
+ account[i2] -= value;
+
+ dbgprintf ("Mutator %p before unlock\n", gl_thread_self ());
+ gl_rwlock_unlock (my_rwlock);
+ dbgprintf ("Mutator %p after unlock\n", gl_thread_self ());
+
+ yield ();
+ }
+
+ dbgprintf ("Mutator %p dying.\n", gl_thread_self ());
+ return NULL;
+}
+
+static volatile int rwlock_checker_done;
+
+static void *
+rwlock_checker_thread (void *arg)
+{
+ while (!rwlock_checker_done)
+ {
+ dbgprintf ("Checker %p before check rdlock\n", gl_thread_self ());
+ gl_rwlock_rdlock (my_rwlock);
+ check_accounts ();
+ gl_rwlock_unlock (my_rwlock);
+ dbgprintf ("Checker %p after check unlock\n", gl_thread_self ());
+
+ yield ();
+ }
+
+ dbgprintf ("Checker %p dying.\n", gl_thread_self ());
+ return NULL;
+}
+
+static void
+test_rwlock (void)
+{
+ int i;
+ gl_thread_t checkerthreads[THREAD_COUNT];
+ gl_thread_t threads[THREAD_COUNT];
+
+ /* Initialization. */
+ for (i = 0; i < ACCOUNT_COUNT; i++)
+ account[i] = 1000;
+ rwlock_checker_done = 0;
+
+ /* Spawn the threads. */
+ for (i = 0; i < THREAD_COUNT; i++)
+ checkerthreads[i] = gl_thread_create (rwlock_checker_thread, NULL);
+ for (i = 0; i < THREAD_COUNT; i++)
+ threads[i] = gl_thread_create (rwlock_mutator_thread, NULL);
+
+ /* Wait for the threads to terminate. */
+ for (i = 0; i < THREAD_COUNT; i++)
+ gl_thread_join (threads[i], NULL);
+ rwlock_checker_done = 1;
+ for (i = 0; i < THREAD_COUNT; i++)
+ gl_thread_join (checkerthreads[i], NULL);
+ check_accounts ();
+}
+
+
+/* -------------------------- Test recursive locks -------------------------- */
+
+/* Test recursive locks by having several bank accounts and several threads
+ which shuffle around money between the accounts (recursively) and another
+ thread checking that all the money is still there. */
+
+gl_recursive_lock_define_initialized(static, my_reclock)
+
+static void
+recshuffle (void)
+{
+ int i1, i2, value;
+
+ dbgprintf ("Mutator %p before lock\n", gl_thread_self ());
+ gl_recursive_lock_lock (my_reclock);
+ dbgprintf ("Mutator %p after lock\n", gl_thread_self ());
+
+ i1 = random_account ();
+ i2 = random_account ();
+ value = ((unsigned int) rand () >> 3) % 10;
+ account[i1] += value;
+ account[i2] -= value;
+
+ /* Recursive with probability 0.5. */
+ if (((unsigned int) rand () >> 3) % 2)
+ recshuffle ();
+
+ dbgprintf ("Mutator %p before unlock\n", gl_thread_self ());
+ gl_recursive_lock_unlock (my_reclock);
+ dbgprintf ("Mutator %p after unlock\n", gl_thread_self ());
+}
+
+static void *
+reclock_mutator_thread (void *arg)
+{
+ int repeat;
+
+ for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
+ {
+ recshuffle ();
+
+ dbgprintf ("Mutator %p before check lock\n", gl_thread_self ());
+ gl_recursive_lock_lock (my_reclock);
+ check_accounts ();
+ gl_recursive_lock_unlock (my_reclock);
+ dbgprintf ("Mutator %p after check unlock\n", gl_thread_self ());
+
+ yield ();
+ }
+
+ dbgprintf ("Mutator %p dying.\n", gl_thread_self ());
+ return NULL;
+}
+
+static volatile int reclock_checker_done;
+
+static void *
+reclock_checker_thread (void *arg)
+{
+ while (!reclock_checker_done)
+ {
+ dbgprintf ("Checker %p before check lock\n", gl_thread_self ());
+ gl_recursive_lock_lock (my_reclock);
+ check_accounts ();
+ gl_recursive_lock_unlock (my_reclock);
+ dbgprintf ("Checker %p after check unlock\n", gl_thread_self ());
+
+ yield ();
+ }
+
+ dbgprintf ("Checker %p dying.\n", gl_thread_self ());
+ return NULL;
+}
+
+static void
+test_recursive_lock (void)
+{
+ int i;
+ gl_thread_t checkerthread;
+ gl_thread_t threads[THREAD_COUNT];
+
+ /* Initialization. */
+ for (i = 0; i < ACCOUNT_COUNT; i++)
+ account[i] = 1000;
+ reclock_checker_done = 0;
+
+ /* Spawn the threads. */
+ checkerthread = gl_thread_create (reclock_checker_thread, NULL);
+ for (i = 0; i < THREAD_COUNT; i++)
+ threads[i] = gl_thread_create (reclock_mutator_thread, NULL);
+
+ /* Wait for the threads to terminate. */
+ for (i = 0; i < THREAD_COUNT; i++)
+ gl_thread_join (threads[i], NULL);
+ reclock_checker_done = 1;
+ gl_thread_join (checkerthread, NULL);
+ check_accounts ();
+}
+
+
+/* ------------------------ Test once-only execution ------------------------ */
+
+/* Test once-only execution by having several threads attempt to grab a
+ once-only task simultaneously (triggered by releasing a read-write lock). */
+
+gl_once_define(static, fresh_once)
+static int ready[THREAD_COUNT];
+static gl_lock_t ready_lock[THREAD_COUNT];
+#if ENABLE_LOCKING
+static gl_rwlock_t fire_signal[REPEAT_COUNT];
+#else
+static volatile int fire_signal_state;
+#endif
+static gl_once_t once_control;
+static int performed;
+gl_lock_define_initialized(static, performed_lock)
+
+static void
+once_execute (void)
+{
+ gl_lock_lock (performed_lock);
+ performed++;
+ gl_lock_unlock (performed_lock);
+}
+
+static void *
+once_contender_thread (void *arg)
+{
+ int id = (int) (long) arg;
+ int repeat;
+
+ for (repeat = 0; repeat <= REPEAT_COUNT; repeat++)
+ {
+ /* Tell the main thread that we're ready. */
+ gl_lock_lock (ready_lock[id]);
+ ready[id] = 1;
+ gl_lock_unlock (ready_lock[id]);
+
+ if (repeat == REPEAT_COUNT)
+ break;
+
+ dbgprintf ("Contender %p waiting for signal for round %d\n",
+ gl_thread_self (), repeat);
+#if ENABLE_LOCKING
+ /* Wait for the signal to go. */
+ gl_rwlock_rdlock (fire_signal[repeat]);
+ /* And don't hinder the others (if the scheduler is unfair). */
+ gl_rwlock_unlock (fire_signal[repeat]);
+#else
+ /* Wait for the signal to go. */
+ while (fire_signal_state <= repeat)
+ yield ();
+#endif
+ dbgprintf ("Contender %p got the signal for round %d\n",
+ gl_thread_self (), repeat);
+
+ /* Contend for execution. */
+ gl_once (once_control, once_execute);
+ }
+
+ return NULL;
+}
+
+static void
+test_once (void)
+{
+ int i, repeat;
+ gl_thread_t threads[THREAD_COUNT];
+
+ /* Initialize all variables. */
+ for (i = 0; i < THREAD_COUNT; i++)
+ {
+ ready[i] = 0;
+ gl_lock_init (ready_lock[i]);
+ }
+#if ENABLE_LOCKING
+ for (i = 0; i < REPEAT_COUNT; i++)
+ gl_rwlock_init (fire_signal[i]);
+#else
+ fire_signal_state = 0;
+#endif
+
+ /* Block all fire_signals. */
+ for (i = REPEAT_COUNT-1; i >= 0; i--)
+ gl_rwlock_wrlock (fire_signal[i]);
+
+ /* Spawn the threads. */
+ for (i = 0; i < THREAD_COUNT; i++)
+ threads[i] = gl_thread_create (once_contender_thread, (void *) (long) i);
+
+ for (repeat = 0; repeat <= REPEAT_COUNT; repeat++)
+ {
+ /* Wait until every thread is ready. */
+ dbgprintf ("Main thread before synchonizing for round %d\n", repeat);
+ for (;;)
+ {
+ int ready_count = 0;
+ for (i = 0; i < THREAD_COUNT; i++)
+ {
+ gl_lock_lock (ready_lock[i]);
+ ready_count += ready[i];
+ gl_lock_unlock (ready_lock[i]);
+ }
+ if (ready_count == THREAD_COUNT)
+ break;
+ yield ();
+ }
+ dbgprintf ("Main thread after synchonizing for round %d\n", repeat);
+
+ if (repeat > 0)
+ {
+ /* Check that exactly one thread executed the once_execute()
+ function. */
+ if (performed != 1)
+ abort ();
+ }
+
+ if (repeat == REPEAT_COUNT)
+ break;
+
+ /* Preparation for the next round: Initialize once_control. */
+ memcpy (&once_control, &fresh_once, sizeof (gl_once_t));
+
+ /* Preparation for the next round: Reset the performed counter. */
+ performed = 0;
+
+ /* Preparation for the next round: Reset the ready flags. */
+ for (i = 0; i < THREAD_COUNT; i++)
+ {
+ gl_lock_lock (ready_lock[i]);
+ ready[i] = 0;
+ gl_lock_unlock (ready_lock[i]);
+ }
+
+ /* Signal all threads simultaneously. */
+ dbgprintf ("Main thread giving signal for round %d\n", repeat);
+#if ENABLE_LOCKING
+ gl_rwlock_unlock (fire_signal[repeat]);
+#else
+ fire_signal_state = repeat + 1;
+#endif
+ }
+
+ /* Wait for the threads to terminate. */
+ for (i = 0; i < THREAD_COUNT; i++)
+ gl_thread_join (threads[i], NULL);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+int
+main ()
+{
+#if TEST_PTH_THREADS
+ if (!pth_init ())
+ abort ();
+#endif
+
+#if DO_TEST_LOCK
+ printf ("Starting test_lock ..."); fflush (stdout);
+ test_lock ();
+ printf (" OK\n"); fflush (stdout);
+#endif
+#if DO_TEST_RWLOCK
+ printf ("Starting test_rwlock ..."); fflush (stdout);
+ test_rwlock ();
+ printf (" OK\n"); fflush (stdout);
+#endif
+#if DO_TEST_RECURSIVE_LOCK
+ printf ("Starting test_recursive_lock ..."); fflush (stdout);
+ test_recursive_lock ();
+ printf (" OK\n"); fflush (stdout);
+#endif
+#if DO_TEST_ONCE
+ printf ("Starting test_once ..."); fflush (stdout);
+ test_once ();
+ printf (" OK\n"); fflush (stdout);
+#endif
+
+ return 0;
+}
+
+#else
+
+/* No multithreading available. */
+
+#include <stdio.h>
+
+int
+main ()
+{
+ fputs ("Skipping test: multithreading not enabled\n", stderr);
+ return 77;
+}
+
+#endif
diff --git a/gl/tests/test-strerror.c b/gl/tests/test-strerror.c
new file mode 100644
index 0000000000..03637d7850
--- /dev/null
+++ b/gl/tests/test-strerror.c
@@ -0,0 +1,75 @@
+/* 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;
+
+ errno = 0;
+ str = strerror (EACCES);
+ ASSERT (str);
+ ASSERT (*str);
+ ASSERT (errno == 0);
+
+ errno = 0;
+ str = strerror (ETIMEDOUT);
+ ASSERT (str);
+ ASSERT (*str);
+ ASSERT (errno == 0);
+
+ errno = 0;
+ str = strerror (EOVERFLOW);
+ ASSERT (str);
+ ASSERT (*str);
+ ASSERT (errno == 0);
+
+ /* POSIX requires strerror (0) to succeed. Reject use of "Unknown
+ error", but allow "Success", "No error", or even Solaris' "Error
+ 0" which are distinct patterns from true out-of-range strings.
+ http://austingroupbugs.net/view.php?id=382 */
+ errno = 0;
+ str = strerror (0);
+ ASSERT (str);
+ ASSERT (*str);
+ ASSERT (errno == 0);
+ ASSERT (strstr (str, "nknown") == NULL);
+
+ /* POSIX requires strerror to produce a non-NULL result for all
+ inputs; as an extension, we also guarantee a non-empty reseult.
+ Reporting EINVAL is optional. */
+ errno = 0;
+ str = strerror (-3);
+ ASSERT (str);
+ ASSERT (*str);
+ ASSERT (errno == 0 || errno == EINVAL);
+
+ return 0;
+}
diff --git a/gl/tests/test-strerror_r.c b/gl/tests/test-strerror_r.c
new file mode 100644
index 0000000000..48287678bd
--- /dev/null
+++ b/gl/tests/test-strerror_r.c
@@ -0,0 +1,112 @@
+/* Test of strerror_r() 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. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (strerror_r, int, (int, char *, size_t));
+
+#include <errno.h>
+
+#include "macros.h"
+
+int
+main (void)
+{
+ char buf[100];
+ int ret;
+
+ /* Test results with valid errnum and enough room. */
+
+ errno = 0;
+ buf[0] = '\0';
+ ASSERT (strerror_r (EACCES, buf, sizeof (buf)) == 0);
+ ASSERT (buf[0] != '\0');
+ ASSERT (errno == 0);
+
+ errno = 0;
+ buf[0] = '\0';
+ ASSERT (strerror_r (ETIMEDOUT, buf, sizeof (buf)) == 0);
+ ASSERT (buf[0] != '\0');
+ ASSERT (errno == 0);
+
+ errno = 0;
+ buf[0] = '\0';
+ ASSERT (strerror_r (EOVERFLOW, buf, sizeof (buf)) == 0);
+ ASSERT (buf[0] != '\0');
+ ASSERT (errno == 0);
+
+ /* POSIX requires strerror (0) to succeed. Reject use of "Unknown
+ error", but allow "Success", "No error", or even Solaris' "Error
+ 0" which are distinct patterns from true out-of-range strings.
+ http://austingroupbugs.net/view.php?id=382 */
+ errno = 0;
+ buf[0] = '\0';
+ ret = strerror_r (0, buf, sizeof (buf));
+ ASSERT (ret == 0);
+ ASSERT (buf[0]);
+ ASSERT (errno == 0);
+ ASSERT (strstr (buf, "nknown") == NULL);
+
+ /* Test results with out-of-range errnum and enough room. */
+
+ errno = 0;
+ buf[0] = '^';
+ ret = strerror_r (-3, buf, sizeof (buf));
+ ASSERT (ret == 0 || ret == EINVAL);
+ if (ret == 0)
+ ASSERT (buf[0] != '^');
+ ASSERT (errno == 0);
+
+ /* Test results with a too small buffer. */
+
+ ASSERT (strerror_r (EACCES, buf, sizeof (buf)) == 0);
+ {
+ size_t len = strlen (buf);
+ size_t i;
+
+ for (i = 0; i <= len; i++)
+ {
+ strcpy (buf, "BADFACE");
+ errno = 0;
+ ret = strerror_r (EACCES, buf, i);
+ ASSERT (errno == 0);
+ if (ret == 0)
+ {
+ /* Truncated result. POSIX allows this, and it actually
+ happens on AIX 6.1 and Cygwin. */
+ ASSERT ((strcmp (buf, "BADFACE") == 0) == (i == 0));
+ }
+ else
+ {
+ /* Failure. */
+ ASSERT (ret == ERANGE);
+ /* buf is clobbered nevertheless, on FreeBSD and MacOS X. */
+ }
+ }
+
+ strcpy (buf, "BADFACE");
+ errno = 0;
+ ret = strerror_r (EACCES, buf, len + 1);
+ ASSERT (ret == 0);
+ ASSERT (errno == 0);
+ }
+
+ return 0;
+}
diff --git a/gl/tests/test-sys_socket.c b/gl/tests/test-sys_socket.c
index 8f323ca1d9..a6e99d6008 100644
--- a/gl/tests/test-sys_socket.c
+++ b/gl/tests/test-sys_socket.c
@@ -30,6 +30,12 @@ int a[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
/* Check that the 'socklen_t' type is defined. */
socklen_t t1;
+/* Check that 'struct iovec' is defined. */
+struct iovec io;
+
+/* Check that a minimal set of 'struct msghdr' is defined. */
+struct msghdr msg;
+
int
main (void)
{
@@ -51,10 +57,8 @@ main (void)
x.ss_family = 42;
i = 42;
+ msg.msg_iov = &io;
- /* Tell the compiler that these variables are used. */
- (void) x;
- (void) i;
-
- return 0;
+ return (x.ss_family - i + msg.msg_namelen + msg.msg_iov->iov_len
+ + msg.msg_iovlen);
}
diff --git a/gl/tests/test-sys_uio.c b/gl/tests/test-sys_uio.c
new file mode 100644
index 0000000000..7855a6bc43
--- /dev/null
+++ b/gl/tests/test-sys_uio.c
@@ -0,0 +1,32 @@
+/* Test of <sys/uio.h> substitute.
+ 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 <eblake@redhat.com>, 2011. */
+
+#include <config.h>
+
+#include <sys/uio.h>
+
+/* Check that necessary types are defined. */
+size_t a;
+ssize_t b;
+struct iovec c;
+
+int
+main (void)
+{
+ return a + b + !!c.iov_base + c.iov_len;
+}