This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake".
The branch, next has been updated via 92361799e2db5eb94c29d3161ee9c06253b11021 (commit) via 3876e2976ed5ca7b2505decb22b3b001944fd027 (commit) via 9783ed1e6eaf87bea54633599a2025026343bbc9 (commit) from 6d95d6d798eb00ce9176a8a5357c9b1143442347 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=92361799e2db5eb94c29d3161ee9c06253b11021 commit 92361799e2db5eb94c29d3161ee9c06253b11021 Merge: 6d95d6d 3876e29 Author: Brad King <brad.k...@kitware.com> AuthorDate: Tue Sep 20 09:06:04 2016 -0400 Commit: CMake Topic Stage <kwro...@kitware.com> CommitDate: Tue Sep 20 09:06:04 2016 -0400 Merge topic 'update-kwsys' into next 3876e297 Merge branch 'upstream-KWSys' into update-kwsys 9783ed1e KWSys 2016-09-20 (3f69ac40) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3876e2976ed5ca7b2505decb22b3b001944fd027 commit 3876e2976ed5ca7b2505decb22b3b001944fd027 Merge: 6b8812c 9783ed1 Author: Brad King <brad.k...@kitware.com> AuthorDate: Tue Sep 20 09:04:14 2016 -0400 Commit: Brad King <brad.k...@kitware.com> CommitDate: Tue Sep 20 09:04:14 2016 -0400 Merge branch 'upstream-KWSys' into update-kwsys * upstream-KWSys: KWSys 2016-09-20 (3f69ac40) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9783ed1e6eaf87bea54633599a2025026343bbc9 commit 9783ed1e6eaf87bea54633599a2025026343bbc9 Author: KWSys Upstream <kwro...@kitware.com> AuthorDate: Tue Sep 20 09:00:49 2016 -0400 Commit: Brad King <brad.k...@kitware.com> CommitDate: Tue Sep 20 09:04:05 2016 -0400 KWSys 2016-09-20 (3f69ac40) Code extracted from: http://public.kitware.com/KWSys.git at commit 3f69ac4009443743e17d6335f1952b8755aee054 (master). Upstream Shortlog ----------------- Dāvis Mosāns (6): f53440fe ConsoleBuf: Improve test error messages fd9e86e8 ConsoleBuf: Use two separate events for test sync fb8530ed ConsoleBuf: Make test more reliable c49ddccb ConsoleBuf: Fix test registry restoration 10e3f947 ConsoleBuf: Fix test to compare all bytes of wide character strings 3f69ac40 ConsoleBuf: Output console and test buffers on test failure diff --git a/testConsoleBuf.cxx b/testConsoleBuf.cxx index 3dec097..3dc3337 100644 --- a/testConsoleBuf.cxx +++ b/testConsoleBuf.cxx @@ -31,6 +31,7 @@ #include <string.h> #include <wchar.h> #include <iostream> +#include <iomanip> #include <stdexcept> #include "testConsoleBuf.hxx" @@ -44,10 +45,67 @@ static UINT TestCodepage = KWSYS_ENCODING_DEFAULT_CODEPAGE; static const DWORD waitTimeout = 10 * 1000; static STARTUPINFO startupInfo; static PROCESS_INFORMATION processInfo; -static HANDLE syncEvent; +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, + NULL, + errorCode, + 0, + (LPWSTR)&message, 0, + NULL) + ) { + 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<char> *errstream(const char *unused) { + static_cast<void>(unused); + return std::cerr.rdbuf(); +} + +std::basic_streambuf<wchar_t> *errstream(const wchar_t *unused) { + static_cast<void>(unused); + return std::wcerr.rdbuf(); +} + +//---------------------------------------------------------------------------- +template<typename T> +static void dumpBuffers(const T *expected, const T *received, size_t size) { + std::basic_ostream<T> err(errstream(expected)); + err << "Expected output: '" << std::basic_string<T>(expected, size) << "'" << std::endl; + if (err.fail()) { + err.clear(); + err << "--- Error while outputting ---" << std::endl; + } + err << "Received output: '" << std::basic_string<T>(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<unsigned int>(expected[i]) << " | " << + "0x" << std::setw(8) << static_cast<unsigned int>(received[i]); + if (static_cast<unsigned int>(expected[i]) != static_cast<unsigned int>(received[i])) { + std::cerr << " MISMATCH!"; + } + std::cerr << std::endl; + } + std::cerr << std::endl << std::flush; +} + //---------------------------------------------------------------------------- static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) { @@ -89,23 +147,8 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr) &processInfo) != 0; // Pointer to PROCESS_INFORMATION structure if (!success) { DWORD lastError = GetLastError(); - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) - << ") failed with error: 0x" << lastError << "!" << std::endl; - LPWSTR message; - if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - lastError, - 0, - (LPWSTR)&message, 0, - NULL) - ) { - 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::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")" << std::endl; + displayError(lastError); } return success; } @@ -162,8 +205,9 @@ static HANDLE createFile(LPCWSTR fileName) FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); // no template if (file == INVALID_HANDLE_VALUE) { - std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) - << ") failed!" << std::endl; + DWORD lastError = GetLastError(); + std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" << std::endl; + displayError(lastError); } return file; } @@ -232,6 +276,7 @@ static int testPipe() HANDLE errPipeWrite = INVALID_HANDLE_VALUE; UINT currentCodepage = GetConsoleCP(); char buffer[200]; + char buffer2[200]; try { if (!createPipe(&inPipeRead, &inPipeWrite) || !createPipe(&outPipeRead, &outPipeWrite) || @@ -254,20 +299,23 @@ static int testPipe() if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) { try { - Sleep(100); - if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) { + 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, NULL) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#1 failed!"); } if ((bytesRead < encodedTestString.size() + 1 + encodedInputTestString.size() && !ReadFile(outPipeRead, buffer + bytesRead, sizeof(buffer) - bytesRead, &bytesRead, NULL)) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#2 failed!"); } if (memcmp(buffer, encodedTestString.c_str(), encodedTestString.size()) == 0 && @@ -275,23 +323,30 @@ static int testPipe() encodedInputTestString.c_str(), encodedInputTestString.size()) == 0) { bytesRead = 0; - if (!ReadFile(errPipeRead, buffer, sizeof(buffer), &bytesRead, NULL) + if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead, NULL) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#3 failed!"); } - buffer[bytesRead - 1] = 0; - didFail = encodedTestString.compare(buffer) == 0 ? 0 : 1; + buffer2[bytesRead - 1] = 0; + didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1; } if (didFail != 0) { std::cerr << "Pipe's output didn't match expected output!" << std::endl << std::flush; + dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size()); + dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size()); + dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size()); } } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishProcess(didFail == 0); } } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishPipe(inPipeRead, inPipeWrite); finishPipe(outPipeRead, outPipeWrite); @@ -316,6 +371,7 @@ static int testFile() int length = 0; DWORD bytesWritten = 0; char buffer[200]; + char buffer2[200]; if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1, buffer, sizeof(buffer), @@ -334,17 +390,20 @@ static int testFile() if (createProcess(inFile, outFile, errFile)) { DWORD bytesRead = 0; try { - Sleep(100); - if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) { + 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 failed!"); + throw std::runtime_error("SetFilePointer#1 failed!"); } if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#1 failed!"); } buffer[bytesRead - 1] = 0; if (memcmp(buffer, encodedTestString.c_str(), @@ -355,25 +414,32 @@ static int testFile() bytesRead = 0; if (SetFilePointer(errFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { - throw std::runtime_error("SetFilePointer failed!"); + throw std::runtime_error("SetFilePointer#2 failed!"); } - if (!ReadFile(errFile, buffer, sizeof(buffer), &bytesRead, NULL) + if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, NULL) || bytesRead == 0) { - throw std::runtime_error("ReadFile failed!"); + throw std::runtime_error("ReadFile#2 failed!"); } - buffer[bytesRead - 1] = 0; - didFail = encodedTestString.compare(buffer) == 0 ? 0 : 1; + buffer2[bytesRead - 1] = 0; + didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1; } if (didFail != 0) { std::cerr << "File's output didn't match expected output!" << std::endl << std::flush; + dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size()); + dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size() - 1); + dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size()); } } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishProcess(didFail == 0); } } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishFile(inFile); finishFile(outFile); @@ -403,6 +469,7 @@ static int testConsole() const DWORD TestFontSize = 0x000c0000; HKEY hConsoleKey; WCHAR FaceName[200]; + FaceName[0] = 0; DWORD FaceNameSize = sizeof(FaceName); DWORD FontFamily = TestFontFamily; DWORD FontSize = TestFontSize; @@ -459,10 +526,20 @@ static int testConsole() securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttributes.bInheritHandle = TRUE; securityAttributes.lpSecurityDescriptor = NULL; - hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, 0, + hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, OPEN_EXISTING, 0, NULL); - hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, 0, + 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, NULL); + 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); @@ -496,8 +573,12 @@ static int testConsole() KEY_WRITE, &hConsoleKey) == ERROR_SUCCESS) { RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD, (BYTE *)&FontFamily, sizeof(FontFamily)); - RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ, - (BYTE *)FaceName, FaceNameSize); + 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); @@ -508,8 +589,12 @@ static int testConsole() if (createProcess(NULL, NULL, NULL)) { try { - if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) { - throw std::runtime_error("WaitForSingleObject failed!"); + 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]; @@ -521,13 +606,18 @@ static int testConsole() } 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 (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) { - throw std::runtime_error("WaitForSingleObject 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)) { @@ -547,22 +637,30 @@ static int testConsole() } std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString); std::wstring wideInputTestString = kwsys::Encoding::ToWide(encodedInputTestString); - if (memcmp(outputBuffer, wideTestString.c_str(), wideTestString.size()) == 0 && + if (memcmp(outputBuffer, wideTestString.c_str(), + wideTestString.size() * sizeof(wchar_t)) == 0 && memcmp(outputBuffer + screenBufferInfo.dwSize.X * 1, - wideTestString.c_str(), wideTestString.size()) == 0 && + 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) == 0 + 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 << std::flush; + dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer, wideTestString.size()); + dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 1, wideTestString.size()); + dumpBuffers<wchar_t>(UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2, (sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR)); + dumpBuffers<wchar_t>(wideInputTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 3, wideInputTestString.size() - 1); } delete[] outputBuffer; } catch (const std::runtime_error &ex) { - std::cerr << ex.what() << std::endl << std::flush; + DWORD lastError = GetLastError(); + std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush; + displayError(lastError); } finishProcess(didFail == 0); } @@ -585,12 +683,18 @@ int testConsoleBuf(int, char*[]) int ret = 0; #if defined(_WIN32) - syncEvent = CreateEventW(NULL, - FALSE, // auto-reset event - FALSE, // initial state is nonsignaled - SyncEventName); // object name - if (!syncEvent) { - std::cerr << "CreateEvent failed " << GetLastError() << std::endl; + beforeInputEvent = CreateEventW(NULL, + 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(NULL, FALSE, FALSE, AfterOutputEventName); + if (!afterOutputEvent) { + std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl; return 1; } @@ -602,7 +706,8 @@ int testConsoleBuf(int, char*[]) ret |= testFile(); ret |= testConsole(); - CloseHandle(syncEvent); + CloseHandle(beforeInputEvent); + CloseHandle(afterOutputEvent); #endif return ret; diff --git a/testConsoleBuf.hxx b/testConsoleBuf.hxx index 855028b..7c2f4c6 100644 --- a/testConsoleBuf.hxx +++ b/testConsoleBuf.hxx @@ -14,7 +14,8 @@ static const wchar_t cmdConsoleBufChild[] = L"testConsoleBufChild"; -static const wchar_t SyncEventName[] = L"SyncEvent"; +static const wchar_t BeforeInputEventName[] = L"BeforeInputEvent"; +static const wchar_t AfterOutputEventName[] = L"AfterOutputEvent"; // यूनिकोड είναι здорово! static const wchar_t UnicodeTestString[] = L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 " diff --git a/testConsoleBufChild.cxx b/testConsoleBufChild.cxx index 3b9ab71..2da39f2 100644 --- a/testConsoleBufChild.cxx +++ b/testConsoleBufChild.cxx @@ -42,16 +42,18 @@ int main(int argc, const char* argv[]) } std::string input; - HANDLE syncEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, SyncEventName); - if (syncEvent) { - SetEvent(syncEvent); + HANDLE event = OpenEventW(EVENT_MODIFY_STATE, FALSE, BeforeInputEventName); + if (event) { + SetEvent(event); + CloseHandle(event); } std::cin >> input; std::cout << input << std::endl; - if (syncEvent) { - SetEvent(syncEvent); - CloseHandle(syncEvent); + event = OpenEventW(EVENT_MODIFY_STATE, FALSE, AfterOutputEventName); + if (event) { + SetEvent(event); + CloseHandle(event); } #else static_cast<void>(argc); ----------------------------------------------------------------------- Summary of changes: Source/kwsys/testConsoleBuf.cxx | 225 +++++++++++++++++++++++++--------- Source/kwsys/testConsoleBuf.hxx | 3 +- Source/kwsys/testConsoleBufChild.cxx | 14 ++- 3 files changed, 175 insertions(+), 67 deletions(-) hooks/post-receive -- CMake _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org http://public.kitware.com/mailman/listinfo/cmake-commits