THRIFT-4081: appveyor retooling - added mingw64 build as a second job to the CI build process

This closes #1205
diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt
index d07b400..9a1ef10 100755
--- a/lib/cpp/CMakeLists.txt
+++ b/lib/cpp/CMakeLists.txt
@@ -68,7 +68,7 @@
 endif()
 
 
-if (WIN32)
+if (WIN32 AND NOT MSYS)
     list(APPEND thriftcpp_SOURCES
         src/thrift/windows/TWinsockSingleton.cpp
         src/thrift/windows/SocketPair.cpp
diff --git a/lib/cpp/src/thrift/concurrency/StdMutex.cpp b/lib/cpp/src/thrift/concurrency/StdMutex.cpp
index 69678a2..49c18d8 100644
--- a/lib/cpp/src/thrift/concurrency/StdMutex.cpp
+++ b/lib/cpp/src/thrift/concurrency/StdMutex.cpp
@@ -38,6 +38,7 @@
 class Mutex::impl : public std::timed_mutex {};
 
 Mutex::Mutex(Initializer init) : impl_(new Mutex::impl()) {
+  ((void)init);
 }
 
 void* Mutex::getUnderlyingImpl() const {
@@ -61,6 +62,7 @@
 }
 
 void Mutex::DEFAULT_INITIALIZER(void* arg) {
+  ((void)arg);
 }
 }
 }
diff --git a/lib/cpp/src/thrift/protocol/TProtocol.h b/lib/cpp/src/thrift/protocol/TProtocol.h
index 448c4fe..276cefa 100644
--- a/lib/cpp/src/thrift/protocol/TProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TProtocol.h
@@ -601,7 +601,7 @@
 
   virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) = 0;
   virtual boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> inTrans,
-						   boost::shared_ptr<TTransport> outTrans) {
+               boost::shared_ptr<TTransport> outTrans) {
     (void)outTrans;
     return getProtocol(inTrans);
   }
@@ -672,7 +672,7 @@
     return prot.readBool(boolv);
   }
   case T_BYTE: {
-    int8_t bytev;
+    int8_t bytev = 0;
     return prot.readByte(bytev);
   }
   case T_I16: {
diff --git a/lib/cpp/src/thrift/transport/TPipe.cpp b/lib/cpp/src/thrift/transport/TPipe.cpp
index 75ce5d2..0f48903 100644
--- a/lib/cpp/src/thrift/transport/TPipe.cpp
+++ b/lib/cpp/src/thrift/transport/TPipe.cpp
@@ -346,7 +346,7 @@
 }
 
 void TPipe::setPipename(const std::string& pipename) {
-  if (pipename.find("\\\\") == -1)
+  if (pipename.find("\\\\") == std::string::npos)
     pipename_ = "\\\\.\\pipe\\" + pipename;
   else
     pipename_ = pipename;
diff --git a/lib/cpp/src/thrift/transport/TPipeServer.cpp b/lib/cpp/src/thrift/transport/TPipeServer.cpp
index cf6b410..5a07f30 100644
--- a/lib/cpp/src/thrift/transport/TPipeServer.cpp
+++ b/lib/cpp/src/thrift/transport/TPipeServer.cpp
@@ -361,7 +361,7 @@
     GlobalOutput.perror("TPipeServer::TCreateNamedPipe() GLE=", lastError);
     throw TTransportException(TTransportException::NOT_OPEN,
                               "TCreateNamedPipe() failed",
-							  lastError);
+                lastError);
     return false;
   }
 
