* Makefile.am (distcheck-hook): Check also flexmember.m4, flexmember.h.
* gettext-runtime/intl/Makefile.in (SOURCES): Add flexmember.h.
* gettext-runtime/intl/flexmember.h: New file, from gnulib.
* gettext-runtime/intl/localcharset.c:
* localcharset.c (relocate2): Define fallback.
(get_charset_aliases): Invoke relocate2 instead of relocate. Free the
allocated memory.
* localcharset.c (WINDOWS_NATIVE): Don't define on Cygwin.
* localcharset.c (locale_charset) [WINDOWS_NATIVE]: Don't use the
return value from setlocale if it would lead to a buffer overrun.
* gettext-runtime/intl/localename.c:
* localename.c [__CYGWIN__]: Include <langinfo.h>, since this is
where NL_LOCALE_NAME is defined.
* localename.c (WINDOWS_NATIVE): Don't define on Cygwin.
* localename.c (gl_locale_name_thread_unsafe): Add clause for
Cygwin.
* localename.c (struct hash_node): Use FLEXIBLE_ARRAY_MEMBER.
* gettext-runtime/intl/lock.c:
* lock.c: On glibc systems without
PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, use the fallback
implementation of rwlocks.
* lock.c [USE_POSIX_THREADS]
(glthread_rwlock_init_for_glibc): New function.
[USE_POSIX_THREADS] (glthread_rwlock_rdlock_multithreaded): Update
comment.
[USE_PTH_THREADS]: New implementation of rwlocks.
[USE_WINDOWS_THREADS] (glthread_rwlock_rdlock_func): Prefer writers over
readers.
* gettext-runtime/intl/lock.h:
* lock.h (pthread_rwlockattr_setkind_np): Don't declare
weak on non-glibc platforms.
* lock.h: On glibc systems without
PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, use the fallback
implementation of rwlocks.
* lock.h [USE_POSIX_THREADS_WEAK]: Declare also
pthread_rwlockattr_init, pthread_rwlockattr_setkind_np,
pthread_rwlockattr_destroy weak.
* lock.h [USE_POSIX_THREADS]: Test
HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER. Use a different implementation
of rwlock initialization on glibc systems without
HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER. Use a different implementation
of rwlocks altogether on non-glibc systems without
HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER.
[USE_PTH_THREADS]: Use a different implementation of rwlocks altogether.
* gettext-runtime/intl/relocatable.c:
* relocatable.c (relocate2): New function.
* relocatable.c (relocate): Assume pathname is non-NULL. Use
ISSLASH macro consistently. Avoid dangerous string concatenation idiom.
* gettext-runtime/intl/relocatable.h:
* relocatable.h (relocate2): New declaration/macro.
* gettext-runtime/intl/vasnprintf.c, gettext-runtime/libasprintf/vasnprintf.c:
* vasnprintf.c (FALLTHROUGH): New macro.
Use it whenever one switch case falls through into the next.
* vasnprintf.c (USE_MSVC__SNPRINTF): New macro.
Everywhere, use !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF instead
of !HAVE_SNPRINTF_RETVAL_C99.
* vasnprintf.c (VASNPRINTF): Move comment down past two cpp
directives, so that it takes effect once again. This is clearly
not a proper change, and I will revert it once this bug is fixed:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77817
* vasnprintf.c (IF_LINT): Treat GCC_LINT like lint.
* gettext-runtime/intl/verify.h:
* verify.h (verify) [!__GNUC__]:
Use shorter albeit meaningless string to bypass silly compiler limits.
* verify.h (assume): Treat GCC_LINT like lint.
* gettext-runtime/intl/xsize.h: Update.
* gettext-runtime/m4/Makefile.am (EXTRA_DIST): Add flexmember.m4.
* gettext-runtime/m4/extern-inline.m4: Update.
* gettext-runtime/m4/fcntl-o.m4: Update.
* gettext-runtime/m4/flexmember.m4: New file, from gnulib.
* gettext-runtime/m4/glibc2.m4: Update.
* gettext-runtime/m4/glibc21.m4: Update.
* gettext-runtime/m4/intdiv0.m4: Update.
* gettext-runtime/m4/intl.m4 (AM_INTL_SUBDIR): Require AC_C_FLEXIBLE_ARRAY_MEMBER.
* gettext-runtime/m4/intmax.m4: Update.
* gettext-runtime/m4/inttypes-pri.m4: Update.
* gettext-runtime/m4/inttypes_h.m4: Update.
* gettext-runtime/m4/lock.m4 (gl_LOCK): Invoke gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER.
* gettext-runtime/m4/longlong.m4: Update.
* gettext-runtime/m4/printf-posix.m4: Update.
* gettext-runtime/m4/progtest.m4: Update.
* gettext-runtime/m4/size_max.m4: Update.
* gettext-runtime/m4/stdint_h.m4: Update.
* gettext-runtime/m4/threadlib.m4 (gl_THREADLIB_BODY): Don't set
PTHREAD_IN_USE_DETECTION_HARD if configuring on Solaris 10 or newer.
Reported by Peter Felecan at <https://savannah.gnu.org/bugs/?32087>.
* gettext-runtime/m4/uintmax_t.m4: Update.
* gettext-runtime/m4/visibility.m4: Update.
* gettext-runtime/m4/wchar_t.m4: Update.
* gettext-runtime/m4/xsize.m4: Update.
* gettext-runtime/tests/test-lock.c:
* test-lock.c: On Mac OS X, use named semaphores, not unnamed
semaphores.
(USE_NAMED_SEMAPHORE, USE_UNNAMED_SEMAPHORE): New macros.
(atomic_int_semaphore): New macro.
* test-lock.c (USE_SEMAPHORE): Don't set if <semaphore.h> does not
exist.
* test-lock.c (USE_SEMAPHORE): New constant.
(struct atomic_int, init_atomic_int, get_atomic_int_value,
set_atomic_int_value) [USE_SEMAPHORE]: Define using a POSIX semaphore.
Suggested by Torvald Riegel <triegel@redhat.com>.
## Makefile for the toplevel directory of GNU gettext
-## Copyright (C) 1995-2016 Free Software Foundation, Inc.
+## Copyright (C) 1995-2017 Free Software Foundation, Inc.
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
cmp -s gettext-runtime/m4/codeset.m4 gettext-tools/gnulib-m4/codeset.m4
cmp -s gettext-runtime/m4/extern-inline.m4 gettext-tools/gnulib-m4/extern-inline.m4
cmp -s gettext-runtime/m4/fcntl-o.m4 gettext-tools/gnulib-m4/fcntl-o.m4
+ cmp -s gettext-runtime/m4/flexmember.m4 gettext-tools/gnulib-m4/flexmember.m4
cmp -s gettext-runtime/m4/gettext.m4 gettext-tools/gnulib-m4/gettext.m4
cmp -s gettext-runtime/m4/glibc2.m4 gettext-tools/gnulib-m4/glibc2.m4
cmp -s gettext-runtime/m4/glibc21.m4 gettext-tools/gnulib-m4/glibc21.m4
cmp -s gettext-runtime/m4/xsize.m4 gettext-tools/gnulib-m4/xsize.m4
cmp -s gettext-runtime/libasprintf/gnulib-m4/intmax_t.m4 gettext-tools/gnulib-m4/intmax_t.m4
test "`sed 1,17d gettext-runtime/intl/config.charset | md5sum`" = "`sed 1,17d gettext-tools/gnulib-lib/config.charset | md5sum`"
+ test "`sed 1,16d gettext-runtime/intl/flexmember.h | md5sum`" = "`sed 1,16d gettext-tools/gnulib-lib/flexmember.h | md5sum`"
test "`sed 1,16d gettext-runtime/intl/localcharset.h | md5sum`" = "`sed 1,16d gettext-tools/gnulib-lib/localcharset.h | md5sum`"
test "`sed 1,16d gettext-runtime/intl/localcharset.c | md5sum`" = "`sed 1,16d gettext-tools/gnulib-lib/localcharset.c | md5sum`"
test "`sed 1,16d gettext-runtime/intl/localename.c | md5sum`" = "`sed 1,16d gettext-tools/gnulib-lib/localename.c | md5sum`"
relocatable.c \
langprefs.c \
localename.c \
+ flexmember.h \
log.c \
printf.c \
setlocale.c \
--- /dev/null
+/* Sizes of structs with flexible array members.
+
+ Copyright 2016-2017 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Written by Paul Eggert. */
+
+#include <stddef.h>
+
+/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below.
+ On older platforms without _Alignof, use a pessimistic bound that is
+ safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1.
+ On newer platforms, use _Alignof to get a tighter bound. */
+
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
+# define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1))
+#else
+# define FLEXALIGNOF(type) _Alignof (type)
+#endif
+
+/* Upper bound on the size of a struct of type TYPE with a flexible
+ array member named MEMBER that is followed by N bytes of other data.
+ This is not simply sizeof (TYPE) + N, since it may require
+ alignment on unusually picky C11 platforms, and
+ FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms.
+ Yield a value less than N if and only if arithmetic overflow occurs. */
+
+#define FLEXSIZEOF(type, member, n) \
+ ((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \
+ & ~ (FLEXALIGNOF (type) - 1))
/* Determine a canonical name for the current locale's character encoding.
- Copyright (C) 2000-2006, 2008-2015 Free Software Foundation, Inc.
+ Copyright (C) 2000-2006, 2008-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
# define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */
#endif
-#if defined _WIN32 || defined __WIN32__
+#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
# define WINDOWS_NATIVE
# include <locale.h>
#endif
# include "relocatable.h"
#else
# define relocate(pathname) (pathname)
+# define relocate2(pathname,allocatedp) (*(allocatedp) = NULL, (pathname))
#endif
/* Get LIBDIR. */
if (cp == NULL)
{
#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__ || defined OS2)
+ char *malloc_dir = NULL;
const char *dir;
const char *base = "charset.alias";
char *file_name;
necessary for running the testsuite before "make install". */
dir = getenv ("CHARSETALIASDIR");
if (dir == NULL || dir[0] == '\0')
- dir = relocate (LIBDIR);
+ dir = relocate2 (LIBDIR, &malloc_dir);
/* Concatenate dir and base into freshly allocated file_name. */
{
}
}
+ free (malloc_dir);
+
if (file_name == NULL)
/* Out of memory. Treat the file as empty. */
cp = "";
current_locale = setlocale (LC_CTYPE, NULL);
pdot = strrchr (current_locale, '.');
- if (pdot)
+ if (pdot && 2 + strlen (pdot + 1) + 1 <= sizeof (buf))
sprintf (buf, "CP%s", pdot + 1);
else
{
/* Determine name of the currently selected locale.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
#include <locale.h>
#include <string.h>
+#include "flexmember.h"
+
#if HAVE_USELOCALE
/* Mac OS X 10.5 defines the locale_t type in <xlocale.h>. */
# if defined __APPLE__ && defined __MACH__
# include <xlocale.h>
# endif
-# if __GLIBC__ >= 2 && !defined __UCLIBC__
+# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || defined __CYGWIN__
# include <langinfo.h>
# endif
# if !defined IN_LIBINTL
# endif
#endif
-#if defined _WIN32 || defined __WIN32__
+#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
# define WINDOWS_NATIVE
# if !defined IN_LIBINTL
# include "glthread/lock.h"
struct hash_node
{
struct hash_node * volatile next;
- char contents[100]; /* has variable size */
+ char contents[FLEXIBLE_ARRAY_MEMBER];
};
# define HASH_TABLE_SIZE 257
size = strlen (string) + 1;
new_node =
(struct hash_node *)
- malloc (offsetof (struct hash_node, contents[0]) + size);
+ malloc (FLEXSIZEOF (struct hash_node, contents, size));
if (new_node == NULL)
/* Out of memory. Return a statically allocated string. */
return "C";
# elif defined __sun && HAVE_GETLOCALENAME_L
/* Solaris >= 12. */
return getlocalename_l (category, thread_locale);
+# elif defined __CYGWIN__
+ /* Cygwin < 2.6 lacks uselocale and thread-local locales altogether.
+ Cygwin <= 2.6.1 lacks NL_LOCALE_NAME, requiring peeking inside
+ an opaque struct. */
+# ifdef NL_LOCALE_NAME
+ return nl_langinfo_l (NL_LOCALE_NAME (category), thread_locale);
+# else
+ /* FIXME: Remove when we can assume new-enough Cygwin. */
+ struct __locale_t {
+ char categories[7][32];
+ };
+ return ((struct __locale_t *) thread_locale)->categories[category];
+# endif
# elif defined __ANDROID__
return MB_CUR_MAX == 4 ? "C.UTF-8" : "C";
# endif
/* Locking in multithreaded situations.
- Copyright (C) 2005-2008, 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2005-2008, 2015-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
/* ------------------------- gl_rwlock_t datatype ------------------------- */
-# if HAVE_PTHREAD_RWLOCK
+# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1)))
-# if !defined PTHREAD_RWLOCK_INITIALIZER
+# ifdef PTHREAD_RWLOCK_INITIALIZER
+
+# if !HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER
+ /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */
+
+int
+glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock)
+{
+ pthread_rwlockattr_t attributes;
+ int err;
+
+ err = pthread_rwlockattr_init (&attributes);
+ if (err != 0)
+ return err;
+ /* Note: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP is the only value that
+ causes the writer to be preferred. PTHREAD_RWLOCK_PREFER_WRITER_NP does not
+ do this; see
+ http://man7.org/linux/man-pages/man3/pthread_rwlockattr_setkind_np.3.html */
+ err = pthread_rwlockattr_setkind_np (&attributes,
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
+ if (err == 0)
+ err = pthread_rwlock_init(lock, &attributes);
+ /* pthread_rwlockattr_destroy always returns 0. It cannot influence the
+ return value. */
+ pthread_rwlockattr_destroy (&attributes);
+ return err;
+}
+
+# endif
+# else
int
glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
if (err != 0)
return err;
/* Test whether only readers are currently running, and whether the runcount
- field will not overflow. */
- /* POSIX says: "It is implementation-defined whether the calling thread
- acquires the lock when a writer does not hold the lock and there are
- writers blocked on the lock." Let's say, no: give the writers a higher
- priority. */
+ field will not overflow, and whether no writer is waiting. The latter
+ condition is because POSIX recommends that "write locks shall take
+ precedence over read locks", to avoid "writer starvation". */
while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0))
{
/* This thread has to wait for a while. Enqueue it among the
/* ------------------------- gl_rwlock_t datatype ------------------------- */
+# if !HAVE_PTH_RWLOCK_ACQUIRE_PREFER_WRITER
+
+int
+glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
+{
+ if (!pth_mutex_init (&lock->lock))
+ return errno;
+ if (!pth_cond_init (&lock->waiting_readers))
+ return errno;
+ if (!pth_cond_init (&lock->waiting_writers))
+ return errno;
+ lock->waiting_writers_count = 0;
+ lock->runcount = 0;
+ lock->initialized = 1;
+ return 0;
+}
+
+int
+glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
+{
+ if (!lock->initialized)
+ glthread_rwlock_init_multithreaded (lock);
+ if (!pth_mutex_acquire (&lock->lock, 0, NULL))
+ return errno;
+ /* Test whether only readers are currently running, and whether the runcount
+ field will not overflow, and whether no writer is waiting. The latter
+ condition is because POSIX recommends that "write locks shall take
+ precedence over read locks", to avoid "writer starvation". */
+ while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0))
+ {
+ /* This thread has to wait for a while. Enqueue it among the
+ waiting_readers. */
+ if (!pth_cond_await (&lock->waiting_readers, &lock->lock, NULL))
+ {
+ int err = errno;
+ pth_mutex_release (&lock->lock);
+ return err;
+ }
+ }
+ lock->runcount++;
+ return (!pth_mutex_release (&lock->lock) ? errno : 0);
+}
+
+int
+glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
+{
+ if (!lock->initialized)
+ glthread_rwlock_init_multithreaded (lock);
+ if (!pth_mutex_acquire (&lock->lock, 0, NULL))
+ return errno;
+ /* Test whether no readers or writers are currently running. */
+ while (!(lock->runcount == 0))
+ {
+ /* This thread has to wait for a while. Enqueue it among the
+ waiting_writers. */
+ lock->waiting_writers_count++;
+ if (!pth_cond_await (&lock->waiting_writers, &lock->lock, NULL))
+ {
+ int err = errno;
+ lock->waiting_writers_count--;
+ pth_mutex_release (&lock->lock);
+ return err;
+ }
+ lock->waiting_writers_count--;
+ }
+ lock->runcount--; /* runcount becomes -1 */
+ return (!pth_mutex_release (&lock->lock) ? errno : 0);
+}
+
+int
+glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
+{
+ int err;
+
+ if (!lock->initialized)
+ return EINVAL;
+ if (!pth_mutex_acquire (&lock->lock, 0, NULL))
+ return errno;
+ if (lock->runcount < 0)
+ {
+ /* Drop a writer lock. */
+ if (!(lock->runcount == -1))
+ {
+ pth_mutex_release (&lock->lock);
+ return EINVAL;
+ }
+ lock->runcount = 0;
+ }
+ else
+ {
+ /* Drop a reader lock. */
+ if (!(lock->runcount > 0))
+ {
+ pth_mutex_release (&lock->lock);
+ return EINVAL;
+ }
+ lock->runcount--;
+ }
+ if (lock->runcount == 0)
+ {
+ /* POSIX recommends that "write locks shall take precedence over read
+ locks", to avoid "writer starvation". */
+ if (lock->waiting_writers_count > 0)
+ {
+ /* Wake up one of the waiting writers. */
+ if (!pth_cond_notify (&lock->waiting_writers, FALSE))
+ {
+ int err = errno;
+ pth_mutex_release (&lock->lock);
+ return err;
+ }
+ }
+ else
+ {
+ /* Wake up all waiting readers. */
+ if (!pth_cond_notify (&lock->waiting_readers, TRUE))
+ {
+ int err = errno;
+ pth_mutex_release (&lock->lock);
+ return err;
+ }
+ }
+ }
+ return (!pth_mutex_release (&lock->lock) ? errno : 0);
+}
+
+int
+glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
+{
+ lock->initialized = 0;
+ return 0;
+}
+
+# endif
+
/* --------------------- gl_recursive_lock_t datatype --------------------- */
/* -------------------------- gl_once_t datatype -------------------------- */
}
EnterCriticalSection (&lock->lock);
/* Test whether only readers are currently running, and whether the runcount
- field will not overflow. */
- if (!(lock->runcount + 1 > 0))
+ field will not overflow, and whether no writer is waiting. The latter
+ condition is because POSIX recommends that "write locks shall take
+ precedence over read locks", to avoid "writer starvation". */
+ if (!(lock->runcount + 1 > 0 && lock->waiting_writers.count == 0))
{
/* This thread has to wait for a while. Enqueue it among the
waiting_readers. */
/* Locking in multithreaded situations.
- Copyright (C) 2005-2008, 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2005-2008, 2015-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
# pragma weak pthread_mutexattr_init
# pragma weak pthread_mutexattr_settype
# pragma weak pthread_mutexattr_destroy
+# pragma weak pthread_rwlockattr_init
+# if __GNU_LIBRARY__ > 1
+# pragma weak pthread_rwlockattr_setkind_np
+# endif
+# pragma weak pthread_rwlockattr_destroy
# ifndef pthread_self
# pragma weak pthread_self
# endif
/* ------------------------- gl_rwlock_t datatype ------------------------- */
-# if HAVE_PTHREAD_RWLOCK
+# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1)))
# ifdef PTHREAD_RWLOCK_INITIALIZER
STORAGECLASS pthread_rwlock_t NAME;
# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
-# define gl_rwlock_initializer \
- PTHREAD_RWLOCK_INITIALIZER
-# define glthread_rwlock_init(LOCK) \
- (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)
+# if HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER
+# define gl_rwlock_initializer \
+ PTHREAD_RWLOCK_INITIALIZER
+# define glthread_rwlock_init(LOCK) \
+ (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)
+# else /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */
+# define gl_rwlock_initializer \
+ PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
+# define glthread_rwlock_init(LOCK) \
+ (pthread_in_use () ? glthread_rwlock_init_for_glibc (LOCK) : 0)
+extern int glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock);
+# endif
# define glthread_rwlock_rdlock(LOCK) \
(pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0)
# define glthread_rwlock_wrlock(LOCK) \
/* ------------------------- gl_rwlock_t datatype ------------------------- */
+/* Pth pth_rwlock_acquire always prefers readers. No autoconf test so far. */
+# if HAVE_PTH_RWLOCK_ACQUIRE_PREFER_WRITER
+
typedef pth_rwlock_t gl_rwlock_t;
# define gl_rwlock_define(STORAGECLASS, NAME) \
STORAGECLASS pth_rwlock_t NAME;
# define glthread_rwlock_destroy(LOCK) \
((void)(LOCK), 0)
+# else
+
+typedef struct
+ {
+ int initialized;
+ pth_mutex_t lock; /* protects the remaining fields */
+ pth_cond_t waiting_readers; /* waiting readers */
+ pth_cond_t waiting_writers; /* waiting writers */
+ unsigned int waiting_writers_count; /* number of waiting writers */
+ int runcount; /* number of readers running, or -1 when a writer runs */
+ }
+ gl_rwlock_t;
+# define gl_rwlock_define(STORAGECLASS, NAME) \
+ STORAGECLASS gl_rwlock_t NAME;
+# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
+ STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
+# define gl_rwlock_initializer \
+ { 0 }
+# define glthread_rwlock_init(LOCK) \
+ (pth_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
+# define glthread_rwlock_rdlock(LOCK) \
+ (pth_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_wrlock(LOCK) \
+ (pth_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_unlock(LOCK) \
+ (pth_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_destroy(LOCK) \
+ (pth_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
+
+# endif
+
/* --------------------- gl_recursive_lock_t datatype --------------------- */
/* In Pth, mutexes are recursive by default. */
/* Provide relocatable packages.
- Copyright (C) 2003-2006, 2008-2016 Free Software Foundation, Inc.
+ Copyright (C) 2003-2006, 2008-2017 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2003.
This program is free software: you can redistribute it and/or modify
# ifdef __KLIBC__
# undef strncmp
- if (pathname && strncmp (pathname, "/@unixroot", 10) == 0
- && (pathname[10] == '\0' || pathname[10] == '/' || pathname[10] == '\\'))
+ if (strncmp (pathname, "/@unixroot", 10) == 0
+ && (pathname[10] == '\0' || ISSLASH (pathname[10])))
{
/* kLIBC itself processes /@unixroot prefix */
-
return pathname;
}
else
# endif
- if (pathname && ISSLASH (pathname[0]))
+ if (ISSLASH (pathname[0]))
{
const char *unixroot = getenv ("UNIXROOT");
- if (unixroot && HAS_DEVICE (unixroot) && !unixroot[2])
+ if (unixroot && HAS_DEVICE (unixroot) && unixroot[2] == '\0')
{
char *result = (char *) xmalloc (2 + strlen (pathname) + 1);
#ifdef NO_XMALLOC
if (result != NULL)
#endif
{
- strcpy (result, unixroot);
+ memcpy (result, unixroot, 2);
strcpy (result + 2, pathname);
return result;
}
return pathname;
}
+/* Returns the pathname, relocated according to the current installation
+ directory.
+ This function sets *ALLOCATEDP to the allocated memory, or to NULL if
+ no memory allocation occurs. So that, after you're done with the return
+ value, to reclaim allocated memory, you can do: free (*ALLOCATEDP). */
+const char *
+relocate2 (const char *pathname, char **allocatedp)
+{
+ const char *result = relocate (pathname);
+ *allocatedp = (result != pathname ? (char *) result : NULL);
+ return result;
+}
+
#endif
/* Provide relocatable packages.
- Copyright (C) 2003, 2005, 2008, 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005, 2008-2017 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2003.
This program is free software: you can redistribute it and/or modify
string that you can free with free() after casting it to 'char *'. */
extern const char * relocate (const char *pathname);
+/* Returns the pathname, relocated according to the current installation
+ directory.
+ This function sets *ALLOCATEDP to the allocated memory, or to NULL if
+ no memory allocation occurs. So that, after you're done with the return
+ value, to reclaim allocated memory, you can do: free (*ALLOCATEDP). */
+extern const char * relocate2 (const char *pathname, char **allocatedp);
+
/* Memory management: relocate() potentially allocates memory, because it has
to construct a fresh pathname. If this is a problem because your program
- calls relocate() frequently, think about caching the result. Or free the
- return value if it was different from the argument pathname. */
+ calls relocate() frequently or because you want to fix all potential memory
+ leaks anyway, you have three options:
+ 1) Use this idiom:
+ const char *pathname = ...;
+ const char *rel_pathname = relocate (pathname);
+ ...
+ if (rel_pathname != pathname)
+ free ((char *) rel_pathname);
+ 2) Use this idiom:
+ char *allocated;
+ const char *rel_pathname = relocate2 (..., &allocated);
+ ...
+ free (allocated);
+ 3) Think about caching the result. */
/* Convenience function:
Computes the current installation prefix, based on the original
/* By default, we use the hardwired pathnames. */
#define relocate(pathname) (pathname)
+#define relocate2(pathname,allocatedp) (*(allocatedp) = NULL, (pathname))
#endif
/* vsprintf with automatic memory allocation.
- Copyright (C) 1999, 2002-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
# include "fpucw.h"
#endif
+#ifndef FALLTHROUGH
+# if __GNUC__ < 7
+# define FALLTHROUGH ((void) 0)
+# else
+# define FALLTHROUGH __attribute__ ((__fallthrough__))
+# endif
+#endif
+
/* Default parameters. */
#ifndef VASNPRINTF
# if WIDE_CHAR_VERSION
# define SNPRINTF snwprintf
# else
# define SNPRINTF _snwprintf
+# define USE_MSVC__SNPRINTF 1
# endif
# else
/* Unix. */
/* Here we need to call the native snprintf, not rpl_snprintf. */
# undef snprintf
# else
+ /* MSVC versions < 14 did not have snprintf, only _snprintf. */
# define SNPRINTF _snprintf
+# define USE_MSVC__SNPRINTF 1
# endif
# else
/* Unix. */
/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
warnings in this file. Use -Dlint to suppress them. */
-#ifdef lint
+#if defined GCC_LINT || defined lint
# define IF_LINT(Code) Code
#else
# define IF_LINT(Code) /* empty */
#undef remainder
#define remainder rem
-#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
+#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION
# if (HAVE_STRNLEN && !defined _AIX)
# define local_strnlen strnlen
# else
# endif
#endif
-#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
+#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
# if HAVE_WCSLEN
# define local_wcslen wcslen
# else
# endif
#endif
-#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
+#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
# if HAVE_WCSNLEN
# define local_wcsnlen wcsnlen
# else
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
/* Use a different function name, to make it possible that the 'wchar_t'
parametrization and the 'char' parametrization get compiled in the same
}
}
#endif
-#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
+#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
else if (dp->conversion == 's'
# if WIDE_CHAR_VERSION
&& a.arg[dp->arg_index].type != TYPE_WIDE_STRING
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
int has_width;
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
size_t width;
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
int has_precision;
size_t precision;
#endif
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
has_width = 0;
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
width = 0;
if (dp->width_start != dp->width_end)
{
}
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
has_precision = 0;
precision = 6;
if (dp->precision_start != dp->precision_end)
break;
# else
*fbp++ = 'l';
- /*FALLTHROUGH*/
# endif
#endif
+ FALLTHROUGH;
case TYPE_LONGINT:
case TYPE_ULONGINT:
#if HAVE_WINT_T
/* Look at the snprintf() return value. */
if (retcount < 0)
{
-# if !HAVE_SNPRINTF_RETVAL_C99
+# if !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
/* HP-UX 10.20 snprintf() is doubly deficient:
It doesn't understand the '%n' directive,
*and* it returns -1 (rather than the length
/* Compile-time assert-like macros.
- Copyright (C) 2005-2006, 2009-2016 Free Software Foundation, Inc.
+ Copyright (C) 2005-2006, 2009-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
/* Verify requirement R at compile-time, as a declaration without a
trailing ';'. */
-#define verify(R) _GL_VERIFY (R, "verify (" #R ")")
+#ifdef __GNUC__
+# define verify(R) _GL_VERIFY (R, "verify (" #R ")")
+#else
+/* PGI barfs if R is long. Play it safe. */
+# define verify(R) _GL_VERIFY (R, "verify (...)")
+#endif
#ifndef __has_builtin
# define __has_builtin(x) 0
# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
#elif 1200 <= _MSC_VER
# define assume(R) __assume (R)
-#elif (defined lint \
+#elif ((defined GCC_LINT || defined lint) \
&& (__has_builtin (__builtin_trap) \
|| 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))))
/* Doing it this way helps various packages when configured with
/* xsize.h -- Checked size_t computations.
- Copyright (C) 2003, 2008-2016 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2008-2017 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
/* vsprintf with automatic memory allocation.
- Copyright (C) 1999, 2002-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
# include "fpucw.h"
#endif
+#ifndef FALLTHROUGH
+# if __GNUC__ < 7
+# define FALLTHROUGH ((void) 0)
+# else
+# define FALLTHROUGH __attribute__ ((__fallthrough__))
+# endif
+#endif
+
/* Default parameters. */
#ifndef VASNPRINTF
# if WIDE_CHAR_VERSION
# define SNPRINTF snwprintf
# else
# define SNPRINTF _snwprintf
+# define USE_MSVC__SNPRINTF 1
# endif
# else
/* Unix. */
/* Here we need to call the native snprintf, not rpl_snprintf. */
# undef snprintf
# else
+ /* MSVC versions < 14 did not have snprintf, only _snprintf. */
# define SNPRINTF _snprintf
+# define USE_MSVC__SNPRINTF 1
# endif
# else
/* Unix. */
/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
warnings in this file. Use -Dlint to suppress them. */
-#ifdef lint
+#if defined GCC_LINT || defined lint
# define IF_LINT(Code) Code
#else
# define IF_LINT(Code) /* empty */
#undef remainder
#define remainder rem
-#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
+#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION
# if (HAVE_STRNLEN && !defined _AIX)
# define local_strnlen strnlen
# else
# endif
#endif
-#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
+#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
# if HAVE_WCSLEN
# define local_wcslen wcslen
# else
# endif
#endif
-#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
+#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
# if HAVE_WCSNLEN
# define local_wcsnlen wcsnlen
# else
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
/* Use a different function name, to make it possible that the 'wchar_t'
parametrization and the 'char' parametrization get compiled in the same
}
}
#endif
-#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
+#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
else if (dp->conversion == 's'
# if WIDE_CHAR_VERSION
&& a.arg[dp->arg_index].type != TYPE_WIDE_STRING
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
int has_width;
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
size_t width;
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
int has_precision;
size_t precision;
#endif
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
has_width = 0;
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
width = 0;
if (dp->width_start != dp->width_end)
{
}
#endif
-#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
has_precision = 0;
precision = 6;
if (dp->precision_start != dp->precision_end)
break;
# else
*fbp++ = 'l';
- /*FALLTHROUGH*/
# endif
#endif
+ FALLTHROUGH;
case TYPE_LONGINT:
case TYPE_ULONGINT:
#if HAVE_WINT_T
/* Look at the snprintf() return value. */
if (retcount < 0)
{
-# if !HAVE_SNPRINTF_RETVAL_C99
+# if !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
/* HP-UX 10.20 snprintf() is doubly deficient:
It doesn't understand the '%n' directive,
*and* it returns -1 (rather than the length
codeset.m4 \
extern-inline.m4 \
fcntl-o.m4 \
+flexmember.m4 \
gettext.m4 \
glibc2.m4 \
glibc21.m4 \
dnl 'extern inline' a la ISO C99.
-dnl Copyright 2012-2016 Free Software Foundation, Inc.
+dnl Copyright 2012-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# fcntl-o.m4 serial 4
-dnl Copyright (C) 2006, 2009-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 2006, 2009-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
--- /dev/null
+# serial 5
+# Check for flexible array member support.
+
+# Copyright (C) 2006, 2009-2017 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Written by Paul Eggert.
+
+AC_DEFUN([AC_C_FLEXIBLE_ARRAY_MEMBER],
+[
+ AC_CACHE_CHECK([for flexible array member],
+ ac_cv_c_flexmember,
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stdlib.h>
+ #include <stdio.h>
+ #include <stddef.h>
+ struct m { struct m *next, **list; char name[]; };
+ struct s { struct s *p; struct m *m; int n; double d[]; };]],
+ [[int m = getchar ();
+ size_t nbytes = offsetof (struct s, d) + m * sizeof (double);
+ nbytes += sizeof (struct s) - 1;
+ nbytes -= nbytes % sizeof (struct s);
+ struct s *p = malloc (nbytes);
+ p->p = p;
+ p->m = NULL;
+ p->d[0] = 0.0;
+ return p->d != (double *) NULL;]])],
+ [ac_cv_c_flexmember=yes],
+ [ac_cv_c_flexmember=no])])
+ if test $ac_cv_c_flexmember = yes; then
+ AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [],
+ [Define to nothing if C supports flexible array members, and to
+ 1 if it does not. That way, with a declaration like 'struct s
+ { int n; double d@<:@FLEXIBLE_ARRAY_MEMBER@:>@; };', the struct hack
+ can be used with pre-C99 compilers.
+ When computing the size of such an object, don't use 'sizeof (struct s)'
+ as it overestimates the size. Use 'offsetof (struct s, d)' instead.
+ Don't use 'offsetof (struct s, d@<:@0@:>@)', as this doesn't work with
+ MSVC and with C++ compilers.])
+ else
+ AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [1])
+ fi
+])
# glibc2.m4 serial 3
-dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2016 Free Software Foundation,
+dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2017 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
# glibc21.m4 serial 5
-dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2016 Free Software Foundation,
+dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2017 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
# intdiv0.m4 serial 6 (gettext-0.18.2)
-dnl Copyright (C) 2002, 2007-2008, 2010-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2007-2008, 2010-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
-# intl.m4 serial 29 (gettext-0.19)
-dnl Copyright (C) 1995-2014, 2016 Free Software Foundation, Inc.
+# intl.m4 serial 30 (gettext-0.19.9)
+dnl Copyright (C) 1995-2014, 2016-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_REQUIRE([gt_INTL_MACOSX])dnl
AC_REQUIRE([gl_EXTERN_INLINE])dnl
AC_REQUIRE([gt_GL_ATTRIBUTE])dnl
+ AC_REQUIRE([AC_C_FLEXIBLE_ARRAY_MEMBER])dnl
dnl Support for automake's --enable-silent-rules.
case "$enable_silent_rules" in
# intmax.m4 serial 6 (gettext-0.18.2)
-dnl Copyright (C) 2002-2005, 2008-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2005, 2008-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# inttypes-pri.m4 serial 7 (gettext-0.18.2)
-dnl Copyright (C) 1997-2002, 2006, 2008-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 1997-2002, 2006, 2008-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# inttypes_h.m4 serial 10
-dnl Copyright (C) 1997-2004, 2006, 2008-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 1997-2004, 2006, 2008-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
-# lock.m4 serial 13 (gettext-0.18.2)
-dnl Copyright (C) 2005-2016 Free Software Foundation, Inc.
+# lock.m4 serial 14
+dnl Copyright (C) 2005-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
if test "$gl_threads_api" = posix; then
# OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the
# pthread_rwlock_* functions.
+ has_rwlock=false
AC_CHECK_TYPE([pthread_rwlock_t],
- [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
+ [has_rwlock=true
+ AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
[Define if the POSIX multithreading library has read/write locks.])],
[],
[#include <pthread.h>])
+ if $has_rwlock; then
+ gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER
+ fi
# glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM(
# longlong.m4 serial 17
-dnl Copyright (C) 1999-2007, 2009-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 1999-2007, 2009-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# printf-posix.m4 serial 6 (gettext-0.18.2)
-dnl Copyright (C) 2003, 2007, 2009-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2007, 2009-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# progtest.m4 serial 7 (gettext-0.18.2)
-dnl Copyright (C) 1996-2003, 2005, 2008-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 1996-2003, 2005, 2008-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# size_max.m4 serial 10
-dnl Copyright (C) 2003, 2005-2006, 2008-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2005-2006, 2008-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# stdint_h.m4 serial 9
-dnl Copyright (C) 1997-2004, 2006, 2008-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 1997-2004, 2006, 2008-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
-# threadlib.m4 serial 11 (gettext-0.18.2)
-dnl Copyright (C) 2005-2016 Free Software Foundation, Inc.
+# threadlib.m4 serial 12
+dnl Copyright (C) 2005-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# Therefore pthread_in_use() needs to actually try to create a
# thread: pthread_create from libc will fail, whereas
# pthread_create will actually create a thread.
+ # On Solaris 10 or newer, this test is no longer needed, because
+ # libc contains the fully functional pthread functions.
case "$host_os" in
- solaris* | hpux*)
+ solaris | solaris2.[1-9] | solaris2.[1-9].* | hpux*)
AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],
[Define if the pthread_in_use() detection is hard.])
esac
# uintmax_t.m4 serial 12
-dnl Copyright (C) 1997-2004, 2007-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 1997-2004, 2007-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# visibility.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2005, 2008, 2010-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 2005, 2008, 2010-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# wchar_t.m4 serial 4 (gettext-0.18.2)
-dnl Copyright (C) 2002-2003, 2008-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2003, 2008-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# xsize.m4 serial 5
-dnl Copyright (C) 2003-2004, 2008-2016 Free Software Foundation, Inc.
+dnl Copyright (C) 2003-2004, 2008-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
#define EXPLICIT_YIELD 1
/* Whether to use 'volatile' on some variables that communicate information
- between threads. If set to 0, a lock is used to protect these variables.
- If set to 1, 'volatile' is used; this is theoretically equivalent but can
- lead to much slower execution (e.g. 30x slower total run time on a 40-core
- machine. */
+ between threads. If set to 0, a semaphore or a lock is used to protect
+ these variables. If set to 1, 'volatile' is used; this is theoretically
+ equivalent but can lead to much slower execution (e.g. 30x slower total
+ run time on a 40-core machine), because 'volatile' does not imply any
+ synchronization/communication between different CPUs. */
#define USE_VOLATILE 0
+#if USE_POSIX_THREADS && HAVE_SEMAPHORE_H
+/* Whether to use a semaphore to communicate information between threads.
+ If set to 0, a lock is used. If set to 1, a semaphore is used.
+ Uncomment this to reduce the dependencies of this test. */
+# define USE_SEMAPHORE 1
+/* Mac OS X provides only named semaphores (sem_open); its facility for
+ unnamed semaphores (sem_init) does not work. */
+# if defined __APPLE__ && defined __MACH__
+# define USE_NAMED_SEMAPHORE 1
+# else
+# define USE_UNNAMED_SEMAPHORE 1
+# endif
+#endif
+
/* Whether to print debugging messages. */
#define ENABLE_DEBUGGING 0
#endif
#include "lock.h"
+#if USE_SEMAPHORE
+# include <errno.h>
+# include <fcntl.h>
+# include <semaphore.h>
+# include <unistd.h>
+#endif
+
#if ENABLE_DEBUGGING
# define dbgprintf printf
#else
{
ai->value = new_value;
}
+#elif USE_SEMAPHORE
+/* This atomic_int implementation can only support the values 0 and 1.
+ It is initially 0 and can be set to 1 only once. */
+# if USE_UNNAMED_SEMAPHORE
+struct atomic_int {
+ sem_t semaphore;
+};
+#define atomic_int_semaphore(ai) (&(ai)->semaphore)
+static void
+init_atomic_int (struct atomic_int *ai)
+{
+ sem_init (&ai->semaphore, 0, 0);
+}
+# endif
+# if USE_NAMED_SEMAPHORE
+struct atomic_int {
+ sem_t *semaphore;
+};
+#define atomic_int_semaphore(ai) ((ai)->semaphore)
+static void
+init_atomic_int (struct atomic_int *ai)
+{
+ sem_t *s;
+ unsigned int count;
+ for (count = 0; ; count++)
+ {
+ char name[80];
+ /* Use getpid() in the name, so that different processes running at the
+ same time will not interfere. Use ai in the name, so that different
+ atomic_int in the same process will not interfere. Use a count in
+ the name, so that even in the (unlikely) case that a semaphore with
+ the specified name already exists, we can try a different name. */
+ sprintf (name, "test-lock-%lu-%p-%u",
+ (unsigned long) getpid (), ai, count);
+ s = sem_open (name, O_CREAT | O_EXCL, 0600, 0);
+ if (s == SEM_FAILED)
+ {
+ if (errno == EEXIST)
+ /* Retry with a different name. */
+ continue;
+ else
+ {
+ perror ("sem_open failed");
+ abort ();
+ }
+ }
+ else
+ {
+ /* Try not to leave a semaphore hanging around on the file system
+ eternally, if we can avoid it. */
+ sem_unlink (name);
+ break;
+ }
+ }
+ ai->semaphore = s;
+}
+# endif
+static int
+get_atomic_int_value (struct atomic_int *ai)
+{
+ if (sem_trywait (atomic_int_semaphore (ai)) == 0)
+ {
+ if (sem_post (atomic_int_semaphore (ai)))
+ abort ();
+ return 1;
+ }
+ else if (errno == EAGAIN)
+ return 0;
+ else
+ abort ();
+}
+static void
+set_atomic_int_value (struct atomic_int *ai, int new_value)
+{
+ if (new_value == 0)
+ /* It's already initialized with 0. */
+ return;
+ /* To set the value 1: */
+ if (sem_post (atomic_int_semaphore (ai)))
+ abort ();
+}
#else
struct atomic_int {
gl_lock_define (, lock)