Commit db0d0bb3 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Copy the vsnprintfW implementation from libunicode.so to msvcrt and

add a handler for the %S flag. That requires a conversion to unicode and knowledge of the current ASCII code page.
parent b90edfb2
......@@ -718,7 +718,7 @@
@ cdecl strtol(str ptr long)
@ cdecl strtoul(str ptr long)
@ cdecl strxfrm(ptr str long)
@ varargs swprintf(wstr wstr) ntdll.swprintf
@ varargs swprintf(wstr wstr) MSVCRT_swprintf
@ varargs swscanf(wstr wstr) MSVCRT_swscanf
@ cdecl system(str) MSVCRT_system
@ cdecl tan(double)
......
......@@ -184,13 +184,184 @@ double MSVCRT_wcstod(const MSVCRT_wchar_t* lpszStr, MSVCRT_wchar_t** end)
return ret;
}
static int MSVCRT_vsnprintfW(WCHAR *str, size_t len, const WCHAR *format, va_list valist)
{
unsigned int written = 0;
const WCHAR *iter = format;
char bufa[256], fmtbufa[64], *fmta;
while (*iter)
{
while (*iter && *iter != '%')
{
if (written++ >= len)
return -1;
*str++ = *iter++;
}
if (*iter == '%')
{
if (iter[1] == '%')
{
if (written++ >= len)
return -1;
*str++ = '%'; /* "%%"->'%' */
iter += 2;
continue;
}
fmta = fmtbufa;
*fmta++ = *iter++;
while (*iter == '0' ||
*iter == '+' ||
*iter == '-' ||
*iter == ' ' ||
*iter == '*' ||
*iter == '#')
{
if (*iter == '*')
{
char *buffiter = bufa;
int fieldlen = va_arg(valist, int);
sprintf(buffiter, "%d", fieldlen);
while (*buffiter)
*fmta++ = *buffiter++;
}
else
*fmta++ = *iter;
iter++;
}
while (isdigit(*iter))
*fmta++ = *iter++;
if (*iter == '.')
{
*fmta++ = *iter++;
if (*iter == '*')
{
char *buffiter = bufa;
int fieldlen = va_arg(valist, int);
sprintf(buffiter, "%d", fieldlen);
while (*buffiter)
*fmta++ = *buffiter++;
}
else
while (isdigit(*iter))
*fmta++ = *iter++;
}
if (*iter == 'h' || *iter == 'l')
*fmta++ = *iter++;
switch (*iter)
{
case 'S':
{
static const char *none = "(null)";
const char *astr = va_arg(valist, const char *);
const char *striter = astr ? astr : none;
int r, n;
while (*striter)
{
if (written >= len)
return -1;
n = 1;
if( IsDBCSLeadByte( *striter ) )
n++;
r = MultiByteToWideChar( CP_ACP, 0,
striter, n, str, len - written );
striter += n;
str += r;
written += r;
}
iter++;
break;
}
case 's':
{
static const WCHAR none[] = { '(','n','u','l','l',')',0 };
const WCHAR *wstr = va_arg(valist, const WCHAR *);
const WCHAR *striter = wstr ? wstr : none;
while (*striter)
{
if (written++ >= len)
return -1;
*str++ = *striter++;
}
iter++;
break;
}
case 'c':
if (written++ >= len)
return -1;
*str++ = (WCHAR)va_arg(valist, int);
iter++;
break;
default:
{
/* For non wc types, use system sprintf and append to wide char output */
/* FIXME: for unrecognised types, should ignore % when printing */
char *bufaiter = bufa;
if (*iter == 'p')
sprintf(bufaiter, "%08lX", va_arg(valist, long));
else
{
*fmta++ = *iter;
*fmta = '\0';
if (*iter == 'a' || *iter == 'A' ||
*iter == 'e' || *iter == 'E' ||
*iter == 'f' || *iter == 'F' ||
*iter == 'g' || *iter == 'G')
sprintf(bufaiter, fmtbufa, va_arg(valist, double));
else
{
/* FIXME: On 32 bit systems this doesn't handle int 64's.
* on 64 bit systems this doesn't work for 32 bit types
*/
sprintf(bufaiter, fmtbufa, va_arg(valist, void *));
}
}
while (*bufaiter)
{
if (written++ >= len)
return -1;
*str++ = *bufaiter++;
}
iter++;
break;
}
}
}
}
if (written >= len)
return -1;
*str++ = 0;
return (int)written;
}
/*********************************************************************
* swprintf (MSVCRT.@)
*/
int MSVCRT_swprintf( MSVCRT_wchar_t *str, const MSVCRT_wchar_t *format, ... )
{
va_list ap;
int r;
va_start( ap, format );
r = MSVCRT_vsnprintfW( str, INT_MAX, format, ap );
va_end( ap );
return r;
}
/*********************************************************************
* _vsnwprintf (MSVCRT.@)
*/
int _vsnwprintf(MSVCRT_wchar_t *str, unsigned int len,
const MSVCRT_wchar_t *format, va_list valist)
{
return vsnprintfW(str, len, format, valist);
return MSVCRT_vsnprintfW(str, len, format, valist);
}
/*********************************************************************
......@@ -198,7 +369,7 @@ int _vsnwprintf(MSVCRT_wchar_t *str, unsigned int len,
*/
int MSVCRT_vswprintf( MSVCRT_wchar_t* str, const MSVCRT_wchar_t* format, va_list args )
{
return vsnprintfW( str, INT_MAX, format, args );
return MSVCRT_vsnprintfW( str, INT_MAX, format, args );
}
/*********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment