Add __vfscanf_internal and __vfwscanf_internal with flags arguments.

There are two flags currently defined: SCANF_LDBL_IS_DBL is the mode
used by __nldbl_ scanf variants, and SCANF_ISOC99_A is the mode used
by __isoc99_ scanf variants.  In this patch, the new functions honor
these flag bits if they're set, but they still also look at the
corresponding bits of environmental state, and callers all pass zero.

The new functions do *not* have the "errp" argument possessed by
_IO_vfscanf and _IO_vfwscanf.  All internal callers passed NULL for
that argument.  External callers could theoretically exist, so I
preserved wrappers, but they are flagged as compat symbols and they
don't preserve the three-way distinction among types of errors that
was formerly exposed.  These functions probably should have been in
the list of deprecated _IO_ symbols in 2.27 NEWS -- they're not just
aliases for vfscanf and vfwscanf.

(It was necessary to introduce ldbl_compat_symbol for _IO_vfscanf.
Please check that part of the patch very carefully, I am still not
confident I understand all of the details of ldbl-opt.)

This patch also introduces helper inlines in libio/strfile.h that
encapsulate the process of initializing an _IO_strfile object for
reading.  This allows us to call __vfscanf_internal directly from
sscanf, and __vfwscanf_internal directly from swscanf, without
duplicating the initialization code.  (Previously, they called their
v-counterparts, but that won't work if we want to control *both* C99
mode and ldbl-is-dbl mode using the flags argument to__vfscanf_internal.)
It's still a little awkward, especially for wide strfiles, but it's
much better than what we had.

Tested for powerpc and powerpc64le.
This commit is contained in:
Zack Weinberg 2018-03-07 14:31:58 -05:00 committed by Gabriel F. T. Gomes
parent 72b8692d7e
commit 349718d4d7
35 changed files with 3351 additions and 3128 deletions

View File

@ -1,3 +1,70 @@
2018-12-05 Zack Weinberg <zackw@panix.com>
Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
* libio/libioP.h (SCANF_LDBL_IS_DBL, SCANF_ISOC99_A): New constants.
(__vfscanf_internal, __vfwscanf_internal): New function prototypes.
* libio/libio.h: Remove libc_hidden_proto for _IO_vfscanf.
* libio/strfile.h: Add multiple inclusion guard.
(_IO_strfile_read, _IO_strfile_readw): New inline functions.
* sysdeps/generic/math_ldbl_opt.h: Include shlib-compat.h, for
consistency with the other version of this file.
(ldbl_compat_symbol): New macro.
* sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h (ldbl_compat_symbol):
New macro.
* stdio-common/vfscanf-internal.c: Rename from vfscanf.c.
Define __vfscanf_internal or __vfwscanf_internal, depending on
COMPILE_WSCANF; don't define any other public symbols.
Remove errval and code to set errp.
Temporarily check __ldbl_is_dbl and _IO_FLAGS2_SCANF_STD as well
as the mode_flags argument.
(encode_error, conv_error, input_error): Don't set errval.
* stdio-common/vfwscanf-internal.c: Rename from vfwscanf.c.
Include vfscanf-internal.c.
* stdio-common/vfscanf.c: New file defining the public entry
point vfscanf, which calls __vfscanf_internal.
* stdio-common/vfwscanf.c: New file defining the public entry
point vfwscanf, which calls __vfwscanf_internal.
* stdio-common/iovfscanf.c: New file.
* stdio-common/iovfwscanf.c: Likewise.
* stdio-common/Makefile (routines): Add vfscanf-internal,
vfwscanf-internal, iovfscanf, iovfwscanf.
* stdio-common/Versions: Mention GLIBC_2.29, so that
it can be used in SHLIB_COMPAT expressions.
* sysdeps/ieee754/ldbl-opt/nldbl-compat.c (__nldbl__IO_vfscanf):
Wrap definition and compat_symbol line in #if SHLIB_COMPAT.
Call __vfscanf_internal, instead of _IO_vfscanf.
(__nldbl___vfscanf): Call __vfscanf_internal, instead of
_IO_vfscanf.
(__nldbl_vfwscanf): Call __vfwscanf_internal, instead of
_IO_vfwscanf.
* libio/iovsscanf.c: Clean up includes, when possible. Use
_IO_strfile_read or _IO_strfile_readw, when needed. Call
__vfscanf_internal or __vfwscanf_internal directly.
* libio/iovswscanf.c: Likewise.
* libio/swscanf.c: Likewise.
* libio/vscanf.c: Likewise.
* libio/vwscanf.c: Likewise.
* libio/wscanf.c: Likewise.
* stdio-common/isoc99_fscanf.c: Likewise.
* stdio-common/isoc99_scanf.c: Likewise.
* stdio-common/isoc99_sscanf.c: Likewise.
* stdio-common/isoc99_vfscanf.c: Likewise.
* stdio-common/isoc99_vscanf.c: Likewise.
* stdio-common/isoc99_vsscanf.c: Likewise.
* stdio-common/scanf.c: Likewise.
* stdio-common/sscanf.c: Likewise.
* wcsmbs/isoc99_fwscanf.c: Likewise.
* wcsmbs/isoc99_swscanf.c: Likewise.
* wcsmbs/isoc99_vfwscanf.c: Likewise.
* wcsmbs/isoc99_vswscanf.c: Likewise.
* wcsmbs/isoc99_vwscanf.c: Likewise.
* wcsmbs/isoc99_wscanf.c: Likewise.
2018-12-05 Albert ARIBAUD <albert.aribaud@3adev.fr> 2018-12-05 Albert ARIBAUD <albert.aribaud@3adev.fr>
* include/time.h * include/time.h

View File

@ -24,22 +24,14 @@
This exception applies to code released by its copyright holders This exception applies to code released by its copyright holders
in files containing the exception. */ in files containing the exception. */
#include "libioP.h"
#include "strfile.h" #include "strfile.h"
int int
_IO_vsscanf (const char *string, const char *format, va_list args) _IO_vsscanf (const char *string, const char *format, va_list args)
{ {
int ret;
_IO_strfile sf; _IO_strfile sf;
#ifdef _IO_MTSAFE_IO FILE *f = _IO_strfile_read (&sf, string);
sf._sbf._f._lock = NULL; return __vfscanf_internal (f, format, args, 0);
#endif
_IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
_IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
_IO_str_init_static_internal (&sf, (char*)string, 0, NULL);
ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL);
return ret;
} }
ldbl_weak_alias (_IO_vsscanf, __vsscanf) ldbl_weak_alias (_IO_vsscanf, __vsscanf)
ldbl_weak_alias (_IO_vsscanf, vsscanf) ldbl_weak_alias (_IO_vsscanf, vsscanf)

View File

@ -24,24 +24,16 @@
This exception applies to code released by its copyright holders This exception applies to code released by its copyright holders
in files containing the exception. */ in files containing the exception. */
#include "libioP.h"
#include "strfile.h"
#include <wchar.h> #include <wchar.h>
#include "strfile.h"
int int
__vswscanf (const wchar_t *string, const wchar_t *format, va_list args) __vswscanf (const wchar_t *string, const wchar_t *format, va_list args)
{ {
int ret;
_IO_strfile sf; _IO_strfile sf;
struct _IO_wide_data wd; struct _IO_wide_data wd;
#ifdef _IO_MTSAFE_IO FILE *f = _IO_strfile_readw (&sf, &wd, string);
sf._sbf._f._lock = NULL; return __vfwscanf_internal (f, format, args, 0);
#endif
_IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps);
_IO_fwide (&sf._sbf._f, 1);
_IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL);
ret = _IO_vfwscanf ((FILE *) &sf._sbf, format, args, NULL);
return ret;
} }
libc_hidden_def (__vswscanf) libc_hidden_def (__vswscanf)
ldbl_hidden_def (__vswscanf, vswscanf) ldbl_hidden_def (__vswscanf, vswscanf)

View File

@ -321,7 +321,6 @@ libc_hidden_proto (_IO_padn)
libc_hidden_proto (_IO_putc) libc_hidden_proto (_IO_putc)
libc_hidden_proto (_IO_sgetn) libc_hidden_proto (_IO_sgetn)
libc_hidden_proto (_IO_vfprintf) libc_hidden_proto (_IO_vfprintf)
libc_hidden_proto (_IO_vfscanf)
#ifdef _IO_MTSAFE_IO #ifdef _IO_MTSAFE_IO
# undef _IO_peekc # undef _IO_peekc

View File

@ -704,6 +704,28 @@ extern off64_t _IO_seekpos_unlocked (FILE *, off64_t, int)
#endif /* _G_HAVE_MMAP */ #endif /* _G_HAVE_MMAP */
/* Flags for __vfscanf_internal and __vfwscanf_internal.
SCANF_LDBL_IS_DBL indicates whether long double values are to be
handled as having the same format as double, in which case the flag
should be set to one, or as another format, otherwise.
SCANF_ISOC99_A, when set to one, indicates that the ISO C99 or POSIX
behavior of the scanf functions is to be used, i.e. automatic
allocation for input strings with %as, %aS and %a[, a GNU extension,
is disabled. This is the behavior that the __isoc99_scanf family of
functions use. When the flag is set to zero, automatic allocation is
enabled. */
#define SCANF_LDBL_IS_DBL 0x0001
#define SCANF_ISOC99_A 0x0002
extern int __vfscanf_internal (FILE *fp, const char *format, va_list argp,
unsigned int flags)
attribute_hidden;
extern int __vfwscanf_internal (FILE *fp, const wchar_t *format, va_list argp,
unsigned int flags)
attribute_hidden;
extern int _IO_vscanf (const char *, va_list) __THROW; extern int _IO_vscanf (const char *, va_list) __THROW;
#ifdef _IO_MTSAFE_IO #ifdef _IO_MTSAFE_IO

View File

