There are some problems with this patch, please ignore it for now.
Sorry for the noise.

2018-01-14 0:15 GMT+01:00 Gijs Vermeulen <gijsvrm@gmail.com>:
Signed-off-by: Gijs Vermeulen <gijsvrm@gmail.com>
---
������dlls/msvcrt/wcs.c | 436 +++++++++++++++++++++++-------------------------------
������1 file changed, 189 insertions(+), 247 deletions(-)

diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c
index 098e0d5ba8..a6c586eb97 100644
--- a/dlls/msvcrt/wcs.c
+++ b/dlls/msvcrt/wcs.c
@@ -720,22 +720,6 @@ printf_arg arg_clbk_positional(void *ctx, int pos, int type, __ms_va_list *valis
������ ������ ������return args[pos];
������}

-/*********************************************************************
- *������ ������ ������ ������ ������ ������ ������ _vsnprintf (MSVCRT.@)
- */
-int CDECL MSVCRT_vsnprintf( char *str, MSVCRT_size_t len,
-������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ const char *format, __ms_va_list valist )
-{
-������ ������ static const char nullbyte = '\0';
-������ ������ struct _str_ctx_a ctx = {len, str};
-������ ������ int ret;
-
-������ ������ ret = pf_printf_a(puts_clbk_str_a, &ctx, format, NULL, 0,
-������ ������ ������ ������ ������ ������ arg_clbk_valist, NULL, &valist);
-������ ������ puts_clbk_str_a(&ctx, 1, &nullbyte);
-������ ������ return ret;
-}
-
������#if _MSVCR_VER>=140

������static int puts_clbk_str_c99_a(void *ctx, int len, const char *str)
@@ -758,94 +742,69 @@ static int puts_clbk_str_c99_a(void *ctx, int len, const char *str)
������ ������ ������return len;
������}

