]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Update gettext-runtime files from gnulib.
authorBruno Haible <bruno@clisp.org>
Thu, 18 May 2017 23:15:33 +0000 (01:15 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 18 May 2017 23:15:33 +0000 (01:15 +0200)
* 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>.

36 files changed:
Makefile.am
gettext-runtime/intl/Makefile.in
gettext-runtime/intl/flexmember.h [new file with mode: 0644]
gettext-runtime/intl/localcharset.c
gettext-runtime/intl/localename.c
gettext-runtime/intl/lock.c
gettext-runtime/intl/lock.h
gettext-runtime/intl/relocatable.c
gettext-runtime/intl/relocatable.h
gettext-runtime/intl/vasnprintf.c
gettext-runtime/intl/verify.h
gettext-runtime/intl/xsize.h
gettext-runtime/libasprintf/vasnprintf.c
gettext-runtime/m4/Makefile.am
gettext-runtime/m4/extern-inline.m4
gettext-runtime/m4/fcntl-o.m4
gettext-runtime/m4/flexmember.m4 [new file with mode: 0644]
gettext-runtime/m4/glibc2.m4
gettext-runtime/m4/glibc21.m4
gettext-runtime/m4/intdiv0.m4
gettext-runtime/m4/intl.m4
gettext-runtime/m4/intmax.m4
gettext-runtime/m4/inttypes-pri.m4
gettext-runtime/m4/inttypes_h.m4
gettext-runtime/m4/lock.m4
gettext-runtime/m4/longlong.m4
gettext-runtime/m4/printf-posix.m4
gettext-runtime/m4/progtest.m4
gettext-runtime/m4/size_max.m4
gettext-runtime/m4/stdint_h.m4
gettext-runtime/m4/threadlib.m4
gettext-runtime/m4/uintmax_t.m4
gettext-runtime/m4/visibility.m4
gettext-runtime/m4/wchar_t.m4
gettext-runtime/m4/xsize.m4
gettext-runtime/tests/test-lock.c

index 0d8276daf4db8e2ec9952b9abdd8a5935b6d5514..b92defda0a7a74df2286325ac1bce2866f138cd2 100644 (file)
@@ -1,5 +1,5 @@
 ## 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
@@ -73,6 +73,7 @@ distcheck-hook:
        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
@@ -102,6 +103,7 @@ distcheck-hook:
        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`"
index 3f2b185beccb7d86d6e3844965a259993cd1ba7a..1422bcc22bd5596bcb124d98fa7460f90760d407 100644 (file)
@@ -158,6 +158,7 @@ SOURCES = \
   relocatable.c \
   langprefs.c \
   localename.c \
+  flexmember.h \
   log.c \
   printf.c \
   setlocale.c \
diff --git a/gettext-runtime/intl/flexmember.h b/gettext-runtime/intl/flexmember.h
new file mode 100644 (file)
index 0000000..56350a7
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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))
index 213e726fb922610bf31f4f40c8f50b4f9555e1cd..2bd741cfaefccdd06d4afd6b2bfa1de3ef2d292f 100644 (file)
@@ -1,6 +1,6 @@
 /* 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
@@ -32,7 +32,7 @@
 # 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
@@ -75,6 +75,7 @@
 # include "relocatable.h"
 #else
 # define relocate(pathname) (pathname)
+# define relocate2(pathname,allocatedp) (*(allocatedp) = NULL, (pathname))
 #endif
 
 /* Get LIBDIR.  */
@@ -129,6 +130,7 @@ get_charset_aliases (void)
   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;
@@ -137,7 +139,7 @@ get_charset_aliases (void)
          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.  */
       {
@@ -154,6 +156,8 @@ get_charset_aliases (void)
           }
       }
 
+      free (malloc_dir);
+
       if (file_name == NULL)
         /* Out of memory.  Treat the file as empty.  */
         cp = "";
@@ -507,7 +511,7 @@ locale_charset (void)
     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
     {
index 81ab21304359429637160b8de437efa51b5d281d..eb0755c6d9430b9681b240d0901a9fe71b3e4f7b 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -59,7 +61,7 @@ extern char * getlocalename_l(int, locale_t);
 # 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"
@@ -2619,7 +2621,7 @@ string_hash (const void *x)
 struct hash_node
   {
     struct hash_node * volatile next;
-    char contents[100]; /* has variable size */
+    char contents[FLEXIBLE_ARRAY_MEMBER];
   };
 
 # define HASH_TABLE_SIZE 257
@@ -2646,7 +2648,7 @@ struniq (const char *string)
   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";
@@ -2732,6 +2734,19 @@ gl_locale_name_thread_unsafe (int category, const char *categoryname)
 #  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
index 69d624d7d8ef0ec0573ed048382e7123cbced069..f8784558a764eb49e2aa5cec3ac62352a3da98cd 100644 (file)
@@ -1,5 +1,5 @@
 /* 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)
@@ -152,11 +181,9 @@ glthread_rwlock_rdlock_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
@@ -481,6 +508,141 @@ glthread_once_singlethreaded (pthread_once_t *once_control)
 
 /* ------------------------- 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 -------------------------- */
@@ -796,8 +958,10 @@ glthread_rwlock_rdlock_func (gl_rwlock_t *lock)
     }
   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.  */
index 6b173f812210cfed1d33e7c6bd33fde87de485e4..33909ec2591bdaedb2c91c36a4da48f399c6a874 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -139,6 +139,11 @@ extern int glthread_in_use (void);
 #  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
@@ -176,7 +181,7 @@ typedef pthread_mutex_t gl_lock_t;
 
 /* ------------------------- 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
 
@@ -185,10 +190,18 @@ typedef pthread_rwlock_t gl_rwlock_t;
       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) \
@@ -427,6 +440,9 @@ typedef pth_mutex_t gl_lock_t;
 
 /* ------------------------- 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;
@@ -445,6 +461,42 @@ typedef pth_rwlock_t gl_rwlock_t;
 #  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.  */
index 401f3e0e45dbe57b62f0fb88a0cc9bf1b9024543..0892e3a42307508456fda424d523b1c3c357829f 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -542,27 +542,26 @@ relocate (const char *pathname)
 # 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;
             }
@@ -574,4 +573,17 @@ relocate (const char *pathname)
   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
index ecad3a76d6602e26759796e050e62db1d89b015f..11bd9aeeed073bbfec4171dc468a825ae87698e7 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -52,10 +52,29 @@ extern RELOCATABLE_DLL_EXPORTED void
    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
@@ -70,6 +89,7 @@ extern char * compute_curr_prefix (const char *orig_installprefix,
 
 /* By default, we use the hardwired pathnames.  */
 #define relocate(pathname) (pathname)
+#define relocate2(pathname,allocatedp) (*(allocatedp) = NULL, (pathname))
 
 #endif
 
index 236bfe5da11dbaecbb9e5cbb72129d4175d4d5d5..eb8f1fd81a81700315479f56ac4796e87fbafafc 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -224,7 +235,7 @@ local_strnlen (const char *string, size_t maxlen)
 # 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
@@ -247,7 +258,7 @@ local_wcslen (const wchar_t *s)
 # 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
@@ -1517,7 +1528,7 @@ is_borderline (const char *digits, size_t precision)
 
 #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
@@ -2392,7 +2403,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   }
               }
 #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
@@ -4591,10 +4602,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #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
@@ -4623,7 +4634,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #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)
                   {
@@ -4657,7 +4668,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   }
 #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)
@@ -4832,9 +4843,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                     break;
 # else
                     *fbp++ = 'l';
-                    /*FALLTHROUGH*/
 # endif
 #endif
+                    FALLTHROUGH;
                   case TYPE_LONGINT:
                   case TYPE_ULONGINT:
 #if HAVE_WINT_T
@@ -5127,7 +5138,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                             /* 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
index 267de295917762f435cce05e4762555e4733184c..3a2f6d129380f4dcc839235e97cb9eafdaef4c4e 100644 (file)
@@ -1,6 +1,6 @@
 /* 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
@@ -248,7 +248,12 @@ template <int w>
 /* 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
@@ -263,7 +268,7 @@ template <int w>
 # 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
index c82712d3e28423d38a3565c4665b99a626e0af28..d6a5508084e11c24f6ef34cb2f9a732c4d08d49f 100644 (file)
@@ -1,6 +1,6 @@
 /* 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
index 236bfe5da11dbaecbb9e5cbb72129d4175d4d5d5..eb8f1fd81a81700315479f56ac4796e87fbafafc 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -224,7 +235,7 @@ local_strnlen (const char *string, size_t maxlen)
 # 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
@@ -247,7 +258,7 @@ local_wcslen (const wchar_t *s)
 # 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
@@ -1517,7 +1528,7 @@ is_borderline (const char *digits, size_t precision)
 
 #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
@@ -2392,7 +2403,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   }
               }
 #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
@@ -4591,10 +4602,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #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
@@ -4623,7 +4634,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #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)
                   {
@@ -4657,7 +4668,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   }
 #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)
@@ -4832,9 +4843,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                     break;
 # else
                     *fbp++ = 'l';
-                    /*FALLTHROUGH*/
 # endif
 #endif
+                    FALLTHROUGH;
                   case TYPE_LONGINT:
                   case TYPE_ULONGINT:
 #if HAVE_WINT_T
@@ -5127,7 +5138,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                             /* 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
index 740e462da3f5912e8898e6afa75227cb642d6a2b..1544a7c4613f46ff764649f51624ca376eacef89 100644 (file)
@@ -6,6 +6,7 @@ EXTRA_DIST = README \
 codeset.m4 \
 extern-inline.m4 \
 fcntl-o.m4 \
+flexmember.m4 \
 gettext.m4 \
 glibc2.m4 \
 glibc21.m4 \
index 1e578f3deb426f10df4f03c5948282aa989f9a89..00f960968b01314a60b065a82d3736cb6d3ae9bb 100644 (file)
@@ -1,6 +1,6 @@
 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.
index 24fcf88d09458ebbfa6cd066ff2792f079d0ab64..3c3b63c5259ae311f3c415eab30bcae257309dac 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
diff --git a/gettext-runtime/m4/flexmember.m4 b/gettext-runtime/m4/flexmember.m4
new file mode 100644 (file)
index 0000000..9d3b50d
--- /dev/null
@@ -0,0 +1,46 @@
+# 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
+])
index 785bba095bfd2bb22d51d55d22206bb68ed63bc1..926edbab70064db77977cb3549b26de24f49871e 100644 (file)
@@ -1,5 +1,5 @@
 # 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,
index dafebf5017d61f0382c739ef693431dee49f8568..2e30ed6884b249ae3a08948e49a1799f57ba0760 100644 (file)
@@ -1,5 +1,5 @@
 # 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,
index 744b99ea8da87ca1f54ab3767030de066029c5f5..bbbc11433f975e9b9076f44c37be9dd2b868fe4d 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index 42fac9535af2bac5adac56ee263b4667c770272e..646c5b5aec10be1c6423159bd665051b54c48253 100644 (file)
@@ -1,5 +1,5 @@
-# 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.
@@ -44,6 +44,7 @@ AC_DEFUN([AM_INTL_SUBDIR],
   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
index 1a47107f1bb83282763b29b641657274df93cc61..b432fae67dc8776bceac336e51225810a8b15b23 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index ae20183db428379fbe31b291f88ca3313429f3d1..205578782f36fea3375ff2ff3002a6e470a395ce 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index 76571199f366b99b5e4a4c44b5b3183e74c5ded0..92403050579e1799bf706d87ff136ef60d9f7f31 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index 1e83e23651f8d877cb8ea2fc49971cd5c489842e..cb04a67d7d581063863fed30ab76de7c4c0164ce 100644 (file)
@@ -1,5 +1,5 @@
-# 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.
@@ -12,11 +12,16 @@ AC_DEFUN([gl_LOCK],
   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(
index 36d8b12421266e7fe5d4d34f52fddf272712b11b..9a3294bc2cab5454d1df1569a9d6b78593d9d919 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index f9088c090a3e7a8a2c82df721454d19ade6dcf6e..0577933586633430e28a4d74cb35d6f85004bad8 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index 9ace7c3418ab17032469546c3cd05d07697f34cb..303bc31824feb853947dce84a59eacf7914507cd 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index de69025d62b6cbfa1525f1eecd417ef35dd941fb..05ad1b602a4e77f69ab3db96fe98784df49d487f 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index f823b94c338ea6dc802e7ac8373988e900f681da..786eaa3c9599bf8a02fe7d76253736d4f18ddb63 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index b43534ea278493cb78eb75d716fc44ff5a206834..f79fde20f5bf3b04b4c3247664ca540b422beb9f 100644 (file)
@@ -1,5 +1,5 @@
-# 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.
@@ -195,8 +195,10 @@ int main ()
              # 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
index 30f4dd5d19f24d5dcafe6a673b086d80388c5777..7e3b3dfe3f7cb5aad7ae0f3703e31bee77b3d307 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index e99e3fbad41161c227fce49242566d3694c968ce..ce00e72501e9b6477427ca53b741aa78d37c341d 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index 2db8c3f2f629af7fdb27b85efa469cea7d9cb516..11783d299a71d1f13fd6ec16bf2e920cfc814640 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index 16764e89ddcdc8200362e25fb1f081c555560b4e..5f8505770c3c81559ed387ed4249d304ff304686 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
index 51cec3d6b8e995a11fa7eb64c58ffffd7a38e39e..751b27b500e67716742916e6c77c893b5156fcb3 100644 (file)
 #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
@@ -239,6 +261,87 @@ set_atomic_int_value (struct atomic_int *ai, int new_value)
 {
   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)