"Alexandre Julliard" <julliard@winehq.com> wrote: > > Is it acceptable to simply copy the whole NTDLL_vsnwprintf to libwine_unicode? > > Well it should of course be a move, not a copy; but yes that's fine. Something like this? Changelog: Move vsnwprintf implementation to libwine_unicode, export snprintfW and vsnprintfW from there, forward MSVCRT and NTDLL functions to libwine_unicode. diff -u cvs/hq/wine/dlls/msvcrt/wcs.c wine/dlls/msvcrt/wcs.c --- cvs/hq/wine/dlls/msvcrt/wcs.c Thu Dec 19 17:19:55 2002 +++ wine/dlls/msvcrt/wcs.c Wed Mar 12 16:01:47 2003 @@ -117,124 +117,7 @@ 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 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 ); } /********************************************************************* diff -u cvs/hq/wine/dlls/ntdll/wcstring.c wine/dlls/ntdll/wcstring.c --- cvs/hq/wine/dlls/ntdll/wcstring.c Sat Sep 14 21:33:35 2002 +++ wine/dlls/ntdll/wcstring.c Wed Mar 12 16:32:23 2003 @@ -386,131 +386,6 @@ return NTDLL__wtol(string); } -/* 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.@) @@ -520,7 +395,7 @@ 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; } @@ -534,7 +409,7 @@ 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; } diff -u cvs/hq/wine/include/wine/unicode.h wine/include/wine/unicode.h --- cvs/hq/wine/include/wine/unicode.h Fri Jan 3 13:20:59 2003 +++ wine/include/wine/unicode.h Wed Mar 12 16:11:33 2003 @@ -76,6 +76,8 @@ 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 ) { diff -u cvs/hq/wine/unicode/string.c wine/unicode/string.c --- cvs/hq/wine/unicode/string.c Sat May 18 16:24:54 2002 +++ wine/unicode/string.c Wed Mar 12 16:18:36 2003 @@ -19,6 +19,7 @@ */ #include <limits.h> +#include <stdio.h> #include "wine/unicode.h" @@ -285,4 +286,134 @@ } 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; } diff -u cvs/hq/wine/unicode/wine_unicode.def wine/unicode/wine_unicode.def --- cvs/hq/wine/unicode/wine_unicode.def Mon May 20 21:59:34 2002 +++ wine/unicode/wine_unicode.def Wed Mar 12 16:07:39 2003 @@ -5,6 +5,7 @@ cp_get_table cp_mbstowcs cp_wcstombs + snprintfW strcmpiW strncmpiW strstrW @@ -12,4 +13,5 @@ strtoulW utf8_mbstowcs utf8_wcstombs + vsnprintfW wctype_table