diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index b66cbbddeb..3af8ab1a68 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -152,7 +152,6 @@ 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. @@ -193,9 +192,6 @@ endif() if(KWSYS_USE_FStream) set(KWSYS_USE_Encoding 1) endif() -if(KWSYS_USE_ConsoleBuf) - set(KWSYS_USE_Encoding 1) -endif() # Specify default 8 bit encoding for Windows if(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE) @@ -619,7 +615,7 @@ set(KWSYS_HXX_FILES Configure) # Add selected C++ classes. set(cppclasses Directory DynamicLoader Encoding Glob RegularExpression SystemTools - CommandLineArguments FStream SystemInformation ConsoleBuf Status + CommandLineArguments FStream SystemInformation Status ) foreach(cpp IN LISTS cppclasses) if(KWSYS_USE_${cpp}) @@ -970,24 +966,6 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) testFStream.cxx ) endif() - if(KWSYS_USE_ConsoleBuf) - add_executable(testConsoleBufChild testConsoleBufChild.cxx) - set_property(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "") - set_property(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "") - set_property(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "") - set_property(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "") - set_property(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE}) - target_link_libraries(testConsoleBufChild ${KWSYS_TARGET_LINK}) - set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} - testConsoleBuf.cxx - ) - if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND - CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "19.0.23506") - 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.cxx) endif() diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in deleted file mode 100644 index b0e3cd53bf..0000000000 --- a/Source/kwsys/ConsoleBuf.hxx.in +++ /dev/null @@ -1,398 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#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 -#include - -#if defined(_WIN32) -# include -# if __cplusplus >= 201103L -# include -# endif -#endif - -namespace @KWSYS_NAMESPACE@ { -#if defined(_WIN32) - -template > -class BasicConsoleBuf : public std::basic_streambuf -{ -public: - typedef typename Traits::int_type int_type; - typedef typename Traits::char_type char_type; - - class Manager - { - public: - Manager(std::basic_ios& ios, bool const err = false) - : m_consolebuf(0) - { - m_ios = &ios; - try { - m_consolebuf = new BasicConsoleBuf(err); - m_streambuf = m_ios->rdbuf(m_consolebuf); - } catch (std::runtime_error const& ex) { - std::cerr << "Failed to create ConsoleBuf!" << std::endl - << ex.what() << std::endl; - }; - } - - BasicConsoleBuf* GetConsoleBuf() { return m_consolebuf; } - - void SetUTF8Pipes() - { - if (m_consolebuf) { - m_consolebuf->input_pipe_codepage = CP_UTF8; - m_consolebuf->output_pipe_codepage = CP_UTF8; - m_consolebuf->activateCodepageChange(); - } - } - - ~Manager() - { - if (m_consolebuf) { - delete m_consolebuf; - m_ios->rdbuf(m_streambuf); - } - } - - private: - std::basic_ios* m_ios; - std::basic_streambuf* m_streambuf; - BasicConsoleBuf* m_consolebuf; - }; - - BasicConsoleBuf(bool const err = false) - : flush_on_newline(true) - , input_pipe_codepage(0) - , output_pipe_codepage(0) - , input_file_codepage(CP_UTF8) - , output_file_codepage(CP_UTF8) - , m_consolesCodepage(0) - { - m_hInput = ::GetStdHandle(STD_INPUT_HANDLE); - checkHandle(true, "STD_INPUT_HANDLE"); - if (!setActiveInputCodepage()) { - throw std::runtime_error("setActiveInputCodepage failed!"); - } - m_hOutput = err ? ::GetStdHandle(STD_ERROR_HANDLE) - : ::GetStdHandle(STD_OUTPUT_HANDLE); - checkHandle(false, err ? "STD_ERROR_HANDLE" : "STD_OUTPUT_HANDLE"); - if (!setActiveOutputCodepage()) { - throw std::runtime_error("setActiveOutputCodepage failed!"); - } - _setg(); - _setp(); - } - - ~BasicConsoleBuf() throw() { sync(); } - - bool activateCodepageChange() - { - return setActiveInputCodepage() && setActiveOutputCodepage(); - } - -protected: - virtual int sync() - { - bool success = true; - if (m_hInput && m_isConsoleInput && - ::FlushConsoleInputBuffer(m_hInput) == 0) { - success = false; - } - if (m_hOutput && !m_obuffer.empty()) { - std::wstring const wbuffer = getBuffer(m_obuffer); - if (m_isConsoleOutput) { - DWORD charsWritten; - success = - ::WriteConsoleW(m_hOutput, wbuffer.c_str(), (DWORD)wbuffer.size(), - &charsWritten, nullptr) == 0 - ? false - : true; - } else { - DWORD bytesWritten; - std::string buffer; - success = encodeOutputBuffer(wbuffer, buffer); - if (success) { - success = - ::WriteFile(m_hOutput, buffer.c_str(), (DWORD)buffer.size(), - &bytesWritten, nullptr) == 0 - ? false - : true; - } - } - } - m_ibuffer.clear(); - m_obuffer.clear(); - _setg(); - _setp(); - return success ? 0 : -1; - } - - virtual int_type underflow() - { - if (this->gptr() >= this->egptr()) { - if (!m_hInput) { - _setg(true); - return Traits::eof(); - } - if (m_isConsoleInput) { - // ReadConsole doesn't tell if there's more input available - // don't support reading more characters than this - wchar_t wbuffer[8192]; - DWORD charsRead; - if (ReadConsoleW(m_hInput, wbuffer, - (sizeof(wbuffer) / sizeof(wbuffer[0])), &charsRead, - nullptr) == 0 || - charsRead == 0) { - _setg(true); - return Traits::eof(); - } - setBuffer(std::wstring(wbuffer, charsRead), m_ibuffer); - } else { - std::wstring wbuffer; - std::string strbuffer; - DWORD bytesRead; - LARGE_INTEGER size; - if (GetFileSizeEx(m_hInput, &size) == 0) { - _setg(true); - return Traits::eof(); - } - char* buffer = new char[size.LowPart]; - while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, nullptr) == - 0) { - if (GetLastError() == ERROR_MORE_DATA) { - strbuffer += std::string(buffer, bytesRead); - continue; - } - _setg(true); - delete[] buffer; - return Traits::eof(); - } - if (bytesRead > 0) { - strbuffer += std::string(buffer, bytesRead); - } - delete[] buffer; - if (!decodeInputBuffer(strbuffer, wbuffer)) { - _setg(true); - return Traits::eof(); - } - setBuffer(wbuffer, m_ibuffer); - } - _setg(); - } - return Traits::to_int_type(*this->gptr()); - } - - virtual int_type overflow(int_type ch = Traits::eof()) - { - if (!Traits::eq_int_type(ch, Traits::eof())) { - char_type chr = Traits::to_char_type(ch); - m_obuffer += chr; - if ((flush_on_newline && Traits::eq(chr, '\n')) || - Traits::eq_int_type(ch, 0x00)) { - sync(); - } - return ch; - } - sync(); - return Traits::eof(); - } - -public: - bool flush_on_newline; - UINT input_pipe_codepage; - UINT output_pipe_codepage; - UINT input_file_codepage; - UINT output_file_codepage; - -private: - HANDLE m_hInput; - HANDLE m_hOutput; - std::basic_string m_ibuffer; - std::basic_string m_obuffer; - bool m_isConsoleInput; - bool m_isConsoleOutput; - UINT m_activeInputCodepage; - UINT m_activeOutputCodepage; - UINT m_consolesCodepage; - void checkHandle(bool input, std::string handleName) - { - if ((input && m_hInput == INVALID_HANDLE_VALUE) || - (!input && m_hOutput == INVALID_HANDLE_VALUE)) { - std::string errmsg = - "GetStdHandle(" + handleName + ") returned INVALID_HANDLE_VALUE"; -# if __cplusplus >= 201103L - throw std::system_error(::GetLastError(), std::system_category(), - errmsg); -# else - throw std::runtime_error(errmsg); -# endif - } - } - UINT getConsolesCodepage() - { - if (!m_consolesCodepage) { - m_consolesCodepage = GetConsoleCP(); - if (!m_consolesCodepage) { - m_consolesCodepage = GetACP(); - } - } - return m_consolesCodepage; - } - bool setActiveInputCodepage() - { - m_isConsoleInput = false; - switch (GetFileType(m_hInput)) { - case FILE_TYPE_DISK: - m_activeInputCodepage = input_file_codepage; - break; - case FILE_TYPE_CHAR: - // Check for actual console. - DWORD consoleMode; - m_isConsoleInput = - GetConsoleMode(m_hInput, &consoleMode) == 0 ? false : true; - if (m_isConsoleInput) { - break; - } - @KWSYS_NAMESPACE@_FALLTHROUGH; - case FILE_TYPE_PIPE: - m_activeInputCodepage = input_pipe_codepage; - break; - default: - return false; - } - if (!m_isConsoleInput && m_activeInputCodepage == 0) { - m_activeInputCodepage = getConsolesCodepage(); - } - return true; - } - bool setActiveOutputCodepage() - { - m_isConsoleOutput = false; - switch (GetFileType(m_hOutput)) { - case FILE_TYPE_DISK: - m_activeOutputCodepage = output_file_codepage; - break; - case FILE_TYPE_CHAR: - // Check for actual console. - DWORD consoleMode; - m_isConsoleOutput = - GetConsoleMode(m_hOutput, &consoleMode) == 0 ? false : true; - if (m_isConsoleOutput) { - break; - } - @KWSYS_NAMESPACE@_FALLTHROUGH; - case FILE_TYPE_PIPE: - m_activeOutputCodepage = output_pipe_codepage; - break; - default: - return false; - } - if (!m_isConsoleOutput && m_activeOutputCodepage == 0) { - m_activeOutputCodepage = getConsolesCodepage(); - } - return true; - } - void _setg(bool empty = false) - { - if (!empty) { - this->setg((char_type*)m_ibuffer.data(), (char_type*)m_ibuffer.data(), - (char_type*)m_ibuffer.data() + m_ibuffer.size()); - } else { - this->setg((char_type*)m_ibuffer.data(), - (char_type*)m_ibuffer.data() + m_ibuffer.size(), - (char_type*)m_ibuffer.data() + m_ibuffer.size()); - } - } - void _setp() - { - this->setp((char_type*)m_obuffer.data(), - (char_type*)m_obuffer.data() + m_obuffer.size()); - } - bool encodeOutputBuffer(std::wstring const wbuffer, std::string& buffer) - { - if (wbuffer.size() == 0) { - buffer = std::string(); - return true; - } - int const length = - WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), nullptr, 0, nullptr, nullptr); - char* buf = new char[length]; - bool const success = - WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), buf, length, nullptr, - nullptr) > 0 - ? true - : false; - buffer = std::string(buf, length); - delete[] buf; - return success; - } - bool decodeInputBuffer(std::string const buffer, std::wstring& wbuffer) - { - size_t length = buffer.length(); - if (length == 0) { - wbuffer = std::wstring(); - return true; - } - int actualCodepage = m_activeInputCodepage; - char const BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) }; - char const* data = buffer.data(); - size_t const BOMsize = sizeof(BOM_UTF8); - if (length >= BOMsize && std::memcmp(data, BOM_UTF8, BOMsize) == 0) { - // PowerShell uses UTF-8 with BOM for pipes - actualCodepage = CP_UTF8; - data += BOMsize; - length -= BOMsize; - } - size_t const wlength = static_cast(MultiByteToWideChar( - actualCodepage, 0, data, static_cast(length), nullptr, 0)); - wchar_t* wbuf = new wchar_t[wlength]; - bool const success = - MultiByteToWideChar(actualCodepage, 0, data, static_cast(length), - wbuf, static_cast(wlength)) > 0 - ? true - : false; - wbuffer = std::wstring(wbuf, wlength); - delete[] wbuf; - return success; - } - std::wstring getBuffer(std::basic_string const buffer) - { - return Encoding::ToWide(buffer); - } - std::wstring getBuffer(std::basic_string const buffer) - { - return buffer; - } - void setBuffer(std::wstring const wbuffer, std::basic_string& target) - { - target = Encoding::ToNarrow(wbuffer); - } - void setBuffer(std::wstring const wbuffer, - std::basic_string& target) - { - target = wbuffer; - } - -}; // BasicConsoleBuf class - -typedef BasicConsoleBuf ConsoleBuf; -typedef BasicConsoleBuf WConsoleBuf; - -#endif -} // KWSYS_NAMESPACE - -#endif diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx deleted file mode 100644 index 46687b2993..0000000000 --- a/Source/kwsys/testConsoleBuf.cxx +++ /dev/null @@ -1,806 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" - -// Ignore Windows version levels defined by command-line flags. This -// source needs access to all APIs available on the host in order for -// the test to run properly. The test binary is not installed anyway. -#undef _WIN32_WINNT -#undef NTDDI_VERSION - -#include KWSYS_HEADER(Encoding.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Encoding.hxx.in" -#endif - -#if defined(_WIN32) - -# include -# include -# include -# include -# include -# include -# include - -# include "testConsoleBuf.hxx" - -# if defined(_MSC_VER) && _MSC_VER >= 1800 -# define KWSYS_WINDOWS_DEPRECATED_GetVersion -# endif -// يونيكود -static const WCHAR UnicodeInputTestString[] = - L"\u064A\u0648\u0646\u064A\u0643\u0648\u062F!"; -static UINT TestCodepage = KWSYS_ENCODING_DEFAULT_CODEPAGE; - -static const DWORD waitTimeout = 10 * 1000; -static STARTUPINFO startupInfo; -static PROCESS_INFORMATION processInfo; -static HANDLE beforeInputEvent; -static HANDLE afterOutputEvent; -static std::string encodedInputTestString; -static std::string encodedTestString; - -static void displayError(DWORD errorCode) -{ - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "Failed with error: 0x" << errorCode << "!" << std::endl; - LPWSTR message; - if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - nullptr, errorCode, 0, (LPWSTR)&message, 0, nullptr)) { - std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message) - << std::endl; - HeapFree(GetProcessHeap(), 0, message); - } else { - std::cerr << "FormatMessage() failed with error: 0x" << GetLastError() - << "!" << std::endl; - } - std::cerr.unsetf(std::ios::hex); -} - -std::basic_streambuf* errstream(char const* unused) -{ - static_cast(unused); - return std::cerr.rdbuf(); -} - -std::basic_streambuf* errstream(wchar_t const* unused) -{ - static_cast(unused); - return std::wcerr.rdbuf(); -} - -template -static void dumpBuffers(T const* expected, T const* received, size_t size) -{ - std::basic_ostream err(errstream(expected)); - err << "Expected output: '" << std::basic_string(expected, size) << "'" - << std::endl; - if (err.fail()) { - err.clear(); - err << "--- Error while outputting ---" << std::endl; - } - err << "Received output: '" << std::basic_string(received, size) << "'" - << std::endl; - if (err.fail()) { - err.clear(); - err << "--- Error while outputting ---" << std::endl; - } - std::cerr << "Expected output | Received output" << std::endl; - for (size_t i = 0; i < size; i++) { - std::cerr << std::setbase(16) << std::setfill('0') << " " - << "0x" << std::setw(8) << static_cast(expected[i]) - << " | " - << "0x" << std::setw(8) - << static_cast(received[i]); - if (static_cast(expected[i]) != - static_cast(received[i])) { - std::cerr << " MISMATCH!"; - } - std::cerr << std::endl; - } - std::cerr << std::endl; -} - -static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) -{ - BOOL bInheritHandles = FALSE; - DWORD dwCreationFlags = 0; - memset(&processInfo, 0, sizeof(processInfo)); - memset(&startupInfo, 0, sizeof(startupInfo)); - startupInfo.cb = sizeof(startupInfo); - startupInfo.dwFlags = STARTF_USESHOWWINDOW; - startupInfo.wShowWindow = SW_HIDE; - if (hIn || hOut || hErr) { - startupInfo.dwFlags |= STARTF_USESTDHANDLES; - startupInfo.hStdInput = hIn; - startupInfo.hStdOutput = hOut; - startupInfo.hStdError = hErr; - bInheritHandles = TRUE; - } - - WCHAR cmd[MAX_PATH]; - if (GetModuleFileNameW(nullptr, cmd, MAX_PATH) == 0) { - std::cerr << "GetModuleFileName failed!" << std::endl; - return false; - } - WCHAR* p = cmd + wcslen(cmd); - while (p > cmd && *p != L'\\') - p--; - *(p + 1) = 0; - wcscat(cmd, cmdConsoleBufChild); - wcscat(cmd, L".exe"); - - bool success = - CreateProcessW(nullptr, // No module name (use command line) - cmd, // Command line - nullptr, // Process handle not inheritable - nullptr, // Thread handle not inheritable - bInheritHandles, // Set handle inheritance - dwCreationFlags, - nullptr, // Use parent's environment block - nullptr, // Use parent's starting directory - &startupInfo, // Pointer to STARTUPINFO structure - &processInfo) != - 0; // Pointer to PROCESS_INFORMATION structure - if (!success) { - DWORD lastError = GetLastError(); - std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")" - << std::endl; - displayError(lastError); - } - return success; -} - -static void finishProcess(bool success) -{ - if (success) { - success = - WaitForSingleObject(processInfo.hProcess, waitTimeout) == WAIT_OBJECT_0; - }; - if (!success) { - TerminateProcess(processInfo.hProcess, 1); - } - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); -} - -static bool createPipe(PHANDLE readPipe, PHANDLE writePipe) -{ - SECURITY_ATTRIBUTES securityAttributes; - securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = nullptr; - return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0 ? false - : true; -} - -static void finishPipe(HANDLE readPipe, HANDLE writePipe) -{ - if (readPipe != INVALID_HANDLE_VALUE) { - CloseHandle(readPipe); - } - if (writePipe != INVALID_HANDLE_VALUE) { - CloseHandle(writePipe); - } -} - -static HANDLE createFile(LPCWSTR fileName) -{ - SECURITY_ATTRIBUTES securityAttributes; - securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = nullptr; - - HANDLE file = - CreateFileW(fileName, GENERIC_READ | GENERIC_WRITE, - 0, // do not share - &securityAttributes, - CREATE_ALWAYS, // overwrite existing - FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, - nullptr); // no template - if (file == INVALID_HANDLE_VALUE) { - DWORD lastError = GetLastError(); - std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" - << std::endl; - displayError(lastError); - } - return file; -} - -static void finishFile(HANDLE file) -{ - if (file != INVALID_HANDLE_VALUE) { - CloseHandle(file); - } -} - -# ifndef MAPVK_VK_TO_VSC -# define MAPVK_VK_TO_VSC (0) -# endif - -static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr) -{ - inputBuffer[0].EventType = KEY_EVENT; - inputBuffer[0].Event.KeyEvent.bKeyDown = TRUE; - inputBuffer[0].Event.KeyEvent.wRepeatCount = 1; - SHORT keyCode = VkKeyScanW(chr); - if (keyCode == -1) { - // Character can't be entered with current keyboard layout - // Just set any, it doesn't really matter - keyCode = 'K'; - } - inputBuffer[0].Event.KeyEvent.wVirtualKeyCode = LOBYTE(keyCode); - inputBuffer[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey( - inputBuffer[0].Event.KeyEvent.wVirtualKeyCode, MAPVK_VK_TO_VSC); - inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar = chr; - inputBuffer[0].Event.KeyEvent.dwControlKeyState = 0; - if ((HIBYTE(keyCode) & 1) == 1) { - inputBuffer[0].Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED; - } - if ((HIBYTE(keyCode) & 2) == 2) { - inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_CTRL_PRESSED; - } - if ((HIBYTE(keyCode) & 4) == 4) { - inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED; - } - inputBuffer[1].EventType = inputBuffer[0].EventType; - inputBuffer[1].Event.KeyEvent.bKeyDown = FALSE; - inputBuffer[1].Event.KeyEvent.wRepeatCount = 1; - inputBuffer[1].Event.KeyEvent.wVirtualKeyCode = - inputBuffer[0].Event.KeyEvent.wVirtualKeyCode; - inputBuffer[1].Event.KeyEvent.wVirtualScanCode = - inputBuffer[0].Event.KeyEvent.wVirtualScanCode; - inputBuffer[1].Event.KeyEvent.uChar.UnicodeChar = - inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar; - inputBuffer[1].Event.KeyEvent.dwControlKeyState = 0; -} - -static int testPipe() -{ - int didFail = 1; - HANDLE inPipeRead = INVALID_HANDLE_VALUE; - HANDLE inPipeWrite = INVALID_HANDLE_VALUE; - HANDLE outPipeRead = INVALID_HANDLE_VALUE; - HANDLE outPipeWrite = INVALID_HANDLE_VALUE; - HANDLE errPipeRead = INVALID_HANDLE_VALUE; - HANDLE errPipeWrite = INVALID_HANDLE_VALUE; - UINT currentCodepage = GetConsoleCP(); - char buffer[200]; - char buffer2[200]; - try { - if (!createPipe(&inPipeRead, &inPipeWrite) || - !createPipe(&outPipeRead, &outPipeWrite) || - !createPipe(&errPipeRead, &errPipeWrite)) { - throw std::runtime_error("createFile failed!"); - } - if (TestCodepage == CP_ACP) { - TestCodepage = GetACP(); - } - if (!SetConsoleCP(TestCodepage)) { - throw std::runtime_error("SetConsoleCP failed!"); - } - - DWORD bytesWritten = 0; - if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(), - (DWORD)encodedInputTestString.size(), &bytesWritten, - nullptr) || - bytesWritten == 0) { - throw std::runtime_error("WriteFile failed!"); - } - - if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) { - try { - DWORD status; - if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != - WAIT_OBJECT_0) { - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "WaitForSingleObject returned unexpected status 0x" - << status << std::endl; - std::cerr.unsetf(std::ios::hex); - throw std::runtime_error("WaitForSingleObject failed!"); - } - DWORD bytesRead = 0; - if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, - nullptr) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#1 failed!"); - } - buffer[bytesRead] = 0; - if ((bytesRead < - encodedTestString.size() + 1 + encodedInputTestString.size() && - !ReadFile(outPipeRead, buffer + bytesRead, - sizeof(buffer) - bytesRead, &bytesRead, nullptr)) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#2 failed!"); - } - if (memcmp(buffer, encodedTestString.c_str(), - encodedTestString.size()) == 0 && - memcmp(buffer + encodedTestString.size() + 1, - encodedInputTestString.c_str(), - encodedInputTestString.size()) == 0) { - bytesRead = 0; - if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead, - nullptr) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#3 failed!"); - } - buffer2[bytesRead] = 0; - didFail = encodedTestString.compare(0, std::string::npos, buffer2, - encodedTestString.size()) == 0 - ? 0 - : 1; - } - if (didFail != 0) { - std::cerr << "Pipe's output didn't match expected output!" - << std::endl; - dumpBuffers(encodedTestString.c_str(), buffer, - encodedTestString.size()); - dumpBuffers(encodedInputTestString.c_str(), - buffer + encodedTestString.size() + 1, - encodedInputTestString.size()); - dumpBuffers(encodedTestString.c_str(), buffer2, - encodedTestString.size()); - } - } catch (std::runtime_error const& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testPipe, line " << __LINE__ << ": " - << ex.what() << std::endl; - displayError(lastError); - } - finishProcess(didFail == 0); - } - } catch (std::runtime_error const& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testPipe, line " << __LINE__ << ": " << ex.what() - << std::endl; - displayError(lastError); - } - finishPipe(inPipeRead, inPipeWrite); - finishPipe(outPipeRead, outPipeWrite); - finishPipe(errPipeRead, errPipeWrite); - SetConsoleCP(currentCodepage); - return didFail; -} - -static int testFile() -{ - int didFail = 1; - HANDLE inFile = INVALID_HANDLE_VALUE; - HANDLE outFile = INVALID_HANDLE_VALUE; - HANDLE errFile = INVALID_HANDLE_VALUE; - try { - if ((inFile = createFile(L"stdinFile.txt")) == INVALID_HANDLE_VALUE || - (outFile = createFile(L"stdoutFile.txt")) == INVALID_HANDLE_VALUE || - (errFile = createFile(L"stderrFile.txt")) == INVALID_HANDLE_VALUE) { - throw std::runtime_error("createFile failed!"); - } - DWORD bytesWritten = 0; - char buffer[200]; - char buffer2[200]; - - int length; - if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, - -1, buffer, sizeof(buffer), nullptr, - nullptr)) == 0) { - throw std::runtime_error("WideCharToMultiByte failed!"); - } - buffer[length - 1] = '\n'; - if (!WriteFile(inFile, buffer, length, &bytesWritten, nullptr) || - bytesWritten == 0) { - throw std::runtime_error("WriteFile failed!"); - } - if (SetFilePointer(inFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { - throw std::runtime_error("SetFilePointer failed!"); - } - - if (createProcess(inFile, outFile, errFile)) { - DWORD bytesRead = 0; - try { - DWORD status; - if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != - WAIT_OBJECT_0) { - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "WaitForSingleObject returned unexpected status 0x" - << status << std::endl; - std::cerr.unsetf(std::ios::hex); - throw std::runtime_error("WaitForSingleObject failed!"); - } - if (SetFilePointer(outFile, 0, 0, FILE_BEGIN) == - INVALID_SET_FILE_POINTER) { - throw std::runtime_error("SetFilePointer#1 failed!"); - } - if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, nullptr) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#1 failed!"); - } - buffer[bytesRead] = 0; - if (memcmp(buffer, encodedTestString.c_str(), - encodedTestString.size()) == 0 && - memcmp(buffer + encodedTestString.size() + 1, - encodedInputTestString.c_str(), - encodedInputTestString.size()) == 0) { - bytesRead = 0; - if (SetFilePointer(errFile, 0, 0, FILE_BEGIN) == - INVALID_SET_FILE_POINTER) { - throw std::runtime_error("SetFilePointer#2 failed!"); - } - - if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, - nullptr) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#2 failed!"); - } - buffer2[bytesRead] = 0; - didFail = encodedTestString.compare(0, std::string::npos, buffer2, - encodedTestString.size()) == 0 - ? 0 - : 1; - } - if (didFail != 0) { - std::cerr << "File's output didn't match expected output!" - << std::endl; - dumpBuffers(encodedTestString.c_str(), buffer, - encodedTestString.size()); - dumpBuffers(encodedInputTestString.c_str(), - buffer + encodedTestString.size() + 1, - encodedInputTestString.size()); - dumpBuffers(encodedTestString.c_str(), buffer2, - encodedTestString.size()); - } - } catch (std::runtime_error const& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testFile, line " << __LINE__ << ": " - << ex.what() << std::endl; - displayError(lastError); - } - finishProcess(didFail == 0); - } - } catch (std::runtime_error const& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testFile, line " << __LINE__ << ": " << ex.what() - << std::endl; - displayError(lastError); - } - finishFile(inFile); - finishFile(outFile); - finishFile(errFile); - return didFail; -} - -# ifndef _WIN32_WINNT_VISTA -# define _WIN32_WINNT_VISTA 0x0600 -# endif - -static bool consoleIsConhost() -{ - wchar_t consoleClassNameBuf[64]; - int const consoleClassNameLen = GetClassNameW( - GetConsoleWindow(), &consoleClassNameBuf[0], sizeof(consoleClassNameBuf)); - // Windows Console Host: ConsoleWindowClass - // Windows Terminal / ConPTY: PseudoConsoleWindow (undocumented) - return (consoleClassNameLen > 0 && - wcscmp(consoleClassNameBuf, L"ConsoleWindowClass") == 0); -} - -static bool charIsNUL(wchar_t c) -{ - return c == 0; -} - -static int testConsole() -{ - int didFail = 1; - HANDLE parentIn = GetStdHandle(STD_INPUT_HANDLE); - HANDLE parentOut = GetStdHandle(STD_OUTPUT_HANDLE); - HANDLE parentErr = GetStdHandle(STD_ERROR_HANDLE); - HANDLE hIn = parentIn; - HANDLE hOut = parentOut; - DWORD consoleMode; - bool newConsole = false; - bool forceNewConsole = false; - bool restoreConsole = false; - LPCWSTR TestFaceName = L"Lucida Console"; - const DWORD TestFontFamily = 0x00000036; - const DWORD TestFontSize = 0x000c0000; - HKEY hConsoleKey; - WCHAR FaceName[200]; - FaceName[0] = 0; - DWORD FaceNameSize = sizeof(FaceName); - DWORD FontFamily = TestFontFamily; - DWORD FontSize = TestFontSize; -# ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion -# pragma warning(push) -# ifdef __INTEL_COMPILER -# pragma warning(disable : 1478) -# elif defined __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -# else -# pragma warning(disable : 4996) -# endif -# endif - bool const isVistaOrGreater = - LOBYTE(LOWORD(GetVersion())) >= HIBYTE(_WIN32_WINNT_VISTA); -# ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion -# ifdef __clang__ -# pragma clang diagnostic pop -# else -# pragma warning(pop) -# endif -# endif - if (!isVistaOrGreater) { - if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE, - &hConsoleKey) == ERROR_SUCCESS) { - DWORD dwordSize = sizeof(DWORD); - if (RegQueryValueExW(hConsoleKey, L"FontFamily", nullptr, nullptr, - (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) { - if (FontFamily != TestFontFamily) { - RegQueryValueExW(hConsoleKey, L"FaceName", nullptr, nullptr, - (LPBYTE)FaceName, &FaceNameSize); - RegQueryValueExW(hConsoleKey, L"FontSize", nullptr, nullptr, - (LPBYTE)&FontSize, &dwordSize); - - RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD, - (BYTE*)&TestFontFamily, sizeof(TestFontFamily)); - RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ, - (BYTE*)TestFaceName, - (DWORD)((wcslen(TestFaceName) + 1) * sizeof(WCHAR))); - RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD, - (BYTE*)&TestFontSize, sizeof(TestFontSize)); - - restoreConsole = true; - forceNewConsole = true; - } - } else { - std::cerr << "RegGetValueW(FontFamily) failed!" << std::endl; - } - RegCloseKey(hConsoleKey); - } else { - std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!" - << std::endl; - } - } - if (forceNewConsole || GetConsoleMode(parentOut, &consoleMode) == 0) { - // Not a real console, let's create new one. - FreeConsole(); - if (!AllocConsole()) { - std::cerr << "AllocConsole failed!" << std::endl; - return didFail; - } - SECURITY_ATTRIBUTES securityAttributes; - securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = nullptr; - hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, - OPEN_EXISTING, 0, nullptr); - if (hIn == INVALID_HANDLE_VALUE) { - DWORD lastError = GetLastError(); - std::cerr << "CreateFile(CONIN$)" << std::endl; - displayError(lastError); - } - hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, - OPEN_EXISTING, 0, nullptr); - if (hOut == INVALID_HANDLE_VALUE) { - DWORD lastError = GetLastError(); - std::cerr << "CreateFile(CONOUT$)" << std::endl; - displayError(lastError); - } - SetStdHandle(STD_INPUT_HANDLE, hIn); - SetStdHandle(STD_OUTPUT_HANDLE, hOut); - SetStdHandle(STD_ERROR_HANDLE, hOut); - newConsole = true; - } - -# if _WIN32_WINNT >= _WIN32_WINNT_VISTA - if (isVistaOrGreater) { - CONSOLE_FONT_INFOEX consoleFont; - memset(&consoleFont, 0, sizeof(consoleFont)); - consoleFont.cbSize = sizeof(consoleFont); - HMODULE kernel32 = LoadLibraryW(L"kernel32.dll"); - typedef BOOL(WINAPI * GetCurrentConsoleFontExFunc)( - HANDLE hConsoleOutput, BOOL bMaximumWindow, - PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx); - typedef BOOL(WINAPI * SetCurrentConsoleFontExFunc)( - HANDLE hConsoleOutput, BOOL bMaximumWindow, - PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx); - GetCurrentConsoleFontExFunc getConsoleFont = - (GetCurrentConsoleFontExFunc)GetProcAddress(kernel32, - "GetCurrentConsoleFontEx"); - SetCurrentConsoleFontExFunc setConsoleFont = - (SetCurrentConsoleFontExFunc)GetProcAddress(kernel32, - "SetCurrentConsoleFontEx"); - if (getConsoleFont(hOut, FALSE, &consoleFont)) { - if (consoleFont.FontFamily != TestFontFamily) { - consoleFont.FontFamily = TestFontFamily; - wcscpy(consoleFont.FaceName, TestFaceName); - if (!setConsoleFont(hOut, FALSE, &consoleFont)) { - std::cerr << "SetCurrentConsoleFontEx failed!" << std::endl; - } - } - } else { - std::cerr << "GetCurrentConsoleFontEx failed!" << std::endl; - } - } else { -# endif - if (restoreConsole && - RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_WRITE, - &hConsoleKey) == ERROR_SUCCESS) { - RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD, - (BYTE*)&FontFamily, sizeof(FontFamily)); - if (FaceName[0] != 0) { - RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ, (BYTE*)FaceName, - FaceNameSize); - } else { - RegDeleteValueW(hConsoleKey, L"FaceName"); - } - RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD, (BYTE*)&FontSize, - sizeof(FontSize)); - RegCloseKey(hConsoleKey); - } -# if _WIN32_WINNT >= _WIN32_WINNT_VISTA - } -# endif - - if (createProcess(nullptr, nullptr, nullptr)) { - try { - DWORD status; - if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) != - WAIT_OBJECT_0) { - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "WaitForSingleObject returned unexpected status 0x" - << status << std::endl; - std::cerr.unsetf(std::ios::hex); - throw std::runtime_error("WaitForSingleObject#1 failed!"); - } - INPUT_RECORD inputBuffer[(sizeof(UnicodeInputTestString) / - sizeof(UnicodeInputTestString[0])) * - 2]; - memset(&inputBuffer, 0, sizeof(inputBuffer)); - unsigned int i; - for (i = 0; i < (sizeof(UnicodeInputTestString) / - sizeof(UnicodeInputTestString[0]) - - 1); - i++) { - writeInputKeyEvent(&inputBuffer[i * 2], UnicodeInputTestString[i]); - } - writeInputKeyEvent(&inputBuffer[i * 2], VK_RETURN); - DWORD eventsWritten = 0; - // We need to wait a bit before writing to console so child process have - // started waiting for input on stdin. - Sleep(300); - if (!WriteConsoleInputW(hIn, inputBuffer, - sizeof(inputBuffer) / sizeof(inputBuffer[0]), - &eventsWritten) || - eventsWritten == 0) { - throw std::runtime_error("WriteConsoleInput failed!"); - } - if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != - WAIT_OBJECT_0) { - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "WaitForSingleObject returned unexpected status 0x" - << status << std::endl; - std::cerr.unsetf(std::ios::hex); - throw std::runtime_error("WaitForSingleObject#2 failed!"); - } - CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo; - if (!GetConsoleScreenBufferInfo(hOut, &screenBufferInfo)) { - throw std::runtime_error("GetConsoleScreenBufferInfo failed!"); - } - - COORD coord; - DWORD charsRead = 0; - coord.X = 0; - coord.Y = screenBufferInfo.dwCursorPosition.Y - 4; - WCHAR* outputBuffer = new WCHAR[screenBufferInfo.dwSize.X * 4]; - if (!ReadConsoleOutputCharacterW(hOut, outputBuffer, - screenBufferInfo.dwSize.X * 4, coord, - &charsRead) || - charsRead == 0) { - delete[] outputBuffer; - throw std::runtime_error("ReadConsoleOutputCharacter failed!"); - } - std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString); - if (consoleIsConhost()) { - // Windows Console Host converts NUL bytes to spaces. - std::replace(wideTestString.begin(), wideTestString.end(), '\0', ' '); - } else { - // Windows Terminal / ConPTY removes NUL bytes. - wideTestString.erase(std::remove_if(wideTestString.begin(), - wideTestString.end(), charIsNUL), - wideTestString.end()); - } - std::wstring wideInputTestString = - kwsys::Encoding::ToWide(encodedInputTestString); - if (memcmp(outputBuffer, wideTestString.c_str(), - wideTestString.size() * sizeof(wchar_t)) == 0 && - memcmp(outputBuffer + screenBufferInfo.dwSize.X * 1, - wideTestString.c_str(), - wideTestString.size() * sizeof(wchar_t)) == 0 && - memcmp(outputBuffer + screenBufferInfo.dwSize.X * 2, - UnicodeInputTestString, - sizeof(UnicodeInputTestString) - sizeof(WCHAR)) == 0 && - memcmp(outputBuffer + screenBufferInfo.dwSize.X * 3, - wideInputTestString.c_str(), - (wideInputTestString.size() - 1) * sizeof(wchar_t)) == 0) { - didFail = 0; - } else { - std::cerr << "Console's output didn't match expected output!" - << std::endl; - dumpBuffers(wideTestString.c_str(), outputBuffer, - wideTestString.size()); - dumpBuffers(wideTestString.c_str(), - outputBuffer + screenBufferInfo.dwSize.X * 1, - wideTestString.size()); - dumpBuffers( - UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2, - (sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR)); - dumpBuffers(wideInputTestString.c_str(), - outputBuffer + screenBufferInfo.dwSize.X * 3, - wideInputTestString.size() - 1); - } - delete[] outputBuffer; - } catch (std::runtime_error const& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testConsole, line " << __LINE__ << ": " - << ex.what() << std::endl; - displayError(lastError); - } - finishProcess(didFail == 0); - } - if (newConsole) { - SetStdHandle(STD_INPUT_HANDLE, parentIn); - SetStdHandle(STD_OUTPUT_HANDLE, parentOut); - SetStdHandle(STD_ERROR_HANDLE, parentErr); - CloseHandle(hIn); - CloseHandle(hOut); - FreeConsole(); - } - return didFail; -} - -#endif - -int testConsoleBuf(int, char*[]) -{ - int ret = 0; - -#if defined(_WIN32) - beforeInputEvent = CreateEventW(nullptr, - FALSE, // auto-reset event - FALSE, // initial state is nonsignaled - BeforeInputEventName); // object name - if (!beforeInputEvent) { - std::cerr << "CreateEvent#1 failed " << GetLastError() << std::endl; - return 1; - } - - afterOutputEvent = CreateEventW(nullptr, FALSE, FALSE, AfterOutputEventName); - if (!afterOutputEvent) { - std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl; - return 1; - } - - encodedTestString = kwsys::Encoding::ToNarrow(std::wstring( - UnicodeTestString, sizeof(UnicodeTestString) / sizeof(wchar_t) - 1)); - encodedInputTestString = kwsys::Encoding::ToNarrow( - std::wstring(UnicodeInputTestString, - sizeof(UnicodeInputTestString) / sizeof(wchar_t) - 1)); - encodedInputTestString += "\n"; - - ret |= testPipe(); - ret |= testFile(); - ret |= testConsole(); - - CloseHandle(beforeInputEvent); - CloseHandle(afterOutputEvent); -#endif - - return ret; -} diff --git a/Source/kwsys/testConsoleBuf.hxx b/Source/kwsys/testConsoleBuf.hxx deleted file mode 100644 index b38e4b35e0..0000000000 --- a/Source/kwsys/testConsoleBuf.hxx +++ /dev/null @@ -1,17 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef testConsoleBuf_hxx -#define testConsoleBuf_hxx - -static wchar_t const cmdConsoleBufChild[] = L"testConsoleBufChild"; - -static wchar_t const BeforeInputEventName[] = L"BeforeInputEvent"; -static wchar_t const AfterOutputEventName[] = L"AfterOutputEvent"; - -// यूनिकोड είναι здорово! -static wchar_t const UnicodeTestString[] = - L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 " - L"\u03B5\u03AF\u03BD\0\u03B1\u03B9 " - L"\u0437\u0434\u043E\u0440\u043E\u0432\u043E!"; - -#endif diff --git a/Source/kwsys/testConsoleBufChild.cxx b/Source/kwsys/testConsoleBufChild.cxx deleted file mode 100644 index f3c309e87a..0000000000 --- a/Source/kwsys/testConsoleBufChild.cxx +++ /dev/null @@ -1,55 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#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 - -#include "testConsoleBuf.hxx" - -int main(int argc, char const* 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(std::wstring( - UnicodeTestString, sizeof(UnicodeTestString) / sizeof(wchar_t) - 1)); - std::cout << str << std::endl; - std::cerr << str << std::endl; - } - - std::string input; - HANDLE event = OpenEventW(EVENT_MODIFY_STATE, FALSE, BeforeInputEventName); - if (event) { - SetEvent(event); - CloseHandle(event); - } - - std::cin >> input; - std::cout << input << std::endl; - event = OpenEventW(EVENT_MODIFY_STATE, FALSE, AfterOutputEventName); - if (event) { - SetEvent(event); - CloseHandle(event); - } -#else - static_cast(argc); - static_cast(argv); -#endif - return 0; -}