code:
/* Locking in multithreaded situations.
   Copyright (C) 2005-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
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>, 2005.
   Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
   gthr-win32.h.  */

/* This file contains locking primitives for use with a given thread library.
   It does not contain primitives for creating threads or for other
   synchronization primitives.

   Normal (non-recursive) locks:
     Type:                gl_lock_t
     Declaration:         gl_lock_define(extern, name)
     Initializer:         gl_lock_define_initialized(, name)
     Initialization:      gl_lock_init (name);
     Taking the lock:     gl_lock_lock (name);
     Releasing the lock:  gl_lock_unlock (name);
     De-initialization:   gl_lock_destroy (name);
   Equivalent functions with control of error handling:
     Initialization:      err = glthread_lock_init (&name);
     Taking the lock:     err = glthread_lock_lock (&name);
     Releasing the lock:  err = glthread_lock_unlock (&name);
     De-initialization:   err = glthread_lock_destroy (&name);

   Read-Write (non-recursive) locks:
     Type:                gl_rwlock_t
     Declaration:         gl_rwlock_define(extern, name)
     Initializer:         gl_rwlock_define_initialized(, name)
     Initialization:      gl_rwlock_init (name);
     Taking the lock:     gl_rwlock_rdlock (name);
                          gl_rwlock_wrlock (name);
     Releasing the lock:  gl_rwlock_unlock (name);
     De-initialization:   gl_rwlock_destroy (name);
   Equivalent functions with control of error handling:
     Initialization:      err = glthread_rwlock_init (&name);
     Taking the lock:     err = glthread_rwlock_rdlock (&name);
                          err = glthread_rwlock_wrlock (&name);
     Releasing the lock:  err = glthread_rwlock_unlock (&name);
     De-initialization:   err = glthread_rwlock_destroy (&name);

   Recursive locks:
     Type:                gl_recursive_lock_t
     Declaration:         gl_recursive_lock_define(extern, name)
     Initializer:         gl_recursive_lock_define_initialized(, name)
     Initialization:      gl_recursive_lock_init (name);
     Taking the lock:     gl_recursive_lock_lock (name);
     Releasing the lock:  gl_recursive_lock_unlock (name);
     De-initialization:   gl_recursive_lock_destroy (name);
   Equivalent functions with control of error handling:
     Initialization:      err = glthread_recursive_lock_init (&name);
     Taking the lock:     err = glthread_recursive_lock_lock (&name);
     Releasing the lock:  err = glthread_recursive_lock_unlock (&name);
     De-initialization:   err = glthread_recursive_lock_destroy (&name);

  Once-only execution:
     Type:                gl_once_t
     Initializer:         gl_once_define(extern, name)
     Execution:           gl_once (name, initfunction);
   Equivalent functions with control of error handling:
     Execution:           err = glthread_once (&name, initfunction);
*/

#ifndef _LOCK_H
#define _LOCK_H

#include <errno.h>
#include <stdlib.h>

/* ========================================================================= */

#if USE_POSIX_THREADS

/* Use the POSIX threads library.  */

# include <pthread.h>

