This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH v2 5/8] Add __v*printf_internal with flags arguments.
- From: "Gabriel F. T. Gomes" <gabriel at inconstante dot eti dot br>
- To: <libc-alpha at sourceware dot org>
- Date: Mon, 29 Oct 2018 09:16:47 -0300
- Subject: [PATCH v2 5/8] Add __v*printf_internal with flags arguments.
- References: <20181029121650.24544-1-gabriel@inconstante.eti.br>
From: Zack Weinberg <zackw@panix.com>
Changes since v1:
- Fixed white-space errors.
- In argp_fmtstream_printf, do not call __vsnprintf, instead call
__vsnprintf_internal passing 0 to mode_flags. With this change,
there's no need to use libc_hidden_{proto,def} for __vsnprintf
(because it doesn't have other internal callers). Also, it is no
longer necessary to '#undef __vsnprintf' and '#define __vsnprintf
vsnprintf' in argp-namefrob.h.
- In __argp_error and __argp_failure call __vasprintf_internal
directly, passing 0 (zero) to mode_flags, since these functions do
not currently have support for long double with the same format as
double (a subsequent patch in my personal branch provides that and
adjusts the call accordingly).
With this change, there's no need to use libc_hidden_{proto,def} for
__vasprintf. It is also no longer required to '#undef __vasprintf'
and '#define __vasprintf vasprintf' in argp-namefrob.h.
- Declarations of _IO_vfprintf, _IO_vsprintf, __vfwprintf, and
__vswprintf removed from the internal headers: libio.h, iolibio.h,
and include/wchar.h, since they are no longer called from within
glibc.
- Added attribute_hidden to all new internal functions, since they are
all called from within libc.
Here are the objdumps of one such calls, before and after this
change, on a 32-bits powerpc machine:
Without attribute_hidden:
$ objdump -d --reloc INTERNAL-VISIBLE-glibc/libc.so | grep "<vprintf@@GLIBC_2.4>:" -A 21
000523a0 <vprintf@@GLIBC_2.4>:
523a0: 94 21 ff f0 stwu r1,-16(r1)
523a4: 7c 85 23 78 mr r5,r4
523a8: 7c 08 02 a6 mflr r0
523ac: 42 9f 00 05 bcl 20,4*cr7+so,523b0 <vprintf@@GLIBC_2.4+0x10>
523b0: 7c 64 1b 78 mr r4,r3
523b4: 38 c0 00 00 li r6,0
523b8: 93 c1 00 08 stw r30,8(r1)
523bc: 90 01 00 14 stw r0,20(r1)
523c0: 7f c8 02 a6 mflr r30
523c4: 3f de 00 15 addis r30,r30,21
523c8: 3b de dc 44 addi r30,r30,-9148
523cc: 81 3e fe 80 lwz r9,-384(r30)
523d0: 80 69 00 00 lwz r3,0(r9)
523d4: 48 01 52 bd bl 67690 <__vfprintf_internal>
523d8: 80 01 00 14 lwz r0,20(r1)
523dc: 83 c1 00 08 lwz r30,8(r1)
523e0: 38 21 00 10 addi r1,r1,16
523e4: 7c 08 03 a6 mtlr r0
523e8: 4e 80 00 20 blr
With attribute_hidden:
$ objdump -d --reloc INTERNAL-HIDDEN-glibc/libc.so | grep "<vprintf@@GLIBC_2.4>:" -A 18
00052370 <vprintf@@GLIBC_2.4>:
52370: 94 21 ff f0 stwu r1,-16(r1)
52374: 7c 85 23 78 mr r5,r4
52378: 7d 88 02 a6 mflr r12
5237c: 42 9f 00 05 bcl 20,4*cr7+so,52380 <vprintf@@GLIBC_2.4+0x10>
52380: 7c 64 1b 78 mr r4,r3
52384: 38 c0 00 00 li r6,0
52388: 93 c1 00 08 stw r30,8(r1)
5238c: 7f c8 02 a6 mflr r30
52390: 7d 88 03 a6 mtlr r12
52394: 3f de 00 15 addis r30,r30,21
52398: 3b de dc 74 addi r30,r30,-9100
5239c: 81 3e fe 80 lwz r9,-384(r30)
523a0: 83 c1 00 08 lwz r30,8(r1)
523a4: 80 69 00 00 lwz r3,0(r9)
523a8: 38 21 00 10 addi r1,r1,16
523ac: 48 01 52 24 b 675d0 <__vfprintf_internal>
The branch-and-link instruction is gone.
Additional note for review:
- Reviewing the changes from vfprintf.c to vfprintf-internal.c in the
original patch would be vey hard, because git doesn't detect the
filename change. To make review a little easier, I did as Zack did
and manually edited the diff. I'll reply to this thread and attach
the original patch if someone wants to apply it.
(ping me if I forget it)
-- 8< --
There are a lot more printf variants than there are scanf variants,
and the code for setting up and tearing down their custom FILE
variants around the call to __vf(w)printf is more complicated and
variable. Therefore, I have added _internal versions of all the
v*printf variants, rather than introducing helper routines so that
they can all directly call __vf(w)printf_internal, as was done with
scanf.
As with the scanf changes, in this patch the _internal functions still
look at the environmental mode bits and all callers pass 0 for the
flags parameter.
Several of the affected public functions had _IO_ name aliases that
were not exported (but, in one case, appeared in libio.h anyway);
I was originally planning to leave them as aliases to avoid having
to touch internal callers, but it turns out ldbl_*_alias only work
for exported symbols, so they've all been removed instead. It also
turns out there were hardly any internal callers. _IO_vsprintf and
_IO_vfprintf *are* exported, so those two stick around.
Summary for the changes to each of the affected symbols:
_IO_vfprintf, _IO_vsprintf:
All internal calls removed, thus the internal declarations, as well
as uses of libc_hidden_proto and libc_hidden_def, were also removed.
The external symbol is now exposed via uses of ldbl_strong_alias
to __vfprintf_internal and __vsprintf_internal, respectively.
_IO_vasprintf, _IO_vdprintf, _IO_vsnprintf,
_IO_vfwprintf, _IO_vswprintf,
_IO_obstack_vprintf, _IO_obstack_printf:
All internal calls removed, thus declaration in internal headers
were also removed. They were never exported, so there are no
aliases tying them to the internal functions. I.e.: entirely gone.
__vsnprintf:
Internal calls were always preceded by macros such as
#define __vsnprintf _IO_vsnprintf, and
#define __vsnprintf vsnprintf
The macros were removed and their uses replaced with calls to the
new internal function __vsnprintf_internal. Since there were no
internal calls, the internal declaration was also removed. The
external symbol is preserved with ldbl_weak_alias to ___vsnprintf.
__vfwprintf:
All internal calls converted into calls to __vfwprintf_internal,
thus the internal declaration was removed. The function is now a
wrapper that calls __vfwprintf_internal. The external symbol is
preserved.
__vswprintf:
Similarly, but no external symbol.
__vasprintf, __vdprintf, __vfprintf, __vsprintf:
New internal wrappers. Not exported.
vasprintf, vdprintf, vfprintf, vsprintf, vsnprintf,
vfwprintf, vswprintf,
obstack_vprintf, obstack_printf:
These functions used to be aliases to the respective _IO_* function,
they are now aliases to their respective __* functions.
Tested for powerpc and powerpc64le.
2018-10-16 Zack Weinberg <zackw@panix.com>
Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
* libio/libioP.h (__vfprintf_internal, __vfwprintf_internal)
(__vasprintf_internal, __vdprintf_internal, __obstack_vprintf_internal)
(__vsprintf_internal, __vsnprintf_internal, __vswprintf_internal):
New functions.
(PRINTF_LDBL_IS_DBL, PRINTF_FORTIFY): New constants.
(_IO_vasprintf, _IO_vdprintf, _IO_vsnprintf): Remove prototypes.
* stdio-common/vfprintf-internal.c: Rename from vfprintf.c.
Include wctype.h here if COMPILE_WPRINTF is defined.
Define __vfprintf_internal or __vfwprintf_internal, depending
on COMPILE_WPRINTF.
Temporarily, on entry to this function, update mode_flags
according to the environmental settings corresponding to
PRINTF_LDBL_IS_DBL and PRINTF_FORTIFY.
(LDBL_IS_DBL, DO_FORTIFY): New macros. Throughout, use
LDBL_IS_DBL instead of __ldbl_is_dbl, and DO_FORTIFY instead of
checking _IO_FLAGS2_FORTIFY on the destination FILE.
* stdio-common/vfwprintf-internal.c: Rename from vfwprintf.c.
Include vfprintf-internal.c. Don't include wctype.h.
* stdio-common/vfprintf.c: New file. Just define __vfprintf
as a wrapper around __vfprintf_internal, with aliases _IO_vfprintf
and vfprintf.
* stdio-common/vfwprintf.c: New file. Just define __vfwprintf
as a wrapper around __vfwprintf_internal, with aliases _IO_vfwprintf
and vfwprintf.
* stdio-common/Makefile: Add vfprintf-internal and vfwprintf-internal.
* libio/iovdprintf.c (_IO_vdprintf): Rename to __vdprintf_internal
and add mode_flags argument; use __vfprintf_internal.
(__vdprintf): New function. Alias vdprintf to this.
* libio/iovsprintf.c (_IO_vsprintf, __vsprintf): Similarly.
* libio/vasprintf.c (_IO_vasprintf, __vasprintf): Similarly.
* libio/obprintf.c (_IO_obstack_vprintf, __obstack_vprintf): Similarly.
(__obstack_printf): Use __obstack_printf_internal.
* libio/vsnprintf.c (_IO_vsnprintf, ___vsnprintf): Similarly, with
public aliases __vsnprintf and vsnprintf.
Remove use of ldbl_hidden_def, since __vsnprintf is no longer
called internally.
* libio/vswprintf (_IO_vswprintf, __vswprintf): Similarly, with
public aliases _IO_vsprintf and vsprintf.
* libio/swprintf.c (__swprintf): Use __vswprintf_internal.
* stdio-common/asprintf.c (__asprintf): Use __vasprintf_internal.
* stdio-common/dprintf.c (__dprintf): Use __vdprintf_internal.
* stdio-common/snprintf.c (__snprintf): Use __vsprintf_internal.
* stdio-common/sprintf.c (__sprintf): Use __vsprintf_internal.
* debug/obprintf_chk.c, debug/vasprintf_chk.c, debug/vdprintf_chk.c
* debug/vsnprintf_chk.c, debug/vsprintf_chk.c, hurd/vpprintf.c
* stdio-common/fprintf.c, stdio-common/fxprintf.c
* stdio-common/printf.c: Use __vfprintf_internal.
* debug/fwprintf_chk.c, debug/vfwprintf_chk.c, debug/vswprintf_chk.c
* debug/vwprintf_chk.c, debug/wprintf_chk.c, libio/fwprintf.c
* libio/vwprintf.c, libio/wprintf.c: Use __vfwprintf_internal.
* sysdeps/ieee754/ldbl-opt/nldbl-compat.c: Use __vsprintf_internal,
__obstack_vprintf_internal, __vasprintf_internal, __vdprintf_internal,
__vsnprintf_internal, __vswprintf_internal, __vfprintf_internal, and
__vfwprintf_internal.
* libio/libio.h: Remove libc_hidden_proto and declaration for
_IO_vfprintf.
Remove declaration of _IO_vfwprintf.
* libio/iolibio.h: Remove libc_hidden_proto and declaration for
_IO_vsprintf.
Remove declarations of _IO_vswprintf, _IO_obstack_printf, and
_IO_obstack_printf.
* include/stdio.h: Add prototype for __vasprintf.
(__vsnprintf): Remove declaration, because there are no more
internal calls.
* include/wchar.h (__vfwprintf, __vswprintf): Remove
declaration, because there are no more internal calls.
* argp/argp-fmtstream.c (__argp_fmtstream_printf): Use
__vsnprintf_internal, instead of _IO_vsnprintf.
* argp/argp-help.c (__argp_error, __argp_failure): Use
__vasprintf_internal, instead of _IO_vasprintf.
* argp/argp-namefrob.h (__vsnprintf): Do not undefined then
redefine, because there are no more internal calls.
Signed-off-by: Zack Weinberg <zackw@panix.com>
Signed-off-by: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
---
argp/argp-fmtstream.c | 3 +-
argp/argp-help.c | 4 +-
argp/argp-namefrob.h | 2 -
debug/fwprintf_chk.c | 2 +-
debug/obprintf_chk.c | 2 +-
debug/vasprintf_chk.c | 2 +-
debug/vdprintf_chk.c | 2 +-
debug/vfwprintf_chk.c | 2 +-
debug/vsnprintf_chk.c | 2 +-
debug/vsprintf_chk.c | 2 +-
debug/vswprintf_chk.c | 2 +-
debug/vwprintf_chk.c | 2 +-
debug/wprintf_chk.c | 2 +-
hurd/vpprintf.c | 2 +-
include/stdio.h | 3 -
include/wchar.h | 10 -
libio/fwprintf.c | 2 +-
libio/iolibio.h | 8 -
libio/iovdprintf.c | 13 +-
libio/iovsprintf.c | 16 +-
libio/libio.h | 5 -
libio/libioP.h | 40 +-
libio/obprintf.c | 19 +-
libio/swprintf.c | 2 +-
libio/vasprintf.c | 20 +-
libio/vsnprintf.c | 16 +-
libio/vswprintf.c | 16 +-
libio/vwprintf.c | 2 +-
libio/wprintf.c | 2 +-
stdio-common/Makefile | 3 +-
stdio-common/asprintf.c | 6 +-
stdio-common/dprintf.c | 5 +-
stdio-common/fprintf.c | 2 +-
stdio-common/fxprintf.c | 4 +-
stdio-common/printf.c | 3 +-
stdio-common/snprintf.c | 4 +-
stdio-common/sprintf.c | 4 +-
stdio-common/vfprintf-internal.c | 2366 +++++++++++++++++++++++++++++++
stdio-common/vfprintf.c | 2351 +-----------------------------
stdio-common/vfwprintf-internal.c | 2 +
stdio-common/vfwprintf.c | 28 +-
stdio-common/vprintf.c | 4 +-
stdlib/strfrom-skeleton.c | 2 +-
sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 21 +-
44 files changed, 2544 insertions(+), 2466 deletions(-)
create mode 100644 stdio-common/vfprintf-internal.c
create mode 100644 stdio-common/vfwprintf-internal.c
diff --git a/argp/argp-fmtstream.c b/argp/argp-fmtstream.c
index e43a0c7cf1..b9dcb2c9c7 100644
--- a/argp/argp-fmtstream.c
+++ b/argp/argp-fmtstream.c
@@ -42,7 +42,6 @@
#ifdef _LIBC
# include <wchar.h>
# include <libio/libioP.h>
-# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
#endif
#define INIT_BUF_SIZE 200
@@ -409,7 +408,7 @@ __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
va_start (args, fmt);
avail = fs->end - fs->p;
- out = __vsnprintf (fs->p, avail, fmt, args);
+ out = __vsnprintf_internal (fs->p, avail, fmt, args, 0);
va_end (args);
if ((size_t) out >= avail)
size_guess = out + 1;
diff --git a/argp/argp-help.c b/argp/argp-help.c
index 2b6b0775d6..6857391ce2 100644
--- a/argp/argp-help.c
+++ b/argp/argp-help.c
@@ -1769,7 +1769,7 @@ __argp_error (const struct argp_state *state, const char *fmt, ...)
#ifdef _LIBC
char *buf;
- if (_IO_vasprintf (&buf, fmt, ap) < 0)
+ if (__vasprintf_internal (&buf, fmt, ap, 0) < 0)
buf = NULL;
__fxprintf (stream, "%s: %s\n",
@@ -1839,7 +1839,7 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
#ifdef _LIBC
char *buf;
- if (_IO_vasprintf (&buf, fmt, ap) < 0)
+ if (__vasprintf_internal (&buf, fmt, ap, 0) < 0)
buf = NULL;
__fxprintf (stream, ": %s", buf);
diff --git a/argp/argp-namefrob.h b/argp/argp-namefrob.h
index 5588fe172a..5e48b5940d 100644
--- a/argp/argp-namefrob.h
+++ b/argp/argp-namefrob.h
@@ -98,8 +98,6 @@
#define __strerror_r strerror_r
#undef __strndup
#define __strndup strndup
-#undef __vsnprintf
-#define __vsnprintf vsnprintf
#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
# define clearerr_unlocked(x) clearerr (x)
diff --git a/debug/fwprintf_chk.c b/debug/fwprintf_chk.c
index aeb83077da..63167c1839 100644
--- a/debug/fwprintf_chk.c
+++ b/debug/fwprintf_chk.c
@@ -32,7 +32,7 @@ __fwprintf_chk (FILE *fp, int flag, const wchar_t *format, ...)
fp->_flags2 |= _IO_FLAGS2_FORTIFY;
va_start (ap, format);
- done = _IO_vfwprintf (fp, format, ap);
+ done = __vfwprintf_internal (fp, format, ap, 0);
va_end (ap);
if (flag > 0)
diff --git a/debug/obprintf_chk.c b/debug/obprintf_chk.c
index 3ac5a3cd4f..41dd481c34 100644
--- a/debug/obprintf_chk.c
+++ b/debug/obprintf_chk.c
@@ -91,7 +91,7 @@ __obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format,
if (flags > 0)
new_f.ofile.file.file._flags2 |= _IO_FLAGS2_FORTIFY;
- result = _IO_vfprintf (&new_f.ofile.file.file, format, args);
+ result = __vfprintf_internal (&new_f.ofile.file.file, format, args, 0);
/* Shrink the buffer to the space we really currently need. */
obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr
diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c
index 48b4741651..dbfebff83f 100644
--- a/debug/vasprintf_chk.c
+++ b/debug/vasprintf_chk.c
@@ -63,7 +63,7 @@ __vasprintf_chk (char **result_ptr, int flags, const char *format,
if (flags > 0)
sf._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY;
- ret = _IO_vfprintf (&sf._sbf._f, format, args);
+ ret = __vfprintf_internal (&sf._sbf._f, format, args, 0);
if (ret < 0)
{
free (sf._sbf._f._IO_buf_base);
diff --git a/debug/vdprintf_chk.c b/debug/vdprintf_chk.c
index bc713b4962..4386127cfe 100644
--- a/debug/vdprintf_chk.c
+++ b/debug/vdprintf_chk.c
@@ -55,7 +55,7 @@ __vdprintf_chk (int d, int flags, const char *format, va_list arg)
if (flags > 0)
tmpfil.file._flags2 |= _IO_FLAGS2_FORTIFY;
- done = _IO_vfprintf (&tmpfil.file, format, arg);
+ done = __vfprintf_internal (&tmpfil.file, format, arg, 0);
_IO_FINISH (&tmpfil.file);
diff --git a/debug/vfwprintf_chk.c b/debug/vfwprintf_chk.c
index 1ffd18cbd2..abf2bd6517 100644
--- a/debug/vfwprintf_chk.c
+++ b/debug/vfwprintf_chk.c
@@ -30,7 +30,7 @@ __vfwprintf_chk (FILE *fp, int flag, const wchar_t *format, va_list ap)
if (flag > 0)
fp->_flags2 |= _IO_FLAGS2_FORTIFY;
- done = _IO_vfwprintf (fp, format, ap);
+ done = __vfwprintf_internal (fp, format, ap, 0);
if (flag > 0)
fp->_flags2 &= ~_IO_FLAGS2_FORTIFY;
diff --git a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c
index d20d0fbd93..95d286f416 100644
--- a/debug/vsnprintf_chk.c
+++ b/debug/vsnprintf_chk.c
@@ -60,7 +60,7 @@ ___vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY;
_IO_str_init_static_internal (&sf.f, s, maxlen - 1, s);
- ret = _IO_vfprintf (&sf.f._sbf._f, format, args);
+ ret = __vfprintf_internal (&sf.f._sbf._f, format, args, 0);
if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
*sf.f._sbf._f._IO_write_ptr = '\0';
diff --git a/debug/vsprintf_chk.c b/debug/vsprintf_chk.c
index 9a443bb699..53f07236ae 100644
--- a/debug/vsprintf_chk.c
+++ b/debug/vsprintf_chk.c
@@ -80,7 +80,7 @@ ___vsprintf_chk (char *s, int flags, size_t slen, const char *format,
if (flags > 0)
f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY;
- ret = _IO_vfprintf (&f._sbf._f, format, args);
+ ret = __vfprintf_internal (&f._sbf._f, format, args, 0);
*f._sbf._f._IO_write_ptr = '\0';
return ret;
diff --git a/debug/vswprintf_chk.c b/debug/vswprintf_chk.c
index c6a7edcacd..4d616f8835 100644
--- a/debug/vswprintf_chk.c
+++ b/debug/vswprintf_chk.c
@@ -59,7 +59,7 @@ __vswprintf_chk (wchar_t *s, size_t maxlen, int flags, size_t slen,
sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY;
_IO_wstr_init_static (&sf.f._sbf._f, s, maxlen - 1, s);
- ret = _IO_vfwprintf ((FILE *) &sf.f._sbf, format, args);
+ ret = __vfwprintf_internal ((FILE *) &sf.f._sbf, format, args, 0);
if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf)
/* ISO C99 requires swprintf/vswprintf to return an error if the
diff --git a/debug/vwprintf_chk.c b/debug/vwprintf_chk.c
index 51b67c159d..fedc7a46bf 100644
--- a/debug/vwprintf_chk.c
+++ b/debug/vwprintf_chk.c
@@ -31,7 +31,7 @@ __vwprintf_chk (int flag, const wchar_t *format, va_list ap)
if (flag > 0)
stdout->_flags2 |= _IO_FLAGS2_FORTIFY;
- done = _IO_vfwprintf (stdout, format, ap);
+ done = __vfwprintf_internal (stdout, format, ap, 0);
if (flag > 0)
stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY;
diff --git a/debug/wprintf_chk.c b/debug/wprintf_chk.c
index 17023b6bb4..819050e5af 100644
--- a/debug/wprintf_chk.c
+++ b/debug/wprintf_chk.c
@@ -33,7 +33,7 @@ __wprintf_chk (int flag, const wchar_t *format, ...)
stdout->_flags2 |= _IO_FLAGS2_FORTIFY;
va_start (ap, format);
- done = _IO_vfwprintf (stdout, format, ap);
+ done = __vfwprintf_internal (stdout, format, ap, 0);
va_end (ap);
if (flag > 0)
diff --git a/hurd/vpprintf.c b/hurd/vpprintf.c
index 76cd31f922..b9634afc2b 100644
--- a/hurd/vpprintf.c
+++ b/hurd/vpprintf.c
@@ -53,7 +53,7 @@ vpprintf (io_t port, const char *format, va_list arg)
_IO_cookie_init (&temp_f.cfile, _IO_NO_READS,
(void *) port, (cookie_io_functions_t) { write: do_write });
- done = _IO_vfprintf (&temp_f.cfile.__fp.file, format, arg);
+ done = __vfprintf_internal (&temp_f.cfile.__fp.file, format, arg, 0);
return done;
}
diff --git a/include/stdio.h b/include/stdio.h
index 51ada4a4c4..0856d729d9 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -14,9 +14,6 @@ extern int __snprintf (char *__restrict __s, size_t __maxlen,
const char *__restrict __format, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
libc_hidden_proto (__snprintf)
-extern int __vsnprintf (char *__restrict __s, size_t __maxlen,
- const char *__restrict __format, __gnuc_va_list __arg)
- __attribute__ ((__format__ (__printf__, 3, 0)));
extern int __vfscanf (FILE *__restrict __s,
const char *__restrict __format,
__gnuc_va_list __arg)
diff --git a/include/wchar.h b/include/wchar.h
index 1db0ac8278..d0fe45c3a6 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -203,20 +203,10 @@ extern int __vfwscanf (__FILE *__restrict __s,
__gnuc_va_list __arg)
attribute_hidden
/* __attribute__ ((__format__ (__wscanf__, 2, 0)) */;
-extern int __vswprintf (wchar_t *__restrict __s, size_t __n,
- const wchar_t *__restrict __format,
- __gnuc_va_list __arg)
- attribute_hidden
- /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
extern int __fwprintf (__FILE *__restrict __s,
const wchar_t *__restrict __format, ...)
attribute_hidden
/* __attribute__ ((__format__ (__wprintf__, 2, 3))) */;
-extern int __vfwprintf (__FILE *__restrict __s,
- const wchar_t *__restrict __format,
- __gnuc_va_list __arg)
- attribute_hidden
- /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */;
extern int __vfwprintf_chk (FILE *__restrict __s, int __flag,
const wchar_t *__restrict __format,
__gnuc_va_list __arg)
diff --git a/libio/fwprintf.c b/libio/fwprintf.c
index fab63a8716..9903f1f342 100644
--- a/libio/fwprintf.c
+++ b/libio/fwprintf.c
@@ -30,7 +30,7 @@ __fwprintf (FILE *stream, const wchar_t *format, ...)
int done;
va_start (arg, format);
- done = __vfwprintf (stream, format, arg);
+ done = __vfwprintf_internal (stream, format, arg, 0);
va_end (arg);
return done;
diff --git a/libio/iolibio.h b/libio/iolibio.h
index 6c94fe6d62..2642d71e4f 100644
--- a/libio/iolibio.h
+++ b/libio/iolibio.h
@@ -51,15 +51,7 @@ extern int _IO_sscanf (const char*, const char*, ...) __THROW;
extern int _IO_sprintf (char *, const char*, ...) __THROW;
extern int _IO_ungetc (int, FILE*) __THROW;
extern int _IO_vsscanf (const char *, const char *, __gnuc_va_list) __THROW;
-extern int _IO_vsprintf (char*, const char*, __gnuc_va_list) __THROW;
-libc_hidden_proto (_IO_vsprintf)
-extern int _IO_vswprintf (wchar_t*, size_t, const wchar_t*, __gnuc_va_list)
- __THROW;
-struct obstack;
-extern int _IO_obstack_vprintf (struct obstack *, const char *, __gnuc_va_list)
- __THROW;
-extern int _IO_obstack_printf (struct obstack *, const char *, ...) __THROW;
#define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN))
#define _IO_fseek(__fp, __offset, __whence) \
(_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) \
diff --git a/libio/iovdprintf.c b/libio/iovdprintf.c
index 78a3a2bd15..1d2ed0f9e7 100644
--- a/libio/iovdprintf.c
+++ b/libio/iovdprintf.c
@@ -28,7 +28,8 @@
#include <stdio_ext.h>
int
-_IO_vdprintf (int d, const char *format, va_list arg)
+__vdprintf_internal (int d, const char *format, va_list arg,
+ unsigned int mode_flags)
{
struct _IO_FILE_plus tmpfil;
struct _IO_wide_data wd;
@@ -50,7 +51,7 @@ _IO_vdprintf (int d, const char *format, va_list arg)
_IO_mask_flags (&tmpfil.file, _IO_NO_READS,
_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
- done = _IO_vfprintf (&tmpfil.file, format, arg);
+ done = __vfprintf_internal (&tmpfil.file, format, arg, mode_flags);
if (done != EOF && _IO_do_flush (&tmpfil.file) == EOF)
done = EOF;
@@ -59,4 +60,10 @@ _IO_vdprintf (int d, const char *format, va_list arg)
return done;
}
-ldbl_weak_alias (_IO_vdprintf, vdprintf)
+
+int
+__vdprintf (int d, const char *format, va_list arg)
+{
+ return __vdprintf_internal (d, format, arg, 0);
+}
+ldbl_weak_alias (__vdprintf, vdprintf)
diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c
index 4def251701..3b1e8292b5 100644
--- a/libio/iovsprintf.c
+++ b/libio/iovsprintf.c
@@ -28,7 +28,8 @@
#include "strfile.h"
int
-__IO_vsprintf (char *string, const char *format, va_list args)
+__vsprintf_internal (char *string, const char *format, va_list args,
+ unsigned int mode_flags)
{
_IO_strfile sf;
int ret;
@@ -39,11 +40,16 @@ __IO_vsprintf (char *string, const char *format, va_list args)
_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, string, -1, string);
- ret = _IO_vfprintf (&sf._sbf._f, format, args);
+ ret = __vfprintf_internal (&sf._sbf._f, format, args, mode_flags);
_IO_putc_unlocked ('\0', &sf._sbf._f);
return ret;
}
-ldbl_hidden_def (__IO_vsprintf, _IO_vsprintf)
-ldbl_strong_alias (__IO_vsprintf, _IO_vsprintf)
-ldbl_weak_alias (__IO_vsprintf, vsprintf)
+int
+__vsprintf (char *string, const char *format, va_list args)
+{
+ return __vsprintf_internal (string, format, args, 0);
+}
+
+ldbl_strong_alias (__vsprintf, _IO_vsprintf)
+ldbl_weak_alias (__vsprintf, vsprintf)
diff --git a/libio/libio.h b/libio/libio.h
index 30cb7d784f..c188814ccc 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -255,8 +255,6 @@ extern int _IO_ftrylockfile (FILE *) __THROW;
extern int _IO_vfscanf (FILE * __restrict, const char * __restrict,
__gnuc_va_list, int *__restrict);
-extern int _IO_vfprintf (FILE *__restrict, const char *__restrict,
- __gnuc_va_list);
extern __ssize_t _IO_padn (FILE *, int, __ssize_t);
extern size_t _IO_sgetn (FILE *, void *, size_t);
@@ -298,8 +296,6 @@ weak_extern (_IO_stdin_used);
extern int _IO_vfwscanf (FILE * __restrict, const wchar_t * __restrict,
__gnuc_va_list, int *__restrict);
-extern int _IO_vfwprintf (FILE *__restrict, const wchar_t *__restrict,
- __gnuc_va_list);
extern __ssize_t _IO_wpadn (FILE *, wint_t, __ssize_t);
extern void _IO_free_wbackup_area (FILE *) __THROW;
@@ -319,7 +315,6 @@ libc_hidden_proto (_IO_free_wbackup_area)
libc_hidden_proto (_IO_padn)
libc_hidden_proto (_IO_putc)
libc_hidden_proto (_IO_sgetn)
-libc_hidden_proto (_IO_vfprintf)
#ifdef _IO_MTSAFE_IO
# undef _IO_peekc
diff --git a/libio/libioP.h b/libio/libioP.h
index f90fb2c050..c762cf9b67 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -658,12 +658,40 @@ extern off64_t _IO_wstr_seekoff (FILE *, off64_t, int, int)
extern wint_t _IO_wstr_pbackfail (FILE *, wint_t) __THROW;
extern void _IO_wstr_finish (FILE *, int) __THROW;
-extern int _IO_vasprintf (char **result_ptr, const char *format,
- va_list args) __THROW;
-extern int _IO_vdprintf (int d, const char *format, va_list arg);
-extern int _IO_vsnprintf (char *string, size_t maxlen,
- const char *format, va_list args) __THROW;
-
+/* Internal versions of v*printf that take an additional flags
+ parameter. */
+extern int __vfprintf_internal (FILE *fp, const char *format, va_list ap,
+ unsigned int mode_flags)
+ attribute_hidden;
+extern int __vfwprintf_internal (FILE *fp, const wchar_t *format, va_list ap,
+ unsigned int mode_flags)
+ attribute_hidden;
+
+extern int __vasprintf_internal (char **result_ptr, const char *format,
+ va_list ap, unsigned int mode_flags)
+ attribute_hidden;
+extern int __vdprintf_internal (int d, const char *format, va_list ap,
+ unsigned int mode_flags)
+ attribute_hidden;
+extern int __obstack_vprintf_internal (struct obstack *ob, const char *fmt,
+ va_list ap, unsigned int mode_flags)
+ attribute_hidden;
+
+extern int __vsprintf_internal (char *string, const char *format, va_list ap,
+ unsigned int mode_flags)
+ attribute_hidden;
+extern int __vsnprintf_internal (char *string, size_t maxlen,
+ const char *format, va_list ap,
+ unsigned int mode_flags)
+ attribute_hidden;
+extern int __vswprintf_internal (wchar_t *string, size_t maxlen,
+ const wchar_t *format, va_list ap,
+ unsigned int mode_flags)
+ attribute_hidden;
+
+/* Flags for __v*printf_internal. */
+#define PRINTF_LDBL_IS_DBL 0x0001
+#define PRINTF_FORTIFY 0x0002
extern size_t _IO_getline (FILE *,char *, size_t, int, int);
libc_hidden_proto (_IO_getline)
diff --git a/libio/obprintf.c b/libio/obprintf.c
index a74f9467a2..10a4b5c10c 100644
--- a/libio/obprintf.c
+++ b/libio/obprintf.c
@@ -117,7 +117,8 @@ const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden =
int
-_IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args)
+__obstack_vprintf_internal (struct obstack *obstack, const char *format,
+ va_list args, unsigned int mode_flags)
{
struct obstack_FILE
{
@@ -164,7 +165,8 @@ _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args)
new_f.ofile.obstack = obstack;
- result = _IO_vfprintf (&new_f.ofile.file.file, format, args);
+ result = __vfprintf_internal (&new_f.ofile.file.file, format, args,
+ mode_flags);
/* Shrink the buffer to the space we really currently need. */
obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr
@@ -172,17 +174,22 @@ _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args)
return result;
}
-ldbl_weak_alias (_IO_obstack_vprintf, obstack_vprintf)
+int
+__obstack_vprintf (struct obstack *obstack, const char *format, va_list ap)
+{
+ return __obstack_vprintf_internal (obstack, format, ap, 0);
+}
+ldbl_weak_alias (__obstack_vprintf, obstack_vprintf)
int
-_IO_obstack_printf (struct obstack *obstack, const char *format, ...)
+__obstack_printf (struct obstack *obstack, const char *format, ...)
{
int result;
va_list ap;
va_start (ap, format);
- result = _IO_obstack_vprintf (obstack, format, ap);
+ result = __obstack_vprintf_internal (obstack, format, ap, 0);
va_end (ap);
return result;
}
-ldbl_weak_alias (_IO_obstack_printf, obstack_printf)
+ldbl_weak_alias (__obstack_printf, obstack_printf)
diff --git a/libio/swprintf.c b/libio/swprintf.c
index 10f722d035..19b3f33198 100644
--- a/libio/swprintf.c
+++ b/libio/swprintf.c
@@ -28,7 +28,7 @@ __swprintf (wchar_t *s, size_t n, const wchar_t *format, ...)
int done;
va_start (arg, format);
- done = __vswprintf (s, n, format, arg);
+ done = __vswprintf_internal (s, n, format, arg, 0);
va_end (arg);
return done;
diff --git a/libio/vasprintf.c b/libio/vasprintf.c
index 6c35d2b108..fabd84f403 100644
--- a/libio/vasprintf.c
+++ b/libio/vasprintf.c
@@ -24,15 +24,13 @@
This exception applies to code released by its copyright holders
in files containing the exception. */
-#include <malloc.h>
#include <string.h>
-#include "libioP.h"
-#include "stdio.h"
-#include <stdio_ext.h>
-#include "strfile.h"
+#include <stdlib.h>
+#include <strfile.h>
int
-_IO_vasprintf (char **result_ptr, const char *format, va_list args)
+__vasprintf_internal (char **result_ptr, const char *format, va_list args,
+ unsigned int mode_flags)
{
/* Initial size of the buffer to be used. Will be doubled each time an
overflow occurs. */
@@ -56,7 +54,7 @@ _IO_vasprintf (char **result_ptr, const char *format, va_list args)
sf._sbf._f._flags &= ~_IO_USER_BUF;
sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
sf._s._free_buffer_unused = (_IO_free_type) free;
- ret = _IO_vfprintf (&sf._sbf._f, format, args);
+ ret = __vfprintf_internal (&sf._sbf._f, format, args, mode_flags);
if (ret < 0)
{
free (sf._sbf._f._IO_buf_base);
@@ -85,4 +83,10 @@ _IO_vasprintf (char **result_ptr, const char *format, va_list args)
(*result_ptr)[needed - 1] = '\0';
return ret;
}
-ldbl_weak_alias (_IO_vasprintf, vasprintf)
+
+int
+__vasprintf (char **result_ptr, const char *format, va_list args)
+{
+ return __vasprintf_internal (result_ptr, format, args, 0);
+}
+ldbl_weak_alias (__vasprintf, vasprintf)
diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c
index 39b5500528..35b267abf8 100644
--- a/libio/vsnprintf.c
+++ b/libio/vsnprintf.c
@@ -90,8 +90,8 @@ const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden =
int
-_IO_vsnprintf (char *string, size_t maxlen, const char *format,
- va_list args)
+__vsnprintf_internal (char *string, size_t maxlen, const char *format,
+ va_list args, unsigned int mode_flags)
{
_IO_strnfile sf;
int ret;
@@ -111,11 +111,17 @@ _IO_vsnprintf (char *string, size_t maxlen, const char *format,
_IO_JUMPS (&sf.f._sbf) = &_IO_strn_jumps;
string[0] = '\0';
_IO_str_init_static_internal (&sf.f, string, maxlen - 1, string);
- ret = _IO_vfprintf (&sf.f._sbf._f, format, args);
+ ret = __vfprintf_internal (&sf.f._sbf._f, format, args, mode_flags);
if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
*sf.f._sbf._f._IO_write_ptr = '\0';
return ret;
}
-ldbl_weak_alias (_IO_vsnprintf, __vsnprintf)
-ldbl_weak_alias (_IO_vsnprintf, vsnprintf)
+
+int
+___vsnprintf (char *string, size_t maxlen, const char *format, va_list args)
+{
+ return __vsnprintf_internal (string, maxlen, format, args, 0);
+}
+ldbl_weak_alias (___vsnprintf, __vsnprintf)
+ldbl_weak_alias (___vsnprintf, vsnprintf)
diff --git a/libio/vswprintf.c b/libio/vswprintf.c
index bcc473d115..e415e39fc9 100644
--- a/libio/vswprintf.c
+++ b/libio/vswprintf.c
@@ -89,8 +89,8 @@ const struct _IO_jump_t _IO_wstrn_jumps libio_vtable attribute_hidden =
int
-_IO_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format,
- va_list args)
+__vswprintf_internal (wchar_t *string, size_t maxlen, const wchar_t *format,
+ va_list args, unsigned int mode_flags)
{
_IO_wstrnfile sf;
int ret;
@@ -108,7 +108,7 @@ _IO_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format,
_IO_fwide (&sf.f._sbf._f, 1);
string[0] = L'\0';
_IO_wstr_init_static (&sf.f._sbf._f, string, maxlen - 1, string);
- ret = _IO_vfwprintf ((FILE *) &sf.f._sbf, format, args);
+ ret = __vfwprintf_internal ((FILE *) &sf.f._sbf, format, args, mode_flags);
if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf)
/* ISO C99 requires swprintf/vswprintf to return an error if the
@@ -120,5 +120,11 @@ _IO_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format,
return ret;
}
-weak_alias (_IO_vswprintf, __vswprintf)
-ldbl_weak_alias (_IO_vswprintf, vswprintf)
+
+int
+__vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format,
+ va_list args)
+{
+ return __vswprintf_internal (string, maxlen, format, args, 0);
+}
+ldbl_weak_alias (__vswprintf, vswprintf)
diff --git a/libio/vwprintf.c b/libio/vwprintf.c
index 72ebfec92d..e8a529afff 100644
--- a/libio/vwprintf.c
+++ b/libio/vwprintf.c
@@ -25,6 +25,6 @@
int
__vwprintf (const wchar_t *format, __gnuc_va_list arg)
{
- return __vfwprintf (stdout, format, arg);
+ return __vfwprintf_internal (stdout, format, arg, 0);
}
ldbl_strong_alias (__vwprintf, vwprintf)
diff --git a/libio/wprintf.c b/libio/wprintf.c
index 5945f651fc..361cd40a1b 100644
--- a/libio/wprintf.c
+++ b/libio/wprintf.c
@@ -29,7 +29,7 @@ __wprintf (const wchar_t *format, ...)
int done;
va_start (arg, format);
- done = __vfwprintf (stdout, format, arg);
+ done = __vfwprintf_internal (stdout, format, arg, 0);
va_end (arg);
return done;
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index f3b3ceddbd..84bad1fafe 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -40,7 +40,8 @@ routines := \
isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \
isoc99_vsscanf \
psiginfo gentempfd \
- vfscanf-internal vfwscanf-internal iovfscanf iovfwscanf
+ vfscanf-internal vfwscanf-internal iovfscanf iovfwscanf \
+ vfprintf-internal vfwprintf-internal
aux := errlist siglist printf-parsemb printf-parsewc fxprintf
diff --git a/stdio-common/asprintf.c b/stdio-common/asprintf.c
index bff858e657..8943ffcae1 100644
--- a/stdio-common/asprintf.c
+++ b/stdio-common/asprintf.c
@@ -16,11 +16,7 @@
<http://www.gnu.org/licenses/>. */
#include <stdarg.h>
-#include <stdio.h>
-
#include <libioP.h>
-#define vasprintf(s, f, a) _IO_vasprintf (s, f, a)
-#undef __asprintf
/* Write formatted output from FORMAT to a string which is
allocated with malloc and stored in *STRING_PTR. */
@@ -32,7 +28,7 @@ ___asprintf (char **string_ptr, const char *format, ...)
int done;
va_start (arg, format);
- done = vasprintf (string_ptr, format, arg);
+ done = __vasprintf_internal (string_ptr, format, arg, 0);
va_end (arg);
return done;
diff --git a/stdio-common/dprintf.c b/stdio-common/dprintf.c
index 11bd12b838..9adc8ae4c7 100644
--- a/stdio-common/dprintf.c
+++ b/stdio-common/dprintf.c
@@ -16,10 +16,7 @@
<http://www.gnu.org/licenses/>. */
#include <stdarg.h>
-#include <stdio.h>
-
#include <libioP.h>
-#define vdprintf(d, f, a) _IO_vdprintf (d, f, a)
/* Write formatted output to D, according to the format string FORMAT. */
/* VARARGS2 */
@@ -30,7 +27,7 @@ __dprintf (int d, const char *format, ...)
int done;
va_start (arg, format);
- done = vdprintf (d, format, arg);
+ done = __vdprintf_internal (d, format, arg, 0);
va_end (arg);
return done;
diff --git a/stdio-common/fprintf.c b/stdio-common/fprintf.c
index 2bbf14bf5d..c8f8ac4faf 100644
--- a/stdio-common/fprintf.c
+++ b/stdio-common/fprintf.c
@@ -29,7 +29,7 @@ __fprintf (FILE *stream, const char *format, ...)
int done;
va_start (arg, format);
- done = vfprintf (stream, format, arg);
+ done = __vfprintf_internal (stream, format, arg, 0);
va_end (arg);
return done;
diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c
index 8d02b71f91..a028e8edd5 100644
--- a/stdio-common/fxprintf.c
+++ b/stdio-common/fxprintf.c
@@ -27,7 +27,7 @@ static int
locked_vfxprintf (FILE *fp, const char *fmt, va_list ap)
{
if (_IO_fwide (fp, 0) <= 0)
- return _IO_vfprintf (fp, fmt, ap);
+ return __vfprintf_internal (fp, fmt, ap, 0);
/* We must convert the narrow format string to a wide one.
Each byte can produce at most one wide character. */
@@ -53,7 +53,7 @@ locked_vfxprintf (FILE *fp, const char *fmt, va_list ap)
res = __mbsrtowcs (wfmt, &fmt, len, &mbstate);
if (res != -1)
- res = _IO_vfwprintf (fp, wfmt, ap);
+ res = __vfwprintf_internal (fp, wfmt, ap, 0);
if (used_malloc)
free (wfmt);
diff --git a/stdio-common/printf.c b/stdio-common/printf.c
index 205b5e42df..ea41dd557c 100644
--- a/stdio-common/printf.c
+++ b/stdio-common/printf.c
@@ -30,7 +30,7 @@ __printf (const char *format, ...)
int done;
va_start (arg, format);
- done = vfprintf (stdout, format, arg);
+ done = __vfprintf_internal (stdout, format, arg, 0);
va_end (arg);
return done;
@@ -38,5 +38,4 @@ __printf (const char *format, ...)
#undef _IO_printf
ldbl_strong_alias (__printf, printf);
-/* This is for libg++. */
ldbl_strong_alias (__printf, _IO_printf);
diff --git a/stdio-common/snprintf.c b/stdio-common/snprintf.c
index 29a169b08b..b75e160ea3 100644
--- a/stdio-common/snprintf.c
+++ b/stdio-common/snprintf.c
@@ -16,9 +16,7 @@
<http://www.gnu.org/licenses/>. */
#include <stdarg.h>
-#include <stdio.h>
#include <libioP.h>
-#define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
/* Write formatted output into S, according to the format
string FORMAT, writing no more than MAXLEN characters. */
@@ -30,7 +28,7 @@ __snprintf (char *s, size_t maxlen, const char *format, ...)
int done;
va_start (arg, format);
- done = __vsnprintf (s, maxlen, format, arg);
+ done = __vsnprintf_internal (s, maxlen, format, arg, 0);
va_end (arg);
return done;
diff --git a/stdio-common/sprintf.c b/stdio-common/sprintf.c
index bf5671dde9..77423b292f 100644
--- a/stdio-common/sprintf.c
+++ b/stdio-common/sprintf.c
@@ -16,9 +16,7 @@
<http://www.gnu.org/licenses/>. */
#include <stdarg.h>
-#include <stdio.h>
#include <libioP.h>
-#define vsprintf(s, f, a) _IO_vsprintf (s, f, a)
/* Write formatted output into S, according to the format string FORMAT. */
/* VARARGS2 */
@@ -29,7 +27,7 @@ __sprintf (char *s, const char *format, ...)
int done;
va_start (arg, format);
- done = vsprintf (s, format, arg);
+ done = __vsprintf_internal (s, format, arg, 0);
va_end (arg);
return done;
diff -u stdio-common/vfprintf.c.old stdio-common/vfprintf-internal.c.new
--- stdio-common/vfprintf.c.old 2018-10-26 11:09:08.538713613 -0300
+++ stdio-common/vfprintf-internal.c.new 2018-10-26 11:08:45.130667960 -0300
@@ -41,6 +41,10 @@
#include <libioP.h>
+#ifdef COMPILE_WPRINTF
+#include <wctype.h>
+#endif
+
/* In some cases we need extra space for all the output which is not
counted in the width of the string. We assume 32 characters is
enough. */
@@ -63,6 +67,8 @@
} \
} while (0)
#define UNBUFFERED_P(S) ((S)->_flags & _IO_UNBUFFERED)
+#define LDBL_IS_DBL (__glibc_unlikely ((mode_flags & PRINTF_LDBL_IS_DBL) != 0))
+#define DO_FORTIFY ((mode_flags & PRINTF_FORTIFY) != 0)
#define done_add(val) \
do { \
@@ -78,7 +84,7 @@
} while (0)
#ifndef COMPILE_WPRINTF
-# define vfprintf _IO_vfprintf_internal
+# define vfprintf __vfprintf_internal
# define CHAR_T char
# define UCHAR_T unsigned char
# define INT_T int
@@ -105,7 +111,7 @@
# define ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\
return -1
#else
-# define vfprintf _IO_vfwprintf
+# define vfprintf __vfwprintf_internal
# define CHAR_T wchar_t
/* This is a hack!!! There should be a type uwchar_t. */
# define UCHAR_T unsigned int /* uwchar_t */
@@ -747,7 +753,7 @@
\
if (fspec == NULL) \
{ \
- if (__ldbl_is_dbl) \
+ if (LDBL_IS_DBL) \
is_long_double = 0; \
\
struct printf_info info = { .prec = prec, \
@@ -778,7 +784,7 @@
else \
{ \
ptr = (const void *) &args_value[fspec->data_arg]; \
- if (__ldbl_is_dbl) \
+ if (LDBL_IS_DBL) \
{ \
fspec->data_arg_type = PA_DOUBLE; \
fspec->info.is_long_double = 0; \
@@ -808,7 +814,7 @@
\
if (fspec == NULL) \
{ \
- if (__ldbl_is_dbl) \
+ if (LDBL_IS_DBL) \
is_long_double = 0; \
\
struct printf_info info = { .prec = prec, \
@@ -838,7 +844,7 @@
else \
{ \
ptr = (const void *) &args_value[fspec->data_arg]; \
- if (__ldbl_is_dbl) \
+ if (LDBL_IS_DBL) \
fspec->info.is_long_double = 0; \
/* Not supported by *printf functions. */ \
fspec->info.is_binary128 = 0; \
@@ -891,7 +897,7 @@
/* NOTREACHED */ \
\
LABEL (form_number): \
- if (s->_flags2 & _IO_FLAGS2_FORTIFY) \
+ if (DO_FORTIFY) \
{ \
if (! readonly_format) \
{ \
@@ -1214,7 +1220,8 @@
#endif
/* Helper function to provide temporary buffering for unbuffered streams. */
-static int buffered_vfprintf (FILE *stream, const CHAR_T *fmt, va_list)
+static int buffered_vfprintf (FILE *stream, const CHAR_T *fmt, va_list,
+ unsigned int)
__THROW __attribute__ ((noinline));
/* Handle positional format specifiers. */
@@ -1223,7 +1230,9 @@
va_list ap, va_list *ap_savep, int done,
int nspecs_done, const UCHAR_T *lead_str_end,
CHAR_T *work_buffer, int save_errno,
- const char *grouping, THOUSANDS_SEP_T);
+ const char *grouping,
+ THOUSANDS_SEP_T thousands_sep,
+ unsigned int mode_flags);
/* Handle unknown format specifier. */
static int printf_unknown (FILE *, const struct printf_info *,
@@ -1235,7 +1244,7 @@
/* The function itself. */
int
-vfprintf (FILE *s, const CHAR_T *format, va_list ap)
+vfprintf (FILE *s, const CHAR_T *format, va_list ap, unsigned int mode_flags)
{
/* The character used as thousands separator. */
THOUSANDS_SEP_T thousands_sep = 0;
@@ -1273,6 +1282,12 @@
0 if unknown. */
int readonly_format = 0;
+ /* Temporarily honor environmental settings. */
+ if (__ldbl_is_dbl)
+ mode_flags |= PRINTF_LDBL_IS_DBL;
+ if (s->_flags2 & _IO_FLAGS2_FORTIFY)
+ mode_flags |= PRINTF_FORTIFY;
+
/* Orient the stream. */
#ifdef ORIENT
ORIENT;
@@ -1293,7 +1308,7 @@
if (UNBUFFERED_P (s))
/* Use a helper function which will allocate a local temporary buffer
for the stream and then call us again. */
- return buffered_vfprintf (s, format, ap);
+ return buffered_vfprintf (s, format, ap, mode_flags);
/* Initialize local variables. */
done = 0;
@@ -1682,7 +1697,7 @@
}
done = printf_positional (s, format, readonly_format, ap, &ap_save,
done, nspecs_done, lead_str_end, work_buffer,
- save_errno, grouping, thousands_sep);
+ save_errno, grouping, thousands_sep, mode_flags);
all_done:
if (__glibc_unlikely (workstart != NULL))
@@ -1699,7 +1714,8 @@
va_list ap, va_list *ap_savep, int done, int nspecs_done,
const UCHAR_T *lead_str_end,
CHAR_T *work_buffer, int save_errno,
- const char *grouping, THOUSANDS_SEP_T thousands_sep)
+ const char *grouping, THOUSANDS_SEP_T thousands_sep,
+ unsigned int mode_flags)
{
/* For positional argument handling. */
struct scratch_buffer specsbuf;
@@ -1789,7 +1805,7 @@
now. */
args_size = &args_value[nargs].pa_int;
args_type = &args_size[nargs];
- memset (args_type, s->_flags2 & _IO_FLAGS2_FORTIFY ? '\xff' : '\0',
+ memset (args_type, DO_FORTIFY ? '\xff' : '\0',
nargs * sizeof (*args_type));
}
@@ -1856,7 +1872,7 @@
case PA_FLOAT: /* Promoted. */
T (PA_DOUBLE, pa_double, double);
case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:
- if (__ldbl_is_dbl)
+ if (LDBL_IS_DBL)
{
args_value[cnt].pa_double = va_arg (*ap_savep, double);
args_type[cnt] &= ~PA_FLAG_LONG_DOUBLE;
@@ -1884,7 +1900,7 @@
case -1:
/* Error case. Not all parameters appear in N$ format
strings. We have no way to determine their type. */
- assert (s->_flags2 & _IO_FLAGS2_FORTIFY);
+ assert (DO_FORTIFY);
__libc_fatal ("*** invalid %N$ use detected ***\n");
}
@@ -2285,7 +2301,8 @@
#endif
static int
-buffered_vfprintf (FILE *s, const CHAR_T *format, va_list args)
+buffered_vfprintf (FILE *s, const CHAR_T *format, va_list args,
+ unsigned int mode_flags)
{
CHAR_T buf[BUFSIZ];
struct helper_file helper;
@@ -2318,11 +2335,7 @@
_IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_helper_jumps;
/* Now print to helper instead. */
-#ifndef COMPILE_WPRINTF
- result = _IO_vfprintf (hp, format, args);
-#else
- result = vfprintf (hp, format, args);
-#endif
+ result = vfprintf (hp, format, args, mode_flags);
/* Lock stream. */
__libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, s);
@@ -2351,14 +2364,3 @@
return result;
}
-
-#undef vfprintf
-#ifdef COMPILE_WPRINTF
-strong_alias (_IO_vfwprintf, __vfwprintf);
-ldbl_weak_alias (_IO_vfwprintf, vfwprintf);
-#else
-ldbl_strong_alias (_IO_vfprintf_internal, vfprintf);
-ldbl_hidden_def (_IO_vfprintf_internal, vfprintf)
-ldbl_strong_alias (_IO_vfprintf_internal, _IO_vfprintf);
-ldbl_hidden_def (_IO_vfprintf_internal, _IO_vfprintf)
-#endif
diff -u /dev/null stdio-common/vfprintf.c.new
--- /dev/null 2018-10-15 19:30:16.914999855 -0300
+++ stdio-common/vfprintf.c.new 2018-10-26 11:08:58.758694540 -0300
@@ -0,0 +1,27 @@
+/* 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 <libio/libioP.h>
+
+extern int
+__vfprintf (FILE *fp, const char *format, va_list ap)
+{
+ return __vfprintf_internal (fp, format, ap, 0);
+}
+ldbl_strong_alias (__vfprintf, _IO_vfprintf);
+ldbl_strong_alias (__vfprintf, vfprintf);
+ldbl_hidden_def (__vfprintf, vfprintf)
diff --git a/stdio-common/vfwprintf-internal.c b/stdio-common/vfwprintf-internal.c
new file mode 100644
index 0000000000..cefaf2fafe
--- /dev/null
+++ b/stdio-common/vfwprintf-internal.c
@@ -0,0 +1,2 @@
+#define COMPILE_WPRINTF 1
+#include "vfprintf-internal.c"
diff --git a/stdio-common/vfwprintf.c b/stdio-common/vfwprintf.c
index 2c3cd06fad..5d65eb7697 100644
--- a/stdio-common/vfwprintf.c
+++ b/stdio-common/vfwprintf.c
@@ -1,3 +1,25 @@
-#include <wctype.h>
-#define COMPILE_WPRINTF 1
-#include "vfprintf.c"
+/* 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 <libio/libioP.h>
+
+extern int
+__vfwprintf (FILE *fp, const wchar_t *format, va_list ap)
+{
+ return __vfwprintf_internal (fp, format, ap, 0);
+}
+ldbl_weak_alias (__vfwprintf, vfwprintf);
diff --git a/stdio-common/vprintf.c b/stdio-common/vprintf.c
index d459642dc8..0da8ba761e 100644
--- a/stdio-common/vprintf.c
+++ b/stdio-common/vprintf.c
@@ -25,9 +25,9 @@
/* Write formatted output to stdout according to the
format string FORMAT, using the argument list in ARG. */
int
-__vprintf (const char *format, __gnuc_va_list arg)
+__vprintf (const char *format, va_list ap)
{
- return vfprintf (stdout, format, arg);
+ return __vfprintf_internal (stdout, format, ap, 0);
}
ldbl_strong_alias (__vprintf, vprintf)
diff --git a/stdlib/strfrom-skeleton.c b/stdlib/strfrom-skeleton.c
index 2840512cae..5b33604427 100644
--- a/stdlib/strfrom-skeleton.c
+++ b/stdlib/strfrom-skeleton.c
@@ -106,7 +106,7 @@ STRFROM (char *dest, size_t size, const char *format, FLOAT f)
}
/* The following code to prepare the virtual file has been adapted from the
- function _IO_vsnprintf from libio. */
+ function __vsnprintf_internal from libio. */
if (size == 0)
{
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
index 468e23dec4..bda84af0bb 100644
--- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
@@ -166,7 +166,7 @@ __nldbl_vfprintf (FILE *s, const char *fmt, va_list ap)
{
int done;
set_no_long_double ();
- done = _IO_vfprintf (s, fmt, ap);
+ done = __vfprintf_internal (s, fmt, ap, 0);
clear_no_long_double ();
return done;
}
@@ -175,15 +175,16 @@ strong_alias (__nldbl_vfprintf, __nldbl__IO_vfprintf)
int
attribute_compat_text_section
-__nldbl__IO_vsprintf (char *string, const char *fmt, va_list ap)
+__nldbl___vsprintf (char *string, const char *fmt, va_list ap)
{
int done;
__no_long_double = 1;
- done = _IO_vsprintf (string, fmt, ap);
+ done = __vsprintf_internal (string, fmt, ap, 0);
__no_long_double = 0;
return done;
}
-weak_alias (__nldbl__IO_vsprintf, __nldbl_vsprintf)
+strong_alias (__nldbl___vsprintf, __nldbl__IO_vsprintf)
+weak_alias (__nldbl___vsprintf, __nldbl_vsprintf)
libc_hidden_def (__nldbl_vsprintf)
int
@@ -193,7 +194,7 @@ __nldbl_obstack_vprintf (struct obstack *obstack, const char *fmt,
{
int done;
__no_long_double = 1;
- done = _IO_obstack_vprintf (obstack, fmt, ap);
+ done = __obstack_vprintf_internal (obstack, fmt, ap, 0);
__no_long_double = 0;
return done;
}
@@ -245,7 +246,7 @@ __nldbl_vasprintf (char **result_ptr, const char *fmt, va_list ap)
{
int res;
__no_long_double = 1;
- res = _IO_vasprintf (result_ptr, fmt, ap);
+ res = __vasprintf_internal (result_ptr, fmt, ap, 0);
__no_long_double = 0;
return res;
}
@@ -257,7 +258,7 @@ __nldbl_vdprintf (int d, const char *fmt, va_list arg)
{
int res;
set_no_long_double ();
- res = _IO_vdprintf (d, fmt, arg);
+ res = __vdprintf_internal (d, fmt, arg, 0);
clear_no_long_double ();
return res;
}
@@ -269,7 +270,7 @@ __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
{
int res;
set_no_long_double ();
- res = _IO_vfwprintf (s, fmt, ap);
+ res = __vfwprintf_internal (s, fmt, ap, 0);
clear_no_long_double ();
return res;
}
@@ -289,7 +290,7 @@ __nldbl_vsnprintf (char *string, size_t maxlen, const char *fmt,
{
int res;
__no_long_double = 1;
- res = _IO_vsnprintf (string, maxlen, fmt, ap);
+ res = __vsnprintf_internal (string, maxlen, fmt, ap, 0);
__no_long_double = 0;
return res;
}
@@ -303,7 +304,7 @@ __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt,
{
int res;
__no_long_double = 1;
- res = _IO_vswprintf (string, maxlen, fmt, ap);
+ res = __vswprintf_internal (string, maxlen, fmt, ap, 0);
__no_long_double = 0;
return res;
}
--
2.14.5