crt: Add support for C95 (v)swprintf() functions when __USE_MINGW_ANSI_STDIO=1

C95 compatible (v)swprintf function takes size argument and returns
negative value on error. __mingw_(v)swprintf function (which is called
when __USE_MINGW_ANSI_STDIO=1) does not take size argument at all.

Fix this problem by adjusting mingw_sprintfw.c and mingw_vsprintfw.c
files to include "n" function variant and also adjust mingw_vsnprintf.c
implementation to return correct value on error for ISO C95+ variant.

Fix also header files to provide correct declarations for
__mingw_(v)swprintf() function and then also inline definitions for
(v)swprintf() when __USE_MINGW_ANSI_STDIO=1.

Note that mingw-w64 provides also additional non-ISO C (v)snwprintf()
function which is built from the same mingw_vsnprintf.c source file.
Distinguish between non-ISO C (v)snwprintf() and ISO C95+ (v)swprintf() by
a new __BUILD_WIDEAPI_ISO macro.

With all these changes, functions swprintf() and vswprintf() when
__USE_MINGW_ANSI_STDIO is set to 1 are now compatible with ISO C95+.

Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
Pali Rohár 2024-11-15 17:59:52 +01:00 committed by Martin Storsjö
parent 73cf399a16
commit c85d64d8cb
6 changed files with 79 additions and 16 deletions

View File

@ -72,13 +72,20 @@
# define __printf __mingw_wprintf
# define __fprintf __mingw_fwprintf
# define __sprintf __mingw_swprintf
#ifdef __BUILD_WIDEAPI_ISO
# define __snprintf __mingw_swprintf
#else
# define __snprintf __mingw_snwprintf
#endif
# define __vprintf __mingw_vwprintf
# define __vfprintf __mingw_vfwprintf
# define __vsprintf __mingw_vswprintf
#ifdef __BUILD_WIDEAPI_ISO
# define __vsnprintf __mingw_vswprintf
#else
# define __vsnprintf __mingw_vsnwprintf
#endif
#else
# define __pformat __mingw_pformat
#define __fputc(X,STR) fputc((X), (STR))

View File

@ -4,7 +4,7 @@
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#define __BUILD_WIDEAPI 1
#define _CRT_NON_CONFORMING_SWPRINTFS 1
#define __BUILD_WIDEAPI_ISO 1
#include "mingw_sprintf.c"
#include "mingw_snprintf.c"

View File

@ -34,11 +34,20 @@ int __cdecl __vsnprintf(APICHAR *buf, size_t length, const APICHAR *fmt, va_list
register int retval;
if( length == (size_t)(0) )
{
#if defined(__BUILD_WIDEAPI) && defined(__BUILD_WIDEAPI_ISO)
/* No buffer; for wide api ISO C95+ vswprintf() function
* simply returns negative value as required by ISO C95+.
*/
return -1;
#else
/*
* No buffer; simply compute and return the size required,
* without actually emitting any data.
*/
return __pformat( 0, buf, 0, fmt, argv);
#endif
}
/* If we get to here, then we have a buffer...
* Emit data up to the limit of buffer length less one,
@ -47,6 +56,15 @@ int __cdecl __vsnprintf(APICHAR *buf, size_t length, const APICHAR *fmt, va_list
retval = __pformat( 0, buf, --length, fmt, argv );
buf[retval < (int) length ? retval : (int)length] = '\0';
#if defined(__BUILD_WIDEAPI) && defined(__BUILD_WIDEAPI_ISO)
/* For wide api ISO C95+ vswprintf() when requested length
* is equal or larger than buffer length, returns negative
* value as required by ISO C95+.
*/
if( retval >= (int) length )
retval = -1;
#endif
return retval;
}

View File

@ -4,7 +4,7 @@
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#define __BUILD_WIDEAPI 1
#define _CRT_NON_CONFORMING_SWPRINTFS 1
#define __BUILD_WIDEAPI_ISO 1
#include "mingw_vsprintf.c"
#include "mingw_vsnprintf.c"

View File

