glibc/libio/bits/stdio.h
Zack Weinberg a4fea3f2c3 Don't install libio.h or _G_config.h.
We shipped 2.27 with libio.h and _G_config.h still installed but
issuing warnings when used.  Let's stop installing them early in 2.28
so that we have plenty of time to think of another plan if there are
problems.

The public stdio.h had a genuine dependency on libio.h for the
complete definitions of FILE and cookie_io_functions_t, and a genuine
dependency on _G_config.h for the complete definitions of fpos_t and
fpos64_t; these are moved to single-type headers.
bits/types/struct_FILE.h also provides a handful of accessor and
bitflags macros so that code is not duplicated between bits/stdio.h
and libio.h.  All the other _IO_ and _G_ names used by the public
stdio.h can be replaced with either public names or __-names.

In order to minimize the risk of breaking our own compatibility code,
bits/types/struct_FILE.h preserves the _IO_USE_OLD_IO_FILE mechanism
exactly as it was in libio.h, but you have to define _LIBC to use it,
or it'll error out.  Similarly, _IO_lock_t_defined is preserved
exactly, but will error out if used without defining _LIBC.

Internally, include/stdio.h continues to include libio.h, and libio.h
scrupulously provides every _IO_* and _G_* name that it always did,
perhaps now defined in terms of the public names.  This is how this
patch avoids touching dozens of files throughout glibc and becoming
entangled with the _IO_MTSAFE_IO mess.  The remaining patches in this
series eliminate most of the _G_ names.

Tested on x86_64-linux; in addition to the test suite, I installed the
library in a sysroot and verified that a simple program that uses
stdio.h could be compiled against the installed library, and I also
verified that installed stripped libraries are unchanged.

	* libio/bits/types/__fpos_t.h, libio/bits/types/__fpos64_t.h:
	New single-type headers split from _G_config.h.
	* libio/bits/types/cookie_io_functions_t.h
	* libio/bits/types/struct_FILE.h
	New single-type headers split from libio.h.

	* libio/Makefile: Install the above new headers.  Don't install
	libio.h, _G_config.h, bits/libio.h, bits/_G_config.h, or
	bits/libio-ldbl.h.
	* libio/_G_config.h, libio/libio.h: Delete file.

	* libio/bits/libio.h: Remove improper-inclusion guard.
	Include stdio.h and don't repeat anything that it does.
	Define _IO_fpos_t as __fpos_t, _IO_fpos64_t as __fpos64_t,
	_IO_BUFSIZ as BUFSIZ, _IO_va_list as __gnuc_va_list,
	__io_read_fn as cookie_read_function_t,
	__io_write_fn as cookie_write_function_t,
	__io_seek_fn as cookie_seek_function_t,
	__io_close_fn as cookie_close_function_t,
	and _IO_cookie_io_functions_t as cookie_io_functions_t.
	Define _STDIO_USES_IOSTREAM, __HAVE_COLUMN, and _IO_file_flags
	here, in the "compatibility defines" section.  Remove an #if 0
	block.  Use the "body" macros from bits/types/struct_FILE.h to
	define _IO_getc_unlocked, _IO_putc_unlocked, _IO_feof_unlocked,
	and _IO_ferror_unlocked.
	Move prototypes of __uflow and __overflow...

	* libio/stdio.h: ...here.  Don't include bits/libio.h.
	Don't define _STDIO_USES_IOSTREAM.  Get __gnuc_va_list
	directly from stdarg.h.  Include bits/types/__fpos_t.h,
	bits/types/__fpos64_t.h, bits/types/struct_FILE.h,
	and, when __USE_GNU, bits/types/cookie_io_functions_t.h.
	Use __gnuc_va_list, not _G_va_list; __fpos_t, not _G_fpos_t;
	__fpos64_t, not _G_fpos64_t; FILE, not struct _IO_FILE;
	cookie_io_functions_t, not _IO_cookie_io_functions_t;
	__ssize_t, not _IO_ssize_t.  Unconditionally define
	BUFSIZ as 8192 and EOF as (-1).

	* libio/bits/stdio.h: Add multiple-include guard.  Use the "body"
	macros from bits/types/struct_FILE.h instead of _IO_* macros
	from libio.h; use __gnuc_va_list instead of va_list and __ssize_t
	instead of _IO_ssize_t.
	* libio/bits/stdio2.h: Similarly.

	* libio/iolibio.h: Add multiple-include guard.
	Include bits/libio.h after stdio.h.
	* libio/libioP.h: Add multiple-include guard.
	Include stdio.h and bits/libio.h before iolibio.h.

        * include/bits/types/__fpos_t.h, include/bits/types/__fpos64_t.h
	* include/bits/types/cookie_io_functions_t.h
	* include/bits/types/struct_FILE.h: New wrappers.

	* bits/_G_config.h, sysdeps/unix/sysv/linux/_G_config.h:
        Get definitions of _G_fpos_t and _G_fpos64_t from
        bits/types/__fpos_t.h and bits/types/__fpos64_t.h
        respectively.  Remove improper-inclusion guards.

        * conform/data/stdio.h-data: Update expectations of va_list.
	* scripts/check-installed-headers.sh: Remove special case for
        libio.h and _G_config.h.
2018-02-07 10:07:31 -05:00

196 lines
5.5 KiB
C

