Commit 669e3a06 authored by Dāvis Mosāns's avatar Dāvis Mosāns

ConsoleBuf: Use a custom std::streambuf for console output on Windows

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.

Change-Id: I33053aa229796e84088aa3beb0ebe8bdbebaf3d1
parent 8e643b9b
......@@ -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)
......@@ -673,7 +677,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})
......@@ -926,6 +930,20 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
testFStream
)
ENDIF()
IF(KWSYS_USE_ConsoleBuf)
ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx)
SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_NAMESPACE})
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConsoleBuf
)
IF("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" AND
NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0")
set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8)
ENDIF()
SET_PROPERTY(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
ENDIF()
IF(KWSYS_USE_SystemInformation)
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation)
ENDIF()
......
This diff is collapsed.
This diff is collapsed.
/*============================================================================
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 testConsoleBuf_hxx
#define testConsoleBuf_hxx
static const wchar_t cmdConsoleBufChild[] = L"testConsoleBufChild";
static const wchar_t SyncEventName[] = L"SyncEvent";
// यूनिकोड είναι здорово!
static const wchar_t UnicodeTestString[] = L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 "
L"\u03B5\u03AF\u03BD\u03B1\u03B9 "
L"\u0437\u0434\u043E\u0440\u043E\u0432\u043E!";
#endif
/*============================================================================
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.
============================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(ConsoleBuf.hxx)
#include KWSYS_HEADER(Encoding.hxx)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
# include "ConsoleBuf.hxx.in"
# include "Encoding.hxx.in"
#endif
#include <iostream>
#include "testConsoleBuf.hxx"
//----------------------------------------------------------------------------
int main(int argc, const char* argv[])
{
#if defined(_WIN32)
kwsys::ConsoleBuf::Manager out(std::cout);
kwsys::ConsoleBuf::Manager err(std::cerr, true);
kwsys::ConsoleBuf::Manager in(std::cin);
if (argc > 1) {
std::cout << argv[1] << std::endl;
std::cerr << argv[1] << std::endl;
} else {
std::string str = kwsys::Encoding::ToNarrow(UnicodeTestString);
std::cout << str << std::endl;
std::cerr << str << std::endl;
}
std::string input;
HANDLE syncEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, SyncEventName);
if (syncEvent) {
SetEvent(syncEvent);
}
std::cin >> input;
std::cout << input << std::endl;
if (syncEvent) {
SetEvent(syncEvent);
CloseHandle(syncEvent);
}
#else
static_cast<void>(argc);
static_cast<void>(argv);
#endif
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment