Move vsnwprintf implementation to libwine_unicode, export snprintfW
and vsnprintfW from there, forward MSVCRT and NTDLL functions to libwine_unicode.
This commit is contained in:
parent
147e2fa467
commit
ad068bc0c2
|
@ -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 )
|
||||
{
|
||||
|
|
131
unicode/string.c
131
unicode/string.c
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue