summaryrefslogtreecommitdiff
path: root/lib/string.in.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/string.in.h')
-rw-r--r--lib/string.in.h473
1 files changed, 417 insertions, 56 deletions
diff --git a/lib/string.in.h b/lib/string.in.h
index f5a6d8b3..33422a06 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -1,6 +1,6 @@
/* A GNU-like <string.h>.
- Copyright (C) 1995-1996, 2001-2024 Free Software Foundation, Inc.
+ Copyright (C) 1995-1996, 2001-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
@@ -20,7 +20,7 @@
#endif
@PRAGMA_COLUMNS@
-#if defined _GL_ALREADY_INCLUDING_STRING_H
+#if defined _@GUARD_PREFIX@_ALREADY_INCLUDING_STRING_H
/* Special invocation convention:
- On OS X/NetBSD we have a sequence of nested includes
<string.h> -> <strings.h> -> "string.h"
@@ -34,12 +34,12 @@
#ifndef _@GUARD_PREFIX@_STRING_H
-#define _GL_ALREADY_INCLUDING_STRING_H
+#define _@GUARD_PREFIX@_ALREADY_INCLUDING_STRING_H
/* The include_next requires a split double-inclusion guard. */
#@INCLUDE_NEXT@ @NEXT_STRING_H@
-#undef _GL_ALREADY_INCLUDING_STRING_H
+#undef _@GUARD_PREFIX@_ALREADY_INCLUDING_STRING_H
#ifndef _@GUARD_PREFIX@_STRING_H
#define _@GUARD_PREFIX@_STRING_H
@@ -54,6 +54,11 @@
/* NetBSD 5.0 mis-defines NULL. */
#include <stddef.h>
+#if @GNULIB_STRERROR_L@
+/* Get locale_t. */
+# include <locale.h>
+#endif
+
/* MirBSD defines mbslen as a macro. */
#if @GNULIB_MBSLEN@ && defined __MirBSD__
# include <wchar.h>
@@ -75,6 +80,12 @@
# include <strings.h>
#endif
+_GL_INLINE_HEADER_BEGIN
+
+#ifndef _GL_STRING_INLINE
+# define _GL_STRING_INLINE _GL_INLINE
+#endif
+
/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
that can be freed by passing them as the Ith argument to the
function F. */
@@ -91,7 +102,7 @@
/* 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/bugzilla/show_bug.cgi?id=108231> */
+/* Work around GCC bug <https://gcc.gnu.org/PR108231> */
# define _GL_ATTRIBUTE_DEALLOC_FREE \
_GL_ATTRIBUTE_DEALLOC ((void (*) (void *)) free, 1)
# else
@@ -111,6 +122,18 @@
# endif
#endif
+/* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP
+ (a pointer) must not be NULL if the argument NI (an integer) is != 0. */
+/* Applies to: functions. */
+#ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO
+# if __GNUC__ >= 15 && !defined __clang__
+# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) \
+ __attribute__ ((__nonnull_if_nonzero__ (np, ni)))
+# else
+# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni)
+# endif
+#endif
+
/* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions.
*/
#ifndef _GL_ATTRIBUTE_NOTHROW
@@ -149,6 +172,7 @@
/* 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@
@@ -193,6 +217,91 @@ _GL_EXTERN_C void free (void *);
# endif
#endif
+
+/* Declarations for ISO C N3322. */
+#if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__
+# ifndef memcpy
+_GL_EXTERN_C void *memcpy (void *__dest, const void *__src, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
+# endif
+# ifndef memccpy
+_GL_EXTERN_C void *memccpy (void *__dest, const void *__src, int __c, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 4)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 4);
+# endif
+# ifndef memmove
+_GL_EXTERN_C void *memmove (void *__dest, const void *__src, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
+# endif
+# ifndef strncpy
+_GL_EXTERN_C char *strncpy (char *__dest, const char *__src, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
+# endif
+# ifndef strndup
+_GL_EXTERN_C char *strndup (const char *__s, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2);
+# endif
+# ifndef strncat
+_GL_EXTERN_C char *strncat (char *__dest, const char *__src, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
+# endif
+# ifndef memcmp
+_GL_EXTERN_C int memcmp (const void *__s1, const void *__s2, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
+# endif
+# ifndef strncmp
+_GL_EXTERN_C int strncmp (const char *__s1, const char *__s2, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
+# endif
+# if !defined memchr && !defined __cplusplus
+_GL_EXTERN_C void *memchr (const void *__s, int __c, size_t __n)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3);
+_GL_EXTERN_C void *memrchr (const void *__s, int __c, size_t __n)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3);
+# endif
+# ifndef memset
+_GL_EXTERN_C void *memset (void *__s, int __c, size_t __n)
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
+ _GL_ATTRIBUTE_NOTHROW
+# endif
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3);
+# endif
+# ifndef memset_explicit
+_GL_EXTERN_C void *memset_explicit (void *__s, int __c, size_t __n)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3);
+# endif
+#endif
+
+
/* Clear a block of memory. The compiler will not delete a call to
this function, even if the block is dead after the call. */
#if @GNULIB_EXPLICIT_BZERO@
@@ -203,13 +312,13 @@ _GL_FUNCDECL_SYS (explicit_bzero, void,
_GL_CXXALIAS_SYS (explicit_bzero, void, (void *__dest, size_t __n));
_GL_CXXALIASWARN (explicit_bzero);
#elif defined GNULIB_POSIXCHECK
-# undef explicit_bzero
# if HAVE_RAW_DECL_EXPLICIT_BZERO
_GL_WARN_ON_USE (explicit_bzero, "explicit_bzero is unportable - "
"use gnulib module explicit_bzero for portability");
# endif
#endif
+
/* Find the index of the least-significant set bit. */
#if @GNULIB_FFSL@
# if !@HAVE_FFSL@
@@ -218,7 +327,6 @@ _GL_FUNCDECL_SYS (ffsl, int, (long int i), );
_GL_CXXALIAS_SYS (ffsl, int, (long int i));
_GL_CXXALIASWARN (ffsl);
#elif defined GNULIB_POSIXCHECK
-# undef ffsl
# if HAVE_RAW_DECL_FFSL
_GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module");
# endif
@@ -241,7 +349,6 @@ _GL_CXXALIAS_SYS (ffsll, int, (long long int i));
# endif
_GL_CXXALIASWARN (ffsll);
#elif defined GNULIB_POSIXCHECK
-# undef ffsll
# if HAVE_RAW_DECL_FFSLL
_GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the ffsll module");
# endif
@@ -276,7 +383,7 @@ _GL_CXXALIASWARN (memccpy);
# endif
_GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n),
_GL_ATTRIBUTE_PURE
- _GL_ARG_NONNULL ((1)));
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3));
_GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n));
# else
/* On some systems, this function is defined as an overloaded function:
@@ -299,10 +406,26 @@ _GL_CXXALIASWARN1 (memchr, void const *,
_GL_CXXALIASWARN (memchr);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef memchr
/* Assume memchr is always declared. */
-_GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - "
- "use gnulib module memchr for portability" );
+_GL_WARN_ON_USE_CXX (memchr,
+ const void *, void *, (void const *, int, size_t),
+ "memchr has platform-specific bugs - "
+ "use gnulib module memchr for portability" );
+#endif
+
+/* Are S1 and S2, of size N, bytewise equal? */
+#if @GNULIB_STRINGEQ@ && !@HAVE_DECL_MEMEQ@
+# ifdef __cplusplus
+extern "C" {
+# endif
+_GL_STRING_INLINE bool
+memeq (void const *__s1, void const *__s2, size_t __n)
+{
+ return !memcmp (__s1, __s2, __n);
+}
+# ifdef __cplusplus
+}
+# endif
#endif
/* Return the first occurrence of NEEDLE in HAYSTACK. */
@@ -333,7 +456,6 @@ _GL_CXXALIAS_SYS (memmem, void *,
# endif
_GL_CXXALIASWARN (memmem);
#elif defined GNULIB_POSIXCHECK
-# undef memmem
# if HAVE_RAW_DECL_MEMMEM
_GL_WARN_ON_USE (memmem, "memmem is unportable and often quadratic - "
"use gnulib module memmem-simple for portability, "
@@ -371,7 +493,6 @@ _GL_CXXALIAS_SYS (mempcpy, void *,
_GL_CXXALIASWARN (mempcpy);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef mempcpy
# if HAVE_RAW_DECL_MEMPCPY
_GL_WARN_ON_USE (mempcpy, "mempcpy is unportable - "
"use gnulib module mempcpy for portability");
@@ -383,7 +504,7 @@ _GL_WARN_ON_USE (mempcpy, "mempcpy is unportable - "
# if ! @HAVE_DECL_MEMRCHR@
_GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t),
_GL_ATTRIBUTE_PURE
- _GL_ARG_NONNULL ((1)));
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3));
# endif
/* On some systems, this function is defined as an overloaded function:
extern "C++" { const void * std::memrchr (const void *, int, size_t); }
@@ -404,7 +525,6 @@ _GL_CXXALIASWARN1 (memrchr, void const *,
_GL_CXXALIASWARN (memrchr);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef memrchr
# if HAVE_RAW_DECL_MEMRCHR
_GL_WARN_ON_USE (memrchr, "memrchr is unportable - "
"use gnulib module memrchr for portability");
@@ -420,18 +540,21 @@ _GL_WARN_ON_USE (memrchr, "memrchr is unportable - "
# define memset_explicit rpl_memset_explicit
# endif
_GL_FUNCDECL_RPL (memset_explicit, void *,
- (void *__dest, int __c, size_t __n), _GL_ARG_NONNULL ((1)));
+ (void *__dest, int __c, size_t __n),
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3));
_GL_CXXALIAS_RPL (memset_explicit, void *, (void *__dest, int __c, size_t __n));
# else
# if !@HAVE_MEMSET_EXPLICIT@
_GL_FUNCDECL_SYS (memset_explicit, void *,
- (void *__dest, int __c, size_t __n), _GL_ARG_NONNULL ((1)));
+ (void *__dest, int __c, size_t __n),
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3));
# endif
_GL_CXXALIAS_SYS (memset_explicit, void *, (void *__dest, int __c, size_t __n));
# endif
+# if __GLIBC__ >= 2
_GL_CXXALIASWARN (memset_explicit);
+# endif
#elif defined GNULIB_POSIXCHECK
-# undef memset_explicit
# if HAVE_RAW_DECL_MEMSET_EXPLICIT
_GL_WARN_ON_USE (memset_explicit, "memset_explicit is unportable - "
"use gnulib module memset_explicit for portability");
@@ -466,7 +589,6 @@ _GL_CXXALIASWARN1 (rawmemchr, void const *,
_GL_CXXALIASWARN (rawmemchr);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef rawmemchr
# if HAVE_RAW_DECL_RAWMEMCHR
_GL_WARN_ON_USE (rawmemchr, "rawmemchr is unportable - "
"use gnulib module rawmemchr for portability");
@@ -498,7 +620,6 @@ _GL_CXXALIAS_SYS (stpcpy, char *,
_GL_CXXALIASWARN (stpcpy);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef stpcpy
# if HAVE_RAW_DECL_STPCPY
_GL_WARN_ON_USE (stpcpy, "stpcpy is unportable - "
"use gnulib module stpcpy for portability");
@@ -535,7 +656,6 @@ _GL_CXXALIAS_SYS (stpncpy, char *,
_GL_CXXALIASWARN (stpncpy);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef stpncpy
# if HAVE_RAW_DECL_STPNCPY
_GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - "
"use gnulib module stpncpy for portability");
@@ -545,7 +665,6 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - "
#if defined GNULIB_POSIXCHECK
/* strchr() does not work with multibyte strings if the locale encoding is
GB18030 and the character to be searched is a digit. */
-# undef strchr
/* Assume strchr is always declared. */
_GL_WARN_ON_USE_CXX (strchr,
const char *, char *, (const char *, int),
@@ -591,7 +710,6 @@ _GL_CXXALIASWARN1 (strchrnul, char const *,
_GL_CXXALIASWARN (strchrnul);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef strchrnul
# if HAVE_RAW_DECL_STRCHRNUL
_GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - "
"use gnulib module strchrnul for portability");
@@ -656,7 +774,6 @@ _GL_FUNCDECL_SYS (strdup, char *,
# endif
# endif
# if defined GNULIB_POSIXCHECK
-# undef strdup
# if HAVE_RAW_DECL_STRDUP
_GL_WARN_ON_USE (strdup, "strdup is unportable - "
"use gnulib module strdup for portability");
@@ -681,6 +798,21 @@ _GL_CXXALIASWARN (strdup);
# endif
#endif
+/* Are strings S1 and S2 equal? */
+#if @GNULIB_STRINGEQ@ && !@HAVE_DECL_STREQ@
+# ifdef __cplusplus
+extern "C" {
+# endif
+_GL_STRING_INLINE bool
+streq (char const *__s1, char const *__s2)
+{
+ return !strcmp (__s1, __s2);
+}
+# ifdef __cplusplus
+}
+# endif
+#endif
+
/* Append no more than N characters from SRC onto DEST. */
#if @GNULIB_STRNCAT@
# if @REPLACE_STRNCAT@
@@ -690,7 +822,8 @@ _GL_CXXALIASWARN (strdup);
# endif
_GL_FUNCDECL_RPL (strncat, char *,
(char *restrict dest, const char *restrict src, size_t n),
- _GL_ARG_NONNULL ((1, 2)));
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3));
_GL_CXXALIAS_RPL (strncat, char *,
(char *restrict dest, const char *restrict src, size_t n));
# else
@@ -701,13 +834,41 @@ _GL_CXXALIAS_SYS (strncat, char *,
_GL_CXXALIASWARN (strncat);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef strncat
# if HAVE_RAW_DECL_STRNCAT
_GL_WARN_ON_USE (strncat, "strncat is unportable - "
"use gnulib module strncat for portability");
# endif
#endif
+/* Copy no more than N bytes of SRC to DST, returning DST. */
+#if @GNULIB_STRNCPY@
+# if @REPLACE_STRNCPY@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strncpy
+# define strncpy rpl_strncpy
+# endif
+_GL_FUNCDECL_RPL (strncpy, char *,
+ (char *restrict __dst, char const *restrict __src,
+ size_t __n),
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (strncpy, char *,
+ (char *restrict __dst, char const *restrict __src,
+ size_t __n));
+# else
+_GL_CXXALIAS_SYS (strncpy, char *,
+ (char *restrict __dst, char const *restrict __src,
+ size_t __n));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (strncpy);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# if HAVE_RAW_DECL_STRNCPY
+_GL_WARN_ON_USE (strncpy, "strncpy is unportable - "
+ "use gnulib module strncpy for portability");
+# endif
+#endif
+
/* Return a newly allocated copy of at most N bytes of STRING. */
#if @GNULIB_STRNDUP@
# if @REPLACE_STRNDUP@
@@ -717,7 +878,7 @@ _GL_WARN_ON_USE (strncat, "strncat is unportable - "
# endif
_GL_FUNCDECL_RPL (strndup, char *,
(char const *__s, size_t __n),
- _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n));
# else
@@ -726,13 +887,13 @@ _GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n));
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_FUNCDECL_SYS (strndup, char *,
(char const *__s, size_t __n),
- _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE)
_GL_ATTRIBUTE_NOTHROW;
# else
_GL_FUNCDECL_SYS (strndup, char *,
(char const *__s, size_t __n),
- _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
# endif
# endif
@@ -745,18 +906,17 @@ _GL_CXXALIASWARN (strndup);
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_FUNCDECL_SYS (strndup, char *,
(char const *__s, size_t __n),
- _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE)
_GL_ATTRIBUTE_NOTHROW;
# else
_GL_FUNCDECL_SYS (strndup, char *,
(char const *__s, size_t __n),
- _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
# endif
# endif
# if defined GNULIB_POSIXCHECK
-# undef strndup
# if HAVE_RAW_DECL_STRNDUP
_GL_WARN_ON_USE (strndup, "strndup is unportable - "
"use gnulib module strndup for portability");
@@ -787,7 +947,6 @@ _GL_CXXALIAS_SYS (strnlen, size_t, (char const *__s, size_t __maxlen));
# endif
_GL_CXXALIASWARN (strnlen);
#elif defined GNULIB_POSIXCHECK
-# undef strnlen
# if HAVE_RAW_DECL_STRNLEN
_GL_WARN_ON_USE (strnlen, "strnlen is unportable - "
"use gnulib module strnlen for portability");
@@ -799,7 +958,6 @@ _GL_WARN_ON_USE (strnlen, "strnlen is unportable - "
Even in this simple case, it does not work with multibyte strings if the
locale encoding is GB18030 and one of the characters to be searched is a
digit. */
-# undef strcspn
/* Assume strcspn is always declared. */
_GL_WARN_ON_USE (strcspn, "strcspn cannot work correctly on character strings "
"in multibyte locales - "
@@ -836,7 +994,6 @@ _GL_CXXALIASWARN (strpbrk);
Even in this simple case, it does not work with multibyte strings if the
locale encoding is GB18030 and one of the characters to be searched is a
digit. */
-# undef strpbrk
_GL_WARN_ON_USE_CXX (strpbrk,
const char *, char *, (const char *, const char *),
"strpbrk cannot work correctly on character strings "
@@ -856,7 +1013,6 @@ _GL_WARN_ON_USE_CXX (strpbrk,
#if defined GNULIB_POSIXCHECK
/* strspn() assumes the second argument is a list of single-byte characters.
Even in this simple case, it cannot work with multibyte strings. */
-# undef strspn
/* Assume strspn is always declared. */
_GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings "
"in multibyte locales - "
@@ -866,7 +1022,6 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings "
#if defined GNULIB_POSIXCHECK
/* strrchr() does not work with multibyte strings if the locale encoding is
GB18030 and the character to be searched is a digit. */
-# undef strrchr
/* Assume strrchr is always declared. */
_GL_WARN_ON_USE_CXX (strrchr,
const char *, char *, (const char *, int),
@@ -901,13 +1056,11 @@ _GL_CXXALIAS_SYS (strsep, char *,
(char **restrict __stringp, char const *restrict __delim));
_GL_CXXALIASWARN (strsep);
# if defined GNULIB_POSIXCHECK
-# undef strsep
_GL_WARN_ON_USE (strsep, "strsep cannot work correctly on character strings "
"in multibyte locales - "
"use mbssep if you care about internationalization");
# endif
#elif defined GNULIB_POSIXCHECK
-# undef strsep
# if HAVE_RAW_DECL_STRSEP
_GL_WARN_ON_USE (strsep, "strsep is unportable - "
"use gnulib module strsep for portability");
@@ -950,11 +1103,13 @@ _GL_CXXALIASWARN (strstr);
as a sequence of bytes, not of characters. */
# undef strstr
/* Assume strstr is always declared. */
-_GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and cannot "
- "work correctly on character strings in most "
- "multibyte locales - "
- "use mbsstr if you care about internationalization, "
- "or use strstr if you care about speed");
+_GL_WARN_ON_USE_CXX (strstr,
+ const char *, char *, (const char *, const char *),
+ "strstr is quadratic on many systems, and cannot "
+ "work correctly on character strings in most "
+ "multibyte locales - "
+ "use mbsstr if you care about internationalization, "
+ "or use strstr if you care about speed");
#endif
/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive
@@ -1000,7 +1155,6 @@ _GL_CXXALIASWARN (strcasestr);
/* strcasestr() does not work with multibyte strings:
It is a glibc extension, and glibc implements it only for unibyte
locales. */
-# undef strcasestr
# if HAVE_RAW_DECL_STRCASESTR
_GL_WARN_ON_USE (strcasestr, "strcasestr does work correctly on character "
"strings in multibyte locales - "
@@ -1046,7 +1200,7 @@ _GL_CXXALIAS_RPL (strtok_r, char *,
(char *restrict s, char const *restrict delim,
char **restrict save_ptr));
# else
-# if @UNDEFINE_STRTOK_R@ || defined GNULIB_POSIXCHECK
+# if @UNDEFINE_STRTOK_R@
# undef strtok_r
# endif
# if ! @HAVE_DECL_STRTOK_R@
@@ -1066,7 +1220,6 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r cannot work correctly on character "
"use mbstok_r if you care about internationalization");
# endif
#elif defined GNULIB_POSIXCHECK
-# undef strtok_r
# if HAVE_RAW_DECL_STRTOK_R
_GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - "
"use gnulib module strtok_r for portability");
@@ -1077,13 +1230,87 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - "
/* The following functions are not specified by POSIX. They are gnulib
extensions. */
+#if @GNULIB_STRNUL@
+/* Returns a pointer to the terminating NUL byte of STRING.
+ strnul (string)
+ This is a type-generic macro:
+ If STRING is a 'const char *', the result is 'const char *'.
+ If STRING is a 'char *', the result is 'char *'.
+ It is equivalent to
+ string + strlen (string)
+ or to
+ strchr (string, '\0'). */
+# ifdef __cplusplus
+extern "C" {
+# endif
+_GL_STRING_INLINE const char *gl_strnul (const char *string)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1));
+_GL_STRING_INLINE const char *gl_strnul (const char *string)
+{
+ /* In gcc >= 7 or clang >= 4, we could use the expression
+ strchr (string, '\0')
+ because these compiler versions produce identical code for both
+ expressions. But this optimization in not available in older
+ compiler versions, and is also not available when the compiler
+ option '-fno-builtin' is in use. */
+ return string + strlen (string);
+}
+# ifdef __cplusplus
+}
+# endif
+# ifdef __cplusplus
+template <typename T> T strnul (T);
+template <> inline const char *strnul<const char *> (const char *s)
+{ return gl_strnul (s); }
+template <> inline char *strnul< char *> ( char *s)
+{ return const_cast<char *>(gl_strnul (s)); }
+# 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-
+ like macro does the same, by mapping its type first:
+ 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))
+# endif
+# endif
+#endif
+
+#if @GNULIB_STR_STARTSWITH@
+/* Returns true if STRING starts with PREFIX.
+ Returns false otherwise. */
+_GL_EXTERN_C bool str_startswith (const char *string, const char *prefix)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_STR_ENDSWITH@
+/* Returns true if STRING ends with SUFFIX.
+ Returns false otherwise. */
+_GL_EXTERN_C bool str_endswith (const char *string, const char *prefix)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
#if @GNULIB_MBSLEN@
/* Return the number of multibyte characters in the character string STRING.
This considers multibyte characters, unlike strlen, which counts bytes. */
# ifdef __MirBSD__ /* MirBSD defines mbslen as a macro. Override it. */
# undef mbslen
# endif
-# if @HAVE_MBSLEN@ /* AIX, OSF/1, MirBSD define mbslen already in libc. */
+# if @HAVE_MBSLEN@ /* AIX, MirBSD define mbslen already in libc. */
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define mbslen rpl_mbslen
# endif
@@ -1162,6 +1389,33 @@ _GL_CXXALIASWARN (mbsrchr);
_GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle)
_GL_ATTRIBUTE_PURE
_GL_ARG_NONNULL ((1, 2));
+# ifndef _GL_NO_CONST_GENERICS
+/* 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 */
+template <typename T>
+ T * mbsstr_template (T* haystack, const char *needle);
+template <>
+ inline char * mbsstr_template (char *haystack, const char *needle)
+ { return mbsstr (haystack, needle); }
+template <>
+ inline const char * mbsstr_template (const char *haystack, const char *needle)
+ { return mbsstr (haystack, needle); }
+}
+# undef mbsstr
+# define mbsstr mbsstr_template
+# elif !defined mbsstr
+# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
+ || defined __ICC || defined __TINYC__ \
+ || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
+# define mbsstr(h,n) \
+ _Generic ((h), \
+ char const *: (char const *) mbsstr ((h), (n)), \
+ default : mbsstr ((h), (n)))
+# endif
+# endif
+# endif
#endif
#if @GNULIB_MBSCASECMP@
@@ -1203,6 +1457,33 @@ _GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n)
_GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix)
_GL_ATTRIBUTE_PURE
_GL_ARG_NONNULL ((1, 2));
+# ifndef _GL_NO_CONST_GENERICS
+/* 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 */
+template <typename T>
+ T * mbspcasecmp_template (T* string, const char *prefix);
+template <>
+ inline char * mbspcasecmp_template (char *string, const char *prefix)
+ { return mbspcasecmp (string, prefix); }
+template <>
+ inline const char * mbspcasecmp_template (const char *string, const char *prefix)
+ { return mbspcasecmp (string, prefix); }
+}
+# undef mbspcasecmp
+# define mbspcasecmp mbspcasecmp_template
+# elif !defined mbspcasecmp
+# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
+ || defined __ICC || defined __TINYC__ \
+ || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
+# define mbspcasecmp(s,p) \
+ _Generic ((s), \
+ char const *: (char const *) mbspcasecmp ((s), (p)), \
+ default : mbspcasecmp ((s), (p)))
+# endif
+# endif
+# endif
#endif
#if @GNULIB_MBSCASESTR@
@@ -1214,6 +1495,33 @@ _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix)
_GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle)
_GL_ATTRIBUTE_PURE
_GL_ARG_NONNULL ((1, 2));
+# ifndef _GL_NO_CONST_GENERICS
+/* 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 */
+template <typename T>
+ T * mbscasestr_template (T* haystack, const char *needle);
+template <>
+ inline char * mbscasestr_template (char *haystack, const char *needle)
+ { return mbscasestr (haystack, needle); }
+template <>
+ inline const char * mbscasestr_template (const char *haystack, const char *needle)
+ { return mbscasestr (haystack, needle); }
+}
+# undef mbscasestr
+# define mbscasestr mbscasestr_template
+# elif !defined mbscasestr
+# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
+ || defined __ICC || defined __TINYC__ \
+ || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
+# define mbscasestr(h,n) \
+ _Generic ((h), \
+ char const *: (char const *) mbscasestr ((h), (n)), \
+ default : mbscasestr ((h), (n)))
+# endif
+# endif
+# endif
#endif
#if @GNULIB_MBSCSPN@
@@ -1301,6 +1609,26 @@ _GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim,
_GL_ARG_NONNULL ((2, 3));
#endif
+#if @GNULIB_MBS_STARTSWITH@
+/* Returns true if STRING starts with PREFIX.
+ Returns false otherwise. */
+_GL_EXTERN_C bool mbs_startswith (const char *string, const char *prefix)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+/* No extra code is needed for multibyte locales for this function. */
+# define mbs_startswith str_startswith
+#endif
+
+#if @GNULIB_MBS_ENDSWITH@
+/* Returns true if STRING ends with SUFFIX.
+ Returns false otherwise.
+ Unlike str_endswith(), this function works correctly in multibyte locales.
+ */
+_GL_EXTERN_C bool mbs_endswith (const char *string, const char *suffix)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
/* Map any int, typically from errno, into an error message. */
#if @GNULIB_STRERROR@
# if @REPLACE_STRERROR@
@@ -1317,7 +1645,6 @@ _GL_CXXALIAS_SYS (strerror, char *, (int));
_GL_CXXALIASWARN (strerror);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef strerror
/* Assume strerror is always declared. */
_GL_WARN_ON_USE (strerror, "strerror is unportable - "
"use gnulib module strerror to guarantee non-NULL result");
@@ -1345,13 +1672,49 @@ _GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen));
_GL_CXXALIASWARN (strerror_r);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef strerror_r
# if HAVE_RAW_DECL_STRERROR_R
_GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - "
"use gnulib module strerror_r-posix for portability");
# endif
#endif
+/* Map any int, typically from errno, into an error message.
+ With locale_t argument. */
+#if @GNULIB_STRERROR_L@
+# if @REPLACE_STRERROR_L@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strerror_l
+# define strerror_l rpl_strerror_l
+# endif
+_GL_FUNCDECL_RPL (strerror_l, char *, (int errnum, locale_t locale),
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (strerror_l, char *, (int errnum, locale_t locale));
+# else
+# if !@HAVE_STRERROR_L@
+_GL_FUNCDECL_SYS (strerror_l, char *, (int errnum, locale_t locale),
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (strerror_l, char *, (int errnum, locale_t locale));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (strerror_l);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# if HAVE_RAW_DECL_STRERROR_L
+_GL_WARN_ON_USE (strerror_l, "strerror_l is unportable - "
+ "use gnulib module strerror_l for portability");
+# endif
+#endif
+
+/* Map any int, typically from errno, into an error message. Multithread-safe,
+ with locale_t argument.
+ Not portable! Only provided by gnulib. */
+#if @GNULIB_STRERROR_L@
+_GL_FUNCDECL_SYS (strerror_l_r, int,
+ (int errnum, char *buf, size_t buflen, locale_t locale),
+ _GL_ARG_NONNULL ((2, 4)));
+#endif
+
/* Return the name of the system error code ERRNUM. */
#if @GNULIB_STRERRORNAME_NP@
# if @REPLACE_STRERRORNAME_NP@
@@ -1367,9 +1730,10 @@ _GL_FUNCDECL_SYS (strerrorname_np, const char *, (int errnum), );
# endif
_GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum));
# endif
+# if __GLIBC__ >= 2
_GL_CXXALIASWARN (strerrorname_np);
+# endif
#elif defined GNULIB_POSIXCHECK
-# undef strerrorname_np
# if HAVE_RAW_DECL_STRERRORNAME_NP
_GL_WARN_ON_USE (strerrorname_np, "strerrorname_np is unportable - "
"use gnulib module strerrorname_np for portability");
@@ -1384,7 +1748,6 @@ _GL_FUNCDECL_SYS (sigabbrev_np, const char *, (int sig), );
_GL_CXXALIAS_SYS (sigabbrev_np, const char *, (int sig));
_GL_CXXALIASWARN (sigabbrev_np);
#elif defined GNULIB_POSIXCHECK
-# undef sigabbrev_np
# if HAVE_RAW_DECL_SIGABBREV_NP
_GL_WARN_ON_USE (sigabbrev_np, "sigabbrev_np is unportable - "
"use gnulib module sigabbrev_np for portability");
@@ -1399,7 +1762,6 @@ _GL_FUNCDECL_SYS (sigdescr_np, const char *, (int sig), );
_GL_CXXALIAS_SYS (sigdescr_np, const char *, (int sig));
_GL_CXXALIASWARN (sigdescr_np);
#elif defined GNULIB_POSIXCHECK
-# undef sigdescr_np
# if HAVE_RAW_DECL_SIGDESCR_NP
_GL_WARN_ON_USE (sigdescr_np, "sigdescr_np is unportable - "
"use gnulib module sigdescr_np for portability");
@@ -1423,7 +1785,6 @@ _GL_CXXALIAS_SYS_CAST (strsignal, char *, (int __sig));
# endif
_GL_CXXALIASWARN (strsignal);
#elif defined GNULIB_POSIXCHECK
-# undef strsignal
# if HAVE_RAW_DECL_STRSIGNAL
_GL_WARN_ON_USE (strsignal, "strsignal is unportable - "
"use gnulib module strsignal for portability");
@@ -1449,13 +1810,13 @@ _GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *));
# endif
_GL_CXXALIASWARN (strverscmp);
#elif defined GNULIB_POSIXCHECK
-# undef strverscmp
# if HAVE_RAW_DECL_STRVERSCMP
_GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - "
"use gnulib module strverscmp for portability");
# endif
#endif
+_GL_INLINE_HEADER_END
#endif /* _@GUARD_PREFIX@_STRING_H */
#endif /* _@GUARD_PREFIX@_STRING_H */