This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  644cdf712be93436cbd3401d72852f5d4bdb0e2a (commit)
       via  12924660b9881d24b60ff13da840d7312fa0486f (commit)
      from  2b7105307a5d47cf29bf03d1d1bcc21b16b476bd (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=644cdf712be93436cbd3401d72852f5d4bdb0e2a
commit 644cdf712be93436cbd3401d72852f5d4bdb0e2a
Merge: 2b71053 1292466
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Wed Aug 17 09:32:46 2016 -0400
Commit:     CMake Topic Stage <kwro...@kitware.com>
CommitDate: Wed Aug 17 09:32:46 2016 -0400

    Merge topic 'process-output-encoding' into next
    
    12924660 Windows: Encode child process output to internally-used encoding


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=12924660b9881d24b60ff13da840d7312fa0486f
commit 12924660b9881d24b60ff13da840d7312fa0486f
Author:     Dāvis Mosāns <davis...@gmail.com>
AuthorDate: Mon Aug 15 23:34:21 2016 +0300
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Wed Aug 17 09:32:23 2016 -0400

    Windows: Encode child process output to internally-used encoding
    
    Typically Windows applications (eg. MSVC compiler) use current console's
    codepage for output to pipes so we need to encode that to our
    internally-used encoding (`KWSYS_ENCODING_DEFAULT_CODEPAGE`).

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index cdc8fb1..580c3eb 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -317,6 +317,8 @@ set(SRCS
   cmOrderDirectories.h
   cmPolicies.h
   cmPolicies.cxx
+  cmProcessOutput.cxx
+  cmProcessOutput.hxx
   cmProcessTools.cxx
   cmProcessTools.h
   cmProperty.cxx
@@ -375,6 +377,9 @@ set(SRCS
   cm_utf8.c
   )
 
+SET_PROPERTY(SOURCE cmProcessOutput.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+  KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
+
 set(COMMAND_INCLUDES "#include \"cmTargetPropCommandBase.cxx\"\n")
 list(APPEND SRCS cmTargetPropCommandBase.cxx)
 set_property(SOURCE cmTargetPropCommandBase.cxx PROPERTY HEADER_FILE_ONLY ON)
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index 58bbc31..4391a19 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -11,6 +11,7 @@
 ============================================================================*/
 #include "cmExecProgramCommand.h"
 
+#include "cmProcessOutput.hxx"
 #include "cmSystemTools.h"
 
 #include <cmsys/Process.h>
@@ -219,6 +220,7 @@ bool cmExecProgramCommand::RunCommand(const char* command, 
std::string& output,
   int length;
   char* data;
   int p;
+  cmProcessOutput processOutput;
   while ((p = cmsysProcess_WaitForData(cp, &data, &length, CM_NULLPTR), p)) {
     if (p == cmsysProcess_Pipe_STDOUT || p == cmsysProcess_Pipe_STDERR) {
       if (verbose) {
@@ -230,6 +232,7 @@ bool cmExecProgramCommand::RunCommand(const char* command, 
std::string& output,
 
   // All output has been read.  Wait for the process to exit.
   cmsysProcess_WaitForExit(cp, CM_NULLPTR);
+  processOutput.DecodeText(output, output);
 
   // Check the result of running the process.
   std::string msg;
diff --git a/Source/cmExecuteProcessCommand.cxx 
b/Source/cmExecuteProcessCommand.cxx
index d97b25f..1ffb163 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -11,6 +11,7 @@
 ============================================================================*/
 #include "cmExecuteProcessCommand.h"
 
+#include "cmProcessOutput.hxx"
 #include "cmSystemTools.h"
 
 #include <cmsys/Process.h>
@@ -228,17 +229,21 @@ bool 
cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
   int length;
   char* data;
   int p;
+  cmProcessOutput processOutput;
+  std::string strdata;
   while ((p = cmsysProcess_WaitForData(cp, &data, &length, CM_NULLPTR), p)) {
     // Put the output in the right place.
     if (p == cmsysProcess_Pipe_STDOUT && !output_quiet) {
       if (output_variable.empty()) {
-        cmSystemTools::Stdout(data, length);
+        processOutput.DecodeText(data, length, strdata, 1);
+        cmSystemTools::Stdout(strdata.c_str(), strdata.size());
       } else {
         cmExecuteProcessCommandAppend(tempOutput, data, length);
       }
     } else if (p == cmsysProcess_Pipe_STDERR && !error_quiet) {
       if (error_variable.empty()) {
-        cmSystemTools::Stderr(data, length);
+        processOutput.DecodeText(data, length, strdata, 2);
+        cmSystemTools::Stderr(strdata.c_str(), strdata.size());
       } else {
         cmExecuteProcessCommandAppend(tempError, data, length);
       }
@@ -247,6 +252,8 @@ bool 
cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
 
   // All output has been read.  Wait for the process to exit.
   cmsysProcess_WaitForExit(cp, CM_NULLPTR);
+  processOutput.DecodeText(tempOutput, tempOutput);
+  processOutput.DecodeText(tempError, tempError);
 
   // Fix the text in the output strings.
   cmExecuteProcessCommandFixText(tempOutput, output_strip_trailing_whitespace);
diff --git a/Source/cmProcessOutput.cxx b/Source/cmProcessOutput.cxx
new file mode 100644
index 0000000..59101dd
--- /dev/null
+++ b/Source/cmProcessOutput.cxx
@@ -0,0 +1,155 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+
+#include "cmProcessOutput.hxx"
+
+#if defined(_WIN32)
+#include <windows.h>
+unsigned int cmProcessOutput::defaultCodepage =
+  KWSYS_ENCODING_DEFAULT_CODEPAGE;
+#endif
+
+cmProcessOutput::cmProcessOutput(unsigned int maxSize)
+{
+#if defined(_WIN32)
+  bufferSize = maxSize;
+  codepage = GetConsoleCP();
+  if (!codepage) {
+    codepage = GetACP();
+  }
+#else
+  static_cast<void>(maxSize);
+#endif
+}
+
+cmProcessOutput::~cmProcessOutput()
+{
+}
+
+bool cmProcessOutput::DecodeText(std::string raw, std::string& decoded,
+                                 size_t id)
+{
+  bool success = true;
+  decoded = raw;
+#if defined(_WIN32)
+  if (id > 0) {
+    if (rawparts.size() < id) {
+      rawparts.reserve(id);
+      while (rawparts.size() < id)
+        rawparts.push_back(std::string());
+    }
+    raw = rawparts[id - 1] + raw;
+    rawparts[id - 1].clear();
+    decoded = raw;
+  }
+  if (raw.size() > 0 && codepage != defaultCodepage) {
+    success = false;
+    CPINFOEXW cpinfo;
+    if (id > 0 && raw.size() == bufferSize &&
+        GetCPInfoExW(codepage, 0, &cpinfo) == 1 && cpinfo.MaxCharSize > 1) {
+      if (cpinfo.MaxCharSize == 2 && cpinfo.LeadByte[0] != 0) {
+        LPSTR prevChar =
+          CharPrevExA(codepage, raw.c_str(), raw.c_str() + raw.size(), 0);
+        bool isLeadByte =
+          (*(prevChar + 1) == 0) && IsDBCSLeadByteEx(codepage, *prevChar);
+        if (isLeadByte) {
+          rawparts[id - 1] += *(raw.end() - 1);
+          raw.resize(raw.size() - 1);
+        }
+        success = DoDecodeText(raw, decoded, NULL);
+      } else {
+        bool restoreDecoded = false;
+        std::string firstDecoded = decoded;
+        wchar_t lastChar = 0;
+        for (UINT i = 0; i < cpinfo.MaxCharSize; i++) {
+          success = DoDecodeText(raw, decoded, &lastChar);
+          if (success && lastChar != 0) {
+            if (i == 0) {
+              firstDecoded = decoded;
+            }
+            if (lastChar == cpinfo.UnicodeDefaultChar) {
+              restoreDecoded = true;
+              rawparts[id - 1] = *(raw.end() - 1) + rawparts[id - 1];
+              raw.resize(raw.size() - 1);
+            } else {
+              restoreDecoded = false;
+              break;
+            }
+          } else {
+            break;
+          }
+        }
+        if (restoreDecoded) {
+          decoded = firstDecoded;
+          rawparts[id - 1].clear();
+        }
+      }
+    } else {
+      success = DoDecodeText(raw, decoded, NULL);
+    }
+  }
+#else
+  static_cast<void>(id);
+#endif
+  return success;
+}
+
+bool cmProcessOutput::DecodeText(const char* data, size_t length,
+                                 std::string& decoded, size_t id)
+{
+  return DecodeText(std::string(data, length), decoded, id);
+}
+
+bool cmProcessOutput::DecodeText(std::vector<char> raw,
+                                 std::vector<char>& decoded, size_t id)
+{
+  std::string str;
+  const bool success =
+    DecodeText(std::string(raw.begin(), raw.end()), str, id);
+  decoded.assign(str.begin(), str.end());
+  return success;
+}
+
+#if defined(_WIN32)
+bool cmProcessOutput::DoDecodeText(std::string raw, std::string& decoded,
+                                   wchar_t* lastChar)
+{
+  bool success = false;
+  const int wlength =
+    MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), NULL, 0);
+  wchar_t* wdata = new wchar_t[wlength];
+  int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), wdata,
+                              wlength);
+  if (r > 0) {
+    if (lastChar) {
+      *lastChar = 0;
+      if ((wlength >= 2 && wdata[wlength - 2] != wdata[wlength - 1]) ||
+          wlength >= 1) {
+        *lastChar = wdata[wlength - 1];
+      }
+    }
+    int length = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, NULL,
+                                     0, NULL, NULL);
+    char* data = new char[length + 1];
+    r = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, data, length,
+                            NULL, NULL);
+    if (r > 0) {
+      data[length] = '\0';
+      decoded = data;
+      success = true;
+    }
+    delete[] data;
+  }
+  delete[] wdata;
+  return success;
+}
+#endif
diff --git a/Source/cmProcessOutput.hxx b/Source/cmProcessOutput.hxx
new file mode 100644
index 0000000..daffad1
--- /dev/null
+++ b/Source/cmProcessOutput.hxx
@@ -0,0 +1,42 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmProcessOutput_hxx
+#define cmProcessOutput_hxx
+
+#include "cmStandardIncludes.h"
+
+#include <string>
+#include <vector>
+
+class cmProcessOutput
+{
+public:
+  static unsigned int defaultCodepage;
+  // must match to KWSYSPE_PIPE_BUFFER_SIZE
+  cmProcessOutput(unsigned int maxSize = 1024);
+  ~cmProcessOutput();
+  bool DecodeText(std::string raw, std::string& decoded, size_t id = 0);
+  bool DecodeText(const char* data, size_t length, std::string& decoded,
+                  size_t id = 0);
+  bool DecodeText(std::vector<char> raw, std::vector<char>& decoded,
+                  size_t id = 0);
+
+private:
+#if defined(_WIN32)
+  unsigned int codepage;
+  unsigned int bufferSize;
+  std::vector<std::string> rawparts;
+  bool DoDecodeText(std::string raw, std::string& decoded, wchar_t* lastChar);
+#endif
+};
+
+#endif
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index 34b8df2..396d4b9 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -10,6 +10,7 @@
   See the License for more information.
 ============================================================================*/
 #include "cmProcessTools.h"
+#include "cmProcessOutput.hxx"
 
 #include <cmsys/Process.h>
 
@@ -20,14 +21,18 @@ void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, 
OutputParser* out,
   char* data = CM_NULLPTR;
   int length = 0;
   int p;
+  cmProcessOutput processOutput;
+  std::string strdata;
   while ((out || err) &&
          (p = cmsysProcess_WaitForData(cp, &data, &length, CM_NULLPTR), p)) {
     if (out && p == cmsysProcess_Pipe_STDOUT) {
-      if (!out->Process(data, length)) {
+      processOutput.DecodeText(data, length, strdata, 1);
+      if (!out->Process(strdata.c_str(), int(strdata.size()))) {
         out = CM_NULLPTR;
       }
     } else if (err && p == cmsysProcess_Pipe_STDERR) {
-      if (!err->Process(data, length)) {
+      processOutput.DecodeText(data, length, strdata, 2);
+      if (!err->Process(strdata.c_str(), int(strdata.size()))) {
         err = CM_NULLPTR;
       }
     }
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 5745a01..fcf0945 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -21,6 +21,7 @@
 #ifdef __QNX__
 #include <malloc.h> /* for malloc/free on QNX */
 #endif
+#include "cmProcessOutput.hxx"
 #include <cmsys/Directory.hxx>
 #include <cmsys/Encoding.hxx>
 #include <cmsys/Glob.hxx>
@@ -612,6 +613,8 @@ bool 
cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
   char* data;
   int length;
   int pipe;
+  cmProcessOutput processOutput;
+  std::string strdata;
   if (outputflag != OUTPUT_PASSTHROUGH &&
       (captureStdOut || captureStdErr || outputflag != OUTPUT_NONE)) {
     while ((pipe = cmsysProcess_WaitForData(cp, &data, &length, CM_NULLPTR)) >
@@ -627,14 +630,16 @@ bool 
cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
 
       if (pipe == cmsysProcess_Pipe_STDOUT) {
         if (outputflag != OUTPUT_NONE) {
-          cmSystemTools::Stdout(data, length);
+          processOutput.DecodeText(data, length, strdata, 1);
+          cmSystemTools::Stdout(strdata.c_str(), strdata.size());
         }
         if (captureStdOut) {
           tempStdOut.insert(tempStdOut.end(), data, data + length);
         }
       } else if (pipe == cmsysProcess_Pipe_STDERR) {
         if (outputflag != OUTPUT_NONE) {
-          cmSystemTools::Stderr(data, length);
+          processOutput.DecodeText(data, length, strdata, 2);
+          cmSystemTools::Stderr(strdata.c_str(), strdata.size());
         }
         if (captureStdErr) {
           tempStdErr.insert(tempStdErr.end(), data, data + length);
@@ -646,9 +651,11 @@ bool 
cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
   cmsysProcess_WaitForExit(cp, CM_NULLPTR);
   if (captureStdOut) {
     captureStdOut->assign(tempStdOut.begin(), tempStdOut.end());
+    processOutput.DecodeText(*captureStdOut, *captureStdOut);
   }
   if (captureStdErr) {
     captureStdErr->assign(tempStdErr.begin(), tempStdErr.end());
+    processOutput.DecodeText(*captureStdErr, *captureStdErr);
   }
 
   bool result = true;
diff --git a/bootstrap b/bootstrap
index 742fa2b..3402c9d 100755
--- a/bootstrap
+++ b/bootstrap
@@ -328,6 +328,7 @@ CMAKE_CXX_SOURCES="\
   cmExprLexer \
   cmExprParser \
   cmExprParserHelper \
+  cmProcessOutput \
 "
 
 if ${cmake_system_mingw}; then
@@ -1343,6 +1344,7 @@ fi
 cmake_c_flags_String="-DKWSYS_STRING_C"
 if ${cmake_system_mingw}; then
   cmake_c_flags_EncodingC="-DKWSYS_ENCODING_DEFAULT_CODEPAGE=CP_ACP"
+  cmake_cxx_flags_cmProcessOutput="${cmake_c_flags_EncodingC}"
 fi
 cmake_cxx_flags_SystemTools="
   -DKWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV}
@@ -1359,8 +1361,9 @@ echo "cmake: ${objs}" > "${cmake_bootstrap_dir}/Makefile"
 echo " ${cmake_cxx_compiler} ${cmake_ld_flags} ${cmake_cxx_flags} ${objs} -o 
cmake" >> "${cmake_bootstrap_dir}/Makefile"
 for a in ${CMAKE_CXX_SOURCES}; do
   src=`cmake_escape "${cmake_source_dir}/Source/${a}.cxx"`
+  src_flags=`eval echo \\${cmake_cxx_flags_\${a}}`
   echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "       ${cmake_cxx_compiler} ${cmake_cxx_flags} -c ${src} -o ${a}.o" 
>> "${cmake_bootstrap_dir}/Makefile"
+  echo "       ${cmake_cxx_compiler} ${cmake_cxx_flags} ${src_flags} -c ${src} 
-o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
 done
 echo "cmBootstrapCommands1.o : $cmBootstrapCommands1Deps" >> 
"${cmake_bootstrap_dir}/Makefile"
 echo "cmBootstrapCommands2.o : $cmBootstrapCommands2Deps" >> 
"${cmake_bootstrap_dir}/Makefile"

-----------------------------------------------------------------------

Summary of changes:


hooks/post-receive
-- 
CMake
_______________________________________________
Cmake-commits mailing list
Cmake-commits@cmake.org
http://public.kitware.com/mailman/listinfo/cmake-commits

Reply via email to