[cmake-developers] [PATCH v3 4/7] For Windows encode process output to internally used encoding

Dāvis Mosāns davispuh at gmail.com
Wed Jul 6 15:12:10 EDT 2016


Typically Windows applications (eg. MSVC compiler) use current console's
codepage for output to pipes so we need to encode that to internally used
encoding (KWSYS_ENCODING_DEFAULT_CODEPAGE).
---
 Source/kwsys/CMakeLists.txt |  2 ++
 Source/kwsys/ProcessWin32.c | 25 ++++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 39b03b3..65203c0 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -708,6 +708,8 @@ IF(KWSYS_USE_Process)
   IF(NOT UNIX)
     # Use the Windows implementation.
     SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
+    SET_PROPERTY(SOURCE ProcessWin32.c APPEND PROPERTY COMPILE_DEFINITIONS
+      KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
   ELSE()
     # Use the UNIX implementation.
     SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 2b93e69..153dc0b 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -181,7 +181,7 @@ struct kwsysProcessPipeData_s
   /* ------------- Data managed per call to Execute ------------- */
 
   /* Buffer for data read in this pipe's thread.  */
-  char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
+  char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE*2];
 
   /* The length of the data stored in the buffer.  */
   DWORD DataLength;
@@ -319,6 +319,9 @@ struct kwsysProcess_s
   /* Own handles for the child's ends of the pipes in the parent process.
      Used temporarily during process creation.  */
   HANDLE PipeChildStd[3];
+
+  /* Console's active codepage */
+  UINT codepage;
 };
 
 /*--------------------------------------------------------------------------*/
@@ -1626,6 +1629,21 @@ void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td)
       KWSYSPE_DEBUG((stderr, "read closed %d\n", td->Index));
       }
 
+    if (td->DataLength > 0) {
+      if (cp->codepage != KWSYS_ENCODING_DEFAULT_CODEPAGE) {
+        const int wlength = MultiByteToWideChar(cp->codepage, 0, td->DataBuffer, td->DataLength, NULL, 0);
+        wchar_t* wdata = malloc(wlength * sizeof(wchar_t));
+        int r = MultiByteToWideChar(cp->codepage, 0, td->DataBuffer, td->DataLength, wdata, wlength);
+        if (r > 0) {
+          r = WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, wdata, wlength, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE * 2, NULL, NULL);
+          if (r > 0) {
+            td->DataLength = r;
+          }
+        }
+        free(wdata);
+      }
+    }
+
     KWSYSPE_DEBUG((stderr, "read %d\n", td->Index));
 
     /* Wait for our turn to be handled by the main thread.  */
@@ -1761,6 +1779,11 @@ int kwsysProcessInitialize(kwsysProcess* cp)
     }
   }
 
+  cp->codepage = GetConsoleCP();
+  if (!cp->codepage) {
+    cp->codepage = GetACP();
+  }
+
   return 1;
 }
 
-- 
2.9.0



More information about the cmake-developers mailing list