diff --git a/modules/rostests/kmtests/kmtest_drv/printf_stubs.c b/modules/rostests/kmtests/kmtest_drv/printf_stubs.c index 389ed46263..8bed2d6cd6 100644 --- a/modules/rostests/kmtests/kmtest_drv/printf_stubs.c +++ b/modules/rostests/kmtests/kmtest_drv/printf_stubs.c @@ -9,6 +9,19 @@ #include #include #include +#include +#include + +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; int __cdecl KmtWcToMb(char *mbchar, wchar_t wchar) { @@ -16,7 +29,7 @@ int __cdecl KmtWcToMb(char *mbchar, wchar_t wchar) return 1; } -int __cdecl streamout(FILE *stream, const char *format, va_list argptr); +int __cdecl streamout(FILE *stream, bool use_pos_params, pos_param_t *pos_params_ctx, const TCHAR *format, va_list argptr); int __cdecl KmtVSNPrintF(char *buffer, size_t count, const char *format, va_list argptr) { @@ -31,7 +44,8 @@ int __cdecl KmtVSNPrintF(char *buffer, size_t count, const char *format, va_list stream._flag = _IOSTRG | _IOWRT; stream._tmpfname = 0; - result = streamout(&stream, format, argptr); + + result = streamout(&stream, false, NULL, format, argptr); /* Only zero terminate if there is enough space left */ if (stream._cnt) *(char *)stream._ptr = '\0'; diff --git a/sdk/lib/crt/printf/_sxprintf.c b/sdk/lib/crt/printf/_sxprintf.c index 0e9d35f978..19f31f6b21 100644 --- a/sdk/lib/crt/printf/_sxprintf.c +++ b/sdk/lib/crt/printf/_sxprintf.c @@ -10,19 +10,75 @@ #include #include #include +#include #if IS_SECAPI #include #endif +#ifdef _UNICODE +# include +#else +# include +#endif + #ifdef _UNICODE #define _tstreamout wstreamout +#define _isdigit iswdigit #else #define _tstreamout streamout +#define _isdigit isdigit +#endif + +#ifdef _USER32_WSPRINTF +# define USE_MULTISIZE 0 +#else +# define USE_MULTISIZE 1 +#endif + +/* MSDN mandates this maximum number of positional parameters allowed in a format string. + * FIXME: Is 100 Ok ??? */ +#define _ARGMAX 100 +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; + +enum +{ + /* Formatting flags */ + FLAG_ALIGN_LEFT = 0x01, + FLAG_FORCE_SIGN = 0x02, + FLAG_FORCE_SIGNSP = 0x04, + FLAG_PAD_ZERO = 0x08, + FLAG_SPECIAL = 0x10, + + /* Data format flags */ + FLAG_SHORT = 0x100, + FLAG_LONG = 0x200, + FLAG_WIDECHAR = FLAG_LONG, + FLAG_INT64 = 0x400, +#ifdef _WIN64 + FLAG_INTPTR = FLAG_INT64, +#else + FLAG_INTPTR = 0, #endif + FLAG_LONGDOUBLE = 0x800, +}; #define min(a,b) (((a) < (b)) ? (a) : (b)) -int __cdecl _tstreamout(FILE *stream, const TCHAR *format, va_list argptr); +int _cdecl _tstreamout(FILE *stream, bool use_pos_params, pos_param_t *pos_params, const TCHAR *format, va_list argptr); + +/* forward declaration */ +#if defined(USE_VARARGS) && defined(USE_POS_PARAMS) +static int parse_possible_pos_params(pos_param_t *pos_params, bool *use_pos_params, const TCHAR *format, va_list argptr); +#endif int #if defined(USER32_WSPRINTF) && defined(_M_IX86) @@ -57,6 +113,23 @@ _sxprintf( int result; FILE stream; +#if defined(USE_VARARGS) && defined(USE_POS_PARAMS) + bool use_pos_params; + pos_param_t pos_params[_ARGMAX]; + result = parse_possible_pos_params(pos_params, &use_pos_params, format, argptr); + if (result < 0) + { +#if IS_SECAPI + MSVCRT_INVALID_PMT("Invalid format string"); + errno = EINVAL; +#endif + return result; + } +#else + bool use_pos_params = false; + pos_param_t *pos_params = NULL; +#endif + #if IS_SECAPI /* Validate parameters */ if (MSVCRT_CHECK_PMT(((buffer == NULL) || (format == NULL) || (sizeOfBuffer <= 0)))) @@ -82,7 +155,7 @@ _sxprintf( #if !USE_VARARGS va_start(argptr, format); #endif - result = _tstreamout(&stream, format, argptr); + result = _tstreamout(&stream, use_pos_params, pos_params, format, argptr); #if !USE_VARARGS va_end(argptr); #endif @@ -120,3 +193,272 @@ _sxprintf( } +#if defined(USE_VARARGS) && defined(USE_POS_PARAMS) +enum { + TYPE_PTR, + TYPE_INT, + TYPE_LONGLONG, + TYPE_DOUBLE, + TYPE_UNINITIALIED, +} arg_type; + +static inline const TCHAR* parse_int(const TCHAR *fmt, int *val) +{ + *val = 0; + + while(_isdigit(*fmt)) { + *val *= 10; + *val += *fmt++ - '0'; + } + + return fmt; +} + +/** + * If this is a format string with positional parameters, + * we just parse the positional parameters, put all the proper + * args in pos_params array, and set the use_pos_params to true. + * Otherwise, we just quit with 0, and use_pos_params is set to false. + */ +static int parse_possible_pos_params(pos_param_t *pos_params, bool *use_pos_params, const TCHAR *format, va_list argptr) +{ + const TCHAR *fmt = format; + TCHAR chr; + int pos, width, precision; + bool use_nonpos_param; + bool use_pp_this_pass; + unsigned int flags; + int i, j; + + if (format == NULL) + return -1; + + /* Now we don't know what type of args are */ + for (i = 0; i < _ARGMAX; i++) + { + pos_params[i].type = TYPE_UNINITIALIED; + } + + /* Now we are ignorant of whether we use pos param or not, until we actually meet it... */ + *use_pos_params = use_nonpos_param = false ; + while ((chr=*fmt++) != _T('\0')) + { + /* Skip normal characters and double "%" */ + if (chr != _T('%') || (chr=*fmt++) == _T('%')) + continue; + + /* Now, here we are one charater behind the "%" */ + /* to pass into parse_int, we shall decrease fmt by 1. */ + fmt--; + if ((fmt = parse_int(fmt, &pos)) && (chr=*fmt++) == _T('$')) + { + *use_pos_params = use_pp_this_pass = true; + /* MSDN says: Positional parameters may not be mixed with + * non-positional parameters in the same format string. + */ + if (use_nonpos_param) + return -1; + if ( pos < 0 || pos >= _ARGMAX) + return -1; + chr = *fmt++; + } + else + use_pp_this_pass = false; + + + /* Check for flag, if any */ + while (1) + { + if (chr == _T('-') || chr == _T('+') || + chr == _T(' ') || chr == _T('0') || chr == _T('#')) + chr = *fmt++; + else break; + } + + + /* Check for width modifier */ + if (chr == _T('*')) + { + /* fmt is now one character behind '*' symbol */ + if (use_pp_this_pass) + { + fmt = parse_int(fmt, &width); + if ( width < 0 || width >= _ARGMAX) + return -1; + if ((chr=*fmt++) == _T('$')) + { + pos_params[width].type = TYPE_INT; + chr = *fmt++; + } else + return -1; /* $ shall appear immediately after number, or it is of ill form, bail out.*/ + } else { + chr = *fmt++; + } + } else while (isdigit(chr)) + chr = *fmt++; /* Just skip the number width */ + + + /* Check for precision modifier */ + if (chr == _T('.')) + { + if ((chr=*fmt++) == _T('*')) + { + if (use_pp_this_pass) + { + fmt = parse_int(fmt, &precision); + if ( precision < 0 || precision >= _ARGMAX) + return -1; + if ((chr=*fmt++) == _T('$')) + { + pos_params[precision].type = TYPE_INT; + chr = *fmt++; + } else + return -1; /* $ shall appear immediately after number, otherwise it is of ill form, bail out.*/ + } else { + chr = *fmt++; + } + } else while (isdigit(chr)) + chr = *fmt++; /* Just skip the number presicion */ + } + + + /* Check for the length modifier */ + do + { + if (chr == _T('h')) flags |= FLAG_SHORT; + else if (chr == _T('w')) flags |= FLAG_WIDECHAR; + else if (chr == _T('L')) flags |= 0; // FIXME: long double + else if (chr == _T('F')) flags |= 0; // FIXME: what is that? + else if (chr == _T('l')) + { + /* Check if this is the 2nd 'l' in a row */ + if (format[-2] == 'l') flags |= FLAG_INT64; + else flags |= FLAG_LONG; + } + else if (chr == _T('I')) + { + if (format[0] == _T('3') && format[1] == _T('2')) + { + format += 2; + } + else if (format[0] == _T('6') && format[1] == _T('4')) + { + format += 2; + flags |= FLAG_INT64; + } + else if (format[0] == _T('x') || format[0] == _T('X') || + format[0] == _T('d') || format[0] == _T('i') || + format[0] == _T('u') || format[0] == _T('o')) + { + flags |= FLAG_INTPTR; + } + else break; + } + else break; + chr = *format++; + } + while (USE_MULTISIZE); + + + /* Check for the format specifier.*/ + if (use_nonpos_param) + { + /* MSDN says: Positional parameters may not be mixed with + * non-positional parameters in the same format string. + * So bail out. + */ + if (*use_pos_params) + return -1; + else /* *use_pos_params == false */ + /* If no pos params used, we just quit. */ + return 0; + } + if (use_pp_this_pass) + { + switch(chr) + { + case _T('n'): + /* void* poiter can accomandate all pointer type */ + pos_params[pos].type = TYPE_PTR; + break; + + case _T('C'): + case _T('c'): + pos_params[pos].type = TYPE_INT; + break; + + case _T('Z'): + case _T('S'): + case _T('s'): + pos_params[pos].type = TYPE_PTR; + break; + +#ifndef _USER32_WSPRINTF + case _T('a'): + case _T('A'): + case _T('e'): + case _T('E'): + case _T('f'): + case _T('g'): + case _T('G'): + pos_params[pos].type = TYPE_DOUBLE; + break; +#endif + case _T('d'): + case _T('i'): + case _T('o'): + case _T('u'): + case _T('X'): + case _T('x'): + if (flags & FLAG_INT64) + pos_params[pos].type = TYPE_LONGLONG; + else + pos_params[pos].type = TYPE_INT; + break; + + case _T('p'): + pos_params[pos].type = TYPE_PTR; + break; + + default: + /* Treat anything else as a new character */ + format--; + continue; + } /* end of switch */ + }/* end of if(*use_pos_params) */ + else + use_nonpos_param = true; + }/* end of while */ + + + /* Ok, after parsing the format string, we have gathered all args type. + * Now we can collect all the args values, and put them in pos_params array */ + for (i = _ARGMAX-1; i > 0; i--) + if (pos_params[i].type != TYPE_UNINITIALIED) + break; + + /* MSDN says positional parameters are indexed starting at the value 1. */ + for (j = 1; j <= i; j++) { + switch(pos_params[j].type) { + case TYPE_INT: + pos_params[j].value.int_val = va_arg(argptr, int); + break; + case TYPE_LONGLONG: + pos_params[j].value.longlong_val = va_arg(argptr, long long); + break; + case TYPE_DOUBLE: + pos_params[j].value.double_val = va_arg(argptr, double); + break; + case TYPE_PTR: + pos_params[j].value.ptr_val = va_arg(argptr, void*); + break; + default: + return -1; + } + } + + /* successfully parse format string */ + return 0; +} +#endif /* USE_POS_PARAMS */ + diff --git a/sdk/lib/crt/printf/_vscprintf.c b/sdk/lib/crt/printf/_vscprintf.c index 1f626783d2..b05c61e60a 100644 --- a/sdk/lib/crt/printf/_vscprintf.c +++ b/sdk/lib/crt/printf/_vscprintf.c @@ -7,8 +7,21 @@ #include #include +#include +#include -int __cdecl streamout(FILE *stream, const char *format, va_list argptr); +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; + +int _cdecl streamout(FILE *stream, bool use_pos_params, pos_param_t *pos_params_ctx, const TCHAR *format, va_list argptr); int __cdecl @@ -20,5 +33,5 @@ _vscprintf( nulfile._tmpfname = nulfile._ptr = nulfile._base = NULL; nulfile._bufsiz = nulfile._charbuf = nulfile._cnt = 0; nulfile._flag = _IOSTRG | _IOWRT; - return streamout(&nulfile, format, argptr); + return streamout(&nulfile, false, NULL, format, argptr); } diff --git a/sdk/lib/crt/printf/_vscwprintf.c b/sdk/lib/crt/printf/_vscwprintf.c index e0c2b1b164..d4dc650832 100644 --- a/sdk/lib/crt/printf/_vscwprintf.c +++ b/sdk/lib/crt/printf/_vscwprintf.c @@ -7,8 +7,21 @@ #include #include +#include +#include -int __cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr); +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; + +int _cdecl wstreamout(FILE *stream, bool use_pos_params, pos_param_t *pos_params_ctx, const wchar_t *format, va_list argptr); int __cdecl @@ -20,5 +33,5 @@ _vscwprintf( nulfile._tmpfname = nulfile._ptr = nulfile._base = NULL; nulfile._bufsiz = nulfile._charbuf = nulfile._cnt = 0; nulfile._flag = _IOSTRG | _IOWRT; - return wstreamout(&nulfile, format, argptr); + return wstreamout(&nulfile, false, NULL, format, argptr); } diff --git a/sdk/lib/crt/printf/_vsprintf_p.c b/sdk/lib/crt/printf/_vsprintf_p.c index 2932b2779e..d857c56913 100644 --- a/sdk/lib/crt/printf/_vsprintf_p.c +++ b/sdk/lib/crt/printf/_vsprintf_p.c @@ -9,5 +9,6 @@ #define _sxprintf _vsprintf_p #define USE_COUNT 1 #define USE_VARARGS 1 +#define USE_POS_PARAMS 1 #include "_sxprintf.c" diff --git a/sdk/lib/crt/printf/streamout.c b/sdk/lib/crt/printf/streamout.c index 2886ad63d1..b3d7c1b01f 100644 --- a/sdk/lib/crt/printf/streamout.c +++ b/sdk/lib/crt/printf/streamout.c @@ -13,12 +13,25 @@ #include #include #include +#include + +#ifdef _UNICODE +# include +# define _isdigit iswdigit +#else +# include +# define _isdigit isdigit +#endif #ifdef _UNICODE # define streamout wstreamout # define format_float format_floatw #endif +/* MB_CUR_MAX is also defined in , to avoid clashing, + * just undefine it first */ +#undef MB_CUR_MAX + #define MB_CUR_MAX 10 #define BUFFER_SIZE (32 + 17) @@ -85,7 +98,8 @@ format_float( int precision, TCHAR **string, const TCHAR **prefix, - va_list *argptr) + long double fpval) + /*va_list *argptr)*/ { static const TCHAR digits_l[] = _T("0123456789abcdef0x"); static const TCHAR digits_u[] = _T("0123456789ABCDEF0X"); @@ -93,7 +107,7 @@ format_float( static const TCHAR _infinity[] = _T("#INF"); const TCHAR *digits = digits_l; int exponent = 0, sign; - long double fpval, fpval2; + long double fpval2; int padding = 0, num_digits, val32, base = 10; /* Normalize the precision */ @@ -104,8 +118,7 @@ format_float( precision = 17; } - /* Get the float value and calculate the exponent */ - fpval = va_arg_ffp(*argptr, flags); + /* Calculate the exponent */ exponent = get_exp(fpval); sign = fpval < 0 ? -1 : 1; @@ -321,9 +334,32 @@ streamout_wstring(FILE *stream, const wchar_t *string, size_t count) # define USE_MULTISIZE 1 #endif +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; + +static inline const TCHAR* _parse_int(const TCHAR *fmt, int *val) +{ + *val = 0; + + while(_isdigit(*fmt)) { + *val *= 10; + *val += *fmt++ - '0'; + } + + return fmt; +} + int __cdecl -streamout(FILE *stream, const TCHAR *format, va_list argptr) +streamout(FILE *stream, bool use_pos_params, pos_param_t *pos_params_ctx, const TCHAR *format, va_list argptr) { static const TCHAR digits_l[] = _T("0123456789abcdef0x"); static const TCHAR digits_u[] = _T("0123456789ABCDEF0X"); @@ -337,6 +373,11 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) int written = 1, written_all = 0; unsigned int flags; unsigned __int64 val64; + int pp_pos; + +#ifndef _USER32_WSPRINTF + int pp_width, pp_precision; +#endif buffer[BUFFER_SIZE] = '\0'; @@ -357,6 +398,10 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) continue; } + /* check for parameter position,if exsits */ + if (use_pos_params && (format = _parse_int(--format, &pp_pos)) && (chr=*format++) == _T('$')) + chr = *format++; + /* Handle flags */ flags = 0; while (1) @@ -378,7 +423,11 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) written_all += written; continue; #else - fieldwidth = va_arg(argptr, int); + if (use_pos_params && (format = _parse_int(format, &pp_width)) && (chr=*format++) == _T('$')) + fieldwidth = pos_params_ctx[pp_width].value.int_val; + else + fieldwidth = va_arg(argptr, int); + if (fieldwidth < 0) { flags |= FLAG_ALIGN_LEFT; @@ -409,7 +458,11 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) written_all += written; continue; #else - precision = va_arg(argptr, int); + if (use_pos_params && (format = _parse_int(format, &pp_precision)) && (chr=*format++) == _T('$')) + precision = pos_params_ctx[pp_precision].value.int_val; + else + precision = va_arg(argptr, int); + chr = *format++; #endif } @@ -470,12 +523,24 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) switch (chr) { case _T('n'): - if (flags & FLAG_INT64) - *va_arg(argptr, __int64*) = written_all; - else if (flags & FLAG_SHORT) - *va_arg(argptr, short*) = written_all; - else - *va_arg(argptr, int*) = written_all; + if (use_pos_params) + { + if (flags & FLAG_INT64) + *(__int64*)(pos_params_ctx[pp_pos].value.ptr_val) = written_all; + else if (flags & FLAG_SHORT) + *(short*)(pos_params_ctx[pp_pos].value.ptr_val) = written_all; + else + *(int*)(pos_params_ctx[pp_pos].value.ptr_val) = written_all; + } + else + { + if (flags & FLAG_INT64) + *va_arg(argptr, __int64*) = written_all; + else if (flags & FLAG_SHORT) + *va_arg(argptr, short*) = written_all; + else + *va_arg(argptr, int*) = written_all; + } continue; case _T('C'): @@ -493,18 +558,27 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) len = 1; if (flags & FLAG_WIDECHAR) { - ((wchar_t*)string)[0] = va_arg(argptr, int); + if (use_pos_params) + ((wchar_t*)string)[0] = pos_params_ctx[pp_pos].value.int_val; + else + ((wchar_t*)string)[0] = va_arg(argptr, int); ((wchar_t*)string)[1] = _T('\0'); } else { - ((char*)string)[0] = va_arg(argptr, int); + if (use_pos_params) + ((char*)string)[0] = pos_params_ctx[pp_pos].value.int_val; + else + ((char*)string)[0] = va_arg(argptr, int); ((char*)string)[1] = _T('\0'); } break; case _T('Z'): - nt_string = va_arg(argptr, void*); + if (use_pos_params) + nt_string = pos_params_ctx[pp_pos].value.ptr_val; + else + nt_string = va_arg(argptr, void*); if (nt_string && (string = nt_string->Buffer)) { len = nt_string->Length; @@ -515,14 +589,20 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) goto case_string; case _T('S'): - string = va_arg(argptr, void*); + if (use_pos_params) + string = pos_params_ctx[pp_pos].value.ptr_val; + else + string = va_arg(argptr, void*); #ifndef _UNICODE if (!(flags & FLAG_SHORT)) flags |= FLAG_WIDECHAR; #endif goto case_string; case _T('s'): - string = va_arg(argptr, void*); + if (use_pos_params) + string = pos_params_ctx[pp_pos].value.ptr_val; + else + string = va_arg(argptr, void*); #ifdef _UNICODE if (!(flags & FLAG_SHORT)) flags |= FLAG_WIDECHAR; #endif @@ -555,7 +635,12 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) flags &= ~FLAG_WIDECHAR; #endif /* Use external function, one for kernel one for user mode */ - format_float(chr, flags, precision, &string, &prefix, &argptr); + long double fpval; + if (use_pos_params) + fpval = pos_params_ctx[pp_pos].value.double_val; // FIXME: to support long double. + else + fpval = va_arg_ffp(argptr, flags); + format_float(chr, flags, precision, &string, &prefix, fpval); len = _tcslen(string); precision = 0; break; @@ -563,7 +648,17 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) case _T('d'): case _T('i'): - val64 = (__int64)va_arg_f(argptr, flags); + if (use_pos_params) + { + if (flags & FLAG_INT64) + val64 = (__int64)(pos_params_ctx[pp_pos].value.longlong_val); + else if (flags & FLAG_SHORT) + val64 = (__int64)(short)(pos_params_ctx[pp_pos].value.int_val); + else + val64 = (__int64)(pos_params_ctx[pp_pos].value.int_val); + } + else + val64 = (__int64)va_arg_f(argptr, flags); if ((__int64)val64 < 0) { @@ -608,7 +703,17 @@ streamout(FILE *stream, const TCHAR *format, va_list argptr) case _T('u'): case_unsigned: - val64 = va_arg_fu(argptr, flags); + if (use_pos_params) + { + if (flags & FLAG_INT64) + val64 = (unsigned __int64)(pos_params_ctx[pp_pos].value.longlong_val); + else if (flags & FLAG_SHORT) + val64 = (unsigned short)(pos_params_ctx[pp_pos].value.int_val); + else + val64 = pos_params_ctx[pp_pos].value.int_val; + } + else + val64 = va_arg_fu(argptr, flags); case_number: #ifdef _UNICODE diff --git a/sdk/lib/crt/printf/vfprintf.c b/sdk/lib/crt/printf/vfprintf.c index 492e897cf4..417deb4b69 100644 --- a/sdk/lib/crt/printf/vfprintf.c +++ b/sdk/lib/crt/printf/vfprintf.c @@ -8,8 +8,21 @@ #include #include +#include +#include -int __cdecl streamout(FILE *stream, const char *format, va_list argptr); +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; + +int _cdecl streamout(FILE *stream, bool use_pos_params, pos_param_t *pos_params_ctx, const TCHAR *format, va_list argptr); int __cdecl @@ -18,7 +31,7 @@ vfprintf(FILE *file, const char *format, va_list argptr) int result; _lock_file(file); - result = streamout(file, format, argptr); + result = streamout(file, false, NULL, format, argptr); _unlock_file(file); return result; diff --git a/sdk/lib/crt/printf/vfprintf_s.c b/sdk/lib/crt/printf/vfprintf_s.c index 6a43d009ad..5ab39806ac 100644 --- a/sdk/lib/crt/printf/vfprintf_s.c +++ b/sdk/lib/crt/printf/vfprintf_s.c @@ -11,8 +11,21 @@ #include #include #include +#include +#include -int __cdecl streamout(FILE *stream, const char *format, va_list argptr); +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; + +int _cdecl streamout(FILE *stream, bool use_pos_params, pos_param_t *pos_params_ctx, const TCHAR *format, va_list argptr); int __cdecl @@ -26,7 +39,7 @@ vfprintf_s(FILE* file, const char *format, va_list argptr) } _lock_file(file); - result = streamout(file, format, argptr); + result = streamout(file, false, NULL, format, argptr); _unlock_file(file); return result; diff --git a/sdk/lib/crt/printf/vfwprintf.c b/sdk/lib/crt/printf/vfwprintf.c index 081450de98..331303c0ee 100644 --- a/sdk/lib/crt/printf/vfwprintf.c +++ b/sdk/lib/crt/printf/vfwprintf.c @@ -8,8 +8,20 @@ #include #include +#include -int __cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr); +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; + +int _cdecl wstreamout(FILE *stream, bool use_pos_params, pos_param_t *pos_params_ctx, const wchar_t *format, va_list argptr); int __cdecl @@ -18,7 +30,7 @@ vfwprintf(FILE* file, const wchar_t *format, va_list argptr) int ret; _lock_file(file); - ret = wstreamout(file, format, argptr); + ret = wstreamout(file, false, NULL, format, argptr); _unlock_file(file); return ret; diff --git a/sdk/lib/crt/printf/vfwprintf_s.c b/sdk/lib/crt/printf/vfwprintf_s.c index c45a82128c..9de5f27588 100644 --- a/sdk/lib/crt/printf/vfwprintf_s.c +++ b/sdk/lib/crt/printf/vfwprintf_s.c @@ -12,8 +12,20 @@ #include #include #include +#include -int __cdecl wstreamout(FILE *stream, const wchar_t *format, va_list argptr); +typedef struct _pos_param +{ + int type; + union { + void *ptr_val; + int int_val; + long long longlong_val; + double double_val; + } value; +} pos_param_t; + +int _cdecl wstreamout(FILE *stream, bool use_pos_params, pos_param_t* pos_params_ctx, const wchar_t *format, va_list argptr); int __cdecl @@ -27,7 +39,7 @@ vfwprintf_s(FILE* file, const wchar_t *format, va_list argptr) } _lock_file(file); - ret = wstreamout(file, format, argptr); + ret = wstreamout(file, false, NULL, format, argptr); _unlock_file(file); return ret;