ucrtbase: Add __stdio_common_vfwprintf.

Signed-off-by: Daniel Lehman <dlehman@esri.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Daniel Lehman 2016-04-06 15:56:43 -07:00 committed by Alexandre Julliard
parent f0dd5a012d
commit 2f783c6828
4 changed files with 187 additions and 2 deletions

View File

@ -5,7 +5,7 @@
@ stub __stdio_common_vfprintf_p @ stub __stdio_common_vfprintf_p
@ stub __stdio_common_vfprintf_s @ stub __stdio_common_vfprintf_s
@ stub __stdio_common_vfscanf @ stub __stdio_common_vfscanf
@ stub __stdio_common_vfwprintf @ cdecl __stdio_common_vfwprintf(int64 ptr ptr ptr ptr) ucrtbase.__stdio_common_vfwprintf
@ stub __stdio_common_vfwprintf_p @ stub __stdio_common_vfwprintf_p
@ stub __stdio_common_vfwprintf_s @ stub __stdio_common_vfwprintf_s
@ stub __stdio_common_vfwscanf @ stub __stdio_common_vfwscanf

View File

@ -5099,6 +5099,34 @@ int CDECL MSVCRT__stdio_common_vfprintf(unsigned __int64 options, MSVCRT_FILE *f
return ret; return ret;
} }
/*********************************************************************
* __stdio_common_vfwprintf (MSVCRT.@)
*/
int CDECL MSVCRT__stdio_common_vfwprintf(unsigned __int64 options, MSVCRT_FILE *file, const MSVCRT_wchar_t *format,
MSVCRT__locale_t locale, __ms_va_list valist)
{
BOOL tmp_buf;
int ret;
if (!MSVCRT_CHECK_PMT( file != NULL )) return -1;
if (!MSVCRT_CHECK_PMT( format != NULL )) return -1;
MSVCRT__lock_file(file);
tmp_buf = add_std_buffer(file);
if (options & ~UCRTBASE_PRINTF_MASK)
FIXME("options %s not handled\n", wine_dbgstr_longlong(options));
ret = pf_printf_w(puts_clbk_file_w, file, format, locale,
options & UCRTBASE_PRINTF_MASK, arg_clbk_valist, NULL, &valist);
if(tmp_buf) remove_std_buffer(file);
MSVCRT__unlock_file(file);
return ret;
}
/********************************************************************* /*********************************************************************
* _vfwprintf_l (MSVCRT.@) * _vfwprintf_l (MSVCRT.@)
*/ */

View File

