Message ID | 20181225112654.23204-1-zackw@panix.com |
---|---|
State | New |
Headers | show |
Series | [v2] Use C99-compliant scanf under _GNU_SOURCE with modern compilers. | expand |
On Dez 25 2018, Zack Weinberg <zackw@panix.com> wrote: > * A complete build-many-glibcs run reports no errors. > (Still probably needs testing on an architecture where the > ldbl-compat tests are actually *run*, not just compiled.) I've started a test build. https://build.opensuse.org/project/monitor/home:Andreas_Schwab:glibc:test Andreas.
On 25/12/18 4:56 PM, Zack Weinberg wrote: > Changes since previous version of patch: > > * The wide versions of *scanf are now included in the change. > This was an oversight in all previous iterations -- I always > forget that the wide I/O functions are declared in wchar.h, > not stdio.h. > > * Redirection of internal sscanf calls to __GI___isoc99_scanf > is now handled centrally, in include/stdio.h. Turns out there > were quite a few more than two files that needed to do this. > (Still open to suggestions that don't involve #define.) > > * A complete build-many-glibcs run reports no errors. > (Still probably needs testing on an architecture where the > ldbl-compat tests are actually *run*, not just compiled.) > > I'm traveling for the next two weeks but I will still be responding > to email. > > zw > > --- 8< --- > > The only difference between noncompliant and C99-compliant scanf is > that the former accepts the archaic GNU extension '%as' (also %aS and > %a[...]) meaning to allocate space for the input string with malloc. > This extension conflicts with C99's use of %a as a format _type_ > meaning to read a floating-point number; POSIX.1-2008 standardized > equivalent functionality using the modifier letter 'm' instead (%ms, > %mS, %m[...]). > > The extension was already disabled in most conformance modes: > specifically, any mode that doesn't involve _GNU_SOURCE and _does_ > involve either strict conformance to C99 or loose conformance to both > C99 and POSIX.1-2001 would get the C99-compliant scanf. With > compilers new enough to use -std=gnu11 instead of -std=gnu89, or > equivalent, that includes the default mode. > > This patch tightens things up further: you now get C99-compliant scanf > in all configurations except when _GNU_SOURCE is defined *and* > __STDC_VERSION__ or __cplusplus (whichever is relevant) indicates > C89/C++98. This leaves the old scanf available under e.g. -std=c89 > -D_GNU_SOURCE, but removes it from e.g. -std=gnu11 -D_GNU_SOURCE (it > was already not present under -std=gnu11 without -D_GNU_SOURCE) and > from -std=gnu89 without -D_GNU_SOURCE. > > There needs to be an internal override so we can compile the > noncompliant scanf itself. This is the same problem we had when we > removed 'gets' from _GNU_SOURCE and it's dealt with the same way: > there's a new __GLIBC_USE symbol, DEPRECATED_SCANF, which defaults to > off under the appropriate conditions for external code, but can be > overridden by individual files within stdio. > > We also run into problems with PLT bypass for internal uses of sscanf, > because libc_hidden_proto uses __REDIRECT and so does the logic in > stdio.h for choosing which implementation of scanf to use; __REDIRECT > isn't transitive, so include/stdio.h needs to bridge the gap with a > macro. As far as I can tell, sscanf is the only function in this > family that's internally called by unrelated code. I'm open to better > ideas if anyone has one. N.B. I would accept "internal code shouldn't > call *scanf ever" as a better idea, but there are several internal > uses and some of them are pretty complicated, I don't want to hold up > this patch for that. > > On a related note, the interaction of the C99/not-C99 scanf redirect > with the __LDBL_COMPAT scanf redirect was complicated, confusing, and > possibly wrong. I tried to match the intent rather than the letter of > the previous behavior. I do not have access to physical hardware for > which __LDBL_COMPAT is relevant, so my ability to test it is limited. > Careful review and maybe even some volunteer testing would be > appreciated. > > Finally, there are several tests in stdio-common that use the > extension. bug21 is a regression test for a crash, and still > exercises the relevant code if changed to use %ms instead of %as. > scanf14 through scanf17 are more complicated since they are actually > testing the subtleties of the extension - under what circumstances is > 'a' treated as a modifier letter, etc. My approach here is to > duplicate scanf14.c and scanf16.c; the originals change to use %ms > instead, the copies select precisely the right conformance mode to get > %as with the old GNU meaning, plus everything else they need (it's not > as simple as saying -std=gnu89, unfortunately). scanf15 and scanf17 > become simpler because they no longer need to avoid _GNU_SOURCE, and > all of them no longer need diagnostic overrides. Yay! > > * include/features.h (__GLIBC_USE_DEPRECATED_SCANF): New __GLIBC_USE > parameter. Only use deprecated scanf when __USE_GNU is defined > and __STDC_VERSION__ is less than 199901L or __cplusplus is less > than 201103L, whichever is relevant for the language being compiled. > > * libio/stdio.h, libio/bits/stdio-ldbl.h: Decide whether or > not to redirect scanf, fscanf, sscanf, vscanf, vfscanf, and > vsscanf to their __isoc99_ variants based only on > __GLIBC_USE(DEPRECATED_SCANF). > * wcsmbs/wchar.h: wcsmbs/bits/wchar-ldbl.h: Likewise for > wscanf, fwscanf, swscanf, vwscanf, vfwscanf, and vswscanf. > > * libio/iovsscanf.c > * libio/fwscanf.c > * libio/iovswscanf.c > * libio/swscanf.c > * libio/vscanf.c > * libio/vwscanf.c > * libio/wscanf.c > * stdio-common/fscanf.c > * stdio-common/scanf.c > * stdio-common/vfscanf.c > * stdio-common/vfwscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-compat.c > * sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-scanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c > * sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c: > Override __GLIBC_USE_DEPRECATED_SCANF to 1. > > * stdio-common/sscanf.c: Likewise. Remove ldbl_hidden_def for __sscanf. > * stdio-common/isoc99_sscanf.c: Add libc_hidden_def for __isoc99_sscanf. > * include/stdio.h: Provide libc_hidden_proto for __isoc99_sscanf, > not sscanf. > [!__GLIBC_USE(DEPRECATED_SCANF)]: Define sscanf as __isoc99_scanf > with a preprocessor macro. > > * stdio-common/bug21.c, stdio-common/scanf14.c: > Use %ms instead of %as, %mS instead of %aS, %m[] instead of %a[]; > remove DIAG_IGNORE_NEEDS_COMMENT for -Wformat. > * stdio-common/scanf16.c: Likewise. Add __attribute__((format(scanf))) > to xscanf, xfscanf, xsscanf. > > * stdio-common/scanf14a.c: New copy of scanf14.c which still uses > %as, %aS, %a[]. Use conformance mode -std=gnu89, > _POSIX_C_SOURCE=199506L, _XOPEN_SOURCE=1, _XOPEN_SOURCE_EXTENDED=1, > which will use the nonconformant scanf implementation. > Remove DIAG_IGNORE_NEEDS_COMMENT for -Wformat. > * stdio-common/scanf16a.c: New copy of scanf16.c which still uses > %as, %aS, %a[]. Use conformance mode -std=gnu89, > _POSIX_C_SOURCE=199506L, _XOPEN_SOURCE=1, _XOPEN_SOURCE_EXTENDED=1, > _ISOC99_SOURCE=1, which will use the nonconformant scanf > implementation. Add __attribute__((format(scanf))) to xscanf, > xfscanf, xsscanf. > > * stdio-common/scanf15.c, stdio-common/scanf17.c: No need to > override feature selection macros or provide definitions of u_char etc. > * stdio-common/Makefile (tests): Add scanf14a and scanf16a. > (CFLAGS-scanf15.c, CFLAGS-scanf17.c): Remove. > (CFLAGS-scanf14a.c, CFLAGS-scanf16a.c): New. The two new tests are missing Copyright headers. With those added the change looks OK to me. Thanks, Siddhesh > --- > NEWS | 17 +++ > include/features.h | 22 +++ > include/stdio.h | 11 +- > libio/bits/stdio-ldbl.h | 7 +- > libio/fwscanf.c | 5 + > libio/iovsscanf.c | 5 + > libio/iovswscanf.c | 5 + > libio/stdio.h | 22 ++- > libio/swscanf.c | 5 + > libio/vscanf.c | 5 + > libio/vwscanf.c | 5 + > libio/wscanf.c | 5 + > stdio-common/Makefile | 14 +- > stdio-common/bug21.c | 11 +- > stdio-common/fscanf.c | 5 + > stdio-common/isoc99_sscanf.c | 1 + > stdio-common/scanf.c | 5 + > stdio-common/scanf14.c | 35 ++--- > stdio-common/scanf14a.c | 126 +++++++++++++++++ > stdio-common/scanf15.c | 14 +- > stdio-common/scanf16.c | 20 +-- > stdio-common/scanf16a.c | 156 +++++++++++++++++++++ > stdio-common/scanf17.c | 14 +- > stdio-common/sscanf.c | 6 +- > stdio-common/vfscanf.c | 5 + > stdio-common/vfwscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-scanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c | 5 + > sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c | 5 + > wcsmbs/bits/wchar-ldbl.h | 7 +- > wcsmbs/wchar.h | 10 +- > 42 files changed, 515 insertions(+), 103 deletions(-) > create mode 100644 stdio-common/scanf14a.c > create mode 100644 stdio-common/scanf16a.c > > diff --git a/NEWS b/NEWS > index cd29ec7c81..5a682832a6 100644 > --- a/NEWS > +++ b/NEWS > @@ -68,6 +68,23 @@ Deprecated and removed features, and other changes affecting compatibility: > used by the Linux kernel. This affects the size and layout of those > structures. > > +* An archaic GNU extension to scanf, under which '%as', '%aS', and '%a[...]' > + meant to scan a string and allocate space for it with malloc, is now > + restricted to programs compiled in C89 or C++98 mode with _GNU_SOURCE > + defined. This extension conflicts with C99's use of '%a' to scan a > + hexadecimal floating-point number, which is now available to programs > + compiled as C99 or C++11 or higher, regardless of _GNU_SOURCE. > + > + POSIX.1-2008 includes the feature of allocating a buffer for string input > + with malloc, using the modifier letter 'm' instead. Programs using > + '%as', '%aS', or '%a[...]' with the old GNU meaning should change to > + '%ms', '%mS', or '%m[...]' respectively. Programs that wish to use the > + C99 '%a' no longer need to avoid _GNU_SOURCE. > + > + GCC's -Wformat warnings can detect most uses of this extension, as long > + as all functions that call vscanf, vfscanf, or vsscanf are annotated with > + __attribute__ ((format (scanf, ...))). > + > Changes to build and runtime requirements: > > * Python 3.4 or later is required to build the GNU C Library. > diff --git a/include/features.h b/include/features.h > index 5bed0a4996..e6177f80f9 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 1b7da0f74d..65ccabbb05 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) > diff --git a/libio/bits/stdio-ldbl.h b/libio/bits/stdio-ldbl.h > index 99d9bcc233..dfcbe5375a 100644 > --- a/libio/bits/stdio-ldbl.h > +++ b/libio/bits/stdio-ldbl.h > @@ -26,9 +26,7 @@ __LDBL_REDIR_DECL (sprintf) > __LDBL_REDIR_DECL (vfprintf) > __LDBL_REDIR_DECL (vprintf) > __LDBL_REDIR_DECL (vsprintf) > -#if defined __USE_ISOC99 && !defined __USE_GNU \ > - && !defined __REDIRECT \ > - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) > +#if !__GLIBC_USE (DEPRECATED_SCANF) > __LDBL_REDIR1_DECL (fscanf, __nldbl___isoc99_fscanf) > __LDBL_REDIR1_DECL (scanf, __nldbl___isoc99_scanf) > __LDBL_REDIR1_DECL (sscanf, __nldbl___isoc99_sscanf) > @@ -44,8 +42,7 @@ __LDBL_REDIR_DECL (vsnprintf) > #endif > > #ifdef __USE_ISOC99 > -# if !defined __USE_GNU && !defined __REDIRECT \ > - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) > +# if !__GLIBC_USE (DEPRECATED_SCANF) > __LDBL_REDIR1_DECL (vfscanf, __nldbl___isoc99_vfscanf) > __LDBL_REDIR1_DECL (vscanf, __nldbl___isoc99_vscanf) > __LDBL_REDIR1_DECL (vsscanf, __nldbl___isoc99_vsscanf) > diff --git a/libio/fwscanf.c b/libio/fwscanf.c > index ce4b35d31d..32cb9fb699 100644 > --- a/libio/fwscanf.c > +++ b/libio/fwscanf.c > @@ -15,6 +15,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <libioP.h> > #include <stdarg.h> > #include <stdio.h> > diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c > index ee6a99ec6a..69de5a09b6 100644 > --- a/libio/iovsscanf.c > +++ b/libio/iovsscanf.c > @@ -24,6 +24,11 @@ > This exception applies to code released by its copyright holders > in files containing the exception. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "strfile.h" > > int > diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c > index cb9cbe15cc..f4b4657c16 100644 > --- a/libio/iovswscanf.c > +++ b/libio/iovswscanf.c > @@ -24,6 +24,11 @@ > This exception applies to code released by its copyright holders > in files containing the exception. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <wchar.h> > #include "strfile.h" > > diff --git a/libio/stdio.h b/libio/stdio.h > index 739e08610d..86e7015655 100644 > --- a/libio/stdio.h > +++ b/libio/stdio.h > @@ -399,13 +399,11 @@ extern int scanf (const char *__restrict __format, ...) __wur; > extern int sscanf (const char *__restrict __s, > const char *__restrict __format, ...) __THROW; > > -#if defined __USE_ISOC99 && !defined __USE_GNU \ > - && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ > - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) > +/* For historical reasons, the C99-compliant versions of the scanf > + functions are at alternative names. When __LDBL_COMPAT is in > + effect, this is handled in bits/stdio-ldbl.h. */ > +#if !__GLIBC_USE (DEPRECATED_SCANF) && !defined __LDBL_COMPAT > # ifdef __REDIRECT > -/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ > - GNU extension which conflicts with valid %a followed by letter > - s, S or [. */ > extern int __REDIRECT (fscanf, (FILE *__restrict __stream, > const char *__restrict __format, ...), > __isoc99_fscanf) __wur; > @@ -447,13 +445,9 @@ extern int vsscanf (const char *__restrict __s, > const char *__restrict __format, __gnuc_va_list __arg) > __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); > > -# if !defined __USE_GNU \ > - && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ > - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) > -# ifdef __REDIRECT > -/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ > - GNU extension which conflicts with valid %a followed by letter > - s, S or [. */ > +/* Same redirection as above for the v*scanf family. */ > +# if !__GLIBC_USE (DEPRECATED_SCANF) > +# if defined __REDIRECT && !defined __LDBL_COMPAT > extern int __REDIRECT (vfscanf, > (FILE *__restrict __s, > const char *__restrict __format, __gnuc_va_list __arg), > @@ -467,7 +461,7 @@ extern int __REDIRECT_NTH (vsscanf, > const char *__restrict __format, > __gnuc_va_list __arg), __isoc99_vsscanf) > __attribute__ ((__format__ (__scanf__, 2, 0))); > -# else > +# elif !defined __REDIRECT > extern int __isoc99_vfscanf (FILE *__restrict __s, > const char *__restrict __format, > __gnuc_va_list __arg) __wur; > diff --git a/libio/swscanf.c b/libio/swscanf.c > index 90f721cc51..560f4e3d3e 100644 > --- a/libio/swscanf.c > +++ b/libio/swscanf.c > @@ -15,6 +15,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <stdarg.h> > #include "strfile.h" > > diff --git a/libio/vscanf.c b/libio/vscanf.c > index a3e2dd43f2..db89259ccb 100644 > --- a/libio/vscanf.c > +++ b/libio/vscanf.c > @@ -24,6 +24,11 @@ > This exception applies to code released by its copyright holders > in files containing the exception. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "libioP.h" > #include "stdio.h" > > diff --git a/libio/vwscanf.c b/libio/vwscanf.c > index 7af770c8c3..46595d8ada 100644 > --- a/libio/vwscanf.c > +++ b/libio/vwscanf.c > @@ -24,6 +24,11 @@ > This exception applies to code released by its copyright holders > in files containing the exception. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "libioP.h" > #include <wchar.h> > > diff --git a/libio/wscanf.c b/libio/wscanf.c > index fe27ff6fa6..ed68b60b9e 100644 > --- a/libio/wscanf.c > +++ b/libio/wscanf.c > @@ -15,6 +15,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <libioP.h> > #include <stdarg.h> > #include <stdio.h> > diff --git a/stdio-common/Makefile b/stdio-common/Makefile > index 8978b3fb1f..85348a6077 100644 > --- a/stdio-common/Makefile > +++ b/stdio-common/Makefile > @@ -65,6 +65,8 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ > tst-vfprintf-mbs-prec \ > tst-scanf-round \ > tst-renameat2 tst-bz11319 tst-bz11319-fortify2 \ > + scanf14a scanf16a \ > + > > test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble > > @@ -146,13 +148,11 @@ CFLAGS-isoc99_scanf.c += -fexceptions > CFLAGS-errlist.c += $(fno-unit-at-a-time) > CFLAGS-siglist.c += $(fno-unit-at-a-time) > > -# The following is a hack since we must compile scanf1{5,7}.c without any > -# GNU extension. The latter are needed, though, when internal headers > -# are used. So made sure we see the installed headers first. > -CFLAGS-scanf15.c += -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ > - -I../wctype > -CFLAGS-scanf17.c += -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ > - -I../wctype > +# scanf14a.c and scanf16a.c test a deprecated extension which is no > +# longer visible under most conformance levels; see the source files > +# for more detail. > +CFLAGS-scanf14a.c += -std=gnu89 > +CFLAGS-scanf16a.c += -std=gnu89 > > CFLAGS-bug3.c += -DOBJPFX=\"$(objpfx)\" > CFLAGS-bug4.c += -DOBJPFX=\"$(objpfx)\" > diff --git a/stdio-common/bug21.c b/stdio-common/bug21.c > index 7a8c6a3542..1f06c0dab4 100644 > --- a/stdio-common/bug21.c > +++ b/stdio-common/bug21.c > @@ -1,5 +1,4 @@ > #include <stdio.h> > -#include <libc-diag.h> > > static int > do_test (void) > @@ -7,15 +6,7 @@ do_test (void) > static const char buf[] = " "; > char *str; > > - /* GCC in C99 mode treats %a as the C99 format expecting float *, > - but glibc with _GNU_SOURCE treats %as as the GNU allocation > - extension, so resulting in "warning: format '%a' expects argument > - of type 'float *', but argument 3 has type 'char **'". This > - applies to the other %as, %aS and %a[] formats below as well. */ > - DIAG_PUSH_NEEDS_COMMENT; > - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); > - int r = sscanf (buf, "%as", &str); > - DIAG_POP_NEEDS_COMMENT; > + int r = sscanf (buf, "%ms", &str); > printf ("%d %p\n", r, str); > > return r != -1 || str != NULL; > diff --git a/stdio-common/fscanf.c b/stdio-common/fscanf.c > index b60a2a3b81..9f2a7cdef9 100644 > --- a/stdio-common/fscanf.c > +++ b/stdio-common/fscanf.c > @@ -15,6 +15,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <libioP.h> > #include <stdarg.h> > #include <stdio.h> > diff --git a/stdio-common/isoc99_sscanf.c b/stdio-common/isoc99_sscanf.c > index c9e5103b81..7edf5307ee 100644 > --- a/stdio-common/isoc99_sscanf.c > +++ b/stdio-common/isoc99_sscanf.c > @@ -33,3 +33,4 @@ __isoc99_sscanf (const char *s, const char *format, ...) > > return done; > } > +libc_hidden_def (__isoc99_sscanf) > diff --git a/stdio-common/scanf.c b/stdio-common/scanf.c > index de38d70353..ebcbb070a8 100644 > --- a/stdio-common/scanf.c > +++ b/stdio-common/scanf.c > @@ -15,6 +15,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <stdarg.h> > #include <stdio.h> > > diff --git a/stdio-common/scanf14.c b/stdio-common/scanf14.c > index 2bcd9c9893..22e5f08341 100644 > --- a/stdio-common/scanf14.c > +++ b/stdio-common/scanf14.c > @@ -2,7 +2,10 @@ > #include <stdlib.h> > #include <string.h> > #include <wchar.h> > -#include <libc-diag.h> > + > +#if __GLIBC_USE_DEPRECATED_SCANF > +# error "This file should not be compiled with deprecated scanf" > +#endif > > #define FAIL() \ > do { \ > @@ -24,14 +27,7 @@ main (void) > FAIL (); > else if (f != 0.25 || memcmp (c, "s x", 3) != 0) > FAIL (); > - /* GCC in C99 mode treats %a as the C99 format expecting float *, > - but glibc with _GNU_SOURCE treats %as as the GNU allocation > - extension, so resulting in "warning: format '%a' expects argument > - of type 'float *', but argument 3 has type 'char **'". This > - applies to the other %as, %aS and %a[] formats below as well. */ > - DIAG_PUSH_NEEDS_COMMENT; > - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); > - if (sscanf (" 1.25s x", "%as%2c", &sp, c) != 2) > + if (sscanf (" 1.25s x", "%ms%2c", &sp, c) != 2) > FAIL (); > else > { > @@ -40,15 +36,11 @@ main (void) > memset (sp, 'x', sizeof "1.25s"); > free (sp); > } > - DIAG_POP_NEEDS_COMMENT; > if (sscanf (" 2.25s x", "%las%2c", &d, c) != 2) > FAIL (); > else if (d != 2.25 || memcmp (c, " x", 2) != 0) > FAIL (); > - /* See explanation above. */ > - DIAG_PUSH_NEEDS_COMMENT; > - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); > - if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) > + if (sscanf (" 3.25S x", "%4mS%3c", &lsp, c) != 2) > FAIL (); > else > { > @@ -57,7 +49,7 @@ main (void) > memset (lsp, 'x', sizeof L"3.25"); > free (lsp); > } > - if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) > + if (sscanf ("4.25[0-9.] x", "%m[0-9.]%8c", &sp, c) != 2) > FAIL (); > else > { > @@ -66,7 +58,6 @@ main (void) > memset (sp, 'x', sizeof "4.25"); > free (sp); > } > - DIAG_POP_NEEDS_COMMENT; > if (sscanf ("5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2) > FAIL (); > else if (d != 5.25 || memcmp (c, " x", 2) != 0) > @@ -95,10 +86,7 @@ main (void) > FAIL (); > if (fseek (fp, 0, SEEK_SET) != 0) > FAIL (); > - /* See explanation above. */ > - DIAG_PUSH_NEEDS_COMMENT; > - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); > - if (fscanf (fp, "%as%2c", &sp, c) != 2) > + if (fscanf (fp, "%ms%2c", &sp, c) != 2) > FAIL (); > else > { > @@ -107,16 +95,12 @@ main (void) > memset (sp, 'x', sizeof "1.25s"); > free (sp); > } > - DIAG_POP_NEEDS_COMMENT; > > if (freopen (fname, "r", stdin) == NULL) > FAIL (); > else > { > - /* See explanation above. */ > - DIAG_PUSH_NEEDS_COMMENT; > - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); > - if (scanf ("%as%2c", &sp, c) != 2) > + if (scanf ("%ms%2c", &sp, c) != 2) > FAIL (); > else > { > @@ -125,7 +109,6 @@ main (void) > memset (sp, 'x', sizeof "1.25s"); > free (sp); > } > - DIAG_POP_NEEDS_COMMENT; > } > > fclose (fp); > diff --git a/stdio-common/scanf14a.c b/stdio-common/scanf14a.c > new file mode 100644 > index 0000000000..34099b8fe3 > --- /dev/null > +++ b/stdio-common/scanf14a.c > @@ -0,0 +1,126 @@ This is a big enough test that it should have a copyright notice. > +/* This test exercises the deprecated GNU %as, %aS, and %a[...] scanf > + modifiers, which are not available to programs compiled as C99 > + anymore; therefore, this file is compiled with -std=gnu89 and C99 > + syntax must not be used. */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <wchar.h> > + > +#if !__GLIBC_USE_DEPRECATED_SCANF > +# error "This file should be compiled with deprecated scanf" > +#endif > + > + > +#define FAIL() \ > + do { \ > + result = 1; \ > + printf ("test at line %d failed\n", __LINE__); \ > + } while (0) > + > +int > +main (void) > +{ > + wchar_t *lsp; > + char *sp; > + float f; > + double d; > + char c[8]; > + int result = 0; > + > + if (sscanf (" 0.25s x", "%e%3c", &f, c) != 2) > + FAIL (); > + else if (f != 0.25 || memcmp (c, "s x", 3) != 0) > + FAIL (); > + if (sscanf (" 1.25s x", "%as%2c", &sp, c) != 2) > + FAIL (); > + else > + { > + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) > + FAIL (); > + memset (sp, 'x', sizeof "1.25s"); > + free (sp); > + } > + if (sscanf (" 2.25s x", "%las%2c", &d, c) != 2) > + FAIL (); > + else if (d != 2.25 || memcmp (c, " x", 2) != 0) > + FAIL (); > + if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) > + FAIL (); > + else > + { > + if (wcscmp (lsp, L"3.25") != 0 || memcmp (c, "S x", 3) != 0) > + FAIL (); > + memset (lsp, 'x', sizeof L"3.25"); > + free (lsp); > + } > + if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) > + FAIL (); > + else > + { > + if (strcmp (sp, "4.25") != 0 || memcmp (c, "[0-9.] x", 8) != 0) > + FAIL (); > + memset (sp, 'x', sizeof "4.25"); > + free (sp); > + } > + if (sscanf ("5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2) > + FAIL (); > + else if (d != 5.25 || memcmp (c, " x", 2) != 0) > + FAIL (); > + > + const char *tmpdir = getenv ("TMPDIR"); > + if (tmpdir == NULL || tmpdir[0] == '\0') > + tmpdir = "/tmp"; > + > + char fname[strlen (tmpdir) + sizeof "/tst-scanf14.XXXXXX"]; > + sprintf (fname, "%s/tst-scanf14.XXXXXX", tmpdir); > + if (fname == NULL) > + FAIL (); > + > + /* Create a temporary file. */ > + int fd = mkstemp (fname); > + if (fd == -1) > + FAIL (); > + > + FILE *fp = fdopen (fd, "w+"); > + if (fp == NULL) > + FAIL (); > + else > + { > + if (fputs (" 1.25s x", fp) == EOF) > + FAIL (); > + if (fseek (fp, 0, SEEK_SET) != 0) > + FAIL (); > + if (fscanf (fp, "%as%2c", &sp, c) != 2) > + FAIL (); > + else > + { > + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) > + FAIL (); > + memset (sp, 'x', sizeof "1.25s"); > + free (sp); > + } > + > + if (freopen (fname, "r", stdin) == NULL) > + FAIL (); > + else > + { > + if (scanf ("%as%2c", &sp, c) != 2) > + FAIL (); > + else > + { > + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) > + FAIL (); > + memset (sp, 'x', sizeof "1.25s"); > + free (sp); > + } > + } > + > + fclose (fp); > + } > + > + remove (fname); > + > + return result; > +} > diff --git a/stdio-common/scanf15.c b/stdio-common/scanf15.c > index a3ab15dea2..142e215ad3 100644 > --- a/stdio-common/scanf15.c > +++ b/stdio-common/scanf15.c > @@ -1,18 +1,12 @@ > -#undef _GNU_SOURCE > -#define _XOPEN_SOURCE 600 > -#undef _LIBC > -#undef _IO_MTSAFE_IO > -/* The following macro definitions are a hack. They word around disabling > - the GNU extension while still using a few internal headers. */ > -#define u_char unsigned char > -#define u_short unsigned short > -#define u_int unsigned int > -#define u_long unsigned long > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <wchar.h> > > +#if __GLIBC_USE_DEPRECATED_SCANF > +# error "This file should not be compiled with deprecated scanf" > +#endif > + > #define FAIL() \ > do { \ > result = 1; \ > diff --git a/stdio-common/scanf16.c b/stdio-common/scanf16.c > index 3e3cb417f2..db640e2e9c 100644 > --- a/stdio-common/scanf16.c > +++ b/stdio-common/scanf16.c > @@ -4,13 +4,17 @@ > #include <string.h> > #include <wchar.h> > > +#if __GLIBC_USE_DEPRECATED_SCANF > +# error "This file should not be compiled with deprecated scanf" > +#endif > + > #define FAIL() \ > do { \ > result = 1; \ > printf ("test at line %d failed\n", __LINE__); \ > } while (0) > > -static int > +static int __attribute__ ((format (scanf, 2, 3))) > xsscanf (const char *str, const char *fmt, ...) > { > va_list ap; > @@ -20,7 +24,7 @@ xsscanf (const char *str, const char *fmt, ...) > return ret; > } > > -static int > +static int __attribute__ ((format (scanf, 1, 2))) > xscanf (const char *fmt, ...) > { > va_list ap; > @@ -30,7 +34,7 @@ xscanf (const char *fmt, ...) > return ret; > } > > -static int > +static int __attribute__ ((format (scanf, 2, 3))) > xfscanf (FILE *f, const char *fmt, ...) > { > va_list ap; > @@ -54,7 +58,7 @@ main (void) > FAIL (); > else if (f != 0.25 || memcmp (c, "s x", 3) != 0) > FAIL (); > - if (xsscanf (" 1.25s x", "%as%2c", &sp, c) != 2) > + if (xsscanf (" 1.25s x", "%ms%2c", &sp, c) != 2) > FAIL (); > else > { > @@ -67,7 +71,7 @@ main (void) > FAIL (); > else if (d != 2.25 || memcmp (c, " x", 2) != 0) > FAIL (); > - if (xsscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) > + if (xsscanf (" 3.25S x", "%4mS%3c", &lsp, c) != 2) > FAIL (); > else > { > @@ -76,7 +80,7 @@ main (void) > memset (lsp, 'x', sizeof L"3.25"); > free (lsp); > } > - if (xsscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) > + if (xsscanf ("4.25[0-9.] x", "%m[0-9.]%8c", &sp, c) != 2) > FAIL (); > else > { > @@ -113,7 +117,7 @@ main (void) > FAIL (); > if (fseek (fp, 0, SEEK_SET) != 0) > FAIL (); > - if (xfscanf (fp, "%as%2c", &sp, c) != 2) > + if (xfscanf (fp, "%ms%2c", &sp, c) != 2) > FAIL (); > else > { > @@ -127,7 +131,7 @@ main (void) > FAIL (); > else > { > - if (xscanf ("%as%2c", &sp, c) != 2) > + if (xscanf ("%ms%2c", &sp, c) != 2) > FAIL (); > else > { > diff --git a/stdio-common/scanf16a.c b/stdio-common/scanf16a.c > new file mode 100644 > index 0000000000..684eeb08f4 > --- /dev/null > +++ b/stdio-common/scanf16a.c > @@ -0,0 +1,156 @@ Please add a copyright header. > +/* This test exercises the deprecated GNU %as, %aS, and %a[...] scanf > + modifiers, which are not available to programs compiled as C99 > + anymore; therefore, this file is compiled with -std=gnu89 and C99 > + syntax must not be used. */ > + > +#include <stdarg.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <wchar.h> > + > +#if !__GLIBC_USE_DEPRECATED_SCANF > +# error "This file should be compiled with deprecated scanf" > +#endif > + > +#define FAIL() \ > + do { \ > + result = 1; \ > + printf ("test at line %d failed\n", __LINE__); \ > + } while (0) > + > +static int __attribute__ ((format (scanf, 2, 3))) > +xsscanf (const char *str, const char *fmt, ...) > +{ > + va_list ap; > + va_start (ap, fmt); > + int ret = vsscanf (str, fmt, ap); > + va_end (ap); > + return ret; > +} > + > +static int __attribute__ ((format (scanf, 1, 2))) > +xscanf (const char *fmt, ...) > +{ > + va_list ap; > + va_start (ap, fmt); > + int ret = vscanf (fmt, ap); > + va_end (ap); > + return ret; > +} > + > +static int __attribute__ ((format (scanf, 2, 3))) > +xfscanf (FILE *f, const char *fmt, ...) > +{ > + va_list ap; > + va_start (ap, fmt); > + int ret = vfscanf (f, fmt, ap); > + va_end (ap); > + return ret; > +} > + > +int > +main (void) > +{ > + wchar_t *lsp; > + char *sp; > + float f; > + double d; > + char c[8]; > + int result = 0; > + > + if (xsscanf (" 0.25s x", "%e%3c", &f, c) != 2) > + FAIL (); > + else if (f != 0.25 || memcmp (c, "s x", 3) != 0) > + FAIL (); > + if (xsscanf (" 1.25s x", "%as%2c", &sp, c) != 2) > + FAIL (); > + else > + { > + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) > + FAIL (); > + memset (sp, 'x', sizeof "1.25s"); > + free (sp); > + } > + if (xsscanf (" 2.25s x", "%las%2c", &d, c) != 2) > + FAIL (); > + else if (d != 2.25 || memcmp (c, " x", 2) != 0) > + FAIL (); > + if (xsscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) > + FAIL (); > + else > + { > + if (wcscmp (lsp, L"3.25") != 0 || memcmp (c, "S x", 3) != 0) > + FAIL (); > + memset (lsp, 'x', sizeof L"3.25"); > + free (lsp); > + } > + if (xsscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) > + FAIL (); > + else > + { > + if (strcmp (sp, "4.25") != 0 || memcmp (c, "[0-9.] x", 8) != 0) > + FAIL (); > + memset (sp, 'x', sizeof "4.25"); > + free (sp); > + } > + if (xsscanf ("5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2) > + FAIL (); > + else if (d != 5.25 || memcmp (c, " x", 2) != 0) > + FAIL (); > + > + const char *tmpdir = getenv ("TMPDIR"); > + if (tmpdir == NULL || tmpdir[0] == '\0') > + tmpdir = "/tmp"; > + > + char fname[strlen (tmpdir) + sizeof "/tst-scanf16.XXXXXX"]; > + sprintf (fname, "%s/tst-scanf16.XXXXXX", tmpdir); > + if (fname == NULL) > + FAIL (); > + > + /* Create a temporary file. */ > + int fd = mkstemp (fname); > + if (fd == -1) > + FAIL (); > + > + FILE *fp = fdopen (fd, "w+"); > + if (fp == NULL) > + FAIL (); > + else > + { > + if (fputs (" 1.25s x", fp) == EOF) > + FAIL (); > + if (fseek (fp, 0, SEEK_SET) != 0) > + FAIL (); > + if (xfscanf (fp, "%as%2c", &sp, c) != 2) > + FAIL (); > + else > + { > + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) > + FAIL (); > + memset (sp, 'x', sizeof "1.25s"); > + free (sp); > + } > + > + if (freopen (fname, "r", stdin) == NULL) > + FAIL (); > + else > + { > + if (xscanf ("%as%2c", &sp, c) != 2) > + FAIL (); > + else > + { > + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) > + FAIL (); > + memset (sp, 'x', sizeof "1.25s"); > + free (sp); > + } > + } > + > + fclose (fp); > + } > + > + remove (fname); > + > + return result; > +} > diff --git a/stdio-common/scanf17.c b/stdio-common/scanf17.c > index b6c0e63ab0..5a0ae42686 100644 > --- a/stdio-common/scanf17.c > +++ b/stdio-common/scanf17.c > @@ -1,19 +1,13 @@ > -#undef _GNU_SOURCE > -#define _XOPEN_SOURCE 600 > -#undef _LIBC > -#undef _IO_MTSAFE_IO > -/* The following macro definitions are a hack. They word around disabling > - the GNU extension while still using a few internal headers. */ > -#define u_char unsigned char > -#define u_short unsigned short > -#define u_int unsigned int > -#define u_long unsigned long > #include <stdarg.h> > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <wchar.h> > > +#if __GLIBC_USE_DEPRECATED_SCANF > +# error "This file should not be compiled with deprecated scanf" > +#endif > + > #define FAIL() \ > do { \ > result = 1; \ > diff --git a/stdio-common/sscanf.c b/stdio-common/sscanf.c > index e25e9c27a5..1c8c58bbe9 100644 > --- a/stdio-common/sscanf.c > +++ b/stdio-common/sscanf.c > @@ -15,6 +15,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <stdarg.h> > #include <libio/strfile.h> > > @@ -34,6 +39,5 @@ __sscanf (const char *s, const char *format, ...) > > return done; > } > -ldbl_hidden_def (__sscanf, sscanf) > ldbl_strong_alias (__sscanf, sscanf) > ldbl_strong_alias (__sscanf, _IO_sscanf) > diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c > index 5eedca8340..b9df35e73b 100644 > --- a/stdio-common/vfscanf.c > +++ b/stdio-common/vfscanf.c > @@ -15,6 +15,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <libioP.h> > > int > diff --git a/stdio-common/vfwscanf.c b/stdio-common/vfwscanf.c > index 86980464c2..cbbbd37730 100644 > --- a/stdio-common/vfwscanf.c > +++ b/stdio-common/vfwscanf.c > @@ -16,6 +16,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <libioP.h> > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c > index f6dd81759d..a67a18915f 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c > @@ -17,6 +17,11 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > +/* This file may define some of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include <stdarg.h> > #include <stdio.h> > #include <libio/strfile.h> > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c > index 1b768e306f..00507187f3 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c > index 27fc1a7271..65782894a2 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c > index 442c11c203..6ed9b48624 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c > index bbab371cbe..c10da284f2 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c > index a771d49996..34e18be0a1 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c > index dd058f47ab..4076debc4e 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c > index f23465ee95..6f5ebc3045 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c > index be9febc9a0..0bef274726 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c > index e75907b905..38f654aa73 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c > index f5594c122c..33e10e49a9 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c > index bd4bb5131b..91c0d4cd4f 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c > index d39578ca4e..b3d0f1be18 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c > index 4ee3fdc15f..2689e27f06 100644 > --- a/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c > +++ b/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c > @@ -1,3 +1,8 @@ > +/* This file defines one of the deprecated scanf variants. */ > +#include <features.h> > +#undef __GLIBC_USE_DEPRECATED_SCANF > +#define __GLIBC_USE_DEPRECATED_SCANF 1 > + > #include "nldbl-compat.h" > > int > diff --git a/wcsmbs/bits/wchar-ldbl.h b/wcsmbs/bits/wchar-ldbl.h > index b91ee9fbf5..ab2601ae5d 100644 > --- a/wcsmbs/bits/wchar-ldbl.h > +++ b/wcsmbs/bits/wchar-ldbl.h > @@ -27,9 +27,7 @@ __LDBL_REDIR_DECL (swprintf); > __LDBL_REDIR_DECL (vfwprintf); > __LDBL_REDIR_DECL (vwprintf); > __LDBL_REDIR_DECL (vswprintf); > -# if defined __USE_ISOC99 && !defined __USE_GNU \ > - && !defined __REDIRECT \ > - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) > +# if !__GLIBC_USE (DEPRECATED_SCANF) > __LDBL_REDIR1_DECL (fwscanf, __nldbl___isoc99_fwscanf) > __LDBL_REDIR1_DECL (wscanf, __nldbl___isoc99_wscanf) > __LDBL_REDIR1_DECL (swscanf, __nldbl___isoc99_swscanf) > @@ -42,8 +40,7 @@ __LDBL_REDIR_DECL (swscanf); > > #ifdef __USE_ISOC99 > __LDBL_REDIR1_DECL (wcstold, wcstod); > -# if !defined __USE_GNU && !defined __REDIRECT \ > - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) > +# if !__GLIBC_USE (DEPRECATED_SCANF) > __LDBL_REDIR1_DECL (vfwscanf, __nldbl___isoc99_vfwscanf) > __LDBL_REDIR1_DECL (vwscanf, __nldbl___isoc99_vwscanf) > __LDBL_REDIR1_DECL (vswscanf, __nldbl___isoc99_vswscanf) > diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h > index 6c94f3ebc6..24573656bc 100644 > --- a/wcsmbs/wchar.h > +++ b/wcsmbs/wchar.h > @@ -632,13 +632,11 @@ extern int swscanf (const wchar_t *__restrict __s, > const wchar_t *__restrict __format, ...) > __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; > > -# if defined __USE_ISOC99 && !defined __USE_GNU \ > - && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ > - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) > +/* For historical reasons, the C99-compliant versions of the scanf > + functions are at alternative names. When __LDBL_COMPAT is in > + effect, this is handled in bits/wchar-ldbl.h. */ > +#if !__GLIBC_USE (DEPRECATED_SCANF) && !defined __LDBL_COMPAT > # ifdef __REDIRECT > -/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ > - GNU extension which conflicts with valid %a followed by letter > - s, S or [. */ > extern int __REDIRECT (fwscanf, (__FILE *__restrict __stream, > const wchar_t *__restrict __format, ...), > __isoc99_fwscanf) >
On Mon, Dec 31, 2018 at 8:59 AM Siddhesh Poyarekar <siddhesh@gotplt.org> wrote: > > The two new tests are missing Copyright headers. With those added the > change looks OK to me. Thanks! I will make those changes and commit the patch. I am still traveling so I may not get to it until Jan. 3 or so. zw
On Mon, Dec 31, 2018 at 12:02 PM Zack Weinberg <zackw@panix.com> wrote: > On Mon, Dec 31, 2018 at 8:59 AM Siddhesh Poyarekar <siddhesh@gotplt.org> wrote: > > The two new tests are missing Copyright headers. With those added the > > change looks OK to me. > > Thanks! I will make those changes and commit the patch. I am still > traveling so I may not get to it until Jan. 3 or so. The patch has now been committed. zw
diff --git a/NEWS b/NEWS index cd29ec7c81..5a682832a6 100644 --- a/NEWS +++ b/NEWS @@ -68,6 +68,23 @@ Deprecated and removed features, and other changes affecting compatibility: used by the Linux kernel. This affects the size and layout of those structures. +* An archaic GNU extension to scanf, under which '%as', '%aS', and '%a[...]' + meant to scan a string and allocate space for it with malloc, is now + restricted to programs compiled in C89 or C++98 mode with _GNU_SOURCE + defined. This extension conflicts with C99's use of '%a' to scan a + hexadecimal floating-point number, which is now available to programs + compiled as C99 or C++11 or higher, regardless of _GNU_SOURCE. + + POSIX.1-2008 includes the feature of allocating a buffer for string input + with malloc, using the modifier letter 'm' instead. Programs using + '%as', '%aS', or '%a[...]' with the old GNU meaning should change to + '%ms', '%mS', or '%m[...]' respectively. Programs that wish to use the + C99 '%a' no longer need to avoid _GNU_SOURCE. + + GCC's -Wformat warnings can detect most uses of this extension, as long + as all functions that call vscanf, vfscanf, or vsscanf are annotated with + __attribute__ ((format (scanf, ...))). + Changes to build and runtime requirements: * Python 3.4 or later is required to build the GNU C Library. diff --git a/include/features.h b/include/features.h index 5bed0a4996..e6177f80f9 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 1b7da0f74d..65ccabbb05 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) diff --git a/libio/bits/stdio-ldbl.h b/libio/bits/stdio-ldbl.h index 99d9bcc233..dfcbe5375a 100644 --- a/libio/bits/stdio-ldbl.h +++ b/libio/bits/stdio-ldbl.h @@ -26,9 +26,7 @@ __LDBL_REDIR_DECL (sprintf) __LDBL_REDIR_DECL (vfprintf) __LDBL_REDIR_DECL (vprintf) __LDBL_REDIR_DECL (vsprintf) -#if defined __USE_ISOC99 && !defined __USE_GNU \ - && !defined __REDIRECT \ - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +#if !__GLIBC_USE (DEPRECATED_SCANF) __LDBL_REDIR1_DECL (fscanf, __nldbl___isoc99_fscanf) __LDBL_REDIR1_DECL (scanf, __nldbl___isoc99_scanf) __LDBL_REDIR1_DECL (sscanf, __nldbl___isoc99_sscanf) @@ -44,8 +42,7 @@ __LDBL_REDIR_DECL (vsnprintf) #endif #ifdef __USE_ISOC99 -# if !defined __USE_GNU && !defined __REDIRECT \ - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# if !__GLIBC_USE (DEPRECATED_SCANF) __LDBL_REDIR1_DECL (vfscanf, __nldbl___isoc99_vfscanf) __LDBL_REDIR1_DECL (vscanf, __nldbl___isoc99_vscanf) __LDBL_REDIR1_DECL (vsscanf, __nldbl___isoc99_vsscanf) diff --git a/libio/fwscanf.c b/libio/fwscanf.c index ce4b35d31d..32cb9fb699 100644 --- a/libio/fwscanf.c +++ b/libio/fwscanf.c @@ -15,6 +15,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <libioP.h> #include <stdarg.h> #include <stdio.h> diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c index ee6a99ec6a..69de5a09b6 100644 --- a/libio/iovsscanf.c +++ b/libio/iovsscanf.c @@ -24,6 +24,11 @@ This exception applies to code released by its copyright holders in files containing the exception. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "strfile.h" int diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c index cb9cbe15cc..f4b4657c16 100644 --- a/libio/iovswscanf.c +++ b/libio/iovswscanf.c @@ -24,6 +24,11 @@ This exception applies to code released by its copyright holders in files containing the exception. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <wchar.h> #include "strfile.h" diff --git a/libio/stdio.h b/libio/stdio.h index 739e08610d..86e7015655 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -399,13 +399,11 @@ extern int scanf (const char *__restrict __format, ...) __wur; extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __THROW; -#if defined __USE_ISOC99 && !defined __USE_GNU \ - && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +/* For historical reasons, the C99-compliant versions of the scanf + functions are at alternative names. When __LDBL_COMPAT is in + effect, this is handled in bits/stdio-ldbl.h. */ +#if !__GLIBC_USE (DEPRECATED_SCANF) && !defined __LDBL_COMPAT # ifdef __REDIRECT -/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ - GNU extension which conflicts with valid %a followed by letter - s, S or [. */ extern int __REDIRECT (fscanf, (FILE *__restrict __stream, const char *__restrict __format, ...), __isoc99_fscanf) __wur; @@ -447,13 +445,9 @@ extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); -# if !defined __USE_GNU \ - && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) -# ifdef __REDIRECT -/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ - GNU extension which conflicts with valid %a followed by letter - s, S or [. */ +/* Same redirection as above for the v*scanf family. */ +# if !__GLIBC_USE (DEPRECATED_SCANF) +# if defined __REDIRECT && !defined __LDBL_COMPAT extern int __REDIRECT (vfscanf, (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg), @@ -467,7 +461,7 @@ extern int __REDIRECT_NTH (vsscanf, const char *__restrict __format, __gnuc_va_list __arg), __isoc99_vsscanf) __attribute__ ((__format__ (__scanf__, 2, 0))); -# else +# elif !defined __REDIRECT extern int __isoc99_vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __wur; diff --git a/libio/swscanf.c b/libio/swscanf.c index 90f721cc51..560f4e3d3e 100644 --- a/libio/swscanf.c +++ b/libio/swscanf.c @@ -15,6 +15,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <stdarg.h> #include "strfile.h" diff --git a/libio/vscanf.c b/libio/vscanf.c index a3e2dd43f2..db89259ccb 100644 --- a/libio/vscanf.c +++ b/libio/vscanf.c @@ -24,6 +24,11 @@ This exception applies to code released by its copyright holders in files containing the exception. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "libioP.h" #include "stdio.h" diff --git a/libio/vwscanf.c b/libio/vwscanf.c index 7af770c8c3..46595d8ada 100644 --- a/libio/vwscanf.c +++ b/libio/vwscanf.c @@ -24,6 +24,11 @@ This exception applies to code released by its copyright holders in files containing the exception. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "libioP.h" #include <wchar.h> diff --git a/libio/wscanf.c b/libio/wscanf.c index fe27ff6fa6..ed68b60b9e 100644 --- a/libio/wscanf.c +++ b/libio/wscanf.c @@ -15,6 +15,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <libioP.h> #include <stdarg.h> #include <stdio.h> diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 8978b3fb1f..85348a6077 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -65,6 +65,8 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ tst-vfprintf-mbs-prec \ tst-scanf-round \ tst-renameat2 tst-bz11319 tst-bz11319-fortify2 \ + scanf14a scanf16a \ + test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble @@ -146,13 +148,11 @@ CFLAGS-isoc99_scanf.c += -fexceptions CFLAGS-errlist.c += $(fno-unit-at-a-time) CFLAGS-siglist.c += $(fno-unit-at-a-time) -# The following is a hack since we must compile scanf1{5,7}.c without any -# GNU extension. The latter are needed, though, when internal headers -# are used. So made sure we see the installed headers first. -CFLAGS-scanf15.c += -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ - -I../wctype -CFLAGS-scanf17.c += -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ - -I../wctype +# scanf14a.c and scanf16a.c test a deprecated extension which is no +# longer visible under most conformance levels; see the source files +# for more detail. +CFLAGS-scanf14a.c += -std=gnu89 +CFLAGS-scanf16a.c += -std=gnu89 CFLAGS-bug3.c += -DOBJPFX=\"$(objpfx)\" CFLAGS-bug4.c += -DOBJPFX=\"$(objpfx)\" diff --git a/stdio-common/bug21.c b/stdio-common/bug21.c index 7a8c6a3542..1f06c0dab4 100644 --- a/stdio-common/bug21.c +++ b/stdio-common/bug21.c @@ -1,5 +1,4 @@ #include <stdio.h> -#include <libc-diag.h> static int do_test (void) @@ -7,15 +6,7 @@ do_test (void) static const char buf[] = " "; char *str; - /* GCC in C99 mode treats %a as the C99 format expecting float *, - but glibc with _GNU_SOURCE treats %as as the GNU allocation - extension, so resulting in "warning: format '%a' expects argument - of type 'float *', but argument 3 has type 'char **'". This - applies to the other %as, %aS and %a[] formats below as well. */ - DIAG_PUSH_NEEDS_COMMENT; - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); - int r = sscanf (buf, "%as", &str); - DIAG_POP_NEEDS_COMMENT; + int r = sscanf (buf, "%ms", &str); printf ("%d %p\n", r, str); return r != -1 || str != NULL; diff --git a/stdio-common/fscanf.c b/stdio-common/fscanf.c index b60a2a3b81..9f2a7cdef9 100644 --- a/stdio-common/fscanf.c +++ b/stdio-common/fscanf.c @@ -15,6 +15,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <libioP.h> #include <stdarg.h> #include <stdio.h> diff --git a/stdio-common/isoc99_sscanf.c b/stdio-common/isoc99_sscanf.c index c9e5103b81..7edf5307ee 100644 --- a/stdio-common/isoc99_sscanf.c +++ b/stdio-common/isoc99_sscanf.c @@ -33,3 +33,4 @@ __isoc99_sscanf (const char *s, const char *format, ...) return done; } +libc_hidden_def (__isoc99_sscanf) diff --git a/stdio-common/scanf.c b/stdio-common/scanf.c index de38d70353..ebcbb070a8 100644 --- a/stdio-common/scanf.c +++ b/stdio-common/scanf.c @@ -15,6 +15,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <stdarg.h> #include <stdio.h> diff --git a/stdio-common/scanf14.c b/stdio-common/scanf14.c index 2bcd9c9893..22e5f08341 100644 --- a/stdio-common/scanf14.c +++ b/stdio-common/scanf14.c @@ -2,7 +2,10 @@ #include <stdlib.h> #include <string.h> #include <wchar.h> -#include <libc-diag.h> + +#if __GLIBC_USE_DEPRECATED_SCANF +# error "This file should not be compiled with deprecated scanf" +#endif #define FAIL() \ do { \ @@ -24,14 +27,7 @@ main (void) FAIL (); else if (f != 0.25 || memcmp (c, "s x", 3) != 0) FAIL (); - /* GCC in C99 mode treats %a as the C99 format expecting float *, - but glibc with _GNU_SOURCE treats %as as the GNU allocation - extension, so resulting in "warning: format '%a' expects argument - of type 'float *', but argument 3 has type 'char **'". This - applies to the other %as, %aS and %a[] formats below as well. */ - DIAG_PUSH_NEEDS_COMMENT; - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); - if (sscanf (" 1.25s x", "%as%2c", &sp, c) != 2) + if (sscanf (" 1.25s x", "%ms%2c", &sp, c) != 2) FAIL (); else { @@ -40,15 +36,11 @@ main (void) memset (sp, 'x', sizeof "1.25s"); free (sp); } - DIAG_POP_NEEDS_COMMENT; if (sscanf (" 2.25s x", "%las%2c", &d, c) != 2) FAIL (); else if (d != 2.25 || memcmp (c, " x", 2) != 0) FAIL (); - /* See explanation above. */ - DIAG_PUSH_NEEDS_COMMENT; - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); - if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) + if (sscanf (" 3.25S x", "%4mS%3c", &lsp, c) != 2) FAIL (); else { @@ -57,7 +49,7 @@ main (void) memset (lsp, 'x', sizeof L"3.25"); free (lsp); } - if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) + if (sscanf ("4.25[0-9.] x", "%m[0-9.]%8c", &sp, c) != 2) FAIL (); else { @@ -66,7 +58,6 @@ main (void) memset (sp, 'x', sizeof "4.25"); free (sp); } - DIAG_POP_NEEDS_COMMENT; if (sscanf ("5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2) FAIL (); else if (d != 5.25 || memcmp (c, " x", 2) != 0) @@ -95,10 +86,7 @@ main (void) FAIL (); if (fseek (fp, 0, SEEK_SET) != 0) FAIL (); - /* See explanation above. */ - DIAG_PUSH_NEEDS_COMMENT; - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); - if (fscanf (fp, "%as%2c", &sp, c) != 2) + if (fscanf (fp, "%ms%2c", &sp, c) != 2) FAIL (); else { @@ -107,16 +95,12 @@ main (void) memset (sp, 'x', sizeof "1.25s"); free (sp); } - DIAG_POP_NEEDS_COMMENT; if (freopen (fname, "r", stdin) == NULL) FAIL (); else { - /* See explanation above. */ - DIAG_PUSH_NEEDS_COMMENT; - DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); - if (scanf ("%as%2c", &sp, c) != 2) + if (scanf ("%ms%2c", &sp, c) != 2) FAIL (); else { @@ -125,7 +109,6 @@ main (void) memset (sp, 'x', sizeof "1.25s"); free (sp); } - DIAG_POP_NEEDS_COMMENT; } fclose (fp); diff --git a/stdio-common/scanf14a.c b/stdio-common/scanf14a.c new file mode 100644 index 0000000000..34099b8fe3 --- /dev/null +++ b/stdio-common/scanf14a.c @@ -0,0 +1,126 @@ +/* This test exercises the deprecated GNU %as, %aS, and %a[...] scanf + modifiers, which are not available to programs compiled as C99 + anymore; therefore, this file is compiled with -std=gnu89 and C99 + syntax must not be used. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +#if !__GLIBC_USE_DEPRECATED_SCANF +# error "This file should be compiled with deprecated scanf" +#endif + + +#define FAIL() \ + do { \ + result = 1; \ + printf ("test at line %d failed\n", __LINE__); \ + } while (0) + +int +main (void) +{ + wchar_t *lsp; + char *sp; + float f; + double d; + char c[8]; + int result = 0; + + if (sscanf (" 0.25s x", "%e%3c", &f, c) != 2) + FAIL (); + else if (f != 0.25 || memcmp (c, "s x", 3) != 0) + FAIL (); + if (sscanf (" 1.25s x", "%as%2c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) + FAIL (); + memset (sp, 'x', sizeof "1.25s"); + free (sp); + } + if (sscanf (" 2.25s x", "%las%2c", &d, c) != 2) + FAIL (); + else if (d != 2.25 || memcmp (c, " x", 2) != 0) + FAIL (); + if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) + FAIL (); + else + { + if (wcscmp (lsp, L"3.25") != 0 || memcmp (c, "S x", 3) != 0) + FAIL (); + memset (lsp, 'x', sizeof L"3.25"); + free (lsp); + } + if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "4.25") != 0 || memcmp (c, "[0-9.] x", 8) != 0) + FAIL (); + memset (sp, 'x', sizeof "4.25"); + free (sp); + } + if (sscanf ("5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2) + FAIL (); + else if (d != 5.25 || memcmp (c, " x", 2) != 0) + FAIL (); + + const char *tmpdir = getenv ("TMPDIR"); + if (tmpdir == NULL || tmpdir[0] == '\0') + tmpdir = "/tmp"; + + char fname[strlen (tmpdir) + sizeof "/tst-scanf14.XXXXXX"]; + sprintf (fname, "%s/tst-scanf14.XXXXXX", tmpdir); + if (fname == NULL) + FAIL (); + + /* Create a temporary file. */ + int fd = mkstemp (fname); + if (fd == -1) + FAIL (); + + FILE *fp = fdopen (fd, "w+"); + if (fp == NULL) + FAIL (); + else + { + if (fputs (" 1.25s x", fp) == EOF) + FAIL (); + if (fseek (fp, 0, SEEK_SET) != 0) + FAIL (); + if (fscanf (fp, "%as%2c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) + FAIL (); + memset (sp, 'x', sizeof "1.25s"); + free (sp); + } + + if (freopen (fname, "r", stdin) == NULL) + FAIL (); + else + { + if (scanf ("%as%2c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) + FAIL (); + memset (sp, 'x', sizeof "1.25s"); + free (sp); + } + } + + fclose (fp); + } + + remove (fname); + + return result; +} diff --git a/stdio-common/scanf15.c b/stdio-common/scanf15.c index a3ab15dea2..142e215ad3 100644 --- a/stdio-common/scanf15.c +++ b/stdio-common/scanf15.c @@ -1,18 +1,12 @@ -#undef _GNU_SOURCE -#define _XOPEN_SOURCE 600 -#undef _LIBC -#undef _IO_MTSAFE_IO -/* The following macro definitions are a hack. They word around disabling - the GNU extension while still using a few internal headers. */ -#define u_char unsigned char -#define u_short unsigned short -#define u_int unsigned int -#define u_long unsigned long #include <stdio.h> #include <stdlib.h> #include <string.h> #include <wchar.h> +#if __GLIBC_USE_DEPRECATED_SCANF +# error "This file should not be compiled with deprecated scanf" +#endif + #define FAIL() \ do { \ result = 1; \ diff --git a/stdio-common/scanf16.c b/stdio-common/scanf16.c index 3e3cb417f2..db640e2e9c 100644 --- a/stdio-common/scanf16.c +++ b/stdio-common/scanf16.c @@ -4,13 +4,17 @@ #include <string.h> #include <wchar.h> +#if __GLIBC_USE_DEPRECATED_SCANF +# error "This file should not be compiled with deprecated scanf" +#endif + #define FAIL() \ do { \ result = 1; \ printf ("test at line %d failed\n", __LINE__); \ } while (0) -static int +static int __attribute__ ((format (scanf, 2, 3))) xsscanf (const char *str, const char *fmt, ...) { va_list ap; @@ -20,7 +24,7 @@ xsscanf (const char *str, const char *fmt, ...) return ret; } -static int +static int __attribute__ ((format (scanf, 1, 2))) xscanf (const char *fmt, ...) { va_list ap; @@ -30,7 +34,7 @@ xscanf (const char *fmt, ...) return ret; } -static int +static int __attribute__ ((format (scanf, 2, 3))) xfscanf (FILE *f, const char *fmt, ...) { va_list ap; @@ -54,7 +58,7 @@ main (void) FAIL (); else if (f != 0.25 || memcmp (c, "s x", 3) != 0) FAIL (); - if (xsscanf (" 1.25s x", "%as%2c", &sp, c) != 2) + if (xsscanf (" 1.25s x", "%ms%2c", &sp, c) != 2) FAIL (); else { @@ -67,7 +71,7 @@ main (void) FAIL (); else if (d != 2.25 || memcmp (c, " x", 2) != 0) FAIL (); - if (xsscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) + if (xsscanf (" 3.25S x", "%4mS%3c", &lsp, c) != 2) FAIL (); else { @@ -76,7 +80,7 @@ main (void) memset (lsp, 'x', sizeof L"3.25"); free (lsp); } - if (xsscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) + if (xsscanf ("4.25[0-9.] x", "%m[0-9.]%8c", &sp, c) != 2) FAIL (); else { @@ -113,7 +117,7 @@ main (void) FAIL (); if (fseek (fp, 0, SEEK_SET) != 0) FAIL (); - if (xfscanf (fp, "%as%2c", &sp, c) != 2) + if (xfscanf (fp, "%ms%2c", &sp, c) != 2) FAIL (); else { @@ -127,7 +131,7 @@ main (void) FAIL (); else { - if (xscanf ("%as%2c", &sp, c) != 2) + if (xscanf ("%ms%2c", &sp, c) != 2) FAIL (); else { diff --git a/stdio-common/scanf16a.c b/stdio-common/scanf16a.c new file mode 100644 index 0000000000..684eeb08f4 --- /dev/null +++ b/stdio-common/scanf16a.c @@ -0,0 +1,156 @@ +/* This test exercises the deprecated GNU %as, %aS, and %a[...] scanf + modifiers, which are not available to programs compiled as C99 + anymore; therefore, this file is compiled with -std=gnu89 and C99 + syntax must not be used. */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +#if !__GLIBC_USE_DEPRECATED_SCANF +# error "This file should be compiled with deprecated scanf" +#endif + +#define FAIL() \ + do { \ + result = 1; \ + printf ("test at line %d failed\n", __LINE__); \ + } while (0) + +static int __attribute__ ((format (scanf, 2, 3))) +xsscanf (const char *str, const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + int ret = vsscanf (str, fmt, ap); + va_end (ap); + return ret; +} + +static int __attribute__ ((format (scanf, 1, 2))) +xscanf (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + int ret = vscanf (fmt, ap); + va_end (ap); + return ret; +} + +static int __attribute__ ((format (scanf, 2, 3))) +xfscanf (FILE *f, const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + int ret = vfscanf (f, fmt, ap); + va_end (ap); + return ret; +} + +int +main (void) +{ + wchar_t *lsp; + char *sp; + float f; + double d; + char c[8]; + int result = 0; + + if (xsscanf (" 0.25s x", "%e%3c", &f, c) != 2) + FAIL (); + else if (f != 0.25 || memcmp (c, "s x", 3) != 0) + FAIL (); + if (xsscanf (" 1.25s x", "%as%2c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) + FAIL (); + memset (sp, 'x', sizeof "1.25s"); + free (sp); + } + if (xsscanf (" 2.25s x", "%las%2c", &d, c) != 2) + FAIL (); + else if (d != 2.25 || memcmp (c, " x", 2) != 0) + FAIL (); + if (xsscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) + FAIL (); + else + { + if (wcscmp (lsp, L"3.25") != 0 || memcmp (c, "S x", 3) != 0) + FAIL (); + memset (lsp, 'x', sizeof L"3.25"); + free (lsp); + } + if (xsscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "4.25") != 0 || memcmp (c, "[0-9.] x", 8) != 0) + FAIL (); + memset (sp, 'x', sizeof "4.25"); + free (sp); + } + if (xsscanf ("5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2) + FAIL (); + else if (d != 5.25 || memcmp (c, " x", 2) != 0) + FAIL (); + + const char *tmpdir = getenv ("TMPDIR"); + if (tmpdir == NULL || tmpdir[0] == '\0') + tmpdir = "/tmp"; + + char fname[strlen (tmpdir) + sizeof "/tst-scanf16.XXXXXX"]; + sprintf (fname, "%s/tst-scanf16.XXXXXX", tmpdir); + if (fname == NULL) + FAIL (); + + /* Create a temporary file. */ + int fd = mkstemp (fname); + if (fd == -1) + FAIL (); + + FILE *fp = fdopen (fd, "w+"); + if (fp == NULL) + FAIL (); + else + { + if (fputs (" 1.25s x", fp) == EOF) + FAIL (); + if (fseek (fp, 0, SEEK_SET) != 0) + FAIL (); + if (xfscanf (fp, "%as%2c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) + FAIL (); + memset (sp, 'x', sizeof "1.25s"); + free (sp); + } + + if (freopen (fname, "r", stdin) == NULL) + FAIL (); + else + { + if (xscanf ("%as%2c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) + FAIL (); + memset (sp, 'x', sizeof "1.25s"); + free (sp); + } + } + + fclose (fp); + } + + remove (fname); + + return result; +} diff --git a/stdio-common/scanf17.c b/stdio-common/scanf17.c index b6c0e63ab0..5a0ae42686 100644 --- a/stdio-common/scanf17.c +++ b/stdio-common/scanf17.c @@ -1,19 +1,13 @@ -#undef _GNU_SOURCE -#define _XOPEN_SOURCE 600 -#undef _LIBC -#undef _IO_MTSAFE_IO -/* The following macro definitions are a hack. They word around disabling - the GNU extension while still using a few internal headers. */ -#define u_char unsigned char -#define u_short unsigned short -#define u_int unsigned int -#define u_long unsigned long #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <wchar.h> +#if __GLIBC_USE_DEPRECATED_SCANF +# error "This file should not be compiled with deprecated scanf" +#endif + #define FAIL() \ do { \ result = 1; \ diff --git a/stdio-common/sscanf.c b/stdio-common/sscanf.c index e25e9c27a5..1c8c58bbe9 100644 --- a/stdio-common/sscanf.c +++ b/stdio-common/sscanf.c @@ -15,6 +15,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <stdarg.h> #include <libio/strfile.h> @@ -34,6 +39,5 @@ __sscanf (const char *s, const char *format, ...) return done; } -ldbl_hidden_def (__sscanf, sscanf) ldbl_strong_alias (__sscanf, sscanf) ldbl_strong_alias (__sscanf, _IO_sscanf) diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index 5eedca8340..b9df35e73b 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -15,6 +15,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <libioP.h> int diff --git a/stdio-common/vfwscanf.c b/stdio-common/vfwscanf.c index 86980464c2..cbbbd37730 100644 --- a/stdio-common/vfwscanf.c +++ b/stdio-common/vfwscanf.c @@ -16,6 +16,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <libioP.h> int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index f6dd81759d..a67a18915f 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -17,6 +17,11 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* This file may define some of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include <stdarg.h> #include <stdio.h> #include <libio/strfile.h> diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c index 1b768e306f..00507187f3 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c index 27fc1a7271..65782894a2 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c index 442c11c203..6ed9b48624 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c index bbab371cbe..c10da284f2 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c index a771d49996..34e18be0a1 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c index dd058f47ab..4076debc4e 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c index f23465ee95..6f5ebc3045 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c index be9febc9a0..0bef274726 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c index e75907b905..38f654aa73 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c index f5594c122c..33e10e49a9 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c index bd4bb5131b..91c0d4cd4f 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c index d39578ca4e..b3d0f1be18 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c index 4ee3fdc15f..2689e27f06 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c @@ -1,3 +1,8 @@ +/* This file defines one of the deprecated scanf variants. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_SCANF +#define __GLIBC_USE_DEPRECATED_SCANF 1 + #include "nldbl-compat.h" int diff --git a/wcsmbs/bits/wchar-ldbl.h b/wcsmbs/bits/wchar-ldbl.h index b91ee9fbf5..ab2601ae5d 100644 --- a/wcsmbs/bits/wchar-ldbl.h +++ b/wcsmbs/bits/wchar-ldbl.h @@ -27,9 +27,7 @@ __LDBL_REDIR_DECL (swprintf); __LDBL_REDIR_DECL (vfwprintf); __LDBL_REDIR_DECL (vwprintf); __LDBL_REDIR_DECL (vswprintf); -# if defined __USE_ISOC99 && !defined __USE_GNU \ - && !defined __REDIRECT \ - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# if !__GLIBC_USE (DEPRECATED_SCANF) __LDBL_REDIR1_DECL (fwscanf, __nldbl___isoc99_fwscanf) __LDBL_REDIR1_DECL (wscanf, __nldbl___isoc99_wscanf) __LDBL_REDIR1_DECL (swscanf, __nldbl___isoc99_swscanf) @@ -42,8 +40,7 @@ __LDBL_REDIR_DECL (swscanf); #ifdef __USE_ISOC99 __LDBL_REDIR1_DECL (wcstold, wcstod); -# if !defined __USE_GNU && !defined __REDIRECT \ - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# if !__GLIBC_USE (DEPRECATED_SCANF) __LDBL_REDIR1_DECL (vfwscanf, __nldbl___isoc99_vfwscanf) __LDBL_REDIR1_DECL (vwscanf, __nldbl___isoc99_vwscanf) __LDBL_REDIR1_DECL (vswscanf, __nldbl___isoc99_vswscanf) diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h index 6c94f3ebc6..24573656bc 100644 --- a/wcsmbs/wchar.h +++ b/wcsmbs/wchar.h @@ -632,13 +632,11 @@ extern int swscanf (const wchar_t *__restrict __s, const wchar_t *__restrict __format, ...) __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; -# if defined __USE_ISOC99 && !defined __USE_GNU \ - && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ - && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +/* For historical reasons, the C99-compliant versions of the scanf + functions are at alternative names. When __LDBL_COMPAT is in + effect, this is handled in bits/wchar-ldbl.h. */ +#if !__GLIBC_USE (DEPRECATED_SCANF) && !defined __LDBL_COMPAT # ifdef __REDIRECT -/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ - GNU extension which conflicts with valid %a followed by letter - s, S or [. */ extern int __REDIRECT (fwscanf, (__FILE *__restrict __stream, const wchar_t *__restrict __format, ...), __isoc99_fwscanf)