texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[5995] Fix output of non-ASCII text on MS-Windows.


From: Eli Zaretskii
Subject: [5995] Fix output of non-ASCII text on MS-Windows.
Date: Fri, 26 Dec 2014 11:56:15 +0000

Revision: 5995
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5995
Author:   eliz
Date:     2014-12-26 11:56:14 +0000 (Fri, 26 Dec 2014)
Log Message:
-----------
Fix output of non-ASCII text on MS-Windows.

Originally suggested by Jason Hood <address@hidden>.

 info/info-utils.c (nl_langinfo) [__MINGW32__]: Redirect to
 rpl_nl_langinfo, defined on pcterm.c.
 (degrade_utf8): Add replacements for 'point', 'print', and
 'expansion' symbols used by Texinfo.
 info/pcterm.c (WIN32_LEAN_AND_MEAN): Define.
 <old_outpmode, output_cp>: New static variables.
 (w32_info_prep): Disable the wrap-at-eol on console output.
 (w32_cleanup): Restore the original position of the cursor.
 (write_utf): New function, writes UTF-8 and UTF-7 text to console.
 (pc_put_text, pc_write_chars) [__MINGW32__]: Call it when the
 output console codepage is UTF-8 or UTF-7.
 (rpl_nl_langinfo): New function, returns the Windows console's
 output codepage and requests transliteration from libiconv.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/info/info-utils.c
    trunk/info/pcterm.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2014-12-26 11:20:18 UTC (rev 5994)
+++ trunk/ChangeLog     2014-12-26 11:56:14 UTC (rev 5995)
@@ -1,3 +1,20 @@
+2014-12-26  Eli Zaretskii  <address@hidden>
+
+       * info/info-utils.c (nl_langinfo) [__MINGW32__]: Redirect to
+       rpl_nl_langinfo, defined on pcterm.c.
+       (degrade_utf8): Add replacements for 'point', 'print', and
+       'expansion' symbols used by Texinfo.
+
+       * info/pcterm.c (WIN32_LEAN_AND_MEAN): Define.
+       <old_outpmode, output_cp>: New static variables.
+       (w32_info_prep): Disable the wrap-at-eol on console output.
+       (w32_cleanup): Restore the original position of the cursor.
+       (write_utf): New function, writes UTF-8 and UTF-7 text to console.
+       (pc_put_text, pc_write_chars) [__MINGW32__]: Call it when the
+       output console codepage is UTF-8 or UTF-7.
+       (rpl_nl_langinfo): New function, returns the Windows console's
+       output codepage and requests transliteration from libiconv.
+
 2014-12-26  Jason Hood  <address@hidden>  (tiny change)
 
        * info/pcterm.c (ScreenVisualBell): Fix setting visual attribute

Modified: trunk/info/info-utils.c
===================================================================
--- trunk/info/info-utils.c     2014-12-26 11:20:18 UTC (rev 5994)
+++ trunk/info/info-utils.c     2014-12-26 11:56:14 UTC (rev 5995)
@@ -27,7 +27,11 @@
 #include <langinfo.h>
 #if HAVE_ICONV
 # include <iconv.h>
+#ifdef __MINGW32__
+# define nl_langinfo rpl_nl_langinfo
+extern char * rpl_nl_langinfo (nl_item);
 #endif
+#endif
 #include <wchar.h>
 
 #ifdef __hpux
@@ -758,6 +762,9 @@
 
     {"\xE2\x86\x92","->"},/* Right arrow */
     {"\xE2\x87\x92","=>"},/* Right double arrow */
+    {"\xE2\x8A\xA3","-|"},/* Print symbol */
+    {"\xE2\x98\x85","-!-"}, /* Point symbol */
+    {"\xE2\x86\xA6","==>"}, /* Expansion symbol */
 
     {"\xE2\x80\x90","-"},  /* Hyphen */
     {"\xE2\x80\x91","-"},  /* Non-breaking hyphen */

Modified: trunk/info/pcterm.c
===================================================================
--- trunk/info/pcterm.c 2014-12-26 11:20:18 UTC (rev 5994)
+++ trunk/info/pcterm.c 2014-12-26 11:56:14 UTC (rev 5995)
@@ -39,6 +39,8 @@
 #include <io.h>
 #include <conio.h>
 #include <process.h>