@ -30,6 +30,36 @@
#include "wine/test.h" #include "wine/test.h"
#define DEFINE_EXPECT(func) \
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
#define SET_EXPECT(func) \
expect_ ## func = TRUE
#define CHECK_EXPECT2(func) \
do { \
ok(expect_ ##func, "unexpected call " #func "\n"); \
called_ ## func = TRUE; \
}while(0)
#define CHECK_EXPECT(func) \
do { \
CHECK_EXPECT2(func); \
expect_ ## func = FALSE; \
}while(0)
#define CHECK_CALLED(func) \
do { \
ok(called_ ## func, "expected " #func "\n"); \
expect_ ## func = called_ ## func = FALSE; \
}while(0)
DEFINE_EXPECT(invalid_parameter_handler);
/* make sure we use the correct errno */
#undef errno
#define errno (*p_errno())
#define UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION (0x0001) #define UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION (0x0001)
#define UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR (0x0002) #define UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR (0x0002)
#define UCRTBASE_PRINTF_LEGACY_WIDE_SPECIFIERS (0x0004) #define UCRTBASE_PRINTF_LEGACY_WIDE_SPECIFIERS (0x0004)
@ -59,6 +89,8 @@ static inline float __port_ind(void)
static int (__cdecl *p_vfprintf)(unsigned __int64 options, FILE *file, const char *format, static int (__cdecl *p_vfprintf)(unsigned __int64 options, FILE *file, const char *format,
void *locale, __ms_va_list valist); void *locale, __ms_va_list valist);
static int (__cdecl *p_vfwprintf)(unsigned __int64 options, FILE *file, const wchar_t *format,
void *locale, __ms_va_list valist);
static int (__cdecl *p_vsprintf)(unsigned __int64 options, char *str, size_t len, const char *format, static int (__cdecl *p_vsprintf)(unsigned __int64 options, char *str, size_t len, const char *format,
void *locale, __ms_va_list valist); void *locale, __ms_va_list valist);
static int (__cdecl *p_vsnprintf_s)(unsigned __int64 options, char *str, size_t sizeOfBuffer, size_t count, const char *format, static int (__cdecl *p_vsnprintf_s)(unsigned __int64 options, char *str, size_t sizeOfBuffer, size_t count, const char *format,
@ -72,6 +104,22 @@ static FILE *(__cdecl *p_fopen)(const char *name, const char *mode);
static int (__cdecl *p_fclose)(FILE *file); static int (__cdecl *p_fclose)(FILE *file);
static long (__cdecl *p_ftell)(FILE *file); static long (__cdecl *p_ftell)(FILE *file);
static char *(__cdecl *p_fgets)(char *str, int size, FILE *file); static char *(__cdecl *p_fgets)(char *str, int size, FILE *file);
static wchar_t *(__cdecl *p_fgetws)(wchar_t *str, int size, FILE *file);
static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
static int* (__cdecl *p_errno)(void);
static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
const wchar_t *function, const wchar_t *file,
unsigned line, uintptr_t arg)
{
CHECK_EXPECT(invalid_parameter_handler);
ok(expression == NULL, "expression is not NULL\n");
ok(function == NULL, "function is not NULL\n");
ok(file == NULL, "file is not NULL\n");
ok(line == 0, "line = %u\n", line);
ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
}
static BOOL init( void ) static BOOL init( void )
{ {
@ -84,6 +132,7 @@ static BOOL init( void )
} }
p_vfprintf = (void *)GetProcAddress(hmod, "__stdio_common_vfprintf"); p_vfprintf = (void *)GetProcAddress(hmod, "__stdio_common_vfprintf");
p_vfwprintf = (void *)GetProcAddress(hmod, "__stdio_common_vfwprintf");
p_vsprintf = (void *)GetProcAddress(hmod, "__stdio_common_vsprintf"); p_vsprintf = (void *)GetProcAddress(hmod, "__stdio_common_vsprintf");
p_vsnprintf_s = (void *)GetProcAddress(hmod, "__stdio_common_vsnprintf_s"); p_vsnprintf_s = (void *)GetProcAddress(hmod, "__stdio_common_vsnprintf_s");
p_vsprintf_s = (void *)GetProcAddress(hmod, "__stdio_common_vsprintf_s"); p_vsprintf_s = (void *)GetProcAddress(hmod, "__stdio_common_vsprintf_s");
@ -93,6 +142,10 @@ static BOOL init( void )
p_fclose = (void *)GetProcAddress(hmod, "fclose"); p_fclose = (void *)GetProcAddress(hmod, "fclose");
p_ftell = (void *)GetProcAddress(hmod, "ftell"); p_ftell = (void *)GetProcAddress(hmod, "ftell");
p_fgets = (void *)GetProcAddress(hmod, "fgets"); p_fgets = (void *)GetProcAddress(hmod, "fgets");
p_fgetws = (void *)GetProcAddress(hmod, "fgetws");
p_set_invalid_parameter_handler = (void *)GetProcAddress(hmod, "_set_invalid_parameter_handler");
p_errno = (void *)GetProcAddress(hmod, "_errno");
return TRUE; return TRUE;
} }
@ -308,6 +361,109 @@ static void test_fprintf(void)
unlink(file_name); unlink(file_name);
} }
static int __cdecl vfwprintf_wrapper(FILE *file,
const wchar_t *format, ...)
{
int ret;
__ms_va_list valist;
__ms_va_start(valist, format);
ret = p_vfwprintf(0, file, format, NULL, valist);
__ms_va_end(valist);
return ret;
}
static void test_fwprintf(void)
{
static const char file_name[] = "fprintf.tst";
static const WCHAR simple[] = {'s','i','m','p','l','e',' ','t','e','s','t','\n',0};
static const WCHAR cont_fmt[] = {'c','o','n','t','a','i','n','s','%','c','n','u','l','l','\n',0};
static const WCHAR cont[] = {'c','o','n','t','a','i','n','s','\0','n','u','l','l','\n',0};
FILE *fp = p_fopen(file_name, "wb");
wchar_t bufw[1024];
char bufa[1024];
int ret;
ret = vfwprintf_wrapper(fp, simple);
ok(ret == 12, "ret = %d\n", ret);
ret = p_ftell(fp);
ok(ret == 24, "ftell returned %d\n", ret);
ret = vfwprintf_wrapper(fp, cont_fmt, '\0');
ok(ret == 14, "ret = %d\n", ret);
ret = p_ftell(fp);
ok(ret == 52, "ftell returned %d\n", ret);
p_fclose(fp);
fp = p_fopen(file_name, "rb");
p_fgetws(bufw, sizeof(bufw)/sizeof(bufw[0]), fp);
ret = p_ftell(fp);
ok(ret == 24, "ftell returned %d\n", ret);
ok(!wcscmp(bufw, simple), "buf = %s\n", wine_dbgstr_w(bufw));
p_fgetws(bufw, sizeof(bufw)/sizeof(bufw[0]), fp);
ret = p_ftell(fp);
ok(ret == 52, "ret = %d\n", ret);
ok(!memcmp(bufw, cont, 28), "buf = %s\n", wine_dbgstr_w(bufw));
p_fclose(fp);
fp = p_fopen(file_name, "wt");
ret = vfwprintf_wrapper(fp, simple);
ok(ret == 12, "ret = %d\n", ret);
ret = p_ftell(fp);
ok(ret == 13, "ftell returned %d\n", ret);
ret = vfwprintf_wrapper(fp, cont_fmt, '\0');
ok(ret == 14, "ret = %d\n", ret);
ret = p_ftell(fp);
ok(ret == 28, "ftell returned %d\n", ret);
p_fclose(fp);
fp = p_fopen(file_name, "rb");
p_fgets(bufa, sizeof(bufa), fp);
ret = p_ftell(fp);
ok(ret == 13, "ftell returned %d\n", ret);
ok(!strcmp(bufa, "simple test\r\n"), "buf = %s\n", bufa);
p_fgets(bufa, sizeof(bufa), fp);
ret = p_ftell(fp);
ok(ret == 28, "ret = %d\n", ret);
ok(!memcmp(bufa, "contains\0null\r\n", 15), "buf = %s\n", bufa);
p_fclose(fp);
unlink(file_name);
ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
"Invalid parameter handler was already set\n");
/* NULL format */
errno = 0xdeadbeef;
SET_EXPECT(invalid_parameter_handler);
ret = vfwprintf_wrapper(fp, NULL);
ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno);
ok(ret == -1, "expected ret -1, got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler);
/* NULL file */
errno = 0xdeadbeef;
SET_EXPECT(invalid_parameter_handler);
ret = vfwprintf_wrapper(NULL, simple);
ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno);
ok(ret == -1, "expected ret -1, got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler);
/* format using % with NULL arglist*/
/* crashes on Windows */
/* ret = p_vfwprintf(0, fp, cont_fmt, NULL, NULL); */
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
"Cannot reset invalid parameter handler\n");
}
static int __cdecl _vsnprintf_s_wrapper(char *str, size_t sizeOfBuffer, static int __cdecl _vsnprintf_s_wrapper(char *str, size_t sizeOfBuffer,
size_t count, const char *format, ...) size_t count, const char *format, ...)
{ {
@ -456,6 +612,7 @@ START_TEST(printf)
test_snprintf(); test_snprintf();
test_swprintf(); test_swprintf();
test_fprintf(); test_fprintf();
test_fwprintf();
test_vsnprintf_s(); test_vsnprintf_s();
test_printf_legacy_wide(); test_printf_legacy_wide();
test_printf_legacy_msvcrt(); test_printf_legacy_msvcrt();

View File

@ -150,7 +150,7 @@
@ stub __stdio_common_vfprintf_p @ stub __stdio_common_vfprintf_p
@ stub __stdio_common_vfprintf_s @ stub __stdio_common_vfprintf_s
@ stub __stdio_common_vfscanf @ stub __stdio_common_vfscanf
@ stub __stdio_common_vfwprintf @ cdecl __stdio_common_vfwprintf(int64 ptr ptr ptr ptr) MSVCRT__stdio_common_vfwprintf
@ stub __stdio_common_vfwprintf_p @ stub __stdio_common_vfwprintf_p
@ stub __stdio_common_vfwprintf_s @ stub __stdio_common_vfwprintf_s
@ stub __stdio_common_vfwscanf @ stub __stdio_common_vfwscanf