diff options
| author | Zack Weinberg <zackw@panix.com> | 2018-03-07 14:31:58 -0500 |
|---|---|---|
| committer | Gabriel F. T. Gomes <gabriel@inconstante.eti.br> | 2018-12-05 18:15:42 -0200 |
| commit | 349718d4d7841df46bcc36df9bc2baef4c40d6f5 (patch) | |
| tree | 1c6ae071a4a6d063e551ae6577b04d952262daea | |
| parent | 72b8692d7e640eb85ea0fb7de6d5e797512691c1 (diff) | |
| download | glibc-349718d4d7841df46bcc36df9bc2baef4c40d6f5.tar.xz glibc-349718d4d7841df46bcc36df9bc2baef4c40d6f5.zip | |
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.
35 files changed, 3351 insertions, 3128 deletions
@@ -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> * include/time.h 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) 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) 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 diff --git a/libio/libioP.h b/libio/libioP.h index df2633d858..525dce19ee 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -704,6 +704,28 @@ extern off64_t _IO_seekpos_unlocked (FILE *, off64_t, int) #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; #ifdef _IO_MTSAFE_IO diff --git a/libio/strfile.h b/libio/strfile.h index 75caac2af5..e51ac34ccd 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); @@ -80,3 +82,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; +} + +/* 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. */ 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; 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) 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) 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; diff --git a/stdio-common/Makefile b/stdio-common/Makefile index a10f12ab3c..f3b3ceddbd 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 diff --git a/stdio-common/Versions b/stdio-common/Versions index b8217578c8..522f302198 100644 --- a/stdio-common/Versions +++ b/stdio-common/Versions @@ -60,6 +60,9 @@ libc { GLIBC_2.28 { renameat2; } + GLIBC_2.29 { + # SHLIB_COMPAT(GLIBC_2_0, GLIBC_2_29) 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..77e698f665 --- /dev/null +++ b/stdio-common/iovfscanf.c @@ -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 diff --git a/stdio-common/iovfwscanf.c b/stdio-common/iovfwscanf.c new file mode 100644 index 0000000000..26a57788cb --- /dev/null +++ b/stdio-common/iovfwscanf.c @@ -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/>. */ + |