+#include <malloc.h>    /* for alloca */
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
 struct text_info {
@@ -90,6 +92,8 @@
 static HANDLE hinfo = INVALID_HANDLE_VALUE;
 static HANDLE hscreen = INVALID_HANDLE_VALUE;
 static DWORD old_inpmode;
+static DWORD old_outpmode;
+static UINT output_cp;
 #else
 static unsigned char    norm_attr, inv_attr;
 #endif
@@ -106,6 +110,8 @@
   current_attr = norm_attr;
   hscreen = hinfo;
   SetConsoleMode (hstdin, ENABLE_WINDOW_INPUT);
+  GetConsoleMode (hscreen, &old_outpmode);
+  SetConsoleMode (hscreen, old_outpmode & ~ENABLE_WRAP_AT_EOL_OUTPUT);
 }
 
 void
@@ -120,6 +126,14 @@
 void
 w32_cleanup (void)
 {
+  COORD cursor_pos;
+
+  /* Restore the original position of the cursor.  */
+  cursor_pos.X = outside_info.curx;
+  cursor_pos.Y = outside_info.cury;
+  SetConsoleCursorPosition (hstdout, cursor_pos);
+
+  /* Close the input handle we created.  */
   CloseHandle (hinfo);
 }
 
@@ -597,6 +611,58 @@
     return _read (fd, buf, n);
 }
 
+/* Write to the console a string of text encoded in UTF-8 or UTF-7.  */
+static void
+write_utf (DWORD cp, const char *text, int nbytes)
+{
+  /* MSDN says UTF-7 requires zero in flags.  */
+  DWORD flags = (cp == CP_UTF7) ? 0 : MB_ERR_INVALID_CHARS;
+  /* How much space do we need for wide characters?  */
+  int wlen = MultiByteToWideChar (cp, flags, text, nbytes, NULL, 0);
+
+  if (wlen)
+    {
+      WCHAR *text_w = alloca (wlen * sizeof (WCHAR));
+      DWORD written;
+
+      if (MultiByteToWideChar (cp, flags, text, nbytes, text_w, wlen) > 0)
+       {
+         WriteConsoleW (hscreen, text_w, (nbytes < 0) ? wlen - 1 : wlen,
+                        &written, NULL);
+         return;
+       }
+    }
+  /* Fall back on conio.  */
+  if (nbytes < 0)
+    cputs (text);
+  else
+    cprintf ("%.*s", nbytes, text);
+}
+
+/* A replacement for nl_langinfo which does a more accurate job for
+   the console output codeset.  Windows can use 3 different encodings
+   at the same time, and the Posix-compliant nl_langinfo simply
+   doesn't know enough to decide which one is needed when CODESET is
+   requested.  */
+#undef nl_langinfo
+#include <langinfo.h>
+
+char *
+rpl_nl_langinfo (nl_item item)
+{
+  if (item == CODESET)
+    {
+      static char buf[100];
+
+      /* We need all the help we can get from GNU libiconv, so we
+        request transliteration as well.  */
+      sprintf (buf, "CP%u//TRANSLIT", GetConsoleOutputCP ());
+      return buf;
+    }
+  else
+    return nl_langinfo (item);
+}
+
 #endif /* _WIN32 */
 
 /* Turn on reverse video. */
@@ -679,6 +745,10 @@
 {
   if (speech_friendly)
     fputs (string, stdout);
+#ifdef __MINGW32__
+  else if (output_cp == CP_UTF8 || output_cp == CP_UTF7)
+    write_utf (output_cp, string, -1);
+#endif
   else
     cputs (string);
 }
@@ -707,9 +777,13 @@
     return;
 
   if (speech_friendly)
-    printf ("%.*s",nchars, string);
+    printf ("%.*s", nchars, string);
+#ifdef __MINGW32__
+  else if (output_cp == CP_UTF8 || output_cp == CP_UTF7)
+    write_utf (output_cp, string, nchars);
+#endif
   else
-    cprintf ("%..*s",nchars, string);
+    cprintf ("%.*s", nchars, string);
 }
 
 /* Scroll an area of the terminal from START to (and excluding) END,
@@ -880,6 +954,11 @@
 
   pc_get_screen_size ();
 
+#ifdef __MINGW32__
+  /* Record the screen output codepage.  */
+  output_cp = GetConsoleOutputCP ();
+#endif
+
 #ifdef __MSDOS__
   /* Store the arrow keys.  */
   term_ku = (char *)find_sequence (K_Up);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]