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+.
---
 mingw-w64-crt/stdio/mingw_pformat.h   | 11 +++++++--
 mingw-w64-crt/stdio/mingw_sprintfw.c  |  4 +--
 mingw-w64-crt/stdio/mingw_vsnprintf.c | 18 ++++++++++++++
 mingw-w64-crt/stdio/mingw_vsprintfw.c |  4 +--
 mingw-w64-headers/crt/stdio.h         | 35 ++++++++++++++++++++++++---
 mingw-w64-headers/crt/wchar.h         | 23 +++++++++++++-----
 6 files changed, 79 insertions(+), 16 deletions(-)

diff --git a/mingw-w64-crt/stdio/mingw_pformat.h 
b/mingw-w64-crt/stdio/mingw_pformat.h
index 4777804322ab..3381ff8ba908 100644
--- a/mingw-w64-crt/stdio/mingw_pformat.h
+++ b/mingw-w64-crt/stdio/mingw_pformat.h
@@ -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))
diff --git a/mingw-w64-crt/stdio/mingw_sprintfw.c 
b/mingw-w64-crt/stdio/mingw_sprintfw.c
index 0baf1e4f387d..179c27970e6b 100644
--- a/mingw-w64-crt/stdio/mingw_sprintfw.c
+++ b/mingw-w64-crt/stdio/mingw_sprintfw.c
@@ -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"
 
diff --git a/mingw-w64-crt/stdio/mingw_vsnprintf.c 
b/mingw-w64-crt/stdio/mingw_vsnprintf.c
index b477300f9700..b9c3578627d1 100644
--- a/mingw-w64-crt/stdio/mingw_vsnprintf.c
+++ b/mingw-w64-crt/stdio/mingw_vsnprintf.c
@@ -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;
 }
 
diff --git a/mingw-w64-crt/stdio/mingw_vsprintfw.c 
b/mingw-w64-crt/stdio/mingw_vsprintfw.c
index fd8808bf477d..6d70b2cfa1e5 100644
--- a/mingw-w64-crt/stdio/mingw_vsprintfw.c
+++ b/mingw-w64-crt/stdio/mingw_vsprintfw.c
@@ -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"
 
diff --git a/mingw-w64-headers/crt/stdio.h b/mingw-w64-headers/crt/stdio.h
index 20cab73dcc00..3934754b01f1 100644
--- a/mingw-w64-headers/crt/stdio.h
+++ b/mingw-w64-headers/crt/stdio.h
@@ -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 */
diff --git a/mingw-w64-headers/crt/wchar.h b/mingw-w64-headers/crt/wchar.h
index ffa2ba25d973..25f222e85dcd 100644
--- a/mingw-w64-headers/crt/wchar.h
+++ b/mingw-w64-headers/crt/wchar.h
@@ -445,10 +445,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,...);
@@ -526,7 +526,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_vswprintf);
+
+/* __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);
@@ -534,7 +543,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
-- 
2.20.1



_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to