aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/features.h22
-rw-r--r--include/stdio.h11
2 files changed, 32 insertions, 1 deletions
diff --git a/include/features.h b/include/features.h
index dc9f8fa..c9bc534 100644
--- a/include/features.h
+++ b/include/features.h
@@ -140,6 +140,7 @@
#undef __USE_FORTIFY_LEVEL
#undef __KERNEL_STRICT_NAMES
#undef __GLIBC_USE_DEPRECATED_GETS
+#undef __GLIBC_USE_DEPRECATED_SCANF
/* Suppress kernel-name space pollution unless user expressedly asks
for it. */
@@ -401,6 +402,27 @@
# define __GLIBC_USE_DEPRECATED_GETS 1
#endif
+/* GNU formerly extended the scanf functions with modified format
+ specifiers %as, %aS, and %a[...] that allocate a buffer for the
+ input using malloc. This extension conflicts with ISO C99, which
+ defines %a as a standalone format specifier that reads a floating-
+ point number; moreover, POSIX.1-2008 provides the same feature
+ using the modifier letter 'm' instead (%ms, %mS, %m[...]).
+
+ We now follow C99 unless GNU extensions are active and the compiler
+ is specifically in C89 or C++98 mode (strict or not). For
+ instance, with GCC, -std=gnu11 will have C99-compliant scanf with
+ or without -D_GNU_SOURCE, but -std=c89 -D_GNU_SOURCE will have the
+ old extension. */
+#if defined __USE_GNU && \
+ (defined __cplusplus \
+ ? (__cplusplus < 201103L && !defined __GXX_EXPERIMENTAL_CXX0X__) \
+ : (!defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L))
+# define __GLIBC_USE_DEPRECATED_SCANF 1
+#else
+# define __GLIBC_USE_DEPRECATED_SCANF 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/stdio.h b/include/stdio.h
index 1b7da0f..65ccabb 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -64,9 +64,19 @@ extern int __isoc99_vscanf (const char *__restrict __format,
extern int __isoc99_vsscanf (const char *__restrict __s,
const char *__restrict __format,
__gnuc_va_list __arg) __THROW;
+libc_hidden_proto (__isoc99_sscanf)
libc_hidden_proto (__isoc99_vsscanf)
libc_hidden_proto (__isoc99_vfscanf)
+/* Internal uses of sscanf should call the C99-compliant version.
+ Unfortunately, symbol redirection is not transitive, so the
+ __REDIRECT in the public header does not link up with the above
+ libc_hidden_proto. Bridge the gap with a macro. */
+# if !__GLIBC_USE (DEPRECATED_SCANF)
+# undef sscanf
+# define sscanf __isoc99_sscanf
+# endif
+
/* Prototypes for compatibility functions. */
extern FILE *__new_tmpfile (void);
extern FILE *__old_tmpfile (void);
@@ -171,7 +181,6 @@ libc_hidden_proto (__dprintf)
libc_hidden_proto (fprintf)
libc_hidden_proto (vfprintf)
libc_hidden_proto (sprintf)
-libc_hidden_proto (sscanf)
libc_hidden_proto (fwrite)
libc_hidden_proto (perror)
libc_hidden_proto (remove)