Browse Source

KWSys 2014-07-02 (c2a329ce)

Extract upstream KWSys using the following shell commands.

$ git archive --prefix=upstream-kwsys/ c2a329ce | tar x
$ git shortlog --no-merges --abbrev=8 --format='%h %s' c282e64f..c2a329ce
Chuck Atkins (3):
      e4bba930 Directory: Make sure the /* suffix uses correct slashes
      97817ce7 SystemTools: Refactor test file and directory locations
      8f991ab0 SystemTools: Use extended paths on Windows for > 256 length

Clinton Stimpson (1):
      c2a329ce Encoding: Fixes uses of stat() on Windows to work with unicode.

Change-Id: I8e3aa1ba66ce80900cb25a692287495b911dcbd0
KWSys Robot 11 years ago
parent
commit
3d127627f8
7 changed files with 432 additions and 74 deletions
  1. 3 4
      CMakeLists.txt
  2. 11 2
      Directory.cxx
  3. 171 38
      SystemTools.cxx
  4. 12 1
      SystemTools.hxx.in
  5. 1 1
      testDynamicLoader.cxx
  6. 231 26
      testSystemTools.cxx
  7. 3 2
      testSystemTools.h.in

+ 3 - 4
CMakeLists.txt

@@ -1171,10 +1171,9 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
     ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
     ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
     SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
     SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
     TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_NAMESPACE})
     TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_NAMESPACE})
-    SET(TEST_SYSTEMTOOLS_BIN_FILE
-      "${CMAKE_CURRENT_SOURCE_DIR}/testSystemTools.bin")
-    SET(TEST_SYSTEMTOOLS_SRC_FILE
-      "${CMAKE_CURRENT_SOURCE_DIR}/testSystemTools.cxx")
+
+    SET(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+    SET(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
     CONFIGURE_FILE(
     CONFIGURE_FILE(
       ${PROJECT_SOURCE_DIR}/testSystemTools.h.in
       ${PROJECT_SOURCE_DIR}/testSystemTools.h.in
       ${PROJECT_BINARY_DIR}/testSystemTools.h)
       ${PROJECT_BINARY_DIR}/testSystemTools.h)

+ 11 - 2
Directory.cxx

@@ -113,15 +113,24 @@ bool Directory::Load(const char* name)
 #endif
 #endif
   char* buf;
   char* buf;
   size_t n = strlen(name);
   size_t n = strlen(name);
-  if ( name[n - 1] == '/' )
+  if ( name[n - 1] == '/' || name[n - 1] == '\\' )
     {
     {
     buf = new char[n + 1 + 1];
     buf = new char[n + 1 + 1];
     sprintf(buf, "%s*", name);
     sprintf(buf, "%s*", name);
     }
     }
   else
   else
     {
     {
+    // Make sure the slashes in the wildcard suffix are consistent with the
+    // rest of the path
     buf = new char[n + 2 + 1];
     buf = new char[n + 2 + 1];
-    sprintf(buf, "%s/*", name);
+    if ( strchr(name, '\\') )
+      {
+      sprintf(buf, "%s\\*", name);
+      }
+    else
+      {
+      sprintf(buf, "%s/*", name);
+      }
     }
     }
   struct _wfinddata_t data;      // data of current file
   struct _wfinddata_t data;      // data of current file
 
 

+ 171 - 38
SystemTools.cxx

@@ -187,17 +187,34 @@ static inline char *realpath(const char *path, char *resolved_path)
 }
 }
 #endif
 #endif
 
 
+#ifdef _WIN32
+static time_t windows_filetime_to_posix_time(const FILETIME& ft)
+{
+  LARGE_INTEGER date;
+  date.HighPart = ft.dwHighDateTime;
+  date.LowPart = ft.dwLowDateTime;
+
+  // removes the diff between 1970 and 1601
+  date.QuadPart -= ((LONGLONG)(369 * 365 + 89) * 24 * 3600 * 10000000);
+
+  // converts back from 100-nanoseconds to seconds
+  return date.QuadPart / 10000000;
+}
+#endif
+
 #if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
 #if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
 
 
 #include <wctype.h>
 #include <wctype.h>
 
 
 inline int Mkdir(const char* dir)
 inline int Mkdir(const char* dir)
 {
 {
-  return _wmkdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
+  return _wmkdir(
+    KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
 }
 }
 inline int Rmdir(const char* dir)
 inline int Rmdir(const char* dir)
 {
 {
-  return _wrmdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
+  return _wrmdir(
+    KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
 }
 }
 inline const char* Getcwd(char* buf, unsigned int len)
 inline const char* Getcwd(char* buf, unsigned int len)
 {
 {
@@ -609,7 +626,7 @@ const char* SystemTools::GetExecutableExtension()
 FILE* SystemTools::Fopen(const char* file, const char* mode)
 FILE* SystemTools::Fopen(const char* file, const char* mode)
 {
 {
 #ifdef _WIN32
 #ifdef _WIN32
-  return _wfopen(Encoding::ToWide(file).c_str(),
+  return _wfopen(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
                  Encoding::ToWide(mode).c_str());
                  Encoding::ToWide(mode).c_str());
 #else
 #else
   return fopen(file, mode);
   return fopen(file, mode);
@@ -1081,7 +1098,8 @@ bool SystemTools::FileExists(const char* filename)
     }
     }
   return access(filename, R_OK) == 0;
   return access(filename, R_OK) == 0;
 #elif defined(_WIN32)
 #elif defined(_WIN32)
-  return (GetFileAttributesW(Encoding::ToWide(filename).c_str())
+  return (GetFileAttributesW(
+            SystemTools::ConvertToWindowsExtendedPath(filename).c_str())
           != INVALID_FILE_ATTRIBUTES);
           != INVALID_FILE_ATTRIBUTES);
 #else
 #else
   return access(filename, R_OK) == 0;
   return access(filename, R_OK) == 0;
@@ -1137,10 +1155,11 @@ bool SystemTools::Touch(const char* filename, bool create)
     return false;
     return false;
     }
     }
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #if defined(_WIN32) && !defined(__CYGWIN__)
-  HANDLE h = CreateFileW(Encoding::ToWide(filename).c_str(),
-                        FILE_WRITE_ATTRIBUTES,
-                        FILE_SHARE_WRITE, 0, OPEN_EXISTING,
-                        FILE_FLAG_BACKUP_SEMANTICS, 0);
+  HANDLE h = CreateFileW(
+    SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+    FILE_WRITE_ATTRIBUTES,
+    FILE_SHARE_WRITE, 0, OPEN_EXISTING,
+    FILE_FLAG_BACKUP_SEMANTICS, 0);
   if(!h)
   if(!h)
     {
     {
     return false;
     return false;
@@ -1242,13 +1261,15 @@ bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
   // Windows version.  Get the modification time from extended file attributes.
   // Windows version.  Get the modification time from extended file attributes.
   WIN32_FILE_ATTRIBUTE_DATA f1d;
   WIN32_FILE_ATTRIBUTE_DATA f1d;
   WIN32_FILE_ATTRIBUTE_DATA f2d;
   WIN32_FILE_ATTRIBUTE_DATA f2d;
-  if(!GetFileAttributesExW(Encoding::ToWide(f1).c_str(),
-                           GetFileExInfoStandard, &f1d))
+  if(!GetFileAttributesExW(
+       SystemTools::ConvertToWindowsExtendedPath(f1).c_str(),
+       GetFileExInfoStandard, &f1d))
     {
     {
     return false;
     return false;
     }
     }
-  if(!GetFileAttributesExW(Encoding::ToWide(f2).c_str(),
-                           GetFileExInfoStandard, &f2d))
+  if(!GetFileAttributesExW(
+       SystemTools::ConvertToWindowsExtendedPath(f2).c_str(),
+       GetFileExInfoStandard, &f2d))
     {
     {
     return false;
     return false;
     }
     }
@@ -1830,6 +1851,71 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
     }
     }
 }
 }
 
 
+#ifdef _WIN32
+// Convert local paths to UNC style paths
+kwsys_stl::wstring
+SystemTools::ConvertToWindowsExtendedPath(const kwsys_stl::string &source)
+{
+  kwsys_stl::wstring wsource = Encoding::ToWide(source);
+
+  // Resolve any relative paths
+  DWORD wfull_len;
+
+  /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
+   * won't return a large enough buffer size if the input is too small */
+  wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
+  kwsys_stl::vector<wchar_t> wfull(wfull_len);
+  GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
+
+  /* This should get the correct size without any extra padding from the
+   * previous size workaround. */
+  wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
+
+  if(wfull_len >= 2 && isalpha(wfull[0]) && wfull[1] == L':')
+    { /* C:\Foo\bar\FooBar.txt */
+    return L"\\\\?\\" + kwsys_stl::wstring(&wfull[0]);
+    }
+  else if(wfull_len >= 2 && wfull[0] == L'\\' && wfull[1] == L'\\')
+    { /* Starts with \\ */
+    if(wfull_len >= 4 && wfull[2] == L'?' && wfull[3] == L'\\')
+      { /* Starts with \\?\ */
+      if(wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
+                           wfull[6] == L'C' && wfull[7] == L'\\')
+        { /* \\?\UNC\Foo\bar\FooBar.txt */
+        return kwsys_stl::wstring(&wfull[0]);
+        }
+      else if(wfull_len >= 6 && isalpha(wfull[4]) && wfull[5] == L':')
+        { /* \\?\C:\Foo\bar\FooBar.txt */
+        return kwsys_stl::wstring(&wfull[0]);
+        }
+      else if(wfull_len >= 5)
+        { /* \\?\Foo\bar\FooBar.txt */
+        return L"\\\\?\\UNC\\" + kwsys_stl::wstring(&wfull[4]);
+        }
+      }
+    else if(wfull_len >= 4 && wfull[2] == L'.' && wfull[3] == L'\\')
+      { /* Starts with \\.\ a device name */
+      if(wfull_len >= 6 && isalpha(wfull[4]) && wfull[5] == L':')
+        { /* \\.\C:\Foo\bar\FooBar.txt */
+        return L"\\\\?\\" + kwsys_stl::wstring(&wfull[4]);
+        }
+      else if(wfull_len >= 5)
+        { /* \\.\Foo\bar\ Device name is left unchanged */
+        return kwsys_stl::wstring(&wfull[0]);
+        }
+      }
+    else if(wfull_len >= 3)
+      { /* \\Foo\bar\FooBar.txt */
+      return L"\\\\?\\UNC\\" + kwsys_stl::wstring(&wfull[2]);
+      }
+    }
+
+  // If this case has been reached, then the path is invalid.  Leave it
+  // unchanged
+  return Encoding::ToWide(source);
+}
+#endif
+
 // change // to /, and escape any spaces in the path
 // change // to /, and escape any spaces in the path
 kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path)
 kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path)
 {
 {
@@ -1960,17 +2046,19 @@ bool SystemTools::FilesDiffer(const char* source,
 
 
 #if defined(_WIN32)
 #if defined(_WIN32)
   WIN32_FILE_ATTRIBUTE_DATA statSource;
   WIN32_FILE_ATTRIBUTE_DATA statSource;
-  if (GetFileAttributesExW(Encoding::ToWide(source).c_str(),
-                           GetFileExInfoStandard,
-                           &statSource) == 0)
+  if (GetFileAttributesExW(
+        SystemTools::ConvertToWindowsExtendedPath(source).c_str(),
+        GetFileExInfoStandard,
+        &statSource) == 0)
     {
     {
     return true;
     return true;
     }
     }
 
 
   WIN32_FILE_ATTRIBUTE_DATA statDestination;
   WIN32_FILE_ATTRIBUTE_DATA statDestination;
-  if (GetFileAttributesExW(Encoding::ToWide(destination).c_str(),
-                           GetFileExInfoStandard,
-                           &statDestination) == 0)
+  if (GetFileAttributesExW(
+        SystemTools::ConvertToWindowsExtendedPath(destination).c_str(),
+        GetFileExInfoStandard,
+        &statDestination) == 0)
     {
     {
     return true;
     return true;
     }
     }
@@ -2191,7 +2279,12 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination,
                                  bool always)
                                  bool always)
 {
 {
   Directory dir;
   Directory dir;
+#ifdef _WIN32
+  dir.Load(Encoding::ToNarrow(
+             SystemTools::ConvertToWindowsExtendedPath(source)).c_str());
+#else
   dir.Load(source);
   dir.Load(source);
+#endif
   size_t fileNum;
   size_t fileNum;
   if ( !SystemTools::MakeDirectory(destination) )
   if ( !SystemTools::MakeDirectory(destination) )
     {
     {
@@ -2234,15 +2327,28 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination,
 // return size of file; also returns zero if no file exists
 // return size of file; also returns zero if no file exists
 unsigned long SystemTools::FileLength(const char* filename)
 unsigned long SystemTools::FileLength(const char* filename)
 {
 {
-  struct stat fs;
-  if (stat(filename, &fs) != 0)
+  unsigned long length = 0;
+#ifdef _WIN32
+  WIN32_FILE_ATTRIBUTE_DATA fs;
+  if (GetFileAttributesExW(
+        SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+        GetFileExInfoStandard, &fs) != 0)
     {
     {
-      return 0;
+    /* To support the full 64-bit file size, use fs.nFileSizeHigh
+     * and fs.nFileSizeLow to construct the 64 bit size
+
+    length = ((__int64)fs.nFileSizeHigh << 32) + fs.nFileSizeLow;
+     */
+    length = static_cast<unsigned long>(fs.nFileSizeLow);
     }
     }
-  else
+#else
+  struct stat fs;
+  if (stat(filename, &fs) == 0)
     {
     {
-      return static_cast<unsigned long>(fs.st_size);
+    length = static_cast<unsigned long>(fs.st_size);
     }
     }
+#endif
+  return length;
 }
 }
 
 
 int SystemTools::Strucmp(const char *s1, const char *s2)
 int SystemTools::Strucmp(const char *s1, const char *s2)
@@ -2261,29 +2367,47 @@ int SystemTools::Strucmp(const char *s1, const char *s2)
 // return file's modified time
 // return file's modified time
 long int SystemTools::ModifiedTime(const char* filename)
 long int SystemTools::ModifiedTime(const char* filename)
 {
 {
-  struct stat fs;
-  if (stat(filename, &fs) != 0)
+  long int mt = 0;
+#ifdef _WIN32
+  WIN32_FILE_ATTRIBUTE_DATA fs;
+  if (GetFileAttributesExW(
+        SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+                           GetFileExInfoStandard,
+                           &fs) != 0)
     {
     {
-    return 0;
+    mt = windows_filetime_to_posix_time(fs.ftLastWriteTime);
     }
     }
-  else
+#else
+  struct stat fs;
+  if (stat(filename, &fs) == 0)
     {
     {
-    return static_cast<long int>(fs.st_mtime);
+    mt = static_cast<long int>(fs.st_mtime);
     }
     }
+#endif
+  return mt;
 }
 }
 
 
 // return file's creation time
 // return file's creation time
 long int SystemTools::CreationTime(const char* filename)
 long int SystemTools::CreationTime(const char* filename)
 {
 {
-  struct stat fs;
-  if (stat(filename, &fs) != 0)
+  long int ct = 0;
+#ifdef _WIN32
+  WIN32_FILE_ATTRIBUTE_DATA fs;
+  if (GetFileAttributesExW(
+        SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+                           GetFileExInfoStandard,
+                           &fs) != 0)
     {
     {
-    return 0;
+    ct = windows_filetime_to_posix_time(fs.ftCreationTime);
     }
     }
-  else
+#else
+  struct stat fs;
+  if (stat(filename, &fs) == 0)
     {
     {
-    return fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0;
+    ct = fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0;
     }
     }
+#endif
+  return ct;
 }
 }
 
 
 bool SystemTools::ConvertDateMacroString(const char *str, time_t *tmt)
 bool SystemTools::ConvertDateMacroString(const char *str, time_t *tmt)
@@ -2406,7 +2530,8 @@ bool SystemTools::RemoveFile(const char* source)
   SystemTools::SetPermissions(source, S_IWRITE);
   SystemTools::SetPermissions(source, S_IWRITE);
 #endif
 #endif
 #ifdef _WIN32
 #ifdef _WIN32
-  bool res = _wunlink(Encoding::ToWide(source).c_str()) != 0 ? false : true;
+  bool res =
+    _wunlink(SystemTools::ConvertToWindowsExtendedPath(source).c_str()) == 0;
 #else
 #else
   bool res = unlink(source) != 0 ? false : true;
   bool res = unlink(source) != 0 ? false : true;
 #endif
 #endif
@@ -2435,7 +2560,12 @@ bool SystemTools::RemoveADirectory(const char* source)
     }
     }
 
 
   Directory dir;
   Directory dir;
+#ifdef _WIN32
+  dir.Load(Encoding::ToNarrow(
+             SystemTools::ConvertToWindowsExtendedPath(source)).c_str());
+#else
   dir.Load(source);
   dir.Load(source);
+#endif
   size_t fileNum;
   size_t fileNum;
   for (fileNum = 0; fileNum <  dir.GetNumberOfFiles(); ++fileNum)
   for (fileNum = 0; fileNum <  dir.GetNumberOfFiles(); ++fileNum)
     {
     {
@@ -2849,7 +2979,8 @@ bool SystemTools::FileIsDirectory(const char* name)
 
 
   // Now check the file node type.
   // Now check the file node type.
 #if defined( _WIN32 )
 #if defined( _WIN32 )
-  DWORD attr = GetFileAttributesW(Encoding::ToWide(name).c_str());
+  DWORD attr = GetFileAttributesW(
+    SystemTools::ConvertToWindowsExtendedPath(name).c_str());
   if (attr != INVALID_FILE_ATTRIBUTES)
   if (attr != INVALID_FILE_ATTRIBUTES)
     {
     {
     return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
     return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
@@ -4041,7 +4172,7 @@ bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string&
   kwsys_stl::wstring wtempPath = Encoding::ToWide(tempPath);
   kwsys_stl::wstring wtempPath = Encoding::ToWide(tempPath);
   kwsys_stl::vector<wchar_t> buffer(wtempPath.size()+1);
   kwsys_stl::vector<wchar_t> buffer(wtempPath.size()+1);
   buffer[0] = 0;
   buffer[0] = 0;
-  ret = GetShortPathNameW(Encoding::ToWide(tempPath).c_str(),
+  ret = GetShortPathNameW(wtempPath.c_str(),
     &buffer[0], static_cast<DWORD>(wtempPath.size()));
     &buffer[0], static_cast<DWORD>(wtempPath.size()));
 
 
   if(buffer[0] == 0 || ret > wtempPath.size())
   if(buffer[0] == 0 || ret > wtempPath.size())
@@ -4279,7 +4410,8 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode)
     }
     }
 
 
 #if defined(_WIN32)
 #if defined(_WIN32)
-  DWORD attr = GetFileAttributesW(Encoding::ToWide(file).c_str());
+  DWORD attr = GetFileAttributesW(
+    SystemTools::ConvertToWindowsExtendedPath(file).c_str());
   if(attr == INVALID_FILE_ATTRIBUTES)
   if(attr == INVALID_FILE_ATTRIBUTES)
     {
     {
     return false;
     return false;
@@ -4331,7 +4463,8 @@ bool SystemTools::SetPermissions(const char* file, mode_t mode)
     return false;
     return false;
     }
     }
 #ifdef _WIN32
 #ifdef _WIN32
-  if ( _wchmod(Encoding::ToWide(file).c_str(), mode) < 0 )
+  if ( _wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
+               mode) < 0 )
 #else
 #else
   if ( chmod(file, mode) < 0 )
   if ( chmod(file, mode) < 0 )
 #endif
 #endif

+ 12 - 1
SystemTools.hxx.in

@@ -249,7 +249,18 @@ public:
    * Replace Windows file system slashes with Unix-style slashes.
    * Replace Windows file system slashes with Unix-style slashes.
    */
    */
   static void ConvertToUnixSlashes(kwsys_stl::string& path);
   static void ConvertToUnixSlashes(kwsys_stl::string& path);
-  
+
+#ifdef _WIN32
+  /**
+   * Convert the path to an extended length path to avoid MAX_PATH length
+   * limitations on Windows. If the input is a local path the result will be
+   * prefixed with \\?\; if the input is instead a network path, the result
+   * will be prefixed with \\?\UNC\. All output will also be converted to
+   * absolute paths with Windows-style backslashes.
+   **/
+  static kwsys_stl::wstring ConvertToWindowsExtendedPath(const kwsys_stl::string&);
+#endif
+
   /**
   /**
    * For windows this calls ConvertToWindowsOutputPath and for unix
    * For windows this calls ConvertToWindowsOutputPath and for unix
    * it calls ConvertToUnixOutputPath
    * it calls ConvertToUnixOutputPath

+ 1 - 1
testDynamicLoader.cxx

@@ -108,7 +108,7 @@ int testDynamicLoader(int argc, char *argv[])
   // Make sure that inexistent lib is giving correct result
   // Make sure that inexistent lib is giving correct result
   res += TestDynamicLoader("azerty_", "foo_bar",0,0,0);
   res += TestDynamicLoader("azerty_", "foo_bar",0,0,0);
   // Make sure that random binary file cannot be assimilated as dylib
   // Make sure that random binary file cannot be assimilated as dylib
-  res += TestDynamicLoader(TEST_SYSTEMTOOLS_BIN_FILE, "wp",0,0,0);
+  res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin", "wp",0,0,0);
 #endif
 #endif
 
 
 #ifdef __linux__
 #ifdef __linux__

+ 231 - 26
testSystemTools.cxx

@@ -98,32 +98,124 @@ static bool CheckEscapeChars(kwsys_stl::string input,
 static bool CheckFileOperations()
 static bool CheckFileOperations()
 {
 {
   bool res = true;
   bool res = true;
-
-  if (kwsys::SystemTools::DetectFileType(TEST_SYSTEMTOOLS_BIN_FILE) !=
+  const kwsys_stl::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+    "/testSystemTools.bin");
+  const kwsys_stl::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+    "/testSystemTools.cxx");
+  const kwsys_stl::string testNewDir(TEST_SYSTEMTOOLS_BINARY_DIR
+    "/testSystemToolsNewDir");
+  const kwsys_stl::string testNewFile(testNewDir + "/testNewFile.txt");
+
+  if (kwsys::SystemTools::DetectFileType(testBinFile.c_str()) !=
       kwsys::SystemTools::FileTypeBinary)
       kwsys::SystemTools::FileTypeBinary)
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with DetectFileType - failed to detect type of: "
       << "Problem with DetectFileType - failed to detect type of: "
-      << TEST_SYSTEMTOOLS_BIN_FILE << kwsys_ios::endl;
+      << testBinFile << kwsys_ios::endl;
     res = false;
     res = false;
     }
     }
 
 
-  if (kwsys::SystemTools::DetectFileType(TEST_SYSTEMTOOLS_SRC_FILE) !=
+  if (kwsys::SystemTools::DetectFileType(testTxtFile.c_str()) !=
       kwsys::SystemTools::FileTypeText)
       kwsys::SystemTools::FileTypeText)
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with DetectFileType - failed to detect type of: "
       << "Problem with DetectFileType - failed to detect type of: "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << testTxtFile << kwsys_ios::endl;
     res = false;
     res = false;
     }
     }
-  
-  if (kwsys::SystemTools::FileLength(TEST_SYSTEMTOOLS_BIN_FILE) != 766)
+
+  if (kwsys::SystemTools::FileLength(testBinFile.c_str()) != 766)
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with FileLength - incorrect length for: "
       << "Problem with FileLength - incorrect length for: "
-      << TEST_SYSTEMTOOLS_BIN_FILE << kwsys_ios::endl;
-    res = false;    
+      << testBinFile << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::MakeDirectory(testNewDir.c_str()))
+    {
+    kwsys_ios::cerr
+      << "Problem with MakeDirectory for: "
+      << testNewDir << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true))
+    {
+    kwsys_ios::cerr
+      << "Problem with Touch for: "
+      << testNewFile << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::RemoveFile(testNewFile.c_str()))
+    {
+    kwsys_ios::cerr
+      << "Problem with RemoveFile: "
+      << testNewFile << kwsys_ios::endl;
+    res = false;
+    }
+
+  kwsys::SystemTools::Touch(testNewFile.c_str(), true);
+  if (!kwsys::SystemTools::RemoveADirectory(testNewDir.c_str()))
+    {
+    kwsys_ios::cerr
+      << "Problem with RemoveADirectory for: "
+      << testNewDir << kwsys_ios::endl;
+    res = false;
+    }
+
+#ifdef KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS
+  // Perform the same file and directory creation and deletion tests but
+  // with paths > 256 characters in length.
+
+  const kwsys_stl::string testNewLongDir(
+    TEST_SYSTEMTOOLS_BINARY_DIR "/"
+    "012345678901234567890123456789012345678901234567890123456789"
+    "012345678901234567890123456789012345678901234567890123456789"
+    "012345678901234567890123456789012345678901234567890123456789"
+    "012345678901234567890123456789012345678901234567890123456789"
+    "01234567890123");
+  const kwsys_stl::string testNewLongFile(testNewLongDir + "/"
+    "012345678901234567890123456789012345678901234567890123456789"
+    "012345678901234567890123456789012345678901234567890123456789"
+    "012345678901234567890123456789012345678901234567890123456789"
+    "012345678901234567890123456789012345678901234567890123456789"
+    "0123456789.txt");
+
+  if (!kwsys::SystemTools::MakeDirectory(testNewLongDir.c_str()))
+    {
+    kwsys_ios::cerr
+      << "Problem with MakeDirectory for: "
+      << testNewLongDir << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::Touch(testNewLongFile.c_str(), true))
+    {
+    kwsys_ios::cerr
+      << "Problem with Touch for: "
+      << testNewLongFile << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::RemoveFile(testNewLongFile.c_str()))
+    {
+    kwsys_ios::cerr
+      << "Problem with RemoveFile: "
+      << testNewLongFile << kwsys_ios::endl;
+    res = false;
+    }
+
+  kwsys::SystemTools::Touch(testNewLongFile.c_str(), true);
+  if (!kwsys::SystemTools::RemoveADirectory(testNewLongDir.c_str()))
+    {
+    kwsys_ios::cerr
+      << "Problem with RemoveADirectory for: "
+      << testNewLongDir << kwsys_ios::endl;
+    res = false;
     }
     }
+#endif
 
 
   return res;
   return res;
 }
 }
@@ -138,7 +230,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with CapitalizedWords "
       << "Problem with CapitalizedWords "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << '"' << test << '"' << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
 
 
@@ -148,7 +240,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with UnCapitalizedWords "
       << "Problem with UnCapitalizedWords "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << '"' << test << '"' << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
 
 
@@ -158,7 +250,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with AddSpaceBetweenCapitalizedWords "
       << "Problem with AddSpaceBetweenCapitalizedWords "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << '"' << test << '"' << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
 
 
@@ -168,7 +260,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with AppendStrings "
       << "Problem with AppendStrings "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A\" \" Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
   delete [] cres;
   delete [] cres;
@@ -179,7 +271,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with AppendStrings "
       << "Problem with AppendStrings "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had\" \" A \" \"Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
   delete [] cres;
   delete [] cres;
@@ -188,7 +280,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with CountChar "
       << "Problem with CountChar "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
 
 
@@ -198,7 +290,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with RemoveChars "
       << "Problem with RemoveChars "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
   delete [] cres;
   delete [] cres;
@@ -209,7 +301,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with RemoveCharsButUpperHex "
       << "Problem with RemoveCharsButUpperHex "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
   delete [] cres;
   delete [] cres;
@@ -221,7 +313,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with ReplaceChars "
       << "Problem with ReplaceChars "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
   delete [] cres2;
   delete [] cres2;
@@ -231,7 +323,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with StringStartsWith "
       << "Problem with StringStartsWith "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
 
 
@@ -240,7 +332,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with StringEndsWith "
       << "Problem with StringEndsWith "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
 
 
@@ -249,7 +341,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with DuplicateString "
       << "Problem with DuplicateString "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
   delete [] cres;
   delete [] cres;
@@ -260,7 +352,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with CropString "
       << "Problem with CropString "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
 
 
@@ -271,16 +363,124 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with Split "
       << "Problem with Split "
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
+    res = false;
+    }
+
+#ifdef _WIN32
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+      ("L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+      L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+      << kwsys_ios::endl;
+    res = false;
     }
     }
 
 
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+      ("L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+      L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+      ("\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+      L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+      ("//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+      L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath("//") !=
+      L"//")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"//\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\") !=
+      L"\\\\.\\")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"\\\\.\\\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X") !=
+      L"\\\\.\\X")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"\\\\.\\X\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:") !=
+      L"\\\\?\\X:")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"\\\\.\\X:\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:\\") !=
+      L"\\\\?\\X:\\")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"\\\\.\\X:\\\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::ConvertToWindowsExtendedPath("NUL") !=
+      L"\\\\.\\NUL")
+    {
+    kwsys_ios::cerr
+      << "Problem with ConvertToWindowsExtendedPath "
+      << "\"NUL\""
+      << kwsys_ios::endl;
+    res = false;
+    }
+
+#endif
+
   if (kwsys::SystemTools::ConvertToWindowsOutputPath
   if (kwsys::SystemTools::ConvertToWindowsOutputPath
       ("L://Local Mojo/Hex Power Pack/Iffy Voodoo") != 
       ("L://Local Mojo/Hex Power Pack/Iffy Voodoo") != 
       "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
       "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with ConvertToWindowsOutputPath "
       << "Problem with ConvertToWindowsOutputPath "
+      << "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\""
       << kwsys_ios::endl;
       << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
@@ -291,6 +491,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with ConvertToWindowsOutputPath "
       << "Problem with ConvertToWindowsOutputPath "
+      << "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\""
       << kwsys_ios::endl;
       << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
@@ -301,6 +502,7 @@ static bool CheckStringOperations()
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with ConvertToUnixOutputPath "
       << "Problem with ConvertToUnixOutputPath "
+      << "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\""
       << kwsys_ios::endl;
       << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
@@ -308,14 +510,17 @@ static bool CheckStringOperations()
   int targc;
   int targc;
   char **targv;
   char **targv;
   kwsys::SystemTools::ConvertWindowsCommandLineToUnixArguments
   kwsys::SystemTools::ConvertWindowsCommandLineToUnixArguments
-    ("\"Local Mojo\\Voodoo.asp\" -CastHex \"D:\\My Secret Mojo\\Voodoo.mp3\"", &targc, &targv);
+    ("\"Local Mojo\\Voodoo.asp\" -CastHex \"D:\\My Secret Mojo\\Voodoo.mp3\"",
+    &targc, &targv);
   if (targc != 4 || strcmp(targv[1],"Local Mojo\\Voodoo.asp") ||
   if (targc != 4 || strcmp(targv[1],"Local Mojo\\Voodoo.asp") ||
       strcmp(targv[2],"-CastHex") || 
       strcmp(targv[2],"-CastHex") || 
       strcmp(targv[3],"D:\\My Secret Mojo\\Voodoo.mp3"))
       strcmp(targv[3],"D:\\My Secret Mojo\\Voodoo.mp3"))
     {
     {
     kwsys_ios::cerr
     kwsys_ios::cerr
       << "Problem with ConvertWindowsCommandLineToUnixArguments"
       << "Problem with ConvertWindowsCommandLineToUnixArguments"
-      << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+      << "\'\"Local Mojo\\Voodoo.asp\" "
+      << "-CastHex \"D:\\My Secret Mojo\\Voodoo.mp3\"\'"
+      << kwsys_ios::endl;
     res = false;    
     res = false;    
     }
     }
   for (;targc >=0; --targc)
   for (;targc >=0; --targc)

+ 3 - 2
testSystemTools.h.in

@@ -14,7 +14,8 @@
 
 
 #define EXECUTABLE_OUTPUT_PATH "@CMAKE_CURRENT_BINARY_DIR@"
 #define EXECUTABLE_OUTPUT_PATH "@CMAKE_CURRENT_BINARY_DIR@"
 
 
-#define TEST_SYSTEMTOOLS_BIN_FILE "@TEST_SYSTEMTOOLS_BIN_FILE@"
-#define TEST_SYSTEMTOOLS_SRC_FILE "@TEST_SYSTEMTOOLS_SRC_FILE@"
+#define TEST_SYSTEMTOOLS_SOURCE_DIR "@TEST_SYSTEMTOOLS_SOURCE_DIR@"
+#define TEST_SYSTEMTOOLS_BINARY_DIR "@TEST_SYSTEMTOOLS_BINARY_DIR@"
+#cmakedefine KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS
 
 
 #endif
 #endif