From db0d0bb39bfd362c92ede6ac24c6892f890a3c37 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 2 Jun 2004 00:35:09 +0000 Subject: [PATCH] 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. --- dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/wcs.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 174 insertions(+), 3 deletions(-) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 445726e684a..4ed4111814a 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -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) diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 3698ec4c5f2..0a346e69e4a 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -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 ); } /********************************************************************* -- 2.11.4.GIT