# ifdef __cplusplus
extern "C" {
# endif

# if PTHREAD_IN_USE_DETECTION_HARD

/* The pthread_in_use() detection needs to be done at runtime.  */
#  define pthread_in_use() \
     glthread_in_use ()
extern int glthread_in_use (void);

# endif

# if USE_POSIX_THREADS_WEAK

/* Use weak references to the POSIX threads library.  */

/* Weak references avoid dragging in external libraries if the other parts
   of the program don't use them.  Here we use them, because we don't want
   every program that uses libintl to depend on libpthread.  This assumes
   that libpthread would not be loaded after libintl; i.e. if libintl is
   loaded first, by an executable that does not depend on libpthread, and
   then a module is dynamically loaded that depends on libpthread, libintl
   will not be multithread-safe.  */

/* The way to test at runtime whether libpthread is present is to test
   whether a function pointer's value, such as &pthread_mutex_init, is
   non-NULL.  However, some versions of GCC have a bug through which, in
   PIC mode, &foo != NULL always evaluates to true if there is a direct
   call to foo(...) in the same function.  To avoid this, we test the
   address of a function in libpthread that we don't use.  */

#  pragma weak pthread_mutex_init
#  pragma weak pthread_mutex_lock
#  pragma weak pthread_mutex_unlock
#  pragma weak pthread_mutex_destroy
#  pragma weak pthread_rwlock_init
#  pragma weak pthread_rwlock_rdlock
#  pragma weak pthread_rwlock_wrlock
#  pragma weak pthread_rwlock_unlock
#  pragma weak pthread_rwlock_destroy
#  pragma weak pthread_once
#  pragma weak pthread_cond_init
#  pragma weak pthread_cond_wait
#  pragma weak pthread_cond_signal
#  pragma weak pthread_cond_broadcast
#  pragma weak pthread_cond_destroy
#  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

#  if !PTHREAD_IN_USE_DETECTION_HARD
#   pragma weak pthread_cancel
#   define pthread_in_use() (pthread_cancel != NULL)
#  endif

# else

#  if !PTHREAD_IN_USE_DETECTION_HARD
#   define pthread_in_use() 1
#  endif

# endif

/* -------------------------- gl_lock_t datatype -------------------------- */

typedef pthread_mutex_t gl_lock_t;
# define gl_lock_define(STORAGECLASS, NAME) \
    STORAGECLASS pthread_mutex_t NAME;
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
    STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
# define gl_lock_initializer \
    PTHREAD_MUTEX_INITIALIZER
# define glthread_lock_init(LOCK) \
    (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0)
# define glthread_lock_lock(LOCK) \
    (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
# define glthread_lock_unlock(LOCK) \
    (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
# define glthread_lock_destroy(LOCK) \
    (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)

/* ------------------------- gl_rwlock_t datatype ------------------------- */

# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1)))

#  ifdef PTHREAD_RWLOCK_INITIALIZER

typedef pthread_rwlock_t gl_rwlock_t;
#   define gl_rwlock_define(STORAGECLASS, NAME) \
      STORAGECLASS pthread_rwlock_t NAME;
#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
      STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
#   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) \
      (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0)
#   define glthread_rwlock_unlock(LOCK) \
      (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0)
#   define glthread_rwlock_destroy(LOCK) \
      (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0)

#  else

typedef struct
        {
          int initialized;
          pthread_mutex_t guard;   /* protects the initialization */
          pthread_rwlock_t rwlock; /* read-write lock */
        }
        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, PTHREAD_MUTEX_INITIALIZER }
#   define glthread_rwlock_init(LOCK) \
      (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
#   define glthread_rwlock_rdlock(LOCK) \
      (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
#   define glthread_rwlock_wrlock(LOCK) \
      (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
#   define glthread_rwlock_unlock(LOCK) \
      (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
#   define glthread_rwlock_destroy(LOCK) \
      (pthread_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

# else

typedef struct
        {
          pthread_mutex_t lock; /* protects the remaining fields */
          pthread_cond_t waiting_readers; /* waiting readers */
          pthread_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 \
    { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
# define glthread_rwlock_init(LOCK) \
    (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
# define glthread_rwlock_rdlock(LOCK) \
    (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
# define glthread_rwlock_wrlock(LOCK) \
    (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
# define glthread_rwlock_unlock(LOCK) \
    (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
# define glthread_rwlock_destroy(LOCK) \
    (pthread_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 --------------------- */

# if HAVE_PTHREAD_MUTEX_RECURSIVE

#  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP

typedef pthread_mutex_t gl_recursive_lock_t;
#   define gl_recursive_lock_define(STORAGECLASS, NAME) \
      STORAGECLASS pthread_mutex_t NAME;
#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
      STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer;
#   ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
#    define gl_recursive_lock_initializer \
       PTHREAD_RECURSIVE_MUTEX_INITIALIZER
#   else
#    define gl_recursive_lock_initializer \
       PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#   endif
#   define glthread_recursive_lock_init(LOCK) \
      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
#   define glthread_recursive_lock_lock(LOCK) \
      (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
#   define glthread_recursive_lock_unlock(LOCK) \
      (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
#   define glthread_recursive_lock_destroy(LOCK) \
      (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);

#  else

typedef struct
        {
          pthread_mutex_t recmutex; /* recursive mutex */
          pthread_mutex_t guard;    /* protects the initialization */
          int initialized;
        }
        gl_recursive_lock_t;
#   define gl_recursive_lock_define(STORAGECLASS, NAME) \
      STORAGECLASS gl_recursive_lock_t NAME;
#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
      STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
#   define gl_recursive_lock_initializer \
      { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
#   define glthread_recursive_lock_init(LOCK) \
      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
#   define glthread_recursive_lock_lock(LOCK) \
      (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
#   define glthread_recursive_lock_unlock(LOCK) \
      (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
#   define glthread_recursive_lock_destroy(LOCK) \
      (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);

#  endif

# else

/* Old versions of POSIX threads on Solaris did not have recursive locks.
   We have to implement them ourselves.  */

typedef struct
        {
          pthread_mutex_t mutex;
          pthread_t owner;
          unsigned long depth;
        }
        gl_recursive_lock_t;
#  define gl_recursive_lock_define(STORAGECLASS, NAME) \
     STORAGECLASS gl_recursive_lock_t NAME;
#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
#  define gl_recursive_lock_initializer \
     { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
#  define glthread_recursive_lock_init(LOCK) \
     (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
#  define glthread_recursive_lock_lock(LOCK) \
     (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
#  define glthread_recursive_lock_unlock(LOCK) \
     (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
#  define glthread_recursive_lock_destroy(LOCK) \
     (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);

# endif

/* -------------------------- gl_once_t datatype -------------------------- */

typedef pthread_once_t gl_once_t;
# define gl_once_define(STORAGECLASS, NAME) \
    STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
    (pthread_in_use ()                                                         \
     ? pthread_once (ONCE_CONTROL, INITFUNCTION)                               \
     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
extern int glthread_once_singlethreaded (pthread_once_t *once_control);

# ifdef __cplusplus
}
# endif

#endif

/* ========================================================================= */

#if USE_PTH_THREADS

/* Use the GNU Pth threads library.  */

# include <pth.h>

# ifdef __cplusplus
extern "C" {
# endif

# if USE_PTH_THREADS_WEAK

/* Use weak references to the GNU Pth threads library.  */

#  pragma weak pth_mutex_init
#  pragma weak pth_mutex_acquire
#  pragma weak pth_mutex_release
#  pragma weak pth_rwlock_init
#  pragma weak pth_rwlock_acquire
#  pragma weak pth_rwlock_release
#  pragma weak pth_once

#  pragma weak pth_cancel
#  define pth_in_use() (pth_cancel != NULL)

# else

#  define pth_in_use() 1

# endif

/* -------------------------- gl_lock_t datatype -------------------------- */

typedef pth_mutex_t gl_lock_t;
# define gl_lock_define(STORAGECLASS, NAME) \
    STORAGECLASS pth_mutex_t NAME;
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
    STORAGECLASS pth_mutex_t NAME = gl_lock_initializer;
# define gl_lock_initializer \
    PTH_MUTEX_INIT
# define glthread_lock_init(LOCK) \
    (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
# define glthread_lock_lock(LOCK) \
    (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
# define glthread_lock_unlock(LOCK) \
    (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
# define glthread_lock_destroy(LOCK) \
    ((void)(LOCK), 0)

/* ------------------------- 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 gl_rwlock_define_initialized(STORAGECLASS, NAME) \
     STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer;
#  define gl_rwlock_initializer \
     PTH_RWLOCK_INIT
#  define glthread_rwlock_init(LOCK) \
     (pth_in_use () && !pth_rwlock_init (LOCK) ? errno : 0)
#  define glthread_rwlock_rdlock(LOCK) \
     (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RD, 0, NULL) ? errno : 0)
#  define glthread_rwlock_wrlock(LOCK) \
     (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RW, 0, NULL) ? errno : 0)
#  define glthread_rwlock_unlock(LOCK) \
     (pth_in_use () && !pth_rwlock_release (LOCK) ? errno : 0)
#  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.  */
typedef pth_mutex_t gl_recursive_lock_t;
#  define gl_recursive_lock_define(STORAGECLASS, NAME) \
     STORAGECLASS pth_mutex_t NAME;
#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
     STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer;
#  define gl_recursive_lock_initializer \
     PTH_MUTEX_INIT
#  define glthread_recursive_lock_init(LOCK) \
     (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
#  define glthread_recursive_lock_lock(LOCK) \
     (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
#  define glthread_recursive_lock_unlock(LOCK) \
     (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
#  define glthread_recursive_lock_destroy(LOCK) \
     ((void)(LOCK), 0)

/* -------------------------- gl_once_t datatype -------------------------- */

typedef pth_once_t gl_once_t;
# define gl_once_define(STORAGECLASS, NAME) \
    STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT;
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
    (pth_in_use ()                                                             \
     ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)                \
     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
extern int glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void));
extern int glthread_once_singlethreaded (pth_once_t *once_control);

# ifdef __cplusplus
}
# endif

#endif

/* ========================================================================= */

#if USE_SOLARIS_THREADS

/* Use the old Solaris threads library.  */

# include <thread.h>
# include <synch.h>

# ifdef __cplusplus
extern "C" {
# endif

# if USE_SOLARIS_THREADS_WEAK

/* Use weak references to the old Solaris threads library.  */

#  pragma weak mutex_init
#  pragma weak mutex_lock
#  pragma weak mutex_unlock
#  pragma weak mutex_destroy
#  pragma weak rwlock_init
#  pragma weak rw_rdlock
#  pragma weak rw_wrlock
#  pragma weak rw_unlock
#  pragma weak rwlock_destroy
#  pragma weak thr_self

#  pragma weak thr_suspend
#  define thread_in_use() (thr_suspend != NULL)

# else

#  define thread_in_use() 1

# endif

/* -------------------------- gl_lock_t datatype -------------------------- */

typedef mutex_t gl_lock_t;
# define gl_lock_define(STORAGECLASS, NAME) \
    STORAGECLASS mutex_t NAME;
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
    STORAGECLASS mutex_t NAME = gl_lock_initializer;
# define gl_lock_initializer \
    DEFAULTMUTEX
# define glthread_lock_init(LOCK) \
    (thread_in_use () ? mutex_init (LOCK, USYNC_THREAD, NULL) : 0)
# define glthread_lock_lock(LOCK) \
    (thread_in_use () ? mutex_lock (LOCK) : 0)
# define glthread_lock_unlock(LOCK) \
    (thread_in_use () ? mutex_unlock (LOCK) : 0)
# define glthread_lock_destroy(LOCK) \
    (thread_in_use () ? mutex_destroy (LOCK) : 0)

/* ------------------------- gl_rwlock_t datatype ------------------------- */

typedef rwlock_t gl_rwlock_t;
# define gl_rwlock_define(STORAGECLASS, NAME) \
    STORAGECLASS rwlock_t NAME;
# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
    STORAGECLASS rwlock_t NAME = gl_rwlock_initializer;
# define gl_rwlock_initializer \
    DEFAULTRWLOCK
# define glthread_rwlock_init(LOCK) \
    (thread_in_use () ? rwlock_init (LOCK, USYNC_THREAD, NULL) : 0)
# define glthread_rwlock_rdlock(LOCK) \
    (thread_in_use () ? rw_rdlock (LOCK) : 0)
# define glthread_rwlock_wrlock(LOCK) \
    (thread_in_use () ? rw_wrlock (LOCK) : 0)
# define glthread_rwlock_unlock(LOCK) \
    (thread_in_use () ? rw_unlock (LOCK) : 0)
# define glthread_rwlock_destroy(LOCK) \
    (thread_in_use () ? rwlock_destroy (LOCK) : 0)

/* --------------------- gl_recursive_lock_t datatype --------------------- */

/* Old Solaris threads did not have recursive locks.
   We have to implement them ourselves.  */

typedef struct
        {
          mutex_t mutex;
          thread_t owner;
          unsigned long depth;
        }
        gl_recursive_lock_t;
# define gl_recursive_lock_define(STORAGECLASS, NAME) \
    STORAGECLASS gl_recursive_lock_t NAME;
# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
# define gl_recursive_lock_initializer \
    { DEFAULTMUTEX, (thread_t) 0, 0 }
# define glthread_recursive_lock_init(LOCK) \
    (thread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
# define glthread_recursive_lock_lock(LOCK) \
    (thread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
# define glthread_recursive_lock_unlock(LOCK) \
    (thread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
# define glthread_recursive_lock_destroy(LOCK) \
    (thread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);

/* -------------------------- gl_once_t datatype -------------------------- */

typedef struct
        {
          volatile int inited;
          mutex_t mutex;
        }
        gl_once_t;
# define gl_once_define(STORAGECLASS, NAME) \
    STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX };
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
    (thread_in_use ()                                                          \
     ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)                \
     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
extern int glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void));
extern int glthread_once_singlethreaded (gl_once_t *once_control);

# ifdef __cplusplus
}
# endif

#endif

/* ========================================================================= */

#if USE_WINDOWS_THREADS

# define WIN32_LEAN_AND_MEAN  /* avoid including junk */
# include <windows.h>

# ifdef __cplusplus
extern "C" {
# endif

/* We can use CRITICAL_SECTION directly, rather than the native Windows Event,
   Mutex, Semaphore types, because
     - we need only to synchronize inside a single process (address space),
       not inter-process locking,
     - we don't need to support trylock operations.  (TryEnterCriticalSection
       does not work on Windows 95/98/ME.  Packages that need trylock usually
       define their own mutex type.)  */

/* There is no way to statically initialize a CRITICAL_SECTION.  It needs
   to be done lazily, once only.  For this we need spinlocks.  */

typedef struct { volatile int done; volatile long started; } gl_spinlock_t;

/* -------------------------- gl_lock_t datatype -------------------------- */

typedef struct
        {
          gl_spinlock_t guard; /* protects the initialization */
          CRITICAL_SECTION lock;
        }
        gl_lock_t;
# define gl_lock_define(STORAGECLASS, NAME) \
    STORAGECLASS gl_lock_t NAME;
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
    STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
# define gl_lock_initializer \
    { { 0, -1 } }
# define glthread_lock_init(LOCK) \
    (glthread_lock_init_func (LOCK), 0)
# define glthread_lock_lock(LOCK) \
    glthread_lock_lock_func (LOCK)
# define glthread_lock_unlock(LOCK) \
    glthread_lock_unlock_func (LOCK)
# define glthread_lock_destroy(LOCK) \
    glthread_lock_destroy_func (LOCK)
extern void glthread_lock_init_func (gl_lock_t *lock);
extern int glthread_lock_lock_func (gl_lock_t *lock);
extern int glthread_lock_unlock_func (gl_lock_t *lock);
extern int glthread_lock_destroy_func (gl_lock_t *lock);

/* ------------------------- gl_rwlock_t datatype ------------------------- */

/* It is impossible to implement read-write locks using plain locks, without
   introducing an extra thread dedicated to managing read-write locks.
   Therefore here we need to use the low-level Event type.  */

typedef struct
        {
          HANDLE *array; /* array of waiting threads, each represented by an event */
          unsigned int count; /* number of waiting threads */
          unsigned int alloc; /* length of allocated array */
          unsigned int offset; /* index of first waiting thread in array */
        }
        gl_carray_waitqueue_t;
typedef struct
        {
          gl_spinlock_t guard; /* protects the initialization */
          CRITICAL_SECTION lock; /* protects the remaining fields */
          gl_carray_waitqueue_t waiting_readers; /* waiting readers */
          gl_carray_waitqueue_t waiting_writers; /* 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, -1 } }
# define glthread_rwlock_init(LOCK) \
    (glthread_rwlock_init_func (LOCK), 0)
# define glthread_rwlock_rdlock(LOCK) \
    glthread_rwlock_rdlock_func (LOCK)
# define glthread_rwlock_wrlock(LOCK) \
    glthread_rwlock_wrlock_func (LOCK)
# define glthread_rwlock_unlock(LOCK) \
    glthread_rwlock_unlock_func (LOCK)
# define glthread_rwlock_destroy(LOCK) \
    glthread_rwlock_destroy_func (LOCK)
extern void glthread_rwlock_init_func (gl_rwlock_t *lock);
extern int glthread_rwlock_rdlock_func (gl_rwlock_t *lock);
extern int glthread_rwlock_wrlock_func (gl_rwlock_t *lock);
extern int glthread_rwlock_unlock_func (gl_rwlock_t *lock);
extern int glthread_rwlock_destroy_func (gl_rwlock_t *lock);

/* --------------------- gl_recursive_lock_t datatype --------------------- */

/* The native Windows documentation says that CRITICAL_SECTION already
   implements a recursive lock.  But we need not rely on it: It's easy to
   implement a recursive lock without this assumption.  */

typedef struct
        {
          gl_spinlock_t guard; /* protects the initialization */
          DWORD owner;
          unsigned long depth;
          CRITICAL_SECTION lock;
        }
        gl_recursive_lock_t;
# define gl_recursive_lock_define(STORAGECLASS, NAME) \
    STORAGECLASS gl_recursive_lock_t NAME;
# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
# define gl_recursive_lock_initializer \
    { { 0, -1 }, 0, 0 }
# define glthread_recursive_lock_init(LOCK) \
    (glthread_recursive_lock_init_func (LOCK), 0)
# define glthread_recursive_lock_lock(LOCK) \
    glthread_recursive_lock_lock_func (LOCK)
# define glthread_recursive_lock_unlock(LOCK) \
    glthread_recursive_lock_unlock_func (LOCK)
# define glthread_recursive_lock_destroy(LOCK) \
    glthread_recursive_lock_destroy_func (LOCK)
extern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock);
extern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock);

/* -------------------------- gl_once_t datatype -------------------------- */

typedef struct
        {
          volatile int inited;
          volatile long started;
          CRITICAL_SECTION lock;
        }
        gl_once_t;
# define gl_once_define(STORAGECLASS, NAME) \
    STORAGECLASS gl_once_t NAME = { -1, -1 };
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
    (glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0)
extern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void));

# ifdef __cplusplus
}
# endif

#endif

/* ========================================================================= */

#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS)

/* Provide dummy implementation if threads are not supported.  */

/* -------------------------- gl_lock_t datatype -------------------------- */

typedef int gl_lock_t;
# define gl_lock_define(STORAGECLASS, NAME)
# define gl_lock_define_initialized(STORAGECLASS, NAME)
# define glthread_lock_init(NAME) 0
# define glthread_lock_lock(NAME) 0
# define glthread_lock_unlock(NAME) 0
# define glthread_lock_destroy(NAME) 0

/* ------------------------- gl_rwlock_t datatype ------------------------- */

typedef int gl_rwlock_t;
# define gl_rwlock_define(STORAGECLASS, NAME)
# define gl_rwlock_define_initialized(STORAGECLASS, NAME)
# define glthread_rwlock_init(NAME) 0
# define glthread_rwlock_rdlock(NAME) 0
# define glthread_rwlock_wrlock(NAME) 0
# define glthread_rwlock_unlock(NAME) 0
# define glthread_rwlock_destroy(NAME) 0

/* --------------------- gl_recursive_lock_t datatype --------------------- */

typedef int gl_recursive_lock_t;
# define gl_recursive_lock_define(STORAGECLASS, NAME)
# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
# define glthread_recursive_lock_init(NAME) 0
# define glthread_recursive_lock_lock(NAME) 0
# define glthread_recursive_lock_unlock(NAME) 0
# define glthread_recursive_lock_destroy(NAME) 0

/* -------------------------- gl_once_t datatype -------------------------- */

typedef int gl_once_t;
# define gl_once_define(STORAGECLASS, NAME) \
    STORAGECLASS gl_once_t NAME = 0;
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
    (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)

#endif

/* ========================================================================= */

/* Macros with built-in error handling.  */

/* -------------------------- gl_lock_t datatype -------------------------- */

#define gl_lock_init(NAME) \
   do                                  \
     {                                 \
       if (glthread_lock_init (&NAME)) \
         abort ();                     \
     }                                 \
   while (0)
#define gl_lock_lock(NAME) \
   do                                  \
     {                                 \
       if (glthread_lock_lock (&NAME)) \
         abort ();                     \
     }                                 \
   while (0)
#define gl_lock_unlock(NAME) \
   do                                    \
     {                                   \
       if (glthread_lock_unlock (&NAME)) \
         abort ();                       \
     }                                   \
   while (0)
#define gl_lock_destroy(NAME) \
   do                                     \
     {                                    \
       if (glthread_lock_destroy (&NAME)) \
         abort ();                        \
     }                                    \
   while (0)

/* ------------------------- gl_rwlock_t datatype ------------------------- */

#define gl_rwlock_init(NAME) \
   do                                    \
     {                                   \
       if (glthread_rwlock_init (&NAME)) \
         abort ();                       \
     }                                   \
   while (0)
#define gl_rwlock_rdlock(NAME) \
   do                                      \
     {                                     \
       if (glthread_rwlock_rdlock (&NAME)) \
         abort ();                         \
     }                                     \
   while (0)
#define gl_rwlock_wrlock(NAME) \
   do                                      \
     {                                     \
       if (glthread_rwlock_wrlock (&NAME)) \
         abort ();                         \
     }                                     \
   while (0)
#define gl_rwlock_unlock(NAME) \
   do                                      \
     {                                     \
       if (glthread_rwlock_unlock (&NAME)) \
         abort ();                         \
     }                                     \
   while (0)
#define gl_rwlock_destroy(NAME) \
   do                                       \
     {                                      \
       if (glthread_rwlock_destroy (&NAME)) \
         abort ();                          \
     }                                      \
   while (0)

/* --------------------- gl_recursive_lock_t datatype --------------------- */

#define gl_recursive_lock_init(NAME) \
   do                                            \
     {                                           \
       if (glthread_recursive_lock_init (&NAME)) \
         abort ();                               \
     }                                           \
   while (0)
#define gl_recursive_lock_lock(NAME) \
   do                                            \
     {                                           \
       if (glthread_recursive_lock_lock (&NAME)) \
         abort ();                               \
     }                                           \
   while (0)
#define gl_recursive_lock_unlock(NAME) \
   do                                              \
     {                                             \
       if (glthread_recursive_lock_unlock (&NAME)) \
         abort ();                                 \
     }                                             \
   while (0)
#define gl_recursive_lock_destroy(NAME) \
   do                                               \
     {                                              \
       if (glthread_recursive_lock_destroy (&NAME)) \
         abort ();                                  \
     }                                              \
   while (0)

/* -------------------------- gl_once_t datatype -------------------------- */

#define gl_once(NAME, INITFUNCTION) \
   do                                           \
     {                                          \
       if (glthread_once (&NAME, INITFUNCTION)) \
         abort ();                              \
     }                                          \
   while (0)

/* ========================================================================= */

#endif /* _LOCK_H */


code:
/* Multithreading primitives.
   Copyright (C) 2005-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
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>, 2005.  */

#include <config.h>

/* ========================================================================= */

#if USE_POSIX_THREADS

/* Use the POSIX threads library.  */

# include <pthread.h>
# include <stdlib.h>

# if PTHREAD_IN_USE_DETECTION_HARD

/* The function to be executed by a dummy thread.  */
static void *
dummy_thread_func (void *arg)
{
  return arg;
}

int
glthread_in_use (void)
{
  static int tested;
  static int result; /* 1: linked with -lpthread, 0: only with libc */

  if (!tested)
    {
      pthread_t thread;

      if (pthread_create (&thread, NULL, dummy_thread_func, NULL) != 0)
        /* Thread creation failed.  */
        result = 0;
      else
        {
          /* Thread creation works.  */
          void *retval;
          if (pthread_join (thread, &retval) != 0)
            abort ();
          result = 1;
        }
      tested = 1;
    }
  return result;
}

# endif

#endif

/* ========================================================================= */

/* This declaration is solely to ensure that after preprocessing
   this file is never empty.  */
typedef int dummy;

repo_name: mthl/texinfo

license: mit


code:
/* hard-locale.c -- Determine whether a locale is hard.

   Copyright (C) 1997-1999, 2002-2004, 2006-2007, 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 General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

#include "hard-locale.h"

#include <locale.h>
#include <stdlib.h>
#include <string.h>

#ifdef __GLIBC__
# define GLIBC_VERSION __GLIBC__
#elif defined __UCLIBC__
# define GLIBC_VERSION 2
#else
# define GLIBC_VERSION 0
#endif

/* Return true if the current CATEGORY locale is hard, i.e. if you
   can't get away with assuming traditional C or POSIX behavior.  */
bool
hard_locale (int category)
{
  bool hard = true;
  char const *p = setlocale (category, NULL);

  if (p)
    {
      if (2 <= GLIBC_VERSION)
        {
          if (strcmp (p, "C") == 0 || strcmp (p, "POSIX") == 0)
            hard = false;
        }
      else
        {
          char *locale = strdup (p);
          if (locale)
            {
              /* Temporarily set the locale to the "C" and "POSIX" locales
                 to find their names, so that we can determine whether one
                 or the other is the caller's locale.  */
              if (((p = setlocale (category, "C"))
                   && strcmp (p, locale) == 0)
                  || ((p = setlocale (category, "POSIX"))
                      && strcmp (p, locale) == 0))
                hard = false;

              /* Restore the caller's locale.  */
              setlocale (category, locale);
              free (locale);
            }
        }
    }

  return hard;
}


code:
/* Determine whether a locale is hard.

   Copyright (C) 1999, 2003-2004, 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 General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef HARD_LOCALE_H_
# define HARD_LOCALE_H_ 1

# include <stdbool.h>

bool hard_locale (int);

#endif /* HARD_LOCALE_H_ */


code:
/* intprops.h -- properties of integer types

   Copyright (C) 2001-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 the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* Written by Paul Eggert.  */

#ifndef _GL_INTPROPS_H
#define _GL_INTPROPS_H

#include <limits.h>
#include <verify.h>

/* Return a value with the common real type of E and V and the value of V.  */
#define _GL_INT_CONVERT(e, v) (0 * (e) + (v))

/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see
   <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00406.html>.  */
#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v))

/* The extra casts in the following macros work around compiler bugs,
   e.g., in Cray C 5.0.3.0.  */

/* True if the arithmetic type T is an integer type.  bool counts as
   an integer.  */
#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)

/* True if the real type T is signed.  */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))

/* Return 1 if the real expression E, after promotion, has a
   signed or floating type.  */
#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)

/* Minimum and maximum values for integer types and expressions.  */

/* The width in bits of the integer type or expression T.
   Padding bits are not supported; this is checked at compile-time below.  */
#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

/* The maximum and minimum values for the integer type T.  */
#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
#define TYPE_MAXIMUM(t)                                                 \
  ((t) (! TYPE_SIGNED (t)                                               \
        ? (t) -1                                                        \
        : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1)))

/* The maximum and minimum values for the type of the expression E,
   after integer promotion.  E should not have side effects.  */
#define _GL_INT_MINIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
   : _GL_INT_CONVERT (e, 0))
#define _GL_INT_MAXIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
   : _GL_INT_NEGATE_CONVERT (e, 1))
#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH ((e) + 0) - 2)) - 1) * 2 + 1)

/* Work around OpenVMS incompatibility with C99.  */
#if !defined LLONG_MAX && defined __INT64_MAX
# define LLONG_MAX __INT64_MAX
# define LLONG_MIN __INT64_MIN
#endif

/* This include file assumes that signed types are two's complement without
   padding bits; the above macros have undefined behavior otherwise.
   If this is a problem for you, please let us know how to fix it for your host.
   As a sanity check, test the assumption for some signed types that
   <limits.h> bounds.  */
verify (TYPE_MINIMUM (signed char) == SCHAR_MIN);
verify (TYPE_MAXIMUM (signed char) == SCHAR_MAX);
verify (TYPE_MINIMUM (short int) == SHRT_MIN);
verify (TYPE_MAXIMUM (short int) == SHRT_MAX);
verify (TYPE_MINIMUM (int) == INT_MIN);
verify (TYPE_MAXIMUM (int) == INT_MAX);
verify (TYPE_MINIMUM (long int) == LONG_MIN);
verify (TYPE_MAXIMUM (long int) == LONG_MAX);
#ifdef LLONG_MAX
verify (TYPE_MINIMUM (long long int) == LLONG_MIN);
verify (TYPE_MAXIMUM (long long int) == LLONG_MAX);
#endif
/* Similarly, sanity-check one ISO/IEC TS 18661-1:2014 macro if defined.  */
#ifdef UINT_WIDTH
verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
#endif

/* Does the __typeof__ keyword work?  This could be done by
   'configure', but for now it's easier to do it by hand.  */
#if (2 <= __GNUC__ \
     || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
     || (0x5110 <= __SUNPRO_C && !__STDC__))
# define _GL_HAVE___TYPEOF__ 1
#else
# define _GL_HAVE___TYPEOF__ 0
#endif

/* Return 1 if the integer type or expression T might be signed.  Return 0
   if it is definitely unsigned.  This macro does not evaluate its argument,
   and expands to an integer constant expression.  */
#if _GL_HAVE___TYPEOF__
# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))
#else
# define _GL_SIGNED_TYPE_OR_EXPR(t) 1
#endif

/* Bound on length of the string representing an unsigned integer
   value representable in B bits.  log10 (2.0) < 146/485.  The
   smallest value of B where this bound is not tight is 2621.  */
#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)

/* Bound on length of the string representing an integer type or expression T.
   Subtract 1 for the sign bit if T is signed, and then add 1 more for
   a minus sign if needed.

   Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is
   signed, this macro may overestimate the true bound by one byte when
   applied to unsigned types of size 2, 4, 16, ... bytes.  */
#define INT_STRLEN_BOUND(t)                                     \
  (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \
   + _GL_SIGNED_TYPE_OR_EXPR (t))

/* Bound on buffer size needed to represent an integer type or expression T,
   including the terminating null.  */
#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)

/* Range overflow checks.

   The INT_<op>_RANGE_OVERFLOW macros return 1 if the corresponding C
   operators might not yield numerically correct answers due to
   arithmetic overflow.  They do not rely on undefined or
   implementation-defined behavior.  Their implementations are simple
   and straightforward, but they are a bit harder to use than the
   INT_<op>_OVERFLOW macros described below.

   Example usage:

     long int i = ...;
     long int j = ...;
     if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX))
       printf ("multiply would overflow");
     else
       printf ("product is %ld", i * j);

   Restrictions on *_RANGE_OVERFLOW macros:

   These macros do not check for all possible numerical problems or
   undefined or unspecified behavior: they do not check for division
   by zero, for bad shift counts, or for shifting negative numbers.

   These macros may evaluate their arguments zero or multiple times,
   so the arguments should not have side effects.  The arithmetic
   arguments (including the MIN and MAX arguments) must be of the same
   integer type after the usual arithmetic conversions, and the type
   must have minimum value MIN and maximum MAX.  Unsigned types should
   use a zero MIN of the proper type.

   These macros are tuned for constant MIN and MAX.  For commutative
   operations such as A + B, they are also tuned for constant B.  */

/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic.
   See above for restrictions.  */
#define INT_ADD_RANGE_OVERFLOW(a, b, min, max)          \
  ((b) < 0                                              \
   ? (a) < (min) - (b)                                  \
   : (max) - (b) < (a))

/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic.
   See above for restrictions.  */
#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max)     \
  ((b) < 0                                              \
   ? (max) + (b) < (a)                                  \
   : (a) < (min) + (b))

/* Return 1 if - A would overflow in [MIN,MAX] arithmetic.
   See above for restrictions.  */
#define INT_NEGATE_RANGE_OVERFLOW(a, min, max)          \
  ((min) < 0                                            \
   ? (a) < - (max)                                      \
   : 0 < (a))

/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic.
   See above for restrictions.  Avoid && and || as they tickle
   bugs in Sun C 5.11 2010/08/13 and other compilers; see
   <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>.  */
#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max)     \
  ((b) < 0                                              \
   ? ((a) < 0                                           \
      ? (a) < (max) / (b)                               \
      : (b) == -1                                       \
      ? 0                                               \
      : (min) / (b) < (a))                              \
   : (b) == 0                                           \
   ? 0                                                  \
   : ((a) < 0                                           \
      ? (a) < (min) / (b)                               \
      : (max) / (b) < (a)))

/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic.
   See above for restrictions.  Do not check for division by zero.  */
#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max)       \
  ((min) < 0 && (b) == -1 && (a) < - (max))

/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic.
   See above for restrictions.  Do not check for division by zero.
   Mathematically, % should never overflow, but on x86-like hosts
   INT_MIN % -1 traps, and the C standard permits this, so treat this
   as an overflow too.  */
#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max)    \
  INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max)

/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic.
   See above for restrictions.  Here, MIN and MAX are for A only, and B need
   not be of the same type as the other arguments.  The C standard says that
   behavior is undefined for shifts unless 0 <= B < wordwidth, and that when
   A is negative then A << B has undefined behavior and A >> B has
   implementation-defined behavior, but do not check these other
   restrictions.  */
#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max)   \
  ((a) < 0                                              \
   ? (a) < (min) >> (b)                                 \
   : (max) >> (b) < (a))

/* True if __builtin_add_overflow (A, B, P) works when P is non-null.  */
#define _GL_HAS_BUILTIN_OVERFLOW (5 <= __GNUC__)

/* True if __builtin_add_overflow_p (A, B, C) works.  */
#define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)

/* The _GL*_OVERFLOW macros have the same restrictions as the
   *_RANGE_OVERFLOW macros, except that they do not assume that operands
   (e.g., A and B) have the same type as MIN and MAX.  Instead, they assume
   that the result (e.g., A + B) has that type.  */
#if _GL_HAS_BUILTIN_OVERFLOW_P
# define _GL_ADD_OVERFLOW(a, b, min, max)                               \
   __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)
# define _GL_SUBTRACT_OVERFLOW(a, b, min, max)                          \
   __builtin_sub_overflow_p (a, b, (__typeof__ ((a) - (b))) 0)
# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                          \
   __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0)
#else
# define _GL_ADD_OVERFLOW(a, b, min, max)                                \
   ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max)                  \
    : (a) < 0 ? (b) <= (a) + (b)                                         \
    : (b) < 0 ? (a) <= (a) + (b)                                         \
    : (a) + (b) < (b))
# define _GL_SUBTRACT_OVERFLOW(a, b, min, max)                           \
   ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max)             \
    : (a) < 0 ? 1                                                        \
    : (b) < 0 ? (a) - (b) <= (a)                                         \
    : (a) < (b))
# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                           \
   (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a))))       \
    || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))
#endif
#define _GL_DIVIDE_OVERFLOW(a, b, min, max)                             \
  ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max)  \
   : (a) < 0 ? (b) <= (a) + (b) - 1                                     \
   : (b) < 0 && (a) + (b) <= (a))
#define _GL_REMAINDER_OVERFLOW(a, b, min, max)                          \
  ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max)  \
   : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b)                     \
   : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max))

