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,
|
int _vsnwprintf(MSVCRT_wchar_t *str, unsigned int len,
|
||||||
const MSVCRT_wchar_t *format, va_list valist)
|
const MSVCRT_wchar_t *format, va_list valist)
|
||||||
{
|
{
|
||||||
/* If you fix a bug in this function, fix it in ntdll/wcstring.c also! */
|
return vsnprintfW(str, len, format, valist);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
@ -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 )
|
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.@)
|
* _snwprintf (NTDLL.@)
|
||||||
|
@ -762,7 +637,7 @@ int __cdecl _snwprintf(WCHAR *str, unsigned int len, const WCHAR *format, ...)
|
||||||
int retval;
|
int retval;
|
||||||
va_list valist;
|
va_list valist;
|
||||||
va_start(valist, format);
|
va_start(valist, format);
|
||||||
retval = NTDLL_vsnwprintf(str, len, format, valist);
|
retval = vsnprintfW(str, len, format, valist);
|
||||||
va_end(valist);
|
va_end(valist);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -776,7 +651,7 @@ int __cdecl NTDLL_swprintf(WCHAR *str, const WCHAR *format, ...)
|
||||||
int retval;
|
int retval;
|
||||||
va_list valist;
|
va_list valist;
|
||||||
va_start(valist, format);
|
va_start(valist, format);
|
||||||
retval = NTDLL_vsnwprintf(str, INT_MAX, format, valist);
|
retval = vsnprintfW(str, INT_MAX, format, valist);
|
||||||
va_end(valist);
|
va_end(valist);
|
||||||
return retval;
|
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 WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
|
||||||
extern long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base );
|
extern long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base );
|
||||||
extern unsigned long int strtoulW( 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 )
|
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 <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
|
@ -286,3 +287,133 @@ noconv:
|
||||||
|
|
||||||
return 0L;
|
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_get_table
|
||||||
cp_mbstowcs
|
cp_mbstowcs
|
||||||
cp_wcstombs
|
cp_wcstombs
|
||||||
|
snprintfW
|
||||||
strcmpiW
|
strcmpiW
|
||||||
strncmpiW
|
strncmpiW
|
||||||
strstrW
|
strstrW
|
||||||
|
@ -12,4 +13,5 @@ EXPORTS
|
||||||
strtoulW
|
strtoulW
|
||||||
utf8_mbstowcs
|
utf8_mbstowcs
|
||||||
utf8_wcstombs
|
utf8_wcstombs
|
||||||
|
vsnprintfW
|
||||||
wctype_table
|
wctype_table
|
||||||
|
|
Loading…
Reference in New Issue