This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch zack/string-headers-cleanups created. glibc-2.24-395-g023131a


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, zack/string-headers-cleanups has been created
        at  023131a22cbb7ae20cd285abbcd70568ae82cf55 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=023131a22cbb7ae20cd285abbcd70568ae82cf55

commit 023131a22cbb7ae20cd285abbcd70568ae82cf55
Author: Zack Weinberg <zackw@panix.com>
Date:   Sun Nov 20 23:00:02 2016 -0500

    The bits/types/*.h treatment for stdio and wchar.
    
    wint_t is a little finicky because it might be defined by stddef.h, which
    belongs to the compiler.
    
    In addition to the _types_, a bunch of other declarations shared between
    wctype.h and wchar.h are factored out to their own header.
    
    	* libio/bits/types/FILE.h, libio/bits/types/__FILE.h
    	* wcsmbs/bits/types/mbstate_t.h, wcsmbs/bits/types/__mbstate_t.h
    	* wcsmbs/bits/types/wint_t.h: New single-type definition files.
    	* wctype/bits/wctype-wchar.h: New file holding declarations shared
    	between wctype.h and wchar.h.
    
    	* libio/Makefile, wcsmbs/Makefile, wctype/Makefile
    	Install them.
    
    	* include/bits/types/FILE.h, include/bits/types/__FILE.h
    	* include/bits/types/mbstate_t.h, include/bits/types/__mbstate_t.h
    	* include/bits/types/wint_t.h, include/bits/wcsmbs-wchar.h:
    	New wrappers.
    	* include/stdio.h, include/wchar.h, include/wctype.h:
    	No need to handle __need macros.
    
    	* grp/grp.h, gshadow/gshadow.h, hurd/hurd.h, iconv/gconv.h
    	* libio/stdio.h, mach/mach.h, misc/mntent.h, pwd/pwd.h
    	* shadow/shadow.h, stdio-common/printf.h, wcsmbs/uchar.h
    	* wcsmbs/wchar.h, wctype/wctype.h
    	* sysdeps/generic/_G_config.h, sysdeps/unix/sysv/linux/_G_config.h
    	Use the new files instead of __need macros.

diff --git a/grp/grp.h b/grp/grp.h
index e904ee2..a044876 100644
--- a/grp/grp.h
+++ b/grp/grp.h
@@ -49,8 +49,7 @@ struct group
 
 
 #ifdef __USE_MISC
-# define __need_FILE
-# include <stdio.h>
+# include <bits/types/FILE.h>
 #endif
 
 
diff --git a/gshadow/gshadow.h b/gshadow/gshadow.h
index 2afd8bd..2e251ba 100644
--- a/gshadow/gshadow.h
+++ b/gshadow/gshadow.h
@@ -21,11 +21,9 @@
 #define _GSHADOW_H	1
 
 #include <features.h>
-
 #include <paths.h>
+#include <bits/types/FILE.h>
 
-#define	__need_FILE
-#include <stdio.h>
 #define __need_size_t
 #include <stddef.h>
 
diff --git a/hurd/hurd.h b/hurd/hurd.h
index ec07827..f61569c 100644
--- a/hurd/hurd.h
+++ b/hurd/hurd.h
@@ -141,8 +141,7 @@ extern struct mutex _hurd_brk_lock;
 
 extern int _hurd_set_brk (vm_address_t newbrk);
 
-#define __need_FILE
-#include <stdio.h>
+#include <bits/types/FILE.h>
 
 /* Calls to get and set basic ports.  */
 
diff --git a/iconv/gconv.h b/iconv/gconv.h
index a870280..2afc778 100644
--- a/iconv/gconv.h
+++ b/iconv/gconv.h
@@ -23,9 +23,9 @@
 #define _GCONV_H	1
 
 #include <features.h>
-#define __need_mbstate_t
-#define __need_wint_t
-#include <wchar.h>
+#include <bits/types/__mbstate_t.h>
+#include <bits/types/wint_t.h>
+
 #define __need_size_t
 #define __need_wchar_t
 #include <stddef.h>
diff --git a/include/bits/types/FILE.h b/include/bits/types/FILE.h
new file mode 100644
index 0000000..09b599b
--- /dev/null
+++ b/include/bits/types/FILE.h
@@ -0,0 +1 @@
+#include <libio/bits/types/FILE.h>
diff --git a/include/bits/types/__FILE.h b/include/bits/types/__FILE.h
new file mode 100644
index 0000000..236f60b
--- /dev/null
+++ b/include/bits/types/__FILE.h
@@ -0,0 +1 @@
+#include <libio/bits/types/__FILE.h>
diff --git a/include/bits/types/__mbstate_t.h b/include/bits/types/__mbstate_t.h
new file mode 100644
index 0000000..13e764e
--- /dev/null
+++ b/include/bits/types/__mbstate_t.h
@@ -0,0 +1 @@
+#include <wcsmbs/bits/types/__mbstate_t.h>
diff --git a/include/bits/types/mbstate_t.h b/include/bits/types/mbstate_t.h
new file mode 100644
index 0000000..99ec08a
--- /dev/null
+++ b/include/bits/types/mbstate_t.h
@@ -0,0 +1 @@
+#include <wcsmbs/bits/types/mbstate_t.h>
diff --git a/include/bits/types/wint_t.h b/include/bits/types/wint_t.h
new file mode 100644
index 0000000..f1e373d
--- /dev/null
+++ b/include/bits/types/wint_t.h
@@ -0,0 +1 @@
+#include <wcsmbs/bits/types/wint_t.h>
diff --git a/include/bits/wctype-wchar.h b/include/bits/wctype-wchar.h
new file mode 100644
index 0000000..8273cd7
--- /dev/null
+++ b/include/bits/wctype-wchar.h
@@ -0,0 +1 @@
+#include <wctype/bits/wctype-wchar.h>
diff --git a/include/stdio.h b/include/stdio.h
index cce55c8..c77e5b6 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -1,7 +1,6 @@
 #ifndef _STDIO_H
-# if defined __need_FILE || defined __need___FILE || defined _ISOMAC
-#  include <libio/stdio.h>
-# else
+# include <libio/stdio.h>
+# ifndef _ISOMAC
 /* Force gets to be declared, since we may be compiling gets itself,
    or tests that use it.  */
 #  include <features.h>
@@ -76,11 +75,11 @@ libc_hidden_proto (__isoc99_vfscanf)
 extern FILE *__new_tmpfile (void);
 extern FILE *__old_tmpfile (void);
 
-
-
 #  define __need_size_t
-#  define __need_wint_t
 #  include <stddef.h>
+
+#  include <bits/types/wint_t.h>
+
 /* Generate a unique file name (and possibly open it).  */
 extern int __path_search (char *__tmpl, size_t __tmpl_len,
 			  const char *__dir, const char *__pfx,
diff --git a/include/wchar.h b/include/wchar.h
index e2579a1..6a7af27 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -1,8 +1,6 @@
 #ifndef _WCHAR_H
-#include <wcsmbs/wchar.h>
-
+# include <wcsmbs/wchar.h>
 # ifndef _ISOMAC
-# ifdef _WCHAR_H
 
 extern __typeof (wcscasecmp_l) __wcscasecmp_l;
 extern __typeof (wcsncasecmp_l) __wcsncasecmp_l;
@@ -216,10 +214,4 @@ extern size_t __mbsrtowcs_l (wchar_t *dst, const char **src, size_t len,
 #  define __mbsinit(state) ((state)->__count == 0)
 
 # endif
-# endif
 #endif
-
-/* Undefine all __need_* constants in case we are included to get those
-   constants but the whole file was already read.  */
-#undef __need_mbstate_t
-#undef __need_wint_t
diff --git a/include/wctype.h b/include/wctype.h
index a71b103..cd8af1a 100644
--- a/include/wctype.h
+++ b/include/wctype.h
@@ -1,18 +1,10 @@
 #ifndef _WCTYPE_H
+#include <wctype/wctype.h>
 
 #ifndef _ISOMAC
-/* We try to get wint_t from <stddef.h>, but not all GCC versions define it
-   there.  So define it ourselves if it remains undefined.  */
-# define __need_wint_t
-# include <stddef.h>
-# ifndef _WINT_T
-/* Integral type unchanged by default argument promotions that can
-   hold any value corresponding to members of the extended character
-   set, as well as at least one value that does not correspond to any
-   member of the extended character set.  */
-#  define _WINT_T
-typedef unsigned int wint_t;
-# endif
+
+#if 0
+#include <bits/types/wint_t.h>
 
 /* Need to repeat these prototypes here, as wctype/wctype.h defines all
    these as macros and thus we couldn't add libc_hidden_proto.  */
@@ -25,6 +17,7 @@ extern int iswspace (wint_t __wc);
 extern int iswxdigit (wint_t __wc);
 extern wint_t towlower (wint_t __wc);
 extern wint_t towupper (wint_t __wc);
+#endif
 
 libc_hidden_proto (iswalpha)
 libc_hidden_proto (iswalnum)
@@ -34,11 +27,7 @@ libc_hidden_proto (iswspace)
 libc_hidden_proto (iswxdigit)
 libc_hidden_proto (towlower)
 libc_hidden_proto (towupper)
-#endif
-
-#include <wctype/wctype.h>
 
-#ifndef _ISOMAC
 /* Internal interfaces.  */
 extern int __iswspace (wint_t __wc);
 extern int __iswctype (wint_t __wc, wctype_t __desc);
diff --git a/libio/Makefile b/libio/Makefile
index 0c7751c..b73d18a 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -23,7 +23,8 @@ subdir	:= libio
 include ../Makeconfig
 
 headers	:= stdio.h libio.h _G_config.h bits/stdio.h \
-	   bits/sys_errlist.h bits/stdio2.h bits/stdio-ldbl.h bits/libio-ldbl.h
+	   bits/sys_errlist.h bits/stdio2.h bits/stdio-ldbl.h bits/libio-ldbl.h \
+	   bits/types/FILE.h bits/types/__FILE.h
 
 routines	:=							      \
 	filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen      \
diff --git a/libio/bits/types/FILE.h b/libio/bits/types/FILE.h
new file mode 100644
index 0000000..a4a2740
--- /dev/null
+++ b/libio/bits/types/FILE.h
@@ -0,0 +1,16 @@
+#ifndef __FILE_defined
+#define __FILE_defined 1
+
+struct _IO_FILE;
+
+__BEGIN_NAMESPACE_STD
+/* The opaque type of streams.  This is the definition used elsewhere.  */
+typedef struct _IO_FILE FILE;
+__END_NAMESPACE_STD
+#if defined __USE_LARGEFILE64 || defined __USE_POSIX \
+    || defined __USE_ISOC99 || defined __USE_XOPEN \
+    || defined __USE_POSIX2
+__USING_NAMESPACE_STD(FILE)
+#endif
+
+#endif
diff --git a/libio/bits/types/__FILE.h b/libio/bits/types/__FILE.h
new file mode 100644
index 0000000..06dd79b
--- /dev/null
+++ b/libio/bits/types/__FILE.h
@@ -0,0 +1,7 @@
+#ifndef ____FILE_defined
+#define ____FILE_defined 1
+
+struct _IO_FILE;
+typedef struct _IO_FILE __FILE;
+
+#endif
diff --git a/libio/stdio.h b/libio/stdio.h
index 792604f..f252dc6 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -21,55 +21,21 @@
  */
 
 #ifndef _STDIO_H
+#define _STDIO_H	1
 
-#if !defined __need_FILE && !defined __need___FILE
-# define _STDIO_H	1
-# define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
-# include <bits/libc-header-start.h>
+#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
+#include <bits/libc-header-start.h>
 
 __BEGIN_DECLS
 
-# define __need_size_t
-# define __need_NULL
-# include <stddef.h>
+#define __need_size_t
+#define __need_NULL
+#include <stddef.h>
 
-# include <bits/types.h>
-# define __need_FILE
-# define __need___FILE
-#endif /* Don't need FILE.  */
+#include <bits/types.h>
+#include <bits/types/__FILE.h>
+#include <bits/types/FILE.h>
 
-
-#if !defined __FILE_defined && defined __need_FILE
-
-/* Define outside of namespace so the C++ is happy.  */
-struct _IO_FILE;
-
-__BEGIN_NAMESPACE_STD
-/* The opaque type of streams.  This is the definition used elsewhere.  */
-typedef struct _IO_FILE FILE;
-__END_NAMESPACE_STD
-#if defined __USE_LARGEFILE64 || defined __USE_POSIX \
-    || defined __USE_ISOC99 || defined __USE_XOPEN \
-    || defined __USE_POSIX2
-__USING_NAMESPACE_STD(FILE)
-#endif
-
-# define __FILE_defined	1
-#endif /* FILE not defined.  */
-#undef	__need_FILE
-
-
-#if !defined ____FILE_defined && defined __need___FILE
-
-/* The opaque type of streams.  This is the definition used elsewhere.  */
-typedef struct _IO_FILE __FILE;
-
-# define ____FILE_defined	1
-#endif /* __FILE not defined.  */
-#undef	__need___FILE
-
-
-#ifdef	_STDIO_H
 #define _STDIO_USES_IOSTREAM
 
 #include <libio.h>
@@ -942,5 +908,3 @@ extern void funlockfile (FILE *__stream) __THROW;
 __END_DECLS
 
 #endif /* <stdio.h> included.  */
-
-#endif /* !_STDIO_H */
diff --git a/mach/mach.h b/mach/mach.h
index c7e7c8c..18979e9 100644
--- a/mach/mach.h
+++ b/mach/mach.h
@@ -20,10 +20,8 @@
 
 #define	_MACH_H	1
 
-/* We must include this before using __need_FILE with <stdio.h> below.  */
 #include <features.h>
 
-
 /* Get the basic types used by Mach.  */
 #include <mach/mach_types.h>
 
@@ -79,9 +77,7 @@ extern void
 __mach_msg_destroy (mach_msg_header_t *msg),
 mach_msg_destroy (mach_msg_header_t *msg);
 
-
-#define __need_FILE
-#include <stdio.h>
+#include <bits/types/FILE.h>
 
 /* Open a stream on a Mach device.  */
 extern FILE *mach_open_devstream (mach_port_t device_port, const char *mode);
diff --git a/misc/mntent.h b/misc/mntent.h
index 43c083b..336789d 100644
--- a/misc/mntent.h
+++ b/misc/mntent.h
@@ -20,10 +20,8 @@
 #define	_MNTENT_H	1
 
 #include <features.h>
-#define __need_FILE
-#include <stdio.h>
 #include <paths.h>
-
+#include <bits/types/FILE.h>
 
 /* File listing canonical interesting mount points.  */
 #define	MNTTAB		_PATH_MNTTAB	/* Deprecated alias.  */
diff --git a/pwd/pwd.h b/pwd/pwd.h
index 07455e7..55300f5 100644
--- a/pwd/pwd.h
+++ b/pwd/pwd.h
@@ -59,8 +59,7 @@ struct passwd
 
 
 #ifdef __USE_MISC
-# define __need_FILE
-# include <stdio.h>
+# include <bits/types/FILE.h>
 #endif
 
 
diff --git a/shadow/shadow.h b/shadow/shadow.h
index 010949f..14dbb1c 100644
--- a/shadow/shadow.h
+++ b/shadow/shadow.h
@@ -24,11 +24,11 @@
 
 #include <paths.h>
 
-#define	__need_FILE
-#include <stdio.h>
 #define __need_size_t
 #include <stddef.h>
 
+#include <bits/types/FILE.h>
+
 /* Paths to the user database files.  */
 #define	SHADOW _PATH_SHADOW
 
diff --git a/stdio-common/printf.h b/stdio-common/printf.h
index d731216..e5073fe 100644
--- a/stdio-common/printf.h
+++ b/stdio-common/printf.h
@@ -22,11 +22,12 @@
 
 __BEGIN_DECLS
 
-#define	__need_FILE
-#include <stdio.h>
+#include <bits/types/FILE.h>
+
 #define	__need_size_t
 #define __need_wchar_t
 #include <stddef.h>
+
 #include <stdarg.h>
 
 
diff --git a/sysdeps/generic/_G_config.h b/sysdeps/generic/_G_config.h
index f44a3d4..c49eed3 100644
--- a/sysdeps/generic/_G_config.h
+++ b/sysdeps/generic/_G_config.h
@@ -13,11 +13,12 @@
 #endif
 #define __need_NULL
 #include <stddef.h>
-#define __need_mbstate_t
+
+#include <bits/types/__mbstate_t.h>
 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-# define __need_wint_t
+# include <bits/types/wint_t.h>
 #endif
-#include <wchar.h>
+
 typedef struct
 {
   __off_t __pos;
diff --git a/sysdeps/unix/sysv/linux/_G_config.h b/sysdeps/unix/sysv/linux/_G_config.h
index abec245..3bc6cfd 100644
--- a/sysdeps/unix/sysv/linux/_G_config.h
+++ b/sysdeps/unix/sysv/linux/_G_config.h
@@ -13,11 +13,12 @@
 #endif
 #define __need_NULL
 #include <stddef.h>
-#define __need_mbstate_t
+
+#include <bits/types/__mbstate_t.h>
 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-# define __need_wint_t
+# include <bits/types/wint_t.h>
 #endif
-#include <wchar.h>
+
 typedef struct
 {
   __off_t __pos;
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 9384a10..956abb9 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -22,7 +22,8 @@ subdir	:= wcsmbs
 
 include ../Makeconfig
 
-headers	:= wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h
+headers	:= wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h \
+	   bits/types/__mbstate_t.h bits/types/mbstate_t.h bits/types/wint_t.h
 
 routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 	    wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
diff --git a/wcsmbs/bits/types/__mbstate_t.h b/wcsmbs/bits/types/__mbstate_t.h
new file mode 100644
index 0000000..8eb9537
--- /dev/null
+++ b/wcsmbs/bits/types/__mbstate_t.h
@@ -0,0 +1,19 @@
+#ifndef ____mbstate_t_defined
+#define ____mbstate_t_defined 1
+
+/* Conversion state information.  */
+typedef struct
+{
+  int __count;
+  union
+  {
+# ifdef __WINT_TYPE__
+    __WINT_TYPE__ __wch;
+# else
+    wint_t __wch;
+# endif
+    char __wchb[4];
+  } __value;		/* Value so far.  */
+} __mbstate_t;
+
+#endif
diff --git a/wcsmbs/bits/types/mbstate_t.h b/wcsmbs/bits/types/mbstate_t.h
new file mode 100644
index 0000000..858db38
--- /dev/null
+++ b/wcsmbs/bits/types/mbstate_t.h
@@ -0,0 +1,14 @@
+#ifndef __mbstate_t_defined
+#define __mbstate_t_defined 1
+
+#include <bits/types/__mbstate_t.h>
+
+__BEGIN_NAMESPACE_C99
+typedef __mbstate_t mbstate_t;
+__END_NAMESPACE_C99
+
+#ifdef __USE_GNU
+__USING_NAMESPACE_C99(mbstate_t)
+#endif
+
+#endif
diff --git a/wcsmbs/bits/types/wint_t.h b/wcsmbs/bits/types/wint_t.h
new file mode 100644
index 0000000..26649c0
--- /dev/null
+++ b/wcsmbs/bits/types/wint_t.h
@@ -0,0 +1,27 @@
+#ifndef _BITS_TYPES_WINT_T_H
+#define _BITS_TYPES_WINT_T_H 1
+
+/* Integral type unchanged by default argument promotions that can
+   hold any value corresponding to members of the extended character
+   set, as well as at least one value that does not correspond to any
+   member of the extended character set.  */
+#ifndef __WINT_TYPE__
+# define __WINT_TYPE__ unsigned int
+#endif
+
+/* GCC's stddef.h may or may not define wint_t.  If it does, it defines
+   _WINT_T to indicate that it has.  */
+#ifndef _WINT_T
+# define _WINT_T 1
+typedef __WINT_TYPE__ wint_t;
+#endif
+
+/* GCC's stddef.h may or may not know to put wint_t in namespace std in C++.
+   Fortunately, redundant using-declarations are harmless.  */
+#if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES
+__BEGIN_NAMESPACE_STD
+using ::wint_t;
+__END_NAMESPACE_STD
+#endif
+
+#endif
diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
index ce92b25..11d7198 100644
--- a/wcsmbs/uchar.h
+++ b/wcsmbs/uchar.h
@@ -27,17 +27,7 @@
 
 #define __need_size_t
 #include <stddef.h>
-#define __need_mbstate_t
-#include <wchar.h>
-
-#ifndef __mbstate_t_defined
-__BEGIN_NAMESPACE_C99
-/* Public type.  */
-typedef __mbstate_t mbstate_t;
-__END_NAMESPACE_C99
-# define __mbstate_t_defined 1
-#endif
-
+#include <bits/types/mbstate_t.h>
 
 #if defined __GNUC__ && !defined __USE_ISOCXX11
 /* Define the 16-bit and 32-bit character types.  Use the information
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index 9d4d373..8521b04 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -21,98 +21,36 @@
  */
 
 #ifndef _WCHAR_H
+#define _WCHAR_H 1
 
-#if !defined __need_mbstate_t && !defined __need_wint_t
-# define _WCHAR_H 1
-# define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
-# include <bits/libc-header-start.h>
-#endif
+#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
+#include <bits/libc-header-start.h>
 
-#ifdef _WCHAR_H
 /* Get FILE definition.  */
-# define __need___FILE
-# if defined __USE_UNIX98 || defined __USE_XOPEN2K
-#  define __need_FILE
-# endif
-# include <stdio.h>
-/* Get va_list definition.  */
-# define __need___va_list
-# include <stdarg.h>
-
-# include <bits/wchar.h>
-
-/* Get size_t, wchar_t, wint_t and NULL from <stddef.h>.  */
-# define __need_size_t
-# define __need_wchar_t
-# define __need_NULL
-#endif
-#if defined _WCHAR_H || defined __need_wint_t || !defined __WINT_TYPE__
-# undef __need_wint_t
-# define __need_wint_t
-# include <stddef.h>
-
-/* We try to get wint_t from <stddef.h>, but not all GCC versions define it
-   there.  So define it ourselves if it remains undefined.  */
-# ifndef _WINT_T
-/* Integral type unchanged by default argument promotions that can
-   hold any value corresponding to members of the extended character
-   set, as well as at least one value that does not correspond to any
-   member of the extended character set.  */
-#  define _WINT_T
-typedef unsigned int wint_t;
-# else
-/* Work around problems with the <stddef.h> file which doesn't put
-   wint_t in the std namespace.  */
-#  if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES \
-      && defined __WINT_TYPE__
-__BEGIN_NAMESPACE_STD
-typedef __WINT_TYPE__ wint_t;
-__END_NAMESPACE_STD
-#  endif
-# endif
-#endif
-
-#if (defined _WCHAR_H || defined __need_mbstate_t) && !defined ____mbstate_t_defined
-# define ____mbstate_t_defined	1
-/* Conversion state information.  */
-typedef struct
-{
-  int __count;
-  union
-  {
-# ifdef __WINT_TYPE__
-    __WINT_TYPE__ __wch;
-# else
-    wint_t __wch;
-# endif
-    char __wchb[4];
-  } __value;		/* Value so far.  */
-} __mbstate_t;
+#include <bits/types/__FILE.h>
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+# include <bits/types/FILE.h>
 #endif
-#undef __need_mbstate_t
 
+/* Get va_list definition.  */
+#define __need___va_list
+#include <stdarg.h>
 
-/* The rest of the file is only used if used if __need_mbstate_t is not
-   defined.  */
-#ifdef _WCHAR_H
+#include <bits/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>
+#define __need_size_t
+#define __need_wchar_t
+#define __need_NULL
+#include <stddef.h>
 
-# ifndef __mbstate_t_defined
-__BEGIN_NAMESPACE_C99
-/* Public type.  */
-typedef __mbstate_t mbstate_t;
-__END_NAMESPACE_C99
-#  define __mbstate_t_defined 1
-# endif
+#include <bits/types/wint_t.h>
+#include <bits/types/mbstate_t.h>
 
-#ifdef __USE_GNU
-__USING_NAMESPACE_C99(mbstate_t)
+/* 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 WCHAR_MIN
 /* These constants might also be defined in <inttypes.h>.  */
@@ -863,11 +801,10 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
    the <wctype.h> header must also appear here.  This is probably
    because some X/Open members wrote their implementation before the
    ISO C standard was published and introduced the better solution.
-   We have to provide these definitions for compliance reasons but we
-   do this nonsense only if really necessary.  */
+   In _GNU_SOURCE mode we follow C99 and provide these definitions
+   only in <wctype.h>.  */
 #if defined __USE_UNIX98 && !defined __USE_GNU
-# define __need_iswxxx
-# include <wctype.h>
+# include <bits/wctype-wchar.h>
 #endif
 
 /* Define some macros helping to catch buffer overflows.  */
@@ -881,11 +818,4 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
 
 __END_DECLS
 
-#endif	/* _WCHAR_H defined */
-
 #endif /* wchar.h  */
-
-/* Undefine all __need_* constants in case we are included to get those
-   constants but the whole file was already read.  */
-#undef __need_mbstate_t
-#undef __need_wint_t
diff --git a/wctype/Makefile b/wctype/Makefile
index f4a9aa6..081cf2c 100644
--- a/wctype/Makefile
+++ b/wctype/Makefile
@@ -22,7 +22,7 @@ subdir	:= wctype
 
 include ../Makeconfig
 
-headers		:= wctype.h
+headers		:= wctype.h bits/wctype-wchar.h
 routines	:= wcfuncs wctype iswctype wctrans towctrans \
 		   wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l
 
diff --git a/wctype/bits/wctype-wchar.h b/wctype/bits/wctype-wchar.h
new file mode 100644
index 0000000..b86d1d2
--- /dev/null
+++ b/wctype/bits/wctype-wchar.h
@@ -0,0 +1,189 @@
+/* Copyright (C) 1996-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/>.  */
+
+/*
+ *	ISO C99 Standard: 7.25
+ *	Wide character classification and mapping utilities  <wctype.h>
+ */
+
+#ifndef _BITS_WCTYPE_WCHAR_H
+#define _BITS_WCTYPE_WCHAR_H 1
+
+#if !defined _WCTYPE_H && !defined _WCHAR_H
+#error "Never include <bits/wctype-wchar.h> directly; include <wctype.h> or <wchar.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/types/wint_t.h>
+
+/* The definitions in this header are specified to appear in <wctype.h>
+   in ISO C99, but in <wchar.h> in Unix98.  _GNU_SOURCE follows C99.  */
+
+__BEGIN_NAMESPACE_C99
+/* Scalar type that can hold values which represent locale-specific
+   character classifications.  */
+typedef unsigned long int wctype_t;
+__END_NAMESPACE_C99
+
+# ifndef _ISwbit
+/* The characteristics are stored always in network byte order (big
+   endian).  We define the bit value interpretations here dependent on the
+   machine's byte order.  */
+
+#  include <endian.h>
+#  if __BYTE_ORDER == __BIG_ENDIAN
+#   define _ISwbit(bit)	(1 << (bit))
+#  else /* __BYTE_ORDER == __LITTLE_ENDIAN */
+#   define _ISwbit(bit)	\
+	((bit) < 8 ? (int) ((1UL << (bit)) << 24)			      \
+	 : ((bit) < 16 ? (int) ((1UL << (bit)) << 8)			      \
+	    : ((bit) < 24 ? (int) ((1UL << (bit)) >> 8)			      \
+	       : (int) ((1UL << (bit)) >> 24))))
+#  endif
+
+enum
+{
+  __ISwupper = 0,			/* UPPERCASE.  */
+  __ISwlower = 1,			/* lowercase.  */
+  __ISwalpha = 2,			/* Alphabetic.  */
+  __ISwdigit = 3,			/* Numeric.  */
+  __ISwxdigit = 4,			/* Hexadecimal numeric.  */
+  __ISwspace = 5,			/* Whitespace.  */
+  __ISwprint = 6,			/* Printing.  */
+  __ISwgraph = 7,			/* Graphical.  */
+  __ISwblank = 8,			/* Blank (usually SPC and TAB).  */
+  __ISwcntrl = 9,			/* Control character.  */
+  __ISwpunct = 10,			/* Punctuation.  */
+  __ISwalnum = 11,			/* Alphanumeric.  */
+
+  _ISwupper = _ISwbit (__ISwupper),	/* UPPERCASE.  */
+  _ISwlower = _ISwbit (__ISwlower),	/* lowercase.  */
+  _ISwalpha = _ISwbit (__ISwalpha),	/* Alphabetic.  */
+  _ISwdigit = _ISwbit (__ISwdigit),	/* Numeric.  */
+  _ISwxdigit = _ISwbit (__ISwxdigit),	/* Hexadecimal numeric.  */
+  _ISwspace = _ISwbit (__ISwspace),	/* Whitespace.  */
+  _ISwprint = _ISwbit (__ISwprint),	/* Printing.  */
+  _ISwgraph = _ISwbit (__ISwgraph),	/* Graphical.  */
+  _ISwblank = _ISwbit (__ISwblank),	/* Blank (usually SPC and TAB).  */
+  _ISwcntrl = _ISwbit (__ISwcntrl),	/* Control character.  */
+  _ISwpunct = _ISwbit (__ISwpunct),	/* Punctuation.  */
+  _ISwalnum = _ISwbit (__ISwalnum)	/* Alphanumeric.  */
+};
+# endif /* Not _ISwbit  */
+
+
+__BEGIN_DECLS
+
+__BEGIN_NAMESPACE_C99
+/*
+ * Wide-character classification functions: 7.15.2.1.
+ */
+
+/* Test for any wide character for which `iswalpha' or `iswdigit' is
+   true.  */
+extern int iswalnum (wint_t __wc) __THROW;
+
+/* Test for any wide character for which `iswupper' or 'iswlower' is
+   true, or any wide character that is one of a locale-specific set of
+   wide-characters for which none of `iswcntrl', `iswdigit',
+   `iswpunct', or `iswspace' is true.  */
+extern int iswalpha (wint_t __wc) __THROW;
+
+/* Test for any control wide character.  */
+extern int iswcntrl (wint_t __wc) __THROW;
+
+/* Test for any wide character that corresponds to a decimal-digit
+   character.  */
+extern int iswdigit (wint_t __wc) __THROW;
+
+/* Test for any wide character for which `iswprint' is true and
+   `iswspace' is false.  */
+extern int iswgraph (wint_t __wc) __THROW;
+
+/* Test for any wide character that corresponds to a lowercase letter
+   or is one of a locale-specific set of wide characters for which
+   none of `iswcntrl', `iswdigit', `iswpunct', or `iswspace' is true.  */
+extern int iswlower (wint_t __wc) __THROW;
+
+/* Test for any printing wide character.  */
+extern int iswprint (wint_t __wc) __THROW;
+
+/* Test for any printing wide character that is one of a
+   locale-specific et of wide characters for which neither `iswspace'
+   nor `iswalnum' is true.  */
+extern int iswpunct (wint_t __wc) __THROW;
+
+/* Test for any wide character that corresponds to a locale-specific
+   set of wide characters for which none of `iswalnum', `iswgraph', or
+   `iswpunct' is true.  */
+extern int iswspace (wint_t __wc) __THROW;
+
+/* Test for any wide character that corresponds to an uppercase letter
+   or is one of a locale-specific set of wide character for which none
+   of `iswcntrl', `iswdigit', `iswpunct', or `iswspace' is true.  */
+extern int iswupper (wint_t __wc) __THROW;
+
+/* Test for any wide character that corresponds to a hexadecimal-digit
+   character equivalent to that performed be the functions described
+   in the previous subclause.  */
+extern int iswxdigit (wint_t __wc) __THROW;
+
+/* Test for any wide character that corresponds to a standard blank
+   wide character or a locale-specific set of wide characters for
+   which `iswalnum' is false.  */
+# ifdef __USE_ISOC99
+extern int iswblank (wint_t __wc) __THROW;
+# endif
+
+/*
+ * Extensible wide-character classification functions: 7.15.2.2.
+ */
+
+/* Construct value that describes a class of wide characters identified
+   by the string argument PROPERTY.  */
+extern wctype_t wctype (const char *__property) __THROW;
+
+/* Determine whether the wide-character WC has the property described by
+   DESC.  */
+extern int iswctype (wint_t __wc, wctype_t __desc) __THROW;
+__END_NAMESPACE_C99
+
+
+/*
+ * Wide-character case-mapping functions: 7.15.3.1.
+ */
+
+__BEGIN_NAMESPACE_C99
+/* Scalar type that can hold values which represent locale-specific
+   character mappings.  */
+typedef const __int32_t *wctrans_t;
+__END_NAMESPACE_C99
+#ifdef __USE_GNU
+__USING_NAMESPACE_C99(wctrans_t)
+#endif
+
+__BEGIN_NAMESPACE_C99
+/* Converts an uppercase letter to the corresponding lowercase letter.  */
+extern wint_t towlower (wint_t __wc) __THROW;
+
+/* Converts an lowercase letter to the corresponding uppercase letter.  */
+extern wint_t towupper (wint_t __wc) __THROW;
+__END_NAMESPACE_C99
+
+__END_DECLS
+
+#endif /* bits/wctype-wchar.h.  */
diff --git a/wctype/wctype.h b/wctype/wctype.h
index acbd8df..9ef6749 100644
--- a/wctype/wctype.h
+++ b/wctype/wctype.h
@@ -21,190 +21,21 @@
  */
 
 #ifndef _WCTYPE_H
+#define _WCTYPE_H 1
 
 #include <features.h>
 #include <bits/types.h>
-
-#ifndef __need_iswxxx
-# define _WCTYPE_H	1
-
-/* Get wint_t from <wchar.h>.  */
-# define __need_wint_t
-# include <wchar.h>
+#include <bits/types/wint_t.h>
 
 /* Constant expression of type `wint_t' whose value does not correspond
    to any member of the extended character set.  */
-# ifndef WEOF
-#  define WEOF (0xffffffffu)
-# endif
+#ifndef WEOF
+# define WEOF (0xffffffffu)
 #endif
-#undef __need_iswxxx
-
 
-/* The following part is also used in the <wcsmbs.h> header when compiled
-   in the Unix98 compatibility mode.  */
-#ifndef __iswxxx_defined
-# define __iswxxx_defined	1
-
-__BEGIN_NAMESPACE_C99
-/* Scalar type that can hold values which represent locale-specific
-   character classifications.  */
-typedef unsigned long int wctype_t;
-__END_NAMESPACE_C99
-
-# ifndef _ISwbit
-/* The characteristics are stored always in network byte order (big
-   endian).  We define the bit value interpretations here dependent on the
-   machine's byte order.  */
-
-#  include <endian.h>
-#  if __BYTE_ORDER == __BIG_ENDIAN
-#   define _ISwbit(bit)	(1 << (bit))
-#  else /* __BYTE_ORDER == __LITTLE_ENDIAN */
-#   define _ISwbit(bit)	\
-	((bit) < 8 ? (int) ((1UL << (bit)) << 24)			      \
-	 : ((bit) < 16 ? (int) ((1UL << (bit)) << 8)			      \
-	    : ((bit) < 24 ? (int) ((1UL << (bit)) >> 8)			      \
-	       : (int) ((1UL << (bit)) >> 24))))
-#  endif
-
-enum
-{
-  __ISwupper = 0,			/* UPPERCASE.  */
-  __ISwlower = 1,			/* lowercase.  */
-  __ISwalpha = 2,			/* Alphabetic.  */
-  __ISwdigit = 3,			/* Numeric.  */
-  __ISwxdigit = 4,			/* Hexadecimal numeric.  */
-  __ISwspace = 5,			/* Whitespace.  */
-  __ISwprint = 6,			/* Printing.  */
-  __ISwgraph = 7,			/* Graphical.  */
-  __ISwblank = 8,			/* Blank (usually SPC and TAB).  */
-  __ISwcntrl = 9,			/* Control character.  */
-  __ISwpunct = 10,			/* Punctuation.  */
-  __ISwalnum = 11,			/* Alphanumeric.  */
-
-  _ISwupper = _ISwbit (__ISwupper),	/* UPPERCASE.  */
-  _ISwlower = _ISwbit (__ISwlower),	/* lowercase.  */
-  _ISwalpha = _ISwbit (__ISwalpha),	/* Alphabetic.  */
-  _ISwdigit = _ISwbit (__ISwdigit),	/* Numeric.  */
-  _ISwxdigit = _ISwbit (__ISwxdigit),	/* Hexadecimal numeric.  */
-  _ISwspace = _ISwbit (__ISwspace),	/* Whitespace.  */
-  _ISwprint = _ISwbit (__ISwprint),	/* Printing.  */
-  _ISwgraph = _ISwbit (__ISwgraph),	/* Graphical.  */
-  _ISwblank = _ISwbit (__ISwblank),	/* Blank (usually SPC and TAB).  */
-  _ISwcntrl = _ISwbit (__ISwcntrl),	/* Control character.  */
-  _ISwpunct = _ISwbit (__ISwpunct),	/* Punctuation.  */
-  _ISwalnum = _ISwbit (__ISwalnum)	/* Alphanumeric.  */
-};
-# endif /* Not _ISwbit  */
-
-
-__BEGIN_DECLS
-
-__BEGIN_NAMESPACE_C99
-/*
- * Wide-character classification functions: 7.15.2.1.
- */
-
-/* Test for any wide character for which `iswalpha' or `iswdigit' is
-   true.  */
-extern int iswalnum (wint_t __wc) __THROW;
-
-/* Test for any wide character for which `iswupper' or 'iswlower' is
-   true, or any wide character that is one of a locale-specific set of
-   wide-characters for which none of `iswcntrl', `iswdigit',
-   `iswpunct', or `iswspace' is true.  */
-extern int iswalpha (wint_t __wc) __THROW;
-
-/* Test for any control wide character.  */
-extern int iswcntrl (wint_t __wc) __THROW;
-
-/* Test for any wide character that corresponds to a decimal-digit
-   character.  */
-extern int iswdigit (wint_t __wc) __THROW;
-
-/* Test for any wide character for which `iswprint' is true and
-   `iswspace' is false.  */
-extern int iswgraph (wint_t __wc) __THROW;
-
-/* Test for any wide character that corresponds to a lowercase letter
-   or is one of a locale-specific set of wide characters for which
-   none of `iswcntrl', `iswdigit', `iswpunct', or `iswspace' is true.  */
-extern int iswlower (wint_t __wc) __THROW;
-
-/* Test for any printing wide character.  */
-extern int iswprint (wint_t __wc) __THROW;
-
-/* Test for any printing wide character that is one of a
-   locale-specific et of wide characters for which neither `iswspace'
-   nor `iswalnum' is true.  */
-extern int iswpunct (wint_t __wc) __THROW;
-
-/* Test for any wide character that corresponds to a locale-specific
-   set of wide characters for which none of `iswalnum', `iswgraph', or
-   `iswpunct' is true.  */
-extern int iswspace (wint_t __wc) __THROW;
-
-/* Test for any wide character that corresponds to an uppercase letter
-   or is one of a locale-specific set of wide character for which none
-   of `iswcntrl', `iswdigit', `iswpunct', or `iswspace' is true.  */
-extern int iswupper (wint_t __wc) __THROW;
-
-/* Test for any wide character that corresponds to a hexadecimal-digit
-   character equivalent to that performed be the functions described
-   in the previous subclause.  */
-extern int iswxdigit (wint_t __wc) __THROW;
-
-/* Test for any wide character that corresponds to a standard blank
-   wide character or a locale-specific set of wide characters for
-   which `iswalnum' is false.  */
-# ifdef __USE_ISOC99
-extern int iswblank (wint_t __wc) __THROW;
-# endif
-
-/*
- * Extensible wide-character classification functions: 7.15.2.2.
- */
-
-/* Construct value that describes a class of wide characters identified
-   by the string argument PROPERTY.  */
-extern wctype_t wctype (const char *__property) __THROW;
-
-/* Determine whether the wide-character WC has the property described by
-   DESC.  */
-extern int iswctype (wint_t __wc, wctype_t __desc) __THROW;
-__END_NAMESPACE_C99
-
-
-/*
- * Wide-character case-mapping functions: 7.15.3.1.
- */
-
-__BEGIN_NAMESPACE_C99
-/* Scalar type that can hold values which represent locale-specific
-   character mappings.  */
-typedef const __int32_t *wctrans_t;
-__END_NAMESPACE_C99
-#ifdef __USE_GNU
-__USING_NAMESPACE_C99(wctrans_t)
-#endif
-
-__BEGIN_NAMESPACE_C99
-/* Converts an uppercase letter to the corresponding lowercase letter.  */
-extern wint_t towlower (wint_t __wc) __THROW;
-
-/* Converts an lowercase letter to the corresponding uppercase letter.  */
-extern wint_t towupper (wint_t __wc) __THROW;
-__END_NAMESPACE_C99
-
-__END_DECLS
-
-#endif	/* need iswxxx.  */
-
-
-/* The remaining definitions and declarations must not appear in the
-   <wchar.h> header.  */
-#ifdef _WCTYPE_H
+/* Some definitions from this header also appear in <wchar.h> in
+   Unix98 mode.  */
+#include <bits/wctype-wchar.h>
 
 /*
  * Extensible wide-character mapping functions: 7.15.3.2.
@@ -289,7 +120,6 @@ extern wctype_t wctype_l (const char *__property, __locale_t __locale)
 extern int iswctype_l (wint_t __wc, wctype_t __desc, __locale_t __locale)
      __THROW;
 
-
 /*
  * Wide-character case-mapping functions.
  */
@@ -313,6 +143,4 @@ extern wint_t towctrans_l (wint_t __wc, wctrans_t __desc,
 
 __END_DECLS
 
-#endif	/* __WCTYPE_H defined.  */
-
 #endif /* wctype.h  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b551190f039fcb74978f62f03632e53fac483ef1

commit b551190f039fcb74978f62f03632e53fac483ef1
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, strings.h, and wchar.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 the C++ standard (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 files 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/Makefile (headers): Add it.
    	* 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.
    	* wcsmbs/wchar.h: Likewise for wcschr, wcsrchr, wcschrnul,
    	wcspbrk, wcsstr, wcswcs, and wmemchr.
    	* include/bits/const-covariance.h: New wrapper.

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/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..6378438
--- /dev/null
+++ b/string/bits/const-covariance.h
@@ -0,0 +1,130 @@
+/* Copyright (C) 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 && !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
+   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 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 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.
+   [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));
-
-# ifdef __OPTIMIZE__
-__extern_always_inline char *
-strchr (char *__s, int __c) __THROW
-{
-  return __builtin_strchr (__s, __c);
-}
+/* 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);
+
+/* 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));
-
-#  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 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);
+
+/* 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)
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)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0e458a2b8be25c60ee286c75e6f94dd48d5f765a

commit 0e458a2b8be25c60ee286c75e6f94dd48d5f765a
Author: Zack Weinberg <zackw@panix.com>
Date:   Wed Nov 16 16:20:26 2016 -0500

    Clean up redundancies between string.h and strings.h.
    
    	* 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  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5622d4bc77ec263a25b3b75f663238d03234a37a

commit 5622d4bc77ec263a25b3b75f663238d03234a37a
Author: Zack Weinberg <zackw@panix.com>
Date:   Sun Nov 20 23:00:28 2016 -0500

    squashme

diff --git a/stdio-common/tst-gets.c b/stdio-common/tst-gets.c
index 073bc54..7eb5a39 100644
--- a/stdio-common/tst-gets.c
+++ b/stdio-common/tst-gets.c
@@ -17,9 +17,12 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <stdio.h>
 #include <string.h>
 
+/* Force gets to be declared, since we are testing it. */
+#undef __GLIBC_USE_DEPRECATED_GETS
+#define __GLIBC_USE_DEPRECATED_GETS 1
+#include <stdio.h>
 
 static int
 do_test (void)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=80fc253367be07eea2150c0b0544dea96e94e387

commit 80fc253367be07eea2150c0b0544dea96e94e387
Author: Zack Weinberg <zackw@panix.com>
Date:   Sun Nov 20 20:46:30 2016 -0500

    Always suppress libc-internal declarations for C++ code.
    
    C++ is only used for tests, and some of the internal declarations are
    not C++-safe.  Rather than playing whack-a-mole with problems, just
    turn on _ISOMAC mode for all C++ code.  (It might make sense to do
    this for all IS_IN(nonlib) code as well.)
    
    This flushed out a few problems: test-skeleton.c uses uintptr_t but wasn't
    including <stdint.h>, libio.h used _GNU_SOURCE instead of __USE_GNU
    in one place, and the kludge for not declaring gets() in _GNU_SOURCE
    mode but still having it around for tests and its own definition needed
    some cleanup.
    
    	* include/libc-symbols.h: Define _ISOMAC when __cplusplus is defined.
    	* include/errno.h, include/stdio.h, include/stdlib.h
    	* include/time.h, include/unistd.h, include/wchar.h: No need to
    	check __cplusplus nor use __BEGIN_DECLS/__END_DECLS.
    
    	* test-skeleton.c: Include <stdint.h> when thread-testing API is
    	activated.
    	* libio/libio.h: Use __USE_GNU, not _GNU_SOURCE.
    
    	* include/features.h (__GLIBC_USE_DEPRECATED_GETS): New macro.
    	* libio/stdio.h, libio/bits/stdio2.h: Condition gets on
    	__GLIBC_USE (DEPRECATED_GETS).  Update comments to indicate
    	gets was removed from C++ in C++14.
    	* include/stdio.h [!_ISOMAC]: Force gets to be declared by
    	libio/stdio.h, instead of repeating its declaration.
    	* debug/tst-chk1.c: Force gets to be declared, since we are
    	testing it.  (This file is sometimes compiled with _ISOMAC in
    	effect.)
    	* stdio-common/Makefile (tst-gets.c): Compile with
    	-Wno-deprecated-declarations.

diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
index 478c2fb..3e9d3a5 100644
--- a/debug/tst-chk1.c
+++ b/debug/tst-chk1.c
@@ -16,6 +16,11 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+/* This file tests gets().  Force it to be declared.  */
+#include <features.h>
+#undef __GLIBC_USE_DEPRECATED_GETS
+#define __GLIBC_USE_DEPRECATED_GETS 1
+
 #include <assert.h>
 #include <fcntl.h>
 #include <locale.h>
diff --git a/include/errno.h b/include/errno.h
index 7df41df..73fc32e 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -2,7 +2,7 @@
 
 #include <stdlib/errno.h>
 
-#if defined _ERRNO_H && !defined _ISOMAC && !defined __cplusplus
+#if defined _ERRNO_H && !defined _ISOMAC
 
 # if IS_IN (rtld)
 #  include <dl-sysdep.h>
diff --git a/include/features.h b/include/features.h
index 650d4c5..94feb1d 100644
--- a/include/features.h
+++ b/include/features.h
@@ -370,6 +370,15 @@
 # define __USE_FORTIFY_LEVEL 0
 #endif
 
+/* The function 'gets' existed in C89, but is impossible to use safely.
+   It has been removed from ISO C11, ISO C++14, and _GNU_SOURCE.  */
+#if !defined __USE_ISOC11 \
+    || (defined __cplusplus && __cplusplus <= 201103L)
+# define __GLIBC_USE_DEPRECATED_GETS 1
+#else
+# define __GLIBC_USE_DEPRECATED_GETS 0
+#endif
+
 /* Get definitions of __STDC_* predefined macros, if the compiler has
    not preincluded this header automatically.  */
 #include <stdc-predef.h>
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 1c91f2e..a7d96cc 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -76,6 +76,15 @@
 #define HAVE_ISWCTYPE	1
 #define ENABLE_NLS	1
 
+/* As C++ is only used in tests, and the internal-use declarations
+   found in wrapper headers in include/ are not always C++-safe,
+   instruct those headers not to provide any of those declarations
+   when compiling C++.  */
+
+#ifdef __cplusplus
+# define _ISOMAC 1
+#endif
+
 /* The symbols in all the user (non-_) macros are C symbols.  */
 
 #ifndef __SYMBOL_PREFIX
diff --git a/include/stdio.h b/include/stdio.h
index 30e737e..cce55c8 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -2,10 +2,14 @@
 # if defined __need_FILE || defined __need___FILE || defined _ISOMAC
 #  include <libio/stdio.h>
 # else
+/* Force gets to be declared, since we may be compiling gets itself,
+   or tests that use it.  */
+#  include <features.h>
+#  undef __GLIBC_USE_DEPRECATED_GETS
+#  define __GLIBC_USE_DEPRECATED_GETS 1
 #  include <libio/stdio.h>
 
 /* Now define the internal interfaces.  */
-__BEGIN_DECLS
 
 extern int __fcloseall (void);
 extern int __snprintf (char *__restrict __s, size_t __maxlen,
@@ -30,7 +34,6 @@ extern int __vsscanf (const char *__restrict __s,
 		      _G_va_list __arg)
      __attribute__ ((__format__ (__scanf__, 2, 0)));
 
-#  ifndef __cplusplus
 extern int __sprintf_chk (char *, int, size_t, const char *, ...) __THROW;
 extern int __snprintf_chk (char *, size_t, int, size_t, const char *, ...)
      __THROW;
@@ -52,7 +55,6 @@ extern int __obstack_printf_chk (struct obstack *, int, const char *, ...)
      __THROW;
 extern int __obstack_vprintf_chk (struct obstack *, int, const char *,
 				  _G_va_list) __THROW;
-#  endif
 
 extern int __isoc99_fscanf (FILE *__restrict __stream,
 			    const char *__restrict __format, ...) __wur;
@@ -181,28 +183,8 @@ libc_hidden_proto (__vasprintf_chk)
 libc_hidden_proto (__vdprintf_chk)
 libc_hidden_proto (__obstack_vprintf_chk)
 
-/* The <stdio.h> header does not include the declaration for gets
-   anymore when compiling with _GNU_SOURCE.  Provide a copy here.  */
-extern char *gets (char *__s);
-#  if __USE_FORTIFY_LEVEL > 0
-extern char *__gets_chk (char *__str, size_t) __wur;
-extern char *__REDIRECT (__gets_warn, (char *__str), gets)
-     __wur __warnattr ("please use fgets or getline instead, gets can't "
-		       "specify buffer size");
-
-__fortify_function __wur char *
-gets (char *__str)
-{
-  if (__bos (__str) != (size_t) -1)
-    return __gets_chk (__str, __bos (__str));
-  return __gets_warn (__str);
-}
-#  endif
-
 extern FILE * __fmemopen (void *buf, size_t len, const char *mode);
 libc_hidden_proto (__fmemopen)
 
-__END_DECLS
 # endif
-
 #endif
diff --git a/include/stdlib.h b/include/stdlib.h
index 352339e..8039876 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -13,8 +13,6 @@
 #if !defined __Need_M_And_C && !defined _ISOMAC
 # include <sys/stat.h>
 
-__BEGIN_DECLS
-
 extern __typeof (strtol_l) __strtol_l;
 extern __typeof (strtoul_l) __strtoul_l;
 extern __typeof (strtoll_l) __strtoll_l;
@@ -265,8 +263,6 @@ extern __typeof (unsetenv) unsetenv attribute_hidden;
 extern __typeof (__strtoul_internal) __strtoul_internal attribute_hidden;
 # endif
 
-__END_DECLS
-
 #endif
 
 #undef __Need_M_And_C
diff --git a/include/time.h b/include/time.h
index 684ceb8..8fe1818 100644
--- a/include/time.h
+++ b/include/time.h
@@ -4,8 +4,6 @@
 #ifndef _ISOMAC
 # include <xlocale.h>
 
-__BEGIN_DECLS
-
 extern __typeof (strftime_l) __strftime_l;
 libc_hidden_proto (__strftime_l)
 extern __typeof (strptime_l) __strptime_l;
@@ -112,7 +110,5 @@ extern double __difftime (time_t time1, time_t time0);
    actual clock ID.  */
 #define CLOCK_IDFIELD_SIZE	3
 
-__END_DECLS
-
 #endif
 #endif
diff --git a/include/unistd.h b/include/unistd.h
index 16d68a1..fbcea1b 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -2,7 +2,6 @@
 # include <posix/unistd.h>
 
 # ifndef _ISOMAC
-__BEGIN_DECLS
 
 libc_hidden_proto (_exit, __noreturn__)
 rtld_hidden_proto (_exit, __noreturn__)
@@ -188,7 +187,5 @@ extern int __getlogin_r_loginuid (char *name, size_t namesize)
 extern __typeof (__access) __access_noerrno attribute_hidden;
 #  endif
 
-__END_DECLS
 # endif
-
 #endif
diff --git a/include/wchar.h b/include/wchar.h
index 6272130..e2579a1 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -172,7 +172,6 @@ extern int __vfwprintf (__FILE *__restrict __s,
 			const wchar_t *__restrict __format,
 			__gnuc_va_list __arg)
      /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */;
-#ifndef __cplusplus
 extern int __vfwprintf_chk (FILE *__restrict __s, int __flag,
 			    const wchar_t *__restrict __format,
 			    __gnuc_va_list __arg)
@@ -184,7 +183,6 @@ extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
      /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
 libc_hidden_proto (__vfwprintf_chk)
 libc_hidden_proto (__vswprintf_chk)
-#endif
 
 extern int __isoc99_fwscanf (__FILE *__restrict __stream,
 			     const wchar_t *__restrict __format, ...);
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
index fa3be79..df9662c 100644
--- a/libio/bits/stdio2.h
+++ b/libio/bits/stdio2.h
@@ -222,8 +222,7 @@ __NTH (obstack_vprintf (struct obstack *__restrict __obstack,
 
 #endif
 
-#if !defined __USE_ISOC11 \
-    || (defined __cplusplus && __cplusplus <= 201103L && !defined __USE_GNU)
+#if __GLIBC_USE (DEPRECATED_GETS)
 extern char *__gets_chk (char *__str, size_t) __wur;
 extern char *__REDIRECT (__gets_warn, (char *__str), gets)
      __wur __warnattr ("please use fgets or getline instead, gets can't "
diff --git a/libio/libio.h b/libio/libio.h
index efd09f1..f4ead83 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -353,7 +353,7 @@ typedef int __io_seek_fn (void *__cookie, _IO_off64_t *__pos, int __w);
 typedef int __io_close_fn (void *__cookie);
 
 
-#ifdef _GNU_SOURCE
+#ifdef __USE_GNU
 /* User-visible names for the above.  */
 typedef __io_read_fn cookie_read_function_t;
 typedef __io_write_fn cookie_write_function_t;
diff --git a/libio/stdio.h b/libio/stdio.h
index e37f901..792604f 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -625,16 +625,13 @@ __BEGIN_NAMESPACE_STD
 extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
      __wur;
 
-#if !defined __USE_ISOC11 \
-    || (defined __cplusplus && __cplusplus <= 201103L)
+#if __GLIBC_USE (DEPRECATED_GETS)
 /* Get a newline-terminated string from stdin, removing the newline.
-   DO NOT USE THIS FUNCTION!!  There is no limit on how much it will read.
 
-   The function has been officially removed in ISO C11.  This opportunity
-   is used to also remove it from the GNU feature list.  It is now only
-   available when explicitly using an old ISO C, Unix, or POSIX standard.
-   GCC defines _GNU_SOURCE when building C++ code and the function is still
-   in C++11, so it is also available for C++.
+   This function is impossible to use safely.  It has been officially
+   removed from ISO C11 and ISO C++14, and we have also removed it
+   from the _GNU_SOURCE feature list.  It remains available when
+   explicitly using an old ISO C, Unix, or POSIX standard.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 4c4834b..dcbf103 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -141,6 +141,9 @@ CFLAGS-scanf15.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \
 CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \
 		   -I../wctype
 
+# tst-gets.c tests a deprecated function.
+CFLAGS-tst-gets.c += -Wno-deprecated-declarations
+
 CPPFLAGS += $(libio-mtsafe)
 
 $(objpfx)tst-setvbuf1.out: /dev/null $(objpfx)tst-setvbuf1
diff --git a/test-skeleton.c b/test-skeleton.c
index fa457be..c7954ca 100644
--- a/test-skeleton.c
+++ b/test-skeleton.c
@@ -611,6 +611,7 @@ main (int argc, char *argv[])
 /* The following functionality is only available if <pthread.h> was
    included before this file.  */
 #ifdef _PTHREAD_H
+#include <stdint.h>
 
 /* Call pthread_sigmask with error checking.  */
 static void

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]