-/*********************************************************************
- *������ ������ ������ ������ ������ ������ ������ __stdio_common_vsprintf (UCRTBASE.@)
- */
-int CDECL MSVCRT__stdio_common_vsprintf( unsigned __int64 options, char *str, MSVCRT_size_t len, const char *format,
-������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������MSVCRT__locale_t locale, __ms_va_list valist )
+static int puts_clbk_str_c99_w(void *ctx, int len, const MSVCRT_wchar_t *str)
������{
-������ ������ static const char nullbyte = '\0';
-������ ������ struct _str_ctx_a ctx = {len, str};
-������ ������ int ret;
+������ ������ struct _str_ctx_w *out = ctx;

-������ ������ if (options & ~UCRTBASE_PRINTF_MASK)
-������ ������ ������ ������ FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
-������ ������ ret = pf_printf_a(puts_clbk_str_c99_a,
-������ ������ ������ ������ ������ ������ &ctx, format, locale, options & UCRTBASE_PRINTF_MASK, arg_clbk_valist, NULL, &valist);
-������ ������ puts_clbk_str_a(&ctx, 1, &nullbyte);
+������ ������ if(!out->buf)
+������ ������ ������ ������ return len;

-������ ������ if(!str)
-������ ������ ������ ������ return ret;
-������ ������ if(options & UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION)
-������ ������ ������ ������ return ret>len ? -1 : ret;
-������ ������ if(ret>=len) {
-������ ������ ������ ������ if(len) str[len-1] = 0;
-������ ������ ������ ������ return (options & UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR) ? ret : -2;
+������ ������ if(out->len < len) {
+������ ������ ������ ������ memcpy(out->buf, str, out->len*sizeof(MSVCRT_wchar_t));
+������ ������ ������ ������ out->buf += out->len;
+������ ������ ������ ������ out->len = 0;
+������ ������ ������ ������ return len;
������ ������ ������}
-������ ������ return ret;
-}
-
-#endif /* _MSVCR_VER>=140 */
-
-/*********************************************************************
- *������ ������ ������ ������ ������ ������ ������_vsnprintf_l (MSVCRT.@)
- */
-int CDECL MSVCRT_vsnprintf_l( char *str, MSVCRT_size_t len, const char *format,
-������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ MSVCRT__locale_t locale, __ms_va_list valist )
-{
-������ ������ static const char nullbyte = '\0';
-������ ������ struct _str_ctx_a ctx = {len, str};
-������ ������ int ret;

-������ ������ ret = pf_printf_a(puts_clbk_str_a, &ctx, format, locale, 0,
-������ ������ ������ ������ ������ ������ arg_clbk_valist, NULL, &valist);
-������ ������ puts_clbk_str_a(&ctx, 1, &nullbyte);
-������ ������ return ret;
-}
-
-/*********************************************************************
- *������ ������ ������ ������ ������ ������ ������_vsprintf_l (MSVCRT.@)
- */
-int CDECL MSVCRT_vsprintf_l( char *str, const char *format,
-������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ MSVCRT__locale_t locale, __ms_va_list valist )
-{
-������ ������ return MSVCRT_vsnprintf_l(str, INT_MAX, format, locale, valist);
+������ ������ memcpy(out->buf, str, len*sizeof(MSVCRT_wchar_t));
+������ ������ out->buf += len;
+������ ������ out->len -= len;
+������ ������ return len;
������}

-/*********************************************************************
- *������ ������ ������ ������ ������ ������ ������_sprintf_l (MSVCRT.@)
- */
-int WINAPIV MSVCRT_sprintf_l(char *str, const char *format,
-������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������MSVCRT__locale_t locale, ...)
-{
-������ ������ int retval;
-������ ������ __ms_va_list valist;
-������ ������ __ms_va_start(valist, locale);
-������ ������ retval = MSVCRT_vsnprintf_l(str, INT_MAX, format, locale, valist);
-������ ������ __ms_va_end(valist);
-������ ������ return retval;
-}
+#endif /* _MSVCR_VER>=140 */

-static int CDECL MSVCRT_vsnprintf_s_l_opt( char *str, MSVCRT_size_t sizeOfBuffer,
-������ ������ ������ ������ MSVCRT_size_t count, const char *format, DWORD options,
-������ ������ ������ ������ MSVCRT__locale_t locale, __ms_va_list valist )
+static int vsprintf_helper(DWORD options, char *str, MSVCRT_size_t sizeOfBuffer, MSVCRT_size_t count,
+������ ������ ������ ������ const char *format, MSVCRT__locale_t locale, __ms_va_list valist)
������{
������ ������ ������static const char nullbyte = '\0';
-������ ������ struct _str_ctx_a ctx;
+������ ������ printf_arg args_ctx[MSVCRT__ARGMAX+1];
+������ ������ struct _str_ctx_a puts_ctx;
������ ������ ������int len, ret;
+������ ������ BOOL postional, secure, c99, initially_positional;

-������ ������ if(sizeOfBuffer<count+1 || count==-1)
-������ ������ ������ ������ len = sizeOfBuffer;
-������ ������ else
-������ ������ ������ ������ len = count+1;
+������ ������ len = sizeOfBuffer;
+������ ������ postional = options & MSVCRT_PRINTF_POSITIONAL_PARAMS;
+������ ������ initially_positional = postional;
+������ ������ secure = options & MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER;
+������ ������ c99 = (options & UCRTBASE_PRINTF_MASK) && !secure;
+
+������ ������ if(secure && !postional)
+������ ������ ������ ������ if(sizeOfBuffer>count+1 && count!=-1) len = count+1;
+
+������ ������ puts_ctx.len = len;
+������ ������ puts_ctx.buf = str;
+
+������ ������ if(postional) {
+������ ������ ������ ������ memset(args_ctx, 0, sizeof(args_ctx));
+
+������ ������ ������ ������ ret = create_positional_ctx_a(args_ctx, format, valist);
+������ ������ ������ ������ if(ret < 0) {
+������ ������ ������ ������ ������ ������ MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
+������ ������ ������ ������ ������ ������ *MSVCRT__errno() = MSVCRT_EINVAL;
+������ ������ ������ ������ ������ ������ return ret;
+������ ������ ������ ������ } else if(!ret)
+������ ������ ������ ������ ������ ������ postional = FALSE;
+������ ������ }

-������ ������ ctx.len = len;
-������ ������ ctx.buf = str;
-������ ������ ret = pf_printf_a(puts_clbk_str_a, &ctx, format, locale, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
-������ ������ ������ ������ ������ ������ arg_clbk_valist, NULL, &valist);
-������ ������ puts_clbk_str_a(&ctx, 1, &nullbyte);
+������ ������ ret = pf_printf_a(c99 ? puts_clbk_str_c99_a : puts_clbk_str_a,
+������ ������ ������ ������ ������ ������ &puts_ctx, format, locale, options,
+������ ������ ������ ������ ������ ������ postional ? arg_clbk_positional : arg_clbk_valist,
+������ ������ ������ ������ ������ ������ postional ? args_ctx : NULL,
+������ ������ ������ ������ ������ ������ postional ? NULL : &valist);
+������ ������ puts_clbk_str_a(&puts_ctx, 1, &nullbyte);

-������ ������ if(ret<0 || ret==len) {
+������ ������ if((secure && !initially_positional) && (ret<0 || ret==len)) {
������ ������ ������ ������ ������if(count!=MSVCRT__TRUNCATE && count>sizeOfBuffer) {
������ ������ ������ ������ ������ ������ ������MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE);
������ ������ ������ ������ ������ ������ ������memset(str, 0, sizeOfBuffer);
@@ -855,28 +814,61 @@ static int CDECL MSVCRT_vsnprintf_s_l_opt( char *str, MSVCRT_size_t sizeOfBuffer
������ ������ ������ ������ ������return -1;
������ ������ ������}

+������ ������ if(c99){
+������ ������ ������ ������ if(!str)
+������ ������ ������ ������ ������ ������ return ret;
+������ ������ ������ ������ if(options & UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION)
+������ ������ ������ ������ ������ ������ return ret>len ? -1 : ret;
+������ ������ ������ ������ if(ret>=len) {
+������ ������ ������ ������ ������ ������ if(len) str[len-1] = 0;
+������ ������ ������ ������ ������ ������ return (options & UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR) ? ret : -2;
+������ ������ ������ ������ }
+������ ������ }
+
������ ������ ������return ret;
������}

-static int MSVCRT_vsnwprintf_s_l_opt( MSVCRT_wchar_t *str, MSVCRT_size_t sizeOfBuffer,
-������ ������ ������ ������ MSVCRT_size_t count, const MSVCRT_wchar_t *format, DWORD options,
-������ ������ ������ ������ MSVCRT__locale_t locale, __ms_va_list valist)
+static int vswprintf_helper(DWORD options, MSVCRT_wchar_t *str, MSVCRT_size_t sizeOfBuffer, MSVCRT_size_t count,
+������ ������ ������ ������ const MSVCRT_wchar_t *format, MSVCRT__locale_t locale, __ms_va_list valist)
������{
-������ ������ static const MSVCRT_wchar_t nullbyte = '\0';
-������ ������ struct _str_ctx_w ctx;
+������ ������ static const char nullbyte = '\0';
+������ ������ printf_arg args_ctx[MSVCRT__ARGMAX+1];
+������ ������ struct _str_ctx_w puts_ctx;
������ ������ ������int len, ret;
+������ ������ BOOL postional, secure, c99, initially_positional;

������ ������ ������len = sizeOfBuffer;
-������ ������ if(count!=-1 && len>count+1)
-������ ������ ������ ������ len = count+1;
+������ ������ postional = options & MSVCRT_PRINTF_POSITIONAL_PARAMS;
+������ ������ initially_positional = postional;
+������ ������ secure = options & MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER;
+������ ������ c99 = (options & UCRTBASE_PRINTF_MASK) && !secure;
+
+������ ������ if(secure && !postional)
+������ ������ ������ ������ if(sizeOfBuffer>count+1 && count!=-1) len = count+1;
+
+������ ������ puts_ctx.len = len;
+������ ������ puts_ctx.buf = str;
+
+������ ������ if(postional) {
+������ ������ ������ ������ memset(args_ctx, 0, sizeof(args_ctx));
+
+������ ������ ������ ������ ret = create_positional_ctx_w(args_ctx, format, valist);
+������ ������ ������ ������ if(ret < 0) {
+������ ������ ������ ������ ������ ������ MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
+������ ������ ������ ������ ������ ������ *MSVCRT__errno() = MSVCRT_EINVAL;
+������ ������ ������ ������ ������ ������ return ret;
+������ ������ ������ ������ } else if(!ret)
+������ ������ ������ ������ ������ ������ postional = FALSE;
+������ ������ }

-������ ������ ctx.len = len;
-������ ������ ctx.buf = str;
-������ ������ ret = pf_printf_w(puts_clbk_str_w, &ctx, format, locale, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
-������ ������ ������ ������ ������ ������ arg_clbk_valist, NULL, &valist);
-������ ������ puts_clbk_str_w(&ctx, 1, &nullbyte);
+������ ������ ret = pf_printf_w(c99 ? puts_clbk_str_c99_w : puts_clbk_str_w,
+������ ������ ������ ������ ������ ������ &puts_ctx, format, locale, options,
+������ ������ ������ ������ ������ ������ postional ? arg_clbk_positional : arg_clbk_valist,
+������ ������ ������ ������ ������ ������ postional ? args_ctx : NULL,
+������ ������ ������ ������ ������ ������ postional ? NULL : &valist);
+������ ������ puts_clbk_str_w(&puts_ctx, 1, &nullbyte);

-������ ������ if(ret<0 || ret==len) {
+������ ������ if((secure && !initially_positional) && (ret<0 || ret==len)) {
������ ������ ������ ������ ������if(count!=MSVCRT__TRUNCATE && count>sizeOfBuffer) {
������ ������ ������ ������ ������ ������ ������MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE);
������ ������ ������ ������ ������ ������ ������memset(str, 0, sizeOfBuffer*sizeof(MSVCRT_wchar_t));
@@ -886,9 +878,76 @@ static int MSVCRT_vsnwprintf_s_l_opt( MSVCRT_wchar_t *str, MSVCRT_size_t sizeOfB
������ ������ ������ ������ ������return -1;
������ ������ ������}

+������ ������ if(c99){
+������ ������ ������ ������ if(!str)
+������ ������ ������ ������ ������ ������ return ret;
+������ ������ ������ ������ if(options & UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION)
+������ ������ ������ ������ ������ ������ return ret>len ? -1 : ret;
+������ ������ ������ ������ if(ret>=len) {
+������ ������ ������ ������ ������ ������ if(len) str[len-1] = 0;
+������ ������ ������ ������ ������ ������ return (options & UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR) ? ret : -2;
+������ ������ ������ ������ }
+������ ������ }
+
������ ������ ������return ret;
������}

+/*********************************************************************
+ *������ ������ ������ ������ ������ ������ ������ _vsnprintf (MSVCRT.@)
+ */
+int CDECL MSVCRT_vsnprintf( char *str, MSVCRT_size_t len,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ const char *format, __ms_va_list valist )
+{
+������ ������ return vsprintf_helper(0, str, len, 0, format, NULL, valist);
+}
+
+#if _MSVCR_VER>=140
+
+/*********************************************************************
+ *������ ������ ������ ������ ������ ������ ������ __stdio_common_vsprintf (UCRTBASE.@)
+ */
+int CDECL MSVCRT__stdio_common_vsprintf( unsigned __int64 options, char *str, MSVCRT_size_t len, const char *format,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������MSVCRT__locale_t locale, __ms_va_list valist )
+{
+������ ������ if (options & ~UCRTBASE_PRINTF_MASK)
+������ ������ ������ ������ FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
+������ ������ return vsprintf_helper(options & UCRTBASE_PRINTF_MASK, str, len, 0, format, locale, valist);
+}
+
+#endif /* _MSVCR_VER>=140 */
+
+/*********************************************************************
+ *������ ������ ������ ������ ������ ������ ������_vsnprintf_l (MSVCRT.@)
+ */
+int CDECL MSVCRT_vsnprintf_l( char *str, MSVCRT_size_t len, const char *format,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ MSVCRT__locale_t locale, __ms_va_list valist )
+{
+������ ������ return vsprintf_helper(0, str, len, format, locale, valist);
+}
+
+/*********************************************************************
+ *������ ������ ������ ������ ������ ������ ������_vsprintf_l (MSVCRT.@)
+ */
+int CDECL MSVCRT_vsprintf_l( char *str, const char *format,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ MSVCRT__locale_t locale, __ms_va_list valist )
+{
+������ ������ return MSVCRT_vsnprintf_l(str, INT_MAX, format, locale, valist);
+}
+
+/*********************************************************************
+ *������ ������ ������ ������ ������ ������ ������_sprintf_l (MSVCRT.@)
+ */
+int WINAPIV MSVCRT_sprintf_l(char *str, const char *format,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������MSVCRT__locale_t locale, ...)
+{
+������ ������ int retval;
+������ ������ __ms_va_list valist;
+������ ������ __ms_va_start(valist, locale);
+������ ������ retval = MSVCRT_vsnprintf_l(str, INT_MAX, format, locale, valist);
+������ ������ __ms_va_end(valist);
+������ ������ return retval;
+}
+
������/*********************************************************************
������ *������ ������ ������ ������ ������ ������ ������_vsnprintf_s_l (MSVCRT.@)
������ */
@@ -896,7 +955,8 @@ int CDECL MSVCRT_vsnprintf_s_l( char *str, MSVCRT_size_t sizeOfBuffer,
������ ������ ������ ������ ������MSVCRT_size_t count, const char *format,
������ ������ ������ ������ ������MSVCRT__locale_t locale, __ms_va_list valist )
������{
-������ ������ return MSVCRT_vsnprintf_s_l_opt(str, sizeOfBuffer, count, format, 0, locale, valist);
+������ ������ return vsprintf_helper(MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, str, sizeOfBuffer, count, format,
+������ ������ ������ ������ ������ ������ locale, valist);
������}

������/*********************************************************************
@@ -942,7 +1002,8 @@ int CDECL MSVCRT__stdio_common_vsnprintf_s( unsigned __int64 options,
������{
������ ������ ������if (options & ~UCRTBASE_PRINTF_MASK)
������ ������ ������ ������ ������FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
-������ ������ return MSVCRT_vsnprintf_s_l_opt(str, sizeOfBuffer, count, format, options & UCRTBASE_PRINTF_MASK, locale, valist);
+������ ������ return vsprintf_helper((options & UCRTBASE_PRINTF_MASK) | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, str,
+������ ������ ������ ������ ������ ������ sizeOfBuffer, count, format, locale, valist);
������}

������/*********************************************************************
@@ -954,7 +1015,8 @@ int CDECL MSVCRT__stdio_common_vsnwprintf_s( unsigned __int64 options,
������{
������ ������ ������if (options & ~UCRTBASE_PRINTF_MASK)
������ ������ ������ ������ ������FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
-������ ������ return MSVCRT_vsnwprintf_s_l_opt(str, sizeOfBuffer, count, format, options & UCRTBASE_PRINTF_MASK, locale, valist);
+������ ������ return vswprintf_helper((options & UCRTBASE_PRINTF_MASK) | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, str,
+������ ������ ������ ������ ������ ������ sizeOfBuffer, count, format, locale, valist);
������}

������/*********************************************************************
@@ -974,9 +1036,7 @@ int CDECL MSVCRT__stdio_common_vsprintf_s( unsigned __int64 options,
������ ������ ������ ������ ������char *str, MSVCRT_size_t count, const char *format,
������ ������ ������ ������ ������MSVCRT__locale_t locale, __ms_va_list valist )
������{
-������ ������ if (options & ~UCRTBASE_PRINTF_MASK)
-������ ������ ������ ������ FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
-������ ������ return MSVCRT_vsnprintf_s_l_opt(str, INT_MAX, count, format, options & UCRTBASE_PRINTF_MASK, locale, valist);
+������ ������ return MSVCRT__stdio_common_vsnprintf_s(options, str, INT_MAX, count, format, locale, valist);
������}

������#endif /* _MSVCR_VER>=140 */
@@ -1011,28 +1071,8 @@ int CDECL MSVCRT__vscprintf( const char *format, __ms_va_list valist )
������int CDECL MSVCRT__vscprintf_p_l(const char *format,
������ ������ ������ ������ ������MSVCRT__locale_t locale, __ms_va_list args)
������{
-������ ������ printf_arg args_ctx[MSVCRT__ARGMAX+1];
-������ ������ struct _str_ctx_a puts_ctx = {INT_MAX, NULL};
-������ ������ int ret;
-
-������ ������ memset(args_ctx, 0, sizeof(args_ctx));
-
-������ ������ ret = create_positional_ctx_a(args_ctx, format, args);
-������ ������ if(ret < 0)������ {
-������ ������ ������ ������ MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
-������ ������ ������ ������ *MSVCRT__errno() = MSVCRT_EINVAL;
-������ ������ ������ ������ return ret;
-������ ������ } else if(ret == 0) {
-������ ������ ������ ������ ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale,
-������ ������ ������ ������ ������ ������ ������ ������ MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER,
-������ ������ ������ ������ ������ ������ ������ ������ arg_clbk_valist, NULL, &args);
-������ ������ } else {
-������ ������ ������ ������ ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale,
-������ ������ ������ ������ ������ ������ ������ ������ MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER,
-������ ������ ������ ������ ������ ������ ������ ������ arg_clbk_positional, args_ctx, NULL);
-������ ������ }
-
-������ ������ return ret;
+������ ������ return vsprintf_helper(MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER,
+������ ������ ������ ������ ������ ������ NULL, INT_MAX, 0, format, locale, args);
������}

������/*********************************************************************
@@ -1103,14 +1143,7 @@ int WINAPIV MSVCRT__scprintf(const char *format, ...)
������int CDECL MSVCRT_vsnwprintf(MSVCRT_wchar_t *str, MSVCRT_size_t len,
������ ������ ������ ������ ������const MSVCRT_wchar_t *format, __ms_va_list valist)
������{
-������ ������ static const MSVCRT_wchar_t nullbyte = '\0';
-������ ������ struct _str_ctx_w ctx = {len, str};
-������ ������ int ret;
-
-������ ������ ret = pf_printf_w(puts_clbk_str_w, &ctx, format, NULL, 0,
-������ ������ ������ ������ ������ ������ arg_clbk_valist, NULL, &valist);
-������ ������ puts_clbk_str_w(&ctx, 1, &nullbyte);
-������ ������ return ret;
+������ ������ return vswprintf_helper(0, str, len, 0, format, NULL, valist);
������}

������/*********************************************************************
@@ -1120,41 +1153,7 @@ int CDECL MSVCRT_vsnwprintf_l(MSVCRT_wchar_t *str, MSVCRT_size_t len,
������ ������ ������ ������ ������const MSVCRT_wchar_t *format, MSVCRT__locale_t locale,
������ ������ ������ ������ ������__ms_va_list valist)
������{
-������ ������ static const MSVCRT_wchar_t nullbyte = '\0';
-������ ������ struct _str_ctx_w ctx = {len, str};
-������ ������ int ret;
-
-������ ������ ret = pf_printf_w(puts_clbk_str_w, &ctx, format, locale, 0,
-������ ������ ������ ������ ������ ������ arg_clbk_valist, NULL, &valist);
-������ ������ puts_clbk_str_w(&ctx, 1, &nullbyte);
-������ ������ return ret;
-}
-
-static int MSVCRT_vswprintf_p_l_opt(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
-������ ������ ������ ������ const MSVCRT_wchar_t *format, DWORD options, MSVCRT__locale_t locale, __ms_va_list args)
-{
-������ ������ static const MSVCRT_wchar_t nullbyte = '\0';
-������ ������ printf_arg args_ctx[MSVCRT__ARGMAX+1];
-������ ������ struct _str_ctx_w puts_ctx = {length, buffer};
-������ ������ int ret;
-
-������ ������ memset(args_ctx, 0, sizeof(args_ctx));
-
-������ ������ ret = create_positional_ctx_w(args_ctx, format, args);
-������ ������ if(ret < 0)������ {
-������ ������ ������ ������ MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
-������ ������ ������ ������ *MSVCRT__errno() = MSVCRT_EINVAL;
-������ ������ ������ ������ return ret;
-������ ������ } else if(ret == 0)
-������ ������ ������ ������ ret = pf_printf_w(puts_clbk_str_w, &puts_ctx, format, locale, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
-������ ������ ������ ������ ������ ������ ������ ������ arg_clbk_valist, NULL, &args);
-������ ������ else
-������ ������ ������ ������ ret = pf_printf_w(puts_clbk_str_w, &puts_ctx, format, locale,
-������ ������ ������ ������ ������ ������ ������ ������ MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
-������ ������ ������ ������ ������ ������ ������ ������ arg_clbk_positional, args_ctx, NULL);
-
-������ ������ puts_clbk_str_w(&puts_ctx, 1, &nullbyte);
-������ ������ return ret;
+������ ������ return vswprintf_helper(0, str, len, 0, format, locale, valist);
������}

������/*********************************************************************
@@ -1163,7 +1162,8 @@ static int MSVCRT_vswprintf_p_l_opt(MSVCRT_wchar_t *buffer, MSVCRT_size_t length
������int CDECL MSVCRT_vswprintf_p_l(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
������ ������ ������ ������ ������const MSVCRT_wchar_t *format, MSVCRT__locale_t locale, __ms_va_list args)
������{
-������ ������ return MSVCRT_vswprintf_p_l_opt(buffer, length, format, 0, locale, args);
+������ ������ return vswprintf_helper(MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER,
+������ ������ ������ ������ ������ ������ buffer, length, 0, format, locale, args);
������}

������#if _MSVCR_VER>=80
@@ -1173,7 +1173,7 @@ int CDECL MSVCRT_vswprintf_p_l(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
������int CDECL MSVCRT__vswprintf_p(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
������ ������ ������ ������ ������const MSVCRT_wchar_t *format, __ms_va_list args)
������{
-������ ������ return MSVCRT_vswprintf_p_l_opt(buffer, length, format, 0, NULL, args);
+������ ������ return MSVCRT_vswprintf_p_l(buffer, length, format, NULL, args);
������}
������#endif

@@ -1187,7 +1187,8 @@ int CDECL MSVCRT__stdio_common_vswprintf_p( unsigned __int64 options,
������{
������ ������ ������if (options & ~UCRTBASE_PRINTF_MASK)
������ ������ ������ ������ ������FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
-������ ������ return MSVCRT_vswprintf_p_l_opt(str, count, format, options & UCRTBASE_PRINTF_MASK, locale, valist);
+������ ������ return vswprintf_helper((options & UCRTBASE_PRINTF_MASK) | (MSVCRT_PRINTF_POSITIONAL_PARAMS |
+������ ������ ������ ������ ������ ������ MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER), str, count, 0, format, locale, valist);
������}
������#endif

@@ -1198,7 +1199,8 @@ int CDECL MSVCRT_vsnwprintf_s_l( MSVCRT_wchar_t *str, MSVCRT_size_t sizeOfBuffer
������ ������ ������ ������ ������MSVCRT_size_t count, const MSVCRT_wchar_t *format,
������ ������ ������ ������ ������MSVCRT__locale_t locale, __ms_va_list valist)
������{
-������ ������ return MSVCRT_vsnwprintf_s_l_opt(str, sizeOfBuffer, count, format, 0, locale, valist);
+������ ������ return vswprintf_helper(MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, str, sizeOfBuffer, count, format,
+������ ������ ������ ������ ������ ������ locale, valist);
������}

������/*********************************************************************
@@ -1268,26 +1270,6 @@ int WINAPIV MSVCRT__snwprintf_s_l( MSVCRT_wchar_t *str, unsigned int len, unsign

������#if _MSVCR_VER>=140

-static int puts_clbk_str_c99_w(void *ctx, int len, const MSVCRT_wchar_t *str)
-{
-������ ������ struct _str_ctx_w *out = ctx;
-
-������ ������ if(!out->buf)
-������ ������ ������ ������ return len;
-
-������ ������ if(out->len < len) {
-������ ������ ������ ������ memcpy(out->buf, str, out->len*sizeof(MSVCRT_wchar_t));
-������ ������ ������ ������ out->buf += out->len;
-������ ������ ������ ������ out->len = 0;
-������ ������ ������ ������ return len;
-������ ������ }
-
-������ ������ memcpy(out->buf, str, len*sizeof(MSVCRT_wchar_t));
-������ ������ out->buf += len;
-������ ������ out->len -= len;
-������ ������ return len;
-}
-
������/*********************************************************************
������ *������ ������ ������ ������ ������ ������ ������ __stdio_common_vswprintf (UCRTBASE.@)
������ */
@@ -1295,25 +1277,9 @@ int CDECL MSVCRT__stdio_common_vswprintf( unsigned __int64 options,
������ ������ ������ ������ ������MSVCRT_wchar_t *str, MSVCRT_size_t len, const MSVCRT_wchar_t *format,
������ ������ ������ ������ ������MSVCRT__locale_t locale, __ms_va_list valist )
������{
-������ ������ static const MSVCRT_wchar_t nullbyte = '\0';
-������ ������ struct _str_ctx_w ctx = {len, str};
-������ ������ int ret;
-
������ ������ ������if (options & ~UCRTBASE_PRINTF_MASK)
������ ������ ������ ������ ������FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
-������ ������ ret = pf_printf_w(puts_clbk_str_c99_w,
-������ ������ ������ ������ ������ ������ &ctx, format, locale, options & UCRTBASE_PRINTF_MASK, arg_clbk_valist, NULL, &valist);
-������ ������ puts_clbk_str_w(&ctx, 1, &nullbyte);
-
-������ ������ if(!str)
-������ ������ ������ ������ return ret;
-������ ������ if(options & UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION)
-������ ������ ������ ������ return ret>len ? -1 : ret;
-������ ������ if(ret>=len) {
-������ ������ ������ ������ if(len) str[len-1] = 0;
-������ ������ ������ ������ return (options & UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR) ? ret : -2;
-������ ������ }
-������ ������ return ret;
+������ ������ return vswprintf_helper(options & UCRTBASE_PRINTF_MASK, str, len, 0, format, locale, valist);
������}

������#endif /* _MSVCR_VER>=140 */
@@ -1444,7 +1410,8 @@ int CDECL MSVCRT__vscwprintf_l( const MSVCRT_wchar_t *format, MSVCRT__locale_t l
������ */
������int CDECL MSVCRT__vscwprintf_p_l( const MSVCRT_wchar_t *format, MSVCRT__locale_t locale, __ms_va_list args )
������{
-������ ������ return MSVCRT_vswprintf_p_l_opt( NULL, INT_MAX, format, 0, locale, args );
+������ ������ return vswprintf_helper(MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, NULL, INT_MAX,
+������ ������ ������ ������ ������ ������ 0, format, locale, args);
������}

������#if _MSVCR_VER>=80
@@ -1453,7 +1420,7 @@ int CDECL MSVCRT__vscwprintf_p_l( const MSVCRT_wchar_t *format, MSVCRT__locale_t
������ */
������int CDECL MSVCRT__vscwprintf_p(const MSVCRT_wchar_t *format, __ms_va_list args)
������{
-������ ������ return MSVCRT_vswprintf_p_l_opt(NULL, INT_MAX, format, 0, NULL, args);
+������ ������ return MSVCRT__vscwprintf_p_l(NULL, INT_MAX, format, 0, NULL, args);
������}
������#endif

@@ -1476,40 +1443,14 @@ int CDECL MSVCRT_vswprintf_s_l(MSVCRT_wchar_t* str, MSVCRT_size_t numberOfElemen
������ ������ ������ ������ ������ ������ ������format, locale, args );
������}

-static int MSVCRT_vsprintf_p_l_opt(char *buffer, MSVCRT_size_t length, const char *format,
-������ ������ ������ ������ DWORD options, MSVCRT__locale_t locale, __ms_va_list args)
-{
-������ ������ static const char nullbyte = '\0';
-������ ������ printf_arg args_ctx[MSVCRT__ARGMAX+1];
-������ ������ struct _str_ctx_a puts_ctx = {length, buffer};
-������ ������ int ret;
-
-������ ������ memset(args_ctx, 0, sizeof(args_ctx));
-
-������ ������ ret = create_positional_ctx_a(args_ctx, format, args);
-������ ������ if(ret < 0) {
-������ ������ ������ ������ MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
-������ ������ ������ ������ *MSVCRT__errno() = MSVCRT_EINVAL;
-������ ������ ������ ������ return ret;
-������ ������ } else if(ret == 0)
-������ ������ ������ ������ ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale,
-������ ������ ������ ������ ������ ������ ������ ������ MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options, arg_clbk_valist, NULL, &args);
-������ ������ else
-������ ������ ������ ������ ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale,
-������ ������ ������ ������ ������ ������ ������ ������ MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER | options,
-������ ������ ������ ������ ������ ������ ������ ������ arg_clbk_positional, args_ctx, NULL);
-
-������ ������ puts_clbk_str_a(&puts_ctx, 1, &nullbyte);
-������ ������ return ret;
-}
-
������/*********************************************************************
������ *������ ������ ������ ������ ������ ������ ������ _vsprintf_p_l (MSVCRT.@)
������ */
������int CDECL MSVCRT_vsprintf_p_l(char *buffer, MSVCRT_size_t length, const char *format,
������ ������ ������ ������ ������MSVCRT__locale_t locale, __ms_va_list args)
������{
-������ ������ return MSVCRT_vsprintf_p_l_opt(buffer, length, format, 0, locale, args);
+������ ������ return vsprintf_helper(MSVCRT_PRINTF_POSITIONAL_PARAMS | MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER, buffer, length,
+������ ������ ������ ������ 0, format, locale, args);
������}

������/*********************************************************************
@@ -1530,7 +1471,8 @@ int CDECL MSVCRT__stdio_common_vsprintf_p(unsigned __int64 options, char *buffer
������{
������ ������ ������if (options & ~UCRTBASE_PRINTF_MASK)
������ ������ ������ ������ ������FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
-������ ������ return MSVCRT_vsprintf_p_l_opt(buffer, length, format, options & UCRTBASE_PRINTF_MASK, locale, args);
+������ ������ return vsprintf_helper((options & UCRTBASE_PRINTF_MASK) | (MSVCRT_PRINTF_POSITIONAL_PARAMS |
+������ ������ ������ ������ ������ ������ MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER), buffer, length, 0, format, locale, args);
������}
������#endif

@@ -1591,7 +1533,7 @@ int WINAPIV MSVCRT_swprintf_p_l(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
������ ������ ������int r;

������ ������ ������__ms_va_start(valist, locale);
-������ ������ r = MSVCRT_vswprintf_p_l_opt(buffer, length, format, 0, locale, valist);
+������ ������ r = MSVCRT_vswprintf_p_l(buffer, length, format, locale, valist);
������ ������ ������__ms_va_end(valist);

������ ������ ������return r;
--
2.15.1