@ -24,7 +24,9 @@
This exception applies to code released by its copyright holders This exception applies to code released by its copyright holders
in files containing the exception. */ in files containing the exception. */
#include <stdio.h> #ifndef STRFILE_H_
#define STRFILE_H_
#include "libioP.h" #include "libioP.h"
typedef void *(*_IO_alloc_type) (size_t); typedef void *(*_IO_alloc_type) (size_t);
@ -80,3 +82,32 @@ typedef struct
} _IO_wstrnfile; } _IO_wstrnfile;
extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden; extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden;
/* Initialize an _IO_strfile SF to read from narrow string STRING, and
return the corresponding FILE object. It is not necessary to fclose
the FILE when it is no longer needed. */
static inline FILE *
_IO_strfile_read (_IO_strfile *sf, const char *string)
{
sf->_sbf._f._lock = NULL;
_IO_no_init (&sf->_sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
_IO_JUMPS (&sf->_sbf) = &_IO_str_jumps;
_IO_str_init_static_internal (sf, (char*)string, 0, NULL);
return &sf->_sbf._f;
}
/* Initialize an _IO_strfile SF and _IO_wide_data WD to read from wide
string STRING, and return the corresponding FILE object. It is not
necessary to fclose the FILE when it is no longer needed. */
static inline FILE *
_IO_strfile_readw (_IO_strfile *sf, struct _IO_wide_data *wd,
const wchar_t *string)
{
sf->_sbf._f._lock = NULL;
_IO_no_init (&sf->_sbf._f, _IO_USER_LOCK, 0, wd, &_IO_wstr_jumps);
_IO_fwide (&sf->_sbf._f, 1);
_IO_wstr_init_static (&sf->_sbf._f, (wchar_t *)string, 0, NULL);
return &sf->_sbf._f;
}
#endif /* strfile.h. */

View File

@ -15,20 +15,22 @@
License along with the GNU C Library; if not, see License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <libioP.h>
#include <stdarg.h> #include <stdarg.h>
#include <wchar.h> #include "strfile.h"
/* Read formatted input from S, according to the format string FORMAT. */ /* Read formatted input from S, according to the format string FORMAT. */
/* VARARGS2 */
int int
__swscanf (const wchar_t *s, const wchar_t *format, ...) __swscanf (const wchar_t *s, const wchar_t *format, ...)
{ {
va_list arg; va_list arg;
int done; int done;
_IO_strfile sf;
struct _IO_wide_data wd;
FILE *f = _IO_strfile_readw (&sf, &wd, s);
va_start (arg, format); va_start (arg, format);
done = __vswscanf (s, format, arg); done = __vfwscanf_internal (f, format, arg, 0);
va_end (arg); va_end (arg);
return done; return done;

View File

@ -32,6 +32,6 @@
int int
_IO_vscanf (const char *format, va_list args) _IO_vscanf (const char *format, va_list args)
{ {
return _IO_vfscanf (_IO_stdin, format, args, NULL); return __vfscanf_internal (_IO_stdin, format, args, 0);
} }
ldbl_weak_alias (_IO_vscanf, vscanf) ldbl_weak_alias (_IO_vscanf, vscanf)

View File

@ -30,6 +30,6 @@
int int
__vwscanf (const wchar_t *format, va_list args) __vwscanf (const wchar_t *format, va_list args)
{ {
return _IO_vfwscanf (_IO_stdin, format, args, NULL); return __vfwscanf_internal (_IO_stdin, format, args, 0);
} }
ldbl_strong_alias (__vwscanf, vwscanf) ldbl_strong_alias (__vwscanf, vwscanf)

View File

@ -30,7 +30,7 @@ __wscanf (const wchar_t *format, ...)
int done; int done;
va_start (arg, format); va_start (arg, format);
done = _IO_vfwscanf (stdin, format, arg, NULL); done = __vfwscanf_internal (stdin, format, arg, 0);
va_end (arg); va_end (arg);
return done; return done;

View File

@ -39,7 +39,8 @@ routines := \
flockfile ftrylockfile funlockfile \ flockfile ftrylockfile funlockfile \
isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \ isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \
isoc99_vsscanf \ isoc99_vsscanf \
psiginfo gentempfd psiginfo gentempfd \
vfscanf-internal vfwscanf-internal iovfscanf iovfwscanf
aux := errlist siglist printf-parsemb printf-parsewc fxprintf aux := errlist siglist printf-parsemb printf-parsewc fxprintf

View File

@ -60,6 +60,9 @@ libc {
GLIBC_2.28 { GLIBC_2.28 {
renameat2; renameat2;
} }
GLIBC_2.29 {
# SHLIB_COMPAT(GLIBC_2_0, GLIBC_2_29) used in iovfscanf.c etc.
}
GLIBC_PRIVATE { GLIBC_PRIVATE {
# global variables # global variables
_itoa_lower_digits; _itoa_lower_digits;

38
stdio-common/iovfscanf.c Normal file
View File

@ -0,0 +1,38 @@
/* Implementation and symbols for _IO_vfscanf.
Copyright (C) 2018 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 <libioP.h>
#include <shlib-compat.h>
/* This function is provided for ports older than GLIBC 2.29 because
external callers could theoretically exist. Newer ports do not need,
since it is not part of the API. */
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29)
int
attribute_compat_text_section
__IO_vfscanf (FILE *fp, const char *format, va_list ap, int *errp)
{
int rv = __vfscanf_internal (fp, format, ap, 0);
if (__glibc_unlikely (errp != 0))
*errp = (rv == -1);
return rv;
}
ldbl_compat_symbol (libc, __IO_vfscanf, _IO_vfscanf, GLIBC_2_0);
#endif

38
stdio-common/iovfwscanf.c Normal file
View File

@ -0,0 +1,38 @@
/* Implementation and symbols for _IO_vfwscanf.
Copyright (C) 1991-2018 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 <libioP.h>
#include <shlib-compat.h>
/* This function is provided for ports older than GLIBC 2.29 because
external callers could theoretically exist. Newer ports do not need,
since it is not part of the API. */
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29)
int
attribute_compat_text_section
__IO_vfwscanf (FILE *fp, const wchar_t *format, va_list ap, int *errp)
{
int rv = __vfwscanf_internal (fp, format, ap, 0);
if (__glibc_unlikely (errp != 0))
*errp = (rv == -1);
return rv;
}
compat_symbol (libc, __IO_vfwscanf, _IO_vfwscanf, GLIBC_2_0);
#endif

View File

@ -31,7 +31,7 @@ __isoc99_fscanf (FILE *stream, const char *format, ...)
stream->_flags2 |= _IO_FLAGS2_SCANF_STD; stream->_flags2 |= _IO_FLAGS2_SCANF_STD;
va_start (arg, format); va_start (arg, format);
done = _IO_vfscanf (stream, format, arg, NULL); done = __vfscanf_internal (stream, format, arg, 0);
va_end (arg); va_end (arg);
_IO_release_lock (stream); _IO_release_lock (stream);

View File

@ -34,7 +34,7 @@ __isoc99_scanf (const char *format, ...)
stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; stdin->_flags2 |= _IO_FLAGS2_SCANF_STD;
va_start (arg, format); va_start (arg, format);
done = _IO_vfscanf (stdin, format, arg, NULL); done = __vfscanf_internal (stdin, format, arg, 0);
va_end (arg); va_end (arg);
#ifdef _IO_MTSAFE_IO #ifdef _IO_MTSAFE_IO

View File

@ -16,19 +16,20 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <libio/strfile.h>
#include <libioP.h>
/* Read formatted input from S, according to the format string FORMAT. */ /* Read formatted input from S, according to the format string FORMAT. */
/* VARARGS2 */
int int
__isoc99_sscanf (const char *s, const char *format, ...) __isoc99_sscanf (const char *s, const char *format, ...)
{ {
va_list arg; va_list arg;
int done; int done;
_IO_strfile sf;
FILE *f = _IO_strfile_read (&sf, s);
f->_flags2 |= _IO_FLAGS2_SCANF_STD;
va_start (arg, format); va_start (arg, format);
done = __isoc99_vsscanf (s, format, arg); done = __vfscanf_internal (f, format, arg, 0);
va_end (arg); va_end (arg);
return done; return done;

View File

@ -27,7 +27,7 @@ __isoc99_vfscanf (FILE *stream, const char *format, va_list args)
_IO_acquire_lock_clear_flags2 (stream); _IO_acquire_lock_clear_flags2 (stream);
stream->_flags2 |= _IO_FLAGS2_SCANF_STD; stream->_flags2 |= _IO_FLAGS2_SCANF_STD;
done = _IO_vfscanf (stream, format, args, NULL); done = __vfscanf_internal (stream, format, args, 0);
_IO_release_lock (stream); _IO_release_lock (stream);
return done; return done;
} }

View File

@ -27,7 +27,7 @@ __isoc99_vscanf (const char *format, va_list args)
_IO_acquire_lock_clear_flags2 (stdin); _IO_acquire_lock_clear_flags2 (stdin);
stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; stdin->_flags2 |= _IO_FLAGS2_SCANF_STD;
done = _IO_vfscanf (stdin, format, args, NULL); done = __vfscanf_internal (stdin, format, args, 0);
_IO_release_lock (stdin); _IO_release_lock (stdin);
return done; return done;
} }

View File

@ -24,23 +24,14 @@
This exception applies to code released by its copyright holders This exception applies to code released by its copyright holders
in files containing the exception. */ in files containing the exception. */
#include <libioP.h> #include <libio/strfile.h>
#include <stdio.h>
#include "../libio/strfile.h"
int int
__isoc99_vsscanf (const char *string, const char *format, va_list args) __isoc99_vsscanf (const char *string, const char *format, va_list args)
{ {
int ret;
_IO_strfile sf; _IO_strfile sf;
#ifdef _IO_MTSAFE_IO FILE *f = _IO_strfile_read (&sf, string);
sf._sbf._f._lock = NULL; f->_flags2 |= _IO_FLAGS2_SCANF_STD;
#endif return __vfscanf_internal (f, format, args, 0);
_IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
_IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
_IO_str_init_static_internal (&sf, (char*)string, 0, NULL);
sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD;
ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL);
return ret;
} }
libc_hidden_def (__isoc99_vsscanf) libc_hidden_def (__isoc99_vsscanf)

View File

@ -30,7 +30,7 @@ __scanf (const char *format, ...)
int done; int done;
va_start (arg, format); va_start (arg, format);
done = _IO_vfscanf (stdin, format, arg, NULL); done = __vfscanf_internal (stdin, format, arg, 0);
va_end (arg); va_end (arg);
return done; return done;

View File

@ -16,26 +16,24 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <libio/strfile.h>
#include <libioP.h>
#define __vsscanf(s, f, a) _IO_vsscanf (s, f, a)
/* Read formatted input from S, according to the format string FORMAT. */ /* Read formatted input from S, according to the format string FORMAT. */
/* VARARGS2 */
int int
__sscanf (const char *s, const char *format, ...) __sscanf (const char *s, const char *format, ...)
{ {
va_list arg; va_list arg;
int done; int done;
_IO_strfile sf;
FILE *f = _IO_strfile_read (&sf, s);
va_start (arg, format); va_start (arg, format);
done = __vsscanf (s, format, arg); done = __vfscanf_internal (f, format, arg, 0);
va_end (arg); va_end (arg);
return done; return done;
} }
ldbl_hidden_def (__sscanf, sscanf) ldbl_hidden_def (__sscanf, sscanf)
ldbl_strong_alias (__sscanf, sscanf) ldbl_strong_alias (__sscanf, sscanf)
#undef _IO_sscanf
/* This is for libg++. */
ldbl_strong_alias (__sscanf, _IO_sscanf) ldbl_strong_alias (__sscanf, _IO_sscanf)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
#define COMPILE_WSCANF 1
#include "vfscanf-internal.c"

View File

@ -1,2 +1,26 @@
#define COMPILE_WSCANF 1 /* Implementation and symbols for vfwscanf.
#include "vfscanf.c" Copyright (C) 2018 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 <libioP.h>
int
__vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
{
return __vfwscanf_internal (s, format, argptr, 0);
}
ldbl_weak_alias (__vfwscanf, vfwscanf)

View File

@ -6,9 +6,13 @@
for platforms where compatibility symbols are required for a previous for platforms where compatibility symbols are required for a previous
ABI that defined long double functions as aliases for the double code. */ ABI that defined long double functions as aliases for the double code. */
#include <shlib-compat.h>
#define LONG_DOUBLE_COMPAT(lib, introduced) 0 #define LONG_DOUBLE_COMPAT(lib, introduced) 0
#define long_double_symbol(lib, local, symbol) #define long_double_symbol(lib, local, symbol)
#define ldbl_hidden_def(local, name) libc_hidden_def (name) #define ldbl_hidden_def(local, name) libc_hidden_def (name)
#define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname) #define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname)
#define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname) #define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname)
#define ldbl_compat_symbol(lib, local, symbol, version) \
compat_symbol (lib, local, symbol, version)
#define __ldbl_is_dbl 0 #define __ldbl_is_dbl 0

View File

@ -20,10 +20,16 @@
long_double_symbol (libc, __GL_##name##_##aliasname, aliasname); long_double_symbol (libc, __GL_##name##_##aliasname, aliasname);
# define long_double_symbol_1(lib, local, symbol, version) \ # define long_double_symbol_1(lib, local, symbol, version) \
versioned_symbol (lib, local, symbol, version) versioned_symbol (lib, local, symbol, version)
# define ldbl_compat_symbol(lib, local, symbol, version) \
compat_symbol (lib, local, symbol, LONG_DOUBLE_COMPAT_VERSION)
#else #else
# define ldbl_hidden_def(local, name) libc_hidden_def (name) # define ldbl_hidden_def(local, name) libc_hidden_def (name)
# define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname) # define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname)
# define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname) # define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname)
/* Same as compat_symbol, ldbl_compat_symbol is not to be used outside
'#if SHLIB_COMPAT' statement and should fail if it is. */
# define ldbl_compat_symbol(lib, local, symbol, version) \
_Static_assert (0, "ldbl_compat_symbol should be used inside SHLIB_COMPAT");
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
/* Note that weak_alias cannot be used - it is defined to nothing /* Note that weak_alias cannot be used - it is defined to nothing
in most of the C files. */ in most of the C files. */

View File

@ -330,16 +330,20 @@ __nldbl_wprintf (const wchar_t *fmt, ...)
return done; return done;
} }
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29)
int int
attribute_compat_text_section attribute_compat_text_section
__nldbl__IO_vfscanf (FILE *s, const char *fmt, va_list ap, int *errp) __nldbl__IO_vfscanf (FILE *s, const char *fmt, va_list ap, int *errp)
{ {
int res; int res;
set_no_long_double (); set_no_long_double ();
res = _IO_vfscanf (s, fmt, ap, errp); res = __vfscanf_internal (s, fmt, ap, 0);
clear_no_long_double (); clear_no_long_double ();
if (__glibc_unlikely (errp != 0))
*errp = (res == -1);
return res; return res;
} }
#endif
int int
attribute_compat_text_section attribute_compat_text_section
@ -347,7 +351,7 @@ __nldbl___vfscanf (FILE *s, const char *fmt, va_list ap)
{ {
int res; int res;
set_no_long_double (); set_no_long_double ();
res = _IO_vfscanf (s, fmt, ap, NULL); res = __vfscanf_internal (s, fmt, ap, 0);
clear_no_long_double (); clear_no_long_double ();
return res; return res;
} }
@ -423,7 +427,7 @@ __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
{ {
int res; int res;
set_no_long_double (); set_no_long_double ();
res = _IO_vfwscanf (s, fmt, ap, NULL); res = __vfwscanf_internal (s, fmt, ap, 0);
clear_no_long_double (); clear_no_long_double ();
return res; return res;
} }
@ -1027,7 +1031,6 @@ compat_symbol (libc, __nldbl_vdprintf, vdprintf, GLIBC_2_0);
compat_symbol (libc, __nldbl_vsnprintf, vsnprintf, GLIBC_2_0); compat_symbol (libc, __nldbl_vsnprintf, vsnprintf, GLIBC_2_0);
compat_symbol (libc, __nldbl_vsprintf, vsprintf, GLIBC_2_0); compat_symbol (libc, __nldbl_vsprintf, vsprintf, GLIBC_2_0);
compat_symbol (libc, __nldbl__IO_sscanf, _IO_sscanf, GLIBC_2_0); compat_symbol (libc, __nldbl__IO_sscanf, _IO_sscanf, GLIBC_2_0);
compat_symbol (libc, __nldbl__IO_vfscanf, _IO_vfscanf, GLIBC_2_0);
compat_symbol (libc, __nldbl___vfscanf, __vfscanf, GLIBC_2_0); compat_symbol (libc, __nldbl___vfscanf, __vfscanf, GLIBC_2_0);
compat_symbol (libc, __nldbl___vsscanf, __vsscanf, GLIBC_2_0); compat_symbol (libc, __nldbl___vsscanf, __vsscanf, GLIBC_2_0);
compat_symbol (libc, __nldbl_fscanf, fscanf, GLIBC_2_0); compat_symbol (libc, __nldbl_fscanf, fscanf, GLIBC_2_0);
@ -1040,6 +1043,12 @@ compat_symbol (libc, __nldbl___printf_fp, __printf_fp, GLIBC_2_0);
compat_symbol (libc, __nldbl_strfmon, strfmon, GLIBC_2_0); compat_symbol (libc, __nldbl_strfmon, strfmon, GLIBC_2_0);
compat_symbol (libc, __nldbl_syslog, syslog, GLIBC_2_0); compat_symbol (libc, __nldbl_syslog, syslog, GLIBC_2_0);
compat_symbol (libc, __nldbl_vsyslog, vsyslog, GLIBC_2_0); compat_symbol (libc, __nldbl_vsyslog, vsyslog, GLIBC_2_0);
/* This function is not in public headers, but was exported until
version 2.29. For platforms that are newer than that, there's no
need to expose the symbol. */
# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29)
compat_symbol (libc, __nldbl__IO_vfscanf, _IO_vfscanf, GLIBC_2_0);
# endif
#endif #endif
#if LONG_DOUBLE_COMPAT(libc, GLIBC_2_1) #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_1)
compat_symbol (libc, __nldbl___asprintf, __asprintf, GLIBC_2_1); compat_symbol (libc, __nldbl___asprintf, __asprintf, GLIBC_2_1);

View File

@ -32,7 +32,7 @@ __isoc99_fwscanf (FILE *stream, const wchar_t *format, ...)
stream->_flags2 |= _IO_FLAGS2_SCANF_STD; stream->_flags2 |= _IO_FLAGS2_SCANF_STD;
va_start (arg, format); va_start (arg, format);
done = _IO_vfwscanf (stream, format, arg, NULL); done = __vfwscanf_internal (stream, format, arg, 0);
va_end (arg); va_end (arg);
_IO_release_lock (stream); _IO_release_lock (stream);

View File

@ -16,20 +16,22 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <libio/strfile.h>
#include <libioP.h>
#include <wchar.h>
/* Read formatted input from S, according to the format string FORMAT. */ /* Read formatted input from S, according to the format string FORMAT. */
/* VARARGS2 */
int int
__isoc99_swscanf (const wchar_t *s, const wchar_t *format, ...) __isoc99_swscanf (const wchar_t *s, const wchar_t *format, ...)
{ {
va_list arg; va_list arg;
int done; int done;
_IO_strfile sf;
struct _IO_wide_data wd;
FILE *f = _IO_strfile_readw (&sf, &wd, s);
f->_flags2 |= _IO_FLAGS2_SCANF_STD;
va_start (arg, format); va_start (arg, format);
done = __isoc99_vswscanf (s, format, arg); done = __vfwscanf_internal (f, format, arg, 0);
va_end (arg); va_end (arg);
return done; return done;

View File

@ -28,7 +28,7 @@ __isoc99_vfwscanf (FILE *stream, const wchar_t *format, va_list args)
_IO_acquire_lock_clear_flags2 (stream); _IO_acquire_lock_clear_flags2 (stream);
stream->_flags2 |= _IO_FLAGS2_SCANF_STD; stream->_flags2 |= _IO_FLAGS2_SCANF_STD;
done = _IO_vfwscanf (stream, format, args, NULL); done = __vfwscanf_internal (stream, format, args, 0);
_IO_release_lock (stream); _IO_release_lock (stream);
return done; return done;
} }

