Browse Source

Merge topic 'update-kwsys'

7f307d9e Merge branch 'upstream-KWSys' into update-kwsys
1b50bd3f KWSys 2016-12-02 (4967ccc0)
Brad King 9 years ago
parent
commit
22f05b1d8c

+ 12 - 1
Source/kwsys/CMakeLists.txt

@@ -429,6 +429,17 @@ SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES
   COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T}"
   )
 
+IF(KWSYS_USE_DynamicLoader)
+  GET_PROPERTY(KWSYS_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+  IF(KWSYS_SUPPORTS_SHARED_LIBS)
+    SET(KWSYS_SUPPORTS_SHARED_LIBS 1)
+  ELSE()
+    SET(KWSYS_SUPPORTS_SHARED_LIBS 0)
+  ENDIF()
+  SET_PROPERTY(SOURCE DynamicLoader.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+    KWSYS_SUPPORTS_SHARED_LIBS=${KWSYS_SUPPORTS_SHARED_LIBS})
+ENDIF()
+
 IF(KWSYS_USE_SystemTools)
   KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_SETENV
     "Checking whether CXX compiler has setenv" DIRECT)
@@ -868,7 +879,7 @@ ENDIF()
 
 IF(KWSYS_USE_Encoding)
   # Set default 8 bit encoding in "EndcodingC.c".
-  SET_PROPERTY(SOURCE EncodingC.c APPEND PROPERTY COMPILE_DEFINITIONS
+  SET_PROPERTY(SOURCE EncodingC.c EncodingCXX.cxx APPEND PROPERTY COMPILE_DEFINITIONS
     KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
 ENDIF()
 

+ 2 - 3
Source/kwsys/ConsoleBuf.hxx.in

@@ -327,14 +327,13 @@ private:
     const int length =
       WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
                           (int)wbuffer.size(), NULL, 0, NULL, NULL);
-    char* buf = new char[length + 1];
+    char* buf = new char[length];
     const bool success =
       WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
                           (int)wbuffer.size(), buf, length, NULL, NULL) > 0
       ? true
       : false;
-    buf[length] = '\0';
-    buffer = buf;
+    buffer = std::string(buf, length);
     delete[] buf;
     return success;
   }

+ 68 - 86
Source/kwsys/DynamicLoader.cxx

@@ -12,20 +12,63 @@
 #include "DynamicLoader.hxx.in"
 #endif
 
-// This file is actually 3 different implementations.
-// 1. HP machines which uses shl_load
-// 2. Mac OS X 10.2.x and earlier which uses NSLinkModule
-// 3. Windows which uses LoadLibrary
-// 4. Most unix systems (including Mac OS X 10.3 and later) which use dlopen
-// (default) Each part of the ifdef contains a complete implementation for
+// This file actually contains several different implementations:
+// * NOOP for environments without dynamic libs
+// * HP machines which uses shl_load
+// * Mac OS X 10.2.x and earlier which uses NSLinkModule
+// * Windows which uses LoadLibrary
+// * BeOS / Haiku
+// * FreeMiNT for Atari
+// * Default implementation for *NIX systems (including Mac OS X 10.3 and
+//   later) which use dlopen
+//
+// Each part of the ifdef contains a complete implementation for
 // the static methods of DynamicLoader.
 
-// ---------------------------------------------------------------
-// 1. Implementation for HPUX  machines
-#ifdef __hpux
+#if !KWSYS_SUPPORTS_SHARED_LIBS
+//----------------------------------------------------------------------------
+// Implementation for environments without dynamic libs
+#include <string.h> // for strerror()
+
+namespace KWSYS_NAMESPACE {
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
+  const std::string& libname)
+{
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+  if (!lib) {
+    return 0;
+  }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+  DynamicLoader::LibraryHandle lib, const std::string& sym)
+{
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+{
+  return "General error";
+}
+
+} // namespace KWSYS_NAMESPACE
+
+#elif defined(__hpux)
+//----------------------------------------------------------------------------
+// Implementation for HPUX  machines
 #include <dl.h>
 #include <errno.h>
-#define DYNAMICLOADER_DEFINED 1
 
 namespace KWSYS_NAMESPACE {
 
@@ -88,15 +131,11 @@ const char* DynamicLoader::LastError()
 
 } // namespace KWSYS_NAMESPACE
 
-#endif //__hpux
-
-// ---------------------------------------------------------------
-// 2. Implementation for Mac OS X 10.2.x and earlier
-#ifdef __APPLE__
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
+#elif defined(__APPLE__) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1030)
+//----------------------------------------------------------------------------
+// Implementation for Mac OS X 10.2.x and earlier
 #include <mach-o/dyld.h>
 #include <string.h> // for strlen
-#define DYNAMICLOADER_DEFINED 1
 
 namespace KWSYS_NAMESPACE {
 
@@ -160,14 +199,10 @@ const char* DynamicLoader::LastError()
 
 } // namespace KWSYS_NAMESPACE
 
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1030
-#endif // __APPLE__
-
-// ---------------------------------------------------------------
-// 3. Implementation for Windows win32 code but not cygwin
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+//----------------------------------------------------------------------------
+// Implementation for Windows win32 code but not cygwin
 #include <windows.h>
-#define DYNAMICLOADER_DEFINED 1
 
 namespace KWSYS_NAMESPACE {
 
@@ -263,19 +298,14 @@ const char* DynamicLoader::LastError()
 
 } // namespace KWSYS_NAMESPACE
 
-#endif //_WIN32
-
-// ---------------------------------------------------------------
-// 4. Implementation for BeOS
-#if defined __BEOS__
-
+#elif defined(__BEOS__)
+//----------------------------------------------------------------------------
+// Implementation for BeOS / Haiku
 #include <string.h> // for strerror()
 
 #include <be/kernel/image.h>
 #include <be/support/Errors.h>
 
-#define DYNAMICLOADER_DEFINED 1
-
 namespace KWSYS_NAMESPACE {
 
 static image_id last_dynamic_err = B_OK;
@@ -351,54 +381,10 @@ const char* DynamicLoader::LastError()
 }
 
 } // namespace KWSYS_NAMESPACE
-#endif
-
-// ---------------------------------------------------------------
-// 5. Implementation for systems without dynamic libs
-// __gnu_blrts__ is IBM BlueGene/L
-// __LIBCATAMOUNT__ is defined on Catamount on Cray compute nodes
-#if defined(__gnu_blrts__) || defined(__LIBCATAMOUNT__) ||                    \
-  defined(__CRAYXT_COMPUTE_LINUX_TARGET)
-#include <string.h> // for strerror()
-#define DYNAMICLOADER_DEFINED 1
-
-namespace KWSYS_NAMESPACE {
-
-//----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
-  const std::string& libname)
-{
-  return 0;
-}
 
+#elif defined(__MINT__)
 //----------------------------------------------------------------------------
-int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
-{
-  if (!lib) {
-    return 0;
-  }
-
-  return 1;
-}
-
-//----------------------------------------------------------------------------
-DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
-  DynamicLoader::LibraryHandle lib, const std::string& sym)
-{
-  return 0;
-}
-
-//----------------------------------------------------------------------------
-const char* DynamicLoader::LastError()
-{
-  return "General error";
-}
-
-} // namespace KWSYS_NAMESPACE
-#endif
-
-#ifdef __MINT__
-#define DYNAMICLOADER_DEFINED 1
+// Implementation for FreeMiNT on Atari
 #define _GNU_SOURCE /* for program_invocation_name */
 #include <dld.h>
 #include <errno.h>
@@ -447,14 +433,11 @@ const char* DynamicLoader::LastError()
 }
 
 } // namespace KWSYS_NAMESPACE
-#endif
 
-// ---------------------------------------------------------------
-// 6. Implementation for default UNIX machines.
-// if nothing has been defined then use this
-#ifndef DYNAMICLOADER_DEFINED
-#define DYNAMICLOADER_DEFINED 1
-// Setup for most unix machines
+#else
+//----------------------------------------------------------------------------
+// Default implementation for *NIX systems (including Mac OS X 10.3 and
+// later) which use dlopen
 #include <dlfcn.h>
 
 namespace KWSYS_NAMESPACE {
@@ -498,5 +481,4 @@ const char* DynamicLoader::LastError()
 }
 
 } // namespace KWSYS_NAMESPACE
-
 #endif

+ 58 - 2
Source/kwsys/EncodingCXX.cxx

@@ -125,12 +125,68 @@ char const* const* Encoding::CommandLineArguments::argv() const
 
 std::wstring Encoding::ToWide(const std::string& str)
 {
-  return ToWide(str.c_str());
+  std::wstring wstr;
+#if defined(_WIN32)
+  const int wlength = MultiByteToWideChar(
+    KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), int(str.size()), NULL, 0);
+  if (wlength > 0) {
+    wchar_t* wdata = new wchar_t[wlength];
+    int r = MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(),
+                                int(str.size()), wdata, wlength);
+    if (r > 0) {
+      wstr = std::wstring(wdata, wlength);
+    }
+    delete[] wdata;
+  }
+#else
+  size_t pos = 0;
+  size_t nullPos = 0;
+  do {
+    if (pos < str.size() && str.at(pos) != '\0') {
+      wstr += ToWide(str.c_str() + pos);
+    }
+    nullPos = str.find('\0', pos);
+    if (nullPos != str.npos) {
+      pos = nullPos + 1;
+      wstr += wchar_t('\0');
+    }
+  } while (nullPos != str.npos);
+#endif
+  return wstr;
 }
 
 std::string Encoding::ToNarrow(const std::wstring& str)
 {
-  return ToNarrow(str.c_str());
+  std::string nstr;
+#if defined(_WIN32)
+  int length =
+    WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(),
+                        int(str.size()), NULL, 0, NULL, NULL);
+  if (length > 0) {
+    char* data = new char[length];
+    int r =
+      WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(),
+                          int(str.size()), data, length, NULL, NULL);
+    if (r > 0) {
+      nstr = std::string(data, length);
+    }
+    delete[] data;
+  }
+#else
+  size_t pos = 0;
+  size_t nullPos = 0;
+  do {
+    if (pos < str.size() && str.at(pos) != '\0') {
+      nstr += ToNarrow(str.c_str() + pos);
+    }
+    nullPos = str.find(wchar_t('\0'), pos);
+    if (nullPos != str.npos) {
+      pos = nullPos + 1;
+      nstr += '\0';
+    }
+  } while (nullPos != str.npos);
+#endif
+  return nstr;
 }
 
 std::wstring Encoding::ToWide(const char* cstr)

+ 24 - 9
Source/kwsys/testConsoleBuf.cxx

@@ -18,6 +18,7 @@
 
 #if defined(_WIN32)
 
+#include <algorithm>
 #include <iomanip>
 #include <iostream>
 #include <stdexcept>
@@ -318,6 +319,7 @@ static int testPipe()
             bytesRead == 0) {
           throw std::runtime_error("ReadFile#1 failed!");
         }
+        buffer[bytesRead] = 0;
         if ((bytesRead <
                encodedTestString.size() + 1 + encodedInputTestString.size() &&
              !ReadFile(outPipeRead, buffer + bytesRead,
@@ -336,8 +338,12 @@ static int testPipe()
               bytesRead == 0) {
             throw std::runtime_error("ReadFile#3 failed!");
           }
-          buffer2[bytesRead - 1] = 0;
-          didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
+          buffer2[bytesRead] = 0;
+          didFail =
+            encodedTestString.compare(0, encodedTestString.npos, buffer2,
+                                      encodedTestString.size()) == 0
+            ? 0
+            : 1;
         }
         if (didFail != 0) {
           std::cerr << "Pipe's output didn't match expected output!"
@@ -423,23 +429,28 @@ static int testFile()
             bytesRead == 0) {
           throw std::runtime_error("ReadFile#1 failed!");
         }
-        buffer[bytesRead - 1] = 0;
+        buffer[bytesRead] = 0;
         if (memcmp(buffer, encodedTestString.c_str(),
                    encodedTestString.size()) == 0 &&
             memcmp(buffer + encodedTestString.size() + 1,
                    encodedInputTestString.c_str(),
-                   encodedInputTestString.size() - 1) == 0) {
+                   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, NULL) ||
               bytesRead == 0) {
             throw std::runtime_error("ReadFile#2 failed!");
           }