/* Return a nonzero value if A is a mathematical multiple of B, where
   A is unsigned, B is negative, and MAX is the maximum value of A's
   type.  A's type must be the same as (A % B)'s type.  Normally (A %
   -B == 0) suffices, but things get tricky if -B would overflow.  */
#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max)                            \
  (((b) < -_GL_SIGNED_INT_MAXIMUM (b)                                   \
    ? (_GL_SIGNED_INT_MAXIMUM (b) == (max)                              \
       ? (a)                                                            \
       : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1))   \
    : (a) % - (b))                                                      \
   == 0)

/* Check for integer overflow, and report low order bits of answer.

   The INT_<op>_OVERFLOW macros return 1 if the corresponding C operators
   might not yield numerically correct answers due to arithmetic overflow.
   The INT_<op>_WRAPV macros also store the low-order bits of the answer.
   These macros work correctly on all known practical hosts, and do not rely
   on undefined behavior due to signed arithmetic overflow.

   Example usage, assuming A and B are long int:

     if (INT_MULTIPLY_OVERFLOW (a, b))
       printf ("result would overflow\n");
     else
       printf ("result is %ld (no overflow)\n", a * b);

   Example usage with WRAPV flavor:

     long int result;
     bool overflow = INT_MULTIPLY_WRAPV (a, b, &result);
     printf ("result is %ld (%s)\n", result,
             overflow ? "after overflow" : "no overflow");

   Restrictions on these macros:

   These macros do not check for all possible numerical problems or
   undefined or unspecified behavior: they do not check for division
   by zero, for bad shift counts, or for shifting negative numbers.

   These macros may evaluate their arguments zero or multiple times, so the
   arguments should not have side effects.

   The WRAPV macros are not constant expressions.  They support only
   +, binary -, and *.  The result type must be signed.

   These macros are tuned for their last argument being a constant.

   Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B,
   A % B, and A << B would overflow, respectively.  */

#define INT_ADD_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW)
#define INT_SUBTRACT_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW)
#if _GL_HAS_BUILTIN_OVERFLOW_P
# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a)
#else
# define INT_NEGATE_OVERFLOW(a) \
   INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
#endif
#define INT_MULTIPLY_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)
#define INT_DIVIDE_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW)
#define INT_REMAINDER_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW)
#define INT_LEFT_SHIFT_OVERFLOW(a, b) \
  INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \
                                 _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))

/* Return 1 if the expression A <op> B would overflow,
   where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test,
   assuming MIN and MAX are the minimum and maximum for the result type.
   Arguments should be free of side effects.  */
#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow)        \
  op_result_overflow (a, b,                                     \
                      _GL_INT_MINIMUM (0 * (b) + (a)),          \
                      _GL_INT_MAXIMUM (0 * (b) + (a)))

/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R.
   Return 1 if the result overflows.  See above for restrictions.  */
#define INT_ADD_WRAPV(a, b, r) \
  _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, INT_ADD_OVERFLOW)
#define INT_SUBTRACT_WRAPV(a, b, r) \
  _GL_INT_OP_WRAPV (a, b, r, -, __builtin_sub_overflow, INT_SUBTRACT_OVERFLOW)
#define INT_MULTIPLY_WRAPV(a, b, r) \
  _GL_INT_OP_WRAPV (a, b, r, *, __builtin_mul_overflow, INT_MULTIPLY_OVERFLOW)

