Module: wine Branch: master Commit: 7d384d23f80926de887c4635e7b39835303b507a URL: http://source.winehq.org/git/wine.git/?a=commit;h=7d384d23f80926de887c4635e7...
Author: Eric Pouech eric.pouech@orange.fr Date: Sun Nov 7 19:11:32 2010 +0100
msvcrt: For internal msvcrt use, added ability to grow automatically the size of the buffer in printf core engine.
---
dlls/msvcrt/msvcrt.h | 18 ++++++++++++ dlls/msvcrt/wcs.c | 71 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 70 insertions(+), 19 deletions(-)
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 2e8263e..b14a326 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -861,4 +861,22 @@ void __cdecl MSVCRT__invalid_parameter(const MSVCRT_wchar_t *expr, const MSVCRT_ #define MSVCRT_CHECK_PMT(x) ((x) || (MSVCRT_INVALID_PMT(0),FALSE)) #endif
+typedef struct pf_output_t +{ + int used; + int len; + BOOL unicode; + union { + LPWSTR W; + LPSTR A; + } buf; + union { + LPWSTR W; + LPSTR A; + } grow; +} pf_output; + +int pf_vsnprintf( pf_output *out, const WCHAR *format, + MSVCRT__locale_t locale, BOOL valid, __ms_va_list valist ); + #endif /* __WINE_MSVCRT_H */ diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 48831b2..922e9d3 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -361,17 +361,6 @@ double CDECL MSVCRT__wtof_l(const MSVCRT_wchar_t *str, MSVCRT__locale_t locale) return MSVCRT__wcstod_l(str, NULL, locale); }
-typedef struct pf_output_t -{ - int used; - int len; - BOOL unicode; - union { - LPWSTR W; - LPSTR A; - } buf; -} pf_output; - typedef struct pf_flags_t { char Sign, LeftAlign, Alternate, PadZero; @@ -381,6 +370,36 @@ typedef struct pf_flags_t char Format; } pf_flags;
+static inline BOOL pf_is_auto_grow(pf_output *out) +{ + return (out->unicode) ? !!out->grow.W : !!out->grow.A; +} + +static inline int pf_check_auto_grow(pf_output *out, unsigned delta) +{ + if (pf_is_auto_grow(out) && out->used + delta > out->len) + { + out->len = max(out->len * 2, out->used + delta); + if (out->unicode) + { + if (out->buf.W != out->grow.W) + out->buf.W = MSVCRT_realloc(out->buf.W, out->len * sizeof(WCHAR)); + else + out->buf.W = MSVCRT_malloc(out->len * sizeof(WCHAR)); + if (!out->buf.W) return -1; + } + else + { + if (out->buf.A != out->grow.A) + out->buf.A = MSVCRT_realloc(out->buf.A, out->len * sizeof(char)); + else + out->buf.A = MSVCRT_malloc(out->len * sizeof(char)); + if (!out->buf.A) return -1; + } + } + return 0; +} + /* * writes a string of characters to the output * returns -1 if the string doesn't fit in the output buffer @@ -388,14 +407,17 @@ typedef struct pf_flags_t */ static inline int pf_output_stringW( pf_output *out, LPCWSTR str, int len ) { - int space = out->len - out->used; + int space;
if( len < 0 ) len = strlenW( str ); if( out->unicode ) { - LPWSTR p = out->buf.W + out->used; + LPWSTR p;
+ if(pf_check_auto_grow(out, len) == -1) return -1; + space = out->len - out->used; + p = out->buf.W + out->used; if( space >= len ) { if (out->buf.W) memcpy( p, str, len*sizeof(WCHAR) ); @@ -409,8 +431,11 @@ static inline int pf_output_stringW( pf_output *out, LPCWSTR str, int len ) else { int n = WideCharToMultiByte( CP_ACP, 0, str, len, NULL, 0, NULL, NULL ); - LPSTR p = out->buf.A + out->used; + LPSTR p;
+ if(pf_check_auto_grow(out, n) == -1) return -1; + space = out->len - out->used; + p = out->buf.A + out->used; if( space >= n ) { if (out->buf.A) WideCharToMultiByte( CP_ACP, 0, str, len, p, n, NULL, NULL ); @@ -426,14 +451,17 @@ static inline int pf_output_stringW( pf_output *out, LPCWSTR str, int len )
static inline int pf_output_stringA( pf_output *out, LPCSTR str, int len ) { - int space = out->len - out->used; + int space;
if( len < 0 ) len = strlen( str ); if( !out->unicode ) { - LPSTR p = out->buf.A + out->used; + LPSTR p;
+ if (pf_check_auto_grow(out, len) == -1) return -1; + p = out->buf.A + out->used; + space = out->len - out->used; if( space >= len ) { if (out->buf.A) memcpy( p, str, len ); @@ -447,8 +475,11 @@ static inline int pf_output_stringA( pf_output *out, LPCSTR str, int len ) else { int n = MultiByteToWideChar( CP_ACP, 0, str, len, NULL, 0 ); - LPWSTR p = out->buf.W + out->used; + LPWSTR p;
+ if (pf_check_auto_grow(out, n) == -1) return -1; + p = out->buf.W + out->used; + space = out->len - out->used; if( space >= n ) { if (out->buf.W) MultiByteToWideChar( CP_ACP, 0, str, len, p, n ); @@ -723,8 +754,8 @@ static void pf_fixup_exponent( char *buf ) * * implements both A and W vsnprintf functions */ -static int pf_vsnprintf( pf_output *out, const WCHAR *format, - MSVCRT__locale_t locale, BOOL valid, __ms_va_list valist ) +int pf_vsnprintf( pf_output *out, const WCHAR *format, + MSVCRT__locale_t locale, BOOL valid, __ms_va_list valist ) { int r; LPCWSTR q, p = format; @@ -1000,6 +1031,7 @@ static inline int vsnprintf_internal( char *str, MSVCRT_size_t len, const char *
out.unicode = FALSE; out.buf.A = str; + out.grow.A = NULL; out.used = 0; out.len = len;
@@ -1146,6 +1178,7 @@ static inline int vsnwprintf_internal(MSVCRT_wchar_t *str, MSVCRT_size_t len,
out.unicode = TRUE; out.buf.W = str; + out.grow.W = NULL; out.used = 0; out.len = len;