-          buffer2[bytesRead - 1] = 0;
-          didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
+          buffer2[bytesRead] = 0;
+          didFail =
+            encodedTestString.compare(0, encodedTestString.npos, buffer2,
+                                      encodedTestString.size()) == 0
+            ? 0
+            : 1;
         }
         if (didFail != 0) {
           std::cerr << "File's output didn't match expected output!"
@@ -448,7 +459,7 @@ static int testFile()
                             encodedTestString.size());
           dumpBuffers<char>(encodedInputTestString.c_str(),
                             buffer + encodedTestString.size() + 1,
-                            encodedInputTestString.size() - 1);
+                            encodedInputTestString.size());
           dumpBuffers<char>(encodedTestString.c_str(), buffer2,
                             encodedTestString.size());
         }
@@ -685,6 +696,7 @@ static int testConsole()
         throw std::runtime_error("ReadConsoleOutputCharacter failed!");
       }
       std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString);
+      std::replace(wideTestString.begin(), wideTestString.end(), '\0', ' ');
       std::wstring wideInputTestString =
         kwsys::Encoding::ToWide(encodedInputTestString);
       if (memcmp(outputBuffer, wideTestString.c_str(),
@@ -757,8 +769,11 @@ int testConsoleBuf(int, char* [])
     return 1;
   }
 
-  encodedTestString = kwsys::Encoding::ToNarrow(UnicodeTestString);
-  encodedInputTestString = kwsys::Encoding::ToNarrow(UnicodeInputTestString);
+  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();

+ 1 - 1
Source/kwsys/testConsoleBuf.hxx

@@ -11,7 +11,7 @@ static const wchar_t AfterOutputEventName[] = L"AfterOutputEvent";
 // यूनिकोड είναι здорово!
 static const wchar_t UnicodeTestString[] =
   L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 "
-  L"\u03B5\u03AF\u03BD\u03B1\u03B9 "
+  L"\u03B5\u03AF\u03BD\0\u03B1\u03B9 "
   L"\u0437\u0434\u043E\u0440\u043E\u0432\u043E!";
 
 #endif

+ 2 - 1
Source/kwsys/testConsoleBufChild.cxx

@@ -28,7 +28,8 @@ int main(int argc, const char* argv[])
     std::cout << argv[1] << std::endl;
     std::cerr << argv[1] << std::endl;
   } else {
-    std::string str = kwsys::Encoding::ToNarrow(UnicodeTestString);
+    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;
   }

+ 31 - 0
Source/kwsys/testEncoding.cxx

@@ -9,6 +9,7 @@
 #include KWSYS_HEADER(Encoding.hxx)
 #include KWSYS_HEADER(Encoding.h)
 
+#include <algorithm>
 #include <iostream>
 #include <locale.h>
 #include <stdlib.h>
@@ -124,6 +125,35 @@ static int testRobustEncoding()
   return ret;
 }
 
+static int testWithNulls()
+{
+  int ret = 0;
+  std::vector<std::string> strings;
+  strings.push_back(std::string("ab") + '\0' + 'c');
+  strings.push_back(std::string("d") + '\0' + '\0' + 'e');
+  strings.push_back(std::string() + '\0' + 'f');
+  strings.push_back(std::string() + '\0' + '\0' + "gh");
+  strings.push_back(std::string("ij") + '\0');
+  strings.push_back(std::string("k") + '\0' + '\0');
+  strings.push_back(std::string("\0\0\0\0", 4) + "lmn" +
+                    std::string("\0\0\0\0", 4));
+  for (std::vector<std::string>::iterator it = strings.begin();
+       it != strings.end(); ++it) {
+    std::wstring wstr = kwsys::Encoding::ToWide(*it);
+    std::string str = kwsys::Encoding::ToNarrow(wstr);
+    std::string s(*it);
+    std::replace(s.begin(), s.end(), '\0', ' ');
+    std::cout << "'" << s << "' (" << it->size() << ")" << std::endl;
+    if (str != *it) {
+      std::replace(str.begin(), str.end(), '\0', ' ');
+      std::cout << "string with null was different: '" << str << "' ("
+                << str.size() << ")" << std::endl;
+      ret++;
+    }
+  }
+  return ret;
+}
+
 static int testCommandLineArguments()
 {
   int status = 0;
@@ -165,6 +195,7 @@ int testEncoding(int, char* [])
   ret |= testHelloWorldEncoding();
   ret |= testRobustEncoding();
   ret |= testCommandLineArguments();
+  ret |= testWithNulls();
 
   return ret;
 }