mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-26 19:23:34 +08:00
Use C99-compliant scanf under _GNU_SOURCE with modern compilers.
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. With this patch, we now provide 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. Finally, there are several tests in stdio-common that use the extension. bug21.c is a regression test for a crash; it still exercises the relevant code when changed to use %ms instead of %as. scanf14.c through scanf17.c are more complicated since they are actually testing the subtleties of the extension - under what circumstances is 'a' treated as a modifier letter, etc. I changed all of them to use %ms instead of %as as well, but duplicated scanf14.c and scanf16.c as scanf14a.c and scanf16a.c. These still use %as and are compiled with -std=gnu89 to access the old extension. A bunch of diagnostic overrides and manual workarounds for the old stdio.h behavior become unnecessary. 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 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[]. Remove DIAG_IGNORE_NEEDS_COMMENT for -Wformat. * stdio-common/scanf16a.c: New copy of scanf16.c which still uses %as, %aS, %a[]. 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. Compile these files with -std=gnu89.
This commit is contained in:
parent
6f343c1f33
commit
03992356e6
65
ChangeLog
65
ChangeLog
@ -1,3 +1,68 @@
|
||||
2019-01-03 Zack Weinberg <zackw@panix.com>
|
||||
|
||||
* 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 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[]. Remove DIAG_IGNORE_NEEDS_COMMENT for -Wformat.
|
||||
* stdio-common/scanf16a.c: New copy of scanf16.c which still uses
|
||||
%as, %aS, %a[]. 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. Compile these files
|
||||
with -std=gnu89.
|
||||
|
||||
2019-01-03 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
|
||||
|
17
NEWS
17
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.
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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)\"
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -33,3 +33,4 @@ __isoc99_sscanf (const char *s, const char *format, ...)
|
||||
|
||||
return done;
|
||||
}
|
||||
libc_hidden_def (__isoc99_sscanf)
|
||||
|
@ -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>
|
||||
|
||||
|
@ -1,8 +1,28 @@
|
||||
/* Copyright (C) 2007-2019 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/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#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 +44,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 +53,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 +66,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 +75,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 +103,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 +112,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 +126,6 @@ main (void)
|
||||
memset (sp, 'x', sizeof "1.25s");
|
||||
free (sp);
|
||||
}
|
||||
DIAG_POP_NEEDS_COMMENT;
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
|
143
stdio-common/scanf14a.c
Normal file
143
stdio-common/scanf14a.c
Normal file
@ -0,0 +1,143 @@
|
||||
/* Copyright (C) 2007-2019 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/>. */
|
||||
|
||||
/* 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;
|
||||
}
|
@ -1,18 +1,29 @@
|
||||
#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
|
||||
/* Copyright (C) 2007-2019 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/>. */
|
||||
|
||||
#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; \
|
||||
|
@ -1,16 +1,37 @@
|
||||
/* Copyright (C) 2008-2019 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/>. */
|
||||
|
||||
#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; \
|
||||
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 +41,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 +51,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 +75,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 +88,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 +97,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 +134,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 +148,7 @@ main (void)
|
||||
FAIL ();
|
||||
else
|
||||
{
|
||||
if (xscanf ("%as%2c", &sp, c) != 2)
|
||||
if (xscanf ("%ms%2c", &sp, c) != 2)
|
||||
FAIL ();
|
||||
else
|
||||
{
|
||||
|
173
stdio-common/scanf16a.c
Normal file
173
stdio-common/scanf16a.c
Normal file
@ -0,0 +1,173 @@
|
||||
/* Copyright (C) 2008-2019 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/>. */
|
||||
|
||||
/* 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;
|
||||
}
|
@ -1,19 +1,30 @@
|
||||
#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
|
||||
/* Copyright (C) 2008-2019 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/>. */
|
||||
|
||||
#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; \
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user