ISO C does not define (v)snwprintf() function. But ISO C11 in optional
Appendix K defines (v)snwprintf_s() function which has same behavior as
non-wide ISO C11 Appendix K (v)snprintf_s() function (which is secure
variant of (v)snprintf()).

Function (v)snwprintf() is not provided by any MS CRT library and neither
by any MS header file.

mingw32 runtime and mingw-w64 runtime since beginning provide function
named (v)snwprintf (without leading underscore) and define it under symbol
name __mingw_(v)snwprintf. This function differs from ISO C (v)swprintf()
just in return value. ISO C (v)swprintf() when buffer is too small returns
negative value but this (v)snwprintf() returns size of buffer in wide
characters, similarly to non-wide ISO C (v)snprintf() function, and also
similarly to ISO C11 Annex K (v)snwprintf_s(). This non-ISO (v)snwprintf()
and both ISO C (v)snwprintf_s() and (v)snprintf() always fill trailing nul
character.

But when __USE_MINGW_ANSI_STDIO=0 the (v)snwprintf() is redirected to
__ms_(v)snwprintf() function, which is just wrapper around msvcrt
_vsnwprintf() function. And msvcrt _vsnwprintf() function does not fill
trailing nul character and does not return required buffer size when output
buffer is too small.

So fix __ms_(v)snwprintf() functions to properly fill trailing nul
character and return required size of bufer, like ISO C vsnprintf().

Also adjust header files and remove wrong symbol aliases for (v)snwprintf
symbols from def files.

This will make API of (v)snwprintf() function compatible for both
__USE_MINGW_ANSI_STDIO=0 and __USE_MINGW_ANSI_STDIO=1 modes and also to
mimics API of ISO C (v)snwprintf_s() function.
---
 mingw-w64-crt/lib-common/msvcrt.def.in |  5 -----
 mingw-w64-crt/lib32/msvcr120.def.in    |  2 --
 mingw-w64-crt/lib32/msvcr120d.def.in   |  2 --
 mingw-w64-crt/lib64/msvcr120.def.in    |  2 --
 mingw-w64-crt/lib64/msvcr120d.def.in   |  2 --
 mingw-w64-crt/stdio/snwprintf.c        |  2 +-
 mingw-w64-crt/stdio/vsnwprintf.c       | 20 +++++++++++++++++++-
 mingw-w64-headers/crt/stdio.h          | 22 ++++------------------
 mingw-w64-headers/crt/wchar.h          | 21 ++++-----------------
 9 files changed, 28 insertions(+), 50 deletions(-)

diff --git a/mingw-w64-crt/lib-common/msvcrt.def.in 
b/mingw-w64-crt/lib-common/msvcrt.def.in
index aec34d43f64b..ab085571b498 100644
--- a/mingw-w64-crt/lib-common/msvcrt.def.in
+++ b/mingw-w64-crt/lib-common/msvcrt.def.in
@@ -1926,8 +1926,3 @@ F_I386(_libm_sse2_tan_precise)
 #define USE_WCSTOK_S_FOR_WCSTOK
 #endif
 #include "crt-aliases.def.in"
-
-; This is list of additional symbol aliases not available in any CRT library
-; FIXME: check if these really are needed
-snwprintf == _snwprintf
-vsnwprintf == _vsnwprintf
diff --git a/mingw-w64-crt/lib32/msvcr120.def.in 
b/mingw-w64-crt/lib32/msvcr120.def.in
index f390148889d5..e1351c6c2c85 100644
--- a/mingw-w64-crt/lib32/msvcr120.def.in
+++ b/mingw-w64-crt/lib32/msvcr120.def.in
@@ -2233,8 +2233,6 @@ vfwscanf
 vfwscanf_s
 vprintf
 vprintf_s
-snwprintf == _snwprintf
-vsnwprintf == _vsnwprintf
 vscanf
 vscanf_s
 vsprintf
diff --git a/mingw-w64-crt/lib32/msvcr120d.def.in 
b/mingw-w64-crt/lib32/msvcr120d.def.in
index 78ffafba026a..a4f773d67c7b 100644
--- a/mingw-w64-crt/lib32/msvcr120d.def.in
+++ b/mingw-w64-crt/lib32/msvcr120d.def.in
@@ -2300,8 +2300,6 @@ vfwscanf
 vfwscanf_s
 vprintf
 vprintf_s
-snwprintf == _snwprintf
-vsnwprintf == _vsnwprintf
 vscanf
 vscanf_s
 vsprintf
diff --git a/mingw-w64-crt/lib64/msvcr120.def.in 
b/mingw-w64-crt/lib64/msvcr120.def.in
index 9f3f623ea32d..2555d0118032 100644
--- a/mingw-w64-crt/lib64/msvcr120.def.in
+++ b/mingw-w64-crt/lib64/msvcr120.def.in
@@ -1592,8 +1592,6 @@ _vsnprintf_c_l
 _vsnprintf_l
 _vsnprintf_s
 _vsnprintf_s_l
-snwprintf == _snwprintf
-vsnwprintf == _vsnwprintf
 _vsnwprintf
 _vsnwprintf_l
 _vsnwprintf_s
diff --git a/mingw-w64-crt/lib64/msvcr120d.def.in 
b/mingw-w64-crt/lib64/msvcr120d.def.in
index 84318c242e8d..4baf686413c4 100644
--- a/mingw-w64-crt/lib64/msvcr120d.def.in
+++ b/mingw-w64-crt/lib64/msvcr120d.def.in
@@ -1651,8 +1651,6 @@ _vsnprintf_c_l
 _vsnprintf_l
 _vsnprintf_s
 _vsnprintf_s_l
-snwprintf == _snwprintf
-vsnwprintf == _vsnwprintf
 _vsnwprintf
 _vsnwprintf_l
 _vsnwprintf_s
diff --git a/mingw-w64-crt/stdio/snwprintf.c b/mingw-w64-crt/stdio/snwprintf.c
index c57a46d893ce..6abf77a44424 100644
--- a/mingw-w64-crt/stdio/snwprintf.c
+++ b/mingw-w64-crt/stdio/snwprintf.c
@@ -12,7 +12,7 @@ int __cdecl __ms_snwprintf(wchar_t *buffer, size_t n, const 
wchar_t *format, ...
     va_list argptr;
           
     va_start(argptr, format);
-    retval = _vsnwprintf(buffer, n, format, argptr);
+    retval = __ms_vsnwprintf(buffer, n, format, argptr);
     va_end(argptr);
     return retval;
 }
diff --git a/mingw-w64-crt/stdio/vsnwprintf.c b/mingw-w64-crt/stdio/vsnwprintf.c
index b5c5ae65cf74..626889a30499 100644
--- a/mingw-w64-crt/stdio/vsnwprintf.c
+++ b/mingw-w64-crt/stdio/vsnwprintf.c
@@ -12,5 +12,23 @@ int  __cdecl __ms_vsnwprintf(wchar_t *buffer,  size_t n, 
const wchar_t * format,
 
 int  __cdecl __ms_vsnwprintf(wchar_t *buffer,  size_t n, const wchar_t * 
format, va_list argptr)
 {
-    return _vsnwprintf(buffer, n, format, argptr);
+    int retval;
+
+    /* _vsnwprintf() does not work with zero length buffer
+     * so count number of characters by _vscwprintf() call */
+    if (n == 0)
+        return _vscwprintf(format, argptr);
+
+    retval = _vsnwprintf(buffer, n, format, argptr);
+
+    /* _vsnwprintf() does not fill trailing null character if there is not 
place for it */
+    if (retval < 0 || (size_t)retval == n)
+        buffer[n-1] = '\0';
+
+    /* _vsnwprintf() returns negative number if buffer is too small
+     * so count number of characters by _vscwprintf() call */
+    if (retval < 0)
+        retval = _vscwprintf(format, argptr);
+
+    return retval;
 }
diff --git a/mingw-w64-headers/crt/stdio.h b/mingw-w64-headers/crt/stdio.h
index 3934754b01f1..f33009a0f593 100644
--- a/mingw-w64-headers/crt/stdio.h
+++ b/mingw-w64-headers/crt/stdio.h
@@ -1214,7 +1214,7 @@ int vsnwprintf (wchar_t *__stream, size_t __n, const 
wchar_t *__format, __builti
   }
 
   __mingw_ovr
-  int snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, ...)
+  int __cdecl snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, ...)
   {
     __builtin_va_list __ap;
     int __ret;
@@ -1226,8 +1226,7 @@ int vsnwprintf (wchar_t *__stream, size_t __n, const 
wchar_t *__format, __builti
   __mingw_ovr
   int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, va_list arg)
   {
-    int __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, 
s, n, format, NULL, arg);
-    return __ret < 0 ? -1 : __ret;
+    return __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | 
_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, s, n, format, NULL, arg);
   }
 #endif
 
@@ -1266,21 +1265,8 @@ int vsnwprintf (wchar_t *__stream, size_t __n, const 
wchar_t *__format, __builti
 #if __USE_MINGW_ANSI_STDIO == 0
   int __cdecl __ms_snwprintf (wchar_t * __restrict__ s, size_t n, const 
wchar_t * __restrict__ format, ...);
   int __cdecl __ms_vsnwprintf (wchar_t * __restrict__ , size_t, const wchar_t 
* __restrict__ , va_list);
-  __mingw_ovr
-  int snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, ...)
-  {
-    int r;
-    va_list argp;
-    __builtin_va_start (argp, format);
-    r = _vsnwprintf (s, n, format, argp);
-    __builtin_va_end (argp);
-    return r;
-  }
-  __mingw_ovr
-  int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, va_list arg)
-  {
-    return _vsnwprintf(s,n,format,arg);
-  }
+  int __cdecl snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, ...);
+  int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, va_list arg);
 #endif
 
 #endif /* ! __NO_ISOCEXT */
diff --git a/mingw-w64-headers/crt/wchar.h b/mingw-w64-headers/crt/wchar.h
index 25f222e85dcd..6d4555dd2b32 100644
--- a/mingw-w64-headers/crt/wchar.h
+++ b/mingw-w64-headers/crt/wchar.h
@@ -731,12 +731,12 @@ __MINGW_ASM_CALL(__mingw_vsnwprintf);
     __builtin_va_start(__ap, format);
     __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | 
_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, s, n, format, NULL, __ap);
     __builtin_va_end(__ap);
-    return __ret;
+    return __ret < 0 ? -1 : __ret;
   }
   __mingw_ovr
   int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, va_list arg)
   {
-    int __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, 
s, n, format, NULL, arg);
+    int __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | 
_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, s, n, format, NULL, arg);
     return __ret < 0 ? -1 : __ret;
   }
 #endif
@@ -758,21 +758,8 @@ __MINGW_ASM_CALL(__mingw_vsnwprintf);
 # undef vsnwprintf
   int __cdecl __ms_snwprintf (wchar_t * __restrict__ s, size_t n, const 
wchar_t * __restrict__ format, ...);
   int __cdecl __ms_vsnwprintf (wchar_t * __restrict__ , size_t, const wchar_t 
* __restrict__ , va_list);
-  __mingw_ovr
-  int snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, ...)
-  {
-    int r;
-    va_list argp;
-    __builtin_va_start (argp, format);
-    r = _vsnwprintf (s, n, format, argp);
-    __builtin_va_end (argp);
-    return r;
-  }
-  __mingw_ovr
-  int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, va_list arg)
-  {
-    return _vsnwprintf(s,n,format,arg);
-  }
+  int __cdecl snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, ...);
+  int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * 
__restrict__ format, va_list arg);
 #pragma pop_macro ("vsnwprintf")
 #pragma pop_macro ("snwprintf")
 #endif
-- 
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