X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=mingwrt%2Finclude%2Fstdio.h;h=8ee362438bda2d4c898a734fa820118a38b0f415;hb=21718add2560a3103b881327bee3779b06a488ff;hp=9e2ccabe22c950226cb7cfe0cb502a0bc19dd9fc;hpb=7428c55ab13b7f25c68e0248269bbca64f2906b2;p=mingw%2Fmingw-org-wsl.git diff --git a/mingwrt/include/stdio.h b/mingwrt/include/stdio.h index 9e2ccab..8ee3624 100644 --- a/mingwrt/include/stdio.h +++ b/mingwrt/include/stdio.h @@ -7,7 +7,7 @@ * $Id$ * * Written by Colin Peters - * Copyright (C) 1997-2005, 2007-2010, 2014-2017, MinGW.org Project. + * Copyright (C) 1997-2005, 2007-2010, 2014-2019, MinGW.org Project. * * * Permission is hereby granted, free of charge, to any person obtaining a @@ -44,8 +44,7 @@ * this partial fashion... */ #ifndef __WCHAR_H_SOURCED__ - /* - * ...which is exclusive to , do we assert the multiple + /* ...which is exclusive to , do we assert the multiple * inclusion guard for itself. */ #define _STDIO_H @@ -75,25 +74,26 @@ # define __need_off_t # define __need_ssize_t #endif -#if !(defined __STRICT_ANSI__ || defined (__NO_MINGW_LFS)) \ - && defined (__MSVCRT__) - /* ...while this is required to support our fseeko64() and ftello64() - * implementations, (neither of which is in any way standardized)... + +/* Although non-standard themselves, we also need either one or other + * of the following pair of data types, from , because our + * standard fpos_t is opaquely defined in terms of... + */ +#ifdef __MSVCRT__ + /* ...an explicitly 64-bit file offset type, for MSVCRT.DLL users... */ # define __need___off64_t -#endif -/* It is sufficient to test for just one define from each of the two - * preceding groups... - */ -#if defined __need_off_t || defined __need___off64_t - /* ...to identify a requirement for selective inclusion of one or more - * of these type definitions from "sys/types.h"; (note that we use the - * #include "..." form here, to ensure that we get the correct header - * file, relative to the location of this ). +#else + /* ...or a 32-bit equivalent, for pre-MSVCRT.DLL users. */ -# include "sys/types.h" +# define __need___off32_t #endif +/* Note the use of the #include "..." form here, to ensure that we get + * the correct header file, relative to the location of this + */ +#include "sys/types.h" + #ifndef __VALIST /* Also similarly, for the va_list type, defined in "stdarg.h" */ @@ -298,10 +298,46 @@ _CRTIMP __cdecl __MINGW_NOTHROW void setbuf (FILE *, char *); /* Formatted Output * * MSVCRT implementations are not ANSI C99 conformant... - * we offer these conforming alternatives from libmingwex.a + * we offer conforming alternatives from libmingwex.a */ #undef __mingw_stdio_redirect__ -#define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __mingw_##F +#define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __Wformat(F) +#define __Wformat_mingw_printf(F,A) __attribute__((__format__(__mingw_printf__,F,A))) + +#if __GNUC__ >= 6 +/* From GCC-6 onwards, we will provide customized -Wformat + * handling, via our own mingw_printf format category... + */ +#define __Wformat(F) __Wformat_##F __mingw_##F + +#else /* __GNUC__ < 6 */ +/* ...whereas, for earlier GCC, we preserve the status quo, + * offering no -Wformat checking for those functions which + * replace the MSVCRT.DLL versions... + */ +#define __Wformat(F) __mingw_##F + +/* ...while degrading to gnu_printf checking for snprintf() + * and vsnprintf(), (which are ALWAYS MinGW.org variants). + */ +#define __mingw_printf__ __gnu_printf__ +#endif + +/* The following convenience macros specify the appropriate + * -Wformat checking for MSVCRT.DLL replacement functions... + */ +#define __Wformat_printf __Wformat_mingw_printf(1,2) +#define __Wformat_fprintf __Wformat_mingw_printf(2,3) +#define __Wformat_sprintf __Wformat_mingw_printf(2,3) +#define __Wformat_vprintf __Wformat_mingw_printf(1,0) +#define __Wformat_vfprintf __Wformat_mingw_printf(2,0) +#define __Wformat_vsprintf __Wformat_mingw_printf(2,0) + +/* ...while this pair are specific to the two MinGW.org + * only functions. + */ +#define __Wformat_snprintf __Wformat_mingw_printf(3,4) +#define __Wformat_vsnprintf __Wformat_mingw_printf(3,0) extern int __mingw_stdio_redirect__(fprintf)(FILE*, const char*, ...); extern int __mingw_stdio_redirect__(printf)(const char*, ...); @@ -339,7 +375,7 @@ extern int __mingw_stdio_redirect__(vsnprintf)(char*, size_t, const char*, __VAL */ extern unsigned int _mingw_output_format_control( unsigned int, unsigned int ); -#if __USE_MINGW_ANSI_STDIO +#if __USE_MINGW_ANSI_STDIO || defined _ISOC99_SOURCE /* User has expressed a preference for C99 conformance... */ # undef __mingw_stdio_redirect__ @@ -357,12 +393,20 @@ extern unsigned int _mingw_output_format_control( unsigned int, unsigned int ); */ # define __mingw_stdio_redirect__ static __inline__ __cdecl __MINGW_NOTHROW -# else +# else /* Neither C++ nor __GNUC__ */ /* Can't use inlines; fall back on module local static stubs. */ # define __mingw_stdio_redirect__ static __cdecl __MINGW_NOTHROW -# endif +# endif /* Neither C++ nor __GNUC__ */ +#endif /* __USE_MINGW_ANSI_STDIO || defined _ISOC99_SOURCE */ + +#if __USE_MINGW_ANSI_STDIO +/* The MinGW ISO-C conforming implementations of the printf() family + * of functions are to be used, in place of non-conforming Microsoft + * implementations; force call redirection, via the following set of + * in-line functions. + */ __mingw_stdio_redirect__ int fprintf (FILE *__stream, const char *__format, ...) { @@ -411,7 +455,7 @@ int vsprintf (char *__stream, const char *__format, __VALIST __local_argv) return __mingw_vsprintf( __stream, __format, __local_argv ); } -#else +#else /* !__USE_MINGW_ANSI_STDIO */ /* Default configuration: simply direct all calls to MSVCRT... */ _CRTIMP __cdecl __MINGW_NOTHROW int fprintf (FILE *, const char *, ...); @@ -421,12 +465,50 @@ _CRTIMP __cdecl __MINGW_NOTHROW int vfprintf (FILE *, const char *, __VALIST); _CRTIMP __cdecl __MINGW_NOTHROW int vprintf (const char *, __VALIST); _CRTIMP __cdecl __MINGW_NOTHROW int vsprintf (char *, const char *, __VALIST); -#endif +#endif /* !__USE_MINGW_ANSI_STDIO */ + +#if __GNUC__ && defined _ISOC99_SOURCE +/* Although MinGW implementations of the ISO-C99 snprintf() and + * vsnprintf() functions do not conflict with any implementation + * in MSVCRT.DLL, (because MSVCRT.DLL does not implement either), + * there are -Wformat attribute conflicts with the GCC built-in + * prototypes associated with each; by providing the following + * in-line function implementations, which will override GCC's + * built-in prototypes, we may avoid these conflicts. + */ +__mingw_stdio_redirect__ +int snprintf (char *__buf, size_t __len, const char *__format, ...) +{ + register int __retval; + __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format ); + __retval = __mingw_vsnprintf( __buf, __len, __format, __local_argv ); + __builtin_va_end( __local_argv ); + return __retval; +} + +__mingw_stdio_redirect__ +int vsnprintf (char *__buf, size_t __len, const char *__format, __VALIST __local_argv) +{ + return __mingw_vsnprintf( __buf, __len, __format, __local_argv ); +} +#endif /* __GNUC__ && defined _ISOC99_SOURCE */ + /* Regardless of user preference, always offer these alternative - * entry points, for direct access to the MSVCRT implementations. + * entry points, for direct access to the MSVCRT implementations, + * with ms_printf -Wformat checking in each case. */ +#undef __Wformat #undef __mingw_stdio_redirect__ -#define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __msvcrt_##F +#define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __Wformat(F) +#define __Wformat_msvcrt_printf(F,A) __attribute__((__format__(__ms_printf__,F,A))) +#define __Wformat(F) __Wformat_ms_##F __msvcrt_##F + +#define __Wformat_ms_printf __Wformat_msvcrt_printf(1,2) +#define __Wformat_ms_fprintf __Wformat_msvcrt_printf(2,3) +#define __Wformat_ms_sprintf __Wformat_msvcrt_printf(2,3) +#define __Wformat_ms_vprintf __Wformat_msvcrt_printf(1,0) +#define __Wformat_ms_vfprintf __Wformat_msvcrt_printf(2,0) +#define __Wformat_ms_vsprintf __Wformat_msvcrt_printf(2,0) _CRTIMP int __mingw_stdio_redirect__(fprintf)(FILE *, const char *, ...); _CRTIMP int __mingw_stdio_redirect__(printf)(const char *, ...); @@ -436,6 +518,7 @@ _CRTIMP int __mingw_stdio_redirect__(vprintf)(const char *, __VALIST); _CRTIMP int __mingw_stdio_redirect__(vsprintf)(char *, const char *, __VALIST); #undef __mingw_stdio_redirect__ +#undef __Wformat /* The following three ALWAYS refer to the MSVCRT implementations... */ @@ -450,10 +533,14 @@ _CRTIMP __cdecl __MINGW_NOTHROW int _vscprintf (const char *, __VALIST); * NOT compatible with C99, but the following are; if you want the * MSVCRT behaviour, you MUST use the Microsoft "uglified" names. */ -__cdecl __MINGW_NOTHROW int snprintf (char *, size_t, const char *, ...); -__cdecl __MINGW_NOTHROW int vsnprintf (char *, size_t, const char *, __VALIST); +__cdecl __MINGW_NOTHROW __Wformat_snprintf +int snprintf (char *, size_t, const char *, ...); -__cdecl __MINGW_NOTHROW int vscanf (const char * __restrict__, __VALIST); +__cdecl __MINGW_NOTHROW __Wformat_vsnprintf +int vsnprintf (char *, size_t, const char *, __VALIST); + +__cdecl __MINGW_NOTHROW +int vscanf (const char * __restrict__, __VALIST); __cdecl __MINGW_NOTHROW int vfscanf (FILE * __restrict__, const char * __restrict__, __VALIST); @@ -465,8 +552,7 @@ int vsscanf (const char * __restrict__, const char * __restrict__, __VALIST); #endif /* included in its own right */ #if __MSVCRT_VERSION__ >= __MSVCR80_DLL || _WIN32_WINNT >= _WIN32_WINNT_VISTA -/* - * In MSVCR80.DLL, (and its descendants), Microsoft introduced variants +/* In MSVCR80.DLL, (and its descendants), Microsoft introduced variants * of the printf() functions, with names qualified by an underscore prefix * and "_p" or "_p_l" suffixes; implemented in Microsoft's typically crass, * non-standard, and non-portable fashion, these provide support for access @@ -541,8 +627,7 @@ int _vsprintf_p_l (char *, size_t, const char *, locale_t, __VALIST); #if ! (defined _STDIO_H && defined _WCHAR_H) #if __MSVCRT_VERSION__ >= __MSVCR80_DLL || _WIN32_WINNT >= _WIN32_WINNT_VISTA -/* - * Wide character variants of the foregoing "positional parameter" printf() +/* Wide character variants of the foregoing "positional parameter" printf() * functions; MSDN says that these should be declared when either , or * is included, so we make them selectively available to , * but, just as in the foregoing, we advise against their use. @@ -688,9 +773,61 @@ _CRTIMP __cdecl __MINGW_NOTHROW int fseek (FILE *, long, int); _CRTIMP __cdecl __MINGW_NOTHROW long ftell (FILE *); _CRTIMP __cdecl __MINGW_NOTHROW void rewind (FILE *); +#ifdef __USE_MINGW_FSEEK +/* Workaround for a limitation on Win9x where a file is not zero padded + * on write, following a seek beyond the original end of file; supporting + * redirector functions are implemented in libmingwex.a + * + * Note: this is improper usage. __USE_MINGW_FSEEK exhibits the form of a + * private (system reserved) feature test macro; as such, users should not + * define it directly, and thus, it really should not have been defined at + * this point; discourage this practice. + */ +#warning "The __USE_MINGW_FSEEK feature test is deprecated" +#pragma info "Define _WIN32_WINDOWS, instead of __USE_MINGW_FSEEK" + +#elif _WIN32_WINDOWS >= _WIN32_WINDOWS_95 && _WIN32_WINDOWS < _WIN32_WINNT_WIN2K +/* This is correct usage; the private __USE_MINGW_FSEEK feature affects only + * Win9x, so enable it implicitly when the _WIN32_WINDOWS feature is specified, + * thus indicating the user's intent to target a Win9x platform. + */ +#define __USE_MINGW_FSEEK +#endif + +#ifdef __USE_MINGW_FSEEK +/* Regardless of how it may have become defined, when __USE_MINGW_FSEEK has + * been defined, we must redirect calls to fseek() and fwrite(), so that the + * Win9x zero padding limitation can be mitigated. + */ +__cdecl __MINGW_NOTHROW int __mingw_fseek (FILE *, __off64_t, int); +__CRT_ALIAS int fseek( FILE *__fp, long __offset, int __whence ) +{ return __mingw_fseek( __fp, (__off64_t)(__offset), __whence ); } + +__cdecl __MINGW_NOTHROW size_t __mingw_fwrite (const void *, size_t, size_t, FILE *); +__CRT_ALIAS size_t fwrite( const void *__buf, size_t __len, size_t __cnt, FILE *__fp ) +{ return __mingw_fwrite( __buf, __len, __cnt, __fp ); } +#endif /* __USE_MINGW_FSEEK */ + +/* An opaque data type used for storing file positions... The contents + * of this type are unknown, but we (the compiler) need to know the size + * because the programmer using fgetpos and fsetpos will be setting aside + * storage for fpos_t aggregates. Actually I tested using a byte array and + * it is fairly evident that fpos_t is a 32-bit type in CRTDLL.DLL, but in + * MSVCRT.DLL, it is a 64-bit type. Define it in terms of an int type of + * the appropriate size, encapsulated within an aggregate type, to make + * it opaque to casting, and so discourage abuse. + */ +#ifdef __MSVCRT__ +typedef union { __int64 __value; __off64_t __offset; } fpos_t; +#else +typedef union { __int32 __value; __off32_t __offset; } fpos_t; +#endif + +_CRTIMP __cdecl __MINGW_NOTHROW int fgetpos (FILE *, fpos_t *); +_CRTIMP __cdecl __MINGW_NOTHROW int fsetpos (FILE *, const fpos_t *); + #if _WIN32_WINNT >= _WIN32_WINNT_VISTA || __MSVCRT_VERSION__ >= __MSVCR80_DLL - /* - * Microsoft introduced a number of variations on fseek() and ftell(), + /* Microsoft introduced a number of variations on fseek() and ftell(), * beginning with MSVCR80.DLL; the bare _fseeki64() and _ftelli64() were * subsequently integrated into MSVCRT.DLL, from Vista onward... */ @@ -698,8 +835,7 @@ _CRTIMP __cdecl __MINGW_NOTHROW int _fseeki64 (FILE *, __int64, int); _CRTIMP __cdecl __MINGW_NOTHROW __int64 _ftelli64 (FILE *); #if __MSVCRT_VERSION__ >= __MSVCR80_DLL - /* - * ...while the "nolock" variants remain exclusive to MSVCR80.DLL, and + /* ...while the "nolock" variants remain exclusive to MSVCR80.DLL, and * its later MSVC specific derivatives. */ _CRTIMP __cdecl __MINGW_NOTHROW int _fseek_nolock (FILE *, long, int); @@ -709,36 +845,30 @@ _CRTIMP __cdecl __MINGW_NOTHROW int _fseeki64_nolock (FILE *, __int64, int); _CRTIMP __cdecl __MINGW_NOTHROW __int64 _ftelli64_nolock (FILE *); #endif /* MSVCR80.DLL and later derivatives ONLY */ -#endif /* MSVCR80.DLL and descendants, or MSVCRT.DLL since Vista */ - -#ifdef __USE_MINGW_FSEEK -/* Workaround for a limitation on Win9x where a file is not zero padded - * on write, following a seek beyond the original end of file; these are - * implemented in libmingwex.a - */ -__cdecl __MINGW_NOTHROW int __mingw_fseek (FILE *, long, int); -__cdecl __MINGW_NOTHROW size_t __mingw_fwrite (const void *, size_t, size_t, FILE *); - -#define fwrite(buffer, size, count, fp) __mingw_fwrite(buffer, size, count, fp) -#define fseek(fp, offset, whence) __mingw_fseek(fp, offset, whence) -#endif /* __USE_MINGW_FSEEK */ -/* An opaque data type used for storing file positions... The contents of - * this type are unknown, but we (the compiler) need to know the size - * because the programmer using fgetpos and fsetpos will be setting aside - * storage for fpos_t structres. Actually I tested using a byte array and - * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL). - * Perhaps an unsigned long? TODO? It's definitely a 64-bit number in - * MSVCRT however, and for now `long long' will do. - */ -#ifdef __MSVCRT__ -typedef long long fpos_t; -#else -typedef long fpos_t; +#else /* pre-MSVCR80.DLL or MSVCRT.DLL pre-Vista */ +/* The Microsoft DLLs don't provide either _fseeki64() or _ftelli64(), but + * they DO provide fgetpos(), fsetpos(), and _lseeki64(), which may be used + * to emulate the two missing functions. (Note that we choose to provide + * these emulations in the form of MinGW external helper functions, rather + * than pollute the namespace with declarations, such as that + * for _lseeki64(), which properly belongs in ). + */ +#ifndef __USE_MINGW_FSEEK +/* If this option has been selected, an alternative emulation for _fseeki64() + * is provided later, to ensure that the call is wrapped in a MinGW specific + * fseek() handling API. + */ +int __cdecl __MINGW_NOTHROW __mingw_fseeki64 (FILE *, __int64, int); +__CRT_ALIAS __cdecl __MINGW_NOTHROW int _fseeki64 (FILE *__f, __int64 __o, int __w) +{ return __mingw_fseeki64 (__f, __o, __w); } #endif -_CRTIMP __cdecl __MINGW_NOTHROW int fgetpos (FILE *, fpos_t *); -_CRTIMP __cdecl __MINGW_NOTHROW int fsetpos (FILE *, const fpos_t *); +__int64 __cdecl __MINGW_NOTHROW __mingw_ftelli64 (FILE *); +__CRT_ALIAS __cdecl __int64 __MINGW_NOTHROW _ftelli64 (FILE *__file ) +{ return __mingw_ftelli64 (__file); } + +#endif /* pre-MSVCR80.DLL or MSVCRT.DLL pre-Vista */ /* Error Functions */ @@ -756,7 +886,6 @@ inline __cdecl __MINGW_NOTHROW int ferror (FILE * __F){ return __F->_flag & _IO _CRTIMP __cdecl __MINGW_NOTHROW void clearerr (FILE *); _CRTIMP __cdecl __MINGW_NOTHROW void perror (const char *); - #ifndef __STRICT_ANSI__ /* * Pipes @@ -883,14 +1012,20 @@ FILE * __cdecl __MINGW_NOTHROW fopen64 (const char * filename, const char * mod int __cdecl __MINGW_NOTHROW fseeko64 (FILE *, __off64_t, int); #ifdef __USE_MINGW_FSEEK -int __cdecl __MINGW_NOTHROW __mingw_fseeko64 (FILE *, __off64_t, int); -#define fseeko64(fp, offset, whence) __mingw_fseeko64(fp, offset, whence) +/* When this option is selected, we need to redirect calls to _fseeki64() + * and fseeko64() through a MinGW specific wrapper. Since the two functions + * are fundamentally identical, differing only in the type of the "offset" + * argument, (and both types are effectively 64-bit signed ints anyway), + * the same wrapper will suffice for both. + */ +__CRT_ALIAS int _fseeki64( FILE *__fp, __int64 __offset, int __whence ) +{ return __mingw_fseek( __fp, (__off64_t)(__offset), __whence ); } + +__CRT_ALIAS int fseeko64( FILE *__fp, __off64_t __offset, int __whence ) +{ return __mingw_fseek( __fp, __offset, __whence ); } #endif -__CRT_ALIAS __off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE *); -__CRT_ALIAS __LIBIMPL__(( FUNCTION = ftello64 )) -__off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE * stream) -{ fpos_t __pos; return (fgetpos(stream, &__pos)) ? -1LL : (__off64_t)(__pos); } +__off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE *); #endif /* __MSVCRT__ && !__NO_MINGW_LFS */ #endif /* !__STRICT_ANSI__ */