/* Optimizing macros and inline functions for stdio functions.
Copyright (C) 1998-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/>. */
#ifndef _BITS_STDIO_H
#define _BITS_STDIO_H 1
#ifndef _STDIO_H
# error "Never include <bits/stdio.h> directly; use <stdio.h> instead."
#endif
#ifndef __extern_inline
# define __STDIO_INLINE inline
#else
# define __STDIO_INLINE __extern_inline
#endif
#ifdef __USE_EXTERN_INLINES
/* For -D_FORTIFY_SOURCE{,=2} bits/stdio2.h will define a different
inline. */
# if !(__USE_FORTIFY_LEVEL > 0 && defined __fortify_function)
/* Write formatted output to stdout from argument list ARG. */
__STDIO_INLINE int
vprintf (const char *__restrict __fmt, __gnuc_va_list __arg)
{
return vfprintf (stdout, __fmt, __arg);
}
# endif
/* Read a character from stdin. */
__STDIO_INLINE int
getchar (void)
{
return getc (stdin);
}
# ifdef __USE_MISC
/* Faster version when locking is not necessary. */
__STDIO_INLINE int
fgetc_unlocked (FILE *__fp)
{
return __getc_unlocked_body (__fp);
}
# endif /* misc */
# ifdef __USE_POSIX
/* This is defined in POSIX.1:1996. */
__STDIO_INLINE int
getc_unlocked (FILE *__fp)
{
return __getc_unlocked_body (__fp);
}
/* This is defined in POSIX.1:1996. */
__STDIO_INLINE int
getchar_unlocked (void)
{
return __getc_unlocked_body (stdin);
}
# endif /* POSIX */
/* Write a character to stdout. */
__STDIO_INLINE int
putchar (int __c)
{
return putc (__c, stdout);
}
# ifdef __USE_MISC
/* Faster version when locking is not necessary. */
__STDIO_INLINE int
fputc_unlocked (int __c, FILE *__stream)
{
return __putc_unlocked_body (__c, __stream);
}
# endif /* misc */
# ifdef __USE_POSIX
/* This is defined in POSIX.1:1996. */
__STDIO_INLINE int
putc_unlocked (int __c, FILE *__stream)
{
return __putc_unlocked_body (__c, __stream);
}
/* This is defined in POSIX.1:1996. */
__STDIO_INLINE int
putchar_unlocked (int __c)
{
return __putc_unlocked_body (__c, stdout);
}
# endif /* POSIX */
# ifdef __USE_GNU
/* Like `getdelim', but reads up to a newline. */
__STDIO_INLINE __ssize_t
getline (char **__lineptr, size_t *__n, FILE *__stream)
{
return __getdelim (__lineptr, __n, '\n', __stream);
}
# endif /* GNU */
# ifdef __USE_MISC
/* Faster versions when locking is not required. */
__STDIO_INLINE int
__NTH (feof_unlocked (FILE *__stream))
{
return __feof_unlocked_body (__stream);
}
/* Faster versions when locking is not required. */
__STDIO_INLINE int
__NTH (ferror_unlocked (FILE *__stream))
{
return __ferror_unlocked_body (__stream);
}
# endif /* misc */
#endif /* Use extern inlines. */
#if defined __USE_MISC && defined __GNUC__ && defined __OPTIMIZE__ \
&& !defined __cplusplus
/* Perform some simple optimizations. */
# define fread_unlocked(ptr, size, n, stream) \
(__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \
&& (size_t) (size) * (size_t) (n) <= 8 \
&& (size_t) (size) != 0) \
? ({ char *__ptr = (char *) (ptr); \
FILE *__stream = (stream); \
size_t __cnt; \
for (__cnt = (size_t) (size) * (size_t) (n); \
__cnt > 0; --__cnt) \
{ \
int __c = getc_unlocked (__stream); \
if (__c == EOF) \
break; \
*__ptr++ = __c; \
} \
((size_t) (size) * (size_t) (n) - __cnt) \
/ (size_t) (size); }) \
: (((__builtin_constant_p (size) && (size_t) (size) == 0) \
|| (__builtin_constant_p (n) && (size_t) (n) == 0)) \
/* Evaluate all parameters once. */ \
? ((void) (ptr), (void) (stream), (void) (size), \
(void) (n), (size_t) 0) \
: fread_unlocked (ptr, size, n, stream))))
# define fwrite_unlocked(ptr, size, n, stream) \
(__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \
&& (size_t) (size) * (size_t) (n) <= 8 \
&& (size_t) (size) != 0) \
? ({ const char *__ptr = (const char *) (ptr); \
FILE *__stream = (stream); \
size_t __cnt; \
for (__cnt = (size_t) (size) * (size_t) (n); \
__cnt > 0; --__cnt) \
if (putc_unlocked (*__ptr++, __stream) == EOF) \
break; \
((size_t) (size) * (size_t) (n) - __cnt) \
/ (size_t) (size); }) \
: (((__builtin_constant_p (size) && (size_t) (size) == 0) \
|| (__builtin_constant_p (n) && (size_t) (n) == 0)) \
/* Evaluate all parameters once. */ \
? ((void) (ptr), (void) (stream), (void) (size), \
(void) (n), (size_t) 0) \
: fwrite_unlocked (ptr, size, n, stream))))
#endif
/* Define helper macro. */
#undef __STDIO_INLINE
#endif /* bits/stdio.h. */