diff options
| author | Paul Eggert <eggert@cs.ucla.edu> | 2026-05-26 17:51:44 -0700 |
|---|---|---|
| committer | Paul Eggert <eggert@cs.ucla.edu> | 2026-05-26 21:57:20 -0700 |
| commit | 834ff524f98024cbf30771df3849a5d9241ab2e2 (patch) | |
| tree | 113a74f16809d82cce66d8a6bfbdfb09942cf094 /lib | |
| parent | 6fb6a4f76ddc5dcbb4f6c4693f59ee498a02baca (diff) | |
Update from Gnulib by running admin/merge-gnulib
In addition to the automatic changes, also do the following,
needed due to recent Gnulib changes.
* admin/merge-gnulib (AVOIDED_MODULES): Add btoc32,
c32_apply_type_test, c32_get_type_test, c32isalnum, c32rtomb,
c32tolower, c32toupper, localeinfo, mbrtoc32-regular.
Remove btowc, iswctype, mbrtowc, wcrtomb, wctype, wctype-h.
Also remove iswblank, iswdigit, iswxdigit, locale-h, raise,
stdarg-h, some of which perhaps could have been removed earlier.
* configure.ac (_REGEX_AVOID_UCHAR_H): New macro.
Diffstat (limited to 'lib')
50 files changed, 2467 insertions, 717 deletions
diff --git a/lib/acl-internal.h b/lib/acl-internal.h index 855005bb756..eafb4d027fb 100644 --- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -249,17 +249,19 @@ struct permission_context { # elif defined GETACL /* Solaris, Cygwin < 2.5 */ int count; - aclent_t *entries; + aclent_t *entries + _GL_ATTRIBUTE_COUNTED_BY (count); # ifdef ACE_GETACL int ace_count; - ace_t *ace_entries; + ace_t *ace_entries + _GL_ATTRIBUTE_COUNTED_BY (ace_count); # endif # elif HAVE_GETACL /* HP-UX */ - struct acl_entry entries[NACLENTRIES]; + struct acl_entry entries[NACLENTRIES] /* COUNTED_BY (count) */; int count; # if HAVE_ACLV_H - struct acl aclv_entries[NACLVENTRIES]; + struct acl aclv_entries[NACLVENTRIES] /* COUNTED_BY (aclv_count) */; int aclv_count; # endif @@ -268,7 +270,7 @@ struct permission_context { bool have_u; # elif HAVE_ACLSORT /* NonStop Kernel */ - struct acl entries[NACLENTRIES]; + struct acl entries[NACLENTRIES] /* COUNTED_BY (count) */; int count; # endif diff --git a/lib/acl.h b/lib/acl.h index 85453217c63..4ac25fe226d 100644 --- a/lib/acl.h +++ b/lib/acl.h @@ -48,7 +48,7 @@ struct aclinfo { /* If 'size' is nonnegative, a buffer holding the concatenation of extended attribute names, each terminated by NUL - (either u.__gl_acl_ch, or heap-allocated). */ + (either u._gl_acl_ch, or heap-allocated). */ char *buf; /* The number of useful bytes at the start of buf, counting trailing NULs. @@ -72,7 +72,7 @@ struct aclinfo trivial NFSv4 ACL (a size used by file-has-acl.c in 2023-2024 but no longer relevant now), and a different value might be better once experience is gained. For internal use only. */ - char __gl_acl_ch[152]; + char _gl_acl_ch[152]; } u; }; diff --git a/lib/attribute.h b/lib/attribute.h index c50befdfdd2..10de47516f3 100644 --- a/lib/attribute.h +++ b/lib/attribute.h @@ -81,8 +81,8 @@ /* This file uses _GL_ATTRIBUTE_ALLOC_SIZE, _GL_ATTRIBUTE_ALWAYS_INLINE, _GL_ATTRIBUTE_ARTIFICIAL, _GL_ATTRIBUTE_COLD, _GL_ATTRIBUTE_CONST, - _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_DEPRECATED, _GL_ATTRIBUTE_ERROR, - _GL_ATTRIBUTE_WARNING, _GL_ATTRIBUTE_EXTERNALLY_VISIBLE, + _GL_ATTRIBUTE_COUNTED_BY, _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_DEPRECATED, + _GL_ATTRIBUTE_ERROR, _GL_ATTRIBUTE_WARNING, _GL_ATTRIBUTE_EXTERNALLY_VISIBLE, _GL_ATTRIBUTE_FALLTHROUGH, _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_LEAF, _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_MAY_ALIAS, _GL_ATTRIBUTE_MAYBE_UNUSED, _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOINLINE, _GL_ATTRIBUTE_NONNULL, @@ -210,6 +210,19 @@ #define FALLTHROUGH _GL_ATTRIBUTE_FALLTHROUGH +/* =================== Attributes for runtime diagnostics =================== */ + +/* Attributes that provide information to the undefined-behaviour sanitizer + (UBSAN). */ + +/* COUNTED_BY (C) declares that the number of elements of the field is given + by C, which must be another field in the same struct. + The programmer is responsible for guaranteeing some invariants; see + <https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html> for details. */ +/* Applies to struct fields of type array or pointer (to data). */ +#define COUNTED_BY(c) _GL_ATTRIBUTE_COUNTED_BY (c) + + /* ================== Attributes for debugging information ================== */ /* Attributes regarding debugging information emitted by the compiler. */ diff --git a/lib/binary-io.c b/lib/binary-io.c index 45060f689c6..d465eb47075 100644 --- a/lib/binary-io.c +++ b/lib/binary-io.c @@ -32,7 +32,7 @@ set_binary_mode (int fd, int mode) with console input or console output. */ return O_TEXT; else - return __gl_setmode (fd, mode); + return _gl_set_fd_mode (fd, mode); } #endif diff --git a/lib/binary-io.h b/lib/binary-io.h index 37eb3c4bb18..bc001a71c0f 100644 --- a/lib/binary-io.h +++ b/lib/binary-io.h @@ -38,9 +38,9 @@ _GL_INLINE_HEADER_BEGIN #if O_BINARY # if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__ # include <io.h> /* declares setmode() */ -# define __gl_setmode setmode +# define _gl_set_fd_mode setmode # else -# define __gl_setmode _setmode +# define _gl_set_fd_mode _setmode # undef fileno # define fileno _fileno # endif @@ -49,7 +49,7 @@ _GL_INLINE_HEADER_BEGIN /* Use a function rather than a macro, to avoid gcc warnings "warning: statement with no effect". */ BINARY_IO_INLINE int -__gl_setmode (_GL_UNUSED int fd, _GL_UNUSED int mode) +_gl_set_fd_mode (_GL_UNUSED int fd, _GL_UNUSED int mode) { return O_BINARY; } @@ -72,7 +72,7 @@ extern int set_binary_mode (int fd, int mode); BINARY_IO_INLINE int set_binary_mode (int fd, int mode) { - return __gl_setmode (fd, mode); + return _gl_set_fd_mode (fd, mode); } #endif diff --git a/lib/boot-time-aux.h b/lib/boot-time-aux.h index adafb8c8182..e09d84b67a2 100644 --- a/lib/boot-time-aux.h +++ b/lib/boot-time-aux.h @@ -16,8 +16,6 @@ /* Written by Bruno Haible <bruno@clisp.org>. */ -#define SIZEOF(a) (sizeof(a)/sizeof(a[0])) - #if defined __linux__ || defined __ANDROID__ /* Store the uptime counter, as managed by the Linux kernel, in *P_UPTIME. @@ -102,7 +100,7 @@ get_linux_boot_time_fallback (struct timespec *p_boot_time) modified when a user logs in, i.e. long after boot. */ "/var/run/utmp" /* seen on Alpine Linux with OpenRC */ }; - for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++) + for (idx_t i = 0; i < countof (boot_touched_files); i++) { const char *filename = boot_touched_files[i]; struct stat statbuf; @@ -214,7 +212,7 @@ get_openbsd_boot_time (struct timespec *p_boot_time) "/var/db/host.random", "/var/run/utmp" }; - for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++) + for (idx_t i = 0; i < countof (boot_touched_files); i++) { const char *filename = boot_touched_files[i]; struct stat statbuf; @@ -325,7 +323,7 @@ get_windows_boot_time (struct timespec *p_boot_time) "C:\\pagefile.sys" #endif }; - for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++) + for (idx_t i = 0; i < countof (boot_touched_files); i++) { const char *filename = boot_touched_files[i]; struct stat statbuf; diff --git a/lib/boot-time.c b/lib/boot-time.c index e8d8811da26..ae305a18067 100644 --- a/lib/boot-time.c +++ b/lib/boot-time.c @@ -21,6 +21,7 @@ /* Specification. */ #include "boot-time.h" +#include <stdcountof.h> #include <stddef.h> #include <stdio.h> #include <string.h> @@ -94,7 +95,8 @@ get_boot_time_uncached (struct timespec *p_boot_time) Solaris' utmpname returns 1 upon success -- which is contrary to what the GNU libc version does. In addition, older GNU libc versions are actually void. */ - UTMP_NAME_FUNCTION ((char *) UTMP_FILE); + static char const utmp_file[] = UTMP_FILE; + UTMP_NAME_FUNCTION ((char *) utmp_file); SET_UTMP_ENT (); diff --git a/lib/boot-time.h b/lib/boot-time.h index 82969272ffe..79129924884 100644 --- a/lib/boot-time.h +++ b/lib/boot-time.h @@ -34,7 +34,7 @@ extern "C" { The difference can matter in GNU/Linux, where times in /proc/stat might be relative to boot time of the host, not the container. - This function is not multithread-safe, since on many platforms it + This function is not thread-safe, since on many platforms it invokes the functions setutxent, getutxent, endutxent. These functions may lock a file like /var/log/wtmp (so that we don't read garbage when a concurrent process writes to that file), diff --git a/lib/byteswap.in.h b/lib/byteswap.in.h index b2b26af8b03..02433d30da4 100644 --- a/lib/byteswap.in.h +++ b/lib/byteswap.in.h @@ -23,13 +23,14 @@ #error "Please include config.h first." #endif -/* Define this now, rather than after including stdint.h, in case - stdint.h recursively includes us. This is for Gnulib endian.h. */ +/* Define this now, rather than after including stdbit.h, in case stdbit.h + recursively includes us via stdint.h. This is for Gnulib endian.h. */ #ifndef _GL_BYTESWAP_INLINE # define _GL_BYTESWAP_INLINE _GL_INLINE #endif -#include <stdint.h> +#include <stdbit.h> /* for stdc_memreverse8u* */ +#include <stdint.h> /* for UINT_LEAST64_MAX */ _GL_INLINE_HEADER_BEGIN @@ -37,38 +38,12 @@ _GL_INLINE_HEADER_BEGIN extern "C" { #endif -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) -# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP16 true -#elif defined __has_builtin -# if __has_builtin (__builtin_bswap16) -# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP16 true -# endif -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) -# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP32 true -# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP64 true -#elif defined __has_builtin -# if __has_builtin (__builtin_bswap32) -# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP32 true -# endif -# if __has_builtin (__builtin_bswap64) -# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP64 true -# endif -#endif - /* Given an unsigned 16-bit argument X, return the value corresponding to X with reversed byte order. */ _GL_BYTESWAP_INLINE uint_least16_t bswap_16 (uint_least16_t x) { -#ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP16 - return __builtin_bswap16 (x); -#else - uint_fast16_t mask = 0xff; - return ( (x & mask << 8 * 1) >> 8 * 1 - | (x & mask << 8 * 0) << 8 * 1); -#endif + return stdc_memreverse8u16 (x); } /* Given an unsigned 32-bit argument X, return the value corresponding to @@ -76,15 +51,7 @@ bswap_16 (uint_least16_t x) _GL_BYTESWAP_INLINE uint_least32_t bswap_32 (uint_least32_t x) { -#ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP32 - return __builtin_bswap32 (x); -#else - uint_fast32_t mask = 0xff; - return ( (x & mask << 8 * 3) >> 8 * 3 - | (x & mask << 8 * 2) >> 8 * 1 - | (x & mask << 8 * 1) << 8 * 1 - | (x & mask << 8 * 0) << 8 * 3); -#endif + return stdc_memreverse8u32 (x); } #ifdef UINT_LEAST64_MAX @@ -93,19 +60,7 @@ bswap_32 (uint_least32_t x) _GL_BYTESWAP_INLINE uint_least64_t bswap_64 (uint_least64_t x) { -# ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP64 - return __builtin_bswap64 (x); -# else - uint_fast64_t mask = 0xff; - return ( (x & mask << 8 * 7) >> 8 * 7 - | (x & mask << 8 * 6) >> 8 * 5 - | (x & mask << 8 * 5) >> 8 * 3 - | (x & mask << 8 * 4) >> 8 * 1 - | (x & mask << 8 * 3) << 8 * 1 - | (x & mask << 8 * 2) << 8 * 3 - | (x & mask << 8 * 1) << 8 * 5 - | (x & mask << 8 * 0) << 8 * 7); -# endif + return stdc_memreverse8u64 (x); } #endif diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c index fa19e09986c..c5e8addc660 100644 --- a/lib/careadlinkat.c +++ b/lib/careadlinkat.c @@ -42,22 +42,17 @@ enum { STACK_BUF_SIZE = 1024 }; /* Act like careadlinkat (see below), with an additional argument STACK_BUF that can be used as temporary storage. - If GCC_LINT is defined, do not inline this function with GCC 10.1 - and later, to avoid creating a pointer to the stack that GCC + In GCC 10+, do not inline this function + to avoid creating a pointer to the stack that -Wreturn-local-addr incorrectly complains about. See: https://gcc.gnu.org/PR93644 Although the noinline attribute can hurt performance a bit, no better way - to pacify GCC is known; even an explicit #pragma does not pacify GCC. - When the GCC bug is fixed this workaround should be limited to the + to pacify GCC is known; even an explicit #pragma does not pacify GCC + 10 or 11, or GCC 12+ with -flto. + If the GCC bug is fixed this workaround should be limited to the broken GCC versions. */ #if _GL_GNUC_PREREQ (10, 1) -# if _GL_GNUC_PREREQ (12, 1) -# pragma GCC diagnostic ignored "-Wreturn-local-addr" -# elif defined GCC_LINT || defined lint __attribute__ ((__noinline__)) -# elif __OPTIMIZE__ && !__NO_INLINE__ -# define GCC_BOGUS_WRETURN_LOCAL_ADDR -# endif #endif static char * readlink_stk (int fd, char const *filename, @@ -172,10 +167,6 @@ careadlinkat (int fd, char const *filename, common case of a symlink of small size, we get away with a single small malloc instead of a big malloc followed by a shrinking realloc. */ - #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR - #warning "GCC might issue a bogus -Wreturn-local-addr warning here." - #warning "See <https://gcc.gnu.org/PR93644>." - #endif char stack_buf[STACK_BUF_SIZE]; return readlink_stk (fd, filename, buffer, buffer_size, alloc, preadlinkat, stack_buf); diff --git a/lib/cdefs.h b/lib/cdefs.h index 42024b20e11..2800057cb7d 100644 --- a/lib/cdefs.h +++ b/lib/cdefs.h @@ -669,7 +669,8 @@ # ifdef __GNUC__ # define __restrict_arr /* Not supported in old GCC. */ # else -# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +# if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L \ + && !defined _MSC_VER) # define __restrict_arr restrict # else /* Some other non-C99 compiler. */ diff --git a/lib/diffseq.h b/lib/diffseq.h index cf710a316f8..73fa47b42e1 100644 --- a/lib/diffseq.h +++ b/lib/diffseq.h @@ -82,10 +82,11 @@ #error "Please include config.h first." #endif -/* Maximum value of type OFFSET. */ +/* Maximum value of type OFFSET. The 1u pacifies -Wuseless-cast, and + unlike a compound literal can appear in an integer constant expression. */ #ifndef OFFSET_MAX # define OFFSET_MAX \ - ((((OFFSET) 1 << (sizeof (OFFSET) * CHAR_BIT - 2)) - 1) * 2 + 1) + ((((OFFSET) 1u << (sizeof (OFFSET) * CHAR_BIT - 2)) - 1) * 2 + 1) #endif /* Default to no early abort. */ diff --git a/lib/dynarray.h b/lib/dynarray.h index a5cdf630e55..256340462d6 100644 --- a/lib/dynarray.h +++ b/lib/dynarray.h @@ -249,11 +249,11 @@ static DYNARRAY_ELEMENT * /* The implementation is imported from glibc. */ /* Avoid possible conflicts with symbols exported by the GNU libc. */ -#define __libc_dynarray_at_failure gl_dynarray_at_failure -#define __libc_dynarray_emplace_enlarge gl_dynarray_emplace_enlarge -#define __libc_dynarray_finalize gl_dynarray_finalize -#define __libc_dynarray_resize_clear gl_dynarray_resize_clear -#define __libc_dynarray_resize gl_dynarray_resize +#define __libc_dynarray_at_failure _gl_dynarray_at_failure +#define __libc_dynarray_emplace_enlarge _gl_dynarray_emplace_enlarge +#define __libc_dynarray_finalize _gl_dynarray_finalize +#define __libc_dynarray_resize_clear _gl_dynarray_resize_clear +#define __libc_dynarray_resize _gl_dynarray_resize #if defined DYNARRAY_STRUCT || defined DYNARRAY_ELEMENT || defined DYNARRAY_PREFIX diff --git a/lib/endian.in.h b/lib/endian.in.h index 8e0c2f23840..6fa0678f939 100644 --- a/lib/endian.in.h +++ b/lib/endian.in.h @@ -109,7 +109,7 @@ _GL_INLINE_HEADER_BEGIN extern "C" { #endif -/* These declarations are needed if Gnulib byteswap.h -> stdint.h -> +/* These declarations are needed if Gnulib byteswap.h -> stdbit.h -> stdint.h -> sys/types.h -> endian.h -> Gnulib byteswap.h, the last of which is blocked by its include guard so the functions are not yet declared. */ #ifdef _GL_BYTESWAP_INLINE @@ -120,138 +120,174 @@ _GL_BYTESWAP_INLINE uint_least64_t bswap_64 (uint_least64_t); /* Big endian to host. */ +#if !GNULIB_defined_be16toh _GL_ENDIAN_INLINE uint16_t be16toh (uint16_t x) { -#if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return x; -#else +# else return bswap_16 (x); -#endif +# endif } +# define GNULIB_defined_be16toh 1 +#endif +#if !GNULIB_defined_be32toh _GL_ENDIAN_INLINE uint32_t be32toh (uint32_t x) { -#if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return x; -#else +# else return bswap_32 (x); -#endif +# endif } +# define GNULIB_defined_be32toh 1 +#endif #ifdef UINT64_MAX +# if !GNULIB_defined_be64toh _GL_ENDIAN_INLINE uint64_t be64toh (uint64_t x) { -# if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return x; -# else +# else return bswap_64 (x); -# endif +# endif } +# define GNULIB_defined_be64toh 1 +# endif #endif /* Host to big endian. */ +#if !GNULIB_defined_htobe16 _GL_ENDIAN_INLINE uint16_t htobe16 (uint16_t x) { -#if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return x; -#else +# else return bswap_16 (x); -#endif +# endif } +# define GNULIB_defined_htobe16 1 +#endif +#if !GNULIB_defined_htobe32 _GL_ENDIAN_INLINE uint32_t htobe32 (uint32_t x) { -#if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return x; -#else +# else return bswap_32 (x); -#endif +# endif } +# define GNULIB_defined_htobe32 1 +#endif #ifdef UINT64_MAX +# if !GNULIB_defined_htobe64 _GL_ENDIAN_INLINE uint64_t htobe64 (uint64_t x) { -# if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return x; -# else +# else return bswap_64 (x); -# endif +# endif } +# define GNULIB_defined_htobe64 1 +# endif #endif /* Little endian to host. */ +#if !GNULIB_defined_le16toh _GL_ENDIAN_INLINE uint16_t le16toh (uint16_t x) { -#if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return bswap_16 (x); -#else +# else return x; -#endif +# endif } +# define GNULIB_defined_le16toh 1 +#endif +#if !GNULIB_defined_le32toh _GL_ENDIAN_INLINE uint32_t le32toh (uint32_t x) { -#if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return bswap_32 (x); -#else +# else return x; -#endif +# endif } +# define GNULIB_defined_le32toh 1 +#endif #ifdef UINT64_MAX +# if !GNULIB_defined_le64toh _GL_ENDIAN_INLINE uint64_t le64toh (uint64_t x) { -# if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return bswap_64 (x); -# else +# else return x; -# endif +# endif } +# define GNULIB_defined_le64toh 1 +# endif #endif /* Host to little endian. */ +#if !GNULIB_defined_htole16 _GL_ENDIAN_INLINE uint16_t htole16 (uint16_t x) { -#if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return bswap_16 (x); -#else +# else return x; -#endif +# endif } +# define GNULIB_defined_htole16 1 +#endif +#if !GNULIB_defined_htole32 _GL_ENDIAN_INLINE uint32_t htole32 (uint32_t x) { -#if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return bswap_32 (x); -#else +# else return x; -#endif +# endif } +# define GNULIB_defined_htole32 1 +#endif #ifdef UINT64_MAX +# if !GNULIB_defined_htole64 _GL_ENDIAN_INLINE uint64_t htole64 (uint64_t x) { -# if BYTE_ORDER == BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN return bswap_64 (x); -# else +# else return x; -# endif +# endif } +# define GNULIB_defined_htole64 1 +# endif #endif #ifdef __cplusplus diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index 3269d7f71b7..8b9bb0468fe 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -160,8 +160,8 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr) static void get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags) { - ai->buf = ai->u.__gl_acl_ch; - ssize_t acl_alloc = sizeof ai->u.__gl_acl_ch; + ai->buf = ai->u._gl_acl_ch; + ssize_t acl_alloc = sizeof ai->u._gl_acl_ch; if (! (USE_ACL || flags & ACL_GET_SCONTEXT)) ai->size = 0; @@ -194,10 +194,10 @@ get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags) /* Grow allocation to at least 'size'. Grow it by a nontrivial amount, to defend against denial of service by an adversary that fiddles with ACLs. */ - if (ai->buf != ai->u.__gl_acl_ch) + if (ai->buf != ai->u._gl_acl_ch) { free (ai->buf); - ai->buf = ai->u.__gl_acl_ch; + ai->buf = ai->u._gl_acl_ch; } if (ckd_add (&acl_alloc, acl_alloc, acl_alloc >> 1)) acl_alloc = SSIZE_MAX; @@ -297,7 +297,7 @@ aclinfo_scontext_free (char *scontext) void aclinfo_free (struct aclinfo *ai) { - if (ai->buf != ai->u.__gl_acl_ch) + if (ai->buf != ai->u._gl_acl_ch) free (ai->buf); aclinfo_scontext_free (ai->scontext); } @@ -510,7 +510,7 @@ fdfile_has_aclinfo (MAYBE_UNUSED int fd, #else /* !USE_LINUX_XATTR */ - ai->buf = ai->u.__gl_acl_ch; + ai->buf = ai->u._gl_acl_ch; ai->size = -1; ai->u.err = ENOTSUP; ai->scontext = (char *) UNKNOWN_SECURITY_CONTEXT; diff --git a/lib/fsusage.c b/lib/fsusage.c index 1700a19c996..fbb38d7ab08 100644 --- a/lib/fsusage.c +++ b/lib/fsusage.c @@ -57,7 +57,7 @@ && (~ (x) == (sizeof (x) < sizeof (int) \ ? - (1 << (sizeof (x) * CHAR_BIT)) \ : 0))) \ - ? UINTMAX_MAX : (uintmax_t) (x)) + ? UINTMAX_MAX : (uintmax_t) {(x)}) /* Extract the top bit of X as an uintmax_t value. */ #define EXTRACT_TOP_BIT(x) ((x) \ diff --git a/lib/gettext.h b/lib/gettext.h index 0291cf09c5f..02b8b7b8de4 100644 --- a/lib/gettext.h +++ b/lib/gettext.h @@ -60,10 +60,40 @@ # endif /* Disabled NLS. */ +/* When gcc is used with option -Wformat=2, we need to silence + "warning: format not a string literal, argument types not checked [-Wformat-nonliteral]" + warnings that would occur at every invocation of a *gettext function + in a *printf format string position. + Do this with inline functions when possible, namely for gettext, dgettext, + dcgettext, which are known to gcc as "external built-ins". + It is not ideal to ignore the possible side effects done in the + Domainname and Category arguments, but it's better than to have a + warning at every invocation in a format string position. */ +/* When clang is used with option -Wformat=2, we need to silence + "warning: format string is not a string literal [-Wformat-nonliteral]" + warnings that would occur at every invocation of a *gettext function + in a *printf format string position. + It is not ideal to ignore the possible side effects done in the + Domainname and Category arguments, but it's better than to have a + warning at every invocation in a format string position. */ +/* These warnings would not occur with enabled NLS. */ +/* A test case: + ================================ foo.c ================================ + #include <stdio.h> + #include "gettext.h" + void foo (int n) + { + printf (gettext ("foo %d"), n); + printf (dgettext ("toto", "foo %d"), n); + printf (dcgettext ("toto", "foo %d", LC_MESSAGES), n); + printf (ngettext ("foo %d", "bar %d", n), n); + printf (dngettext ("toto", "foo %d", "bar %d", n), n); + printf (dcngettext ("toto", "foo %d", "bar %d", n, LC_MESSAGES), n); + } + ======================================================================= + $CC -Wformat=2 -S foo.c + */ # if defined __GNUC__ && !defined __clang__ && !defined __cplusplus -/* Use inline functions, to avoid warnings - warning: format not a string literal and no format arguments - that don't occur with enabled NLS. */ /* The return type 'const char *' serves the purpose of producing warnings for invalid uses of the value returned from these functions. */ # if __GNUC__ >= 9 @@ -118,36 +148,80 @@ dcgettext (const char *domain, const char *msgid, int category) # if __GNUC__ >= 9 # pragma GCC diagnostic pop # endif -# else -/* The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. */ +# elif defined __clang__ # undef gettext # define gettext(Msgid) ((const char *) (Msgid)) # undef dgettext -# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) +# define dgettext(Domainname, Msgid) gettext (Msgid) +# undef dcgettext +# define dcgettext(Domainname, Msgid, Category) dgettext (Domainname, Msgid) +# else +/* The conversions to 'const char *' via compound literals serve the purpose + of producing warnings for invalid uses of the value returned from these + functions and for invalid-typed Msgid arguments. */ +# undef gettext +# define gettext(Msgid) ((const char *) {(Msgid)}) +/* The conversions via compound literals serve the purpose of producing warnings + for invalid-typed arguments. */ +# undef dgettext +# define dgettext(Domainname, Msgid) \ + ((void) (const char *) {(Domainname)}, gettext (Msgid)) # undef dcgettext # define dcgettext(Domainname, Msgid, Category) \ - ((void) (Category), dgettext (Domainname, Msgid)) + ((void) (int) {(Category)}, dgettext (Domainname, Msgid)) +# endif + +# if (defined __GNUC__ && defined __cplusplus) || defined __clang__ +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# undef dngettext +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ngettext (Msgid1, Msgid2, N) +# undef dcngettext +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + dngettext (Domainname, Msgid1, Msgid2, N) +# elif defined __GNUC__ && !defined __cplusplus +/* Silence -Wuseless-cast warnings. */ +# if __GNUC__ >= 14 +# pragma GCC diagnostic ignored "-Wuseless-cast" +# endif +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# undef dngettext +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void) (const char *) (Domainname), ngettext (Msgid1, Msgid2, N)) +# undef dcngettext +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void) (int) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) +# else +/* The conversions to 'const char *' via compound literals serve the purpose + of producing warnings for invalid uses of the value returned from these + functions and for invalid-typed Msgid1 and Msgid2 arguments. */ +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 \ + ? ((void) (Msgid2), (const char *) {(Msgid1)}) \ + : ((void) (Msgid1), (const char *) {(Msgid2)})) +/* The conversions via compound literals serve the purpose of producing warnings + for invalid-typed arguments. */ +# undef dngettext +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void) (const char *) {(Domainname)}, ngettext (Msgid1, Msgid2, N)) +# undef dcngettext +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void) (int) {(Category)}, dngettext (Domainname, Msgid1, Msgid2, N)) # endif -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 \ - ? ((void) (Msgid2), (const char *) (Msgid1)) \ - : ((void) (Msgid1), (const char *) (Msgid2))) -# undef dngettext -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) -# undef dcngettext -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) + # undef textdomain -# define textdomain(Domainname) ((const char *) (Domainname)) +# define textdomain(Domainname) ((const char *) {(Domainname)}) # undef bindtextdomain # define bindtextdomain(Domainname, Dirname) \ - ((void) (Domainname), (const char *) (Dirname)) + ((void) (const char *) {(Domainname)}, (const char *) {(Dirname)}) # undef bind_textdomain_codeset # define bind_textdomain_codeset(Domainname, Codeset) \ - ((void) (Domainname), (const char *) (Codeset)) + ((void) (const char *) {(Domainname)}, (const char *) {(Codeset)}) #endif @@ -178,6 +252,11 @@ dcgettext (const char *domain, const char *msgid, int category) The letter 'p' stands for 'particular' or 'special'. */ #include <locale.h> /* for LC_MESSAGES */ +/* The LC_MESSAGES locale category is specified in POSIX, but not in ISO C. + On systems that don't define it, use the same value as GNU libintl. */ +#if !defined LC_MESSAGES +# define LC_MESSAGES 1729 +#endif #ifdef DEFAULT_TEXT_DOMAIN # define pgettext(Msgctxt, Msgid) \ @@ -204,11 +283,9 @@ dcgettext (const char *domain, const char *msgid, int category) #if defined __GNUC__ || defined __clang__ __inline -#else -#ifdef __cplusplus +#elif defined __cplusplus inline #endif -#endif static const char * pgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, @@ -223,11 +300,9 @@ pgettext_aux (const char *domain, #if defined __GNUC__ || defined __clang__ __inline -#else -#ifdef __cplusplus +#elif defined __cplusplus inline #endif -#endif static const char * npgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, @@ -274,11 +349,9 @@ npgettext_aux (const char *domain, #if defined __GNUC__ || defined __clang__ __inline -#else -#ifdef __cplusplus +#elif defined __cplusplus inline #endif -#endif static const char * dcpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, @@ -320,11 +393,9 @@ dcpgettext_expr (const char *domain, #if defined __GNUC__ || defined __clang__ __inline -#else -#ifdef __cplusplus +#elif defined __cplusplus inline #endif -#endif static const char * dcnpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 824931caf90..2a18a330fa1 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -35,7 +35,13 @@ # --macro-prefix=gl \ # --no-vc-files \ # --avoid=access \ -# --avoid=btowc \ +# --avoid=btoc32 \ +# --avoid=c32_apply_type_test \ +# --avoid=c32_get_type_test \ +# --avoid=c32isalnum \ +# --avoid=c32rtomb \ +# --avoid=c32tolower \ +# --avoid=c32toupper \ # --avoid=chmod \ # --avoid=close \ # --avoid=crypto/af_alg \ @@ -43,17 +49,13 @@ # --avoid=fchdir \ # --avoid=fstat \ # --avoid=gnulib-i18n \ -# --avoid=iswblank \ -# --avoid=iswctype \ -# --avoid=iswdigit \ -# --avoid=iswxdigit \ # --avoid=langinfo-h \ # --avoid=libgmp-mpq \ # --avoid=localcharset \ -# --avoid=locale-h \ +# --avoid=localeinfo \ # --avoid=localename-unsafe-limited \ # --avoid=lock \ -# --avoid=mbrtowc \ +# --avoid=mbrtoc32-regular \ # --avoid=mbsinit \ # --avoid=memchr \ # --avoid=mkdir \ @@ -63,14 +65,12 @@ # --avoid=openat-die \ # --avoid=opendir \ # --avoid=pthread-h \ -# --avoid=raise \ # --avoid=save-cwd \ # --avoid=select \ # --avoid=setenv \ # --avoid=sigprocmask \ # --avoid=stat \ # --avoid=std-gnu11 \ -# --avoid=stdarg-h \ # --avoid=strncpy \ # --avoid=threadlib \ # --avoid=tzset \ @@ -78,9 +78,7 @@ # --avoid=utime \ # --avoid=utime-h \ # --avoid=wchar-h \ -# --avoid=wcrtomb \ -# --avoid=wctype \ -# --avoid=wctype-h \ +# --avoid=uchar-h \ # alignasof \ # alloca-opt \ # attribute \ @@ -254,6 +252,7 @@ CPPFLAGS = @CPPFLAGS@ CRYPTOLIB = @CRYPTOLIB@ CXX = @CXX@ CXXFLAGS = @CXXFLAGS@ +CXX_HAVE_STDCOUNTOF_H = @CXX_HAVE_STDCOUNTOF_H@ CYGWIN_OBJ = @CYGWIN_OBJ@ C_SWITCH_MACHINE = @C_SWITCH_MACHINE@ C_SWITCH_SYSTEM = @C_SWITCH_SYSTEM@ @@ -372,6 +371,7 @@ GL_GENERATE_LIMITS_H_CONDITION = @GL_GENERATE_LIMITS_H_CONDITION@ GL_GENERATE_MINI_GMP_H_CONDITION = @GL_GENERATE_MINI_GMP_H_CONDITION@ GL_GENERATE_STDBIT_H_CONDITION = @GL_GENERATE_STDBIT_H_CONDITION@ GL_GENERATE_STDCKDINT_H_CONDITION = @GL_GENERATE_STDCKDINT_H_CONDITION@ +GL_GENERATE_STDCOUNTOF_H_CONDITION = @GL_GENERATE_STDCOUNTOF_H_CONDITION@ GL_GENERATE_STDDEF_H_CONDITION = @GL_GENERATE_STDDEF_H_CONDITION@ GL_GENERATE_STDINT_H_CONDITION = @GL_GENERATE_STDINT_H_CONDITION@ GL_GNULIB_ABORT_DEBUG = @GL_GNULIB_ABORT_DEBUG@ @@ -621,6 +621,28 @@ GL_GNULIB_SNZPRINTF = @GL_GNULIB_SNZPRINTF@ GL_GNULIB_SPRINTF_POSIX = @GL_GNULIB_SPRINTF_POSIX@ GL_GNULIB_STACK_TRACE = @GL_GNULIB_STACK_TRACE@ GL_GNULIB_STAT = @GL_GNULIB_STAT@ +GL_GNULIB_STDC_BIT_CEIL = @GL_GNULIB_STDC_BIT_CEIL@ +GL_GNULIB_STDC_BIT_FLOOR = @GL_GNULIB_STDC_BIT_FLOOR@ +GL_GNULIB_STDC_BIT_WIDTH = @GL_GNULIB_STDC_BIT_WIDTH@ +GL_GNULIB_STDC_COUNT_ONES = @GL_GNULIB_STDC_COUNT_ONES@ +GL_GNULIB_STDC_COUNT_ZEROS = @GL_GNULIB_STDC_COUNT_ZEROS@ +GL_GNULIB_STDC_FIRST_LEADING_ONE = @GL_GNULIB_STDC_FIRST_LEADING_ONE@ +GL_GNULIB_STDC_FIRST_LEADING_ZERO = @GL_GNULIB_STDC_FIRST_LEADING_ZERO@ +GL_GNULIB_STDC_FIRST_TRAILING_ONE = @GL_GNULIB_STDC_FIRST_TRAILING_ONE@ +GL_GNULIB_STDC_FIRST_TRAILING_ZERO = @GL_GNULIB_STDC_FIRST_TRAILING_ZERO@ +GL_GNULIB_STDC_HAS_SINGLE_BIT = @GL_GNULIB_STDC_HAS_SINGLE_BIT@ +GL_GNULIB_STDC_LEADING_ONES = @GL_GNULIB_STDC_LEADING_ONES@ +GL_GNULIB_STDC_LEADING_ZEROS = @GL_GNULIB_STDC_LEADING_ZEROS@ +GL_GNULIB_STDC_LOAD8 = @GL_GNULIB_STDC_LOAD8@ +GL_GNULIB_STDC_LOAD8_ALIGNED = @GL_GNULIB_STDC_LOAD8_ALIGNED@ +GL_GNULIB_STDC_MEMREVERSE8 = @GL_GNULIB_STDC_MEMREVERSE8@ +GL_GNULIB_STDC_MEMREVERSE8U = @GL_GNULIB_STDC_MEMREVERSE8U@ +GL_GNULIB_STDC_ROTATE_LEFT = @GL_GNULIB_STDC_ROTATE_LEFT@ +GL_GNULIB_STDC_ROTATE_RIGHT = @GL_GNULIB_STDC_ROTATE_RIGHT@ +GL_GNULIB_STDC_STORE8 = @GL_GNULIB_STDC_STORE8@ +GL_GNULIB_STDC_STORE8_ALIGNED = @GL_GNULIB_STDC_STORE8_ALIGNED@ +GL_GNULIB_STDC_TRAILING_ONES = @GL_GNULIB_STDC_TRAILING_ONES@ +GL_GNULIB_STDC_TRAILING_ZEROS = @GL_GNULIB_STDC_TRAILING_ZEROS@ GL_GNULIB_STDIO_H_NONBLOCKING = @GL_GNULIB_STDIO_H_NONBLOCKING@ GL_GNULIB_STDIO_H_SIGPIPE = @GL_GNULIB_STDIO_H_SIGPIPE@ GL_GNULIB_STPCPY = @GL_GNULIB_STPCPY@ @@ -681,6 +703,7 @@ GL_GNULIB_UNLOCKPT = @GL_GNULIB_UNLOCKPT@ GL_GNULIB_UNSETENV = @GL_GNULIB_UNSETENV@ GL_GNULIB_USLEEP = @GL_GNULIB_USLEEP@ GL_GNULIB_UTIMENSAT = @GL_GNULIB_UTIMENSAT@ +GL_GNULIB_VAPRINTF = @GL_GNULIB_VAPRINTF@ GL_GNULIB_VASPRINTF = @GL_GNULIB_VASPRINTF@ GL_GNULIB_VASZPRINTF = @GL_GNULIB_VASZPRINTF@ GL_GNULIB_VDPRINTF = @GL_GNULIB_VDPRINTF@ @@ -701,20 +724,7 @@ GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@ GL_GNULIB_WRITE = @GL_GNULIB_WRITE@ GL_GNULIB_ZPRINTF = @GL_GNULIB_ZPRINTF@ GL_GNULIB__EXIT = @GL_GNULIB__EXIT@ -GL_STDC_BIT_CEIL = @GL_STDC_BIT_CEIL@ -GL_STDC_BIT_FLOOR = @GL_STDC_BIT_FLOOR@ -GL_STDC_BIT_WIDTH = @GL_STDC_BIT_WIDTH@ -GL_STDC_COUNT_ONES = @GL_STDC_COUNT_ONES@ -GL_STDC_COUNT_ZEROS = @GL_STDC_COUNT_ZEROS@ -GL_STDC_FIRST_LEADING_ONE = @GL_STDC_FIRST_LEADING_ONE@ -GL_STDC_FIRST_LEADING_ZERO = @GL_STDC_FIRST_LEADING_ZERO@ -GL_STDC_FIRST_TRAILING_ONE = @GL_STDC_FIRST_TRAILING_ONE@ -GL_STDC_FIRST_TRAILING_ZERO = @GL_STDC_FIRST_TRAILING_ZERO@ -GL_STDC_HAS_SINGLE_BIT = @GL_STDC_HAS_SINGLE_BIT@ -GL_STDC_LEADING_ONES = @GL_STDC_LEADING_ONES@ -GL_STDC_LEADING_ZEROS = @GL_STDC_LEADING_ZEROS@ -GL_STDC_TRAILING_ONES = @GL_STDC_TRAILING_ONES@ -GL_STDC_TRAILING_ZEROS = @GL_STDC_TRAILING_ZEROS@ +GL_HAVE_STDBIT_H_CONDITION = @GL_HAVE_STDBIT_H_CONDITION@ GMALLOC_OBJ = @GMALLOC_OBJ@ GMP_H = @GMP_H@ GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@ @@ -924,7 +934,9 @@ HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ HAVE_SIGSET_T = @HAVE_SIGSET_T@ HAVE_SLEEP = @HAVE_SLEEP@ HAVE_SPAWN_H = @HAVE_SPAWN_H@ +HAVE_STDBIT_H = @HAVE_STDBIT_H@ HAVE_STDCKDINT_H = @HAVE_STDCKDINT_H@ +HAVE_STDCOUNTOF_H = @HAVE_STDCOUNTOF_H@ HAVE_STDINT_H = @HAVE_STDINT_H@ HAVE_STPCPY = @HAVE_STPCPY@ HAVE_STPNCPY = @HAVE_STPNCPY@ @@ -1104,7 +1116,9 @@ NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@ NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ NEXT_AS_FIRST_DIRECTIVE_LIMITS_H = @NEXT_AS_FIRST_DIRECTIVE_LIMITS_H@ NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@ +NEXT_AS_FIRST_DIRECTIVE_STDBIT_H = @NEXT_AS_FIRST_DIRECTIVE_STDBIT_H@ NEXT_AS_FIRST_DIRECTIVE_STDCKDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDCKDINT_H@ +NEXT_AS_FIRST_DIRECTIVE_STDCOUNTOF_H = @NEXT_AS_FIRST_DIRECTIVE_STDCOUNTOF_H@ NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@ NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@ NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@ @@ -1125,7 +1139,9 @@ NEXT_GETOPT_H = @NEXT_GETOPT_H@ NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ NEXT_LIMITS_H = @NEXT_LIMITS_H@ NEXT_SIGNAL_H = @NEXT_SIGNAL_H@ +NEXT_STDBIT_H = @NEXT_STDBIT_H@ NEXT_STDCKDINT_H = @NEXT_STDCKDINT_H@ +NEXT_STDCOUNTOF_H = @NEXT_STDCOUNTOF_H@ NEXT_STDDEF_H = @NEXT_STDDEF_H@ NEXT_STDINT_H = @NEXT_STDINT_H@ NEXT_STDIO_H = @NEXT_STDIO_H@ @@ -1391,6 +1407,7 @@ SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ SQLITE3_LIBS = @SQLITE3_LIBS@ STDBIT_H = @STDBIT_H@ STDCKDINT_H = @STDCKDINT_H@ +STDCOUNTOF_H = @STDCOUNTOF_H@ STDDEF_H = @STDDEF_H@ STDDEF_NOT_IDEMPOTENT = @STDDEF_NOT_IDEMPOTENT@ STDINT_H = @STDINT_H@ @@ -1516,6 +1533,7 @@ gl_GNULIB_ENABLED_issymlinkat_CONDITION = @gl_GNULIB_ENABLED_issymlinkat_CONDITI gl_GNULIB_ENABLED_lchmod_CONDITION = @gl_GNULIB_ENABLED_lchmod_CONDITION@ gl_GNULIB_ENABLED_open_CONDITION = @gl_GNULIB_ENABLED_open_CONDITION@ gl_GNULIB_ENABLED_rawmemchr_CONDITION = @gl_GNULIB_ENABLED_rawmemchr_CONDITION@ +gl_GNULIB_ENABLED_stdc_memreverse8u_CONDITION = @gl_GNULIB_ENABLED_stdc_memreverse8u_CONDITION@ gl_GNULIB_ENABLED_strtoll_CONDITION = @gl_GNULIB_ENABLED_strtoll_CONDITION@ gl_GNULIB_ENABLED_utimens_CONDITION = @gl_GNULIB_ENABLED_utimens_CONDITION@ gl_GNULIB_ENABLED_verify_CONDITION = @gl_GNULIB_ENABLED_verify_CONDITION@ @@ -3199,23 +3217,36 @@ BUILT_SOURCES += $(STDBIT_H) ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) stdbit.h: stdbit.in.h $(top_builddir)/config.status $(gl_V_at)$(SED_HEADER_STDOUT) \ - -e 's/@''GL_STDC_LEADING_ZEROS''@/$(GL_STDC_LEADING_ZEROS)/g' \ - -e 's/@''GL_STDC_LEADING_ONES''@/$(GL_STDC_LEADING_ONES)/g' \ - -e 's/@''GL_STDC_TRAILING_ZEROS''@/$(GL_STDC_TRAILING_ZEROS)/g' \ - -e 's/@''GL_STDC_TRAILING_ONES''@/$(GL_STDC_TRAILING_ONES)/g' \ - -e 's/@''GL_STDC_FIRST_LEADING_ZERO''@/$(GL_STDC_FIRST_LEADING_ZERO)/g' \ - -e 's/@''GL_STDC_FIRST_LEADING_ONE''@/$(GL_STDC_FIRST_LEADING_ONE)/g' \ - -e 's/@''GL_STDC_FIRST_TRAILING_ZERO''@/$(GL_STDC_FIRST_TRAILING_ZERO)/g' \ - -e 's/@''GL_STDC_FIRST_TRAILING_ONE''@/$(GL_STDC_FIRST_TRAILING_ONE)/g' \ - -e 's/@''GL_STDC_COUNT_ZEROS''@/$(GL_STDC_COUNT_ZEROS)/g' \ - -e 's/@''GL_STDC_COUNT_ONES''@/$(GL_STDC_COUNT_ONES)/g' \ - -e 's/@''GL_STDC_HAS_SINGLE_BIT''@/$(GL_STDC_HAS_SINGLE_BIT)/g' \ - -e 's/@''GL_STDC_BIT_WIDTH''@/$(GL_STDC_BIT_WIDTH)/g' \ - -e 's/@''GL_STDC_BIT_FLOOR''@/$(GL_STDC_BIT_FLOOR)/g' \ - -e 's/@''GL_STDC_BIT_CEIL''@/$(GL_STDC_BIT_CEIL)/g' \ + -e 's/@''HAVE_STDBIT_H''@/$(HAVE_STDBIT_H)/g' \ + -e 's/@''GUARD_PREFIX''@/$(GUARD_PREFIX)/g' \ + -e 's/@''PRAGMA_SYSTEM_HEADER''@/$(PRAGMA_SYSTEM_HEADER)/g' \ + -e 's/@''PRAGMA_COLUMNS''@/$(PRAGMA_COLUMNS)/g' \ + -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ + -e 's/@''NEXT_STDBIT_H''@/$(NEXT_STDBIT_H)/g' \ + -e 's/@''GNULIB_STDC_LEADING_ZEROS''@/$(GL_GNULIB_STDC_LEADING_ZEROS)/g' \ + -e 's/@''GNULIB_STDC_LEADING_ONES''@/$(GL_GNULIB_STDC_LEADING_ONES)/g' \ + -e 's/@''GNULIB_STDC_TRAILING_ZEROS''@/$(GL_GNULIB_STDC_TRAILING_ZEROS)/g' \ + -e 's/@''GNULIB_STDC_TRAILING_ONES''@/$(GL_GNULIB_STDC_TRAILING_ONES)/g' \ + -e 's/@''GNULIB_STDC_FIRST_LEADING_ZERO''@/$(GL_GNULIB_STDC_FIRST_LEADING_ZERO)/g' \ + -e 's/@''GNULIB_STDC_FIRST_LEADING_ONE''@/$(GL_GNULIB_STDC_FIRST_LEADING_ONE)/g' \ + -e 's/@''GNULIB_STDC_FIRST_TRAILING_ZERO''@/$(GL_GNULIB_STDC_FIRST_TRAILING_ZERO)/g' \ + -e 's/@''GNULIB_STDC_FIRST_TRAILING_ONE''@/$(GL_GNULIB_STDC_FIRST_TRAILING_ONE)/g' \ + -e 's/@''GNULIB_STDC_COUNT_ZEROS''@/$(GL_GNULIB_STDC_COUNT_ZEROS)/g' \ + -e 's/@''GNULIB_STDC_COUNT_ONES''@/$(GL_GNULIB_STDC_COUNT_ONES)/g' \ + -e 's/@''GNULIB_STDC_HAS_SINGLE_BIT''@/$(GL_GNULIB_STDC_HAS_SINGLE_BIT)/g' \ + -e 's/@''GNULIB_STDC_BIT_WIDTH''@/$(GL_GNULIB_STDC_BIT_WIDTH)/g' \ + -e 's/@''GNULIB_STDC_BIT_FLOOR''@/$(GL_GNULIB_STDC_BIT_FLOOR)/g' \ + -e 's/@''GNULIB_STDC_BIT_CEIL''@/$(GL_GNULIB_STDC_BIT_CEIL)/g' \ + -e 's/@''GNULIB_STDC_ROTATE_LEFT''@/$(GL_GNULIB_STDC_ROTATE_LEFT)/g' \ + -e 's/@''GNULIB_STDC_ROTATE_RIGHT''@/$(GL_GNULIB_STDC_ROTATE_RIGHT)/g' \ + -e 's/@''GNULIB_STDC_MEMREVERSE8''@/$(GL_GNULIB_STDC_MEMREVERSE8)/g' \ + -e 's/@''GNULIB_STDC_MEMREVERSE8U''@/$(GL_GNULIB_STDC_MEMREVERSE8U)/g' \ + -e 's/@''GNULIB_STDC_LOAD8_ALIGNED''@/$(GL_GNULIB_STDC_LOAD8_ALIGNED)/g' \ + -e 's/@''GNULIB_STDC_LOAD8''@/$(GL_GNULIB_STDC_LOAD8)/g' \ + -e 's/@''GNULIB_STDC_STORE8_ALIGNED''@/$(GL_GNULIB_STDC_STORE8_ALIGNED)/g' \ + -e 's/@''GNULIB_STDC_STORE8''@/$(GL_GNULIB_STDC_STORE8)/g' \ $(srcdir)/stdbit.in.h > $@-t $(AM_V_at)mv $@-t $@ -libgnu_a_SOURCES += stdbit.c else stdbit.h: $(top_builddir)/config.status rm -f $@ @@ -3230,7 +3261,8 @@ endif ## begin gnulib module stdc_bit_width ifeq (,$(OMIT_GNULIB_MODULE_stdc_bit_width)) -ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) +ifneq (,$(GL_HAVE_STDBIT_H_CONDITION)) +else libgnu_a_SOURCES += stdc_bit_width.c endif @@ -3240,7 +3272,8 @@ endif ## begin gnulib module stdc_count_ones ifeq (,$(OMIT_GNULIB_MODULE_stdc_count_ones)) -ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) +ifneq (,$(GL_HAVE_STDBIT_H_CONDITION)) +else libgnu_a_SOURCES += stdc_count_ones.c endif @@ -3250,17 +3283,31 @@ endif ## begin gnulib module stdc_leading_zeros ifeq (,$(OMIT_GNULIB_MODULE_stdc_leading_zeros)) -ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) +ifneq (,$(GL_HAVE_STDBIT_H_CONDITION)) +else libgnu_a_SOURCES += stdc_leading_zeros.c endif endif ## end gnulib module stdc_leading_zeros +## begin gnulib module stdc_memreverse8u +ifeq (,$(OMIT_GNULIB_MODULE_stdc_memreverse8u)) + +ifneq (,$(gl_GNULIB_ENABLED_stdc_memreverse8u_CONDITION)) +ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) +libgnu_a_SOURCES += stdc_memreverse8u.c +endif + +endif +endif +## end gnulib module stdc_memreverse8u + ## begin gnulib module stdc_trailing_zeros ifeq (,$(OMIT_GNULIB_MODULE_stdc_trailing_zeros)) -ifneq (,$(GL_GENERATE_STDBIT_H_CONDITION)) +ifneq (,$(GL_HAVE_STDBIT_H_CONDITION)) +else libgnu_a_SOURCES += stdc_trailing_zeros.c endif @@ -3299,6 +3346,36 @@ EXTRA_DIST += intprops-internal.h stdckdint.in.h endif ## end gnulib module stdckdint-h +## begin gnulib module stdcountof-h +ifeq (,$(OMIT_GNULIB_MODULE_stdcountof-h)) + +BUILT_SOURCES += $(STDCOUNTOF_H) + +# We need the following in order to create <stdcountof.h> when the system +# doesn't have one that works with the given compiler. +ifneq (,$(GL_GENERATE_STDCOUNTOF_H_CONDITION)) +stdcountof.h: stdcountof.in.h $(top_builddir)/config.status + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's/@''HAVE_STDCOUNTOF_H''@/$(HAVE_STDCOUNTOF_H)/g' \ + -e 's/@''CXX_HAVE_STDCOUNTOF_H''@/$(CXX_HAVE_STDCOUNTOF_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDCOUNTOF_H''@|$(NEXT_STDCOUNTOF_H)|g' \ + $(srcdir)/stdcountof.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +stdcountof.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdcountof.h stdcountof.h-t + +EXTRA_DIST += stdcountof.in.h + +endif +## end gnulib module stdcountof-h + ## begin gnulib module stddef-h ifeq (,$(OMIT_GNULIB_MODULE_stddef-h)) @@ -3445,6 +3522,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GL_GNULIB_STDIO_H_SIGPIPE)/g' \ -e 's/@''GNULIB_SZPRINTF''@/$(GL_GNULIB_SZPRINTF)/g' \ -e 's/@''GNULIB_TMPFILE''@/$(GL_GNULIB_TMPFILE)/g' \ + -e 's/@''GNULIB_VAPRINTF''@/$(GL_GNULIB_VAPRINTF)/g' \ -e 's/@''GNULIB_VASPRINTF''@/$(GL_GNULIB_VASPRINTF)/g' \ -e 's/@''GNULIB_VASZPRINTF''@/$(GL_GNULIB_VASZPRINTF)/g' \ -e 's/@''GNULIB_VDPRINTF''@/$(GL_GNULIB_VDPRINTF)/g' \ @@ -3468,6 +3546,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_MDA_GETW''@/$(GL_GNULIB_MDA_GETW)/g' \ -e 's/@''GNULIB_MDA_PUTW''@/$(GL_GNULIB_MDA_PUTW)/g' \ -e 's/@''GNULIB_MDA_TEMPNAM''@/$(GL_GNULIB_MDA_TEMPNAM)/g' \ + -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \ < $(srcdir)/stdio.in.h > $@-t1 $(AM_V_at)sed \ -e 's|@''HAVE_DECL_FCLOSEALL''@|$(HAVE_DECL_FCLOSEALL)|g' \ @@ -3499,6 +3578,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''REPLACE_FOPEN_FOR_FOPEN_GNU''@|$(REPLACE_FOPEN_FOR_FOPEN_GNU)|g' \ -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ -e 's|@''REPLACE_FPURGE''@|$(REPLACE_FPURGE)|g' \ + -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \ -e 's|@''REPLACE_FREOPEN''@|$(REPLACE_FREOPEN)|g' \ -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ diff --git a/lib/idx.h b/lib/idx.h index deb7dc4cb13..b6d304dbbd8 100644 --- a/lib/idx.h +++ b/lib/idx.h @@ -19,11 +19,17 @@ #ifndef _IDX_H #define _IDX_H -/* Get ptrdiff_t. */ -#include <stddef.h> +#ifndef __PTRDIFF_TYPE__ +# include <stddef.h> +#endif -/* Get PTRDIFF_MAX. */ -#include <stdint.h> +/* IDX_MAX is the maximum value of an idx_t. */ +#ifdef __PTRDIFF_MAX__ +# define IDX_MAX __PTRDIFF_MAX__ +#else +# include <stdint.h> +# define IDX_MAX PTRDIFF_MAX +#endif /* The type 'idx_t' holds an (array) index or an (object) size. Its implementation promotes to a signed integer type, @@ -127,10 +133,12 @@ extern "C" { /* Use the signed type 'ptrdiff_t'. */ /* Note: ISO C does not mandate that 'size_t' and 'ptrdiff_t' have the same size, but it is so on all platforms we have seen since 1990. */ +#ifdef __PTRDIFF_TYPE__ +typedef __PTRDIFF_TYPE__ idx_t; +#else +/* <stddef.h> already included above. */ typedef ptrdiff_t idx_t; - -/* IDX_MAX is the maximum value of an idx_t. */ -#define IDX_MAX PTRDIFF_MAX +#endif /* So far no need has been found for an IDX_WIDTH macro. Perhaps there should be another macro IDX_VALUE_BITS that does not diff --git a/lib/intprops-internal.h b/lib/intprops-internal.h index 0df385b9bf3..1fb3b799011 100644 --- a/lib/intprops-internal.h +++ b/lib/intprops-internal.h @@ -25,6 +25,23 @@ # pragma GCC diagnostic ignored "-Wtype-limits" #endif +/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25764. See: + https://gcc.gnu.org/PR68193 + https://github.com/llvm/llvm-project/issues/25764 + For now, assume GCC < 14 and all Clang versions generate bogus + warnings for _Generic. This matters only for compilers that + lack relevant builtins. */ +#if (__GNUC__ && __GNUC__ < 14) || defined __clang__ +# define _GL__GENERIC_BOGUS 1 +#else +# define _GL__GENERIC_BOGUS 0 +#endif + +/* Suppress -Wuseless-cast for, e.g., gcc-14 -std=gnu99. */ +#if __STDC_VERSION__ < 201112 && 14 <= __GNUC__ +# pragma GCC diagnostic ignored "-Wuseless-cast" +#endif + /* Return a value with the common real type of E and V and the value of V. Do not evaluate E. */ #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) @@ -32,8 +49,20 @@ /* The extra casts in the following macros work around compiler bugs, e.g., in Cray C 5.0.3.0. */ -/* True if the real type T is signed. */ -#define _GL_TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) +/* True if the standard integer or standard real type T is signed. */ +#if (__STDC_VERSION__ < 201112 || (defined _MSC_VER && _MSC_VER < 1944) \ + || _GL__GENERIC_BOGUS) +# define _GL_TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) +#else +/* Pacify -Wuseless-cast, but do not default to the simpler expression; + see <https://gcc.gnu.org/PR125261>. */ +# define _GL_TYPE_SIGNED(t) \ + (_Generic ((t) {0}, \ + bool: 0, char: CHAR_MIN < 0, signed char: 1, unsigned char: 0, \ + short int: 1, unsigned short int: 0, int: 1, unsigned int: 0, \ + long int: 1, unsigned long int: 0, long long int: 1, unsigned long long int: 0, \ + float: 1, double: 1, long double: 1)) +#endif /* Return 1 if the real expression E, after promotion, has a signed or floating type. Do not evaluate E. */ @@ -179,18 +208,6 @@ _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW) #endif -/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25764. See: - https://gcc.gnu.org/PR68193 - https://github.com/llvm/llvm-project/issues/25764 - For now, assume GCC < 14 and all Clang versions generate bogus - warnings for _Generic. This matters only for compilers that - lack relevant builtins. */ -#if (__GNUC__ && __GNUC__ < 14) || defined __clang__ -# 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 and OVERFLOW the overflow predicate. Return 1 if the result overflows. Arguments should not have side effects, @@ -304,15 +321,15 @@ ? (*(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 1 if the integer expressions A - B and -A would overflow, - respectively. Arguments should not have side effects, +/* Return 1 if the integer expression -A would overflow. + Arguments should not have side effects, and can be any signed integer type other than char, bool, a bit-precise integer type, or an enumeration type. These macros are tuned for their last input argument being a constant. */ #if _GL_HAS_BUILTIN_OVERFLOW_P # define _GL_INT_NEGATE_OVERFLOW(a) \ - __builtin_sub_overflow_p (0, a, (__typeof__ (- (a))) 0) + __builtin_sub_overflow_p (0, a, _GL_INT_CONVERT (- (a), 0)) #else # define _GL_INT_NEGATE_OVERFLOW(a) \ _GL_INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) diff --git a/lib/intprops.h b/lib/intprops.h index 924b6f9a466..8279cd73e34 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -25,9 +25,21 @@ /* True if the arithmetic type T is an integer type. bool counts as an integer. */ -#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) +#if (__STDC_VERSION__ < 201112 || (defined _MSC_VER && _MSC_VER < 1944) \ + || _GL__GENERIC_BOGUS) +# define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) +#else +/* Pacify -Wuseless-cast and do not default to the simpler expression; + see <https://gcc.gnu.org/PR125261>. */ +# define TYPE_IS_INTEGER(t) \ + (_Generic ((t) {0}, \ + bool: 1, char: 1, signed char: 1, unsigned char: 1, \ + short int: 1, unsigned short int: 1, int: 1, unsigned int: 1, \ + long int: 1, unsigned long int: 1, long long int: 1, unsigned long long int: 1, \ + float: 0, double: 0, long double: 0)) +#endif -/* True if the real type T is signed. */ +/* True if the standard integer or standard real type T is signed. */ #define TYPE_SIGNED(t) _GL_TYPE_SIGNED (t) /* Return 1 if the real expression E, after promotion, has a @@ -50,12 +62,34 @@ Padding bits are not supported; this is checked at compile-time below. */ #define TYPE_WIDTH(t) _GL_TYPE_WIDTH (t) -/* 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 standard integer type T. */ +#if (__STDC_VERSION__ < 201112 || (defined _MSC_VER && _MSC_VER < 1944) \ + || _GL__GENERIC_BOGUS) +# 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))) +#else +/* Pacify -Wuseless-cast and do not default to the simpler expressions; + see <https://gcc.gnu.org/PR125261>. */ +# define TYPE_MINIMUM(t) \ + (_Generic ((t) {0}, \ + bool: (bool) 0, char: (char) CHAR_MIN, \ + signed char: (signed char) SCHAR_MIN, unsigned char: (unsigned char) 0, \ + short int: (short int) SHRT_MIN, unsigned short int: (unsigned short int) 0, \ + int: INT_MIN, unsigned int: 0u, \ + long int: LONG_MIN, unsigned long int: 0ul, \ + long long int: LLONG_MIN, unsigned long long int: 0ull)) +# define TYPE_MAXIMUM(t) \ + (_Generic ((t) {0}, \ + bool: (bool) 1, char: (char) CHAR_MAX, \ + signed char: (signed char) SCHAR_MAX, unsigned char: (unsigned char) -1, \ + short int: (short int) SHRT_MAX, unsigned short int: (unsigned short int) -1, \ + int: INT_MAX, unsigned int: -1u, \ + long int: LONG_MAX, unsigned long int: -1ul, \ + long long int: LLONG_MAX, unsigned long long int: -1ull)) +#endif /* Bound on length of the string representing an unsigned integer value representable in B bits. log10 (2.0) < 146/485. The @@ -184,11 +218,11 @@ 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) + __builtin_add_overflow_p (a, b, _GL_INT_CONVERT ((a) + (b), 0)) # define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ - __builtin_sub_overflow_p (a, b, (__typeof__ ((a) - (b))) 0) + __builtin_sub_overflow_p (a, b, _GL_INT_CONVERT ((a) - (b), 0)) # define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ - __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0) + __builtin_mul_overflow_p (a, b, _GL_INT_CONVERT ((a) * (b), 0)) #else # define _GL_ADD_OVERFLOW(a, b, min, max) \ ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ diff --git a/lib/nproc.c b/lib/nproc.c index b0c9514115b..ef86975fb1f 100644 --- a/lib/nproc.c +++ b/lib/nproc.c @@ -25,6 +25,7 @@ #if HAVE_SETMNTENT # include <mntent.h> #endif +#include <stdcountof.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -61,8 +62,6 @@ #include "minmax.h" -#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) - #define NPROC_MINIMUM 1 /* Return the number of processors available to the current process, based @@ -335,9 +334,9 @@ num_processors_available (enum nproc_query query) # endif { CTL_HW, HW_NCPU } }; - for (int i = 0; i < ARRAY_SIZE (mib); i++) + for (int i = 0; i < countof (mib); i++) { - if (sysctl (mib[i], ARRAY_SIZE (mib[i]), &nprocs, &len, NULL, 0) == 0 + if (sysctl (mib[i], countof (mib[i]), &nprocs, &len, NULL, 0) == 0 && len == sizeof (nprocs) && 0 < nprocs) return nprocs; diff --git a/lib/pthread_sigmask.c b/lib/pthread_sigmask.c index 95600d6098b..7a21ec76a25 100644 --- a/lib/pthread_sigmask.c +++ b/lib/pthread_sigmask.c @@ -19,19 +19,22 @@ /* Specification. */ #include <signal.h> -#include <errno.h> -#include <stddef.h> +/* The native Windows implementation is defined in sigprocmask.c. */ +#if !(defined _WIN32 && !defined __CYGWIN__) -#if PTHREAD_SIGMASK_INEFFECTIVE -# include <string.h> -#endif +# include <errno.h> +# include <stddef.h> + +# if PTHREAD_SIGMASK_INEFFECTIVE +# include <string.h> +# endif int pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) -#undef pthread_sigmask +# undef pthread_sigmask { -#if HAVE_PTHREAD_SIGMASK -# if PTHREAD_SIGMASK_INEFFECTIVE +# if HAVE_PTHREAD_SIGMASK && !PTHREAD_SIGMASK_NOT_IN_LIBC +# if PTHREAD_SIGMASK_INEFFECTIVE sigset_t omask; sigset_t *old_mask_ptr = &omask; sigemptyset (&omask); @@ -40,13 +43,13 @@ pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) sigaddset (&omask, SIGILL); sigset_t omask_copy; memcpy (&omask_copy, &omask, sizeof omask); -# else +# else sigset_t *old_mask_ptr = old_mask; -# endif +# endif int ret = pthread_sigmask (how, new_mask, old_mask_ptr); -# if PTHREAD_SIGMASK_INEFFECTIVE +# if PTHREAD_SIGMASK_INEFFECTIVE if (ret == 0) { /* Detect whether pthread_sigmask is currently ineffective. @@ -64,14 +67,18 @@ pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) if (old_mask) memcpy (old_mask, &omask, sizeof omask); } -# endif -# if PTHREAD_SIGMASK_FAILS_WITH_ERRNO +# endif +# if PTHREAD_SIGMASK_FAILS_WITH_ERRNO if (ret == -1) return errno; -# endif +# endif return ret; -#else +# else int ret = sigprocmask (how, new_mask, old_mask); - return (ret < 0 ? errno : 0); -#endif + /* Test for ret != 0, not ret < 0, as a workaround against NetBSD bug + <https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=57213>. */ + return (ret != 0 ? errno : 0); +# endif } + +#endif diff --git a/lib/readutmp.h b/lib/readutmp.h index 7b6af7eb554..badbbc4331e 100644 --- a/lib/readutmp.h +++ b/lib/readutmp.h @@ -330,7 +330,7 @@ char *extract_trimmed_name (const STRUCT_UTMP *ut) If OPTIONS & READ_UTMP_NO_BOOT_TIME is nonzero, omit the boot time entries. - This function is not multithread-safe, since on many platforms it + This function is not thread-safe, since on many platforms it invokes the functions setutxent, getutxent, endutxent. These functions are needed because they may lock FILE (so that we don't read garbage when a concurrent process writes to FILE), but their diff --git a/lib/regcomp.c b/lib/regcomp.c index aa2f6800886..ab3783f94ce 100644 --- a/lib/regcomp.c +++ b/lib/regcomp.c @@ -21,6 +21,12 @@ # include <locale/weight.h> #endif +/* The localeinfo-related code fixes glibc bug 20381. + Someday this fix should be merged into glibc. */ +#if !defined _LIBC && !defined _REGEX_AVOID_UCHAR_H +# include "localeinfo.h" +#endif + static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, size_t length, reg_syntax_t syntax); static void re_compile_fastmap_iter (regex_t *bufp, @@ -267,11 +273,31 @@ re_compile_fastmap (struct re_pattern_buffer *bufp) weak_alias (__re_compile_fastmap, re_compile_fastmap) static __always_inline void -re_set_fastmap (char *fastmap, bool icase, int ch) +re_set_fastmap (char *fastmap, unsigned char ch) { fastmap[ch] = 1; - if (icase) - fastmap[tolower (ch)] = 1; +} + +/* Record in FASTMAP the initial byte of the representations of all + characters that match WC ignoring case, other than WC itself. + Use MBS as a scratch state. */ + +static void +re_set_fastmap_icase (char *fastmap, wchar_t wc, mbstate_t *mbs) +{ +#if defined _LIBC || defined _REGEX_AVOID_UCHAR_H + wchar_t folded[1] = {__towlower (wc)}; + int nfolded = folded[0] != wc; +#else + wchar_t folded[CASE_FOLDED_BUFSIZE]; + int nfolded = case_folded_counterparts (wc, folded); +#endif + for (int i = 0; i < nfolded; i++) + { + char buf[MB_LEN_MAX]; + if (__wcrtomb (buf, folded[i], mbs) != (size_t) -1) + re_set_fastmap (fastmap, buf[0]); + } } /* Helper function for re_compile_fastmap. @@ -283,7 +309,6 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, { re_dfa_t *dfa = bufp->buffer; Idx node_cnt; - bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE)); for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) { Idx node = init_state->nodes.elems[node_cnt]; @@ -291,8 +316,8 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, if (type == CHARACTER) { - re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) + re_set_fastmap (fastmap, dfa->nodes[node].opr.c); + if (bufp->syntax & RE_ICASE) { unsigned char buf[MB_LEN_MAX]; unsigned char *p; @@ -307,10 +332,8 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, *p++ = dfa->nodes[node].opr.c; memset (&state, '\0', sizeof (state)); if (__mbrtowc (&wc, (const char *) buf, p - buf, - &state) == p - buf - && (__wcrtomb ((char *) buf, __towlower (wc), &state) - != (size_t) -1)) - re_set_fastmap (fastmap, false, buf[0]); + &state) == p - buf) + re_set_fastmap_icase (fastmap, wc, &state); } } else if (type == SIMPLE_BRACKET) @@ -322,7 +345,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, bitset_word_t w = dfa->nodes[node].opr.sbcset[i]; for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) if (w & ((bitset_word_t) 1 << j)) - re_set_fastmap (fastmap, icase, ch); + re_set_fastmap (fastmap, ch); } } else if (type == COMPLEX_BRACKET) @@ -344,7 +367,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); for (i = 0; i < SBC_MAX; ++i) if (table[i] < 0) - re_set_fastmap (fastmap, icase, i); + re_set_fastmap (fastmap, i); } #endif /* _LIBC */ @@ -365,7 +388,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, mbstate_t mbs; memset (&mbs, 0, sizeof (mbs)); if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2) - re_set_fastmap (fastmap, false, (int) c); + re_set_fastmap (fastmap, c); } while (++c != 0); } @@ -375,17 +398,13 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, /* ... Else catch all bytes which can start the mbchars. */ for (i = 0; i < cset->nmbchars; ++i) { - char buf[256]; + char buf[MB_LEN_MAX]; mbstate_t state; memset (&state, '\0', sizeof (state)); if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) - re_set_fastmap (fastmap, icase, *(unsigned char *) buf); - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) - { - if (__wcrtomb (buf, __towlower (cset->mbchars[i]), &state) - != (size_t) -1) - re_set_fastmap (fastmap, false, *(unsigned char *) buf); - } + re_set_fastmap (fastmap, buf[0]); + if (bufp->syntax & RE_ICASE) + re_set_fastmap_icase (fastmap, cset->mbchars[i], &state); } } } @@ -499,7 +518,7 @@ regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf, { const char *msg; size_t msg_size; - int nerrcodes = sizeof __re_error_msgid_idx / sizeof __re_error_msgid_idx[0]; + int nerrcodes = countof (__re_error_msgid_idx); if (__glibc_unlikely (errcode < 0 || errcode >= nerrcodes)) /* Only error codes returned by the rest of the code should be passed diff --git a/lib/regex.c b/lib/regex.c index f9f333d237d..d0c7af90186 100644 --- a/lib/regex.c +++ b/lib/regex.c @@ -20,6 +20,7 @@ #define __STDC_WANT_IEC_60559_BFP_EXT__ #ifndef _LIBC +# define _GL_USE_STDLIB_ALLOC 1 # include <libc-config.h> # if __GNUC_PREREQ (4, 6) diff --git a/lib/regex.h b/lib/regex.h index df35c93e5ae..152a157c2f7 100644 --- a/lib/regex.h +++ b/lib/regex.h @@ -645,15 +645,15 @@ extern int re_exec (const char *); array_name[restrict] use glibc's __restrict_arr if available. Otherwise, GCC 3.1 and clang support this syntax (but not in C++ mode). - Other ISO C99 compilers support it as well. */ + Other ISO C99 compilers support it as well, except for MSVC. */ #ifndef _Restrict_arr_ # ifdef __restrict_arr # define _Restrict_arr_ __restrict_arr # else -# if ((199901L <= __STDC_VERSION__ \ - || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \ - || __clang_major__ >= 3) \ - && !defined __cplusplus) +# if (((199901L <= __STDC_VERSION__ && !defined _MSC_VER) \ + || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \ + || __clang_major__ >= 3) \ + && !defined __cplusplus) # define _Restrict_arr_ _Restrict_ # else # define _Restrict_arr_ diff --git a/lib/regex_internal.c b/lib/regex_internal.c index 4b9b80f6b95..e5e5be84bd4 100644 --- a/lib/regex_internal.c +++ b/lib/regex_internal.c @@ -387,7 +387,7 @@ build_wcs_upper_buffer (re_string_t *pstr) { size_t mbcdlen; - mbcdlen = __wcrtomb ((char *) buf, wcu, &prev_st); + mbcdlen = __wcrtomb (buf, wcu, &prev_st); if (__glibc_likely (mbclen == mbcdlen)) memcpy (pstr->mbs + byte_idx, buf, mbclen); else if (mbcdlen != (size_t) -1) @@ -1241,8 +1241,8 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) } /* Insert the new element ELEM to the re_node_set* SET. - SET should not already have ELEM. - Return true if successful. */ + SET is not expected to already contain ELEM, but tolerate + duplicates as a no-op. Return true if successful. */ static bool __attribute_warn_unused_result__ @@ -1285,8 +1285,16 @@ re_node_set_insert (re_node_set *set, Idx elem) else { for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) - set->elems[idx] = set->elems[idx - 1]; - DEBUG_ASSERT (set->elems[idx - 1] < elem); + { + set->elems[idx] = set->elems[idx - 1]; + /* Although we already guaranteed that idx is at least 2 here, + add an assertion to pacify GCC 16.1.1 -Wanalyzer-out-of-bounds + when _REGEX_AVOID_UCHAR_H is defined. */ + DEBUG_ASSERT (1 < idx); + } + /* Already in set. Return early. */ + if (__glibc_unlikely (set->elems[idx - 1] == elem)) + return true; } /* Insert the new element. */ diff --git a/lib/regex_internal.h b/lib/regex_internal.h index 11b745ef28c..bf6c9ba3b84 100644 --- a/lib/regex_internal.h +++ b/lib/regex_internal.h @@ -27,9 +27,8 @@ #include <langinfo.h> #include <locale.h> -#include <wchar.h> -#include <wctype.h> #include <stdckdint.h> +#include <stdcountof.h> #include <stdint.h> #ifndef _LIBC @@ -120,22 +119,47 @@ #define NEWLINE_CHAR '\n' #define WIDE_NEWLINE_CHAR L'\n' -/* Rename to standard API for using out of glibc. */ +/* Use Gnulib <uchar.h> if outside glibc and not avoided by the app. */ +#if defined _LIBC || defined _REGEX_AVOID_UCHAR_H +# include <wchar.h> +# include <wctype.h> +#else +# include <uchar.h> +# undef wctype_t +# define wchar_t char32_t +# define wctype_t c32_type_test_t +#endif + #ifndef _LIBC # undef __wctype # undef __iswalnum # undef __iswctype # undef __towlower # undef __towupper -# define __wctype wctype -# define __iswalnum iswalnum -# define __iswctype iswctype -# define __towlower towlower -# define __towupper towupper -# define __btowc btowc -# define __mbrtowc mbrtowc -# define __wcrtomb wcrtomb +# undef __btowc +# undef __mbrtowc +# undef __wcrtomb +# undef __regfree # define __regfree regfree +# ifdef _REGEX_AVOID_UCHAR_H +# define __wctype wctype +# define __iswalnum iswalnum +# define __iswctype iswctype +# define __towlower towlower +# define __towupper towupper +# define __btowc btowc +# define __mbrtowc mbrtowc +# define __wcrtomb wcrtomb +# else +# define __wctype c32_get_type_test +# define __iswalnum c32isalnum +# define __iswctype c32_apply_type_test +# define __towlower c32tolower +# define __towupper c32toupper +# define __btowc btoc32 +# define __mbrtowc mbrtoc32 +# define __wcrtomb c32rtomb +# endif #endif /* not _LIBC */ /* Types related to integers. Unless protected by #ifdef _LIBC, the @@ -171,7 +195,11 @@ reindenting a lot of regex code that formerly used 'int'. */ typedef regoff_t Idx; #ifdef _REGEX_LARGE_OFFSETS -# define IDX_MAX SSIZE_MAX +# ifdef SSIZE_MAX +# define IDX_MAX SSIZE_MAX +# else +# define IDX_MAX ((Idx) ((size_t) -1 / 2)) +# endif #else # define IDX_MAX INT_MAX #endif @@ -435,7 +463,11 @@ typedef struct re_dfa_t re_dfa_t; # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif -#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) +#if defined _LIBC || HAVE_MALLOC_0_NONNULL +# define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) +#else +# define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t) + ((n) == 0))) +#endif #define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t))) #define re_free(p) free (p) @@ -772,8 +804,8 @@ __attribute__ ((pure, unused)) re_string_wchar_at (const re_string_t *pstr, Idx idx) { if (pstr->mb_cur_max == 1) - return (wint_t) pstr->mbs[idx]; - return (wint_t) pstr->wcs[idx]; + return pstr->mbs[idx]; + return pstr->wcs[idx]; } #ifdef _LIBC diff --git a/lib/regexec.c b/lib/regexec.c index c84ce1ef339..ff62ac08ef1 100644 --- a/lib/regexec.c +++ b/lib/regexec.c @@ -627,6 +627,8 @@ re_search_internal (const regex_t *preg, const char *string, Idx length, /* We must check the longest matching, if nmatch > 0. */ fl_longest_match = (nmatch != 0 || dfa->nbackref); + re_dfastate_t **save_state_log = NULL; + err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1, preg->translate, (preg->syntax & RE_ICASE) != 0, dfa); @@ -802,11 +804,32 @@ re_search_internal (const regex_t *preg, const char *string, Idx length, if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match) || dfa->nbackref) { + /* Save state_log before pruning, in case set_regs + later fails and we need to retry with a shorter + match. */ + re_free (save_state_log); + save_state_log = NULL; + if (!preg->no_sub && nmatch > 1 && dfa->nbackref) + { + save_state_log + = re_malloc (re_dfastate_t *, + mctx.match_last + 1); + if (__glibc_unlikely (save_state_log == NULL)) + { + err = REG_ESPACE; + goto free_return; + } + memcpy (save_state_log, mctx.state_log, + sizeof (re_dfastate_t *) + * (mctx.match_last + 1)); + } err = prune_impossible_nodes (&mctx); if (err == REG_NOERROR) break; if (__glibc_unlikely (err != REG_NOMATCH)) goto free_return; + re_free (save_state_log); + save_state_log = NULL; match_last = -1; } else @@ -825,24 +848,79 @@ re_search_internal (const regex_t *preg, const char *string, Idx length, { Idx reg_idx; - /* Initialize registers. */ - for (reg_idx = 1; reg_idx < nmatch; ++reg_idx) - pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1; + /* When set_regs fails for a backref pattern, the structural + match at match_last has no valid register assignment. Try + shorter match lengths, since a valid shorter match may + exist (e.g., all groups matching empty). */ + for (;;) + { + /* Initialize registers. */ + for (reg_idx = 1; reg_idx < nmatch; ++reg_idx) + pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1; + pmatch[0].rm_so = 0; + pmatch[0].rm_eo = mctx.match_last; - /* Set the points where matching start/end. */ - pmatch[0].rm_so = 0; - pmatch[0].rm_eo = mctx.match_last; - /* FIXME: This function should fail if mctx.match_last exceeds - the maximum possible regoff_t value. We need a new error - code REG_OVERFLOW. */ + if (preg->no_sub || nmatch <= 1) + break; - if (!preg->no_sub && nmatch > 1) - { err = set_regs (preg, &mctx, nmatch, pmatch, dfa->has_plural_match && dfa->nbackref > 0); + if (__glibc_likely (err == REG_NOERROR) + || save_state_log == NULL + || err != REG_NOMATCH) + break; + + /* set_regs failed; try a shorter match_last. */ + Idx ml = mctx.match_last; + re_free (mctx.state_log); + do + { + --ml; + if (ml < 0) + break; + } + while (save_state_log[ml] == NULL + || !save_state_log[ml]->halt + || !check_halt_state_context + (&mctx, save_state_log[ml], ml)); + if (ml < 0) + { + err = REG_NOMATCH; + mctx.state_log = save_state_log; + save_state_log = NULL; + break; + } + mctx.state_log + = re_malloc (re_dfastate_t *, ml + 1); + if (__glibc_unlikely (mctx.state_log == NULL)) + { + mctx.state_log = save_state_log; + save_state_log = NULL; + err = REG_ESPACE; + break; + } + memcpy (mctx.state_log, save_state_log, + sizeof (re_dfastate_t *) * (ml + 1)); + mctx.match_last = ml; + mctx.last_node + = check_halt_state_context + (&mctx, save_state_log[ml], ml); + err = prune_impossible_nodes (&mctx); if (__glibc_unlikely (err != REG_NOERROR)) - goto free_return; + { + if (err == REG_NOMATCH) + { + re_free (mctx.state_log); + mctx.state_log = save_state_log; + save_state_log = NULL; + } + break; + } } + re_free (save_state_log); + save_state_log = NULL; + if (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; /* At last, add the offset to each register, since we slid the buffers so that we could assume that the matching starts @@ -882,6 +960,7 @@ re_search_internal (const regex_t *preg, const char *string, Idx length, } free_return: + re_free (save_state_log); re_free (mctx.state_log); if (dfa->nbackref) match_ctx_free (&mctx); @@ -934,7 +1013,7 @@ prune_impossible_nodes (re_match_context_t *mctx) goto free_return; if (sifted_states[0] != NULL || lim_states[0] != NULL) break; - do + for (;;) { --match_last; if (match_last < 0) @@ -942,11 +1021,17 @@ prune_impossible_nodes (re_match_context_t *mctx) ret = REG_NOMATCH; goto free_return; } - } while (mctx->state_log[match_last] == NULL - || !mctx->state_log[match_last]->halt); - halt_node = check_halt_state_context (mctx, - mctx->state_log[match_last], - match_last); + if (mctx->state_log[match_last] != NULL + && mctx->state_log[match_last]->halt) + { + halt_node + = check_halt_state_context (mctx, + mctx->state_log[match_last], + match_last); + if (halt_node) + break; + } + } } ret = merge_state_array (dfa, sifted_states, lim_states, match_last + 1); @@ -2256,7 +2341,7 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, mctx->state_log[cur_idx] = next_state; mctx->state_log_top = cur_idx; } - else if (mctx->state_log[cur_idx] == 0) + else if (mctx->state_log[cur_idx] == NULL) { mctx->state_log[cur_idx] = next_state; } diff --git a/lib/scratch_buffer.h b/lib/scratch_buffer.h index 1185a8e452f..5fc582fe9e6 100644 --- a/lib/scratch_buffer.h +++ b/lib/scratch_buffer.h @@ -102,9 +102,9 @@ extern bool scratch_buffer_set_array_size (struct scratch_buffer *buffer, /* The implementation is imported from glibc. */ /* Avoid possible conflicts with symbols exported by the GNU libc. */ -#define __libc_scratch_buffer_grow gl_scratch_buffer_grow -#define __libc_scratch_buffer_grow_preserve gl_scratch_buffer_grow_preserve -#define __libc_scratch_buffer_set_array_size gl_scratch_buffer_set_array_size +#define __libc_scratch_buffer_grow _gl_scratch_buffer_grow +#define __libc_scratch_buffer_grow_preserve _gl_scratch_buffer_grow_preserve +#define __libc_scratch_buffer_set_array_size _gl_scratch_buffer_set_array_size #ifndef _GL_LIKELY /* Rely on __builtin_expect, as provided by the module 'builtin-expect'. */ diff --git a/lib/set-permissions.c b/lib/set-permissions.c index 8a0eadf5c46..f6a1315e0d6 100644 --- a/lib/set-permissions.c +++ b/lib/set-permissions.c @@ -21,6 +21,8 @@ #include "acl.h" +#include <stdcountof.h> + #include "acl-internal.h" #include "minmax.h" @@ -251,11 +253,9 @@ set_acls_from_mode (const char *name, int desc, mode_t mode, bool *must_chmod) int ret; if (desc != -1) - ret = facl (desc, SETACL, - sizeof (entries) / sizeof (aclent_t), entries); + ret = facl (desc, SETACL, countof (entries), entries); else - ret = acl (name, SETACL, - sizeof (entries) / sizeof (aclent_t), entries); + ret = acl (name, SETACL, countof (entries), entries); if (ret < 0) { if (errno == ENOSYS || errno == EOPNOTSUPP) diff --git a/lib/sha1.c b/lib/sha1.c index bb7aa2af293..150e38ea47a 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -240,7 +240,7 @@ sha1_process_block (void const *restrict buffer, size_t len, ctx->total[0] += lolen; ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); -#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n)))) +#define rol(x, n) (((x) << (n)) | ((uint32_t) {(x)} >> (32 - (n)))) #define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ diff --git a/lib/sig2str.c b/lib/sig2str.c index da54234ac48..3141ff88066 100644 --- a/lib/sig2str.c +++ b/lib/sig2str.c @@ -23,6 +23,7 @@ #include <signal.h> #include <limits.h> +#include <stdcountof.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -260,8 +261,6 @@ static struct numname { int num; char const name[8]; } numname_table[] = { 0, "EXIT" } }; -#define NUMNAME_ENTRIES (sizeof numname_table / sizeof numname_table[0]) - /* ISDIGIT differs from isdigit, as follows: - Its arg may be any int or unsigned int; it need not be an unsigned char or EOF. @@ -286,7 +285,7 @@ str2signum (char const *signame) } else { - for (unsigned int i = 0; i < NUMNAME_ENTRIES; i++) + for (int i = 0; i < countof (numname_table); i++) if (streq (numname_table[i].name, signame)) return numname_table[i].num; @@ -331,7 +330,7 @@ str2sig (char const *signame, int *signum) int sig2str (int signum, char *signame) { - for (unsigned int i = 0; i < NUMNAME_ENTRIES; i++) + for (int i = 0; i < countof (numname_table); i++) if (numname_table[i].num == signum) { strcpy (signame, numname_table[i].name); diff --git a/lib/signal.in.h b/lib/signal.in.h index ce844b1a9cc..9e140ca5e83 100644 --- a/lib/signal.in.h +++ b/lib/signal.in.h @@ -20,6 +20,12 @@ #endif @PRAGMA_COLUMNS@ +/* Deactivate the mingw <pthread_signal.h>, that provides an unusable definition + of pthread_sigmask(). We need to do this before including <signal.h>. */ +#ifndef WIN_PTHREADS_SIGNAL_H +#define WIN_PTHREADS_SIGNAL_H +#endif + #if defined __need_sig_atomic_t || defined __need_sigset_t || defined _@GUARD_PREFIX@_ALREADY_INCLUDING_SIGNAL_H || (defined _SIGNAL_H && !defined __SIZEOF_PTHREAD_MUTEX_T) /* Special invocation convention: - Inside glibc header files. @@ -68,12 +74,13 @@ /* Mac OS X 10.3, FreeBSD < 8.0, OpenBSD < 5.1, Solaris 2.6, Android, OS/2 kLIBC declare pthread_sigmask in <pthread.h>, not in <signal.h>. - But avoid namespace pollution on glibc systems.*/ + But avoid namespace pollution on glibc systems. */ #if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \ && ((defined __APPLE__ && defined __MACH__) \ || (defined __FreeBSD__ && __FreeBSD__ < 8) \ || (defined __OpenBSD__ && OpenBSD < 201205) \ - || defined __sun || defined __ANDROID__ \ + || (defined __sun && !defined __cplusplus) \ + || defined __ANDROID__ \ || defined __KLIBC__) \ && ! defined __GLIBC__ # include <pthread.h> diff --git a/lib/stat-time.h b/lib/stat-time.h index 45364316645..461a0c88b93 100644 --- a/lib/stat-time.h +++ b/lib/stat-time.h @@ -28,6 +28,7 @@ #include <errno.h> #include <stdckdint.h> +#include <stdcountof.h> #include <stddef.h> #include <sys/stat.h> #include <time.h> @@ -232,7 +233,7 @@ stat_time_normalize (int result, _GL_UNUSED struct stat *st) short int const ts_off[] = { STAT_TIMESPEC_OFFSETOF (st_atim), STAT_TIMESPEC_OFFSETOF (st_mtim), STAT_TIMESPEC_OFFSETOF (st_ctim) }; - for (int i = 0; i < sizeof ts_off / sizeof *ts_off; i++) + for (int i = 0; i < countof (ts_off); i++) { struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]); long int q = ts->tv_nsec / timespec_hz; diff --git a/lib/stdbit.in.h b/lib/stdbit.in.h index 88f298afb9f..92749487fa8 100644 --- a/lib/stdbit.in.h +++ b/lib/stdbit.in.h @@ -17,19 +17,92 @@ /* Written by Paul Eggert. */ -#ifndef STDBIT_H -#define STDBIT_H 1 +#ifndef _@GUARD_PREFIX@_STDBIT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_STDBIT_H@ +# @INCLUDE_NEXT@ @NEXT_STDBIT_H@ +#endif + +#ifndef _@GUARD_PREFIX@_STDBIT_H +#define _@GUARD_PREFIX@_STDBIT_H /* This file uses _GL_INLINE, WORDS_BIGENDIAN. */ #if !_GL_CONFIG_H_INCLUDED #error "Please include config.h first." #endif -_GL_INLINE_HEADER_BEGIN +/* If needed for APIs, get size_t, avoiding namespace pollution on GNU. */ +#if @GNULIB_STDC_MEMREVERSE8@ && !defined __STDC_VERSION_STDBIT_H__ +# define __need_size_t +# include <stddef.h> +#endif + +/* If needed for APIs, get intN_t, uintN_t, int_leastN_t, + uint_leastN_t, and (for internal use) get equivalents of + uint_fast{16,32,64}_t. Avoid namespace pollution on GNU. */ +#if (@GNULIB_STDC_MEMREVERSE8U@ \ + || @GNULIB_STDC_LOAD8@ || @GNULIB_STDC_LOAD8_ALIGNED@ \ + || @GNULIB_STDC_STORE8@ || @GNULIB_STDC_STORE8_ALIGNED@) +# if !(defined __STDC_VERSION_STDBIT_H__ && defined __UINT_FAST64_TYPE__) +# include <stdint.h> +# define _GL_STDBIT_UINT_FAST16 uint_fast16_t +# define _GL_STDBIT_UINT_FAST32 uint_fast32_t +# define _GL_STDBIT_UINT_FAST64 uint_fast64_t +# else +# define _GL_STDBIT_UINT_FAST16 __UINT_FAST16_TYPE__ +# define _GL_STDBIT_UINT_FAST32 __UINT_FAST32_TYPE__ +# define _GL_STDBIT_UINT_FAST64 __UINT_FAST64_TYPE__ +# endif +#endif + +#if @GNULIB_STDC_MEMREVERSE8U@ || @GNULIB_STDC_LOAD8_ALIGNED@ || @GNULIB_STDC_STORE8_ALIGNED@ + +/* Determine whether the compiler supports the __builtin_bswap{16,32,64} + builtins. */ +# if defined __GNUC__ && 4 < __GNUC__ + (8 <= __GNUC_MINOR__) +# define _GL_STDBIT_HAS_BUILTIN_BSWAP16 1 +# elif defined __has_builtin +# if __has_builtin (__builtin_bswap16) +# define _GL_STDBIT_HAS_BUILTIN_BSWAP16 1 +# endif +# endif +# if defined __GNUC__ && 4 < __GNUC__ + (3 <= __GNUC_MINOR__) +# define _GL_STDBIT_HAS_BUILTIN_BSWAP32 1 +# define _GL_STDBIT_HAS_BUILTIN_BSWAP64 1 +# elif defined __has_builtin +# if __has_builtin (__builtin_bswap32) +# define _GL_STDBIT_HAS_BUILTIN_BSWAP32 1 +# endif +# if __has_builtin (__builtin_bswap64) +# define _GL_STDBIT_HAS_BUILTIN_BSWAP64 1 +# endif +# endif + +#endif + +#if @GNULIB_STDC_LOAD8_ALIGNED@ || @GNULIB_STDC_STORE8_ALIGNED@ + +/* Get memcpy, but keep namespace clean on GNU. */ +# ifdef __has_builtin +# if __has_builtin (__builtin_memcpy) +# define _GL_STDBIT_MEMCPY(dest, src, n) __builtin_memcpy (dest, src, n) +# endif +# endif +# ifndef _GL_STDBIT_MEMCPY +# include <string.h> +# define _GL_STDBIT_MEMCPY(dest, src, n) memcpy (dest, src, n) +# endif -#ifndef _GL_STDBIT_INLINE -# define _GL_STDBIT_INLINE _GL_INLINE #endif + +_GL_INLINE_HEADER_BEGIN + #ifndef _GL_STDC_LEADING_ZEROS_INLINE # define _GL_STDC_LEADING_ZEROS_INLINE _GL_INLINE #endif @@ -72,6 +145,30 @@ _GL_INLINE_HEADER_BEGIN #ifndef _GL_STDC_BIT_CEIL_INLINE # define _GL_STDC_BIT_CEIL_INLINE _GL_INLINE #endif +#ifndef _GL_STDC_ROTATE_LEFT_INLINE +# define _GL_STDC_ROTATE_LEFT_INLINE _GL_INLINE +#endif +#ifndef _GL_STDC_ROTATE_RIGHT_INLINE +# define _GL_STDC_ROTATE_RIGHT_INLINE _GL_INLINE +#endif +#ifndef _GL_STDC_MEMREVERSE8_INLINE +# define _GL_STDC_MEMREVERSE8_INLINE _GL_INLINE +#endif +#ifndef _GL_STDC_MEMREVERSE8U_INLINE +# define _GL_STDC_MEMREVERSE8U_INLINE _GL_INLINE +#endif +#ifndef _GL_STDC_LOAD8_ALIGNED_INLINE +# define _GL_STDC_LOAD8_ALIGNED_INLINE _GL_INLINE +#endif +#ifndef _GL_STDC_LOAD8_INLINE +# define _GL_STDC_LOAD8_INLINE _GL_INLINE +#endif +#ifndef _GL_STDC_STORE8_ALIGNED_INLINE +# define _GL_STDC_STORE8_ALIGNED_INLINE _GL_INLINE +#endif +#ifndef _GL_STDC_STORE8_INLINE +# define _GL_STDC_STORE8_INLINE _GL_INLINE +#endif /* An expression, preferably with the type of A, that has the value of B. */ #if ((defined __GNUC__ && 2 <= __GNUC__) \ @@ -90,10 +187,13 @@ _GL_INLINE_HEADER_BEGIN #endif -/* ISO C 23 § 7.18.1 General */ +#ifdef __cplusplus +extern "C" { +#endif -#define __STDC_VERSION_STDBIT_H__ 202311L +/* Some systems are only missing C2y features in stdbit.h. */ +#ifndef __STDC_VERSION_STDBIT_H__ /* ISO C 23 § 7.18.2 Endian */ @@ -105,88 +205,82 @@ _GL_INLINE_HEADER_BEGIN # define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__ #endif +#endif /* !__STDC_VERSION_STDBIT_H__ */ -#ifdef __cplusplus -extern "C" { -#endif -#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) || 4 <= __clang_major__ -# define _GL_STDBIT_HAS_BUILTIN_CLZ true -# define _GL_STDBIT_HAS_BUILTIN_CTZ true -# define _GL_STDBIT_HAS_BUILTIN_POPCOUNT true -#elif defined __has_builtin -# if (__has_builtin (__builtin_clz) \ - && __has_builtin (__builtin_clzl) \ - && __has_builtin (__builtin_clzll)) +/* Some systems are only missing C2y features in stdbit.h. */ +#ifndef __STDC_VERSION_STDBIT_H__ + +/* ISO C 23 § 7.18.3 Count Leading Zeros */ + +#if @GNULIB_STDC_LEADING_ZEROS@ + +# if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) || 4 <= __clang_major__ # define _GL_STDBIT_HAS_BUILTIN_CLZ true +# elif defined __has_builtin +# if (__has_builtin (__builtin_clz) \ + && __has_builtin (__builtin_clzl) \ + && __has_builtin (__builtin_clzll)) +# define _GL_STDBIT_HAS_BUILTIN_CLZ true +# endif # endif -# if (__has_builtin (__builtin_ctz) \ - && __has_builtin (__builtin_ctzl) \ - && __has_builtin (__builtin_ctzll)) -# define _GL_STDBIT_HAS_BUILTIN_CTZ true -# endif -# if (__has_builtin (__builtin_popcount) \ - && __has_builtin (__builtin_popcountl) \ - && __has_builtin (__builtin_popcountll)) -# define _GL_STDBIT_HAS_BUILTIN_POPCOUNT true -# endif -#endif /* Count leading 0 bits of N, even if N is 0. */ -#ifdef _GL_STDBIT_HAS_BUILTIN_CLZ -_GL_STDBIT_INLINE int -__gl_stdbit_clz (unsigned int n) +# if !GNULIB_defined_clz_functions +# ifdef _GL_STDBIT_HAS_BUILTIN_CLZ +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clz (unsigned int n) { return n ? __builtin_clz (n) : 8 * sizeof n; } -_GL_STDBIT_INLINE int -__gl_stdbit_clzl (unsigned long int n) +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clzl (unsigned long int n) { return n ? __builtin_clzl (n) : 8 * sizeof n; } -_GL_STDBIT_INLINE int -__gl_stdbit_clzll (unsigned long long int n) +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clzll (unsigned long long int n) { return n ? __builtin_clzll (n) : 8 * sizeof n; } -#elif defined _MSC_VER +# elif defined _MSC_VER /* Declare the few MSVC intrinsics that we need. We prefer not to include <intrin.h> because it would pollute the namespace. */ extern unsigned char _BitScanReverse (unsigned long *, unsigned long); -# pragma intrinsic (_BitScanReverse) -# ifdef _M_X64 +# pragma intrinsic (_BitScanReverse) +# ifdef _M_X64 extern unsigned char _BitScanReverse64 (unsigned long *, unsigned long long); -# pragma intrinsic (_BitScanReverse64) -# endif +# pragma intrinsic (_BitScanReverse64) +# endif -_GL_STDBIT_INLINE int -__gl_stdbit_clzl (unsigned long int n) +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clzl (unsigned long int n) { unsigned long int r; return 8 * sizeof n - (_BitScanReverse (&r, n) ? r + 1 : 0); } -_GL_STDBIT_INLINE int -__gl_stdbit_clz (unsigned int n) +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clz (unsigned int n) { - return __gl_stdbit_clzl (n) - 8 * (sizeof 0ul - sizeof n); + return _gl_stdbit_clzl (n) - 8 * (sizeof 0ul - sizeof n); } -_GL_STDBIT_INLINE int -__gl_stdbit_clzll (unsigned long long int n) +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clzll (unsigned long long int n) { -# ifdef _M_X64 +# ifdef _M_X64 unsigned long int r; return 8 * sizeof n - (_BitScanReverse64 (&r, n) ? r + 1 : 0); -# else +# else unsigned long int hi = n >> 32; - return __gl_stdbit_clzl (hi ? hi : n) + (hi ? 0 : 32); -# endif + return _gl_stdbit_clzl (hi ? hi : n) + (hi ? 0 : 32); +# endif } -#else /* !_MSC_VER */ +# else /* !_MSC_VER */ -_GL_STDBIT_INLINE int -__gl_stdbit_clzll (unsigned long long int n) +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clzll (unsigned long long int n) { int r = 0; for (int i = 8 * sizeof n >> 1; 1 << 6 <= i; i >>= 1) @@ -199,218 +293,27 @@ __gl_stdbit_clzll (unsigned long long int n) int a2 = (0x000000000000000f < n) << 2; n >>= a2; r += a2; return (8 * sizeof n - (1 << 2) - r) + ((0x11112234ull >> (n << 2)) & 0xf); } -_GL_STDBIT_INLINE int -__gl_stdbit_clz (unsigned int n) +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clz (unsigned int n) { - return __gl_stdbit_clzll (n) - 8 * (sizeof 0ull - sizeof 0u); + return _gl_stdbit_clzll (n) - 8 * (sizeof 0ull - sizeof 0u); } -_GL_STDBIT_INLINE int -__gl_stdbit_clzl (unsigned long int n) +_GL_STDC_LEADING_ZEROS_INLINE int +_gl_stdbit_clzl (unsigned long int n) { - return __gl_stdbit_clzll (n) - 8 * (sizeof 0ull - sizeof 0ul); -} -#endif - -/* Count trailing 0 bits of N, even if N is 0. */ -#ifdef _GL_STDBIT_HAS_BUILTIN_CTZ -_GL_STDBIT_INLINE int -__gl_stdbit_ctz (unsigned int n) -{ - return n ? __builtin_ctz (n) : 8 * sizeof n; -} -_GL_STDBIT_INLINE int -__gl_stdbit_ctzl (unsigned long int n) -{ - return n ? __builtin_ctzl (n) : 8 * sizeof n; -} -_GL_STDBIT_INLINE int -__gl_stdbit_ctzll (unsigned long long int n) -{ - return n ? __builtin_ctzll (n) : 8 * sizeof n; + return _gl_stdbit_clzll (n) - 8 * (sizeof 0ull - sizeof 0ul); } -#elif defined _MSC_VER - -/* Declare the few MSVC intrinsics that we need. We prefer not to include - <intrin.h> because it would pollute the namespace. */ -extern unsigned char _BitScanForward (unsigned long *, unsigned long); -# pragma intrinsic (_BitScanForward) -# ifdef _M_X64 -extern unsigned char _BitScanForward64 (unsigned long *, unsigned long long); -# pragma intrinsic (_BitScanForward64) -# endif - -_GL_STDBIT_INLINE int -__gl_stdbit_ctzl (unsigned long int n) -{ - unsigned long int r; - return _BitScanForward (&r, n) ? r : 8 * sizeof n; -} -_GL_STDBIT_INLINE int -__gl_stdbit_ctz (unsigned int n) -{ - return __gl_stdbit_ctzl (n | (1ul << (8 * sizeof n - 1) << 1)); -} -_GL_STDBIT_INLINE int -__gl_stdbit_ctzll (unsigned long long int n) -{ -# ifdef _M_X64 - unsigned long int r; - return _BitScanForward64 (&r, n) ? r : 8 * sizeof n; -# else - unsigned int lo = n; - return __gl_stdbit_ctzl (lo ? lo : n >> 32) + (lo ? 0 : 32); -# endif -} - -#else /* !_MSC_VER */ - -_GL_STDBIT_INLINE int -__gl_stdbit_ctz (unsigned int n) -{ - return 8 * sizeof n - (n ? __gl_stdbit_clz (n & -n) + 1 : 0); -} -_GL_STDBIT_INLINE int -__gl_stdbit_ctzl (unsigned long int n) -{ - return 8 * sizeof n - (n ? __gl_stdbit_clzl (n & -n) + 1 : 0); -} -_GL_STDBIT_INLINE int -__gl_stdbit_ctzll (unsigned long long int n) -{ - return 8 * sizeof n - (n ? __gl_stdbit_clzll (n & -n) + 1 : 0); -} -#endif - -#if @GL_STDC_COUNT_ONES@ -/* Count 1 bits in N. */ -# ifdef _GL_STDBIT_HAS_BUILTIN_POPCOUNT -# define __gl_stdbit_popcount __builtin_popcount -# define __gl_stdbit_popcountl __builtin_popcountl -# define __gl_stdbit_popcountll __builtin_popcountll -# else -_GL_STDC_COUNT_ONES_INLINE int -__gl_stdbit_popcount_wide (unsigned long long int n) -{ - if (sizeof n & (sizeof n - 1)) - { - /* Use a simple O(log N) loop on theoretical platforms where N's - width is not a power of 2. */ - int count = 0; - for (int i = 0; i < 8 * sizeof n; i++, n >>= 1) - count += n & 1; - return count; - } - else - { - /* N's width is a power of 2; count in parallel. */ - unsigned long long int - max = -1ull, - x555555 = max / (1 << 1 | 1), /* 0x555555... */ - x333333 = max / (1 << 2 | 1), /* 0x333333... */ - x0f0f0f = max / (1 << 4 | 1), /* 0x0f0f0f... */ - x010101 = max / ((1 << 8) - 1), /* 0x010101... */ - x000_7f = max / 0xffffffffffffffffLL * 0x7f; /* 0x000000000000007f... */ - n -= (n >> 1) & x555555; - n = (n & x333333) + ((n >> 2) & x333333); - n = (n + (n >> 4)) & x0f0f0f; - - /* If the popcount always fits in 8 bits, multiply so that the - popcount is in the leading 8 bits of the product; these days - this is typically faster than the alternative below. */ - if (8 * sizeof n < 1 << 8) - return n * x010101 >> 8 * (sizeof n - 1); - - /* N is at least 256 bits wide! Fall back on an O(log log N) - loop that a compiler could unroll. Unroll the first three - iterations by hand, to skip some division and masking. This - is the most we can easily do without hassling with constants - that a typical-platform compiler would reject. */ - n += n >> (1 << 3); - n += n >> (1 << 4); - n += n >> (1 << 5); - n &= x000_7f; - for (int i = 64; i < 8 * sizeof n; i <<= 1) - n = (n + (n >> i)) & max / (1ull << i | 1); - return n; - } -} - -# ifdef _MSC_VER -# if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) -/* Declare the few MSVC intrinsics that we need. We prefer not to include - <intrin.h> because it would pollute the namespace. */ -extern void __cpuid (int[4], int); -# pragma intrinsic (__cpuid) -extern unsigned int __popcnt (unsigned int); -# pragma intrinsic (__popcnt) -# ifdef _M_X64 -extern unsigned long long __popcnt64 (unsigned long long); -# pragma intrinsic (__popcnt64) -# else -_GL_STDC_COUNT_ONES_INLINE int -__popcnt64 (unsigned long long int n) -{ - return __popcnt (n >> 32) + __popcnt (n); -} -# endif -# endif - -/* 1 if supported, -1 if not, 0 if unknown. */ -extern signed char __gl_stdbit_popcount_support; - -_GL_STDC_COUNT_ONES_INLINE bool -__gl_stdbit_popcount_supported (void) -{ - if (!__gl_stdbit_popcount_support) - { - /* Do as described in - <https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64> - Although Microsoft started requiring POPCNT in MS-Windows 11 24H2, - we'll be more cautious. */ - int cpu_info[4]; - __cpuid (cpu_info, 1); - __gl_stdbit_popcount_support = cpu_info[2] & 1 << 23 ? 1 : -1; - } - return 0 < __gl_stdbit_popcount_support; -} -_GL_STDC_COUNT_ONES_INLINE int -__gl_stdbit_popcount (unsigned int n) -{ - return (__gl_stdbit_popcount_supported () - ? __popcnt (n) - : __gl_stdbit_popcount_wide (n)); -} -_GL_STDC_COUNT_ONES_INLINE int -__gl_stdbit_popcountl (unsigned long int n) -{ - return (__gl_stdbit_popcount_supported () - ? __popcnt (n) - : __gl_stdbit_popcount_wide (n)); -} -_GL_STDC_COUNT_ONES_INLINE int -__gl_stdbit_popcountll (unsigned long long int n) -{ - return (__gl_stdbit_popcount_supported () - ? __popcnt64 (n) - : __gl_stdbit_popcount_wide (n)); -} -# else /* !_MSC_VER */ -# define __gl_stdbit_popcount __gl_stdbit_popcount_wide -# define __gl_stdbit_popcountl __gl_stdbit_popcount_wide -# define __gl_stdbit_popcountll __gl_stdbit_popcount_wide # endif -# endif -#endif - -/* ISO C 23 § 7.18.3 Count Leading Zeros */ +# define GNULIB_defined_clz_functions 1 +# endif -#if @GL_STDC_LEADING_ZEROS@ +# if !GNULIB_defined_stdc_leading_zeros_functions _GL_STDC_LEADING_ZEROS_INLINE unsigned int stdc_leading_zeros_ui (unsigned int n) { - return __gl_stdbit_clz (n); + return _gl_stdbit_clz (n); } _GL_STDC_LEADING_ZEROS_INLINE unsigned int @@ -428,15 +331,18 @@ stdc_leading_zeros_us (unsigned short int n) _GL_STDC_LEADING_ZEROS_INLINE unsigned int stdc_leading_zeros_ul (unsigned long int n) { - return __gl_stdbit_clzl (n); + return _gl_stdbit_clzl (n); } _GL_STDC_LEADING_ZEROS_INLINE unsigned int stdc_leading_zeros_ull (unsigned long long int n) { - return __gl_stdbit_clzll (n); + return _gl_stdbit_clzll (n); } +# define GNULIB_defined_stdc_leading_zeros_functions 1 +# endif + # define stdc_leading_zeros(n) \ (sizeof (n) == 1 ? stdc_leading_zeros_uc (n) \ : sizeof (n) == sizeof (unsigned short int) ? stdc_leading_zeros_us (n) \ @@ -449,7 +355,9 @@ stdc_leading_zeros_ull (unsigned long long int n) /* ISO C 23 § 7.18.4 Count Leading Ones */ -#if @GL_STDC_LEADING_ONES@ +#if @GNULIB_STDC_LEADING_ONES@ + +# if !GNULIB_defined_stdc_leading_ones_functions _GL_STDC_LEADING_ONES_INLINE unsigned int stdc_leading_ones_uc (unsigned char n) @@ -481,6 +389,9 @@ stdc_leading_ones_ull (unsigned long long int n) return stdc_leading_zeros_ull (~n); } +# define GNULIB_defined_stdc_leading_ones_functions 1 +# endif + # define stdc_leading_ones(n) \ (sizeof (n) == 1 ? stdc_leading_ones_uc (n) \ : sizeof (n) == sizeof (unsigned short int) ? stdc_leading_ones_us (n) \ @@ -493,12 +404,98 @@ stdc_leading_ones_ull (unsigned long long int n) /* ISO C 23 § 7.18.5 Count Trailing Zeros */ -#if @GL_STDC_TRAILING_ZEROS@ +#if @GNULIB_STDC_TRAILING_ZEROS@ + +# if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) || 4 <= __clang_major__ +# define _GL_STDBIT_HAS_BUILTIN_CTZ true +# elif defined __has_builtin +# if (__has_builtin (__builtin_ctz) \ + && __has_builtin (__builtin_ctzl) \ + && __has_builtin (__builtin_ctzll)) +# define _GL_STDBIT_HAS_BUILTIN_CTZ true +# endif +# endif + +/* Count trailing 0 bits of N, even if N is 0. */ +# if !GNULIB_defined_ctz_functions +# ifdef _GL_STDBIT_HAS_BUILTIN_CTZ +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctz (unsigned int n) +{ + return n ? __builtin_ctz (n) : 8 * sizeof n; +} +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctzl (unsigned long int n) +{ + return n ? __builtin_ctzl (n) : 8 * sizeof n; +} +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctzll (unsigned long long int n) +{ + return n ? __builtin_ctzll (n) : 8 * sizeof n; +} +# elif defined _MSC_VER + +/* Declare the few MSVC intrinsics that we need. We prefer not to include + <intrin.h> because it would pollute the namespace. */ +extern unsigned char _BitScanForward (unsigned long *, unsigned long); +# pragma intrinsic (_BitScanForward) +# ifdef _M_X64 +extern unsigned char _BitScanForward64 (unsigned long *, unsigned long long); +# pragma intrinsic (_BitScanForward64) +# endif + +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctzl (unsigned long int n) +{ + unsigned long int r; + return _BitScanForward (&r, n) ? r : 8 * sizeof n; +} +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctz (unsigned int n) +{ + return _gl_stdbit_ctzl (n | (1ul << (8 * sizeof n - 1) << 1)); +} +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctzll (unsigned long long int n) +{ +# ifdef _M_X64 + unsigned long int r; + return _BitScanForward64 (&r, n) ? r : 8 * sizeof n; +# else + unsigned int lo = n; + return _gl_stdbit_ctzl (lo ? lo : n >> 32) + (lo ? 0 : 32); +# endif +} + +# else /* !_MSC_VER */ + +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctz (unsigned int n) +{ + return 8 * sizeof n - (n ? _gl_stdbit_clz (n & -n) + 1 : 0); +} +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctzl (unsigned long int n) +{ + return 8 * sizeof n - (n ? _gl_stdbit_clzl (n & -n) + 1 : 0); +} +_GL_STDC_TRAILING_ZEROS_INLINE int +_gl_stdbit_ctzll (unsigned long long int n) +{ + return 8 * sizeof n - (n ? _gl_stdbit_clzll (n & -n) + 1 : 0); +} +# endif + +# define GNULIB_defined_ctz_functions 1 +# endif + +# if !GNULIB_defined_stdc_trailing_zeros_functions _GL_STDC_TRAILING_ZEROS_INLINE unsigned int stdc_trailing_zeros_ui (unsigned int n) { - return __gl_stdbit_ctz (n); + return _gl_stdbit_ctz (n); } _GL_STDC_TRAILING_ZEROS_INLINE unsigned int @@ -516,15 +513,18 @@ stdc_trailing_zeros_us (unsigned short int n) _GL_STDC_TRAILING_ZEROS_INLINE unsigned int stdc_trailing_zeros_ul (unsigned long int n) { - return __gl_stdbit_ctzl (n); + return _gl_stdbit_ctzl (n); } _GL_STDC_TRAILING_ZEROS_INLINE unsigned int stdc_trailing_zeros_ull (unsigned long long int n) { - return __gl_stdbit_ctzll (n); + return _gl_stdbit_ctzll (n); } +# define GNULIB_defined_stdc_trailing_zeros_functions 1 +# endif + # define stdc_trailing_zeros(n) \ (sizeof (n) == 1 ? stdc_trailing_zeros_uc (n) \ : sizeof (n) == sizeof (unsigned short int) ? stdc_trailing_zeros_us (n) \ @@ -537,7 +537,9 @@ stdc_trailing_zeros_ull (unsigned long long int n) /* ISO C 23 § 7.18.6 Count Trailing Ones */ -#if @GL_STDC_TRAILING_ONES@ +#if @GNULIB_STDC_TRAILING_ONES@ + +# if !GNULIB_defined_stdc_trailing_ones_functions _GL_STDC_TRAILING_ONES_INLINE unsigned int stdc_trailing_ones_uc (unsigned char n) @@ -569,6 +571,9 @@ stdc_trailing_ones_ull (unsigned long long int n) return stdc_trailing_zeros_ull (~n); } +# define GNULIB_defined_stdc_trailing_ones_functions 1 +# endif + # define stdc_trailing_ones(n) \ (sizeof (n) == 1 ? stdc_trailing_ones_uc (n) \ : sizeof (n) == sizeof (unsigned short int) ? stdc_trailing_ones_us (n) \ @@ -581,7 +586,9 @@ stdc_trailing_ones_ull (unsigned long long int n) /* ISO C 23 § 7.18.7 First Leading Zero */ -#if @GL_STDC_FIRST_LEADING_ZERO@ +#if @GNULIB_STDC_FIRST_LEADING_ZERO@ + +# if !GNULIB_defined_stdc_first_leading_zero_functions _GL_STDC_FIRST_LEADING_ZERO_INLINE unsigned int stdc_first_leading_zero_uc (unsigned char n) @@ -623,6 +630,9 @@ stdc_first_leading_zero_ull (unsigned long long int n) return count % bits + (count < bits); } +# define GNULIB_defined_stdc_first_leading_zero_functions 1 +# endif + # define stdc_first_leading_zero(n) \ (sizeof (n) == 1 ? stdc_first_leading_zero_uc (n) \ : sizeof (n) == sizeof (unsigned short) ? stdc_first_leading_zero_us (n) \ @@ -635,7 +645,9 @@ stdc_first_leading_zero_ull (unsigned long long int n) /* ISO C 23 § 7.18.8 First Leading One */ -#if @GL_STDC_FIRST_LEADING_ONE@ +#if @GNULIB_STDC_FIRST_LEADING_ONE@ + +# if !GNULIB_defined_stdc_first_leading_one_functions _GL_STDC_FIRST_LEADING_ONE_INLINE unsigned int stdc_first_leading_one_uc (unsigned char n) @@ -677,6 +689,9 @@ stdc_first_leading_one_ull (unsigned long long int n) return count % bits + (count < bits); } +# define GNULIB_defined_stdc_first_leading_one_functions 1 +# endif + # define stdc_first_leading_one(n) \ (sizeof (n) == 1 ? stdc_first_leading_one_uc (n) \ : sizeof (n) == sizeof (unsigned short) ? stdc_first_leading_one_us (n) \ @@ -689,7 +704,9 @@ stdc_first_leading_one_ull (unsigned long long int n) /* ISO C 23 § 7.18.9 First Trailing Zero */ -#if @GL_STDC_FIRST_TRAILING_ZERO@ +#if @GNULIB_STDC_FIRST_TRAILING_ZERO@ + +# if !GNULIB_defined_stdc_first_trailing_zero_functions _GL_STDC_FIRST_TRAILING_ZERO_INLINE unsigned int stdc_first_trailing_zero_uc (unsigned char n) @@ -731,6 +748,9 @@ stdc_first_trailing_zero_ull (unsigned long long int n) return count % bits + (count < bits); } +# define GNULIB_defined_stdc_first_trailing_zero_functions 1 +# endif + # define stdc_first_trailing_zero(n) \ (sizeof (n) == 1 ? stdc_first_trailing_zero_uc (n) \ : sizeof (n) == sizeof (unsigned short) ? stdc_first_trailing_zero_us (n) \ @@ -743,7 +763,9 @@ stdc_first_trailing_zero_ull (unsigned long long int n) /* ISO C 23 § 7.18.10 First Trailing One */ -#if @GL_STDC_FIRST_TRAILING_ONE@ +#if @GNULIB_STDC_FIRST_TRAILING_ONE@ + +# if !GNULIB_defined_stdc_first_trailing_one_functions _GL_STDC_FIRST_TRAILING_ONE_INLINE unsigned int stdc_first_trailing_one_uc (unsigned char n) @@ -785,7 +807,10 @@ stdc_first_trailing_one_ull (unsigned long long int n) return count % bits + (count < bits); } -#define stdc_first_trailing_one(n) \ +# define GNULIB_defined_stdc_first_trailing_one_functions 1 +# endif + +# define stdc_first_trailing_one(n) \ (sizeof (n) == 1 ? stdc_first_trailing_one_uc (n) \ : sizeof (n) == sizeof (unsigned short) ? stdc_first_trailing_one_us (n) \ : sizeof (n) == sizeof 0u ? stdc_first_trailing_one_ui (n) \ @@ -797,12 +822,146 @@ stdc_first_trailing_one_ull (unsigned long long int n) /* ISO C 23 § 7.18.12 Count Ones */ -#if @GL_STDC_COUNT_ONES@ +#if @GNULIB_STDC_COUNT_ONES@ + +# if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) || 4 <= __clang_major__ +# define _GL_STDBIT_HAS_BUILTIN_POPCOUNT true +# elif defined __has_builtin +# if (__has_builtin (__builtin_popcount) \ + && __has_builtin (__builtin_popcountl) \ + && __has_builtin (__builtin_popcountll)) +# define _GL_STDBIT_HAS_BUILTIN_POPCOUNT true +# endif +# endif + +/* Count 1 bits in N. */ +# if !GNULIB_defined_popcount_functions +# ifdef _GL_STDBIT_HAS_BUILTIN_POPCOUNT +# define _gl_stdbit_popcount __builtin_popcount +# define _gl_stdbit_popcountl __builtin_popcountl +# define _gl_stdbit_popcountll __builtin_popcountll +# else +_GL_STDC_COUNT_ONES_INLINE int +_gl_stdbit_popcount_wide (unsigned long long int n) +{ + if (sizeof n & (sizeof n - 1)) + { + /* Use a simple O(log N) loop on theoretical platforms where N's + width is not a power of 2. */ + int count = 0; + for (int i = 0; i < 8 * sizeof n; i++, n >>= 1) + count += n & 1; + return count; + } + else + { + /* N's width is a power of 2; count in parallel. */ + unsigned long long int + max = -1ull, + x555555 = max / (1 << 1 | 1), /* 0x555555... */ + x333333 = max / (1 << 2 | 1), /* 0x333333... */ + x0f0f0f = max / (1 << 4 | 1), /* 0x0f0f0f... */ + x010101 = max / ((1 << 8) - 1), /* 0x010101... */ + x000_7f = max / 0xffffffffffffffffLL * 0x7f; /* 0x000000000000007f... */ + n -= (n >> 1) & x555555; + n = (n & x333333) + ((n >> 2) & x333333); + n = (n + (n >> 4)) & x0f0f0f; + + /* If the popcount always fits in 8 bits, multiply so that the + popcount is in the leading 8 bits of the product; these days + this is typically faster than the alternative below. */ + if (8 * sizeof n < 1 << 8) + return n * x010101 >> 8 * (sizeof n - 1); + + /* N is at least 256 bits wide! Fall back on an O(log log N) + loop that a compiler could unroll. Unroll the first three + iterations by hand, to skip some division and masking. This + is the most we can easily do without hassling with constants + that a typical-platform compiler would reject. */ + n += n >> (1 << 3); + n += n >> (1 << 4); + n += n >> (1 << 5); + n &= x000_7f; + for (int i = 64; i < 8 * sizeof n; i <<= 1) + n = (n + (n >> i)) & max / (1ull << i | 1); + return n; + } +} + +# ifdef _MSC_VER +# if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) +/* Declare the few MSVC intrinsics that we need. We prefer not to include + <intrin.h> because it would pollute the namespace. */ +extern void __cpuid (int[4], int); +# pragma intrinsic (__cpuid) +extern unsigned int __popcnt (unsigned int); +# pragma intrinsic (__popcnt) +# ifdef _M_X64 +extern unsigned long long __popcnt64 (unsigned long long); +# pragma intrinsic (__popcnt64) +# else +_GL_STDC_COUNT_ONES_INLINE int +__popcnt64 (unsigned long long int n) +{ + return __popcnt (n >> 32) + __popcnt (n); +} +# endif +# endif + +/* 1 if supported, -1 if not, 0 if unknown. */ +extern signed char _gl_stdbit_popcount_support; + +_GL_STDC_COUNT_ONES_INLINE bool +_gl_stdbit_popcount_supported (void) +{ + if (!_gl_stdbit_popcount_support) + { + /* Do as described in + <https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64> + Although Microsoft started requiring POPCNT in MS-Windows 11 24H2, + we'll be more cautious. */ + int cpu_info[4]; + __cpuid (cpu_info, 1); + _gl_stdbit_popcount_support = cpu_info[2] & 1 << 23 ? 1 : -1; + } + return 0 < _gl_stdbit_popcount_support; +} +_GL_STDC_COUNT_ONES_INLINE int +_gl_stdbit_popcount (unsigned int n) +{ + return (_gl_stdbit_popcount_supported () + ? __popcnt (n) + : _gl_stdbit_popcount_wide (n)); +} +_GL_STDC_COUNT_ONES_INLINE int +_gl_stdbit_popcountl (unsigned long int n) +{ + return (_gl_stdbit_popcount_supported () + ? __popcnt (n) + : _gl_stdbit_popcount_wide (n)); +} +_GL_STDC_COUNT_ONES_INLINE int +_gl_stdbit_popcountll (unsigned long long int n) +{ + return (_gl_stdbit_popcount_supported () + ? __popcnt64 (n) + : _gl_stdbit_popcount_wide (n)); +} +# else /* !_MSC_VER */ +# define _gl_stdbit_popcount _gl_stdbit_popcount_wide +# define _gl_stdbit_popcountl _gl_stdbit_popcount_wide +# define _gl_stdbit_popcountll _gl_stdbit_popcount_wide +# endif +# endif +# define GNULIB_defined_popcount_functions 1 +# endif + +# if !GNULIB_defined_stdc_count_ones_functions _GL_STDC_COUNT_ONES_INLINE unsigned int stdc_count_ones_ui (unsigned int n) { - return __gl_stdbit_popcount (n); + return _gl_stdbit_popcount (n); } _GL_STDC_COUNT_ONES_INLINE unsigned int @@ -820,15 +979,18 @@ stdc_count_ones_us (unsigned short int n) _GL_STDC_COUNT_ONES_INLINE unsigned int stdc_count_ones_ul (unsigned long int n) { - return __gl_stdbit_popcountl (n); + return _gl_stdbit_popcountl (n); } _GL_STDC_COUNT_ONES_INLINE unsigned int stdc_count_ones_ull (unsigned long long int n) { - return __gl_stdbit_popcountll (n); + return _gl_stdbit_popcountll (n); } +# define GNULIB_defined_stdc_count_ones_functions 1 +# endif + # define stdc_count_ones(n) \ (sizeof (n) == 1 ? stdc_count_ones_uc (n) \ : sizeof (n) == sizeof (unsigned short int) ? stdc_count_ones_us (n) \ @@ -841,7 +1003,9 @@ stdc_count_ones_ull (unsigned long long int n) /* ISO C 23 § 7.18.11 Count Zeros */ -#if @GL_STDC_COUNT_ZEROS@ +#if @GNULIB_STDC_COUNT_ZEROS@ + +# if !GNULIB_defined_stdc_count_zeros_functions _GL_STDC_COUNT_ZEROS_INLINE unsigned int stdc_count_zeros_uc (unsigned char n) @@ -873,6 +1037,9 @@ stdc_count_zeros_ull (unsigned long long int n) return stdc_count_ones_ull (~n); } +# define GNULIB_defined_stdc_count_zeros_functions 1 +# endif + # define stdc_count_zeros(n) \ (sizeof (n) == 1 ? stdc_count_zeros_uc (n) \ : sizeof (n) == sizeof (unsigned short int) ? stdc_count_zeros_us (n) \ @@ -885,7 +1052,9 @@ stdc_count_zeros_ull (unsigned long long int n) /* ISO C 23 § 7.18.13 Single-bit Check */ -#if @GL_STDC_HAS_SINGLE_BIT@ +#if @GNULIB_STDC_HAS_SINGLE_BIT@ + +# if !GNULIB_defined_stdc_has_single_bit_functions _GL_STDC_HAS_SINGLE_BIT_INLINE bool stdc_has_single_bit_uc (unsigned char n) @@ -922,6 +1091,9 @@ stdc_has_single_bit_ull (unsigned long long int n) return n_1 < nx; } +# define GNULIB_defined_stdc_has_single_bit_functions 1 +# endif + # define stdc_has_single_bit(n) \ ((bool) \ (sizeof (n) == 1 ? stdc_has_single_bit_uc (n) \ @@ -935,7 +1107,9 @@ stdc_has_single_bit_ull (unsigned long long int n) /* ISO C 23 § 7.18.14 Bit Width */ -#if @GL_STDC_BIT_WIDTH@ +#if @GNULIB_STDC_BIT_WIDTH@ + +# if !GNULIB_defined_stdc_bit_width_functions _GL_STDC_BIT_WIDTH_INLINE unsigned int stdc_bit_width_uc (unsigned char n) @@ -967,6 +1141,9 @@ stdc_bit_width_ull (unsigned long long int n) return 8 * sizeof n - stdc_leading_zeros_ull (n); } +# define GNULIB_defined_stdc_bit_width_functions 1 +# endif + # define stdc_bit_width(n) \ (sizeof (n) == 1 ? stdc_bit_width_uc (n) \ : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_width_us (n) \ @@ -976,10 +1153,15 @@ stdc_bit_width_ull (unsigned long long int n) #endif +#endif /* !__STDC_VERSION_STDBIT_H__ */ + /* ISO C 23 § 7.18.15 Bit Floor */ -#if @GL_STDC_BIT_FLOOR@ +#if @GNULIB_STDC_BIT_FLOOR@ + +# if !defined __STDC_VERSION_STDBIT_H__ +# if !GNULIB_defined_stdc_bit_floor_functions _GL_STDC_BIT_FLOOR_INLINE unsigned char stdc_bit_floor_uc (unsigned char n) @@ -1011,21 +1193,32 @@ stdc_bit_floor_ull (unsigned long long int n) return n ? 1ull << (stdc_bit_width_ull (n) - 1) : 0; } -# define stdc_bit_floor(n) \ - (_GL_STDBIT_TYPEOF_CAST \ - (n, \ - (sizeof (n) == 1 ? stdc_bit_floor_uc (n) \ - : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_floor_us (n) \ - : sizeof (n) == sizeof 0u ? stdc_bit_floor_ui (n) \ - : sizeof (n) == sizeof 0ul ? stdc_bit_floor_ul (n) \ - : stdc_bit_floor_ull (n)))) +# define GNULIB_defined_stdc_bit_floor_functions 1 +# endif +# endif + +# if !defined __STDC_VERSION_STDBIT_H__ \ + || (defined __sun && defined _SYS_STDBIT_H) +# undef stdc_bit_floor +# define stdc_bit_floor(n) \ + (_GL_STDBIT_TYPEOF_CAST \ + (n, \ + (sizeof (n) == 1 ? stdc_bit_floor_uc (n) \ + : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_floor_us (n) \ + : sizeof (n) == sizeof 0u ? stdc_bit_floor_ui (n) \ + : sizeof (n) == sizeof 0ul ? stdc_bit_floor_ul (n) \ + : stdc_bit_floor_ull (n)))) +# endif #endif /* ISO C 23 § 7.18.16 Bit Ceiling */ -#if @GL_STDC_BIT_CEIL@ +#if @GNULIB_STDC_BIT_CEIL@ + +# if !defined __STDC_VERSION_STDBIT_H__ +# if !GNULIB_defined_stdc_bit_ceil_functions _GL_STDC_BIT_CEIL_INLINE unsigned char stdc_bit_ceil_uc (unsigned char n) @@ -1057,14 +1250,962 @@ stdc_bit_ceil_ull (unsigned long long int n) return n <= 1 ? 1 : 2ull << (stdc_bit_width_ull (n - 1) - 1); } -# define stdc_bit_ceil(n) \ - (_GL_STDBIT_TYPEOF_CAST \ - (n, \ - (sizeof (n) == 1 ? stdc_bit_ceil_uc (n) \ - : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_ceil_us (n) \ - : sizeof (n) == sizeof 0u ? stdc_bit_ceil_ui (n) \ - : sizeof (n) == sizeof 0ul ? stdc_bit_ceil_ul (n) \ - : stdc_bit_ceil_ull (n)))) +# define GNULIB_defined_stdc_bit_ceil_functions 1 +# endif +# endif + +# if !defined __STDC_VERSION_STDBIT_H__ \ + || (defined __sun && defined _SYS_STDBIT_H) +# undef stdc_bit_ceil +# define stdc_bit_ceil(n) \ + (_GL_STDBIT_TYPEOF_CAST \ + (n, \ + (sizeof (n) == 1 ? stdc_bit_ceil_uc (n) \ + : sizeof (n) == sizeof (unsigned short int) ? stdc_bit_ceil_us (n) \ + : sizeof (n) == sizeof 0u ? stdc_bit_ceil_ui (n) \ + : sizeof (n) == sizeof 0ul ? stdc_bit_ceil_ul (n) \ + : stdc_bit_ceil_ull (n)))) +# endif + +#endif + + +/* ISO C2y § 7.18.17 Rotate Left */ + +#if @GNULIB_STDC_ROTATE_LEFT@ + +# ifdef __has_builtin +# if __has_builtin (__builtin_stdc_rotate_left) +# define _gl_stdc_rotate_left __builtin_stdc_rotate_left +# define stdc_rotate_left __builtin_stdc_rotate_left +# endif +# endif + +# ifndef _gl_stdc_rotate_left +# define _gl_stdc_rotate_left(v, c) \ + (((v) << ((c) & (sizeof (v) * 8 - 1))) \ + | ((v) >> (-(c) & (sizeof (v) * 8 - 1)))) +# endif + +# if !GNULIB_defined_stdc_rotate_left_functions + +_GL_STDC_ROTATE_LEFT_INLINE unsigned char +stdc_rotate_left_uc (unsigned char v, unsigned int c) +{ + return _gl_stdc_rotate_left (v, c); +} + +_GL_STDC_ROTATE_LEFT_INLINE unsigned short int +stdc_rotate_left_us (unsigned short int v, unsigned int c) +{ + return _gl_stdc_rotate_left (v, c); +} + +_GL_STDC_ROTATE_LEFT_INLINE unsigned int +stdc_rotate_left_ui (unsigned int v, unsigned int c) +{ + return _gl_stdc_rotate_left (v, c); +} + +_GL_STDC_ROTATE_LEFT_INLINE unsigned long int +stdc_rotate_left_ul (unsigned long int v, unsigned int c) +{ + return _gl_stdc_rotate_left (v, c); +} + +_GL_STDC_ROTATE_LEFT_INLINE unsigned long long int +stdc_rotate_left_ull (unsigned long long int v, unsigned int c) +{ + return _gl_stdc_rotate_left (v, c); +} + +# define GNULIB_defined_stdc_rotate_left_functions 1 +# endif + +# ifndef stdc_rotate_left +# define stdc_rotate_left(v, c) \ + (_GL_STDBIT_TYPEOF_CAST \ + (v, \ + (sizeof (v) == 1 ? stdc_rotate_left_uc (v, c) \ + : sizeof (v) == sizeof (unsigned short int) ? stdc_rotate_left_us (v, c) \ + : sizeof (v) == sizeof 0u ? stdc_rotate_left_ui (v, c) \ + : sizeof (v) == sizeof 0ul ? stdc_rotate_left_ul (v, c) \ + : stdc_rotate_left_ull (v, c)))) +# endif + +#endif + + +/* ISO C2y § 7.18.18 Rotate Right */ + +#if @GNULIB_STDC_ROTATE_RIGHT@ + +# ifdef __has_builtin +# if __has_builtin (__builtin_stdc_rotate_right) +# define _gl_stdc_rotate_right __builtin_stdc_rotate_right +# define stdc_rotate_right __builtin_stdc_rotate_right +# endif +# endif + +# ifndef _gl_stdc_rotate_right +# define _gl_stdc_rotate_right(v, c) \ + (((v) >> ((c) & (sizeof (v) * 8 - 1))) \ + | ((v) << (-(c) & (sizeof (v) * 8 - 1)))) +# endif + +# if !GNULIB_defined_stdc_rotate_right_functions + +_GL_STDC_ROTATE_RIGHT_INLINE unsigned char +stdc_rotate_right_uc (unsigned char v, unsigned int c) +{ + return _gl_stdc_rotate_right (v, c); +} + +_GL_STDC_ROTATE_RIGHT_INLINE unsigned short int +stdc_rotate_right_us (unsigned short int v, unsigned int c) +{ + return _gl_stdc_rotate_right (v, c); +} + +_GL_STDC_ROTATE_RIGHT_INLINE unsigned int +stdc_rotate_right_ui (unsigned int v, unsigned int c) +{ + return _gl_stdc_rotate_right (v, c); +} + +_GL_STDC_ROTATE_RIGHT_INLINE unsigned long int +stdc_rotate_right_ul (unsigned long int v, unsigned int c) +{ + return _gl_stdc_rotate_right (v, c); +} + +_GL_STDC_ROTATE_RIGHT_INLINE unsigned long long int +stdc_rotate_right_ull (unsigned long long int v, unsigned int c) +{ + return _gl_stdc_rotate_right (v, c); +} + +# define GNULIB_defined_stdc_rotate_right_functions 1 +# endif + +# ifndef stdc_rotate_right +# define stdc_rotate_right(v, c) \ + (_GL_STDBIT_TYPEOF_CAST \ + (v, \ + (sizeof (v) == 1 ? stdc_rotate_right_uc (v, c) \ + : sizeof (v) == sizeof (unsigned short int) ? stdc_rotate_right_us (v, c) \ + : sizeof (v) == sizeof 0u ? stdc_rotate_right_ui (v, c) \ + : sizeof (v) == sizeof 0ul ? stdc_rotate_right_ul (v, c) \ + : stdc_rotate_right_ull (v, c)))) +# endif + +#endif + + +/* ISO C2y § 7.18.19 8-bit Memory Reversal */ + +#if @GNULIB_STDC_MEMREVERSE8@ + +# if !GNULIB_defined_stdc_memreverse8 + +_GL_STDC_MEMREVERSE8_INLINE void +stdc_memreverse8 (size_t n, unsigned char *ptr) +{ + if (n > 0) + { + /* There is no need to optimize the cases N == 1, N == 2, N == 4 + specially using __builtin_constant_p, because GCC does the possible + optimizations already, taking into account the alignment of PTR: + GCC >= 3 for N == 1, GCC >= 8 for N == 2, GCC >= 13 for N == 4. + (Whereas clang >= 3, <= 22 optimizes only the case N == 1.) */ + size_t i, j; + for (i = 0, j = n-1; i < j; i++, j--) + { + unsigned char xi = ptr[i]; + unsigned char xj = ptr[j]; + ptr[j] = xi; + ptr[i] = xj; + } + } +} + +# define GNULIB_defined_stdc_memreverse8 1 +# endif + +#endif + + +/* ISO C2y § 7.18.20 Exact-width 8-bit Memory Reversal */ + +#if @GNULIB_STDC_MEMREVERSE8U@ + +/* Note: ISO C defines these functions with argument and return type uintN_t. + We do it here with argument and return type uint_leastN_t. This is a + generalization that does not contradict ISO C: When uintN_t exists, it is + known that uint_leastN_t is the same type as uintN_t. */ + +# if !GNULIB_defined_stdc_memreverse8u_functions + +_GL_STDC_MEMREVERSE8U_INLINE uint_least8_t +stdc_memreverse8u8 (uint_least8_t value) +{ + return value; +} + +_GL_STDC_MEMREVERSE8U_INLINE uint_least16_t +stdc_memreverse8u16 (uint_least16_t value) +{ +# ifdef _GL_STDBIT_HAS_BUILTIN_BSWAP16 + return __builtin_bswap16 (value); +# else + _GL_STDBIT_UINT_FAST16 mask = 0xFFU; + return ( (value & (mask << (8 * 1))) >> (8 * 1) + | (value & (mask << (8 * 0))) << (8 * 1)); +# endif +} + +_GL_STDC_MEMREVERSE8U_INLINE uint_least32_t +stdc_memreverse8u32 (uint_least32_t value) +{ +# ifdef _GL_STDBIT_HAS_BUILTIN_BSWAP32 + return __builtin_bswap32 (value); +# else + _GL_STDBIT_UINT_FAST32 mask = 0xFFU; + return ( (value & (mask << (8 * 3))) >> (8 * 3) + | (value & (mask << (8 * 2))) >> (8 * 1) + | (value & (mask << (8 * 1))) << (8 * 1) + | (value & (mask << (8 * 0))) << (8 * 3)); +# endif +} + +_GL_STDC_MEMREVERSE8U_INLINE uint_least64_t +stdc_memreverse8u64 (uint_least64_t value) +{ +# ifdef _GL_STDBIT_HAS_BUILTIN_BSWAP64 + return __builtin_bswap64 (value); +# else + _GL_STDBIT_UINT_FAST64 mask = 0xFFU; + return ( (value & (mask << (8 * 7))) >> (8 * 7) + | (value & (mask << (8 * 6))) >> (8 * 5) + | (value & (mask << (8 * 5))) >> (8 * 3) + | (value & (mask << (8 * 4))) >> (8 * 1) + | (value & (mask << (8 * 3))) << (8 * 1) + | (value & (mask << (8 * 2))) << (8 * 3) + | (value & (mask << (8 * 1))) << (8 * 5) + | (value & (mask << (8 * 0))) << (8 * 7)); +# endif +} + +# define GNULIB_defined_stdc_memreverse8u_functions 1 +# endif + +#endif + + +/* ISO C2y § 7.18.21 Endian-Aware 8-Bit Load */ + +/* On hosts where _GL_STDBIT_OPTIMIZE_VIA_MEMCPY (see below) might be useful, + we need to avoid type-punning, because the compiler's aliasing + analysis would frequently produce incorrect code, and requiring the + option '-fno-strict-aliasing' is no viable solution. + So, this definition won't work: + + uint_least16_t + load16 (const unsigned char ptr[2]) + { + return *(const uint_least16_t *)ptr; + } + + Instead, the following definitions are candidates: + + // Trick from Lasse Collin: use memcpy and __builtin_assume_aligned. + uint_least16_t + load16_a (const unsigned char ptr[2]) + { + uint_least16_t value; + memcpy (&value, __builtin_assume_aligned (ptr, 2), 2); + return value; + } + + // Use __builtin_assume_aligned, without memcpy. + uint_least16_t + load16_b (const unsigned char ptr[2]) + { + const unsigned char *aptr = + (const unsigned char *) __builtin_assume_aligned (ptr, 2); + return (_GL_STDBIT_BIGENDIAN + ? ((uint_least16_t) aptr [0] << 8) | (uint_least16_t) aptr [1] + : (uint_least16_t) aptr [0] | ((uint_least16_t) aptr [1] << 8)); + } + + // Use memcpy and __assume. + uint_least16_t + load16_c (const unsigned char ptr[2]) + { + __assume (((uintptr_t) ptr & (2 - 1)) == 0); + uint_least16_t value; + memcpy (&value, __builtin_assume_aligned (ptr, 2), 2); + return value; + } + + // Use __assume, without memcpy. + uint_least16_t + load16_d (const unsigned char ptr[2]) + { + __assume (((uintptr_t) ptr & (2 - 1)) == 0); + return (_GL_STDBIT_BIGENDIAN + ? ((uint_least16_t) ptr [0] << 8) | (uint_least16_t) ptr [1] + : (uint_least16_t) ptr [0] | ((uint_least16_t) ptr [1] << 8)); + } + + // Use memcpy, without __builtin_assume_aligned or __assume. + uint_least16_t + load16_e (const unsigned char ptr[2]) + { + uint_least16_t value; + memcpy (&value, ptr, 2); + return value; + } + + // Use the code for the unaligned case. + uint_least16_t + load16_f (const unsigned char ptr[2]) + { + return (_GL_STDBIT_BIGENDIAN + ? ((uint_least16_t) ptr [0] << 8) | (uint_least16_t) ptr [1] + : (uint_least16_t) ptr [0] | ((uint_least16_t) ptr [1] << 8)); + } + + Portability constraints: + - __builtin_assume_aligned works only in GCC >= 4.7 and clang >= 4. + - __assume works only with MSVC (_MSC_VER >= 1200). + + Which variant produces the best code? + - memcpy is inlined only in gcc >= 3.4, g++ >= 4.9, clang >= 4. + - MSVC's __assume has no effect. + - With gcc 13: + On armelhf, arm64, i686, powerpc, powerpc64, powerpc64le, s390x, x86_64: + All of a,b,e,f are equally good. + On alpha, arm, hppa, mips, mips64, riscv64, sh4, sparc64: + Only a,b are good; f medium; e worst. + - With older gcc versions on x86_64: + gcc >= 10: All of a,b,e,f are equally good. + gcc < 10: Only a,e are good; b,f medium. + - With MSVC 14: Only c,e are good; d,f medium. + + So, we use the following heuristic for getting good code: + - gcc >= 4.7, g++ >= 4.9, clang >= 4, or any other platform + with __builtin_assume_aligned: Use variant a. + - MSVC: Use variant e. + - Otherwise: Use variant f. + */ +#if (defined __clang__ ? __clang_major__ >= 4 : \ + (defined __GNUC__ \ + && (defined __cplusplus \ + ? __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 \ + : __GNUC__ + (__GNUC_MINOR__ >= 7) > 4))) +# define _GL_HAS_BUILTIN_ASSUME_ALIGNED 1 +#elif defined __has_builtin +# if __has_builtin (__builtin_assume_aligned) +# define _GL_HAS_BUILTIN_ASSUME_ALIGNED 1 +# endif +#endif +#ifdef _GL_HAS_BUILTIN_ASSUME_ALIGNED +# define _GL_STDBIT_ASSUME_ALIGNED(ptr, align) \ + __builtin_assume_aligned (ptr, align) +#else +# define _GL_STDBIT_ASSUME_ALIGNED(ptr, align) (ptr) +#endif + +#if defined _GL_HAS_BUILTIN_ASSUME_ALIGNED || defined _MSC_VER +/* The _GL_STDBIT_OPTIMIZE_VIA_MEMCPY trick works on typical hosts + where CHAR_BIT == 8 and uint_leastN_t types have minimal sizes. + Check to be safe and to document the assumption. */ +# define _GL_STDBIT_OPTIMIZE_VIA_MEMCPY \ + ((unsigned char) -1 == 0xFF \ + && sizeof (uint_least16_t) == 2 \ + && sizeof (uint_least32_t) == 4 \ + && sizeof (uint_least64_t) == 8) +#endif + +#ifndef _GL_STDBIT_OPTIMIZE_VIA_MEMCPY +# define _GL_STDBIT_OPTIMIZE_VIA_MEMCPY 0 +#endif + +#define _GL_STDBIT_BIGENDIAN (__STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_BIG__) + +#if @GNULIB_STDC_LOAD8@ + +# if !GNULIB_defined_stdc_load8_functions + +_GL_STDC_LOAD8_INLINE uint_least8_t +stdc_load8_beu8 (const unsigned char ptr[1]) +{ + return ptr[0]; +} + +_GL_STDC_LOAD8_INLINE uint_least16_t +stdc_load8_beu16 (const unsigned char ptr[2]) +{ + _GL_STDBIT_UINT_FAST16 v0 = ptr[0]; + _GL_STDBIT_UINT_FAST16 v1 = ptr[1]; + return (v0 << (8 * 1)) | (v1 << (8 * 0)); +} + +_GL_STDC_LOAD8_INLINE uint_least32_t +stdc_load8_beu32 (const unsigned char ptr[4]) +{ + _GL_STDBIT_UINT_FAST32 v0 = ptr[0]; + _GL_STDBIT_UINT_FAST32 v1 = ptr[1]; + _GL_STDBIT_UINT_FAST32 v2 = ptr[2]; + _GL_STDBIT_UINT_FAST32 v3 = ptr[3]; + return (v0 << (8 * 3)) | (v1 << (8 * 2)) | (v2 << (8 * 1)) | (v3 << (8 * 0)); +} + +_GL_STDC_LOAD8_INLINE uint_least64_t +stdc_load8_beu64 (const unsigned char ptr[8]) +{ + _GL_STDBIT_UINT_FAST64 v0 = ptr[0]; + _GL_STDBIT_UINT_FAST64 v1 = ptr[1]; + _GL_STDBIT_UINT_FAST64 v2 = ptr[2]; + _GL_STDBIT_UINT_FAST64 v3 = ptr[3]; + _GL_STDBIT_UINT_FAST64 v4 = ptr[4]; + _GL_STDBIT_UINT_FAST64 v5 = ptr[5]; + _GL_STDBIT_UINT_FAST64 v6 = ptr[6]; + _GL_STDBIT_UINT_FAST64 v7 = ptr[7]; + return ((v0 << (8 * 7)) | (v1 << (8 * 6)) + | (v2 << (8 * 5)) | (v3 << (8 * 4)) + | (v4 << (8 * 3)) | (v5 << (8 * 2)) + | (v6 << (8 * 1)) | (v7 << (8 * 0))); +} + +_GL_STDC_LOAD8_INLINE uint_least8_t +stdc_load8_leu8 (const unsigned char ptr[1]) +{ + return ptr[0]; +} + +_GL_STDC_LOAD8_INLINE uint_least16_t +stdc_load8_leu16 (const unsigned char ptr[2]) +{ + _GL_STDBIT_UINT_FAST16 v0 = ptr[0]; + _GL_STDBIT_UINT_FAST16 v1 = ptr[1]; + return (v0 << (8 * 0)) | (v1 << (8 * 1)); +} + +_GL_STDC_LOAD8_INLINE uint_least32_t +stdc_load8_leu32 (const unsigned char ptr[4]) +{ + _GL_STDBIT_UINT_FAST32 v0 = ptr[0]; + _GL_STDBIT_UINT_FAST32 v1 = ptr[1]; + _GL_STDBIT_UINT_FAST32 v2 = ptr[2]; + _GL_STDBIT_UINT_FAST32 v3 = ptr[3]; + return (v0 << (8 * 0)) | (v1 << (8 * 1)) | (v2 << (8 * 2)) | (v3 << (8 * 3)); +} + +_GL_STDC_LOAD8_INLINE uint_least64_t +stdc_load8_leu64 (const unsigned char ptr[8]) +{ + _GL_STDBIT_UINT_FAST64 v0 = ptr[0]; + _GL_STDBIT_UINT_FAST64 v1 = ptr[1]; + _GL_STDBIT_UINT_FAST64 v2 = ptr[2]; + _GL_STDBIT_UINT_FAST64 v3 = ptr[3]; + _GL_STDBIT_UINT_FAST64 v4 = ptr[4]; + _GL_STDBIT_UINT_FAST64 v5 = ptr[5]; + _GL_STDBIT_UINT_FAST64 v6 = ptr[6]; + _GL_STDBIT_UINT_FAST64 v7 = ptr[7]; + return ((v0 << (8 * 0)) | (v1 << (8 * 1)) + | (v2 << (8 * 2)) | (v3 << (8 * 3)) + | (v4 << (8 * 4)) | (v5 << (8 * 5)) + | (v6 << (8 * 6)) | (v7 << (8 * 7))); +} + +_GL_STDC_LOAD8_INLINE int_least8_t +stdc_load8_bes8 (const unsigned char ptr[1]) +{ + return stdc_load8_beu8 (ptr); +} + +_GL_STDC_LOAD8_INLINE int_least16_t +stdc_load8_bes16 (const unsigned char ptr[2]) +{ + return stdc_load8_beu16 (ptr); +} + +_GL_STDC_LOAD8_INLINE int_least32_t +stdc_load8_bes32 (const unsigned char ptr[4]) +{ + return stdc_load8_beu32 (ptr); +} + +_GL_STDC_LOAD8_INLINE int_least64_t +stdc_load8_bes64 (const unsigned char ptr[8]) +{ + return stdc_load8_beu64 (ptr); +} + +_GL_STDC_LOAD8_INLINE int_least8_t +stdc_load8_les8 (const unsigned char ptr[1]) +{ + return stdc_load8_leu8 (ptr); +} + +_GL_STDC_LOAD8_INLINE int_least16_t +stdc_load8_les16 (const unsigned char ptr[2]) +{ + return stdc_load8_leu16 (ptr); +} + +_GL_STDC_LOAD8_INLINE int_least32_t +stdc_load8_les32 (const unsigned char ptr[4]) +{ + return stdc_load8_leu32 (ptr); +} + +_GL_STDC_LOAD8_INLINE int_least64_t +stdc_load8_les64 (const unsigned char ptr[8]) +{ + return stdc_load8_leu64 (ptr); +} + +# define GNULIB_defined_stdc_load8_functions 1 +# endif + +#endif + +#if @GNULIB_STDC_LOAD8_ALIGNED@ + +# if !GNULIB_defined_stdc_load8_aligned_functions + +_GL_STDC_LOAD8_ALIGNED_INLINE uint_least8_t +stdc_load8_aligned_beu8 (const unsigned char ptr[1]) +{ + return stdc_load8_beu8 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE uint_least16_t +stdc_load8_aligned_beu16 (const unsigned char ptr[2]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + uint_least16_t value; + _GL_STDBIT_MEMCPY (&value, _GL_STDBIT_ASSUME_ALIGNED (ptr, 2), 2); + if (!_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u16 (value); + return value; + } + else + return stdc_load8_beu16 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE uint_least32_t +stdc_load8_aligned_beu32 (const unsigned char ptr[4]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + uint_least32_t value; + _GL_STDBIT_MEMCPY (&value, _GL_STDBIT_ASSUME_ALIGNED (ptr, 4), 4); + if (!_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u32 (value); + return value; + } + else + return stdc_load8_beu32 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE uint_least64_t +stdc_load8_aligned_beu64 (const unsigned char ptr[8]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + uint_least64_t value; + _GL_STDBIT_MEMCPY (&value, _GL_STDBIT_ASSUME_ALIGNED (ptr, 8), 8); + if (!_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u64 (value); + return value; + } + else + return stdc_load8_beu64 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE uint_least8_t +stdc_load8_aligned_leu8 (const unsigned char ptr[1]) +{ + return stdc_load8_leu8 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE uint_least16_t +stdc_load8_aligned_leu16 (const unsigned char ptr[2]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + uint_least16_t value; + _GL_STDBIT_MEMCPY (&value, _GL_STDBIT_ASSUME_ALIGNED (ptr, 2), 2); + if (_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u16 (value); + return value; + } + else + return stdc_load8_leu16 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE uint_least32_t +stdc_load8_aligned_leu32 (const unsigned char ptr[4]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + uint_least32_t value; + _GL_STDBIT_MEMCPY (&value, _GL_STDBIT_ASSUME_ALIGNED (ptr, 4), 4); + if (_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u32 (value); + return value; + } + else + return stdc_load8_leu32 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE uint_least64_t +stdc_load8_aligned_leu64 (const unsigned char ptr[8]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + uint_least64_t value; + _GL_STDBIT_MEMCPY (&value, _GL_STDBIT_ASSUME_ALIGNED (ptr, 8), 8); + if (_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u64 (value); + return value; + } + else + return stdc_load8_leu64 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE int_least8_t +stdc_load8_aligned_bes8 (const unsigned char ptr[1]) +{ + return stdc_load8_aligned_beu8 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE int_least16_t +stdc_load8_aligned_bes16 (const unsigned char ptr[2]) +{ + return stdc_load8_aligned_beu16 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE int_least32_t +stdc_load8_aligned_bes32 (const unsigned char ptr[4]) +{ + return stdc_load8_aligned_beu32 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE int_least64_t +stdc_load8_aligned_bes64 (const unsigned char ptr[8]) +{ + return stdc_load8_aligned_beu64 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE int_least8_t +stdc_load8_aligned_les8 (const unsigned char ptr[1]) +{ + return stdc_load8_aligned_leu8 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE int_least16_t +stdc_load8_aligned_les16 (const unsigned char ptr[2]) +{ + return stdc_load8_aligned_leu16 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE int_least32_t +stdc_load8_aligned_les32 (const unsigned char ptr[4]) +{ + return stdc_load8_aligned_leu32 (ptr); +} + +_GL_STDC_LOAD8_ALIGNED_INLINE int_least64_t +stdc_load8_aligned_les64 (const unsigned char ptr[8]) +{ + return stdc_load8_aligned_leu64 (ptr); +} + +# define GNULIB_defined_stdc_load8_aligned_functions 1 +# endif + +#endif + + +/* ISO C2y § 7.18.22 Endian-Aware 8-Bit Store */ + +#if @GNULIB_STDC_STORE8@ + +# if !GNULIB_defined_stdc_store8_functions + +_GL_STDC_STORE8_INLINE void +stdc_store8_beu8 (uint_least8_t value, unsigned char ptr[1]) +{ + ptr[0] = value; +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_beu16 (uint_least16_t value, unsigned char ptr[2]) +{ + ptr[0] = (value >> 8) & 0xFFU; + ptr[1] = value & 0xFFU; +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_beu32 (uint_least32_t value, unsigned char ptr[4]) +{ + ptr[0] = (value >> 24) & 0xFFU; + ptr[1] = (value >> 16) & 0xFFU; + ptr[2] = (value >> 8) & 0xFFU; + ptr[3] = value & 0xFFU; +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_beu64 (uint_least64_t value, unsigned char ptr[8]) +{ + ptr[0] = (value >> 56) & 0xFFU; + ptr[1] = (value >> 48) & 0xFFU; + ptr[2] = (value >> 40) & 0xFFU; + ptr[3] = (value >> 32) & 0xFFU; + ptr[4] = (value >> 24) & 0xFFU; + ptr[5] = (value >> 16) & 0xFFU; + ptr[6] = (value >> 8) & 0xFFU; + ptr[7] = value & 0xFFU; +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_leu8 (uint_least8_t value, unsigned char ptr[1]) +{ + ptr[0] = value; +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_leu16 (uint_least16_t value, unsigned char ptr[2]) +{ + ptr[0] = value & 0xFFU; + ptr[1] = (value >> 8) & 0xFFU; +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_leu32 (uint_least32_t value, unsigned char ptr[4]) +{ + ptr[0] = value & 0xFFU; + ptr[1] = (value >> 8) & 0xFFU; + ptr[2] = (value >> 16) & 0xFFU; + ptr[3] = (value >> 24) & 0xFFU; +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_leu64 (uint_least64_t value, unsigned char ptr[8]) +{ + ptr[0] = value & 0xFFU; + ptr[1] = (value >> 8) & 0xFFU; + ptr[2] = (value >> 16) & 0xFFU; + ptr[3] = (value >> 24) & 0xFFU; + ptr[4] = (value >> 32) & 0xFFU; + ptr[5] = (value >> 40) & 0xFFU; + ptr[6] = (value >> 48) & 0xFFU; + ptr[7] = (value >> 56) & 0xFFU; +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_bes8 (int_least8_t value, unsigned char ptr[1]) +{ + stdc_store8_beu8 (value, ptr); +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_bes16 (int_least16_t value, unsigned char ptr[2]) +{ + stdc_store8_beu16 (value, ptr); +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_bes32 (int_least32_t value, unsigned char ptr[4]) +{ + stdc_store8_beu32 (value, ptr); +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_bes64 (int_least64_t value, unsigned char ptr[8]) +{ + stdc_store8_beu64 (value, ptr); +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_les8 (int_least8_t value, unsigned char ptr[1]) +{ + stdc_store8_leu8 (value, ptr); +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_les16 (int_least16_t value, unsigned char ptr[2]) +{ + stdc_store8_leu16 (value, ptr); +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_les32 (int_least32_t value, unsigned char ptr[4]) +{ + stdc_store8_leu32 (value, ptr); +} + +_GL_STDC_STORE8_INLINE void +stdc_store8_les64 (int_least64_t value, unsigned char ptr[8]) +{ + stdc_store8_leu64 (value, ptr); +} + +# define GNULIB_defined_stdc_store8_functions 1 +# endif + +#endif + +#if @GNULIB_STDC_STORE8_ALIGNED@ + +# if !GNULIB_defined_stdc_store8_aligned_functions + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_beu8 (uint_least8_t value, unsigned char ptr[1]) +{ + stdc_store8_beu8 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_beu16 (uint_least16_t value, unsigned char ptr[2]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + if (!_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u16 (value); + _GL_STDBIT_MEMCPY (_GL_STDBIT_ASSUME_ALIGNED (ptr, 2), &value, 2); + } + else + stdc_store8_beu16 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_beu32 (uint_least32_t value, unsigned char ptr[4]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + if (!_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u32 (value); + _GL_STDBIT_MEMCPY (_GL_STDBIT_ASSUME_ALIGNED (ptr, 4), &value, 4); + } + else + stdc_store8_beu32 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_beu64 (uint_least64_t value, unsigned char ptr[8]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + if (!_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u64 (value); + _GL_STDBIT_MEMCPY (_GL_STDBIT_ASSUME_ALIGNED (ptr, 8), &value, 8); + } + else + stdc_store8_beu64 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_leu8 (uint_least8_t value, unsigned char ptr[1]) +{ + stdc_store8_leu8 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_leu16 (uint_least16_t value, unsigned char ptr[2]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + if (_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u16 (value); + _GL_STDBIT_MEMCPY (_GL_STDBIT_ASSUME_ALIGNED (ptr, 2), &value, 2); + } + else + stdc_store8_leu16 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_leu32 (uint_least32_t value, unsigned char ptr[4]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + if (_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u32 (value); + _GL_STDBIT_MEMCPY (_GL_STDBIT_ASSUME_ALIGNED (ptr, 4), &value, 4); + } + else + stdc_store8_leu32 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_leu64 (uint_least64_t value, unsigned char ptr[8]) +{ + if (_GL_STDBIT_OPTIMIZE_VIA_MEMCPY) + { + if (_GL_STDBIT_BIGENDIAN) + value = stdc_memreverse8u64 (value); + _GL_STDBIT_MEMCPY (_GL_STDBIT_ASSUME_ALIGNED (ptr, 8), &value, 8); + } + else + stdc_store8_leu64 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_bes8 (int_least8_t value, unsigned char ptr[1]) +{ + stdc_store8_aligned_beu8 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_bes16 (int_least16_t value, unsigned char ptr[2]) +{ + stdc_store8_aligned_beu16 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_bes32 (int_least32_t value, unsigned char ptr[4]) +{ + stdc_store8_aligned_beu32 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_bes64 (int_least64_t value, unsigned char ptr[8]) +{ + stdc_store8_aligned_beu64 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_les8 (int_least8_t value, unsigned char ptr[1]) +{ + stdc_store8_aligned_leu8 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_les16 (int_least16_t value, unsigned char ptr[2]) +{ + stdc_store8_aligned_leu16 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_les32 (int_least32_t value, unsigned char ptr[4]) +{ + stdc_store8_aligned_leu32 (value, ptr); +} + +_GL_STDC_STORE8_ALIGNED_INLINE void +stdc_store8_aligned_les64 (int_least64_t value, unsigned char ptr[8]) +{ + stdc_store8_aligned_leu64 (value, ptr); +} + +# define GNULIB_defined_stdc_store8_aligned_functions 1 +# endif #endif @@ -1075,4 +2216,10 @@ stdc_bit_ceil_ull (unsigned long long int n) _GL_INLINE_HEADER_END -#endif /* STDBIT_H */ +/* ISO C 23 § 7.18.1 General */ +#ifndef __STDC_VERSION_STDBIT_H__ +# define __STDC_VERSION_STDBIT_H__ 202311L +#endif + +#endif /* _@GUARD_PREFIX@_STDBIT_H */ +#endif /* _@GUARD_PREFIX@_STDBIT_H */ diff --git a/lib/stdc_count_ones.c b/lib/stdc_count_ones.c index bcb4d6c2965..1a75445c827 100644 --- a/lib/stdc_count_ones.c +++ b/lib/stdc_count_ones.c @@ -19,5 +19,5 @@ #include <stdbit.h> #if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) -signed char __gl_stdbit_popcount_support; +signed char _gl_stdbit_popcount_support; #endif diff --git a/lib/stdc_memreverse8u.c b/lib/stdc_memreverse8u.c new file mode 100644 index 00000000000..ec83306dfff --- /dev/null +++ b/lib/stdc_memreverse8u.c @@ -0,0 +1,19 @@ +/* stdc_memreverse8u* functions. + Copyright (C) 2026 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +#define _GL_STDC_MEMREVERSE8U_INLINE _GL_EXTERN_INLINE +#include <config.h> +#include <stdbit.h> diff --git a/lib/stdcountof.in.h b/lib/stdcountof.in.h new file mode 100644 index 00000000000..c2de1adce8b --- /dev/null +++ b/lib/stdcountof.in.h @@ -0,0 +1,124 @@ +/* Copyright 2025-2026 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2025. */ + +#ifndef _@GUARD_PREFIX@_STDCOUNTOF_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if (defined __cplusplus ? @CXX_HAVE_STDCOUNTOF_H@ : @HAVE_STDCOUNTOF_H@) +# @INCLUDE_NEXT@ @NEXT_STDCOUNTOF_H@ +#else + +#ifndef _@GUARD_PREFIX@_STDCOUNTOF_H +#define _@GUARD_PREFIX@_STDCOUNTOF_H + +/* This file uses _GL_GNUC_PREREQ. */ +#if !_GL_CONFIG_H_INCLUDED + #error "Please include config.h first." +#endif + +/* Get size_t. */ +#include <stddef.h> + +/* Returns the number of elements of the array A, as a value of type size_t. + + Example declarations of arrays: + extern int a[]; + extern int a[10]; + static int a[10][20]; + void func () { int a[10]; ... } + It works for arrays that are declared outside functions and for local + variables of array type. It does *not* work for function parameters + of array type, because they are actually parameters of pointer type. + In this case, i.e. if A is a pointer, e.g. in + void func (int a[10]) { ... } + this macro attempts to produce an error. + */ +#define countof(...) \ + ((size_t) (sizeof (__VA_ARGS__) / sizeof (__VA_ARGS__)[0] \ + + 0 * _gl_verify_is_array (__VA_ARGS__))) + +/* Attempts to verify that A is an array. */ +#if defined __cplusplus +/* Borrowed from verify.h. */ +# if !GNULIB_defined_struct__gl_verify_type +template <int w> + struct _gl_verify_type { + unsigned int _gl_verify_error_if_negative: w; + }; +# define GNULIB_defined_struct__gl_verify_type 1 +# endif +# if __cplusplus >= 201103L +# if 1 + /* Use decltype. */ +/* Default case. */ +template <typename T> + struct _gl_array_type_test { static const int is_array = -1; }; +/* Unbounded arrays. */ +template <typename T> + struct _gl_array_type_test<T[]> { static const int is_array = 1; }; +/* Bounded arrays. */ +template <typename T, size_t N> + struct _gl_array_type_test<T[N]> { static const int is_array = 1; }; +/* String literals. */ +template <typename T, size_t N> + struct _gl_array_type_test<T const (&)[N]> { static const int is_array = 1; }; +# define _gl_verify_is_array(...) \ + sizeof (_gl_verify_type<_gl_array_type_test<decltype(__VA_ARGS__)>::is_array>) +# else + /* Use template argument deduction. + Use sizeof to get a constant expression from an unknown type. + Note: This approach does not work for countof (((int[]) { a, b, c })). */ +/* Default case. */ +template <typename T> + struct _gl_array_type_test { double large; }; +/* Unbounded arrays. */ +template <typename T> + struct _gl_array_type_test<T[]> { char small; }; +/* Bounded arrays. */ +template <typename T, size_t N> + struct _gl_array_type_test<T[N]> { char small; }; +/* The T& parameter is essential here: it prevents decay (array-to-pointer + conversion). */ +template <typename T> _gl_array_type_test<T> _gl_array_type_test_helper(T&); +# define _gl_verify_is_array(...) \ + sizeof (_gl_verify_type<(sizeof (_gl_array_type_test_helper(__VA_ARGS__)) < sizeof (double) ? 1 : -1)>) +# endif +# else +/* The compiler does not have the necessary functionality. */ +# define _gl_verify_is_array(...) 0 +# endif +#else +/* In C, we can use typeof and __builtin_types_compatible_p. */ +/* Work around clang bug <https://github.com/llvm/llvm-project/issues/143284>. */ +# if (_GL_GNUC_PREREQ (3, 1) && ! defined __clang__ /* || defined __clang__ */) \ + && !(defined __STRICT_ANSI__ && __STDC_VERSION__ < 202311L) /* but not with -std=c99 or -std=c11 */ +# define _gl_verify_is_array(...) \ + sizeof (struct { unsigned int _gl_verify_error_if_negative : __builtin_types_compatible_p (typeof (__VA_ARGS__), typeof (&*(__VA_ARGS__))) ? -1 : 1; }) +# else +/* The compiler does not have the necessary built-ins. */ +# define _gl_verify_is_array(...) 0 +# endif +#endif + +#endif /* _@GUARD_PREFIX@_STDCOUNTOF_H */ +#endif +#endif /* _@GUARD_PREFIX@_STDCOUNTOF_H */ diff --git a/lib/stdio-consolesafe.c b/lib/stdio-consolesafe.c index f634de13ef4..3d913d555e8 100644 --- a/lib/stdio-consolesafe.c +++ b/lib/stdio-consolesafe.c @@ -56,7 +56,7 @@ workaround_fwrite0 (char *s, size_t n, FILE *fp) } size_t -gl_consolesafe_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *fp) +_gl_consolesafe_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *fp) { size_t nbytes; if (ckd_mul (&nbytes, size, nmemb) || nbytes == 0) @@ -133,7 +133,7 @@ local_vasprintf (char **resultp, const char *format, va_list args) __mingw_*printf. */ int -gl_consolesafe_fprintf (FILE *restrict fp, const char *restrict format, ...) +_gl_consolesafe_fprintf (FILE *restrict fp, const char *restrict format, ...) { va_list args; va_start (args, format); @@ -151,7 +151,7 @@ gl_consolesafe_fprintf (FILE *restrict fp, const char *restrict format, ...) } int -gl_consolesafe_printf (const char *restrict format, ...) +_gl_consolesafe_printf (const char *restrict format, ...) { va_list args; va_start (args, format); @@ -169,8 +169,8 @@ gl_consolesafe_printf (const char *restrict format, ...) } int -gl_consolesafe_vfprintf (FILE *restrict fp, - const char *restrict format, va_list args) +_gl_consolesafe_vfprintf (FILE *restrict fp, + const char *restrict format, va_list args) { char *tmpstring; int result = vasprintf (&tmpstring, format, args); @@ -185,7 +185,7 @@ gl_consolesafe_vfprintf (FILE *restrict fp, } int -gl_consolesafe_vprintf (const char *restrict format, va_list args) +_gl_consolesafe_vprintf (const char *restrict format, va_list args) { char *tmpstring; int result = vasprintf (&tmpstring, format, args); diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 33b0b8e48a5..107ebd6df13 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -122,6 +122,20 @@ # endif #endif +/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that + can be freed via 'free'; it can be used only after declaring 'free'. */ +/* Applies to: functions. Cannot be used on inline functions. */ +#ifndef _GL_ATTRIBUTE_DEALLOC_FREE +# if defined __cplusplus && defined __GNUC__ && !defined __clang__ +/* Work around GCC bug <https://gcc.gnu.org/PR108231> */ +# define _GL_ATTRIBUTE_DEALLOC_FREE \ + _GL_ATTRIBUTE_DEALLOC ((void (*) (void *)) free, 1) +# else +# define _GL_ATTRIBUTE_DEALLOC_FREE \ + _GL_ATTRIBUTE_DEALLOC (free, 1) +# endif +#endif + /* The __attribute__ feature is available in gcc versions 2.5 and later. The __-protected variants of the attributes 'format' and 'printf' are accepted by gcc versions 2.6.4 (effectively 2.7) and later. @@ -231,6 +245,50 @@ /* The definition of _GL_WARN_ON_USE is copied here. */ +/* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though <stdlib.h> may not have + been included yet. */ +#if @GNULIB_FREE_POSIX@ +# if (@REPLACE_FREE@ && !defined free \ + && !(defined __cplusplus && defined GNULIB_NAMESPACE)) +/* We can't do '#define free rpl_free' here. */ +# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) +_GL_EXTERN_C void rpl_free (void *) _GL_ATTRIBUTE_NOTHROW; +# else +_GL_EXTERN_C void rpl_free (void *); +# endif +# undef _GL_ATTRIBUTE_DEALLOC_FREE +# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1) +# else +# if defined _MSC_VER && !defined free +_GL_EXTERN_C +# if defined _DLL + __declspec (dllimport) +# endif + void __cdecl free (void *); +# else +# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) +_GL_EXTERN_C void free (void *) _GL_ATTRIBUTE_NOTHROW; +# else +_GL_EXTERN_C void free (void *); +# endif +# endif +# endif +#else +# if defined _MSC_VER && !defined free +_GL_EXTERN_C +# if defined _DLL + __declspec (dllimport) +# endif + void __cdecl free (void *); +# else +# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) +_GL_EXTERN_C void free (void *) _GL_ATTRIBUTE_NOTHROW; +# else +_GL_EXTERN_C void free (void *); +# endif +# endif +#endif + /* Macros for stringification. */ #define _GL_STDIO_STRINGIZE(token) #token #define _GL_STDIO_MACROEXPAND_AND_STRINGIZE(token) _GL_STDIO_STRINGIZE(token) @@ -273,24 +331,24 @@ #if (defined _WIN32 && !defined __CYGWIN__) && !defined _UCRT /* Workarounds against msvcrt bugs. */ -_GL_FUNCDECL_SYS (gl_consolesafe_fwrite, size_t, +_GL_FUNCDECL_SYS (_gl_consolesafe_fwrite, size_t, (const void *ptr, size_t size, size_t nmemb, FILE *fp), _GL_ARG_NONNULL ((1, 4))); # if defined __MINGW32__ -_GL_FUNCDECL_SYS (gl_consolesafe_fprintf, int, +_GL_FUNCDECL_SYS (_gl_consolesafe_fprintf, int, (FILE *restrict fp, const char *restrict format, ...), _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) _GL_ARG_NONNULL ((1, 2))); -_GL_FUNCDECL_SYS (gl_consolesafe_printf, int, +_GL_FUNCDECL_SYS (_gl_consolesafe_printf, int, (const char *restrict format, ...), _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) _GL_ARG_NONNULL ((1))); -_GL_FUNCDECL_SYS (gl_consolesafe_vfprintf, int, +_GL_FUNCDECL_SYS (_gl_consolesafe_vfprintf, int, (FILE *restrict fp, const char *restrict format, va_list args), _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) _GL_ARG_NONNULL ((1, 2))); -_GL_FUNCDECL_SYS (gl_consolesafe_vprintf, int, +_GL_FUNCDECL_SYS (_gl_consolesafe_vprintf, int, (const char *restrict format, va_list args), _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0) _GL_ARG_NONNULL ((1))); @@ -633,7 +691,7 @@ _GL_CXXALIASWARN (fprintf); #elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef fprintf -# define fprintf gl_consolesafe_fprintf +# define fprintf _gl_consolesafe_fprintf # endif #endif #if !@GNULIB_FPRINTF_POSIX@ && defined GNULIB_POSIXCHECK @@ -985,7 +1043,7 @@ _GL_CXXALIASWARN (fwrite); #elif (defined _WIN32 && !defined __CYGWIN__) && !defined _UCRT # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef fwrite -# define fwrite gl_consolesafe_fwrite +# define fwrite _gl_consolesafe_fwrite # endif #endif @@ -1371,7 +1429,7 @@ _GL_CXXALIASWARN (printf); #elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef printf -# define printf gl_consolesafe_printf +# define printf _gl_consolesafe_printf # endif #endif #if !@GNULIB_PRINTF_POSIX@ && defined GNULIB_POSIXCHECK @@ -1808,6 +1866,26 @@ _GL_CXXALIAS_SYS (vasprintf, int, _GL_CXXALIASWARN (vasprintf); #endif +#if @GNULIB_VAPRINTF@ +/* Write formatted output to a string dynamically allocated with malloc(). + Return the resulting string. Upon memory allocation error, or some + other error, return NULL, with errno set. */ +_GL_FUNCDECL_SYS (aprintf, char *, + (const char *format, ...), + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +_GL_CXXALIAS_SYS (aprintf, char *, + (const char *format, ...)); +_GL_FUNCDECL_SYS (vaprintf, char *, + (const char *format, va_list args), + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +_GL_CXXALIAS_SYS (vaprintf, char *, + (const char *format, va_list args)); +#endif + #if @GNULIB_VDZPRINTF@ /* Prints formatted output to file descriptor FD. Returns the number of bytes written to the file descriptor. Upon @@ -1918,7 +1996,7 @@ _GL_CXXALIASWARN (vfprintf); #elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef vfprintf -# define vfprintf gl_consolesafe_vfprintf +# define vfprintf _gl_consolesafe_vfprintf # endif #endif #if !@GNULIB_VFPRINTF_POSIX@ && defined GNULIB_POSIXCHECK @@ -2001,7 +2079,7 @@ _GL_CXXALIASWARN (vprintf); #elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef vprintf -# define vprintf gl_consolesafe_vprintf +# define vprintf _gl_consolesafe_vprintf # endif #endif #if !@GNULIB_VPRINTF_POSIX@ && defined GNULIB_POSIXCHECK diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 95237f2a5cb..3c2004611fe 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -757,7 +757,7 @@ _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - " #if @REPLACE_MB_CUR_MAX@ # if !GNULIB_defined_MB_CUR_MAX _GL_STDLIB_INLINE size_t -gl_MB_CUR_MAX (void) +_gl_MB_CUR_MAX (void) { # if 0 < @REPLACE_MB_CUR_MAX@ return @REPLACE_MB_CUR_MAX@; @@ -768,7 +768,7 @@ gl_MB_CUR_MAX (void) # endif } # undef MB_CUR_MAX -# define MB_CUR_MAX gl_MB_CUR_MAX () +# define MB_CUR_MAX _gl_MB_CUR_MAX () # define GNULIB_defined_MB_CUR_MAX 1 # endif #endif @@ -1458,7 +1458,7 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " #if @GNULIB_REALLOC_POSIX@ # if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ -# if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ == 2 +# if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ == 2 && !_GL_INLINE_RPL_REALLOC # define _GL_INLINE_RPL_REALLOC 1 # ifdef __cplusplus extern "C" { diff --git a/lib/strftime.c b/lib/strftime.c index f7cf65d5413..5a3544674e2 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -109,6 +109,7 @@ #include <limits.h> #include <locale.h> #include <stdckdint.h> +#include <stdcountof.h> #include <stddef.h> #include <stdint.h> #include <stdlib.h> @@ -1882,7 +1883,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) #endif } - bufp = buf + sizeof (buf) / sizeof (buf[0]); + bufp = buf + countof (buf); if (negative_number) u_number_value = - u_number_value; @@ -1913,7 +1914,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) CHAR_T sign_char = (negative_number ? L_('-') : always_output_a_sign ? L_('+') : 0); - int number_bytes = buf + sizeof buf / sizeof buf[0] - bufp; + int number_bytes = buf + countof (buf) - bufp; int number_digits = number_bytes; #if SUPPORT_NON_GREG_CALENDARS_IN_STRFTIME if (digits_base >= 0x100) @@ -2098,7 +2099,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) /* Generate string value for T using time_t arithmetic; this works even if sizeof (long) < sizeof (time_t). */ - bufp = buf + sizeof (buf) / sizeof (buf[0]); + bufp = buf + countof (buf); negative_number = t < 0; do diff --git a/lib/string.in.h b/lib/string.in.h index 0cd83c7844f..1c46c65f60d 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -420,16 +420,19 @@ _GL_WARN_ON_USE_CXX (memchr, /* Are S1 and S2, of size N, bytewise equal? */ #if @GNULIB_MEMEQ@ && !@HAVE_DECL_MEMEQ@ -# ifdef __cplusplus +# if !GNULIB_defined_memeq +# ifdef __cplusplus extern "C" { -# endif +# endif _GL_MEMEQ_INLINE bool memeq (void const *__s1, void const *__s2, size_t __n) { return !memcmp (__s1, __s2, __n); } -# ifdef __cplusplus +# ifdef __cplusplus } +# endif +# define GNULIB_defined_memeq 1 # endif #endif @@ -805,16 +808,19 @@ _GL_CXXALIASWARN (strdup); /* Are strings S1 and S2 equal? */ #if @GNULIB_STREQ@ && !@HAVE_DECL_STREQ@ -# ifdef __cplusplus +# if !GNULIB_defined_streq +# ifdef __cplusplus extern "C" { -# endif +# endif _GL_STREQ_INLINE bool streq (char const *__s1, char const *__s2) { return !strcmp (__s1, __s2); } -# ifdef __cplusplus +# ifdef __cplusplus } +# endif +# define GNULIB_defined_streq 1 # endif #endif @@ -1041,7 +1047,7 @@ _GL_WARN_ON_USE_CXX (strrchr, If *STRINGP was already NULL, nothing happens. Return the old value of *STRINGP. - This is a variant of strtok() that is multithread-safe and supports + This is a variant of strtok() that is thread-safe and supports empty fields. Caveat: It modifies the original string. @@ -1179,7 +1185,7 @@ _GL_WARN_ON_USE (strcasestr, "strcasestr does work correctly on character " x = strtok_r(NULL, "=", &sp); // x = NULL // s = "abc\0-def\0" - This is a variant of strtok() that is multithread-safe. + This is a variant of strtok() that is thread-safe. For the POSIX documentation for this function, see: https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html @@ -1245,13 +1251,14 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " string + strlen (string) or to strchr (string, '\0'). */ -# ifdef __cplusplus +# if !GNULIB_defined_strnul +# ifdef __cplusplus extern "C" { -# endif -_GL_STRNUL_INLINE const char *gl_strnul (const char *string) +# endif +_GL_STRNUL_INLINE const char *_gl_strnul (const char *string) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1)); -_GL_STRNUL_INLINE const char *gl_strnul (const char *string) +_GL_STRNUL_INLINE const char *_gl_strnul (const char *string) { /* In gcc >= 7 or clang >= 4, we could use the expression strchr (string, '\0') @@ -1261,22 +1268,24 @@ _GL_STRNUL_INLINE const char *gl_strnul (const char *string) option '-fno-builtin' is in use. */ return string + strlen (string); } -# ifdef __cplusplus +# ifdef __cplusplus } -# endif -# ifdef __cplusplus +# endif +# ifdef __cplusplus +extern "C++" { /* needed for AIX and Solaris 10 */ _GL_BEGIN_NAMESPACE template <typename T> T strnul (T); template <> inline const char *strnul<const char *> (const char *s) -{ return gl_strnul (s); } +{ return _gl_strnul (s); } template <> inline char *strnul< char *> ( char *s) -{ return const_cast<char *>(gl_strnul (s)); } +{ return const_cast<char *>(_gl_strnul (s)); } _GL_END_NAMESPACE -# else -# if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 && !defined __cplusplus) \ - || (defined __clang__ && __clang_major__ >= 3) \ - || (defined __SUNPRO_C && __SUNPRO_C >= 0x5150) \ - || (__STDC_VERSION__ >= 201112L && !defined __GNUC__) +} +# else +# if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 && !defined __cplusplus) \ + || (defined __clang__ && __clang_major__ >= 3) \ + || (defined __SUNPRO_C && __SUNPRO_C >= 0x5150) \ + || (__STDC_VERSION__ >= 201112L && !defined __GNUC__) /* The compiler supports _Generic from ISO C11. */ /* Since in C (but not in C++!), any function that accepts a '[const] char *' also accepts a '[const] void *' as argument, we make sure that the function- @@ -1284,14 +1293,16 @@ _GL_END_NAMESPACE char *, void * -> void * const char *, const void * -> const void * This mapping is done through the conditional expression. */ -# define strnul(s) \ - _Generic (1 ? (s) : (void *) 99, \ - void * : (char *) gl_strnul (s), \ - const void * : gl_strnul (s)) -# else -# define strnul(s) \ - ((char *) gl_strnul (s)) +# define strnul(s) \ + _Generic (1 ? (s) : (void *) 99, \ + void * : (char *) _gl_strnul (s), \ + const void * : _gl_strnul (s)) +# else +# define strnul(s) \ + ((char *) _gl_strnul (s)) +# endif # endif +# define GNULIB_defined_strnul 1 # endif #endif @@ -1400,7 +1411,7 @@ _GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) /* Don't silently convert a 'const char *' to a 'char *'. Programmers want compiler warnings for 'const' related mistakes. */ # ifdef __cplusplus -extern "C++" { /* needed for AIX */ +extern "C++" { /* needed for AIX and Solaris 10 */ template <typename T> T * mbsstr_template (T* haystack, const char *needle); template <> @@ -1468,7 +1479,7 @@ _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) /* Don't silently convert a 'const char *' to a 'char *'. Programmers want compiler warnings for 'const' related mistakes. */ # ifdef __cplusplus -extern "C++" { /* needed for AIX */ +extern "C++" { /* needed for AIX and Solaris 10 */ template <typename T> T * mbspcasecmp_template (T* string, const char *prefix); template <> @@ -1506,7 +1517,7 @@ _GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) /* Don't silently convert a 'const char *' to a 'char *'. Programmers want compiler warnings for 'const' related mistakes. */ # ifdef __cplusplus -extern "C++" { /* needed for AIX */ +extern "C++" { /* needed for AIX and Solaris 10 */ template <typename T> T * mbscasestr_template (T* haystack, const char *needle); template <> @@ -1655,7 +1666,7 @@ _GL_WARN_ON_USE (strerror, "strerror is unportable - " "use gnulib module strerror to guarantee non-NULL result"); #endif -/* Map any int, typically from errno, into an error message. Multithread-safe. +/* Map any int, typically from errno, into an error message. Thread-safe. Uses the POSIX declaration, not the glibc declaration. */ #if @GNULIB_STRERROR_R@ # if @REPLACE_STRERROR_R@ @@ -1711,7 +1722,7 @@ _GL_WARN_ON_USE (strerror_l, "strerror_l is unportable - " # endif #endif -/* Map any int, typically from errno, into an error message. Multithread-safe, +/* Map any int, typically from errno, into an error message. Thread-safe, with locale_t argument. Not portable! Only provided by gnulib. */ #if @GNULIB_STRERROR_L@ diff --git a/lib/strnul.c b/lib/strnul.c index a567f0722ec..e825542e550 100644 --- a/lib/strnul.c +++ b/lib/strnul.c @@ -1,4 +1,4 @@ -/* gl_strnul function. +/* _gl_strnul function. Copyright (C) 2025-2026 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify diff --git a/lib/tempname.c b/lib/tempname.c index 1edba07a02c..6b166253e82 100644 --- a/lib/tempname.c +++ b/lib/tempname.c @@ -111,9 +111,11 @@ random_bits (random_value *r, random_value s) __clock_gettime64 (CLOCK_REALTIME, &tv); v = mix_random_values (v, tv.tv_sec); v = mix_random_values (v, tv.tv_nsec); +#else + v = mix_random_values (v, clock ()); #endif - *r = mix_random_values (v, clock ()); + *r = v; return false; } diff --git a/lib/time_r.c b/lib/time_r.c index dfc427f6679..9da4ffa9297 100644 --- a/lib/time_r.c +++ b/lib/time_r.c @@ -22,7 +22,7 @@ #include <time.h> /* The replacement functions in this file are only used on native Windows. - They are multithread-safe, because the gmtime() and localtime() functions + They are thread-safe, because the gmtime() and localtime() functions on native Windows — both in the ucrt and in the older MSVCRT — return a pointer to a 'struct tm' in thread-local memory. */ diff --git a/lib/time_rz.c b/lib/time_rz.c index 0e8ea47e791..03aa3e6700e 100644 --- a/lib/time_rz.c +++ b/lib/time_rz.c @@ -18,7 +18,7 @@ /* Written by Paul Eggert. */ /* Although this module is not thread-safe, any races should be fairly - rare and reasonably benign. For complete thread-safety, use a C + rare and reasonably benign. For complete thread safety, use a C library with a working timezone_t type, so that this module is not needed. */ @@ -118,7 +118,8 @@ save_abbr (timezone_t tz, struct tm *tm) { # if HAVE_STRUCT_TM_TM_ZONE char const *zone = tm->tm_zone; - char *zone_copy = (char *) ""; + static char const mt[] = ""; + char *zone_copy = (char *) mt; /* No need to replace null zones, or zones within the struct tm. */ if (!zone || ((char *) tm <= zone && zone < (char *) (tm + 1))) diff --git a/lib/u64.h b/lib/u64.h index 2f9c7918151..cde952fa316 100644 --- a/lib/u64.h +++ b/lib/u64.h @@ -46,10 +46,10 @@ extern "C" { /* Native implementations are trivial. See below for comments on what these operations do. */ typedef uint64_t u64; -# define u64hilo(hi, lo) ((u64) (((u64) (hi) << 32) + (lo))) -# define u64init(hi, lo) u64hilo (hi, lo) -# define u64lo(x) ((u64) (x)) -# define u64getlo(x) ((uint32_t) ((x) & UINT32_MAX)) +# define u64hilo(hi, lo) ((u64) {((u64) {(hi)} << 32) + (lo)}) +# define u64init(hi, lo) (((u64) (hi) << 32) + (lo)) +# define u64lo(x) ((u64) {(x)}) +# define u64getlo(x) ((uint32_t) {(x) & UINT32_MAX}) # define u64size(x) u64lo (x) # define u64not(x) (~(x)) # define u64lt(x, y) ((x) < (y)) |
