ucrtbase: Add support for natural string widths.

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2016-08-08 13:43:04 +01:00 committed by Alexandre Julliard
parent fd10b07782
commit 10eb6fa718
2 changed files with 26 additions and 4 deletions

View File

@ -35,7 +35,7 @@ typedef struct FUNC_NAME(pf_flags_t)
APICHAR Sign, LeftAlign, Alternate, PadZero; APICHAR Sign, LeftAlign, Alternate, PadZero;
int FieldLength, Precision; int FieldLength, Precision;
APICHAR IntegerLength, IntegerDouble, IntegerNative; APICHAR IntegerLength, IntegerDouble, IntegerNative;
APICHAR WideString; APICHAR WideString, NaturalString;
APICHAR Format; APICHAR Format;
} FUNC_NAME(pf_flags); } FUNC_NAME(pf_flags);
@ -208,7 +208,8 @@ static inline int FUNC_NAME(pf_output_format_str)(FUNC_NAME(puts_clbk) pf_puts,
static inline int FUNC_NAME(pf_handle_string)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, static inline int FUNC_NAME(pf_handle_string)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx,
const void *str, int len, FUNC_NAME(pf_flags) *flags, MSVCRT_pthreadlocinfo locinfo, BOOL legacy_wide) const void *str, int len, FUNC_NAME(pf_flags) *flags, MSVCRT_pthreadlocinfo locinfo, BOOL legacy_wide)
{ {
BOOL complement_is_narrow = legacy_wide ? (sizeof(APICHAR)==sizeof(MSVCRT_wchar_t)) : FALSE; BOOL api_is_wide = sizeof(APICHAR) == sizeof(MSVCRT_wchar_t);
BOOL complement_is_narrow = legacy_wide ? api_is_wide : FALSE;
#ifdef PRINTF_WIDE #ifdef PRINTF_WIDE
static const MSVCRT_wchar_t nullW[] = {'(','n','u','l','l',')',0}; static const MSVCRT_wchar_t nullW[] = {'(','n','u','l','l',')',0};
@ -219,9 +220,9 @@ static inline int FUNC_NAME(pf_handle_string)(FUNC_NAME(puts_clbk) pf_puts, void
return FUNC_NAME(pf_output_format_str)(pf_puts, puts_ctx, "(null)", 6, flags, locinfo); return FUNC_NAME(pf_output_format_str)(pf_puts, puts_ctx, "(null)", 6, flags, locinfo);
#endif #endif
if(flags->WideString || flags->IntegerLength=='l') if((flags->NaturalString && api_is_wide) || flags->WideString || flags->IntegerLength=='l')
return FUNC_NAME(pf_output_format_wstr)(pf_puts, puts_ctx, str, len, flags, locinfo); return FUNC_NAME(pf_output_format_wstr)(pf_puts, puts_ctx, str, len, flags, locinfo);
if(flags->IntegerLength == 'h') if((flags->NaturalString && !api_is_wide) || flags->IntegerLength == 'h')
return FUNC_NAME(pf_output_format_str)(pf_puts, puts_ctx, str, len, flags, locinfo); return FUNC_NAME(pf_output_format_str)(pf_puts, puts_ctx, str, len, flags, locinfo);
if((flags->Format=='S' || flags->Format=='C') == complement_is_narrow) if((flags->Format=='S' || flags->Format=='C') == complement_is_narrow)
@ -476,6 +477,8 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
#if _MSVCR_VER >= 140 #if _MSVCR_VER >= 140
else if(*p == 'z') else if(*p == 'z')
flags.IntegerNative = *p++; flags.IntegerNative = *p++;
else if(*p == 'T')
flags.NaturalString = *p++;
#endif #endif
else if((*p == 'F' || *p == 'N') && legacy_msvcrt_compat) else if((*p == 'F' || *p == 'N') && legacy_msvcrt_compat)
p++; /* ignore */ p++; /* ignore */

View File

@ -660,6 +660,24 @@ static void test_printf_c99(void)
} }
} }
static void test_printf_natural_string(void)
{
const wchar_t wide[] = {'A','B','C','D',0};
const char narrow[] = "abcd";
const char narrow_fmt[] = "%s %Ts";
const char narrow_out[] = "abcd abcd";
const wchar_t wide_fmt[] = {'%','s',' ','%','T','s',0};
const wchar_t wide_out[] = {'a','b','c','d',' ','A','B','C','D',0};
char buffer[20];
wchar_t wbuffer[20];
vsprintf_wrapper(0, buffer, sizeof(buffer), narrow_fmt, narrow, narrow);
ok(!strcmp(buffer, narrow_out), "buffer wrong, got=%s\n", buffer);
vswprintf_wrapper(0, wbuffer, sizeof(wbuffer), wide_fmt, narrow, wide);
ok(!lstrcmpW(wbuffer, wide_out), "buffer wrong, got=%s\n", wine_dbgstr_w(wbuffer));
}
START_TEST(printf) START_TEST(printf)
{ {
if (!init()) return; if (!init()) return;
@ -674,4 +692,5 @@ START_TEST(printf)
test_printf_legacy_msvcrt(); test_printf_legacy_msvcrt();
test_printf_legacy_three_digit_exp(); test_printf_legacy_three_digit_exp();
test_printf_c99(); test_printf_c99();
test_printf_natural_string();
} }