1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00

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

@ -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

View File

@ -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;

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;
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);

View File

@ -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

View File

@ -16,19 +16,20 @@
<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 */
int
__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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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)

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
#include "vfscanf.c"
/* Implementation and symbols for vfwscanf.
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)