/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390.  See:
   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193
   https://llvm.org/bugs/show_bug.cgi?id=25390
   For now, assume all versions of GCC-like compilers generate bogus
   warnings for _Generic.  This matters only for older compilers that
   lack __builtin_add_overflow.  */
#if __GNUC__
# define _GL__GENERIC_BOGUS 1
#else
# define _GL__GENERIC_BOGUS 0
#endif

/* Store the low-order bits of A <op> B into *R, where OP specifies
   the operation.  BUILTIN is the builtin operation, and OVERFLOW the
   overflow predicate.  Return 1 if the result overflows.  See above
   for restrictions.  */
#if _GL_HAS_BUILTIN_OVERFLOW
# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r)
#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS
# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
   (_Generic \
    (*(r), \
     signed char: \
       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                        signed char, SCHAR_MIN, SCHAR_MAX), \
     short int: \
       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                        short int, SHRT_MIN, SHRT_MAX), \
     int: \
       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                        int, INT_MIN, INT_MAX), \
     long int: \
       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
                        long int, LONG_MIN, LONG_MAX), \
     long long int: \
       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
                        long long int, LLONG_MIN, LLONG_MAX)))
#else
# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
   (sizeof *(r) == sizeof (signed char) \
    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                       signed char, SCHAR_MIN, SCHAR_MAX) \
    : sizeof *(r) == sizeof (short int) \
    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                       short int, SHRT_MIN, SHRT_MAX) \
    : sizeof *(r) == sizeof (int) \
    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                       int, INT_MIN, INT_MAX) \
    : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow))
# ifdef LLONG_MAX
#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
    (sizeof *(r) == sizeof (long int) \
     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
                        long int, LONG_MIN, LONG_MAX) \
     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
                        long long int, LLONG_MIN, LLONG_MAX))
# else
#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
    _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
                     long int, LONG_MIN, LONG_MAX)
# endif
#endif

/* Store the low-order bits of A <op> B into *R, where the operation
   is given by OP.  Use the unsigned type UT for calculation to avoid
   overflow problems.  *R's type is T, with extrema TMIN and TMAX.
   T must be a signed integer type.  Return 1 if the result overflows.  */
#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
  (sizeof ((a) op (b)) < sizeof (t) \
   ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \
   : _GL_INT_OP_CALC1 (a, b, r, op, overflow, ut, t, tmin, tmax))
#define _GL_INT_OP_CALC1(a, b, r, op, overflow, ut, t, tmin, tmax) \
  ((overflow (a, b) \
    || (EXPR_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \
    || (tmax) < ((a) op (b))) \
   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))

/* Return the low-order bits of A <op> B, where the operation is given
   by OP.  Use the unsigned type UT for calculation to avoid undefined
   behavior on signed integer overflow, and convert the result to type T.
   UT is at least as wide as T and is no narrower than unsigned int,
   T is two's complement, and there is no padding or trap representations.
   Assume that converting UT to T yields the low-order bits, as is
   done in all known two's-complement C compilers.  E.g., see:
   https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

   According to the C standard, converting UT to T yields an
   implementation-defined result or signal for values outside T's
   range.  However, code that works around this theoretical problem
   runs afoul of a compiler bug in Oracle Studio 12.3 x86.  See:
   http://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html
   As the compiler bug is real, don't try to work around the
   theoretical problem.  */

#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
  ((t) ((ut) (a) op (ut) (b)))

#endif /* _GL_INTPROPS_H */


code:
/* Test wide character for being blank.
   Copyright (C) 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 General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <wctype.h>

int
iswblank (wint_t wc)
{
  return wc == ' ' || wc == '\t';
}


code:
/* Replacement for 'int' to 'long double' conversion routine.
   Copyright (C) 2011-2017 Free Software Foundation, Inc.
   Written by Bruno Haible <bruno@clisp.org>, 2011.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <float.h>

void
_Qp_itoq (long double *result, int a)
{
  /* Convert from 'int' to 'double', then from 'double' to 'long double'.  */
  *result = (double) a;
}


code:
/* Substitute for and wrapper around <langinfo.h>.
   Copyright (C) 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 General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */

/*
 * POSIX <langinfo.h> for platforms that lack it or have an incomplete one.
 * <http://www.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html>
 */

#ifndef _@GUARD_PREFIX@_LANGINFO_H

#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
#endif
@PRAGMA_COLUMNS@

/* The include_next requires a split double-inclusion guard.  */
#if @HAVE_LANGINFO_H@
# @INCLUDE_NEXT@ @NEXT_LANGINFO_H@
#endif

#ifndef _@GUARD_PREFIX@_LANGINFO_H
#define _@GUARD_PREFIX@_LANGINFO_H

#if !@HAVE_LANGINFO_H@

/* A platform that lacks <langinfo.h>.  */

/* Assume that it also lacks <nl_types.h> and the nl_item type.  */
# if !GNULIB_defined_nl_item
typedef int nl_item;
#  define GNULIB_defined_nl_item 1
# endif

