Commit ad068bc0 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Move vsnwprintf implementation to libwine_unicode, export snprintfW

and vsnprintfW from there, forward MSVCRT and NTDLL functions to libwine_unicode.
parent 147e2fa4
......@@ -117,124 +117,7 @@ MSVCRT_wchar_t* _wcsset( MSVCRT_wchar_t* str, MSVCRT_wchar_t c )
int _vsnwprintf(MSVCRT_wchar_t *str, unsigned int len,
const MSVCRT_wchar_t *format, va_list valist)
{
/* If you fix a bug in this function, fix it in ntdll/wcstring.c also! */
unsigned int written = 0;
const MSVCRT_wchar_t *iter = format;
char bufa[256], fmtbufa[64], *fmta;
TRACE("(%d,%s)\n",len,debugstr_w(format));
while (*iter)
{
while (*iter && *iter != '%')
{
if (written++ >= len)
return -1;
*str++ = *iter++;
}
if (*iter == '%')
{
fmta = fmtbufa;
*fmta++ = *iter++;
while (*iter == '0' ||
*iter == '+' ||
*iter == '-' ||
*iter == ' ' ||
*iter == '0' ||
*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 MSVCRT_wchar_t none[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
const MSVCRT_wchar_t *wstr = va_arg(valist, const MSVCRT_wchar_t *);
const MSVCRT_wchar_t *striter = wstr ? wstr : none;
while (*striter)
{
if (written++ >= len)
return -1;
*str++ = *striter++;
}
iter++;
break;
}
case 'c':
if (written++ >= len)
return -1;
*str++ = (MSVCRT_wchar_t)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 == 'f')
sprintf(bufaiter, fmtbufa, va_arg(valist, double));
else
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;
return vsnprintfW(str, len, format, valist);
}
/*********************************************************************
......@@ -242,7 +125,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 _vsnwprintf( str, INT_MAX, format, args );
return vsnprintfW( str, INT_MAX, format, args );
}
/*********************************************************************
......
......@@ -628,131 +628,6 @@ LONGLONG __cdecl _wtoi64( LPWSTR str )
}
/* INTERNAL: Wide char snprintf
* If you fix a bug in this function, fix it in msvcrt/wcs.c also!
*/
static int __cdecl NTDLL_vsnwprintf(WCHAR *str, unsigned int len,
const WCHAR *format, va_list valist)
{
unsigned int written = 0;
const WCHAR *iter = format;
char bufa[256], fmtbufa[64], *fmta;
TRACE("(%d,%s)\n",len,debugstr_w(format));
while (*iter)
{
while (*iter && *iter != (WCHAR)L'%')
{
if (written++ >= len)
return -1;
*str++ = *iter++;
}
if (*iter == (WCHAR)L'%')
{
fmta = fmtbufa;
*fmta++ = *iter++;
while (*iter == (WCHAR)L'0' ||
*iter == (WCHAR)L'+' ||
*iter == (WCHAR)L'-' ||
*iter == (WCHAR)L' ' ||
*iter == (WCHAR)L'0' ||
*iter == (WCHAR)L'*' ||
*iter == (WCHAR)L'#')
{
if (*iter == (WCHAR)L'*')
{
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 == (WCHAR)L'.')
{
*fmta++ = *iter++;
if (*iter == (WCHAR)L'*')
{
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 == (WCHAR)L'h' ||
*iter == (WCHAR)L'l')
*fmta++ = *iter++;
switch (*iter)
{
case (WCHAR)L'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 (WCHAR)L'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 == (WCHAR)L'p')
sprintf(bufaiter, "%08lX", va_arg(valist, long));
else
{
*fmta++ = *iter;
*fmta = '\0';
if (*iter == (WCHAR)L'f')
sprintf(bufaiter, fmtbufa, va_arg(valist, double));
else
sprintf(bufaiter, fmtbufa, va_arg(valist, void *));
}
while (*bufaiter)
{
if (written++ >= len)
return -1;
*str++ = *bufaiter++;
}
iter++;
break;
}
}
}
}
if (written >= len)
return -1;
*str++ = (WCHAR)L'\0';
return (int)written;
}
/***********************************************************************
* _snwprintf (NTDLL.@)
......@@ -762,7 +637,7 @@ int __cdecl _snwprintf(WCHAR *str, unsigned int len, const WCHAR *format, ...)
int retval;
va_list valist;
va_start(valist, format);
retval = NTDLL_vsnwprintf(str, len, format, valist);
retval = vsnprintfW(str, len, format, valist);
va_end(valist);
return retval;
}
......@@ -776,7 +651,7 @@ int __cdecl NTDLL_swprintf(WCHAR *str, const WCHAR *format, ...)
int retval;
va_list valist;
va_start(valist, format);
retval = NTDLL_vsnwprintf(str, INT_MAX, format, valist);
retval = vsnprintfW(str, INT_MAX, format, valist);
va_end(valist);
return retval;
}
......@@ -76,6 +76,8 @@ extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n );
extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
extern long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base );
extern unsigned long int strtoulW( const WCHAR *nptr, WCHAR **endptr, int base );
extern int snprintfW( WCHAR *str, unsigned int len, const WCHAR *format, ... );
extern int vsnprintfW( WCHAR *str, unsigned int len, const WCHAR *format, va_list valist );
static inline int is_dbcs_leadbyte( const union cptable *table, unsigned char ch )
{
......
......@@ -19,6 +19,7 @@
*/
#include <limits.h>
#include <stdio.h>
#include "wine/unicode.h"
......@@ -286,3 +287,133 @@ noconv:
return 0L;
}
int vsnprintfW(WCHAR *str, unsigned int 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 == '%')
{
fmta = fmtbufa;
*fmta++ = *iter++;
while (*iter == '0' ||
*iter == '+' ||
*iter == '-' ||
*iter == ' ' ||
*iter == '0' ||
*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 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 == 'f')
sprintf(bufaiter, fmtbufa, va_arg(valist, double));
else
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;
}
int snprintfW(WCHAR *str, unsigned int len, const WCHAR *format, ...)
{
int retval;
va_list valist;
va_start(valist, format);
retval = vsnprintfW(str, len, format, valist);
va_end(valist);
return retval;
}
......@@ -5,6 +5,7 @@ EXPORTS
cp_get_table
cp_mbstowcs
cp_wcstombs
snprintfW
strcmpiW
strncmpiW
strstrW
......@@ -12,4 +13,5 @@ EXPORTS
strtoulW
utf8_mbstowcs
utf8_wcstombs
vsnprintfW
wctype_table
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