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/CMakeLists.txt | 2 +
Source/ProcessOutput.hxx.in| 160 +
Source/cmExecProgramCommand.cxx| 3 +
Source/cmExecuteProcessCommand.cxx | 11 ++-
Source/cmProcessTools.cxx | 9 ++-
Source/cmSystemTools.cxx | 11 ++-
bootstrap | 3 +
7 files changed, 193 insertions(+), 6 deletions(-)
create mode 100644 Source/ProcessOutput.hxx.in
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index a790994..eb51683 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -419,6 +419,8 @@ foreach(command_file
endforeach()
configure_file(cmCommands.cxx.in ${CMAKE_CURRENT_BINARY_DIR}/cmCommands.cxx
@ONLY)
+configure_file(ProcessOutput.hxx.in
${CMAKE_CURRENT_BINARY_DIR}/ProcessOutput.hxx)
+
# Kdevelop only works on UNIX and not windows
if(UNIX)
set(SRCS ${SRCS} cmGlobalKdevelopGenerator.cxx)
diff --git a/Source/ProcessOutput.hxx.in b/Source/ProcessOutput.hxx.in
new file mode 100644
index 000..ea7b881
--- /dev/null
+++ b/Source/ProcessOutput.hxx.in
@@ -0,0 +1,160 @@
+/*
+ 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 ProcessOutput_hxx
+#define ProcessOutput_hxx
+
+#include
+#include
+#if defined(_WIN32)
+# ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+# endif
+# include
+#endif
+
+ class ProcessOutput
+ {
+public:
+#if defined(_WIN32)
+ static const UINT defaultCodepage = @KWSYS_ENCODING_DEFAULT_CODEPAGE@;
+#endif
+ // must match to KWSYSPE_PIPE_BUFFER_SIZE
+ ProcessOutput(unsigned int maxSize = 1024)
+ {
+#if defined(_WIN32)
+bufferSize = maxSize;
+codepage = GetConsoleCP();
+if (!codepage) {
+ codepage = GetACP();
+}
+#else
+static_cast(maxSize);
+#endif
+ }
+
+ ~ProcessOutput()
+ {
+ }
+
+ bool DecodeText(std::string raw, std::string& decoded, size_t id = 0)
+ {
+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(id);
+#endif
+return success;
+ }
+
+ b