* [patch] Don't duplicate declarations between string.h and strings.h
@ 2016-11-16 20:55 Zack Weinberg
2016-11-17 0:36 ` Zack Weinberg
2016-11-21 17:17 ` Zack Weinberg
0 siblings, 2 replies; 5+ messages in thread
From: Zack Weinberg @ 2016-11-16 20:55 UTC (permalink / raw)
To: GNU C Library, Joseph Myers
I was looking into something else and noticed that all of the
declarations in strings.h are duplicated in string.h, but not quite
consistently. This patch cleans that all up; strings.h is given
consistent declarations of everything, and then string.h just does
#ifdef __USE_MISC
# include <strings.h>
#endif
The prototype of __bzero is moved to include/string.h instead of
strings.h, since it is an internal name.
Tested on x86-64/linux. OK?
zw
* string/string.h [__USE_MISC]: Include strings.h.
(__bzero, bcmp, bcopy, bzero, index, rindex)
(strcasecmp, strncasecmp, strcasecmp_l, strncasecmp_l)
(ffs, ffsl, ffsll): Don't declare.
* string/strings.h: Do not suppress the file if string.h has
already been included.
(bcmp, bcopy, bzero, strcasecmp, strncasecmp): Add __nonnull
annotations.
(index, rindex): Define inline forwarders even if
__CORRECT_ISO_CPP_STRING_H_PROTO is defined.
(ffs): Use __attribute_const__.
(ffsl, ffsll): Declare here.
(strcasecmp_l, strncasecmp_l): Correct comments; these functions
have now been standardized.
* include/string.h (__bzero): Declare here.
diff --git a/include/string.h b/include/string.h
index e145bfd..749e691 100644
--- a/include/string.h
+++ b/include/string.h
@@ -41,6 +41,8 @@ extern void *__memrchr (const void *__s, int __c,
size_t __n)
extern void *__memchr (const void *__s, int __c, size_t __n)
__attribute_pure__;
+extern void __bzero (void *__s, size_t __n) __THROW __nonnull ((1));
+
extern int __ffs (int __i) __attribute__ ((const));
extern char *__strerror_r (int __errnum, char *__buf, size_t __buflen);
diff --git a/string/string.h b/string/string.h
index b103e64..ca22cd0 100644
--- a/string/string.h
+++ b/string/string.h
@@ -440,110 +440,8 @@ extern char *strerror_r (int __errnum, char
*__buf, size_t __buflen)
extern char *strerror_l (int __errnum, __locale_t __l) __THROW;
#endif
-
-/* We define this function always since `bzero' is sometimes needed when
- the namespace rules does not allow this. */
-extern void __bzero (void *__s, size_t __n) __THROW __nonnull ((1));
-
#ifdef __USE_MISC
-/* Copy N bytes of SRC to DEST (like memmove, but args reversed). */
-extern void bcopy (const void *__src, void *__dest, size_t __n)
- __THROW __nonnull ((1, 2));
-
-/* Set N bytes of S to 0. */
-extern void bzero (void *__s, size_t __n) __THROW __nonnull ((1));
-
-/* Compare N bytes of S1 and S2 (same as memcmp). */
-extern int bcmp (const void *__s1, const void *__s2, size_t __n)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-
-/* Find the first occurrence of C in S (same as strchr). */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern char *index (char *__s, int __c)
- __THROW __asm ("index") __attribute_pure__ __nonnull ((1));
-extern const char *index (const char *__s, int __c)
- __THROW __asm ("index") __attribute_pure__ __nonnull ((1));
-
-# if defined __OPTIMIZE__ && !defined __CORRECT_ISO_CPP_STRINGS_H_PROTO
-__extern_always_inline char *
-index (char *__s, int __c) __THROW
-{
- return __builtin_index (__s, __c);
-}
-
-__extern_always_inline const char *
-index (const char *__s, int __c) __THROW
-{
- return __builtin_index (__s, __c);
-}
-# endif
-}
-# else
-extern char *index (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
-
-/* Find the last occurrence of C in S (same as strrchr). */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern char *rindex (char *__s, int __c)
- __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
-extern const char *rindex (const char *__s, int __c)
- __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
-
-# if defined __OPTIMIZE__ && !defined __CORRECT_ISO_CPP_STRINGS_H_PROTO
-__extern_always_inline char *
-rindex (char *__s, int __c) __THROW
-{
- return __builtin_rindex (__s, __c);
-}
-
-__extern_always_inline const char *
-rindex (const char *__s, int __c) __THROW
-{
- return __builtin_rindex (__s, __c);
-}
-#endif
-}
-# else
-extern char *rindex (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
-
-/* Return the position of the first bit set in I, or 0 if none are set.
- The least-significant bit is position 1, the most-significant 32. */
-extern int ffs (int __i) __THROW __attribute__ ((__const__));
-
-/* The following two functions are non-standard but necessary for
non-32 bit
- platforms. */
-# ifdef __USE_GNU
-extern int ffsl (long int __l) __THROW __attribute__ ((__const__));
-__extension__ extern int ffsll (long long int __ll)
- __THROW __attribute__ ((__const__));
-# endif
-
-/* Compare S1 and S2, ignoring case. */
-extern int strcasecmp (const char *__s1, const char *__s2)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-
-/* Compare no more than N chars of S1 and S2, ignoring case. */
-extern int strncasecmp (const char *__s1, const char *__s2, size_t __n)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-#endif /* Use misc. */
-
-#ifdef __USE_GNU
-/* Again versions of a few functions which use the given locale instead
- of the global one. */
-extern int strcasecmp_l (const char *__s1, const char *__s2,
- __locale_t __loc)
- __THROW __attribute_pure__ __nonnull ((1, 2, 3));
-
-extern int strncasecmp_l (const char *__s1, const char *__s2,
- size_t __n, __locale_t __loc)
- __THROW __attribute_pure__ __nonnull ((1, 2, 4));
+# include <strings.h>
#endif
#ifdef __USE_MISC
diff --git a/string/strings.h b/string/strings.h
index e372a33..f78eca5 100644
--- a/string/strings.h
+++ b/string/strings.h
@@ -18,35 +18,31 @@
#ifndef _STRINGS_H
#define _STRINGS_H 1
-/* We don't need and should not read this file if <string.h> was already
- read. The one exception being that if __USE_MISC isn't defined, then
- these aren't defined in string.h, so we need to define them here. */
-#if !defined _STRING_H || !defined __USE_MISC
-
-# include <features.h>
-# define __need_size_t
-# include <stddef.h>
+#include <features.h>
+#define __need_size_t
+#include <stddef.h>
/* Tell the caller that we provide correct C++ prototypes. */
-# if defined __cplusplus && __GNUC_PREREQ (4, 4)
-# define __CORRECT_ISO_CPP_STRINGS_H_PROTO
-# endif
+#if defined __cplusplus && __GNUC_PREREQ (4, 4)
+# define __CORRECT_ISO_CPP_STRINGS_H_PROTO
+#endif
__BEGIN_DECLS
-# if defined __USE_MISC || !defined __USE_XOPEN2K8
+#if defined __USE_MISC || !defined __USE_XOPEN2K8
/* Compare N bytes of S1 and S2 (same as memcmp). */
extern int bcmp (const void *__s1, const void *__s2, size_t __n)
- __THROW __attribute_pure__;
+ __THROW __attribute_pure__ __nonnull ((1, 2));
/* Copy N bytes of SRC to DEST (like memmove, but args reversed). */
-extern void bcopy (const void *__src, void *__dest, size_t __n) __THROW;
+extern void bcopy (const void *__src, void *__dest, size_t __n)
+ __THROW __nonnull ((1, 2));
/* Set N bytes of S to 0. */
-extern void bzero (void *__s, size_t __n) __THROW;
+extern void bzero (void *__s, size_t __n) __THROW __nonnull ((1));
/* Find the first occurrence of C in S (same as strchr). */
-# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
+# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
extern "C++"
{
extern char *index (char *__s, int __c)
@@ -54,7 +50,7 @@ extern char *index (char *__s, int __c)
extern const char *index (const char *__s, int __c)
__THROW __asm ("index") __attribute_pure__ __nonnull ((1));
-# if defined __OPTIMIZE__ && !defined __CORRECT_ISO_CPP_STRING_H_PROTO
+# if defined __OPTIMIZE__
__extern_always_inline char *
index (char *__s, int __c) __THROW
{
@@ -66,15 +62,15 @@ index (const char *__s, int __c) __THROW
{
return __builtin_index (__s, __c);
}
-# endif
+# endif
}
-# else
+# else
extern char *index (const char *__s, int __c)
__THROW __attribute_pure__ __nonnull ((1));
-# endif
+# endif
/* Find the last occurrence of C in S (same as strrchr). */
-# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
+# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
extern "C++"
{
extern char *rindex (char *__s, int __c)
@@ -82,7 +78,7 @@ extern char *rindex (char *__s, int __c)
extern const char *rindex (const char *__s, int __c)
__THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
-# if defined __OPTIMIZE__ && !defined __CORRECT_ISO_CPP_STRING_H_PROTO
+# if defined __OPTIMIZE__
__extern_always_inline char *
rindex (char *__s, int __c) __THROW
{
@@ -94,39 +90,45 @@ rindex (const char *__s, int __c) __THROW
{
return __builtin_rindex (__s, __c);
}
-# endif
+# endif
}
-# else
+# else
extern char *rindex (const char *__s, int __c)
__THROW __attribute_pure__ __nonnull ((1));
-# endif
# endif
+#endif
#if defined __USE_MISC || !defined __USE_XOPEN2K8 || defined
__USE_XOPEN2K8XSI
/* Return the position of the first bit set in I, or 0 if none are set.
The least-significant bit is position 1, the most-significant 32. */
-extern int ffs (int __i) __THROW __attribute__ ((const));
+extern int ffs (int __i) __THROW __attribute_const__;
#endif
+/* The following two functions are non-standard but necessary for
non-32 bit
+ platforms. */
+# ifdef __USE_GNU
+extern int ffsl (long int __l) __THROW __attribute_const__;
+__extension__ extern int ffsll (long long int __ll)
+ __THROW __attribute_const__;
+# endif
+
/* Compare S1 and S2, ignoring case. */
extern int strcasecmp (const char *__s1, const char *__s2)
- __THROW __attribute_pure__;
+ __THROW __attribute_pure__ __nonnull ((1, 2));
/* Compare no more than N chars of S1 and S2, ignoring case. */
extern int strncasecmp (const char *__s1, const char *__s2, size_t __n)
- __THROW __attribute_pure__;
+ __THROW __attribute_pure__ __nonnull ((1, 2));
#ifdef __USE_XOPEN2K8
-/* The following functions are equivalent to the both above but they
- take the locale they use for the collation as an extra argument.
- This is not standardsized but something like will come. */
# include <xlocale.h>
-/* Again versions of a few functions which use the given locale instead
- of the global one. */
+/* Compare S1 and S2, ignoring case, using collation rules from LOC. */
extern int strcasecmp_l (const char *__s1, const char *__s2, __locale_t
__loc)
__THROW __attribute_pure__ __nonnull ((1, 2, 3));
+/* Compare no more than N chars of S1 and S2, ignoring case, using
+ collation rules from LOC. */
extern int strncasecmp_l (const char *__s1, const char *__s2,
size_t __n, __locale_t __loc)
__THROW __attribute_pure__ __nonnull ((1, 2, 4));
@@ -134,6 +136,4 @@ extern int strncasecmp_l (const char *__s1, const
char *__s2,
__END_DECLS
-#endif /* string.h */
-
#endif /* strings.h */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Don't duplicate declarations between string.h and strings.h
2016-11-16 20:55 [patch] Don't duplicate declarations between string.h and strings.h Zack Weinberg
@ 2016-11-17 0:36 ` Zack Weinberg
2016-11-17 1:03 ` Joseph Myers
2016-11-21 17:17 ` Zack Weinberg
1 sibling, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2016-11-17 0:36 UTC (permalink / raw)
To: GNU C Library, Joseph Myers
On 11/16/2016 03:55 PM, Zack Weinberg wrote:
> I was looking into something else and noticed that all of the
> declarations in strings.h are duplicated in string.h, but not quite
> consistently. This patch cleans that all up
And as a follow-on, here is a patch that makes declaring const-covariant
string functions much tidier. The macros involved are messy, but I
think the reduced duplication in the public header file is worth it.
zw
commit d076c75978afa4b22f1827503c197f90c309586a
Author: Zack Weinberg <zackw@panix.com>
Date: Wed Nov 16 18:34:27 2016 -0500
New mechanism for declaring const-covariant string functions.
Several functions in string.h and strings.h return a pointer into a
buffer passed as their first argument. That pointer logically ought
to inherit the 'const'-ness of the original buffer. There's no way to
express that in C, so all these functions are specified with a
prototype that, as a side-effect, strips the 'const', potentially
leading to bugs:
char *strfoo(const char *buf, ...);
In C++, however, you can get it exactly right via function overloads:
char *strfoo(char *buf, ...);
const char *strfoo(const char *buf, ...);
and C++11 (21.7 [c.strings]) requires the library to do just that.
We were implementing this requirement via a repetitive and error-prone
mess of #ifdefs for each and every one of the affected functions.
This patch absorbs the entire mess into a pair of macros,
__CONST_COV_PROTO and __CONST_COV_BUILTIN, which are far less
error-prone to use, and which make the public header file much nicer
to read, too. They needed some black magic to _implement_, but it's
hiding in a bits header and hopefully nobody need ever change that
file again.
* string/bits/const-covariance.h: New file.
* string/string.h: Use __CONST_COV_PROTO and
__CONST_COV_BUILTIN to
declare memchr, rawmemchr, memrchr, strchr, strrchr, strchrnul,
strpbrk, strstr, strcasestr, memmem, and basename.
* string/strings.h: Likewise for index and rindex.
* include/bits/const-covariance.h: New wrapper.
* include/string.h: Suppress internal definitions when
__cplusplus
is defined, as well as when _ISOMAC is defined.
diff --git a/ChangeLog b/ChangeLog
index 4a5dc8a..18f8296 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2016-11-16 Zack Weinberg <zackw@panix.com>
+ * string/bits/const-covariance.h: New file.
+ * string/string.h: Use __CONST_COV_PROTO and __CONST_COV_BUILTIN to
+ declare memchr, rawmemchr, memrchr, strchr, strrchr, strchrnul,
+ strpbrk, strstr, strcasestr, memmem, and basename.
+ * string/strings.h: Likewise for index and rindex.
+
+ * include/bits/const-covariance.h: New wrapper.
+ * include/string.h: Suppress internal definitions when __cplusplus
+ is defined, as well as when _ISOMAC is defined.
+
+2016-11-16 Zack Weinberg <zackw@panix.com>
+
* string/string.h [__USE_MISC]: Include strings.h.
(__bzero, bcmp, bcopy, bzero, index, rindex)
(strcasecmp, strncasecmp, strcasecmp_l, strncasecmp_l)
diff --git a/include/bits/const-covariance.h
b/include/bits/const-covariance.h
new file mode 100644
index 0000000..564d730
--- /dev/null
+++ b/include/bits/const-covariance.h
@@ -0,0 +1 @@
+#include <string/bits/const-covariance.h>
diff --git a/include/string.h b/include/string.h
index 749e691..4c029cf 100644
--- a/include/string.h
+++ b/include/string.h
@@ -1,6 +1,6 @@
#ifndef _STRING_H
-#ifndef _ISOMAC
+#if !defined _ISOMAC && !defined __cplusplus
#include <sys/types.h>
extern void *__memccpy (void *__dest, const void *__src,
@@ -46,16 +46,16 @@ extern void __bzero (void *__s, size_t __n) __THROW
__nonnull ((1));
extern int __ffs (int __i) __attribute__ ((const));
extern char *__strerror_r (int __errnum, char *__buf, size_t __buflen);
-#endif
/* Get _STRING_ARCH_unaligned. */
#include <string_private.h>
+#endif /* !_ISOMAC && !__cplusplus */
/* Now the real definitions. We do this here since some of the functions
above are defined as macros in the headers. */
#include <string/string.h>
-#ifndef _ISOMAC
+#if !defined _ISOMAC && !defined __cplusplus
extern __typeof (strcoll_l) __strcoll_l;
extern __typeof (strxfrm_l) __strxfrm_l;
extern __typeof (strcasecmp_l) __strcasecmp_l;
@@ -151,13 +151,11 @@ extern __typeof (mempcpy) mempcpy __asm__
("__mempcpy");
extern __typeof (stpcpy) stpcpy __asm__ ("__stpcpy");
#endif
-# ifndef _ISOMAC
-# ifndef index
-# define index(s, c) (strchr ((s), (c)))
-# endif
-# ifndef rindex
-# define rindex(s, c) (strrchr ((s), (c)))
-# endif
+# ifndef index
+# define index(s, c) (strchr ((s), (c)))
+# endif
+# ifndef rindex
+# define rindex(s, c) (strrchr ((s), (c)))
# endif
extern void *__memcpy_chk (void *__restrict __dest,
@@ -185,6 +183,6 @@ extern char *__strcat_chk (char *__restrict __dest,
extern char *__strncat_chk (char *__restrict __dest,
const char *__restrict __src,
size_t __len, size_t __destlen) __THROW;
-#endif
+#endif /* !_ISOMAC && !__cplusplus */
#endif
diff --git a/string/Makefile b/string/Makefile
index 69d3f80..c009872 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -24,7 +24,8 @@ include ../Makeconfig
headers := string.h strings.h memory.h endian.h bits/endian.h \
argz.h envz.h byteswap.h bits/byteswap.h bits/byteswap-16.h \
- bits/string.h bits/string2.h bits/string3.h
+ bits/string.h bits/string2.h bits/string3.h \
+ bits/const-covariance.h
routines := strcat strchr strcmp strcoll strcpy strcspn \
strverscmp strdup strndup \
diff --git a/string/bits/const-covariance.h b/string/bits/const-covariance.h
new file mode 100644
index 0000000..19b3e31
--- /dev/null
+++ b/string/bits/const-covariance.h
@@ -0,0 +1,130 @@
+/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library 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.
+
+ The GNU C Library 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 the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_CONST_COVARIANCE_H
+#define _BITS_CONST_COVARIANCE_H 1
+
+#if !defined _STRING_H && !defined _STRINGS_H
+# error "Never use <bits/const-covariance.h> directly; include
<string.h> or <strings.h> instead."
+#endif
+
+/* This header defines internal-use macros that expand a C prototype
+ declaration like
+
+ extern void *memchr (const void *, int, size_t) attrs;
+
+ to a pair of C++ overloaded function declarations with improved
+ const-correctness:
+
+ extern void *memchr (void *, int, size_t) attrs;
+ extern const void *memchr (const void *, int, size_t) attrs;
+
+ You use them like this:
+
+ __CONST_COV_PROTO (memchr, attrs,
+ void *, __s, int, __c, size_t, __n);
+
+ where the arguments after 'attrs' are the function's arguments,
+ alternating with argument names. The first of these will be used
+ as the const-covariant return type. It should be written without
+ a 'const' qualifier.
+
+ If the compiler has intrinsic knowledge of the function, use
+ __CONST_COV_BUILTIN instead of __CONST_COV_PROTO. In C++ mode,
+ this will also generate inline functions of the form
+
+ __extern_always_inline [const] void *
+ memchr (void *__s, int __c, size_t __n) attrs
+ {
+ return __builtin_memchr (__s, __c, __n);
+ }
+
+ Due to limitations in the preprocessor, these macros support no
+ more than four arguments to any function. This is all that
+ string.h/strings.h currently require.
+
+ Because g++ only accepts throw(), __asm("..."), and
+ __attribute__((whatever)) annotations in a specific order, all
+ functions declared with __CONST_COV_PROTO or defined with
+ __CONST_COV_BUILTIN are automatically marked __THROW. Do not put
+ __THROW in 'attrs'. */
+
+#define __CC_VA_NARGS(...) __CC_VA_NARGS_(__VA_ARGS__, __CC_RSEQ)
+#define __CC_VA_NARGS_(...) __CC_VA_NARGS__(__VA_ARGS__)
+#define __CC_VA_NARGS__(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
+#define __CC_RSEQ 8, 7, 6, 5, 4, 3, 2, 1
+
+#define __CC_2FOR2(op, a, b) op (a, b)
+#define __CC_2FOR4(op, a, b, ...) op (a, b), __CC_2FOR2 (op, __VA_ARGS__)
+#define __CC_2FOR6(op, a, b, ...) op (a, b), __CC_2FOR4 (op, __VA_ARGS__)
+#define __CC_2FOR8(op, a, b, ...) op (a, b), __CC_2FOR6 (op, __VA_ARGS__)
+
+#define __CC_2FOR(op, ...) \
+ __CC_2FOR_ (__CC_VA_NARGS (__VA_ARGS__)) (op, __VA_ARGS__)
+#define __CC_2FOR_(n) __CC_2FOR__ (n)
+#define __CC_2FOR__(n) __CC_2FOR##n
+
+#define __CC_XPROTO(...) (__CC_2FOR (__CC_XPROTO_, __VA_ARGS__))
+#define __CC_XPROTO_(type, name) type name
+
+#define __CC_XCALL(...) (__CC_2FOR (__CC_XCALL_, __VA_ARGS__))
+#define __CC_XCALL_(type, name) name
+
+#if !defined __cplusplus || !__GNUC_PREREQ (4, 4)
+
+# define __CONST_COV_PROTO(name, attrs, rtype, ...) \
+ extern rtype name __CC_XPROTO(const rtype, __VA_ARGS__) __THROW attrs
+
+# define __CONST_COV_BUILTIN(...) __CONST_COV_PROTO (__VA_ARGS__)
+
+#else
+
+# define __CONST_COV_PROTO_BODY(name, attrs, rtype, ...) \
+ extern rtype name __CC_XPROTO(rtype, __VA_ARGS__) \
+ __THROW __asm (#name) attrs; \
+ extern const rtype name __CC_XPROTO(const rtype, __VA_ARGS__) \
+ __THROW __asm (#name) attrs;
+
+# define __CONST_COV_PROTO(...) \
+ extern "C++" \
+ { \
+ __CONST_COV_PROTO_BODY(__VA_ARGS__) \
+ } \
+ struct __require_semicolon
+
+# ifndef __OPTIMIZE__
+# define __CONST_COV_BUILTIN(...) __CONST_COV_PROTO (__VA_ARGS__)
+
+# else
+
+# define __CONST_COV_BUILTIN(name, attrs, rtype, ...) \
+ extern "C++" \
+ { \
+ __CONST_COV_PROTO_BODY (name, attrs, rtype, __VA_ARGS__) \
+ __extern_always_inline rtype \
+ name __CC_XPROTO (rtype, __VA_ARGS__) __THROW \
+ { return __builtin_##name __CC_XCALL (rtype, __VA_ARGS__); } \
+ __extern_always_inline const rtype \
+ name __CC_XPROTO (const rtype, __VA_ARGS__) __THROW \
+ { return __builtin_##name __CC_XCALL (rtype, __VA_ARGS__); } \
+ } \
+ struct __require_semicolon
+
+# endif /* __OPTIMIZE__ */
+#endif /* C++ and GCC >=4.4 */
+
+#endif /* const-covariance.h */
diff --git a/string/string.h b/string/string.h
index ca22cd0..601025b 100644
--- a/string/string.h
+++ b/string/string.h
@@ -36,7 +36,7 @@ __BEGIN_DECLS
#if defined __cplusplus && __GNUC_PREREQ (4, 4)
# define __CORRECT_ISO_CPP_STRING_H_PROTO
#endif
-
+#include <bits/const-covariance.h>
__BEGIN_NAMESPACE_STD
/* Copy N bytes of SRC to DEST. */
@@ -66,61 +66,31 @@ extern void *memset (void *__s, int __c, size_t __n)
__THROW __nonnull ((1));
extern int memcmp (const void *__s1, const void *__s2, size_t __n)
__THROW __attribute_pure__ __nonnull ((1, 2));
-/* Search N bytes of S for C. */
-#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern void *memchr (void *__s, int __c, size_t __n)
- __THROW __asm ("memchr") __attribute_pure__ __nonnull ((1));
-extern const void *memchr (const void *__s, int __c, size_t __n)
- __THROW __asm ("memchr") __attribute_pure__ __nonnull ((1));
-
-# ifdef __OPTIMIZE__
-__extern_always_inline void *
-memchr (void *__s, int __c, size_t __n) __THROW
-{
- return __builtin_memchr (__s, __c, __n);
-}
-
-__extern_always_inline const void *
-memchr (const void *__s, int __c, size_t __n) __THROW
-{
- return __builtin_memchr (__s, __c, __n);
-}
-# endif
-}
-#else
-extern void *memchr (const void *__s, int __c, size_t __n)
- __THROW __attribute_pure__ __nonnull ((1));
-#endif
+/* Search N bytes of S for C.
+ [C] extern void *memchr (const void *s, int c, size_t n);
+ [C++] extern void *memchr (void *s, int c, size_t n);
+ extern const void *memchr (const void *s, int c, size_t n); */
+__CONST_COV_BUILTIN (memchr, __attribute_pure__ __nonnull ((1)),
+ void *, __s, int, __c, size_t, __n);
__END_NAMESPACE_STD
#ifdef __USE_GNU
-/* Search in S for C. This is similar to `memchr' but there is no
- length limit. */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++" void *rawmemchr (void *__s, int __c)
- __THROW __asm ("rawmemchr") __attribute_pure__ __nonnull ((1));
-extern "C++" const void *rawmemchr (const void *__s, int __c)
- __THROW __asm ("rawmemchr") __attribute_pure__ __nonnull ((1));
-# else
-extern void *rawmemchr (const void *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
+/* Search in S for C. This is similar to 'memchr' but there is no
+ length limit.
+ [C] extern void *rawmemchr (const void *s, int c);
+ [C++] extern void *rawmemchr (void *s, int c);
+ extern const void *rawmemchr (const void *s, int c); */
+__CONST_COV_PROTO (rawmemchr, __attribute_pure__ __nonnull ((1)),
+ void *, __s, int, __c);
-/* Search N bytes of S for the final occurrence of C. */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++" void *memrchr (void *__s, int __c, size_t __n)
- __THROW __asm ("memrchr") __attribute_pure__ __nonnull ((1));
-extern "C++" const void *memrchr (const void *__s, int __c, size_t __n)
- __THROW __asm ("memrchr") __attribute_pure__ __nonnull ((1));
-# else
-extern void *memrchr (const void *__s, int __c, size_t __n)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
+/* Search N bytes of S for the final occurrence of C.
+ [C] extern void *memrchr (const void *s, int c, size_t n);
+ [C++] extern void *memrchr (void *s, int c, size_t n);
+ extern const void *memrchr (const void *s, int c, size_t n); */
+__CONST_COV_PROTO (memrchr, __attribute_pure__ __nonnull ((1)),
+ void *, __s, int, __c, size_t, __n);
#endif
-
__BEGIN_NAMESPACE_STD
/* Copy SRC to DEST. */
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
@@ -204,74 +174,30 @@ extern char *strndup (const char *__string, size_t
__n)
#endif
__BEGIN_NAMESPACE_STD
-/* Find the first occurrence of C in S. */
-#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern char *strchr (char *__s, int __c)
- __THROW __asm ("strchr") __attribute_pure__ __nonnull ((1));
-extern const char *strchr (const char *__s, int __c)
- __THROW __asm ("strchr") __attribute_pure__ __nonnull ((1));
+/* Find the first occurrence of C in S.
+ [C] extern char *strchr (const char *s, int c);
+ [C++] extern char *strchr (char *s, int c);
+ extern const char *strchr (const char *s, int c); */
+__CONST_COV_BUILTIN (strchr, __attribute_pure__ __nonnull ((1)),
+ char *, __s, int, __c);
-# ifdef __OPTIMIZE__
-__extern_always_inline char *
-strchr (char *__s, int __c) __THROW
-{
- return __builtin_strchr (__s, __c);
-}
+/* Find the last occurrence of C in S.
+ [C] extern char *strrchr (const char *s, int c);
+ [C++] extern char *strrchr (char *s, int c);
+ extern const char *strrchr (const char *s, int c); */
+__CONST_COV_BUILTIN (strrchr, __attribute_pure__ __nonnull ((1)),
+ char *, __s, int, __c);
-__extern_always_inline const char *
-strchr (const char *__s, int __c) __THROW
-{
- return __builtin_strchr (__s, __c);
-}
-# endif
-}
-#else
-extern char *strchr (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-#endif
-/* Find the last occurrence of C in S. */
-#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern char *strrchr (char *__s, int __c)
- __THROW __asm ("strrchr") __attribute_pure__ __nonnull ((1));
-extern const char *strrchr (const char *__s, int __c)
- __THROW __asm ("strrchr") __attribute_pure__ __nonnull ((1));
-
-# ifdef __OPTIMIZE__
-__extern_always_inline char *
-strrchr (char *__s, int __c) __THROW
-{
- return __builtin_strrchr (__s, __c);
-}
-
-__extern_always_inline const char *
-strrchr (const char *__s, int __c) __THROW
-{
- return __builtin_strrchr (__s, __c);
-}
-# endif
-}
-#else
-extern char *strrchr (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-#endif
__END_NAMESPACE_STD
#ifdef __USE_GNU
/* This function is similar to `strchr'. But it returns a pointer to
- the closing NUL byte in case C is not found in S. */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++" char *strchrnul (char *__s, int __c)
- __THROW __asm ("strchrnul") __attribute_pure__ __nonnull ((1));
-extern "C++" const char *strchrnul (const char *__s, int __c)
- __THROW __asm ("strchrnul") __attribute_pure__ __nonnull ((1));
-# else
-extern char *strchrnul (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
+ the closing NUL byte in case C is not found in S.
+ [C] extern char *strchrnul (const char *s, int c);
+ [C++] extern char *strchrnul (char *s, int c);
+ extern const char *strchrnul (const char *s, int c); */
+__CONST_COV_PROTO (strchrnul, __attribute_pure__ __nonnull ((1)),
+ char *, __s, int, __c);
#endif
__BEGIN_NAMESPACE_STD
@@ -279,65 +205,26 @@ __BEGIN_NAMESPACE_STD
consists entirely of characters not in REJECT. */
extern size_t strcspn (const char *__s, const char *__reject)
__THROW __attribute_pure__ __nonnull ((1, 2));
+
/* Return the length of the initial segment of S which
consists entirely of characters in ACCEPT. */
extern size_t strspn (const char *__s, const char *__accept)
__THROW __attribute_pure__ __nonnull ((1, 2));
-/* Find the first occurrence in S of any character in ACCEPT. */
-#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern char *strpbrk (char *__s, const char *__accept)
- __THROW __asm ("strpbrk") __attribute_pure__ __nonnull ((1, 2));
-extern const char *strpbrk (const char *__s, const char *__accept)
- __THROW __asm ("strpbrk") __attribute_pure__ __nonnull ((1, 2));
-# ifdef __OPTIMIZE__
-__extern_always_inline char *
-strpbrk (char *__s, const char *__accept) __THROW
-{
- return __builtin_strpbrk (__s, __accept);
-}
-
-__extern_always_inline const char *
-strpbrk (const char *__s, const char *__accept) __THROW
-{
- return __builtin_strpbrk (__s, __accept);
-}
-# endif
-}
-#else
-extern char *strpbrk (const char *__s, const char *__accept)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-#endif
-/* Find the first occurrence of NEEDLE in HAYSTACK. */
-#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++"
-{
-extern char *strstr (char *__haystack, const char *__needle)
- __THROW __asm ("strstr") __attribute_pure__ __nonnull ((1, 2));
-extern const char *strstr (const char *__haystack, const char *__needle)
- __THROW __asm ("strstr") __attribute_pure__ __nonnull ((1, 2));
-
-# ifdef __OPTIMIZE__
-__extern_always_inline char *
-strstr (char *__haystack, const char *__needle) __THROW
-{
- return __builtin_strstr (__haystack, __needle);
-}
-
-__extern_always_inline const char *
-strstr (const char *__haystack, const char *__needle) __THROW
-{
- return __builtin_strstr (__haystack, __needle);
-}
-# endif
-}
-#else
-extern char *strstr (const char *__haystack, const char *__needle)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-#endif
+/* Find the first occurrence in S of any character in ACCEPT.
+ [C] extern char *strpbrk (const char *s, const char *accept);
+ [C++] extern char *strpbrk (char *s, const char *accept);
+ extern const char *strpbrk (const char *s, const char *accept); */
+__CONST_COV_BUILTIN (strpbrk, __attribute_pure__ __nonnull ((1, 2)),
+ char *, __s, const char *, __accept);
+/* Find the first occurrence of NEEDLE in HAYSTACK.
+ [C] extern char *strstr (const char *haystack, const char *needle);
+ [C++] extern char *strstr (char *haystack, const char *needle);
+ extern const char *strstr (const char *haystack, const char
*needle);
+ */
+__CONST_COV_BUILTIN (strstr, __attribute_pure__ __nonnull ((1, 2)),
+ char *, __haystack, const char *, __needle);
/* Divide S into tokens separated by characters in DELIM. */
extern char *strtok (char *__restrict __s, const char *__restrict __delim)
@@ -357,26 +244,26 @@ extern char *strtok_r (char *__restrict __s, const
char *__restrict __delim,
#endif
#ifdef __USE_GNU
-/* Similar to `strstr' but this function ignores the case of both
strings. */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++" char *strcasestr (char *__haystack, const char *__needle)
- __THROW __asm ("strcasestr") __attribute_pure__ __nonnull ((1, 2));
-extern "C++" const char *strcasestr (const char *__haystack,
- const char *__needle)
- __THROW __asm ("strcasestr") __attribute_pure__ __nonnull ((1, 2));
-# else
-extern char *strcasestr (const char *__haystack, const char *__needle)
- __THROW __attribute_pure__ __nonnull ((1, 2));
-# endif
-#endif
+/* Similar to 'strstr', but ignores the case of both strings.
+ [C] extern char *strcasestr (const char *haystack, const char
*needle);
+ [C++] extern char *strcasestr (char *haystack, const char *needle);
+ extern const char *strcasestr (const char *haystack,
+ const char *needle); */
+__CONST_COV_PROTO (strcasestr, __attribute_pure__ __nonnull ((1, 2)),
+ char *, __haystack, const char *, __needle);
-#ifdef __USE_GNU
/* Find the first occurrence of NEEDLE in HAYSTACK.
NEEDLE is NEEDLELEN bytes long;
- HAYSTACK is HAYSTACKLEN bytes long. */
-extern void *memmem (const void *__haystack, size_t __haystacklen,
- const void *__needle, size_t __needlelen)
- __THROW __attribute_pure__ __nonnull ((1, 3));
+ HAYSTACK is HAYSTACKLEN bytes long.
+ [C] extern void *memmem (const void *haystack, size_t haystacklen,
+ const void *needle, size_t needlelen);
+ [C++] extern void *memmem (void *haystack, size_t haystacklen,
+ const void *needle, size_t needlelen);
+ extern const void *memmem (const void *haystack, size_t
haystacklen,
+ const void *needle, size_t
needlelen); */
+__CONST_COV_PROTO (memmem, __attribute_pure__ __nonnull ((1, 3)),
+ void *, __haystack, size_t, __haystacklen,
+ const void *, __needle, size_t, __needlelen);
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
last written byte. */
@@ -487,15 +374,12 @@ extern void *memfrob (void *__s, size_t __n)
__THROW __nonnull ((1));
/* Return the file name within directory of FILENAME. We don't
declare the function if the `basename' macro is available (defined
in <libgen.h>) which makes the XPG version of this function
- available. */
-# ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
-extern "C++" char *basename (char *__filename)
- __THROW __asm ("basename") __nonnull ((1));
-extern "C++" const char *basename (const char *__filename)
- __THROW __asm ("basename") __nonnull ((1));
-# else
-extern char *basename (const char *__filename) __THROW __nonnull ((1));
-# endif
+ available.
+ [C] char *basename (const char *filename);
+ [C++] char *basename (char *filename);
+ const char *basename (const char *filename); */
+__CONST_COV_PROTO (basename, __nonnull ((1)),
+ char *, __filename);
# endif
#endif
diff --git a/string/strings.h b/string/strings.h
index f78eca5..a72530a 100644
--- a/string/strings.h
+++ b/string/strings.h
@@ -26,6 +26,7 @@
#if defined __cplusplus && __GNUC_PREREQ (4, 4)
# define __CORRECT_ISO_CPP_STRINGS_H_PROTO
#endif
+#include <bits/const-covariance.h>
__BEGIN_DECLS
@@ -41,61 +42,19 @@ extern void bcopy (const void *__src, void *__dest,
size_t __n)
/* Set N bytes of S to 0. */
extern void bzero (void *__s, size_t __n) __THROW __nonnull ((1));
-/* Find the first occurrence of C in S (same as strchr). */
-# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
-extern "C++"
-{
-extern char *index (char *__s, int __c)
- __THROW __asm ("index") __attribute_pure__ __nonnull ((1));
-extern const char *index (const char *__s, int __c)
- __THROW __asm ("index") __attribute_pure__ __nonnull ((1));
+/* Find the first occurrence of C in S (same as strchr).
+ [C] extern char *index (const char *s, int c);
+ [C++] extern char *index (char *s, int c);
+ extern const char *index (const char *s, int c); */
+__CONST_COV_BUILTIN (index, __attribute_pure__ __nonnull ((1)),
+ char *, __s, int, __c);
-# if defined __OPTIMIZE__
-__extern_always_inline char *
-index (char *__s, int __c) __THROW
-{
- return __builtin_index (__s, __c);
-}
-
-__extern_always_inline const char *
-index (const char *__s, int __c) __THROW
-{
- return __builtin_index (__s, __c);
-}
-# endif
-}
-# else
-extern char *index (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
-
-/* Find the last occurrence of C in S (same as strrchr). */
-# ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO
-extern "C++"
-{
-extern char *rindex (char *__s, int __c)
- __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
-extern const char *rindex (const char *__s, int __c)
- __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1));
-
-# if defined __OPTIMIZE__
-__extern_always_inline char *
-rindex (char *__s, int __c) __THROW
-{
- return __builtin_rindex (__s, __c);
-}
-
-__extern_always_inline const char *
-rindex (const char *__s, int __c) __THROW
-{
- return __builtin_rindex (__s, __c);
-}
-# endif
-}
-# else
-extern char *rindex (const char *__s, int __c)
- __THROW __attribute_pure__ __nonnull ((1));
-# endif
+/* Find the last occurrence of C in S (same as strrchr).
+ [C] extern char *rindex (const char *s, int c);
+ [C++] extern char *rindex (char *s, int c);
+ extern const char *rindex (const char *s, int c); */
+__CONST_COV_BUILTIN (rindex, __attribute_pure__ __nonnull ((1)),
+ char *, __s, int, __c);
#endif
#if defined __USE_MISC || !defined __USE_XOPEN2K8 || defined
__USE_XOPEN2K8XSI
@@ -106,11 +65,11 @@ extern int ffs (int __i) __THROW __attribute_const__;
/* The following two functions are non-standard but necessary for
non-32 bit
platforms. */
-# ifdef __USE_GNU
+#ifdef __USE_GNU
extern int ffsl (long int __l) __THROW __attribute_const__;
__extension__ extern int ffsll (long long int __ll)
__THROW __attribute_const__;
-# endif
+#endif
/* Compare S1 and S2, ignoring case. */
extern int strcasecmp (const char *__s1, const char *__s2)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Don't duplicate declarations between string.h and strings.h
2016-11-17 0:36 ` Zack Weinberg
@ 2016-11-17 1:03 ` Joseph Myers
2016-11-17 3:18 ` Zack Weinberg
0 siblings, 1 reply; 5+ messages in thread
From: Joseph Myers @ 2016-11-17 1:03 UTC (permalink / raw)
To: Zack Weinberg; +Cc: GNU C Library
On Wed, 16 Nov 2016, Zack Weinberg wrote:
> On 11/16/2016 03:55 PM, Zack Weinberg wrote:
> > I was looking into something else and noticed that all of the
> > declarations in strings.h are duplicated in string.h, but not quite
> > consistently. This patch cleans that all up
>
> And as a follow-on, here is a patch that makes declaring const-covariant
> string functions much tidier. The macros involved are messy, but I
> think the reduced duplication in the public header file is worth it.
const-covariance applies equally to wchar.h. Have you designed the macros
to be usable there as well?
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Don't duplicate declarations between string.h and strings.h
2016-11-17 1:03 ` Joseph Myers
@ 2016-11-17 3:18 ` Zack Weinberg
0 siblings, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2016-11-17 3:18 UTC (permalink / raw)
To: Joseph Myers; +Cc: GNU C Library
On 11/16/2016 08:02 PM, Joseph Myers wrote:
> On Wed, 16 Nov 2016, Zack Weinberg wrote:
>
>> On 11/16/2016 03:55 PM, Zack Weinberg wrote:
>>> I was looking into something else and noticed that all of the
>>> declarations in strings.h are duplicated in string.h, but not quite
>>> consistently. This patch cleans that all up
>>
>> And as a follow-on, here is a patch that makes declaring const-covariant
>> string functions much tidier. The macros involved are messy, but I
>> think the reduced duplication in the public header file is worth it.
>
> const-covariance applies equally to wchar.h. Have you designed the macros
> to be usable there as well?
I should have thought to check for other headders needing the same
treatment. They don't save quite as much typing since none of those
functions have __builtin versions, but they work; see for yourself. I
think the comments are needed for the sake of end-users reading the header.
(If this is approved I would squash it together with the earlier patch.)
zw
* wcsmbs/wchar.h: Use __CONST_COV_PROTO to declare wcschr,
wcsrchr, wcschrnul, wcspbrk, wcsstr, wcswcs, and wmemchr.
diff --git a/string/bits/const-covariance.h b/string/bits/const-covariance.h
index bec187b..6378438 100644
--- a/string/bits/const-covariance.h
+++ b/string/bits/const-covariance.h
@@ -18,8 +18,8 @@
#ifndef _BITS_CONST_COVARIANCE_H
#define _BITS_CONST_COVARIANCE_H 1
-#if !defined _STRING_H && !defined _STRINGS_H
-# error "Never use <bits/const-covariance.h> directly; include
<string.h> or <strings.h> instead."
+#if !defined _STRING_H && !defined _STRINGS_H && !defined _WCHAR_H
+# error "Never use <bits/const-covariance.h> directly; include
<string.h>, <strings.h>, or <wchar.h> instead."
#endif
/* This header defines internal-use macros that expand a C prototype
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index 9686fcd..9d4d373 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -70,11 +70,6 @@ typedef __WINT_TYPE__ wint_t;
__END_NAMESPACE_STD
# endif
# endif
-
-/* Tell the caller that we provide correct C++ prototypes. */
-# if defined __cplusplus && __GNUC_PREREQ (4, 4)
-# define __CORRECT_ISO_CPP_WCHAR_H_PROTO
-# endif
#endif
#if (defined _WCHAR_H || defined __need_mbstate_t) && !defined
____mbstate_t_defined
@@ -101,6 +96,12 @@ typedef struct
defined. */
#ifdef _WCHAR_H
+/* Tell the caller that we provide correct C++ prototypes. */
+# if defined __cplusplus && __GNUC_PREREQ (4, 4)
+# define __CORRECT_ISO_CPP_WCHAR_H_PROTO
+# endif
+# include <bits/const-covariance.h>
+
# ifndef __mbstate_t_defined
__BEGIN_NAMESPACE_C99
/* Public type. */
@@ -221,33 +222,29 @@ extern wchar_t *wcsdup (const wchar_t *__s)
__THROW __attribute_malloc__;
#endif
__BEGIN_NAMESPACE_STD
-/* Find the first occurrence of WC in WCS. */
-#ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO
-extern "C++" wchar_t *wcschr (wchar_t *__wcs, wchar_t __wc)
- __THROW __asm ("wcschr") __attribute_pure__;
-extern "C++" const wchar_t *wcschr (const wchar_t *__wcs, wchar_t __wc)
- __THROW __asm ("wcschr") __attribute_pure__;
-#else
-extern wchar_t *wcschr (const wchar_t *__wcs, wchar_t __wc)
- __THROW __attribute_pure__;
-#endif
-/* Find the last occurrence of WC in WCS. */
-#ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO
-extern "C++" wchar_t *wcsrchr (wchar_t *__wcs, wchar_t __wc)
- __THROW __asm ("wcsrchr") __attribute_pure__;
-extern "C++" const wchar_t *wcsrchr (const wchar_t *__wcs, wchar_t __wc)
- __THROW __asm ("wcsrchr") __attribute_pure__;
-#else
-extern wchar_t *wcsrchr (const wchar_t *__wcs, wchar_t __wc)
- __THROW __attribute_pure__;
-#endif
+/* Find the first occurrence of WC in WCS.
+ [C] extern wchar_t *wcschr (const wchar_t *wcs, wchar_t wc);
+ [C++] extern wchar_t *wcschr (wchar_t *wcs, wchar_t wc);
+ extern const wchar_t *wcschr (const wchar_t *wcs, wchar_t wc); */
+__CONST_COV_PROTO (wcschr, __attribute_pure__,
+ wchar_t *, __wcs, wchar_t, __wc);
+
+/* Find the last occurrence of WC in WCS.
+ [C] extern wchar_t *wcsrchr (const wchar_t *wcs, wchar_t wc);
+ [C++] extern wchar_t *wcsrchr (wchar_t *wcs, wchar_t wc);
+ extern const wchar_t *wcsrchr (const wchar_t *wcs, wchar_t wc); */
+__CONST_COV_PROTO (wcsrchr, __attribute_pure__,
+ wchar_t *, __wcs, wchar_t, __wc);
__END_NAMESPACE_STD
#ifdef __USE_GNU
/* This function is similar to `wcschr'. But it returns a pointer to
- the closing NUL wide character in case C is not found in S. */
-extern wchar_t *wcschrnul (const wchar_t *__s, wchar_t __wc)
- __THROW __attribute_pure__;
+ the closing NUL wide character in case C is not found in S.
+ [C] extern wchar_t *wcschrnul (const wchar_t *wcs, wchar_t wc);
+ [C++] extern wchar_t *wcschrnul (wchar_t *wcs, wchar_t wc);
+ extern const wchar_t *wcschrnul (const wchar_t *wcs, wchar_t
wc); */
+__CONST_COV_PROTO (wcschrnul, __attribute_pure__,
+ wchar_t *, __wcs, wchar_t, __wc);
#endif
__BEGIN_NAMESPACE_STD
@@ -259,28 +256,23 @@ extern size_t wcscspn (const wchar_t *__wcs, const
wchar_t *__reject)
consists entirely of wide characters in ACCEPT. */
extern size_t wcsspn (const wchar_t *__wcs, const wchar_t *__accept)
__THROW __attribute_pure__;
-/* Find the first occurrence in WCS of any character in ACCEPT. */
-#ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO
-extern "C++" wchar_t *wcspbrk (wchar_t *__wcs, const wchar_t *__accept)
- __THROW __asm ("wcspbrk") __attribute_pure__;
-extern "C++" const wchar_t *wcspbrk (const wchar_t *__wcs,
- const wchar_t *__accept)
- __THROW __asm ("wcspbrk") __attribute_pure__;
-#else
-extern wchar_t *wcspbrk (const wchar_t *__wcs, const wchar_t *__accept)
- __THROW __attribute_pure__;
-#endif
-/* Find the first occurrence of NEEDLE in HAYSTACK. */
-#ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO
-extern "C++" wchar_t *wcsstr (wchar_t *__haystack, const wchar_t *__needle)
- __THROW __asm ("wcsstr") __attribute_pure__;
-extern "C++" const wchar_t *wcsstr (const wchar_t *__haystack,
- const wchar_t *__needle)
- __THROW __asm ("wcsstr") __attribute_pure__;
-#else
-extern wchar_t *wcsstr (const wchar_t *__haystack, const wchar_t *__needle)
- __THROW __attribute_pure__;
-#endif
+/* Find the first occurrence in WCS of any character in ACCEPT.
+ [C] extern wchar_t *wcspbrk (const wchar_t *wcs, const wchar_t
*accept);
+ [C++] extern wchar_t *wcspbrk (wchar_t *wcs, const wchar_t *accept);
+ extern const wchar_t *wcspbrk (const wchar_t *wcs,
+ const wchar_t *accept); */
+__CONST_COV_PROTO (wcspbrk, __attribute_pure__,
+ wchar_t *, __wcs, const wchar_t *, __accept);
+
+/* Find the first occurrence of NEEDLE in HAYSTACK.
+ [C] extern wchar_t *wcsstr (const wchar_t *haystack,
+ const wchar_t *needle);
+ [C++] extern wchar_t *wcsstr (wchar_t *haystack,
+ const wchar_t *needle);
+ extern const wchar_t *wcsstr (const wchar_t *haystack,
+ const wchar_t *needle); */
+__CONST_COV_PROTO (wcsstr, __attribute_pure__,
+ wchar_t *, __haystack, const wchar_t *, __needle);
/* Divide WCS into tokens separated by characters in DELIM. */
extern wchar_t *wcstok (wchar_t *__restrict __s,
@@ -292,17 +284,15 @@ extern size_t wcslen (const wchar_t *__s) __THROW
__attribute_pure__;
__END_NAMESPACE_STD
#ifdef __USE_XOPEN
-/* Another name for `wcsstr' from XPG4. */
-# ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO
-extern "C++" wchar_t *wcswcs (wchar_t *__haystack, const wchar_t *__needle)
- __THROW __asm ("wcswcs") __attribute_pure__;
-extern "C++" const wchar_t *wcswcs (const wchar_t *__haystack,
- const wchar_t *__needle)
- __THROW __asm ("wcswcs") __attribute_pure__;
-# else
-extern wchar_t *wcswcs (const wchar_t *__haystack, const wchar_t *__needle)
- __THROW __attribute_pure__;
-# endif
+/* Another name for `wcsstr' from XPG4.
+ [C] extern wchar_t *wcswcs (const wchar_t *haystack,
+ const wchar_t *needle);
+ [C++] extern wchar_t *wcswcs (wchar_t *haystack,
+ const wchar_t *needle);
+ extern const wchar_t *wcswcs (const wchar_t *haystack,
+ const wchar_t *needle); */
+__CONST_COV_PROTO (wcswcs, __attribute_pure__,
+ wchar_t *, __haystack, const wchar_t *, __needle);
#endif
#ifdef __USE_XOPEN2K8
@@ -311,19 +301,14 @@ extern size_t wcsnlen (const wchar_t *__s, size_t
__maxlen)
__THROW __attribute_pure__;
#endif
-
__BEGIN_NAMESPACE_STD
-/* Search N wide characters of S for C. */
-#ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO
-extern "C++" wchar_t *wmemchr (wchar_t *__s, wchar_t __c, size_t __n)
- __THROW __asm ("wmemchr") __attribute_pure__;
-extern "C++" const wchar_t *wmemchr (const wchar_t *__s, wchar_t __c,
- size_t __n)
- __THROW __asm ("wmemchr") __attribute_pure__;
-#else
-extern wchar_t *wmemchr (const wchar_t *__s, wchar_t __c, size_t __n)
- __THROW __attribute_pure__;
-#endif
+/* Search N wide characters of S for C.
+ [C] extern wchar_t *wmemchr (const wchar_t *s, wchar_t wc, size_t n);
+ [C++] extern wchar_t *wmemchr (wchar_t *s, wchar_t wc, size_t n);
+ extern const wchar_t *wmemchr (const wchar_t *s, wchar_t wc,
+ size_t n); */
+__CONST_COV_PROTO (wmemchr, __attribute_pure__,
+ wchar_t *, __s, wchar_t, __c, size_t, __n);
/* Compare N wide characters of S1 and S2. */
extern int wmemcmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Don't duplicate declarations between string.h and strings.h
2016-11-16 20:55 [patch] Don't duplicate declarations between string.h and strings.h Zack Weinberg
2016-11-17 0:36 ` Zack Weinberg
@ 2016-11-21 17:17 ` Zack Weinberg
1 sibling, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2016-11-21 17:17 UTC (permalink / raw)
To: GNU C Library
On Wed, Nov 16, 2016 at 3:55 PM, Zack Weinberg <zackw@panix.com> wrote:
> I was looking into something else and noticed that all of the
> declarations in strings.h are duplicated in string.h, but not quite
> consistently. This patch cleans that all up; strings.h is given
> consistent declarations of everything, and then string.h just does
>
> #ifdef __USE_MISC
> # include <strings.h>
> #endif
>
> The prototype of __bzero is moved to include/string.h instead of
> strings.h, since it is an internal name.
>
> Tested on x86-64/linux. OK?
Ping?
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-11-21 17:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-16 20:55 [patch] Don't duplicate declarations between string.h and strings.h Zack Weinberg
2016-11-17 0:36 ` Zack Weinberg
2016-11-17 1:03 ` Joseph Myers
2016-11-17 3:18 ` Zack Weinberg
2016-11-21 17:17 ` Zack Weinberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).