View File

@ -24,24 +24,16 @@
This exception applies to code released by its copyright holders This exception applies to code released by its copyright holders
in files containing the exception. */ in files containing the exception. */
#include <libioP.h>
#include <wchar.h> #include <wchar.h>
#include "../libio/strfile.h" #include <libio/strfile.h>
int int
__isoc99_vswscanf (const wchar_t *string, const wchar_t *format, va_list args) __isoc99_vswscanf (const wchar_t *string, const wchar_t *format, va_list args)
{ {
int ret;
_IO_strfile sf; _IO_strfile sf;
struct _IO_wide_data wd; struct _IO_wide_data wd;
#ifdef _IO_MTSAFE_IO FILE *f = _IO_strfile_readw (&sf, &wd, string);
sf._sbf._f._lock = NULL; f->_flags2 |= _IO_FLAGS2_SCANF_STD;
#endif return __vfwscanf_internal (f, format, args, 0);
_IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps);
_IO_fwide (&sf._sbf._f, 1);
_IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL);
sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD;
ret = _IO_vfwscanf ((FILE *) &sf._sbf, format, args, NULL);
return ret;
} }
libc_hidden_def (__isoc99_vswscanf) libc_hidden_def (__isoc99_vswscanf)

View File

@ -28,7 +28,7 @@ __isoc99_vwscanf (const wchar_t *format, va_list args)
_IO_acquire_lock_clear_flags2 (stdin); _IO_acquire_lock_clear_flags2 (stdin);
stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; stdin->_flags2 |= _IO_FLAGS2_SCANF_STD;
done = _IO_vfwscanf (stdin, format, args, NULL); done = __vfwscanf_internal (stdin, format, args, 0);
_IO_release_lock (stdin); _IO_release_lock (stdin);
return done; return done;
} }

View File

@ -33,7 +33,7 @@ __isoc99_wscanf (const wchar_t *format, ...)
stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; stdin->_flags2 |= _IO_FLAGS2_SCANF_STD;
va_start (arg, format); va_start (arg, format);
done = _IO_vfwscanf (stdin, format, arg, NULL); done = __vfwscanf_internal (stdin, format, arg, 0);
va_end (arg); va_end (arg);
_IO_release_lock (stdin); _IO_release_lock (stdin);