This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH 2/9] Add __vfscanf_internal and __vfwscanf_internal with flags arguments.
- From: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- To: libc-alpha at sourceware dot org
- Date: Tue, 13 Mar 2018 09:35:11 -0300
- Subject: Re: [PATCH 2/9] Add __vfscanf_internal and __vfwscanf_internal with flags arguments.
- Authentication-results: sourceware.org; auth=none
- References: <20180307193205.4751-1-zackw@panix.com> <20180307193205.4751-3-zackw@panix.com>
On 07/03/2018 16:31, Zack Weinberg wrote:
> 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.
Look good in general, some remarks below.
>
> * 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_WPRINTF; don't define any other public symbols.
> 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, stdio-common/vfwscanf.c: New files
> defining the public entry points vfscanf and vfwscanf respectively.
> * stdio-common/iovfscanf.c, stdio-common/iovfwscanf.c: New files
> defining the compat symbols _IO_vfscanf and _IO_vfwscanf respectively.
> * stdio-common/Makefile (routines): Add vfscanf-internal,
> vfwscanf-internal, iovfscanf, iovfwscanf.
> * stdio-common/Versions: Mention GLIBC_2.28, 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.
>
> * libio/iovsscanf.c, libio/vscanf.c, libio/vwscanf.c, libio/wscanf.c
> * libio/iovswscanf.c, stdio-common/isoc99_fscanf.c
> * stdio-common/isoc99_scanf.c, stdio-common/isoc99_vfscanf.c
> * stdio-common/isoc99_vscanf.c, stdio-common/isoc99_vsscanf.c
> * stdio-common/scanf.c, sysdeps/ieee754/ldbl-opt/nldbl-compat.c
> * wcsmbs/isoc99_fwscanf.c, wcsmbs/isoc99_vfwscanf.c
> * wcsmbs/isoc99_vswscanf.c, wcsmbs/isoc99_vwscanf.c
> * wcsmbs/isoc99_wscanf.c: Use __vfscanf_internal instead of
> _IO_vfscanf, and/or __vfwscanf_internal instead of _IO_vfwscanf.
>
> * libio/iovsscanf.c, stdio-common/isoc99_vsscanf.c:
> Use _IO_strfile_read. Clean up includes.
> * stdio-common/sscanf.c, stdio-common/isoc99_sscanf.c:
> Use _IO_strfile_read to set up a FILE, and then call
> __vfwcanf_internal directly. Clean up includes.
>
> * libio/iovswscanf.c, wcsmbs/isoc99_vswscanf.c:
> Use _IO_strfile_readw. Clean up includes.
> * libio/swscanf.c, wcsmbs/isoc99_swscanf.c:
> Use _IO_strfile_readw to set up a FILE, and then call
> __vfwscanf_internal directly. Clean up includes.
> ---
> libio/iovsscanf.c | 12 +-
> libio/iovswscanf.c | 14 +-
> libio/libio.h | 1 -
> libio/libioP.h | 9 +
> libio/strfile.h | 33 +-
> libio/swscanf.c | 10 +-
> libio/vscanf.c | 2 +-
> libio/vwscanf.c | 2 +-
> libio/wscanf.c | 2 +-
> stdio-common/Makefile | 3 +-
> stdio-common/Versions | 3 +
> stdio-common/iovfscanf.c | 34 +
> stdio-common/iovfwscanf.c | 34 +
> stdio-common/isoc99_fscanf.c | 2 +-
> stdio-common/isoc99_scanf.c | 2 +-
> stdio-common/isoc99_sscanf.c | 8 +-
> stdio-common/isoc99_vfscanf.c | 2 +-
> stdio-common/isoc99_vscanf.c | 2 +-
> stdio-common/isoc99_vsscanf.c | 17 +-
> stdio-common/scanf.c | 2 +-
> stdio-common/sscanf.c | 12 +-
> stdio-common/{vfscanf.c => vfscanf-internal.c} | 46 +-
> stdio-common/vfscanf.c | 27 +
> stdio-common/{vfwscanf.c => vfwscanf-internal.c} | 2 +-
> stdio-common/vfwscanf.c | 25 +
> sysdeps/generic/math_ldbl_opt.h | 4 +
> sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h | 4 +
> sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 12 +-
> wcsmbs/isoc99_fwscanf.c | 2 +-
> wcsmbs/isoc99_swscanf.c | 12 +-
> wcsmbs/isoc99_vfwscanf.c | 2 +-
> wcsmbs/isoc99_vswscanf.c | 16 +-
> wcsmbs/isoc99_vwscanf.c | 2 +-
> wcsmbs/isoc99_wscanf.c | 2 +-
> 34 files changed, 211 insertions(+), 115 deletions(-)
> create mode 100644 stdio-common/iovfscanf.c
> create mode 100644 stdio-common/iovfwscanf.c
> create mode 100644 stdio-common/vfscanf.c
> create mode 100644 stdio-common/vfwscanf.c
>
> diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c
> index e56ab8bd7d..ee6a99ec6a 100644
> --- a/libio/iovsscanf.c
> +++ b/libio/iovsscanf.c
> @@ -24,22 +24,14 @@
> This exception applies to code released by its copyright holders
> in files containing the exception. */
>
> -#include "libioP.h"
> #include "strfile.h"
>
> int
> _IO_vsscanf (const char *string, const char *format, va_list args)
> {
> - int ret;
> _IO_strfile sf;
> -#ifdef _IO_MTSAFE_IO
> - sf._sbf._f._lock = NULL;
> -#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;
> + FILE *f = _IO_strfile_read (&sf, string);
> + return __vfscanf_internal (f, format, args, 0);
> }
> ldbl_weak_alias (_IO_vsscanf, __vsscanf)
> ldbl_weak_alias (_IO_vsscanf, vsscanf)
Ok.
> diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c
> index 5bd1c88412..cb9cbe15cc 100644
> --- a/libio/iovswscanf.c
> +++ b/libio/iovswscanf.c
> @@ -24,24 +24,16 @@
> This exception applies to code released by its copyright holders
> in files containing the exception. */
>
> -#include "libioP.h"
> -#include "strfile.h"
> #include <wchar.h>
> +#include "strfile.h"
>
> int
> __vswscanf (const wchar_t *string, const wchar_t *format, va_list args)
> {
> - int ret;
> _IO_strfile sf;
> struct _IO_wide_data wd;
> -#ifdef _IO_MTSAFE_IO
> - sf._sbf._f._lock = NULL;
> -#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;
> + FILE *f = _IO_strfile_readw (&sf, &wd, string);
> + return __vfwscanf_internal (f, format, args, 0);
> }
> libc_hidden_def (__vswscanf)
> ldbl_hidden_def (__vswscanf, vswscanf)
Ok.
> diff --git a/libio/libio.h b/libio/libio.h
> index 00f9169613..d4eba2df54 100644
> --- a/libio/libio.h
> +++ b/libio/libio.h
> @@ -321,7 +321,6 @@ libc_hidden_proto (_IO_padn)
> libc_hidden_proto (_IO_putc)
> libc_hidden_proto (_IO_sgetn)
> libc_hidden_proto (_IO_vfprintf)
> -libc_hidden_proto (_IO_vfscanf)
>
> #ifdef _IO_MTSAFE_IO
> # undef _IO_peekc
Ok.
> diff --git a/libio/libioP.h b/libio/libioP.h
> index 8afe7032e3..a471c90be8 100644
> --- a/libio/libioP.h
> +++ b/libio/libioP.h
> @@ -704,6 +704,15 @@ extern off64_t _IO_seekpos_unlocked (FILE *, off64_t, int)
>
> #endif /* _G_HAVE_MMAP */
>
> +/* Flags for __vfscanf_internal and __vfwscanf_internal. */
> +#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);
> +extern int __vfwscanf_internal (FILE *fp, const wchar_t *format, va_list argp,
> + unsigned int flags);
> +
> extern int _IO_vscanf (const char *, va_list) __THROW;
>
> #ifdef _IO_MTSAFE_IO
Ok.
> diff --git a/libio/strfile.h b/libio/strfile.h
> index 46ac81809a..715149f5bd 100644
> --- a/libio/strfile.h
> +++ b/libio/strfile.h
> @@ -24,7 +24,9 @@
> This exception applies to code released by its copyright holders
> in files containing the exception. */
>
> -#include <stdio.h>
> +#ifndef STRFILE_H_
> +#define STRFILE_H_
> +
> #include "libioP.h"
>
> typedef void *(*_IO_alloc_type) (size_t);
> @@ -81,3 +83,32 @@ typedef struct
> } _IO_wstrnfile;
>
> 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;
> +}
Should we add a note about _IO_MTSAFE_IO cleanup?
> +
> +/* 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. */
Ok.
> diff --git a/libio/swscanf.c b/libio/swscanf.c
> index c8686bcbaf..90f721cc51 100644
> --- a/libio/swscanf.c
> +++ b/libio/swscanf.c
> @@ -15,20 +15,22 @@
> License along with the GNU C Library; if not, see
> <http://www.gnu.org/licenses/>. */
>
> -#include <libioP.h>
> #include <stdarg.h>
> -#include <wchar.h>
> +#include "strfile.h"
>
> /* Read formatted input from S, according to the format string FORMAT. */
> -/* VARARGS2 */
> +
> int
> __swscanf (const wchar_t *s, const wchar_t *format, ...)
> {
> va_list arg;
> int done;
> + _IO_strfile sf;
> + struct _IO_wide_data wd;
> + FILE *f = _IO_strfile_readw (&sf, &wd, s);
>
> va_start (arg, format);
> - done = __vswscanf (s, format, arg);
> + done = __vfwscanf_internal (f, format, arg, 0);
> va_end (arg);
>
> return done;
Ok.
> diff --git a/libio/vscanf.c b/libio/vscanf.c
> index 9c27122c27..a3e2dd43f2 100644
> --- a/libio/vscanf.c
> +++ b/libio/vscanf.c
> @@ -32,6 +32,6 @@
> int
> _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)
Ok.
> diff --git a/libio/vwscanf.c b/libio/vwscanf.c
> index 0d5f558758..7af770c8c3 100644
> --- a/libio/vwscanf.c
> +++ b/libio/vwscanf.c
> @@ -30,6 +30,6 @@
> int
> __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)
Ok.
> diff --git a/libio/wscanf.c b/libio/wscanf.c
> index c8cdad0acd..fe27ff6fa6 100644
> --- a/libio/wscanf.c
> +++ b/libio/wscanf.c
> @@ -30,7 +30,7 @@ __wscanf (const wchar_t *format, ...)
> int done;
>
> va_start (arg, format);
> - done = _IO_vfwscanf (stdin, format, arg, NULL);
> + done = __vfwscanf_internal (stdin, format, arg, 0);
> va_end (arg);
>
> return done;
Ok.
> diff --git a/stdio-common/Makefile b/stdio-common/Makefile
> index 9dfc115313..b7b1f01bdd 100644
> --- a/stdio-common/Makefile
> +++ b/stdio-common/Makefile
> @@ -39,7 +39,8 @@ routines := \
> flockfile ftrylockfile funlockfile \
> isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \
> isoc99_vsscanf \
> - psiginfo gentempfd
> + psiginfo gentempfd \
> + vfscanf-internal vfwscanf-internal iovfscanf iovfwscanf
>
> aux := errlist siglist printf-parsemb printf-parsewc fxprintf
>
Ok.
> diff --git a/stdio-common/Versions b/stdio-common/Versions
> index 5016f69c20..7af44949f7 100644
> --- a/stdio-common/Versions
> +++ b/stdio-common/Versions
> @@ -57,6 +57,9 @@ libc {
> psiginfo;
> register_printf_modifier; register_printf_type; register_printf_specifier;
> }
> + GLIBC_2.28 {
> + # SHLIB_COMPAT(GLIBC_2_0, GLIBC_2_28) used in iovfscanf.c etc
> + }
> GLIBC_PRIVATE {
> # global variables
> _itoa_lower_digits;
> diff --git a/stdio-common/iovfscanf.c b/stdio-common/iovfscanf.c
> new file mode 100644
> index 0000000000..fb347d60cb
> --- /dev/null
> +++ b/stdio-common/iovfscanf.c
> @@ -0,0 +1,34 @@
> +/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
Missing one line description.
> +
> + 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>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_28)
> +
> +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
> diff --git a/stdio-common/iovfwscanf.c b/stdio-common/iovfwscanf.c
> new file mode 100644
> index 0000000000..73936f68b2
> --- /dev/null
> +++ b/stdio-common/iovfwscanf.c
> @@ -0,0 +1,34 @@
> +/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
Missing one line description.
> +
> + 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>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_28)
> +
> +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
> diff --git a/stdio-common/isoc99_fscanf.c b/stdio-common/isoc99_fscanf.c
> index 9cdf85e679..4210d11f2b 100644
> --- a/stdio-common/isoc99_fscanf.c
> +++ b/stdio-common/isoc99_fscanf.c
> @@ -31,7 +31,7 @@ __isoc99_fscanf (FILE *stream, const char *format, ...)
> stream->_flags2 |= _IO_FLAGS2_SCANF_STD;
>
> va_start (arg, format);
> - done = _IO_vfscanf (stream, format, arg, NULL);
> + done = __vfscanf_internal (stream, format, arg, 0);
> va_end (arg);
>
> _IO_release_lock (stream);
Ok.
> diff --git a/stdio-common/isoc99_scanf.c b/stdio-common/isoc99_scanf.c
> index bf7dbe86bb..64c873eed9 100644
> --- a/stdio-common/isoc99_scanf.c
> +++ b/stdio-common/isoc99_scanf.c
> @@ -34,7 +34,7 @@ __isoc99_scanf (const char *format, ...)
> stdin->_flags2 |= _IO_FLAGS2_SCANF_STD;
>
> va_start (arg, format);
> - done = _IO_vfscanf (stdin, format, arg, NULL);
> + done = __vfscanf_internal (stdin, format, arg, 0);
> va_end (arg);
>
> #ifdef _IO_MTSAFE_IO
Ok.
> diff --git a/stdio-common/isoc99_sscanf.c b/stdio-common/isoc99_sscanf.c
> index 56a60a2c05..95b94a68b5 100644
> --- a/stdio-common/isoc99_sscanf.c
> +++ b/stdio-common/isoc99_sscanf.c
> @@ -16,8 +16,7 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <stdarg.h>
> -#include <stdio.h>
> -#include <libioP.h>
> +#include <libio/strfile.h>
>
> /* Read formatted input from S, according to the format string FORMAT. */
> /* VARARGS2 */
I think you can cleanup this VARARGS2 comment as before.
> @@ -26,9 +25,12 @@ __isoc99_sscanf (const char *s, const char *format, ...)
> {
> va_list arg;
> int done;
> + _IO_strfile sf;
> + FILE *f = _IO_strfile_read (&sf, s);
> + f->_flags2 |= _IO_FLAGS2_SCANF_STD;
>
> va_start (arg, format);
> - done = __isoc99_vsscanf (s, format, arg);
> + done = __vfscanf_internal (f, format, arg, 0);
> va_end (arg);
>
> return done;
Ok.
> diff --git a/stdio-common/isoc99_vfscanf.c b/stdio-common/isoc99_vfscanf.c
> index b80e05f8db..c96ca831ae 100644
> --- a/stdio-common/isoc99_vfscanf.c
> +++ b/stdio-common/isoc99_vfscanf.c
> @@ -27,7 +27,7 @@ __isoc99_vfscanf (FILE *stream, const char *format, va_list args)
>
> _IO_acquire_lock_clear_flags2 (stream);
> stream->_flags2 |= _IO_FLAGS2_SCANF_STD;
> - done = _IO_vfscanf (stream, format, args, NULL);
> + done = __vfscanf_internal (stream, format, args, 0);
> _IO_release_lock (stream);
> return done;
> }
Ok.
> diff --git a/stdio-common/isoc99_vscanf.c b/stdio-common/isoc99_vscanf.c
> index 0b747f85ba..72ae72ddee 100644
> --- a/stdio-common/isoc99_vscanf.c
> +++ b/stdio-common/isoc99_vscanf.c
> @@ -27,7 +27,7 @@ __isoc99_vscanf (const char *format, va_list args)
>
> _IO_acquire_lock_clear_flags2 (stdin);
> stdin->_flags2 |= _IO_FLAGS2_SCANF_STD;
> - done = _IO_vfscanf (stdin, format, args, NULL);
> + done = __vfscanf_internal (stdin, format, args, 0);
> _IO_release_lock (stdin);
> return done;
> }
Ok.
> diff --git a/stdio-common/isoc99_vsscanf.c b/stdio-common/isoc99_vsscanf.c
> index ac85ef2d0d..02bc0f50e6 100644
> --- a/stdio-common/isoc99_vsscanf.c
> +++ b/stdio-common/isoc99_vsscanf.c
> @@ -24,23 +24,14 @@
> This exception applies to code released by its copyright holders
> in files containing the exception. */
>
> -#include <libioP.h>
> -#include <stdio.h>
> -#include "../libio/strfile.h"
> +#include <libio/strfile.h>
>
> int
> __isoc99_vsscanf (const char *string, const char *format, va_list args)
> {
> - int ret;
> _IO_strfile sf;
> -#ifdef _IO_MTSAFE_IO
> - sf._sbf._f._lock = NULL;
> -#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);
> - sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD;
> - ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL);
> - return ret;
> + FILE *f = _IO_strfile_read (&sf, string);
> + f->_flags2 |= _IO_FLAGS2_SCANF_STD;
> + return __vfscanf_internal (f, format, args, 0);
> }
> libc_hidden_def (__isoc99_vsscanf)
Ok.
> diff --git a/stdio-common/scanf.c b/stdio-common/scanf.c
> index e61b5f1ad3..de38d70353 100644
> --- a/stdio-common/scanf.c
> +++ b/stdio-common/scanf.c
> @@ -30,7 +30,7 @@ __scanf (const char *format, ...)
> int done;
>
> va_start (arg, format);
> - done = _IO_vfscanf (stdin, format, arg, NULL);
> + done = __vfscanf_internal (stdin, format, arg, 0);
> va_end (arg);
>
> return done;
Ok.
> diff --git a/stdio-common/sscanf.c b/stdio-common/sscanf.c
> index 88cd641798..e25e9c27a5 100644
> --- a/stdio-common/sscanf.c
> +++ b/stdio-common/sscanf.c
> @@ -16,26 +16,24 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <stdarg.h>
> -#include <stdio.h>
> -#include <libioP.h>
> -#define __vsscanf(s, f, a) _IO_vsscanf (s, f, a)
> +#include <libio/strfile.h>
>
> /* Read formatted input from S, according to the format string FORMAT. */
> -/* VARARGS2 */
> +
> int
> __sscanf (const char *s, const char *format, ...)
> {
> va_list arg;
> int done;
> + _IO_strfile sf;
> + FILE *f = _IO_strfile_read (&sf, s);
>
> va_start (arg, format);
> - done = __vsscanf (s, format, arg);
> + done = __vfscanf_internal (f, format, arg, 0);
> va_end (arg);
>
> return done;
> }
> ldbl_hidden_def (__sscanf, sscanf)
> ldbl_strong_alias (__sscanf, sscanf)
> -#undef _IO_sscanf
> -/* This is for libg++. */
> ldbl_strong_alias (__sscanf, _IO_sscanf)
Ok.
> diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf-internal.c
> similarity index 98%
> rename from stdio-common/vfscanf.c
> rename to stdio-common/vfscanf-internal.c
> index 3263268c7e..93b07ad4bc 100644
> --- a/stdio-common/vfscanf.c
> +++ b/stdio-common/vfscanf-internal.c
> @@ -132,16 +132,13 @@
> #include "printf-parse.h" /* Use read_int. */
>
> #define encode_error() do { \
> - errval = 4; \
> __set_errno (EILSEQ); \
> goto errout; \
> } while (0)
> #define conv_error() do { \
> - errval = 2; \
> goto errout; \
> } while (0)
> #define input_error() do { \
> - errval = 1; \
> if (done == 0) done = EOF; \
> goto errout; \
> } while (0)
> @@ -267,12 +264,12 @@ char_buffer_add (struct char_buffer *buffer, CHAR_T ch)
> Return the number of assignments made, or -1 for an input error. */
> #ifdef COMPILE_WSCANF
> int
> -_IO_vfwscanf (FILE *s, const wchar_t *format, va_list argptr,
> - int *errp)
> +__vfwscanf_internal (FILE *s, const wchar_t *format, va_list argptr,
> + unsigned int mode_flags)
> #else
> int
> -_IO_vfscanf_internal (FILE *s, const char *format, va_list argptr,
> - int *errp)
> +__vfscanf_internal (FILE *s, const char *format, va_list argptr,
> + unsigned int mode_flags)
> #endif
> {
> va_list arg;
> @@ -283,7 +280,6 @@ _IO_vfscanf_internal (FILE *s, const char *format, va_list argptr,
> WINT_T c = 0; /* Last char read. */
> int width; /* Maximum field width. */
> int flags; /* Modifiers for current format element. */
> - int errval = 0;
> #ifndef COMPILE_WSCANF
> locale_t loc = _NL_CURRENT_LOCALE;
> struct __locale_data *const curctype = loc->__locales[LC_CTYPE];
> @@ -335,6 +331,14 @@ _IO_vfscanf_internal (FILE *s, const char *format, va_list argptr,
> struct char_buffer charbuf;
> scratch_buffer_init (&charbuf.scratch);
>
> +#define LDBL_DISTINCT (__glibc_likely ((mode_flags & SCANF_LDBL_IS_DBL) == 0))
> +#define USE_ISOC99_A (__glibc_likely (mode_flags & SCANF_ISOC99_A))
> + /* Temporarily honor the environmental mode bits. */
> + if (__ldbl_is_dbl)
> + mode_flags |= SCANF_LDBL_IS_DBL;
> + if (s->_flags2 & _IO_FLAGS2_SCANF_STD)
> + mode_flags |= SCANF_ISOC99_A;
> +
> #ifdef __va_copy
> __va_copy (arg, argptr);
> #else
> @@ -566,7 +570,7 @@ _IO_vfscanf_internal (FILE *s, const char *format, va_list argptr,
> }
> /* In __isoc99_*scanf %as, %aS and %a[ extension is not
> supported at all. */
> - if (s->_flags2 & _IO_FLAGS2_SCANF_STD)
> + if (USE_ISOC99_A)
> {
> --f;
> break;
> @@ -2422,7 +2426,7 @@ _IO_vfscanf_internal (FILE *s, const char *format, va_list argptr,
> done = EOF;
> goto errout;
> }
> - if ((flags & LONGDBL) && !__ldbl_is_dbl)
> + if ((flags & LONGDBL) && LDBL_DISTINCT)
> {
> long double d = __strtold_internal
> (char_buffer_start (&charbuf), &tw, flags & GROUP);
> @@ -3017,8 +3021,6 @@ _IO_vfscanf_internal (FILE *s, const char *format, va_list argptr,
> UNLOCK_STREAM (s);
>
> scratch_buffer_free (&charbuf.scratch);
> - if (errp != NULL)
> - *errp |= errval;
>
> if (__glibc_unlikely (done == EOF))
> {
> @@ -3044,23 +3046,3 @@ _IO_vfscanf_internal (FILE *s, const char *format, va_list argptr,
> }
> return done;
> }
> -
> -#ifdef COMPILE_WSCANF
> -int
> -__vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
> -{
> - return _IO_vfwscanf (s, format, argptr, NULL);
> -}
> -ldbl_weak_alias (__vfwscanf, vfwscanf)
> -#else
> -int
> -___vfscanf (FILE *s, const char *format, va_list argptr)
> -{
> - return _IO_vfscanf_internal (s, format, argptr, NULL);
> -}
> -ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
> -ldbl_hidden_def (_IO_vfscanf_internal, _IO_vfscanf)
> -ldbl_strong_alias (___vfscanf, __vfscanf)
> -ldbl_hidden_def (___vfscanf, __vfscanf)
> -ldbl_weak_alias (___vfscanf, vfscanf)
> -#endif
Ok.
> diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
> index 0000000000..5eedca8340 100644
> --- /dev/null 2018-02-21 11:21:31.435874074 -0500
> +++ b/stdio-common/vfscanf.c 2018-03-07 08:44:37.578545222 -0500
> @@ -0,0 +1,27 @@
> +/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
Missing one line description.
> +
> + 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
> +___vfscanf (FILE *s, const char *format, va_list argptr)
> +{
> + return __vfscanf_internal (s, format, argptr, 0);
> +}
> +ldbl_strong_alias (___vfscanf, __vfscanf)
> +ldbl_hidden_def (___vfscanf, __vfscanf)
> +ldbl_weak_alias (___vfscanf, vfscanf)
Ok.
> diff --git a/stdio-common/vfwscanf.c b/stdio-common/vfwscanf-internal.c
> similarity index 50%
> rename from stdio-common/vfscanf.c
> rename to stdio-common/vfscanf-internal.c
> index 26b1a66608..26c89270b7 100644
> --- a/stdio-common/vfwscanf.c
> +++ b/stdio-common/vfwscanf-internal.c
> @@ -1,2 +1,2 @@
> #define COMPILE_WSCANF 1
> -#include "vfscanf.c"
> +#include "vfscanf-internal.c"
Ok.
> diff --git a/stdio-common/vfwscanf.c b/stdio-common/vfwscanf.c
> new file mode 100644
> index 0000000000..0554b7eae1
> --- a/stdio-common/vfwscanf.c
> +++ b/stdio-common/vfwscanf.c
> @@ -0,0 +1,25 @@
> +/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
Missing one line description.
> +
> + 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)
Ok.
> diff --git a/sysdeps/generic/math_ldbl_opt.h b/sysdeps/generic/math_ldbl_opt.h
> index 8a5d8ba107..92f670dff7 100644
> --- a/sysdeps/generic/math_ldbl_opt.h
> +++ b/sysdeps/generic/math_ldbl_opt.h
> @@ -6,9 +6,13 @@
> for platforms where compatibility symbols are required for a previous
> 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_symbol(lib, local, symbol)
> #define ldbl_hidden_def(local, name) libc_hidden_def (name)
> #define ldbl_strong_alias(name, aliasname) strong_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
Isn't the idea that if long double being a different type than double the compat
symbols are not really required? I think this should be just an empty macro.
> diff --git a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
> index af861c11ea..ee70d085fd 100644
> --- a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
> +++ b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
> @@ -20,10 +20,14 @@
> long_double_symbol (libc, __GL_##name##_##aliasname, aliasname);
> # define long_double_symbol_1(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
> # define ldbl_hidden_def(local, name) libc_hidden_def (name)
> # define ldbl_strong_alias(name, aliasname) strong_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)
> # ifndef __ASSEMBLER__
> /* Note that weak_alias cannot be used - it is defined to nothing
> in most of the C files. */
Ok.
> diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
> index 7d19eaba8d..9ac88deb74 100644
> --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
> +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
> @@ -329,16 +329,20 @@ __nldbl_wprintf (const wchar_t *fmt, ...)
> return done;
> }
>
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_28)
> int
> attribute_compat_text_section
> __nldbl__IO_vfscanf (FILE *s, const char *fmt, va_list ap, int *errp)
> {
> int res;
> set_no_long_double ();
> - res = _IO_vfscanf (s, fmt, ap, errp);
> + res = __vfscanf_internal (s, fmt, ap, 0);
> clear_no_long_double ();
> + if (__glibc_unlikely (errp != 0))
> + *errp = (res == -1);
> return res;
> }
> +#endif
>
> int
> attribute_compat_text_section
> @@ -346,7 +350,7 @@ __nldbl___vfscanf (FILE *s, const char *fmt, va_list ap)
> {
> int res;
> set_no_long_double ();
> - res = _IO_vfscanf (s, fmt, ap, NULL);
> + res = __vfscanf_internal (s, fmt, ap, 0);
> clear_no_long_double ();
> return res;
> }
> @@ -422,7 +426,7 @@ __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
> {
> int res;
> set_no_long_double ();
> - res = _IO_vfwscanf (s, fmt, ap, NULL);
> + res = __vfwscanf_internal (s, fmt, ap, 0);
> clear_no_long_double ();
> return res;
> }
> @@ -1026,7 +1030,9 @@ compat_symbol (libc, __nldbl_vdprintf, vdprintf, 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__IO_sscanf, _IO_sscanf, GLIBC_2_0);
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_28)
> compat_symbol (libc, __nldbl__IO_vfscanf, _IO_vfscanf, GLIBC_2_0);
> +#endif
> compat_symbol (libc, __nldbl___vfscanf, __vfscanf, GLIBC_2_0);
> compat_symbol (libc, __nldbl___vsscanf, __vsscanf, GLIBC_2_0);
> compat_symbol (libc, __nldbl_fscanf, fscanf, GLIBC_2_0);
I am not sure that nesting SHLIB_COMPAT is correct way logically and stylisc here:
the compat symbol will be create only for ABI which initial version of GLIBC_2_0
(which might not be an issue with current ABIs that requires ldbl to dbl compat
symbol).
Should we just add it on the end of the list?
> diff --git a/wcsmbs/isoc99_fwscanf.c b/wcsmbs/isoc99_fwscanf.c
> index 0c6a2c47ac..00b07dd48e 100644
> --- a/wcsmbs/isoc99_fwscanf.c
> +++ b/wcsmbs/isoc99_fwscanf.c
> @@ -32,7 +32,7 @@ __isoc99_fwscanf (FILE *stream, const wchar_t *format, ...)
> stream->_flags2 |= _IO_FLAGS2_SCANF_STD;
>
> va_start (arg, format);
> - done = _IO_vfwscanf (stream, format, arg, NULL);
> + done = __vfwscanf_internal (stream, format, arg, 0);
> va_end (arg);
>
> _IO_release_lock (stream);
Ok.
> diff --git a/wcsmbs/isoc99_swscanf.c b/wcsmbs/isoc99_swscanf.c
> index ff523db706..40401d0aa1 100644
> --- a/wcsmbs/isoc99_swscanf.c
> +++ b/wcsmbs/isoc99_swscanf.c
> @@ -16,20 +16,22 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <stdarg.h>
> -#include <stdio.h>
> -#include <libioP.h>
> -#include <wchar.h>
> +#include <libio/strfile.h>
>
> /* Read formatted input from S, according to the format string FORMAT. */
> -/* VARARGS2 */
> +
> int
> __isoc99_swscanf (const wchar_t *s, const wchar_t *format, ...)
> {
> va_list arg;
> 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);
> - done = __isoc99_vswscanf (s, format, arg);
> + done = __vfwscanf_internal (f, format, arg, 0);
> va_end (arg);
>
> return done;
Ok.
> diff --git a/wcsmbs/isoc99_vfwscanf.c b/wcsmbs/isoc99_vfwscanf.c
> index 7beb45b4d3..f70c6b596d 100644
> --- a/wcsmbs/isoc99_vfwscanf.c
> +++ b/wcsmbs/isoc99_vfwscanf.c
> @@ -28,7 +28,7 @@ __isoc99_vfwscanf (FILE *stream, const wchar_t *format, va_list args)
>
> _IO_acquire_lock_clear_flags2 (stream);
> stream->_flags2 |= _IO_FLAGS2_SCANF_STD;
> - done = _IO_vfwscanf (stream, format, args, NULL);
> + done = __vfwscanf_internal (stream, format, args, 0);
> _IO_release_lock (stream);
> return done;
> }
Ok.
> diff --git a/wcsmbs/isoc99_vswscanf.c b/wcsmbs/isoc99_vswscanf.c
> index 130769154d..b91eb651a3 100644
> --- a/wcsmbs/isoc99_vswscanf.c
> +++ b/wcsmbs/isoc99_vswscanf.c
> @@ -24,24 +24,16 @@
> This exception applies to code released by its copyright holders
> in files containing the exception. */
>
> -#include <libioP.h>
> #include <wchar.h>
> -#include "../libio/strfile.h"
> +#include <libio/strfile.h>
>
> int
> __isoc99_vswscanf (const wchar_t *string, const wchar_t *format, va_list args)
> {
> - int ret;
> _IO_strfile sf;
> struct _IO_wide_data wd;
> -#ifdef _IO_MTSAFE_IO
> - sf._sbf._f._lock = NULL;
> -#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);
> - sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD;
> - ret = _IO_vfwscanf ((FILE *) &sf._sbf, format, args, NULL);
> - return ret;
> + FILE *f = _IO_strfile_readw (&sf, &wd, string);
> + f->_flags2 |= _IO_FLAGS2_SCANF_STD;
> + return __vfwscanf_internal (f, format, args, 0);
> }
> libc_hidden_def (__isoc99_vswscanf)
Ok.
> diff --git a/wcsmbs/isoc99_vwscanf.c b/wcsmbs/isoc99_vwscanf.c
> index 049521b964..eb22c8acae 100644
> --- a/wcsmbs/isoc99_vwscanf.c
> +++ b/wcsmbs/isoc99_vwscanf.c
> @@ -28,7 +28,7 @@ __isoc99_vwscanf (const wchar_t *format, va_list args)
>
> _IO_acquire_lock_clear_flags2 (stdin);
> stdin->_flags2 |= _IO_FLAGS2_SCANF_STD;
> - done = _IO_vfwscanf (stdin, format, args, NULL);
> + done = __vfwscanf_internal (stdin, format, args, 0);
> _IO_release_lock (stdin);
> return done;
> }
Ok.
> diff --git a/wcsmbs/isoc99_wscanf.c b/wcsmbs/isoc99_wscanf.c
> index abfbd50c11..59f80d78fb 100644
> --- a/wcsmbs/isoc99_wscanf.c
> +++ b/wcsmbs/isoc99_wscanf.c
> @@ -33,7 +33,7 @@ __isoc99_wscanf (const wchar_t *format, ...)
> stdin->_flags2 |= _IO_FLAGS2_SCANF_STD;
>
> va_start (arg, format);
> - done = _IO_vfwscanf (stdin, format, arg, NULL);
> + done = __vfwscanf_internal (stdin, format, arg, 0);
> va_end (arg);
>
> _IO_release_lock (stdin);
>
Ok.