Fix mingw wprintf family function for _O_U8TEXT modeThis patch uses __ms_fwprintf function for '%ls', '%lc', '%s', '%c' and literal strings in mingw wprintf family function. It works with _O_U8TEXT mode and is much faster.
Please review.
diff --git a/mingw-w64-crt/lib32/msvcr100.def.in b/mingw-w64-crt/lib32/msvcr100.def.in index a1d7447..d103a2b 100644 --- a/mingw-w64-crt/lib32/msvcr100.def.in +++ b/mingw-w64-crt/lib32/msvcr100.def.in @@ -1724,6 +1724,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib32/msvcr110.def.in b/mingw-w64-crt/lib32/msvcr110.def.in index f9f0294..7296955 100644 --- a/mingw-w64-crt/lib32/msvcr110.def.in +++ b/mingw-w64-crt/lib32/msvcr110.def.in @@ -1857,6 +1857,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib32/msvcr120.def.in b/mingw-w64-crt/lib32/msvcr120.def.in index c3158eb..57122cb 100644 --- a/mingw-w64-crt/lib32/msvcr120.def.in +++ b/mingw-w64-crt/lib32/msvcr120.def.in @@ -2018,6 +2018,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib32/msvcr120_app.def.in b/mingw-w64-crt/lib32/msvcr120_app.def.in index 579edb3..b29eaf9 100644 --- a/mingw-w64-crt/lib32/msvcr120_app.def.in +++ b/mingw-w64-crt/lib32/msvcr120_app.def.in @@ -1374,6 +1374,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib32/msvcr120d.def.in b/mingw-w64-crt/lib32/msvcr120d.def.in index f676867..194a0d2 100644 --- a/mingw-w64-crt/lib32/msvcr120d.def.in +++ b/mingw-w64-crt/lib32/msvcr120d.def.in @@ -2085,6 +2085,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib32/msvcr80.def.in b/mingw-w64-crt/lib32/msvcr80.def.in index f3408b9..79cd7dd 100644 --- a/mingw-w64-crt/lib32/msvcr80.def.in +++ b/mingw-w64-crt/lib32/msvcr80.def.in @@ -587,6 +587,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwrite fwscanf getc diff --git a/mingw-w64-crt/lib32/msvcr90.def.in b/mingw-w64-crt/lib32/msvcr90.def.in index 394d7f5..861ce56 100644 --- a/mingw-w64-crt/lib32/msvcr90.def.in +++ b/mingw-w64-crt/lib32/msvcr90.def.in @@ -1358,6 +1358,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib32/msvcr90d.def.in b/mingw-w64-crt/lib32/msvcr90d.def.in index 8846e13..419c65c 100644 --- a/mingw-w64-crt/lib32/msvcr90d.def.in +++ b/mingw-w64-crt/lib32/msvcr90d.def.in @@ -1430,6 +1430,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib32/msvcrt.def.in b/mingw-w64-crt/lib32/msvcrt.def.in index 71bdf56..6cc95a0 100644 --- a/mingw-w64-crt/lib32/msvcrt.def.in +++ b/mingw-w64-crt/lib32/msvcrt.def.in @@ -585,6 +585,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwrite fwscanf getc diff --git a/mingw-w64-crt/lib64/msvcr100.def.in b/mingw-w64-crt/lib64/msvcr100.def.in index a3ba8cd..b3be302 100644 --- a/mingw-w64-crt/lib64/msvcr100.def.in +++ b/mingw-w64-crt/lib64/msvcr100.def.in @@ -1679,6 +1679,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib64/msvcr110.def.in b/mingw-w64-crt/lib64/msvcr110.def.in index 6e8a487..5986892 100644 --- a/mingw-w64-crt/lib64/msvcr110.def.in +++ b/mingw-w64-crt/lib64/msvcr110.def.in @@ -1803,6 +1803,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib64/msvcr120.def.in b/mingw-w64-crt/lib64/msvcr120.def.in index 8784981..7afa0da 100644 --- a/mingw-w64-crt/lib64/msvcr120.def.in +++ b/mingw-w64-crt/lib64/msvcr120.def.in @@ -1967,6 +1967,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib64/msvcr120_app.def.in b/mingw-w64-crt/lib64/msvcr120_app.def.in index 8c60b42..53b2f7b 100644 --- a/mingw-w64-crt/lib64/msvcr120_app.def.in +++ b/mingw-w64-crt/lib64/msvcr120_app.def.in @@ -1326,6 +1326,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib64/msvcr120d.def.in b/mingw-w64-crt/lib64/msvcr120d.def.in index 2aab635..f5304d4 100644 --- a/mingw-w64-crt/lib64/msvcr120d.def.in +++ b/mingw-w64-crt/lib64/msvcr120d.def.in @@ -2032,6 +2032,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib64/msvcr80.def.in b/mingw-w64-crt/lib64/msvcr80.def.in index 18b8d2d..c84be87 100644 --- a/mingw-w64-crt/lib64/msvcr80.def.in +++ b/mingw-w64-crt/lib64/msvcr80.def.in @@ -713,6 +713,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwrite fwscanf getc diff --git a/mingw-w64-crt/lib64/msvcr90.def.in b/mingw-w64-crt/lib64/msvcr90.def.in index 7b74907..f18166a 100644 --- a/mingw-w64-crt/lib64/msvcr90.def.in +++ b/mingw-w64-crt/lib64/msvcr90.def.in @@ -1299,6 +1299,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib64/msvcr90d.def.in b/mingw-w64-crt/lib64/msvcr90d.def.in index 4649135..0775538 100644 --- a/mingw-w64-crt/lib64/msvcr90d.def.in +++ b/mingw-w64-crt/lib64/msvcr90d.def.in @@ -1365,6 +1365,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/lib64/msvcrt.def.in b/mingw-w64-crt/lib64/msvcrt.def.in index 946c200..0873041 100644 --- a/mingw-w64-crt/lib64/msvcrt.def.in +++ b/mingw-w64-crt/lib64/msvcrt.def.in @@ -1084,6 +1084,7 @@ fseek fsetpos ftell fwprintf +__ms_fwprintf == fwprintf fwprintf_s fwrite fwscanf diff --git a/mingw-w64-crt/stdio/mingw_pformat.c b/mingw-w64-crt/stdio/mingw_pformat.c index c9808f9..d193519 100644 --- a/mingw-w64-crt/stdio/mingw_pformat.c +++ b/mingw-w64-crt/stdio/mingw_pformat.c @@ -465,6 +465,7 @@ void __pformat_putc( int c, __pformat_t *stream ) static void __pformat_putchars( const char *s, int count, __pformat_t *stream ) { +#ifndef __BUILD_WIDEAPI /* Handler for `%c' and (indirectly) `%s' conversion specifications. * * Transfer characters from the string buffer at `s', character by @@ -508,7 +509,56 @@ void __pformat_putchars( const char *s, int count, __pformat_t *stream ) /* Emit the data... */ -#ifdef __BUILD_WIDEAPI + while( count-- ) + /* + * copying the requisite number of characters from the input. + */ + __pformat_putc( *s++, stream ); + + /* If we still haven't consumed the entire specified field width, + * we must be doing flush left justification; any residual width + * must be filled with blanks, to the right of the output value. + */ + while( stream->width-- > 0 ) + __pformat_putc( '\x20', stream ); + +#else /* __BUILD_WIDEAPI */ + + int len; + + if( (stream->precision >= 0) && (count > stream->precision) ) + count = stream->precision; + + if( (stream->flags & PFORMAT_TO_FILE) && (stream->flags & PFORMAT_NOLIMIT) ) + { + int __cdecl __ms_fwprintf(FILE *, const wchar_t *, ...); + + if( stream->width > count ) + { + if( (stream->flags & PFORMAT_LJUSTIFY) == 0 ) + len = __ms_fwprintf( (FILE *)(stream->dest), L"%*.*S", stream->width, count, s ); + else + len = __ms_fwprintf( (FILE *)(stream->dest), L"%-*.*S", stream->width, count, s ); + } + else + { + len = __ms_fwprintf( (FILE *)(stream->dest), L"%.*S", count, s ); + } + if( len > 0 ) + stream->count += len; + stream->width = PFORMAT_IGNORE; + return; + } + + if( stream->width > count ) + stream->width -= count; + else + stream->width = PFORMAT_IGNORE; + + if( (stream->width > 0) && ((stream->flags & PFORMAT_LJUSTIFY) == 0) ) + while( stream->width-- ) + __pformat_putc( '\x20', stream ); + { /* mbrtowc */ size_t l; @@ -531,20 +581,11 @@ void __pformat_putchars( const char *s, int count, __pformat_t *stream ) __pformat_putc((int)w[0], stream); } } -#else - while( count-- ) - /* - * copying the requisite number of characters from the input. - */ - __pformat_putc( *s++, stream ); -#endif - /* If we still haven't consumed the entire specified field width, - * we must be doing flush left justification; any residual width - * must be filled with blanks, to the right of the output value. - */ while( stream->width-- > 0 ) __pformat_putc( '\x20', stream ); + +#endif /* __BUILD_WIDEAPI */ } static @@ -563,12 +604,17 @@ void __pformat_puts( const char *s, __pformat_t *stream ) * (after first verifying that the input pointer is not NULL). */ if( s == NULL ) s = "(null)"; - __pformat_putchars( s, strlen( s ), stream ); + + if( stream->precision >= 0 ) + __pformat_putchars( s, strnlen( s, stream->precision ), stream ); + else + __pformat_putchars( s, strlen( s ), stream ); } static void __pformat_wputchars( const wchar_t *s, int count, __pformat_t *stream ) { +#ifndef __BUILD_WIDEAPI /* Handler for `%C'(`%lc') and `%S'(`%ls') conversion specifications; * (this is a wide character variant of `__pformat_putchars()'). * @@ -613,27 +659,67 @@ void __pformat_wputchars( const wchar_t *s, int count, __pformat_t *stream ) /* Emit the data, converting each character from the wide * to the multibyte domain as we go... */ -#ifdef __BUILD_WIDEAPI - len = count; - while(len-- > 0 && *s != 0) - { - __pformat_putc(*s++, stream); - } - count = len; -#else while( (count-- > 0) && ((len = wcrtomb( buf, *s++, &state )) > 0) ) { char *p = buf; while( len-- > 0 ) __pformat_putc( *p++, stream ); } -#endif + /* If we still haven't consumed the entire specified field width, * we must be doing flush left justification; any residual width * must be filled with blanks, to the right of the output value. */ while( stream->width-- > 0 ) __pformat_putc( '\x20', stream ); + +#else /* __BUILD_WIDEAPI */ + + int len; + + if( (stream->precision >= 0) && (count > stream->precision) ) + count = stream->precision; + + if( (stream->flags & PFORMAT_TO_FILE) && (stream->flags & PFORMAT_NOLIMIT) ) + { + int __cdecl __ms_fwprintf(FILE *, const wchar_t *, ...); + + if( stream->width > count ) + { + if( (stream->flags & PFORMAT_LJUSTIFY) == 0 ) + len = __ms_fwprintf( (FILE *)(stream->dest), L"%*.*s", stream->width, count, s ); + else + len = __ms_fwprintf( (FILE *)(stream->dest), L"%-*.*s", stream->width, count, s ); + } + else + { + len = __ms_fwprintf( (FILE *)(stream->dest), L"%.*s", count, s ); + } + if( len > 0 ) + stream->count += len; + stream->width = PFORMAT_IGNORE; + return; + } + + if( stream->width > count ) + stream->width -= count; + else + stream->width = PFORMAT_IGNORE; + + if( (stream->width > 0) && ((stream->flags & PFORMAT_LJUSTIFY) == 0) ) + while( stream->width-- ) + __pformat_putc( '\x20', stream ); + + len = count; + while(len-- > 0 && *s != 0) + { + __pformat_putc(*s++, stream); + } + + while( stream->width-- > 0 ) + __pformat_putc( '\x20', stream ); + +#endif /* __BUILD_WIDEAPI */ } static @@ -653,7 +739,11 @@ void __pformat_wcputs( const wchar_t *s, __pformat_t *stream ) * (after first verifying that the input pointer is not NULL). */ if( s == NULL ) s = L"(null)"; - __pformat_wputchars( s, wcslen( s ), stream ); + + if( stream->precision >= 0 ) + __pformat_wputchars( s, wcsnlen( s, stream->precision ), stream ); + else + __pformat_wputchars( s, wcslen( s ), stream ); } static @@ -2284,6 +2374,10 @@ __pformat (int flags, void *dest, int max, const APICHAR *fmt, va_list argv) -1 means to be determined. */ }; +#ifdef __BUILD_WIDEAPI + const APICHAR *literal_string_start = NULL; +#endif + format_scan: while( (c = *fmt++) != 0 ) { /* Format string parsing loop... @@ -2308,6 +2402,15 @@ __pformat (int flags, void *dest, int max, const APICHAR *fmt, va_list argv) */ int *width_spec = &stream.width; + #ifdef __BUILD_WIDEAPI + if (literal_string_start) + { + stream.width = stream.precision = PFORMAT_IGNORE; + __pformat_wputchars( literal_string_start, fmt - literal_string_start - 1, &stream ); + literal_string_start = NULL; + } + #endif + /* Reset initial state for flags, width and precision specs... */ stream.flags = flags; @@ -2332,7 +2435,12 @@ __pformat (int flags, void *dest, int max, const APICHAR *fmt, va_list argv) * on GNU/Linux does NOT appear to require this, but POSIX * and SUSv3 do seem to demand it). */ + #ifndef __BUILD_WIDEAPI __pformat_putc( c, &stream ); + #else + stream.width = stream.precision = PFORMAT_IGNORE; + __pformat_wputchars( L"%", 1, &stream ); + #endif goto format_scan; case 'C': @@ -2860,8 +2968,8 @@ __pformat (int flags, void *dest, int max, const APICHAR *fmt, va_list argv) */ length = PFORMAT_LENGTH_LONG; - state = PFORMAT_END; - break; + state = PFORMAT_END; + break; case 'L': /* @@ -3088,7 +3196,12 @@ __pformat (int flags, void *dest, int max, const APICHAR *fmt, va_list argv) * backtrack, and emit it as literal text... */ fmt = backtrack; + #ifndef __BUILD_WIDEAPI __pformat_putc( '%', &stream ); + #else + stream.width = stream.precision = PFORMAT_IGNORE; + __pformat_wputchars( L"%", 1, &stream ); + #endif goto format_scan; } } @@ -3099,12 +3212,25 @@ __pformat (int flags, void *dest, int max, const APICHAR *fmt, va_list argv) /* We just parsed a character which is not included within any format * specification; we simply emit it as a literal. */ + #ifndef __BUILD_WIDEAPI __pformat_putc( c, &stream ); + #else + if (literal_string_start == NULL) + literal_string_start = fmt - 1; + #endif } /* When we have fully dispatched the format string, the return value is the * total number of bytes we transferred to the output destination. */ +#ifdef __BUILD_WIDEAPI + if (literal_string_start) + { + stream.width = stream.precision = PFORMAT_IGNORE; + __pformat_wputchars( literal_string_start, fmt - literal_string_start - 1, &stream ); + } +#endif + return stream.count; }
------------------------------------------------------------------------------ Find and fix application performance issues faster with Applications Manager Applications Manager provides deep performance insights into multiple tiers of your business applications. It resolves application problems quickly and reduces your MTTR. Get your free trial! https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public