@ -915,10 +915,10 @@ int vsprintf (char * __restrict__ __stream, const char * __restrict__ __format,
int __cdecl __mingw_snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...);
/* __attribute__((__format__ (gnu_wprintf, 3, 0))) */ __MINGW_ATTRIB_NONNULL(3)
int __cdecl __mingw_vsnwprintf (wchar_t * __restrict__ , size_t, const wchar_t * __restrict__ , va_list);
/* __attribute__((__format__ (gnu_wprintf, 2, 3))) */ __MINGW_ATTRIB_NONNULL(2)
int __cdecl __mingw_swprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , ...);
/* __attribute__((__format__ (gnu_wprintf, 2, 0))) */ __MINGW_ATTRIB_NONNULL(2)
int __cdecl __mingw_vswprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ ,va_list);
/* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
int __cdecl __mingw_swprintf(wchar_t * __restrict__ , size_t, const wchar_t * __restrict__ , ...);
/* __attribute__((__format__ (gnu_wprintf, 3, 0))) */ __MINGW_ATTRIB_NONNULL(3)
int __cdecl __mingw_vswprintf(wchar_t * __restrict__ , size_t, const wchar_t * __restrict__ ,va_list);
/* __attribute__((__format__ (ms_wscanf, 2, 3))) */ __MINGW_ATTRIB_NONNULL(2)
int __cdecl __ms_swscanf(const wchar_t * __restrict__ _Src,const wchar_t * __restrict__ _Format,...);
@ -996,6 +996,32 @@ __MINGW_ASM_CALL(__mingw_vfwprintf);
int vwprintf (const wchar_t *__format, __builtin_va_list __local_argv)
__MINGW_ASM_CALL(__mingw_vwprintf);
/* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
int swprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, ...)
__MINGW_ASM_CALL(__mingw_swprintf);
#if __MINGW_FORTIFY_VA_ARG
__mingw_bos_extern_ovr
/* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
int swprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, ...)
{
__mingw_bos_ptr_chk_warn(__stream, __n * sizeof(wchar_t), 1);
return __mingw_swprintf( __stream, __n, __format, __builtin_va_arg_pack() );
}
#endif /* __MINGW_FORTIFY_VA_ARG */
__mingw_bos_ovr
/* __attribute__((__format__ (gnu_wprintf, 3, 0))) */ __MINGW_ATTRIB_NONNULL(3)
int vswprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, __builtin_va_list __local_argv)
{
#if __MINGW_FORTIFY_LEVEL > 0
__mingw_bos_ptr_chk_warn(__stream, __n * sizeof(wchar_t), 1);
#endif
return __mingw_vswprintf( __stream, __n, __format, __local_argv );
}
#ifndef __NO_ISOCEXT /* externs in libmingwex.a */
/* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
@ -1023,6 +1049,7 @@ int vsnwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, __builti
#endif
return __mingw_vsnwprintf( __stream, __n, __format, __local_argv );
}
#endif /* __NO_ISOCEXT */
#else /* !__USE_MINGW_ANSI_STDIO */

View File

@ -452,10 +452,10 @@ _CRTIMP FILE *__cdecl __acrt_iob_func(unsigned index);
int __cdecl __mingw_snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...);
/* __attribute__((__format__ (gnu_wprintf, 3, 0))) */ __MINGW_ATTRIB_NONNULL(3)
int __cdecl __mingw_vsnwprintf (wchar_t * __restrict__ , size_t, const wchar_t * __restrict__ , va_list);
/* __attribute__((__format__ (gnu_wprintf, 2, 3))) */ __MINGW_ATTRIB_NONNULL(2)
int __cdecl __mingw_swprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , ...);
/* __attribute__((__format__ (gnu_wprintf, 2, 0))) */ __MINGW_ATTRIB_NONNULL(2)
int __cdecl __mingw_vswprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ ,va_list);
/* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
int __cdecl __mingw_swprintf(wchar_t * __restrict__ , size_t, const wchar_t * __restrict__ , ...);
/* __attribute__((__format__ (gnu_wprintf, 3, 0))) */ __MINGW_ATTRIB_NONNULL(3)
int __cdecl __mingw_vswprintf(wchar_t * __restrict__ , size_t, const wchar_t * __restrict__ ,va_list);
/* __attribute__((__format__ (ms_wscanf, 2, 3))) */ __MINGW_ATTRIB_NONNULL(2)
int __cdecl __ms_swscanf(const wchar_t * __restrict__ _Src,const wchar_t * __restrict__ _Format,...);
@ -533,7 +533,16 @@ __MINGW_ASM_CALL(__mingw_vfwprintf);
int vwprintf (const wchar_t *__format, __builtin_va_list __local_argv)
__MINGW_ASM_CALL(__mingw_vwprintf);
/*#ifndef __NO_ISOCEXT */ /* externs in libmingwex.a */
/* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
int swprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, ...)
__MINGW_ASM_CALL(__mingw_swprintf);
/* __attribute__((__format__ (gnu_wprintf, 3, 0))) */ __MINGW_ATTRIB_NONNULL(3)
int vswprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, __builtin_va_list __local_argv)
__MINGW_ASM_CALL(__mingw_vswprintf);
#ifndef __NO_ISOCEXT /* externs in libmingwex.a */
/* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
int snwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, ...)
__MINGW_ASM_CALL(__mingw_snwprintf);
@ -541,7 +550,9 @@ __MINGW_ASM_CALL(__mingw_snwprintf);
/* __attribute__((__format__ (gnu_wprintf, 3, 0))) */ __MINGW_ATTRIB_NONNULL(3)
int vsnwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, __builtin_va_list __local_argv)
__MINGW_ASM_CALL(__mingw_vsnwprintf);
/* #endif */ /* __NO_ISOCEXT */
#endif /* __NO_ISOCEXT */
#else /* !__USE_MINGW_ANSI_STDIO */
#ifdef _UCRT