On Mon, 2 Nov 2015, Piotr Caban wrote:
Hi,
I don't like the code I've proposed in last email. Something like this seems to be nicer: static int puts_clbk_str_c99_a(void *ctx, int len, const char *str) { struct _str_ctx_a *out = ctx;
if(!out->buf) return len;
if(out->len < len) { memcpy(out->buf, str, out->len); out->buf += out->len; out->len = 0; return len; }
memcpy(out->buf, str, len); out->buf += len; out->len -= len; return len; }
/*********************************************************************
__stdio_common_vsprintf (MSVCRT.@)
*/ 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 const char nullbyte = '\0'; struct _str_ctx_a ctx = {len, str}; int ret;
if (options & ~UCRTBASE_PRINTF_TERMINATION_MASK) FIXME("options %s not handled\n", wine_dbgstr_longlong(options)); ret = pf_printf_a(puts_clbk_str_c99_a, &ctx, format, locale, FALSE, FALSE, arg_clbk_valist, NULL, &valist); puts_clbk_str_a(&ctx, 1, &nullbyte);
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; } if you think that your initial code is better please let me know.
No, this feels like the most straightforward and explicit way of implementing it so far - thanks!
Probably in this code UCRTBASE_PRINTF_TERMINATION_MASK define is not needed.
I'd keep it here (as condition for the fixme warning - alternatively add "|| options == 0" to the condition), but remove it once that warning is removed in a later patch.
// Martin