@@ -409,7 +409,7 @@
 }
 
 void TPipeServer::setPipename(const std::string& pipename) {
-  if (pipename.find("\\\\") == -1)
+  if (pipename.find("\\\\") == std::string::npos)
     pipename_ = "\\\\.\\pipe\\" + pipename;
   else
     pipename_ = pipename;
diff --git a/lib/cpp/src/thrift/transport/TServerSocket.cpp b/lib/cpp/src/thrift/transport/TServerSocket.cpp
index 8b65319..dc698d5 100644
--- a/lib/cpp/src/thrift/transport/TServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TServerSocket.cpp
@@ -609,7 +609,7 @@
   THRIFT_SOCKET clientSocket
       = ::accept(serverSocket_, (struct sockaddr*)&clientAddress, (socklen_t*)&size);
 
-  if (clientSocket == -1) {
+  if (clientSocket == THRIFT_INVALID_SOCKET) {
     int errno_copy = THRIFT_GET_SOCKET_ERROR;
     GlobalOutput.perror("TServerSocket::acceptImpl() ::accept() ", errno_copy);
     throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy);
diff --git a/lib/cpp/src/thrift/transport/TSocket.cpp b/lib/cpp/src/thrift/transport/TSocket.cpp
index 9fad590..21a9aca 100644
--- a/lib/cpp/src/thrift/transport/TSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TSocket.cpp
@@ -763,7 +763,7 @@
 void TSocket::setKeepAlive(bool keepAlive) {
   keepAlive_ = keepAlive;
 
-  if (socket_ == -1) {
+  if (socket_ == THRIFT_INVALID_SOCKET) {
     return;
   }
 
diff --git a/lib/cpp/src/thrift/windows/config.h b/lib/cpp/src/thrift/windows/config.h
index f54cb5e..bc4aa42 100644
--- a/lib/cpp/src/thrift/windows/config.h
+++ b/lib/cpp/src/thrift/windows/config.h
@@ -66,7 +66,9 @@
 #define SIGNED_RIGHT_SHIFT_IS 1
 #endif
 
+#ifndef __MINGW32__
 #pragma warning(disable : 4996) // Deprecated posix name.
+#endif
 
 #define HAVE_GETTIMEOFDAY 1
 #define HAVE_SYS_STAT_H 1
@@ -97,11 +99,14 @@
 // windows
 #include <Winsock2.h>
 #include <ws2tcpip.h>
-#ifdef _WIN32_WCE
-#pragma comment(lib, "Ws2.lib")
-#else
-#pragma comment(lib, "Ws2_32.lib")
-#pragma comment(lib, "advapi32.lib") // For security APIs in TPipeServer
-#pragma comment(lib, "Shlwapi.lib")  // For StrStrIA in TPipeServer
-#endif
+#ifndef __MINGW32__
+  #ifdef _WIN32_WCE
+  #pragma comment(lib, "Ws2.lib")
+  #else
+  #pragma comment(lib, "Ws2_32.lib")
+  #pragma comment(lib, "advapi32.lib") // For security APIs in TPipeServer
+  #pragma comment(lib, "Shlwapi.lib")  // For StrStrIA in TPipeServer
+  #endif
+#endif // __MINGW32__
+
 #endif // _THRIFT_WINDOWS_CONFIG_H_
diff --git a/lib/cpp/test/Base64Test.cpp b/lib/cpp/test/Base64Test.cpp
index e9e86dd..7686e4e 100644
--- a/lib/cpp/test/Base64Test.cpp
+++ b/lib/cpp/test/Base64Test.cpp
@@ -37,6 +37,10 @@
 }
 
 void checkEncoding(uint8_t* data, int len) {
+#ifdef NDEBUG
+  ((void)data);
+#endif
+
   for (int i = 0; i < len; i++) {
     BOOST_ASSERT(isalnum(data[i]) || data[i] == '/' || data[i] == '+');
   }
diff --git a/lib/cpp/test/CMakeLists.txt b/lib/cpp/test/CMakeLists.txt
index b7a7798..ef3d417 100644
--- a/lib/cpp/test/CMakeLists.txt
+++ b/lib/cpp/test/CMakeLists.txt
@@ -79,7 +79,7 @@
     TServerTransportTest.cpp
 )
 
-if(NOT WITH_BOOSTTHREADS AND NOT WITH_STDTHREADS AND NOT MSVC)
+if(NOT WITH_BOOSTTHREADS AND NOT WITH_STDTHREADS AND NOT MSVC AND NOT MINGW)
     list(APPEND UnitTest_SOURCES RWMutexStarveTest.cpp)
 endif()
 
@@ -112,7 +112,7 @@
 if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
 target_link_libraries(TInterruptTest -lrt)
 endif ()
-add_test(NAME TInterruptTest COMMAND TInterruptTest "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
+add_test(NAME TInterruptTest COMMAND TInterruptTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
 
 add_executable(TServerIntegrationTest TServerIntegrationTest.cpp)
 target_link_libraries(TServerIntegrationTest
@@ -317,7 +317,7 @@
 if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
 target_link_libraries(SecurityTest -lrt)
 endif ()
-add_test(NAME SecurityTest COMMAND SecurityTest "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
+add_test(NAME SecurityTest COMMAND SecurityTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
 
 endif()
 
diff --git a/lib/cpp/test/TFileTransportTest.cpp b/lib/cpp/test/TFileTransportTest.cpp
index 82e84e8..700a1ac 100644
--- a/lib/cpp/test/TFileTransportTest.cpp
+++ b/lib/cpp/test/TFileTransportTest.cpp
@@ -83,7 +83,7 @@
   void fsync(int fd) {
     (void)fd;
     FsyncCall call;
-    gettimeofday(&call.time, NULL);
+    THRIFT_GETTIMEOFDAY(&call.time, NULL);
     calls_.push_back(call);
   }
 
@@ -100,6 +100,7 @@
 public:
   TempFile(const char* directory, const char* prefix) {
   #ifdef __MINGW32__
+    ((void)directory);
     size_t path_len = strlen(prefix) + 8;
     path_ = new char[path_len];
     snprintf(path_, path_len, "%sXXXXXX", prefix);
@@ -208,9 +209,9 @@
     struct timeval start;
     struct timeval end;
 
-    gettimeofday(&start, NULL);
+    THRIFT_GETTIMEOFDAY(&start, NULL);
     delete transport;
-    gettimeofday(&end, NULL);
+    THRIFT_GETTIMEOFDAY(&end, NULL);
 
     int delta = time_diff(&start, &end);
 
@@ -331,13 +332,13 @@
   transport.write(buf, 1);
 
   struct timeval start;
-  gettimeofday(&start, NULL);
+  THRIFT_GETTIMEOFDAY(&start, NULL);
 
   for (unsigned int n = 0; n < 10; ++n) {
     transport.flush();
 
     struct timeval now;
-    gettimeofday(&now, NULL);
+    THRIFT_GETTIMEOFDAY(&now, NULL);
 
     // Fail if at any point we've been running for longer than half a second.
     // (With the buggy code, TFileTransport used to take 3 seconds per flush())
diff --git a/lib/cpp/test/TSSLSocketInterruptTest.cpp b/lib/cpp/test/TSSLSocketInterruptTest.cpp
index ba43daf..bf5c7d7 100644
--- a/lib/cpp/test/TSSLSocketInterruptTest.cpp
+++ b/lib/cpp/test/TSSLSocketInterruptTest.cpp
@@ -214,7 +214,7 @@
   uint8_t buf[400];
   try {
     tt->read(buf, 1);
-    tt->peek();
+    BOOST_CHECK_EQUAL(expectedResult, tt->peek());
   } catch (const TTransportException& tx) {
     BOOST_CHECK_EQUAL(TTransportException::TIMED_OUT, tx.getType());
   }
diff --git a/lib/cpp/test/ZlibTest.cpp b/lib/cpp/test/ZlibTest.cpp
index a4387a9..25db4b8 100644
--- a/lib/cpp/test/ZlibTest.cpp
+++ b/lib/cpp/test/ZlibTest.cpp
@@ -21,7 +21,7 @@
 #define _GNU_SOURCE // needed for getopt_long
 #endif
 
-#if (_MSC_VER <= 1700)
+#if defined(_MSC_VER) && (_MSC_VER <= 1700)
 // polynomial and std::fill_t warning happens in MSVC 2010, 2013, maybe others
 // https://svn.boost.org/trac/boost/ticket/11426
 #pragma warning(disable:4996)
diff --git a/lib/java/CMakeLists.txt b/lib/java/CMakeLists.txt
index 57b97f1..f7a1a63 100644
--- a/lib/java/CMakeLists.txt
+++ b/lib/java/CMakeLists.txt
@@ -74,7 +74,7 @@
 
     if(BUILD_TESTING)
         add_test(NAME JavaTest
-                 COMMAND ${Ant_EXECUTABLE} ${ANT_FLAGS} -Dbuild.dir="${CMAKE_CURRENT_BINARY_DIR}" -Dthrift.compiler="${THRIFT_COMPILER}" -f build.xml test
+                 COMMAND ${Ant_EXECUTABLE} ${ANT_FLAGS} -Dbuild.dir=${CMAKE_CURRENT_BINARY_DIR} -Dthrift.compiler=${THRIFT_COMPILER} -f build.xml test
                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
     endif()
 endif(ANDROID)
diff --git a/lib/py/src/ext/module.cpp b/lib/py/src/ext/module.cpp
index 34ec7f6..7158b8f 100644
--- a/lib/py/src/ext/module.cpp
+++ b/lib/py/src/ext/module.cpp
@@ -87,12 +87,7 @@
   }
 
   T protocol;
-#ifdef _MSC_VER
-  // workaround strange VC++ 2015 bug where #else path does not compile
-  int32_t default_limit = INT32_MAX;
-#else
-  int32_t default_limit = std::numeric_limits<int32_t>::max();
-#endif
+  int32_t default_limit = (std::numeric_limits<int32_t>::max)();
   protocol.setStringLengthLimit(
       as_long_then_delete(PyObject_GetAttr(oprot, INTERN_STRING(string_length_limit)),
                           default_limit));