Fix mingw wprintf family function for _O_U8TEXT mode

This 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

Reply via email to