From 9e556829c8fd2e78860e798f454f90dc1160dd20 Mon Sep 17 00:00:00 2001
From: KWSys Upstream <kwrobot@kitware.com>
Date: Mon, 8 Mar 2021 13:32:05 -0500
Subject: [PATCH] KWSys 2021-03-08 (5bfba5e1)

Code extracted from:

    https://gitlab.kitware.com/utils/kwsys.git

at commit 5bfba5e1a988e16df833e86062d61f4b70d83645 (master).

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

Ben Boeckel (4):
      f69c5cb7 Directory: return a bool literal on Windows
      2a118b34 SystemTools: use nullptr in Windows-only code
      7ee0dbee Directory: capture the error message
      dd703ac6 SystemTools: make file copying mechanisms public

Sean McBride (1):
      3ba8a6de Glob: Change deleted ctor and operator= from private to public
---
 Directory.cxx      | 30 +++++++++++++++++++++++++++++-
 Glob.hxx.in        |  7 +++----
 SystemTools.cxx    | 17 +++++++----------
 SystemTools.hxx.in | 11 +++++++++++
 4 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/Directory.cxx b/Directory.cxx
index 0c2190aee5..e70d4e8688 100644
--- a/Directory.cxx
+++ b/Directory.cxx
@@ -121,7 +121,21 @@ bool Directory::Load(const std::string& name, std::string* errorMessage)
   delete[] buf;
 
   if (srchHandle == -1) {
-    return 0;
+    if (errorMessage) {
+      if (unsigned int errorId = GetLastError()) {
+        LPSTR message = nullptr;
+        DWORD size = FormatMessageA(
+          FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+          nullptr, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+          (LPSTR)&message, 0, nullptr);
+        *errorMessage = std::string(message, size);
+        LocalFree(message);
+      } else {
+        *errorMessage = "Unknown error.";
+      }
+    }
+    return false;
   }
 
   // Loop through names
@@ -152,6 +166,20 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
   delete[] buf;
 
   if (srchHandle == -1) {
+    if (errorMessage) {
+      if (unsigned int errorId = GetLastError()) {
+        LPSTR message = nullptr;
+        DWORD size = FormatMessageA(
+          FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+          nullptr, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+          (LPSTR)&message, 0, nullptr);
+        *errorMessage = std::string(message, size);
+        LocalFree(message);
+      } else {
+        *errorMessage = "Unknown error.";
+      }
+    }
     return 0;
   }
 
diff --git a/Glob.hxx.in b/Glob.hxx.in
index e8474e2001..fd39775417 100644
--- a/Glob.hxx.in
+++ b/Glob.hxx.in
@@ -54,6 +54,9 @@ public:
   Glob();
   ~Glob();
 
+  Glob(const Glob&) = delete;
+  void operator=(const Glob&) = delete;
+
   //! Find all files that match the pattern.
   bool FindFiles(const std::string& inexpr, GlobMessages* messages = nullptr);
 
@@ -124,10 +127,6 @@ protected:
   std::vector<std::string> VisitedSymlinks;
   bool ListDirs;
   bool RecurseListDirs;
-
-private:
-  Glob(const Glob&) = delete;
-  void operator=(const Glob&) = delete;
 };
 
 } // namespace @KWSYS_NAMESPACE@
diff --git a/SystemTools.cxx b/SystemTools.cxx
index 6144d9c04d..cf04799776 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -244,7 +244,7 @@ inline int Chdir(const std::string& dir)
   return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
 }
 inline void Realpath(const std::string& path, std::string& resolved_path,
-                     std::string* errorMessage = 0)
+                     std::string* errorMessage = nullptr)
 {
   std::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path);
   wchar_t* ptemp;
@@ -2273,11 +2273,8 @@ bool SystemTools::TextFilesDiffer(const std::string& path1,
   return false;
 }
 
-/**
- * Blockwise copy source to destination file
- */
-static bool CopyFileContentBlockwise(const std::string& source,
-                                     const std::string& destination)
+bool SystemTools::CopyFileContentBlockwise(const std::string& source,
+                                           const std::string& destination)
 {
   // Open files
   kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary);
@@ -2341,8 +2338,8 @@ static bool CopyFileContentBlockwise(const std::string& source,
  * - The underlying filesystem does not support file cloning
  * - An unspecified error occurred
  */
-static bool CloneFileContent(const std::string& source,
-                             const std::string& destination)
+bool SystemTools::CloneFileContent(const std::string& source,
+                                   const std::string& destination)
 {
 #if defined(__linux) && defined(FICLONE)
   int in = open(source.c_str(), O_RDONLY);
@@ -2410,9 +2407,9 @@ bool SystemTools::CopyFileAlways(const std::string& source,
 
     SystemTools::MakeDirectory(destination_dir);
 
-    if (!CloneFileContent(source, real_destination)) {
+    if (!SystemTools::CloneFileContent(source, real_destination)) {
       // if cloning did not succeed, fall back to blockwise copy
-      if (!CopyFileContentBlockwise(source, real_destination)) {
+      if (!SystemTools::CopyFileContentBlockwise(source, real_destination)) {
         return false;
       }
     }
diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in
index 74dc176514..a7b1288733 100644
--- a/SystemTools.hxx.in
+++ b/SystemTools.hxx.in
@@ -577,6 +577,17 @@ public:
   static bool TextFilesDiffer(const std::string& path1,
                               const std::string& path2);
 
+  /**
+   * Blockwise copy source to destination file
+   */
+  static bool CopyFileContentBlockwise(const std::string& source,
+                                       const std::string& destination);
+  /**
+   * Clone the source file to the destination file
+   */
+  static bool CloneFileContent(const std::string& source,
+                               const std::string& destination);
+
   /**
    * Return true if the two files are the same file
    */
-- 
GitLab