KWSys 2016-11-28 (1c7c2139)

Code extracted from:

    http://public.kitware.com/KWSys.git

at commit 1c7c2139e773124c0a2b80e10b2840c22a750980 (master).

Upstream Shortlog
-----------------

Brad King (2):
      5e556d53 Refactor CMake policy settings
      cb55cf5a Set CMake Policy CMP0063 to NEW within KWSys

Dāvis Mosāns (1):
      1c7c2139 ConsoleBuf: Fix character handling between buffer boundaries
This commit is contained in:
KWSys Upstream
2016-11-28 09:03:37 -05:00
committed by Brad King
parent 0a56e6fe35
commit cd5cff1337
2 changed files with 53 additions and 33 deletions

View File

@@ -67,12 +67,15 @@
# written. # written.
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR) CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
IF(POLICY CMP0025) FOREACH(p
CMAKE_POLICY(SET CMP0025 NEW) CMP0025 # CMake 3.0, Compiler id for Apple Clang is now AppleClang.
ENDIF() CMP0056 # CMake 3.2, Honor link flags in try_compile() source-file signature.
IF(POLICY CMP0056) CMP0063 # CMake 3.3, Honor visibility properties for all target types.
CMAKE_POLICY(SET CMP0056 NEW) )
ENDIF() IF(POLICY ${p})
CMAKE_POLICY(SET ${p} NEW)
ENDIF()
ENDFOREACH()
SET(CMAKE_LEGACY_CYGWIN_WIN32 0) SET(CMAKE_LEGACY_CYGWIN_WIN32 0)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------

View File

@@ -147,42 +147,47 @@ protected:
return Traits::eof(); return Traits::eof();
} }
if (m_isConsoleInput) { if (m_isConsoleInput) {
wchar_t wbuffer[128]; // ReadConsole doesn't tell if there's more input available
// don't support reading more characters than this
wchar_t wbuffer[8192];
DWORD charsRead; DWORD charsRead;
if (::ReadConsoleW(m_hInput, wbuffer, if (ReadConsoleW(m_hInput, wbuffer,
(sizeof(wbuffer) / sizeof(wbuffer[0])) - 1, (sizeof(wbuffer) / sizeof(wbuffer[0])), &charsRead,
&charsRead, NULL) == 0 || NULL) == 0 ||
charsRead == 0) { charsRead == 0) {
_setg(true); _setg(true);
return Traits::eof(); return Traits::eof();
} }
wbuffer[charsRead] = L'\0'; setBuffer(std::wstring(wbuffer, charsRead), m_ibuffer);
setBuffer(wbuffer, m_ibuffer);
} else { } else {
std::wstring totalBuffer;
std::wstring wbuffer; std::wstring wbuffer;
char buffer[128]; std::string strbuffer;
DWORD bytesRead; DWORD bytesRead;
while (::ReadFile(m_hInput, buffer, LARGE_INTEGER size;
(sizeof(buffer) / sizeof(buffer[0])) - 1, &bytesRead, if (GetFileSizeEx(m_hInput, &size) == 0) {
NULL) == 0) { _setg(true);
if (::GetLastError() == ERROR_MORE_DATA) { return Traits::eof();
buffer[bytesRead] = '\0'; }
if (decodeInputBuffer(buffer, wbuffer)) { char* buffer = new char[size.LowPart];
totalBuffer += wbuffer; while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, NULL) ==
continue; 0) {
} if (GetLastError() == ERROR_MORE_DATA) {
strbuffer += std::string(buffer, bytesRead);
continue;
} }
_setg(true); _setg(true);
delete[] buffer;
return Traits::eof(); return Traits::eof();
} }
buffer[bytesRead] = '\0'; if (bytesRead > 0) {
if (!decodeInputBuffer(buffer, wbuffer)) { strbuffer += std::string(buffer, bytesRead);
}
delete[] buffer;
if (!decodeInputBuffer(strbuffer, wbuffer)) {
_setg(true); _setg(true);
return Traits::eof(); return Traits::eof();
} }
totalBuffer += wbuffer; setBuffer(wbuffer, m_ibuffer);
setBuffer(totalBuffer, m_ibuffer);
} }
_setg(); _setg();
} }
@@ -315,6 +320,10 @@ private:
} }
bool encodeOutputBuffer(const std::wstring wbuffer, std::string& buffer) bool encodeOutputBuffer(const std::wstring wbuffer, std::string& buffer)
{ {
if (wbuffer.size() == 0) {
buffer = std::string();
return true;
}
const int length = const int length =
WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
(int)wbuffer.size(), NULL, 0, NULL, NULL); (int)wbuffer.size(), NULL, 0, NULL, NULL);
@@ -329,23 +338,31 @@ private:
delete[] buf; delete[] buf;
return success; return success;
} }
bool decodeInputBuffer(const char* buffer, std::wstring& wbuffer) bool decodeInputBuffer(const std::string buffer, std::wstring& wbuffer)
{ {
int length = int(buffer.length());
if (length == 0) {
wbuffer = std::wstring();
return true;
}
int actualCodepage = m_activeInputCodepage; int actualCodepage = m_activeInputCodepage;
const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) }; const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) };
if (std::memcmp(buffer, BOM_UTF8, sizeof(BOM_UTF8)) == 0) { const char* data = buffer.data();
const size_t BOMsize = sizeof(BOM_UTF8);
if (length >= BOMsize && std::memcmp(data, BOM_UTF8, BOMsize) == 0) {
// PowerShell uses UTF-8 with BOM for pipes // PowerShell uses UTF-8 with BOM for pipes
actualCodepage = CP_UTF8; actualCodepage = CP_UTF8;
buffer += sizeof(BOM_UTF8); data += BOMsize;
length -= BOMsize;
} }
const int wlength = const int wlength =
MultiByteToWideChar(actualCodepage, 0, buffer, -1, NULL, 0); MultiByteToWideChar(actualCodepage, 0, data, length, NULL, 0);
wchar_t* wbuf = new wchar_t[wlength]; wchar_t* wbuf = new wchar_t[wlength];
const bool success = const bool success =
MultiByteToWideChar(actualCodepage, 0, buffer, -1, wbuf, wlength) > 0 MultiByteToWideChar(actualCodepage, 0, data, length, wbuf, wlength) > 0
? true ? true
: false; : false;
wbuffer = wbuf; wbuffer = std::wstring(wbuf, wlength);
delete[] wbuf; delete[] wbuf;
return success; return success;
} }