/* nl_langinfo items of the LC_CTYPE category */
# define CODESET     10000
/* nl_langinfo items of the LC_NUMERIC category */
# define RADIXCHAR   10001
# define DECIMAL_POINT RADIXCHAR
# define THOUSEP     10002
# define THOUSANDS_SEP THOUSEP
# define GROUPING    10114
/* nl_langinfo items of the LC_TIME category */
# define D_T_FMT     10003
# define D_FMT       10004
# define T_FMT       10005
# define T_FMT_AMPM  10006
# define AM_STR      10007
# define PM_STR      10008
# define DAY_1       10009
# define DAY_2       (DAY_1 + 1)
# define DAY_3       (DAY_1 + 2)
# define DAY_4       (DAY_1 + 3)
# define DAY_5       (DAY_1 + 4)
# define DAY_6       (DAY_1 + 5)
# define DAY_7       (DAY_1 + 6)
# define ABDAY_1     10016
# define ABDAY_2     (ABDAY_1 + 1)
# define ABDAY_3     (ABDAY_1 + 2)
# define ABDAY_4     (ABDAY_1 + 3)
# define ABDAY_5     (ABDAY_1 + 4)
# define ABDAY_6     (ABDAY_1 + 5)
# define ABDAY_7     (ABDAY_1 + 6)
# define MON_1       10023
# define MON_2       (MON_1 + 1)
# define MON_3       (MON_1 + 2)
# define MON_4       (MON_1 + 3)
# define MON_5       (MON_1 + 4)
# define MON_6       (MON_1 + 5)
# define MON_7       (MON_1 + 6)
# define MON_8       (MON_1 + 7)
# define MON_9       (MON_1 + 8)
# define MON_10      (MON_1 + 9)
# define MON_11      (MON_1 + 10)
# define MON_12      (MON_1 + 11)
# define ABMON_1     10035
# define ABMON_2     (ABMON_1 + 1)
# define ABMON_3     (ABMON_1 + 2)
# define ABMON_4     (ABMON_1 + 3)
# define ABMON_5     (ABMON_1 + 4)
# define ABMON_6     (ABMON_1 + 5)
# define ABMON_7     (ABMON_1 + 6)
# define ABMON_8     (ABMON_1 + 7)
# define ABMON_9     (ABMON_1 + 8)
# define ABMON_10    (ABMON_1 + 9)
# define ABMON_11    (ABMON_1 + 10)
# define ABMON_12    (ABMON_1 + 11)
# define ERA         10047
# define ERA_D_FMT   10048
# define ERA_D_T_FMT 10049
# define ERA_T_FMT   10050
# define ALT_DIGITS  10051
/* nl_langinfo items of the LC_MONETARY category */
# define CRNCYSTR    10052
# define CURRENCY_SYMBOL   CRNCYSTR
# define INT_CURR_SYMBOL   10100
# define MON_DECIMAL_POINT 10101
# define MON_THOUSANDS_SEP 10102
# define MON_GROUPING      10103
# define POSITIVE_SIGN     10104
# define NEGATIVE_SIGN     10105
# define FRAC_DIGITS       10106
# define INT_FRAC_DIGITS   10107
# define P_CS_PRECEDES     10108
# define N_CS_PRECEDES     10109
# define P_SEP_BY_SPACE    10110
# define N_SEP_BY_SPACE    10111
# define P_SIGN_POSN       10112
# define N_SIGN_POSN       10113
/* nl_langinfo items of the LC_MESSAGES category */
# define YESEXPR     10053
# define NOEXPR      10054

#else

/* A platform that has <langinfo.h>.  */

# if !@HAVE_LANGINFO_CODESET@
#  define CODESET     10000
#  define GNULIB_defined_CODESET 1
# endif

# if !@HAVE_LANGINFO_T_FMT_AMPM@
#  define T_FMT_AMPM  10006
#  define GNULIB_defined_T_FMT_AMPM 1
# endif

# if !@HAVE_LANGINFO_ERA@
#  define ERA         10047
#  define ERA_D_FMT   10048
#  define ERA_D_T_FMT 10049
#  define ERA_T_FMT   10050
#  define ALT_DIGITS  10051
#  define GNULIB_defined_ERA 1
# endif

# if !@HAVE_LANGINFO_YESEXPR@
#  define YESEXPR     10053
#  define NOEXPR      10054
#  define GNULIB_defined_YESEXPR 1
# endif

#endif

/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */

/* The definition of _GL_WARN_ON_USE is copied here.  */

/* Declare overridden functions.  */

/* Return a piece of locale dependent information.
   Note: The difference between nl_langinfo (CODESET) and locale_charset ()
   is that the latter normalizes the encoding names to GNU conventions.  */

#if @GNULIB_NL_LANGINFO@
# if @REPLACE_NL_LANGINFO@
#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
#   undef nl_langinfo
#   define nl_langinfo rpl_nl_langinfo
#  endif
_GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item));
_GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item));
# else
#  if !@HAVE_NL_LANGINFO@
_GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item));
#  endif
_GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item));
# endif
_GL_CXXALIASWARN (nl_langinfo);
#elif defined GNULIB_POSIXCHECK
# undef nl_langinfo
# if HAVE_RAW_DECL_NL_LANGINFO
_GL_WARN_ON_USE (nl_langinfo, "nl_langinfo is not portable - "
                 "use gnulib module nl_langinfo for portability");
# endif
#endif

#endif /* _@GUARD_PREFIX@_LANGINFO_H */
#endif /* _@GUARD_PREFIX@_LANGINFO_H */


code:
/* A GNU-like <limits.h>.

   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 General Public License
   as published by the Free Software Foundation; either version 3, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */

#ifndef _@GUARD_PREFIX@_LIMITS_H

#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
#endif
@PRAGMA_COLUMNS@

/* The include_next requires a split double-inclusion guard.  */
#@INCLUDE_NEXT@ @NEXT_LIMITS_H@

#ifndef _@GUARD_PREFIX@_LIMITS_H
#define _@GUARD_PREFIX@_LIMITS_H

/* For HP-UX 11.31.  */
#if defined LONG_LONG_MIN && !defined LLONG_MIN
# define LLONG_MIN LONG_LONG_MIN
#endif
#if defined LONG_LONG_MAX && !defined LLONG_MAX
# define LLONG_MAX LONG_LONG_MAX
#endif
#if defined ULONG_LONG_MAX && !defined ULLONG_MAX
# define ULLONG_MAX ULONG_LONG_MAX
#endif

/* The number of usable bits in an unsigned or signed integer type
   with minimum value MIN and maximum value MAX, as an int expression
   suitable in #if.  Cover all known practical hosts.  This
   implementation exploits the fact that MAX is 1 less than a power of
   2, and merely counts the number of 1 bits in MAX; "COBn" means
   "count the number of 1 bits in the low-order n bits").  */
#define _GL_INTEGER_WIDTH(min, max) (((min) < 0) + _GL_COB128 (max))
#define _GL_COB128(n) (_GL_COB64 ((n) >> 31 >> 31 >> 2) + _GL_COB64 (n))
#define _GL_COB64(n) (_GL_COB32 ((n) >> 31 >> 1) + _GL_COB32 (n))
#define _GL_COB32(n) (_GL_COB16 ((n) >> 16) + _GL_COB16 (n))
#define _GL_COB16(n) (_GL_COB8 ((n) >> 8) + _GL_COB8 (n))
#define _GL_COB8(n) (_GL_COB4 ((n) >> 4) + _GL_COB4 (n))
#define _GL_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + !!((n) & 1))

/* Macros specified by ISO/IEC TS 18661-1:2014.  */

#if (! defined ULLONG_WIDTH                                             \
     && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__))
# define CHAR_WIDTH _GL_INTEGER_WIDTH (CHAR_MIN, CHAR_MAX)
# define SCHAR_WIDTH _GL_INTEGER_WIDTH (SCHAR_MIN, SCHAR_MAX)
# define UCHAR_WIDTH _GL_INTEGER_WIDTH (0, UCHAR_MAX)
# define SHRT_WIDTH _GL_INTEGER_WIDTH (SHRT_MIN, SHRT_MAX)
# define USHRT_WIDTH _GL_INTEGER_WIDTH (0, USHRT_MAX)
# define INT_WIDTH _GL_INTEGER_WIDTH (INT_MIN, INT_MAX)
# define UINT_WIDTH _GL_INTEGER_WIDTH (0, UINT_MAX)
# define LONG_WIDTH _GL_INTEGER_WIDTH (LONG_MIN, LONG_MAX)
# define ULONG_WIDTH _GL_INTEGER_WIDTH (0, ULONG_MAX)
# define LLONG_WIDTH _GL_INTEGER_WIDTH (LLONG_MIN, LLONG_MAX)
# define ULLONG_WIDTH _GL_INTEGER_WIDTH (0, ULLONG_MAX)
#endif /* !ULLONG_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */

#endif /* _@GUARD_PREFIX@_LIMITS_H */
#endif /* _@GUARD_PREFIX@_LIMITS_H */


code:
/* Determine a canonical name for the current locale's character encoding.

   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 General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, see <http://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>.  */

#include <config.h>

/* Specification.  */
#include "localcharset.h"

#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET
# define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */
#endif

#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
# define WINDOWS_NATIVE
# include <locale.h>
#endif

#if defined __EMX__
/* Assume EMX program runs on OS/2, even if compiled under DOS.  */
# ifndef OS2
#  define OS2
# endif
#endif

#if !defined WINDOWS_NATIVE
# include <unistd.h>
# if HAVE_LANGINFO_CODESET
#  include <langinfo.h>
# else
#  if 0 /* see comment below */
#   include <locale.h>
#  endif
# endif
# ifdef __CYGWIN__
#  define WIN32_LEAN_AND_MEAN
#  include <windows.h>
# endif
#elif defined WINDOWS_NATIVE
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
#if defined OS2
# define INCL_DOS
# include <os2.h>
#endif

/* For MB_CUR_MAX_L */
#if defined DARWIN7
# include <xlocale.h>
#endif

#if ENABLE_RELOCATABLE
# include "relocatable.h"
#else
# define relocate(pathname) (pathname)
#endif

/* Get LIBDIR.  */
#ifndef LIBDIR
# include "configmake.h"
#endif

/* Define O_NOFOLLOW to 0 on platforms where it does not exist.  */
#ifndef O_NOFOLLOW
# define O_NOFOLLOW 0
#endif

#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
  /* Native Windows, Cygwin, OS/2, DOS */
# define ISSLASH(C) ((C) == '/' || (C) == '\\')
#endif

#ifndef DIRECTORY_SEPARATOR
# define DIRECTORY_SEPARATOR '/'
#endif

#ifndef ISSLASH
# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
#endif

#if HAVE_DECL_GETC_UNLOCKED
# undef getc
# define getc getc_unlocked
#endif

/* The following static variable is declared 'volatile' to avoid a
   possible multithread problem in the function get_charset_aliases. If we
   are running in a threaded environment, and if two threads initialize
   'charset_aliases' simultaneously, both will produce the same value,
   and everything will be ok if the two assignments to 'charset_aliases'
   are atomic. But I don't know what will happen if the two assignments mix.  */
#if __STDC__ != 1
# define volatile /* empty */
#endif
/* Pointer to the contents of the charset.alias file, if it has already been
   read, else NULL.  Its format is:
   ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0'  */
static const char * volatile charset_aliases;

/* Return a pointer to the contents of the charset.alias file.  */
static const char *
get_charset_aliases (void)
{
  const char *cp;

  cp = charset_aliases;
  if (cp == NULL)
    {
#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__ || defined OS2)
      const char *dir;
      const char *base = "charset.alias";
      char *file_name;

      /* Make it possible to override the charset.alias location.  This is
         necessary for running the testsuite before "make install".  */
      dir = getenv ("CHARSETALIASDIR");
      if (dir == NULL || dir[0] == '\0')
        dir = relocate (LIBDIR);

      /* Concatenate dir and base into freshly allocated file_name.  */
      {
        size_t dir_len = strlen (dir);
        size_t base_len = strlen (base);
        int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
        file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
        if (file_name != NULL)
          {
            memcpy (file_name, dir, dir_len);
            if (add_slash)
              file_name[dir_len] = DIRECTORY_SEPARATOR;
            memcpy (file_name + dir_len + add_slash, base, base_len + 1);
          }
      }

      if (file_name == NULL)
        /* Out of memory.  Treat the file as empty.  */
        cp = "";
      else
        {
          int fd;

          /* Open the file.  Reject symbolic links on platforms that support
             O_NOFOLLOW.  This is a security feature.  Without it, an attacker
             could retrieve parts of the contents (namely, the tail of the
             first line that starts with "* ") of an arbitrary file by placing
             a symbolic link to that file under the name "charset.alias" in
             some writable directory and defining the environment variable
             CHARSETALIASDIR to point to that directory.  */
          fd = open (file_name,
                     O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0));
          if (fd < 0)
            /* File not found.  Treat it as empty.  */
            cp = "";
          else
            {
              FILE *fp;

              fp = fdopen (fd, "r");
              if (fp == NULL)
                {
                  /* Out of memory.  Treat the file as empty.  */
                  close (fd);
                  cp = "";
                }
              else
                {
                  /* Parse the file's contents.  */
                  char *res_ptr = NULL;
                  size_t res_size = 0;

                  for (;;)
                    {
                      int c;
                      char buf1[50+1];
                      char buf2[50+1];
                      size_t l1, l2;
                      char *old_res_ptr;

                      c = getc (fp);
                      if (c == EOF)
                        break;
                      if (c == '\n' || c == ' ' || c == '\t')
                        continue;
                      if (c == '#')
                        {
                          /* Skip comment, to end of line.  */
                          do
                            c = getc (fp);
                          while (!(c == EOF || c == '\n'));
                          if (c == EOF)
                            break;
                          continue;
                        }
                      ungetc (c, fp);
                      if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
                        break;
                      l1 = strlen (buf1);
                      l2 = strlen (buf2);
                      old_res_ptr = res_ptr;
                      if (res_size == 0)
                        {
                          res_size = l1 + 1 + l2 + 1;
                          res_ptr = (char *) malloc (res_size + 1);
                        }
                      else
                        {
                          res_size += l1 + 1 + l2 + 1;
                          res_ptr = (char *) realloc (res_ptr, res_size + 1);
                        }
                      if (res_ptr == NULL)
                        {
                          /* Out of memory. */
                          res_size = 0;
                          free (old_res_ptr);
                          break;
                        }
                      strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
                      strcpy (res_ptr + res_size - (l2 + 1), buf2);
                    }
                  fclose (fp);
                  if (res_size == 0)
                    cp = "";
                  else
                    {
                      *(res_ptr + res_size) = '\0';
                      cp = res_ptr;
                    }
                }
            }

          free (file_name);
        }

#else

# if defined DARWIN7
      /* To avoid the trouble of installing a file that is shared by many
         GNU packages -- many packaging systems have problems with this --,
         simply inline the aliases here.  */
      cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
           "ISO8859-2" "\0" "ISO-8859-2" "\0"
           "ISO8859-4" "\0" "ISO-8859-4" "\0"
           "ISO8859-5" "\0" "ISO-8859-5" "\0"
           "ISO8859-7" "\0" "ISO-8859-7" "\0"
           "ISO8859-9" "\0" "ISO-8859-9" "\0"
           "ISO8859-13" "\0" "ISO-8859-13" "\0"
           "ISO8859-15" "\0" "ISO-8859-15" "\0"
           "KOI8-R" "\0" "KOI8-R" "\0"
           "KOI8-U" "\0" "KOI8-U" "\0"
           "CP866" "\0" "CP866" "\0"
           "CP949" "\0" "CP949" "\0"
           "CP1131" "\0" "CP1131" "\0"
           "CP1251" "\0" "CP1251" "\0"
           "eucCN" "\0" "GB2312" "\0"
           "GB2312" "\0" "GB2312" "\0"
           "eucJP" "\0" "EUC-JP" "\0"
           "eucKR" "\0" "EUC-KR" "\0"
           "Big5" "\0" "BIG5" "\0"
           "Big5HKSCS" "\0" "BIG5-HKSCS" "\0"
           "GBK" "\0" "GBK" "\0"
           "GB18030" "\0" "GB18030" "\0"
           "SJIS" "\0" "SHIFT_JIS" "\0"
           "ARMSCII-8" "\0" "ARMSCII-8" "\0"
           "PT154" "\0" "PT154" "\0"
         /*"ISCII-DEV" "\0" "?" "\0"*/
           "*" "\0" "UTF-8" "\0";
# endif

# if defined VMS
      /* To avoid the troubles of an extra file charset.alias_vms in the
         sources of many GNU packages, simply inline the aliases here.  */
      /* The list of encodings is taken from the OpenVMS 7.3-1 documentation
         "Compaq C Run-Time Library Reference Manual for OpenVMS systems"
         section 10.7 "Handling Different Character Sets".  */
      cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
           "ISO8859-2" "\0" "ISO-8859-2" "\0"
           "ISO8859-5" "\0" "ISO-8859-5" "\0"
           "ISO8859-7" "\0" "ISO-8859-7" "\0"
           "ISO8859-8" "\0" "ISO-8859-8" "\0"
           "ISO8859-9" "\0" "ISO-8859-9" "\0"
           /* Japanese */
           "eucJP" "\0" "EUC-JP" "\0"
           "SJIS" "\0" "SHIFT_JIS" "\0"
           "DECKANJI" "\0" "DEC-KANJI" "\0"
           "SDECKANJI" "\0" "EUC-JP" "\0"
           /* Chinese */
           "eucTW" "\0" "EUC-TW" "\0"
           "DECHANYU" "\0" "DEC-HANYU" "\0"
           "DECHANZI" "\0" "GB2312" "\0"
           /* Korean */
           "DECKOREAN" "\0" "EUC-KR" "\0";
# endif

# if defined WINDOWS_NATIVE || defined __CYGWIN__
      /* To avoid the troubles of installing a separate file in the same
         directory as the DLL and of retrieving the DLL's directory at
         runtime, simply inline the aliases here.  */

      cp = "CP936" "\0" "GBK" "\0"
           "CP1361" "\0" "JOHAB" "\0"
           "CP20127" "\0" "ASCII" "\0"
           "CP20866" "\0" "KOI8-R" "\0"
           "CP20936" "\0" "GB2312" "\0"
           "CP21866" "\0" "KOI8-RU" "\0"
           "CP28591" "\0" "ISO-8859-1" "\0"
           "CP28592" "\0" "ISO-8859-2" "\0"
           "CP28593" "\0" "ISO-8859-3" "\0"
           "CP28594" "\0" "ISO-8859-4" "\0"
           "CP28595" "\0" "ISO-8859-5" "\0"
           "CP28596" "\0" "ISO-8859-6" "\0"
           "CP28597" "\0" "ISO-8859-7" "\0"
           "CP28598" "\0" "ISO-8859-8" "\0"
           "CP28599" "\0" "ISO-8859-9" "\0"
           "CP28605" "\0" "ISO-8859-15" "\0"
           "CP38598" "\0" "ISO-8859-8" "\0"
           "CP51932" "\0" "EUC-JP" "\0"
           "CP51936" "\0" "GB2312" "\0"
           "CP51949" "\0" "EUC-KR" "\0"
           "CP51950" "\0" "EUC-TW" "\0"
           "CP54936" "\0" "GB18030" "\0"
           "CP65001" "\0" "UTF-8" "\0";
# endif
# if defined OS2
      /* To avoid the troubles of installing a separate file in the same
         directory as the DLL and of retrieving the DLL's directory at
         runtime, simply inline the aliases here.  */

      /* The list of encodings is taken from "List of OS/2 Codepages"
         by Alex Taylor:
         <http://altsan.org/os2/toolkits/uls/index.html#codepages>.
         See also "IBM Globalization - Code page identifiers":
         <http://www-01.ibm.com/software/globalization/cp/cp_cpgid.html>.  */
      cp = "CP813" "\0" "ISO-8859-7" "\0"
           "CP878" "\0" "KOI8-R" "\0"
           "CP819" "\0" "ISO-8859-1" "\0"
           "CP912" "\0" "ISO-8859-2" "\0"
           "CP913" "\0" "ISO-8859-3" "\0"
           "CP914" "\0" "ISO-8859-4" "\0"
           "CP915" "\0" "ISO-8859-5" "\0"
           "CP916" "\0" "ISO-8859-8" "\0"
           "CP920" "\0" "ISO-8859-9" "\0"
           "CP921" "\0" "ISO-8859-13" "\0"
           "CP923" "\0" "ISO-8859-15" "\0"
           "CP954" "\0" "EUC-JP" "\0"
           "CP964" "\0" "EUC-TW" "\0"
           "CP970" "\0" "EUC-KR" "\0"
           "CP1089" "\0" "ISO-8859-6" "\0"
           "CP1208" "\0" "UTF-8" "\0"
           "CP1381" "\0" "GB2312" "\0"
           "CP1386" "\0" "GBK" "\0"
           "CP3372" "\0" "EUC-JP" "\0";
# endif
#endif

      charset_aliases = cp;
    }

  return cp;
}

/* Determine the current locale's character encoding, and canonicalize it
   into one of the canonical names listed in config.charset.
   The result must not be freed; it is statically allocated.
   If the canonical name cannot be determined, the result is a non-canonical
   name.  */

#ifdef STATIC
STATIC
#endif
const char *
locale_charset (void)
{
  const char *codeset;
  const char *aliases;

#if !(defined WINDOWS_NATIVE || defined OS2)

# if HAVE_LANGINFO_CODESET

  /* Most systems support nl_langinfo (CODESET) nowadays.  */
  codeset = nl_langinfo (CODESET);

#  ifdef __CYGWIN__
  /* Cygwin < 1.7 does not have locales.  nl_langinfo (CODESET) always
     returns "US-ASCII".  Return the suffix of the locale name from the
     environment variables (if present) or the codepage as a number.  */
  if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0)
    {
      const char *locale;
      static char buf[2 + 10 + 1];

      locale = getenv ("LC_ALL");
      if (locale == NULL || locale[0] == '\0')
        {
          locale = getenv ("LC_CTYPE");
          if (locale == NULL || locale[0] == '\0')
            locale = getenv ("LANG");
        }
      if (locale != NULL && locale[0] != '\0')
        {
          /* If the locale name contains an encoding after the dot, return
             it.  */
          const char *dot = strchr (locale, '.');

          if (dot != NULL)
            {
              const char *modifier;

              dot++;
              /* Look for the possible @... trailer and remove it, if any.  */
              modifier = strchr (dot, '@');
              if (modifier == NULL)
                return dot;
              if (modifier - dot < sizeof (buf))
                {
                  memcpy (buf, dot, modifier - dot);
                  buf [modifier - dot] = '\0';
                  return buf;
                }
            }
        }

      /* The Windows API has a function returning the locale's codepage as a
         number: GetACP().  This encoding is used by Cygwin, unless the user
         has set the environment variable CYGWIN=codepage:oem (which very few
         people do).
         Output directed to console windows needs to be converted (to
         GetOEMCP() if the console is using a raster font, or to
         GetConsoleOutputCP() if it is using a TrueType font).  Cygwin does
         this conversion transparently (see winsup/cygwin/fhandler_console.cc),
         converting to GetConsoleOutputCP().  This leads to correct results,
         except when SetConsoleOutputCP has been called and a raster font is
         in use.  */
      sprintf (buf, "CP%u", GetACP ());
      codeset = buf;
    }
#  endif

# else

  /* On old systems which lack it, use setlocale or getenv.  */
  const char *locale = NULL;

  /* But most old systems don't have a complete set of locales.  Some
     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
     use setlocale here; it would return "C" when it doesn't support the
     locale name the user has set.  */
#  if 0
  locale = setlocale (LC_CTYPE, NULL);
#  endif
  if (locale == NULL || locale[0] == '\0')
    {
      locale = getenv ("LC_ALL");
      if (locale == NULL || locale[0] == '\0')
        {
          locale = getenv ("LC_CTYPE");
          if (locale == NULL || locale[0] == '\0')
            locale = getenv ("LANG");
        }
    }

  /* On some old systems, one used to set locale = "iso8859_1". On others,
     you set it to "language_COUNTRY.charset". In any case, we resolve it
     through the charset.alias file.  */
  codeset = locale;

# endif

#elif defined WINDOWS_NATIVE

  static char buf[2 + 10 + 1];

  /* The Windows API has a function returning the locale's codepage as
     a number, but the value doesn't change according to what the
     'setlocale' call specified.  So we use it as a last resort, in
     case the string returned by 'setlocale' doesn't specify the
     codepage.  */
  char *current_locale = setlocale (LC_ALL, NULL);
  char *pdot;

  /* If they set different locales for different categories,
     'setlocale' will return a semi-colon separated list of locale
     values.  To make sure we use the correct one, we choose LC_CTYPE.  */
  if (strchr (current_locale, ';'))
    current_locale = setlocale (LC_CTYPE, NULL);

  pdot = strrchr (current_locale, '.');
  if (pdot && 2 + strlen (pdot + 1) + 1 <= sizeof (buf))
    sprintf (buf, "CP%s", pdot + 1);
  else
    {
      /* The Windows API has a function returning the locale's codepage as a
        number: GetACP().
        When the output goes to a console window, it needs to be provided in
        GetOEMCP() encoding if the console is using a raster font, or in
        GetConsoleOutputCP() encoding if it is using a TrueType font.
        But in GUI programs and for output sent to files and pipes, GetACP()
        encoding is the best bet.  */
      sprintf (buf, "CP%u", GetACP ());
    }
  codeset = buf;

#elif defined OS2

  const char *locale;
  static char buf[2 + 10 + 1];
  ULONG cp[3];
  ULONG cplen;

  codeset = NULL;

  /* Allow user to override the codeset, as set in the operating system,
     with standard language environment variables.  */
  locale = getenv ("LC_ALL");
  if (locale == NULL || locale[0] == '\0')
    {
      locale = getenv ("LC_CTYPE");
      if (locale == NULL || locale[0] == '\0')
        locale = getenv ("LANG");
    }
  if (locale != NULL && locale[0] != '\0')
    {
      /* If the locale name contains an encoding after the dot, return it.  */
      const char *dot = strchr (locale, '.');

      if (dot != NULL)
        {
          const char *modifier;

          dot++;
          /* Look for the possible @... trailer and remove it, if any.  */
          modifier = strchr (dot, '@');
          if (modifier == NULL)
            return dot;
          if (modifier - dot < sizeof (buf))
            {
              memcpy (buf, dot, modifier - dot);
              buf [modifier - dot] = '\0';
              return buf;
            }
        }

      /* For the POSIX locale, don't use the system's codepage.  */
      if (strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0)
        codeset = "";
    }

  if (codeset == NULL)
    {
      /* OS/2 has a function returning the locale's codepage as a number.  */
      if (DosQueryCp (sizeof (cp), cp, &cplen))
        codeset = "";
      else
        {
          sprintf (buf, "CP%u", cp[0]);
          codeset = buf;
        }
    }

#endif

  if (codeset == NULL)
    /* The canonical name cannot be determined.  */
    codeset = "";

  /* Resolve alias. */
  for (aliases = get_charset_aliases ();
       *aliases != '\0';
       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
    if (strcmp (codeset, aliases) == 0
        || (aliases[0] == '*' && aliases[1] == '\0'))
      {
        codeset = aliases + strlen (aliases) + 1;
        break;
      }

  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
     the empty string as denoting "the locale's character encoding",
     thus GNU libiconv would call this function a second time.  */
  if (codeset[0] == '\0')
    codeset = "ASCII";

#ifdef DARWIN7
  /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8"
     (the default codeset) does not work when MB_CUR_MAX is 1.  */
  if (strcmp (codeset, "UTF-8") == 0 && MB_CUR_MAX_L (uselocale (NULL)) <= 1)
    codeset = "ASCII";
#endif

  return codeset;
}


code:
/* Determine a canonical name for the current locale's character encoding.
   Copyright (C) 2000-2003, 2009-2017 Free Software Foundation, Inc.
   This file is part of the GNU CHARSET Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, see <http://www.gnu.org/licenses/>.  */

#ifndef _LOCALCHARSET_H
#define _LOCALCHARSET_H

#ifdef __cplusplus
extern "C" {
#endif

/* Determine the current locale's character encoding, and canonicalize it
   into one of the canonical names listed in config.charset.
   The result must not be freed; it is statically allocated.
   If the canonical name cannot be determined, the result is a non-canonical
   name.  */
extern const char * locale_charset (void);

#ifdef __cplusplus
}
#endif

#endif /* _LOCALCHARSET_H */