Currently Microsoft's C++ libraries implementation of std::cout/cerr
can't output Unicode characters but only ASCII or ANSI if locale is set
so we implement and use our own ConsoleBuf which can output Unicode
characters to console and it doesn't matter what locale or console's
codepage is set.
---
CMakeLists.txt | 1 +
Source/cmakemain.cxx | 27
Source/kwsys/CMakeLists.txt| 6 +-
Source/kwsys/ConsoleBuf.hxx.in | 282 +
bootstrap | 1 +
5 files changed, 316 insertions(+), 1 deletion(-)
create mode 100644 Source/kwsys/ConsoleBuf.hxx.in
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ae5990e..792b5a5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -258,6 +258,7 @@ macro (CMAKE_BUILD_UTILITIES)
set(KWSYS_USE_MD5 1)
set(KWSYS_USE_Process 1)
set(KWSYS_USE_CommandLineArguments 1)
+ set(KWSYS_USE_ConsoleBuf 1)
set(KWSYS_HEADER_ROOT ${CMake_BINARY_DIR}/Source)
set(KWSYS_INSTALL_DOC_DIR "${CMAKE_DOC_DIR}")
add_subdirectory(Source/kwsys)
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 521a5bf..95eb154 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -26,6 +26,7 @@
#include "cmake.h"
#include "cmcmd.h"
#include
+#include
#ifdef CMAKE_BUILD_WITH_CMAKE
static const char* cmDocumentationName[][2] = {
@@ -153,6 +154,22 @@ static void cmakemainProgressCallback(const char* m, float
prog,
int main(int ac, char const* const* av)
{
+#if defined(_WIN32)
+ // Replace streambuf so we can output Unicode to console
+ cmsys::ConsoleBuf *cbufio = CM_NULLPTR;
+ cmsys::ConsoleBuf *cbuferr = CM_NULLPTR;
+ std::streambuf *coutbuf = std::cout.rdbuf();
+ std::streambuf *cerrbuf = std::cerr.rdbuf();
+ try {
+cbufio = new cmsys::ConsoleBuf();
+coutbuf = std::cout.rdbuf(cbufio);
+cbuferr = new cmsys::ConsoleBuf(true);
+cerrbuf = std::cerr.rdbuf(cbuferr);
+ } catch (const std::runtime_error& ex) {
+std::cerr << "Failed to create ConsoleBuf!" << std::endl
+ << ex.what() << std::endl;
+ };
+#endif
cmsys::Encoding::CommandLineArguments args =
cmsys::Encoding::CommandLineArguments::Main(ac, av);
ac = args.argc();
@@ -171,6 +188,16 @@ int main(int ac, char const* const* av)
#ifdef CMAKE_BUILD_WITH_CMAKE
cmDynamicLoader::FlushCache();
#endif
+#if defined(_WIN32)
+ if (cbufio) {
+delete cbufio;
+std::cout.rdbuf(coutbuf);
+ }
+ if (cbuferr) {
+delete cbuferr;
+std::cerr.rdbuf(cerrbuf);
+ }
+#endif
return ret;
}
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 65203c0..33a97e6 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -123,6 +123,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(KWSYS_USE_FStream 1)
SET(KWSYS_USE_String 1)
SET(KWSYS_USE_SystemInformation 1)
+ SET(KWSYS_USE_ConsoleBuf 1)
ENDIF()
# Enforce component dependencies.
@@ -154,6 +155,9 @@ ENDIF()
IF(KWSYS_USE_FStream)
SET(KWSYS_USE_Encoding 1)
ENDIF()
+IF(KWSYS_USE_ConsoleBuf)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
# Setup the large file support default.
IF(KWSYS_LFS_DISABLE)
@@ -668,7 +672,7 @@ SET(KWSYS_HXX_FILES Configure String
# Add selected C++ classes.
SET(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
- CommandLineArguments IOStream FStream SystemInformation
+ CommandLineArguments IOStream FStream SystemInformation ConsoleBuf
)
FOREACH(cpp ${cppclasses})
IF(KWSYS_USE_${cpp})
diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in
new file mode 100644
index 000..4ee37dd
--- /dev/null
+++ b/Source/kwsys/ConsoleBuf.hxx.in
@@ -0,0 +1,282 @@
+/*
+ KWSys - Kitware System Library
+ 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 @KWSYS_NAMESPACE@_ConsoleBuf_hxx
+#define @KWSYS_NAMESPACE@_ConsoleBuf_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+#include <@KWSYS_NAMESPACE@/Encoding.hxx>
+#include
+#include
+#include
+#include
+#include
+
+#if defined(_WIN32)
+# include
+# if __cplusplus >= 201103L
+#include
+# endif
+#endif
+
+namespace @KWSYS_NAMESPACE@
+{
+#if defined(_WIN32)
+
+ template >
+ class @KWSYS_NAMESPACE@_EXPORT BasicConsoleBuf : public
std::basic_streambuf {
+public:
+ typedef typename Traits::int_type int_type;
+ typedef typename Traits::char_type char_type;
+
+ BasicConsoleBuf(const bool err = false) :
+flush_on_newline(true),
+inp