msvcrt: Added sprintf_p_l implementation.
This commit is contained in:
parent
a415974b2e
commit
00182ca6d9
|
@ -1119,7 +1119,7 @@
|
||||||
@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
|
@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
|
||||||
@ stub _sprintf_l
|
@ stub _sprintf_l
|
||||||
@ stub _sprintf_p
|
@ stub _sprintf_p
|
||||||
@ stub _sprintf_p_l
|
@ varargs _sprintf_p_l(ptr long str ptr) msvcrt._sprintf_p_l
|
||||||
@ stub _sprintf_s_l
|
@ stub _sprintf_s_l
|
||||||
@ varargs _sscanf_l(str str ptr) msvcrt._sscanf_l
|
@ varargs _sscanf_l(str str ptr) msvcrt._sscanf_l
|
||||||
@ varargs _sscanf_s_l(str str ptr) msvcrt._sscanf_s_l
|
@ varargs _sscanf_s_l(str str ptr) msvcrt._sscanf_s_l
|
||||||
|
@ -1174,7 +1174,7 @@
|
||||||
@ stub _swprintf_c
|
@ stub _swprintf_c
|
||||||
@ stub _swprintf_c_l
|
@ stub _swprintf_c_l
|
||||||
@ stub _swprintf_p
|
@ stub _swprintf_p
|
||||||
@ stub _swprintf_p_l
|
@ varargs _swprintf_p_l(ptr long wstr ptr) msvcrt._swprintf_p_l
|
||||||
@ stub _swprintf_s_l
|
@ stub _swprintf_s_l
|
||||||
@ varargs _swscanf_l(wstr wstr ptr) msvcrt._swscanf_l
|
@ varargs _swscanf_l(wstr wstr ptr) msvcrt._swscanf_l
|
||||||
@ varargs _swscanf_s_l(wstr wstr ptr) msvcrt._swscanf_s_l
|
@ varargs _swscanf_s_l(wstr wstr ptr) msvcrt._swscanf_s_l
|
||||||
|
@ -1259,8 +1259,8 @@
|
||||||
@ cdecl _vsnwprintf_s(ptr long long wstr ptr) msvcrt._vsnwprintf_s
|
@ cdecl _vsnwprintf_s(ptr long long wstr ptr) msvcrt._vsnwprintf_s
|
||||||
@ cdecl _vsnwprintf_s_l(ptr long long wstr ptr ptr) msvcrt._vsnwprintf_s_l
|
@ cdecl _vsnwprintf_s_l(ptr long long wstr ptr ptr) msvcrt._vsnwprintf_s_l
|
||||||
@ stub _vsprintf_l
|
@ stub _vsprintf_l
|
||||||
@ stub _vsprintf_p
|
@ cdecl _vsprintf_p(ptr long str ptr) msvcrt._vsprintf_p
|
||||||
@ stub _vsprintf_p_l
|
@ cdecl _vsprintf_p_l(ptr long str ptr ptr) msvcrt._vsprintf_p_l
|
||||||
@ stub _vsprintf_s_l
|
@ stub _vsprintf_s_l
|
||||||
@ cdecl _vswprintf(ptr long wstr ptr) msvcrt._vswprintf
|
@ cdecl _vswprintf(ptr long wstr ptr) msvcrt._vswprintf
|
||||||
@ cdecl _vswprintf_c(ptr long wstr ptr) msvcrt._vswprintf_c
|
@ cdecl _vswprintf_c(ptr long wstr ptr) msvcrt._vswprintf_c
|
||||||
|
|
|
@ -973,7 +973,7 @@
|
||||||
@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
|
@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
|
||||||
@ stub _sprintf_l
|
@ stub _sprintf_l
|
||||||
@ stub _sprintf_p
|
@ stub _sprintf_p
|
||||||
@ stub _sprintf_p_l
|
@ varargs _sprintf_p_l(ptr long str ptr) msvcrt._sprintf_p_l
|
||||||
@ stub _sprintf_s_l
|
@ stub _sprintf_s_l
|
||||||
@ varargs _sscanf_l(str str ptr) msvcrt._sscanf_l
|
@ varargs _sscanf_l(str str ptr) msvcrt._sscanf_l
|
||||||
@ varargs _sscanf_s_l(str str ptr) msvcrt._sscanf_s_l
|
@ varargs _sscanf_s_l(str str ptr) msvcrt._sscanf_s_l
|
||||||
|
@ -1027,7 +1027,7 @@
|
||||||
@ stub _swprintf
|
@ stub _swprintf
|
||||||
@ stub _swprintf_c
|
@ stub _swprintf_c
|
||||||
@ stub _swprintf_p
|
@ stub _swprintf_p
|
||||||
@ stub _swprintf_p_l
|
@ varargs _swprintf_p_l(ptr long wstr ptr) msvcrt._swprintf_p_l
|
||||||
@ stub _swprintf_s_l
|
@ stub _swprintf_s_l
|
||||||
@ varargs _swscanf_l(wstr wstr ptr) msvcrt._swscanf_l
|
@ varargs _swscanf_l(wstr wstr ptr) msvcrt._swscanf_l
|
||||||
@ varargs _swscanf_s_l(wstr wstr ptr) msvcrt._swscanf_s_l
|
@ varargs _swscanf_s_l(wstr wstr ptr) msvcrt._swscanf_s_l
|
||||||
|
@ -1112,8 +1112,8 @@
|
||||||
@ cdecl _vsnwprintf_s(ptr long long wstr ptr) msvcrt._vsnwprintf_s
|
@ cdecl _vsnwprintf_s(ptr long long wstr ptr) msvcrt._vsnwprintf_s
|
||||||
@ cdecl _vsnwprintf_s_l(ptr long long wstr ptr ptr) msvcrt._vsnwprintf_s_l
|
@ cdecl _vsnwprintf_s_l(ptr long long wstr ptr ptr) msvcrt._vsnwprintf_s_l
|
||||||
@ stub _vsprintf_l
|
@ stub _vsprintf_l
|
||||||
@ stub _vsprintf_p
|
@ cdecl _vsprintf_p(ptr long str ptr) msvcrt._vsprintf_p
|
||||||
@ stub _vsprintf_p_l
|
@ cdecl _vsprintf_p_l(ptr long str ptr ptr) msvcrt._vsprintf_p_l
|
||||||
@ stub _vsprintf_s_l
|
@ stub _vsprintf_s_l
|
||||||
@ cdecl _vswprintf(ptr long wstr ptr) msvcrt._vswprintf
|
@ cdecl _vswprintf(ptr long wstr ptr) msvcrt._vswprintf
|
||||||
@ cdecl _vswprintf_c(ptr long wstr ptr) msvcrt._vswprintf_c
|
@ cdecl _vswprintf_c(ptr long wstr ptr) msvcrt._vswprintf_c
|
||||||
|
|
|
@ -959,7 +959,7 @@
|
||||||
@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
|
@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
|
||||||
@ stub _sprintf_l
|
@ stub _sprintf_l
|
||||||
@ stub _sprintf_p
|
@ stub _sprintf_p
|
||||||
@ stub _sprintf_p_l
|
@ varargs _sprintf_p_l(ptr long str ptr) msvcrt._sprintf_p_l
|
||||||
@ stub _sprintf_s_l
|
@ stub _sprintf_s_l
|
||||||
@ varargs _sscanf_l(str str ptr) msvcrt._sscanf_l
|
@ varargs _sscanf_l(str str ptr) msvcrt._sscanf_l
|
||||||
@ varargs _sscanf_s_l(str str ptr) msvcrt._sscanf_s_l
|
@ varargs _sscanf_s_l(str str ptr) msvcrt._sscanf_s_l
|
||||||
|
@ -1014,7 +1014,7 @@
|
||||||
@ stub _swprintf_c
|
@ stub _swprintf_c
|
||||||
@ stub _swprintf_c_l
|
@ stub _swprintf_c_l
|
||||||
@ stub _swprintf_p
|
@ stub _swprintf_p
|
||||||
@ stub _swprintf_p_l
|
@ varargs _swprintf_p_l(ptr long wstr ptr) msvcrt._swprintf_p_l
|
||||||
@ stub _swprintf_s_l
|
@ stub _swprintf_s_l
|
||||||
@ varargs _swscanf_l(wstr wstr ptr) msvcrt._swscanf_l
|
@ varargs _swscanf_l(wstr wstr ptr) msvcrt._swscanf_l
|
||||||
@ varargs _swscanf_s_l(wstr wstr ptr) msvcrt._swscanf_s_l
|
@ varargs _swscanf_s_l(wstr wstr ptr) msvcrt._swscanf_s_l
|
||||||
|
@ -1099,8 +1099,8 @@
|
||||||
@ cdecl _vsnwprintf_s(ptr long long wstr ptr) msvcrt._vsnwprintf_s
|
@ cdecl _vsnwprintf_s(ptr long long wstr ptr) msvcrt._vsnwprintf_s
|
||||||
@ cdecl _vsnwprintf_s_l(ptr long long wstr ptr ptr) msvcrt._vsnwprintf_s_l
|
@ cdecl _vsnwprintf_s_l(ptr long long wstr ptr ptr) msvcrt._vsnwprintf_s_l
|
||||||
@ stub _vsprintf_l
|
@ stub _vsprintf_l
|
||||||
@ stub _vsprintf_p
|
@ cdecl _vsprintf_p(ptr long str ptr) msvcrt._vsprintf_p
|
||||||
@ stub _vsprintf_p_l
|
@ cdecl _vsprintf_p_l(ptr long str ptr ptr) msvcrt._vsprintf_p_l
|
||||||
@ stub _vsprintf_s_l
|
@ stub _vsprintf_s_l
|
||||||
@ cdecl _vswprintf(ptr long wstr ptr) msvcrt._vswprintf
|
@ cdecl _vswprintf(ptr long wstr ptr) msvcrt._vswprintf
|
||||||
@ cdecl _vswprintf_c(ptr long wstr ptr) msvcrt._vswprintf_c
|
@ cdecl _vswprintf_c(ptr long wstr ptr) msvcrt._vswprintf_c
|
||||||
|
|
|
@ -916,6 +916,7 @@ void __cdecl MSVCRT__invalid_parameter(const MSVCRT_wchar_t *expr, const MSVCRT_
|
||||||
#define MSVCRT_CHECK_PMT(x) ((x) || (MSVCRT_INVALID_PMT(0),FALSE))
|
#define MSVCRT_CHECK_PMT(x) ((x) || (MSVCRT_INVALID_PMT(0),FALSE))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MSVCRT__ARGMAX 100
|
||||||
typedef int (*puts_clbk_a)(void*, int, const char*);
|
typedef int (*puts_clbk_a)(void*, int, const char*);
|
||||||
typedef int (*puts_clbk_w)(void*, int, const MSVCRT_wchar_t*);
|
typedef int (*puts_clbk_w)(void*, int, const MSVCRT_wchar_t*);
|
||||||
typedef union _printf_arg
|
typedef union _printf_arg
|
||||||
|
@ -931,6 +932,7 @@ int pf_printf_a(puts_clbk_a, void*, const char*, MSVCRT__locale_t,
|
||||||
int pf_printf_w(puts_clbk_w, void*, const MSVCRT_wchar_t*, MSVCRT__locale_t,
|
int pf_printf_w(puts_clbk_w, void*, const MSVCRT_wchar_t*, MSVCRT__locale_t,
|
||||||
BOOL, BOOL, args_clbk, void*, __ms_va_list);
|
BOOL, BOOL, args_clbk, void*, __ms_va_list);
|
||||||
printf_arg arg_clbk_valist(void*, int, int, __ms_va_list*);
|
printf_arg arg_clbk_valist(void*, int, int, __ms_va_list*);
|
||||||
|
printf_arg arg_clbk_positional(void*, int, int, __ms_va_list*);
|
||||||
|
|
||||||
#define MSVCRT__OVERFLOW 3
|
#define MSVCRT__OVERFLOW 3
|
||||||
#define MSVCRT__UNDERFLOW 4
|
#define MSVCRT__UNDERFLOW 4
|
||||||
|
|
|
@ -901,7 +901,7 @@
|
||||||
@ cdecl _splitpath(str ptr ptr ptr ptr)
|
@ cdecl _splitpath(str ptr ptr ptr ptr)
|
||||||
@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long)
|
@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long)
|
||||||
# stub _sprintf_l
|
# stub _sprintf_l
|
||||||
# stub _sprintf_p_l
|
@ varargs _sprintf_p_l(ptr long str ptr) MSVCRT_sprintf_p_l
|
||||||
# stub _sprintf_s_l
|
# stub _sprintf_s_l
|
||||||
@ varargs _sscanf_l(str str ptr) MSVCRT__sscanf_l
|
@ varargs _sscanf_l(str str ptr) MSVCRT__sscanf_l
|
||||||
@ varargs _sscanf_s_l(str str ptr) MSVCRT__sscanf_s_l
|
@ varargs _sscanf_s_l(str str ptr) MSVCRT__sscanf_s_l
|
||||||
|
@ -954,7 +954,7 @@
|
||||||
# stub _swprintf
|
# stub _swprintf
|
||||||
# stub _swprintf_c
|
# stub _swprintf_c
|
||||||
# stub _swprintf_c_l
|
# stub _swprintf_c_l
|
||||||
# stub _swprintf_p_l
|
@ varargs _swprintf_p_l(ptr long wstr ptr) MSVCRT_swprintf_p_l
|
||||||
# stub _swprintf_s_l
|
# stub _swprintf_s_l
|
||||||
@ varargs _swscanf_l(wstr wstr ptr) MSVCRT__swscanf_l
|
@ varargs _swscanf_l(wstr wstr ptr) MSVCRT__swscanf_l
|
||||||
@ varargs _swscanf_s_l(wstr wstr ptr) MSVCRT__swscanf_s_l
|
@ varargs _swscanf_s_l(wstr wstr ptr) MSVCRT__swscanf_s_l
|
||||||
|
@ -1035,14 +1035,14 @@
|
||||||
@ cdecl _vsnwprintf_s(ptr long long wstr ptr) MSVCRT_vsnwprintf_s
|
@ cdecl _vsnwprintf_s(ptr long long wstr ptr) MSVCRT_vsnwprintf_s
|
||||||
@ cdecl _vsnwprintf_s_l(ptr long long wstr ptr ptr) MSVCRT_vsnwprintf_s_l
|
@ cdecl _vsnwprintf_s_l(ptr long long wstr ptr ptr) MSVCRT_vsnwprintf_s_l
|
||||||
# stub _vsprintf_l
|
# stub _vsprintf_l
|
||||||
# stub _vsprintf_p
|
@ cdecl _vsprintf_p(ptr long str ptr) MSVCRT_vsprintf_p
|
||||||
# stub _vsprintf_p_l
|
@ cdecl _vsprintf_p_l(ptr long str ptr ptr) MSVCRT_vsprintf_p_l
|
||||||
# stub _vsprintf_s_l
|
# stub _vsprintf_s_l
|
||||||
@ cdecl _vswprintf(ptr long wstr ptr) MSVCRT_vsnwprintf
|
@ cdecl _vswprintf(ptr long wstr ptr) MSVCRT_vsnwprintf
|
||||||
@ cdecl _vswprintf_c(ptr long wstr ptr) MSVCRT_vsnwprintf
|
@ cdecl _vswprintf_c(ptr long wstr ptr) MSVCRT_vsnwprintf
|
||||||
@ cdecl _vswprintf_c_l(ptr long wstr ptr ptr) MSVCRT_vsnwprintf_l
|
@ cdecl _vswprintf_c_l(ptr long wstr ptr ptr) MSVCRT_vsnwprintf_l
|
||||||
@ cdecl _vswprintf_l(ptr long wstr ptr ptr) MSVCRT_vsnwprintf_l
|
@ cdecl _vswprintf_l(ptr long wstr ptr ptr) MSVCRT_vsnwprintf_l
|
||||||
@ cdecl _vswprintf_p_l(ptr long wstr ptr ptr) MSVCRT_vsnwprintf_l
|
@ cdecl _vswprintf_p_l(ptr long wstr ptr ptr) MSVCRT_vswprintf_p_l
|
||||||
@ cdecl _vswprintf_s_l(ptr long wstr ptr ptr) MSVCRT_vswprintf_s_l
|
@ cdecl _vswprintf_s_l(ptr long wstr ptr ptr) MSVCRT_vswprintf_s_l
|
||||||
# stub _vwprintf_l
|
# stub _vwprintf_l
|
||||||
# stub _vwprintf_p
|
# stub _vwprintf_p
|
||||||
|
|
|
@ -553,6 +553,79 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PRINTF_WIDE
|
||||||
|
enum types_clbk_flags {
|
||||||
|
TYPE_CLBK_VA_LIST = 1,
|
||||||
|
TYPE_CLBK_POSITIONAL = 2,
|
||||||
|
TYPE_CLBK_ERROR_POS = 4,
|
||||||
|
TYPE_CLBK_ERROR_TYPE = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This functions stores types of arguments. It uses args[0] internally */
|
||||||
|
static printf_arg arg_clbk_type(void *ctx, int pos, int type, __ms_va_list *valist)
|
||||||
|
{
|
||||||
|
static const printf_arg ret;
|
||||||
|
printf_arg *args = ctx;
|
||||||
|
|
||||||
|
if(pos == -1) {
|
||||||
|
args[0].get_int |= TYPE_CLBK_VA_LIST;
|
||||||
|
return ret;
|
||||||
|
} else
|
||||||
|
args[0].get_int |= TYPE_CLBK_POSITIONAL;
|
||||||
|
|
||||||
|
if(pos<1 || pos>MSVCRT__ARGMAX)
|
||||||
|
args[0].get_int |= TYPE_CLBK_ERROR_POS;
|
||||||
|
else if(args[pos].get_int && args[pos].get_int!=type)
|
||||||
|
args[0].get_int |= TYPE_CLBK_ERROR_TYPE;
|
||||||
|
else
|
||||||
|
args[pos].get_int = type;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int FUNC_NAME(create_positional_ctx)(void *args_ctx, const APICHAR *format, __ms_va_list valist)
|
||||||
|
{
|
||||||
|
struct FUNC_NAME(_str_ctx) puts_ctx = {INT_MAX, NULL};
|
||||||
|
printf_arg *args = args_ctx;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
i = FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk_str), &puts_ctx, format, NULL, TRUE, FALSE,
|
||||||
|
arg_clbk_type, args_ctx, NULL);
|
||||||
|
if(i < 0)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
if(args[0].get_int==0 || args[0].get_int==TYPE_CLBK_VA_LIST)
|
||||||
|
return 0;
|
||||||
|
if(args[0].get_int != TYPE_CLBK_POSITIONAL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for(i=MSVCRT__ARGMAX; i>0; i--)
|
||||||
|
if(args[i].get_int)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for(j=1; j<=i; j++) {
|
||||||
|
switch(args[j].get_int) {
|
||||||
|
case VT_I8:
|
||||||
|
args[j].get_longlong = va_arg(valist, LONGLONG);
|
||||||
|
break;
|
||||||
|
case VT_INT:
|
||||||
|
args[j].get_int = va_arg(valist, int);
|
||||||
|
break;
|
||||||
|
case VT_R8:
|
||||||
|
args[j].get_double = va_arg(valist, double);
|
||||||
|
break;
|
||||||
|
case VT_PTR:
|
||||||
|
args[j].get_ptr = va_arg(valist, void*);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
#undef APICHAR
|
#undef APICHAR
|
||||||
#undef CONVCHAR
|
#undef CONVCHAR
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
|
@ -44,6 +44,7 @@ static int (__cdecl *p__ecvt_s)(char *buffer, size_t length, double number,
|
||||||
static int (__cdecl *p__fcvt_s)(char *buffer, size_t length, double number,
|
static int (__cdecl *p__fcvt_s)(char *buffer, size_t length, double number,
|
||||||
int ndigits, int *decpt, int *sign);
|
int ndigits, int *decpt, int *sign);
|
||||||
static unsigned int (__cdecl *p__get_output_format)(void);
|
static unsigned int (__cdecl *p__get_output_format)(void);
|
||||||
|
static int (__cdecl *p__vsprintf_p)(char*, size_t, const char*, __ms_va_list);
|
||||||
|
|
||||||
static void init( void )
|
static void init( void )
|
||||||
{
|
{
|
||||||
|
@ -55,6 +56,7 @@ static void init( void )
|
||||||
p__ecvt_s = (void *)GetProcAddress(hmod, "_ecvt_s");
|
p__ecvt_s = (void *)GetProcAddress(hmod, "_ecvt_s");
|
||||||
p__fcvt_s = (void *)GetProcAddress(hmod, "_fcvt_s");
|
p__fcvt_s = (void *)GetProcAddress(hmod, "_fcvt_s");
|
||||||
p__get_output_format = (void *)GetProcAddress(hmod, "_get_output_format");
|
p__get_output_format = (void *)GetProcAddress(hmod, "_get_output_format");
|
||||||
|
p__vsprintf_p = (void*)GetProcAddress(hmod, "_vsprintf_p");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_sprintf( void )
|
static void test_sprintf( void )
|
||||||
|
@ -1050,6 +1052,47 @@ static void test_vsnwprintf_s(void)
|
||||||
ok( !wcscmp(out1, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
|
ok( !wcscmp(out1, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cdecl _vsprintf_p_wrapper(char *str, size_t sizeOfBuffer,
|
||||||
|
const char *format, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
__ms_va_list valist;
|
||||||
|
__ms_va_start(valist, format);
|
||||||
|
ret = p__vsprintf_p(str, sizeOfBuffer, format, valist);
|
||||||
|
__ms_va_end(valist);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_vsprintf_p(void)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(!p__vsprintf_p) {
|
||||||
|
win_skip("vsprintf_p not available\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%s %d", "test", 1234);
|
||||||
|
ok(ret == 9, "ret = %d\n", ret);
|
||||||
|
ok(!memcmp(buf, "test 1234", 10), "buf = %s\n", buf);
|
||||||
|
|
||||||
|
ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%1$d", 1234, "additional param");
|
||||||
|
ok(ret == 4, "ret = %d\n", ret);
|
||||||
|
ok(!memcmp(buf, "1234", 5), "buf = %s\n", buf);
|
||||||
|
|
||||||
|
ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%2$s %1$d", 1234, "test");
|
||||||
|
ok(ret == 9, "ret = %d\n", ret);
|
||||||
|
ok(!memcmp(buf, "test 1234", 10), "buf = %s\n", buf);
|
||||||
|
|
||||||
|
ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%2$*3$s %2$.*1$s", 2, "test", 3);
|
||||||
|
ok(ret == 7, "ret = %d\n", ret);
|
||||||
|
ok(!memcmp(buf, "test te", 8), "buf = %s\n", buf);
|
||||||
|
|
||||||
|
/* Following test invokes invalid parameter handler */
|
||||||
|
/* ret = _vsprintf_p_wrapper(buf, sizeof(buf), "%d %1$d", 1234); */
|
||||||
|
}
|
||||||
|
|
||||||
static void test__get_output_format(void)
|
static void test__get_output_format(void)
|
||||||
{
|
{
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
|
@ -1078,5 +1121,6 @@ START_TEST(printf)
|
||||||
test_vscprintf();
|
test_vscprintf();
|
||||||
test_vscwprintf();
|
test_vscwprintf();
|
||||||
test_vsnwprintf_s();
|
test_vsnwprintf_s();
|
||||||
|
test_vsprintf_p();
|
||||||
test__get_output_format();
|
test__get_output_format();
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,6 +436,15 @@ printf_arg arg_clbk_valist(void *ctx, int arg_pos, int type, __ms_va_list *valis
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* arg_clbk_positional (INTERNAL)
|
||||||
|
*/
|
||||||
|
printf_arg arg_clbk_positional(void *ctx, int pos, int type, __ms_va_list *valist)
|
||||||
|
{
|
||||||
|
printf_arg *args = ctx;
|
||||||
|
return args[pos];
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _vsnprintf (MSVCRT.@)
|
* _vsnprintf (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
@ -789,6 +798,105 @@ int CDECL MSVCRT_vswprintf_s_l(MSVCRT_wchar_t* str, MSVCRT_size_t numberOfElemen
|
||||||
format, locale, args );
|
format, locale, args );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _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)
|
||||||
|
{
|
||||||
|
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, FALSE, TRUE,
|
||||||
|
arg_clbk_valist, NULL, args);
|
||||||
|
else
|
||||||
|
ret = pf_printf_a(puts_clbk_str_a, &puts_ctx, format, locale, TRUE, TRUE,
|
||||||
|
arg_clbk_positional, args_ctx, NULL);
|
||||||
|
|
||||||
|
puts_clbk_str_a(&puts_ctx, 1, &nullbyte);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _vsprintf_p (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
int CDECL MSVCRT_vsprintf_p(char *buffer, MSVCRT_size_t length,
|
||||||
|
const char *format, __ms_va_list args)
|
||||||
|
{
|
||||||
|
return MSVCRT_vsprintf_p_l(buffer, length, format, NULL, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _sprintf_p_l (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
int CDECL MSVCRT_sprintf_p_l(char *buffer, MSVCRT_size_t length,
|
||||||
|
const char *format, MSVCRT__locale_t locale, ...)
|
||||||
|
{
|
||||||
|
__ms_va_list valist;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
__ms_va_start(valist, locale);
|
||||||
|
r = MSVCRT_vsprintf_p_l(buffer, length, format, locale, valist);
|
||||||
|
__ms_va_end(valist);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _vswprintf_p_l (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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, TRUE, TRUE,
|
||||||
|
arg_clbk_valist, NULL, args);
|
||||||
|
else
|
||||||
|
ret = pf_printf_w(puts_clbk_str_w, &puts_ctx, format, locale, TRUE, TRUE,
|
||||||
|
arg_clbk_positional, args_ctx, NULL);
|
||||||
|
|
||||||
|
puts_clbk_str_w(&puts_ctx, 1, &nullbyte);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _swprintf_p_l (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
int CDECL MSVCRT_swprintf_p_l(MSVCRT_wchar_t *buffer, MSVCRT_size_t length,
|
||||||
|
const MSVCRT_wchar_t *format, MSVCRT__locale_t locale, ...)
|
||||||
|
{
|
||||||
|
__ms_va_list valist;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
__ms_va_start(valist, locale);
|
||||||
|
r = MSVCRT_vswprintf_p_l(buffer, length, format, locale, valist);
|
||||||
|
__ms_va_end(valist);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* wcscoll (MSVCRT.@)
|
* wcscoll (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -97,6 +97,8 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _ARGMAX 100
|
||||||
|
|
||||||
#ifndef _MSVCRT_LONG_DEFINED
|
#ifndef _MSVCRT_LONG_DEFINED
|
||||||
#define _MSVCRT_LONG_DEFINED
|
#define _MSVCRT_LONG_DEFINED
|
||||||
/* we need 32-bit longs even on 64-bit */
|
/* we need 32-bit longs even on 64-bit */
|
||||||
|
|
Loading…
Reference in New Issue