summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2021-04-15 15:11:12 (GMT)
committerKitware Robot <kwrobot@kitware.com>2021-04-15 15:11:17 (GMT)
commit27b5dc35a67f28f46a2b91cf813cd6b34c5a21b8 (patch)
tree222a588e93b1eb85ca561706d72f9da28ca7e359 /Source
parentb65912006e5c0644329b838103226597af4fecef (diff)
parent3ef5dab010aef5ebab2022021989cb80718d00fc (diff)
downloadCMake-27b5dc35a67f28f46a2b91cf813cd6b34c5a21b8.zip
CMake-27b5dc35a67f28f46a2b91cf813cd6b34c5a21b8.tar.gz
CMake-27b5dc35a67f28f46a2b91cf813cd6b34c5a21b8.tar.bz2
Merge topic 'update-kwsys'
3ef5dab010 cmSystemTools: Simplify using KWSys Status ec1b6157cb Update CMake code using KWSys to account for Status return values eef585efaa Merge branch 'upstream-KWSys' into update-kwsys a790167101 KWSys 2021-04-14 (7ab1c601) Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Ben Boeckel <ben.boeckel@kitware.com> Merge-request: !6004
Diffstat (limited to 'Source')
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx13
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx2
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx2
-rw-r--r--Source/cmCTest.cxx6
-rw-r--r--Source/cmConditionEvaluator.cxx4
-rw-r--r--Source/cmFileCommand.cxx9
-rw-r--r--Source/cmQtAutoGenerator.cxx2
-rw-r--r--Source/cmSystemTools.cxx61
-rw-r--r--Source/cmSystemTools.h1
-rw-r--r--Source/cmWorkingDirectory.cxx2
-rw-r--r--Source/cmcmd.cxx2
-rw-r--r--Source/kwsys/CMakeLists.txt6
-rw-r--r--Source/kwsys/Directory.cxx35
-rw-r--r--Source/kwsys/Directory.hxx.in6
-rw-r--r--Source/kwsys/Status.cxx60
-rw-r--r--Source/kwsys/Status.hxx.in101
-rw-r--r--Source/kwsys/SystemTools.cxx300
-rw-r--r--Source/kwsys/SystemTools.hxx.in65
-rw-r--r--Source/kwsys/testDirectory.cxx4
-rw-r--r--Source/kwsys/testStatus.cxx117
20 files changed, 555 insertions, 243 deletions
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index 3e36e8c..ad0a3e2 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -51,15 +51,16 @@ int cmCPackSTGZGenerator::PackageFiles()
* so we must iterate over generated packages.
*/
for (std::string const& pfn : this->packageFileNames) {
- retval &= cmSystemTools::SetPermissions(pfn.c_str(),
+ retval &= static_cast<bool>(
+ cmSystemTools::SetPermissions(pfn.c_str(),
#if defined(_MSC_VER) || defined(__MINGW32__)
- S_IREAD | S_IWRITE | S_IEXEC
+ S_IREAD | S_IWRITE | S_IEXEC
#else
- S_IRUSR | S_IWUSR | S_IXUSR |
- S_IRGRP | S_IWGRP | S_IXGRP |
- S_IROTH | S_IWOTH | S_IXOTH
+ S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
+ S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH |
+ S_IXOTH
#endif
- );
+ ));
}
return retval;
}
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index ff0b179..d2cad39 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -921,7 +921,7 @@ bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce(
}
}
- return cmSystemTools::RemoveADirectory(directoryPath);
+ return static_cast<bool>(cmSystemTools::RemoveADirectory(directoryPath));
}
cmDuration cmCTestScriptHandler::GetRemainingTimeAllowed()
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 742e78a..db5cb9c 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1881,7 +1881,7 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
std::string dirName = this->CTest->GetBinaryDir() + "/Testing/Temporary";
cmsys::Directory directory;
- if (directory.Load(dirName) == 0) {
+ if (!directory.Load(dirName)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to read the contents of " << dirName << std::endl);
return;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 0dfd1bd..643b43f 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -4,7 +4,6 @@
#include <algorithm>
#include <cctype>
-#include <cerrno>
#include <chrono>
#include <cstdio>
#include <cstdlib>
@@ -2842,9 +2841,10 @@ int cmCTest::ExecuteTests()
cmCTestLog(this, OUTPUT,
"Internal ctest changing into directory: " << workDir
<< std::endl);
- if (cmSystemTools::ChangeDirectory(workDir) != 0) {
+ cmsys::Status status = cmSystemTools::ChangeDirectory(workDir);
+ if (!status) {
auto msg = "Failed to change working directory to \"" + workDir +
- "\" : " + std::strerror(errno) + "\n";
+ "\" : " + status.GetString() + "\n";
cmCTestLog(this, ERROR_MESSAGE, msg);
return 1;
}
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 62bc526..f99592c 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -654,10 +654,10 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
this->IsKeyword(keyIS_NEWER_THAN, *argP1)) {
int fileIsNewer = 0;
- bool success = cmSystemTools::FileTimeCompare(
+ cmsys::Status ftcStatus = cmSystemTools::FileTimeCompare(
arg->GetValue(), (argP2)->GetValue(), &fileIsNewer);
this->HandleBinaryOp(
- (!success || fileIsNewer == 1 || fileIsNewer == 0), reducible, arg,
+ (!ftcStatus || fileIsNewer == 1 || fileIsNewer == 0), reducible, arg,
newArgs, argP1, argP2);
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index a06ed48..26bdedf 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2956,9 +2956,12 @@ bool HandleCreateLinkCommand(std::vector<std::string> const& args,
// Check if copy-on-error is enabled in the arguments.
if (!completed && arguments.CopyOnError) {
- completed = cmsys::SystemTools::CopyFileAlways(fileName, newFileName);
- if (!completed) {
- result = "Copy failed: " + cmSystemTools::GetLastSystemError();
+ cmsys::Status copied =
+ cmsys::SystemTools::CopyFileAlways(fileName, newFileName);
+ if (copied) {
+ completed = true;
+ } else {
+ result = "Copy failed: " + copied.GetString();
}
}
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index 6e88e26..568926e 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -116,7 +116,7 @@ bool cmQtAutoGenerator::MakeParentDirectory(std::string const& filename)
bool success = true;
std::string const dirName = cmSystemTools::GetFilenamePath(filename);
if (!dirName.empty()) {
- success = cmSystemTools::MakeDirectory(dirName);
+ success = static_cast<bool>(cmSystemTools::MakeDirectory(dirName));
}
return success;
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 3a438fd..2b3266d 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -153,27 +153,6 @@ static int cm_archive_read_open_file(struct archive* a, const char* file,
# define environ (*_NSGetEnviron())
#endif
-namespace {
-void ReportError(std::string* err)
-{
- if (!err) {
- return;
- }
-#ifdef _WIN32
- LPSTR message = NULL;
- DWORD size = FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR)&message, 0, NULL);
- *err = std::string(message, size);
- LocalFree(message);
-#else
- *err = strerror(errno);
-#endif
-}
-}
-
bool cmSystemTools::s_RunCommandHideConsole = false;
bool cmSystemTools::s_DisableRunCommandOutput = false;
bool cmSystemTools::s_ErrorOccured = false;
@@ -1016,23 +995,31 @@ cmSystemTools::CopyResult cmSystemTools::CopySingleFile(
}
mode_t perm = 0;
- bool perms = SystemTools::GetPermissions(oldname, perm);
+ cmsys::Status perms = SystemTools::GetPermissions(oldname, perm);
// If files are the same do not copy
if (SystemTools::SameFile(oldname, newname)) {
return CopyResult::Success;
}
- if (!cmsys::SystemTools::CloneFileContent(oldname, newname)) {
+ cmsys::Status status;
+ status = cmsys::SystemTools::CloneFileContent(oldname, newname);
+ if (!status) {
// if cloning did not succeed, fall back to blockwise copy
- if (!cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname)) {
- ReportError(err);
- return CopyResult::Failure;
+ status = cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname);
+ }
+ if (!status) {
+ if (err) {
+ *err = status.GetString();
}
+ return CopyResult::Failure;
}
if (perms) {
- if (!SystemTools::SetPermissions(newname, perm)) {
- ReportError(err);
+ status = SystemTools::SetPermissions(newname, perm);
+ if (!status) {
+ if (err) {
+ *err = status.GetString();
+ }
return CopyResult::Failure;
}
}
@@ -1090,7 +1077,9 @@ cmSystemTools::RenameResult cmSystemTools::RenameFile(
if (replace == Replace::No && move_last_error == ERROR_ALREADY_EXISTS) {
return RenameResult::NoReplace;
}
- ReportError(err);
+ if (err) {
+ *err = cmsys::Status::Windows(move_last_error).GetString();
+ }
return RenameResult::Failure;
}
@@ -1121,7 +1110,9 @@ cmSystemTools::RenameResult cmSystemTools::RenameFile(
if (replace == Replace::No && GetLastError() == ERROR_ALREADY_EXISTS) {
return RenameResult::NoReplace;
}
- ReportError(err);
+ if (err) {
+ *err = cmsys::Status::Windows_GetLastError().GetString();
+ }
return RenameResult::Failure;
#else
// On UNIX we have OS-provided calls to create 'newname' atomically.
@@ -1132,13 +1123,17 @@ cmSystemTools::RenameResult cmSystemTools::RenameFile(
if (errno == EEXIST) {
return RenameResult::NoReplace;
}
- ReportError(err);
+ if (err) {
+ *err = cmsys::Status::POSIX_errno().GetString();
+ }
return RenameResult::Failure;
}
if (rename(oldname.c_str(), newname.c_str()) == 0) {
return RenameResult::Success;
}
- ReportError(err);
+ if (err) {
+ *err = cmsys::Status::POSIX_errno().GetString();
+ }
return RenameResult::Failure;
#endif
}
@@ -3130,7 +3125,7 @@ bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir)
}
return false;
#else
- return cmSystemTools::RemoveADirectory(dir);
+ return static_cast<bool>(cmSystemTools::RemoveADirectory(dir));
#endif
}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 5620899..99f20e0 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -12,6 +12,7 @@
#include <cm/string_view>
#include "cmsys/Process.h"
+#include "cmsys/Status.hxx" // IWYU pragma: export
#include "cmsys/SystemTools.hxx" // IWYU pragma: export
#include "cmCryptoHash.h"
diff --git a/Source/cmWorkingDirectory.cxx b/Source/cmWorkingDirectory.cxx
index 5700b1c..12fae12 100644
--- a/Source/cmWorkingDirectory.cxx
+++ b/Source/cmWorkingDirectory.cxx
@@ -19,7 +19,7 @@ cmWorkingDirectory::~cmWorkingDirectory()
bool cmWorkingDirectory::SetDirectory(std::string const& newdir)
{
- if (cmSystemTools::ChangeDirectory(newdir) == 0) {
+ if (cmSystemTools::ChangeDirectory(newdir)) {
this->ResultCode = 0;
return true;
}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 9ba4b93..a47eccd 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1635,7 +1635,7 @@ bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link)
cmSystemTools::RemoveFile(link);
}
#if defined(_WIN32) && !defined(__CYGWIN__)
- return cmSystemTools::CopyFileAlways(file, link);
+ return static_cast<bool>(cmSystemTools::CopyFileAlways(file, link));
#else
std::string linktext = cmSystemTools::GetFilenameName(file);
return cmSystemTools::CreateSymlink(linktext, link);
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index b0a8542..bf8543e 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -142,6 +142,7 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
set(KWSYS_USE_MD5 1)
set(KWSYS_USE_Process 1)
set(KWSYS_USE_RegularExpression 1)
+ set(KWSYS_USE_Status 1)
set(KWSYS_USE_System 1)
set(KWSYS_USE_SystemTools 1)
set(KWSYS_USE_CommandLineArguments 1)
@@ -157,6 +158,7 @@ if(KWSYS_USE_SystemTools)
set(KWSYS_USE_Directory 1)
set(KWSYS_USE_FStream 1)
set(KWSYS_USE_Encoding 1)
+ set(KWSYS_USE_Status 1)
endif()
if(KWSYS_USE_Glob)
set(KWSYS_USE_Directory 1)
@@ -177,6 +179,7 @@ if(KWSYS_USE_System)
endif()
if(KWSYS_USE_Directory)
set(KWSYS_USE_Encoding 1)
+ set(KWSYS_USE_Status 1)
endif()
if(KWSYS_USE_DynamicLoader)
set(KWSYS_USE_Encoding 1)
@@ -630,7 +633,7 @@ set(KWSYS_HXX_FILES Configure String)
# Add selected C++ classes.
set(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
- CommandLineArguments FStream SystemInformation ConsoleBuf
+ CommandLineArguments FStream SystemInformation ConsoleBuf Status
)
foreach(cpp ${cppclasses})
if(KWSYS_USE_${cpp})
@@ -963,6 +966,7 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
# C++ tests
set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConfigure.cxx
+ testStatus.cxx
testSystemTools.cxx
testCommandLineArguments.cxx
testCommandLineArguments1.cxx
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index e70d4e8..2e8aa83 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -94,7 +94,7 @@ void Directory::Clear()
namespace KWSYS_NAMESPACE {
-bool Directory::Load(const std::string& name, std::string* errorMessage)
+Status Directory::Load(std::string const& name, std::string* errorMessage)
{
this->Clear();
intptr_t srchHandle;
@@ -121,21 +121,11 @@ bool Directory::Load(const std::string& name, std::string* errorMessage)
delete[] buf;
if (srchHandle == -1) {
+ Status status = Status::POSIX_errno();
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.";
- }
+ *errorMessage = status.GetString();
}
- return false;
+ return status;
}
// Loop through names
@@ -143,7 +133,14 @@ bool Directory::Load(const std::string& name, std::string* errorMessage)
this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
} while (_wfindnext(srchHandle, &data) != -1);
this->Internal->Path = name;
- return _findclose(srchHandle) != -1;
+ if (_findclose(srchHandle) == -1) {
+ Status status = Status::POSIX_errno();
+ if (errorMessage) {
+ *errorMessage = status.GetString();
+ }
+ return status;
+ }
+ return Status::Success();
}
unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
@@ -220,7 +217,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
namespace KWSYS_NAMESPACE {
-bool Directory::Load(const std::string& name, std::string* errorMessage)
+Status Directory::Load(std::string const& name, std::string* errorMessage)
{
this->Clear();
@@ -231,7 +228,7 @@ bool Directory::Load(const std::string& name, std::string* errorMessage)
if (errorMessage != nullptr) {
*errorMessage = std::string(strerror(errno));
}
- return false;
+ return Status::POSIX_errno();
}
errno = 0;
@@ -242,12 +239,12 @@ bool Directory::Load(const std::string& name, std::string* errorMessage)
if (errorMessage != nullptr) {
*errorMessage = std::string(strerror(errno));
}
- return false;
+ return Status::POSIX_errno();
}
this->Internal->Path = name;
closedir(dir);
- return true;
+ return Status::Success();
}
unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index 7bc9db0..d501116 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -4,6 +4,7 @@
#define @KWSYS_NAMESPACE@_Directory_hxx
#include <@KWSYS_NAMESPACE@/Configure.h>
+#include <@KWSYS_NAMESPACE@/Status.hxx>
#include <string>
@@ -32,10 +33,9 @@ public:
/**
* Load the specified directory and load the names of the files
- * in that directory. 0 is returned if the directory can not be
- * opened, 1 if it is opened.
+ * in that directory.
*/
- bool Load(const std::string&, std::string* errorMessage = nullptr);
+ Status Load(std::string const&, std::string* errorMessage = nullptr);
/**
* Return the number of files in the current directory.
diff --git a/Source/kwsys/Status.cxx b/Source/kwsys/Status.cxx
new file mode 100644
index 0000000..503d1e1
--- /dev/null
+++ b/Source/kwsys/Status.cxx
@@ -0,0 +1,60 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(Status.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Status.hxx.in"
+#endif
+
+#include <cerrno>
+#include <cstring>
+#include <string>
+
+#if defined(_WIN32)
+# include <windows.h>
+#endif
+
+namespace KWSYS_NAMESPACE {
+
+Status Status::POSIX_errno()
+{
+ return Status::POSIX(errno);
+}
+
+#ifdef _WIN32
+Status Status::Windows_GetLastError()
+{
+ return Status::Windows(GetLastError());
+}
+#endif
+
+std::string Status::GetString() const
+{
+ std::string err;
+ switch (this->Kind_) {
+ case Kind::Success:
+ err = "Success";
+ break;
+ case Kind::POSIX:
+ err = strerror(this->POSIX_);
+ break;
+#ifdef _WIN32
+ case Kind::Windows: {
+ LPSTR message = NULL;
+ DWORD size = FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, this->Windows_, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&message, 0, NULL);
+ err = std::string(message, size);
+ LocalFree(message);
+ } break;
+#endif
+ };
+ return err;
+}
+
+} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/Status.hxx.in b/Source/kwsys/Status.hxx.in
new file mode 100644
index 0000000..feb5b84
--- /dev/null
+++ b/Source/kwsys/Status.hxx.in
@@ -0,0 +1,101 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
+#ifndef @KWSYS_NAMESPACE@_Status_hxx
+#define @KWSYS_NAMESPACE@_Status_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+
+#include <string>
+
+namespace @KWSYS_NAMESPACE@ {
+
+/** \class Status
+ * \brief OS-specific status of a system operation.
+ */
+class @KWSYS_NAMESPACE@_EXPORT Status
+{
+public:
+ enum class Kind
+ {
+ Success,
+ POSIX,
+#ifdef _WIN32
+ Windows,
+#endif
+ };
+
+ /** Construct with kind "Success". */
+ Status() = default;
+
+ /** Construct with kind "Success". */
+ static Status Success() { return Status(); }
+
+ /** Construct with kind "POSIX" using given errno-style value. */
+ static Status POSIX(int e)
+ {
+ Status s(Kind::POSIX);
+ s.POSIX_ = e;
+ return s;
+ }
+
+ /** Construct with kind "POSIX" using errno. */
+ static Status POSIX_errno();
+
+#ifdef _WIN32
+ /** Construct with kind "Windows" using given GetLastError()-style value. */
+ static Status Windows(unsigned int e)
+ {
+ Status s(Kind::Windows);
+ s.Windows_ = e;
+ return s;
+ }
+
+ /** Construct with kind "Windows" using GetLastError(). */
+ static Status Windows_GetLastError();
+#endif
+
+ /** Return true on "Success", false otherwise. */
+ explicit operator bool() const { return this->Kind_ == Kind::Success; }
+
+ /** Return the kind of status. */
+ Kind GetKind() const { return this->Kind_; }
+
+ /** If the kind is "POSIX", returns the errno-style value.
+ Otherwise, returns 0. */
+ int GetPOSIX() const
+ {
+ return this->Kind_ == Kind::POSIX ? this->POSIX_ : 0;
+ }
+
+#ifdef _WIN32
+ /** If the kind is "Windows", returns the GetLastError()-style value.
+ Otherwise, returns 0. */
+ int GetWindows() const
+ {
+ return this->Kind_ == Kind::Windows ? this->Windows_ : 0;
+ }
+#endif
+
+ /** Return a human-readable description of the status. */
+ std::string GetString() const;
+
+private:
+ Status(Kind kind)
+ : Kind_(kind)
+ {
+ }
+
+ Kind Kind_ = Kind::Success;
+
+ union
+ {
+ int POSIX_;
+#ifdef _WIN32
+ unsigned int Windows_;
+#endif
+ };
+};
+
+} // namespace @KWSYS_NAMESPACE@
+
+#endif
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 4d974a8..2518845 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -882,21 +882,24 @@ FILE* SystemTools::Fopen(const std::string& file, const char* mode)
#endif
}
-bool SystemTools::MakeDirectory(const char* path, const mode_t* mode)
+Status SystemTools::MakeDirectory(const char* path, const mode_t* mode)
{
if (!path) {
- return false;
+ return Status::POSIX(EINVAL);
}
return SystemTools::MakeDirectory(std::string(path), mode);
}
-bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
+Status SystemTools::MakeDirectory(std::string const& path, const mode_t* mode)
{
- if (SystemTools::PathExists(path)) {
- return SystemTools::FileIsDirectory(path);
- }
if (path.empty()) {
- return false;
+ return Status::POSIX(EINVAL);
+ }
+ if (SystemTools::PathExists(path)) {
+ if (SystemTools::FileIsDirectory(path)) {
+ return Status::Success();
+ }
+ return Status::POSIX(EEXIST);
}
std::string dir = path;
SystemTools::ConvertToUnixSlashes(dir);
@@ -914,15 +917,11 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
++pos;
}
topdir = dir;
- if (Mkdir(topdir, mode) != 0) {
- // if it is some other error besides directory exists
- // then return false
- if (errno != EEXIST) {
- return false;
- }
+ if (Mkdir(topdir, mode) != 0 && errno != EEXIST) {
+ return Status::POSIX_errno();
}
- return true;
+ return Status::Success();
}
// replace replace with with as many times as it shows up in source.
@@ -1411,18 +1410,18 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf)
#endif
}
-bool SystemTools::Touch(const std::string& filename, bool create)
+Status SystemTools::Touch(std::string const& filename, bool create)
{
if (!SystemTools::FileExists(filename)) {
if (create) {
FILE* file = Fopen(filename, "a+b");
if (file) {
fclose(file);
- return true;
+ return Status::Success();
}
- return false;
+ return Status::POSIX_errno();
} else {
- return true;
+ return Status::Success();
}
}
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1430,31 +1429,32 @@ bool SystemTools::Touch(const std::string& filename, bool create)
FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (!h) {
- return false;
+ return Status::Windows_GetLastError();
}
FILETIME mtime;
GetSystemTimeAsFileTime(&mtime);
if (!SetFileTime(h, 0, 0, &mtime)) {
+ Status status = Status::Windows_GetLastError();
CloseHandle(h);
- return false;
+ return status;
}
CloseHandle(h);
#elif KWSYS_CXX_HAS_UTIMENSAT
// utimensat is only available on newer Unixes and macOS 10.13+
if (utimensat(AT_FDCWD, filename.c_str(), nullptr, 0) < 0) {
- return false;
+ return Status::POSIX_errno();
}
#else
// fall back to utimes
if (utimes(filename.c_str(), nullptr) < 0) {
- return false;
+ return Status::POSIX_errno();
}
#endif
- return true;
+ return Status::Success();
}
-bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2,
- int* result)
+Status SystemTools::FileTimeCompare(std::string const& f1,
+ std::string const& f2, int* result)
{
// Default to same time.
*result = 0;
@@ -1462,11 +1462,11 @@ bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2,
// POSIX version. Use stat function to get file modification time.
struct stat s1;
if (stat(f1.c_str(), &s1) != 0) {
- return false;
+ return Status::POSIX_errno();
}
struct stat s2;
if (stat(f2.c_str(), &s2) != 0) {
- return false;
+ return Status::POSIX_errno();
}
# if KWSYS_CXX_STAT_HAS_ST_MTIM
// Compare using nanosecond resolution.
@@ -1504,17 +1504,17 @@ bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2,
WIN32_FILE_ATTRIBUTE_DATA f2d;
if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f1).c_str(),
GetFileExInfoStandard, &f1d)) {
- return false;
+ return Status::Windows_GetLastError();
}
if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f2).c_str(),
GetFileExInfoStandard, &f2d)) {
- return false;
+ return Status::Windows_GetLastError();
}
// Compare the file times using resolution provided by system call.
*result = (int)CompareFileTime(&f1d.ftLastWriteTime, &f2d.ftLastWriteTime);
#endif
- return true;
+ return Status::Success();
}
// Return a capitalized string (i.e the first letter is uppercased, all other
@@ -2129,8 +2129,8 @@ static std::string FileInDir(const std::string& source, const std::string& dir)
return new_destination + '/' + SystemTools::GetFilenameName(source);
}
-bool SystemTools::CopyFileIfDifferent(const std::string& source,
- const std::string& destination)
+Status SystemTools::CopyFileIfDifferent(std::string const& source,
+ std::string const& destination)
{
// special check for a destination that is a directory
// FilesDiffer does not handle file to directory compare
@@ -2147,7 +2147,7 @@ bool SystemTools::CopyFileIfDifferent(const std::string& source,
}
}
// at this point the files must be the same so return true
- return true;
+ return Status::Success();
}
#define KWSYS_ST_BUFFER 4096
@@ -2273,13 +2273,13 @@ bool SystemTools::TextFilesDiffer(const std::string& path1,
return false;
}
-bool SystemTools::CopyFileContentBlockwise(const std::string& source,
- const std::string& destination)
+Status SystemTools::CopyFileContentBlockwise(std::string const& source,
+ std::string const& destination)
{
// Open files
kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary);
if (!fin) {
- return false;
+ return Status::POSIX_errno();
}
// try and remove the destination file so that read only destination files
@@ -2291,7 +2291,7 @@ bool SystemTools::CopyFileContentBlockwise(const std::string& source,
kwsys::ofstream fout(destination.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
if (!fout) {
- return false;
+ return Status::POSIX_errno();
}
// This copy loop is very sensitive on certain platforms with
@@ -2320,10 +2320,10 @@ bool SystemTools::CopyFileContentBlockwise(const std::string& source,
fout.close();
if (!fout) {
- return false;
+ return Status::POSIX_errno();
}
- return true;
+ return Status::Success();
}
/**
@@ -2338,13 +2338,13 @@ bool SystemTools::CopyFileContentBlockwise(const std::string& source,
* - The underlying filesystem does not support file cloning
* - An unspecified error occurred
*/
-bool SystemTools::CloneFileContent(const std::string& source,
- const std::string& destination)
+Status SystemTools::CloneFileContent(std::string const& source,
+ std::string const& destination)
{
#if defined(__linux) && defined(FICLONE)
int in = open(source.c_str(), O_RDONLY);
if (in < 0) {
- return false;
+ return Status::POSIX_errno();
}
SystemTools::RemoveFile(destination);
@@ -2352,38 +2352,42 @@ bool SystemTools::CloneFileContent(const std::string& source,
int out =
open(destination.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (out < 0) {
+ Status status = Status::POSIX_errno();
close(in);
- return false;
+ return status;
}
- int result = ioctl(out, FICLONE, in);
+ Status status = Status::Success();
+ if (ioctl(out, FICLONE, in) < 0) {
+ status = Status::POSIX_errno();
+ }
close(in);
close(out);
- if (result < 0) {
- return false;
- }
-
- return true;
+ return status;
#else
(void)source;
(void)destination;
- return false;
+ return Status::POSIX(ENOSYS);
#endif
}
/**
* Copy a file named by "source" to the file named by "destination".
*/
-bool SystemTools::CopyFileAlways(const std::string& source,
- const std::string& destination)
+Status SystemTools::CopyFileAlways(std::string const& source,
+ std::string const& destination)
{
+ Status status;
mode_t perm = 0;
- bool perms = SystemTools::GetPermissions(source, perm);
+ Status perms = SystemTools::GetPermissions(source, perm);
std::string real_destination = destination;
if (SystemTools::FileIsDirectory(source)) {
- SystemTools::MakeDirectory(destination);
+ status = SystemTools::MakeDirectory(destination);
+ if (!status) {
+ return status;
+ }
} else {
// If destination is a directory, try to create a file with the same
// name as the source in that directory.
@@ -2400,30 +2404,34 @@ bool SystemTools::CopyFileAlways(const std::string& source,
}
// If files are the same do not copy
if (SystemTools::SameFile(source, real_destination)) {
- return true;
+ return status;
}
// Create destination directory
-
- SystemTools::MakeDirectory(destination_dir);
-
- if (!SystemTools::CloneFileContent(source, real_destination)) {
- // if cloning did not succeed, fall back to blockwise copy
- if (!SystemTools::CopyFileContentBlockwise(source, real_destination)) {
- return false;
+ if (!destination_dir.empty()) {
+ status = SystemTools::MakeDirectory(destination_dir);
+ if (!status) {
+ return status;
}
}
+
+ status = SystemTools::CloneFileContent(source, real_destination);
+ // if cloning did not succeed, fall back to blockwise copy
+ if (!status) {
+ status = SystemTools::CopyFileContentBlockwise(source, real_destination);
+ }
+ if (!status) {
+ return status;
+ }
}
if (perms) {
- if (!SystemTools::SetPermissions(real_destination, perm)) {
- return false;
- }
+ status = SystemTools::SetPermissions(real_destination, perm);
}
- return true;
+ return status;
}
-bool SystemTools::CopyAFile(const std::string& source,
- const std::string& destination, bool always)
+Status SystemTools::CopyAFile(std::string const& source,
+ std::string const& destination, bool always)
{
if (always) {
return SystemTools::CopyFileAlways(source, destination);
@@ -2436,18 +2444,21 @@ bool SystemTools::CopyAFile(const std::string& source,
* Copy a directory content from "source" directory to the directory named by
* "destination".
*/
-bool SystemTools::CopyADirectory(const std::string& source,
- const std::string& destination, bool always)
+Status SystemTools::CopyADirectory(std::string const& source,
+ std::string const& destination, bool always)
{
+ Status status;
Directory dir;
- if (dir.Load(source) == 0) {
- return false;
+ status = dir.Load(source);
+ if (!status) {
+ return status;
}
- size_t fileNum;
- if (!SystemTools::MakeDirectory(destination)) {
- return false;
+ status = SystemTools::MakeDirectory(destination);
+ if (!status) {
+ return status;
}
- for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
+
+ for (size_t fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 &&
strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) {
std::string fullPath = source;
@@ -2457,18 +2468,20 @@ bool SystemTools::CopyADirectory(const std::string& source,
std::string fullDestPath = destination;
fullDestPath += "/";
fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if (!SystemTools::CopyADirectory(fullPath, fullDestPath, always)) {
- return false;
+ status = SystemTools::CopyADirectory(fullPath, fullDestPath, always);
+ if (!status) {
+ return status;
}
} else {
- if (!SystemTools::CopyAFile(fullPath, destination, always)) {
- return false;
+ status = SystemTools::CopyAFile(fullPath, destination, always);
+ if (!status) {
+ return status;
}
}
}
}
- return true;
+ return status;
}
// return size of file; also returns zero if no file exists
@@ -2550,26 +2563,26 @@ std::string SystemTools::GetLastSystemError()
return strerror(e);
}
-bool SystemTools::RemoveFile(const std::string& source)
+Status SystemTools::RemoveFile(std::string const& source)
{
#ifdef _WIN32
std::wstring const& ws = Encoding::ToWindowsExtendedPath(source);
if (DeleteFileW(ws.c_str())) {
- return true;
+ return Status::Success();
}
DWORD err = GetLastError();
if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
- return true;
+ return Status::Success();
}
if (err != ERROR_ACCESS_DENIED) {
- return false;
+ return Status::Windows(err);
}
/* The file may be read-only. Try adding write permission. */
mode_t mode;
if (!SystemTools::GetPermissions(source, mode) ||
!SystemTools::SetPermissions(source, S_IWRITE)) {
SetLastError(err);
- return false;
+ return Status::Windows(err);
}
const DWORD DIRECTORY_SOFT_LINK_ATTRS =
@@ -2578,26 +2591,29 @@ bool SystemTools::RemoveFile(const std::string& source)
if (attrs != INVALID_FILE_ATTRIBUTES &&
(attrs & DIRECTORY_SOFT_LINK_ATTRS) == DIRECTORY_SOFT_LINK_ATTRS &&
RemoveDirectoryW(ws.c_str())) {
- return true;
+ return Status::Success();
}
if (DeleteFileW(ws.c_str()) || GetLastError() == ERROR_FILE_NOT_FOUND ||
GetLastError() == ERROR_PATH_NOT_FOUND) {
- return true;
+ return Status::Success();
}
/* Try to restore the original permissions. */
SystemTools::SetPermissions(source, mode);
SetLastError(err);
- return false;
+ return Status::Windows(err);
#else
- return unlink(source.c_str()) == 0 || errno == ENOENT;
+ if (unlink(source.c_str()) != 0 && errno != ENOENT) {
+ return Status::POSIX_errno();
+ }
+ return Status::Success();
#endif
}
-bool SystemTools::RemoveADirectory(const std::string& source)
+Status SystemTools::RemoveADirectory(std::string const& source)
{
// Add write permission to the directory so we can modify its
// content to remove files and directories from it.
- mode_t mode;
+ mode_t mode = 0;
if (SystemTools::GetPermissions(source, mode)) {
#if defined(_WIN32) && !defined(__CYGWIN__)
mode |= S_IWRITE;
@@ -2607,8 +2623,13 @@ bool SystemTools::RemoveADirectory(const std::string& source)
SystemTools::SetPermissions(source, mode);
}
+ Status status;
Directory dir;
- dir.Load(source);
+ status = dir.Load(source);
+ if (!status) {
+ return status;
+ }
+
size_t fileNum;
for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 &&
@@ -2618,18 +2639,23 @@ bool SystemTools::RemoveADirectory(const std::string& source)
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
if (SystemTools::FileIsDirectory(fullPath) &&
!SystemTools::FileIsSymlink(fullPath)) {
- if (!SystemTools::RemoveADirectory(fullPath)) {
- return false;
+ status = SystemTools::RemoveADirectory(fullPath);
+ if (!status) {
+ return status;
}
} else {
- if (!SystemTools::RemoveFile(fullPath)) {
- return false;
+ status = SystemTools::RemoveFile(fullPath);
+ if (!status) {
+ return status;
}
}
}
}
- return (Rmdir(source) == 0);
+ if (Rmdir(source) != 0) {
+ status = Status::POSIX_errno();
+ }
+ return status;
}
/**
@@ -3023,44 +3049,49 @@ bool SystemTools::FileIsFIFO(const std::string& name)
}
#if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::CreateSymlink(const std::string&, const std::string&)
+Status SystemTools::CreateSymlink(std::string const&, std::string const&)
{
- return false;
+ return Status::Windows(ERROR_NOT_SUPPORTED);
}
#else
-bool SystemTools::CreateSymlink(const std::string& origName,
- const std::string& newName)
+Status SystemTools::CreateSymlink(std::string const& origName,
+ std::string const& newName)
{
- return symlink(origName.c_str(), newName.c_str()) >= 0;
+ if (symlink(origName.c_str(), newName.c_str()) < 0) {
+ return Status::POSIX_errno();
+ }
+ return Status::Success();
}
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::ReadSymlink(const std::string&, std::string&)
+Status SystemTools::ReadSymlink(std::string const&, std::string&)
{
- return false;
+ return Status::Windows(ERROR_NOT_SUPPORTED);
}
#else
-bool SystemTools::ReadSymlink(const std::string& newName,
- std::string& origName)
+Status SystemTools::ReadSymlink(std::string const& newName,
+ std::string& origName)
{
char buf[KWSYS_SYSTEMTOOLS_MAXPATH + 1];
int count = static_cast<int>(
readlink(newName.c_str(), buf, KWSYS_SYSTEMTOOLS_MAXPATH));
- if (count >= 0) {
- // Add null-terminator.
- buf[count] = 0;
- origName = buf;
- return true;
- } else {
- return false;
+ if (count < 0) {
+ return Status::POSIX_errno();
}
+ // Add null-terminator.
+ buf[count] = 0;
+ origName = buf;
+ return Status::Success();
}
#endif
-int SystemTools::ChangeDirectory(const std::string& dir)
+Status SystemTools::ChangeDirectory(std::string const& dir)
{
- return Chdir(dir);
+ if (Chdir(dir) < 0) {
+ return Status::POSIX_errno();
+ }
+ return Status::Success();
}
std::string SystemTools::GetCurrentWorkingDirectory()
@@ -3957,7 +3988,8 @@ bool SystemToolsStatic::FileIsFullPath(const char* in_name, size_t len)
return false;
}
-bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
+Status SystemTools::GetShortPath(std::string const& path,
+ std::string& shortPath)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
std::string tempPath = path; // create a buffer
@@ -3977,14 +4009,14 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
}
if (ret == 0) {
- return false;
+ return Status::Windows_GetLastError();
} else {
shortPath = Encoding::ToNarrow(&buffer[0]);
- return true;
+ return Status::Success();
}
#else
shortPath = path;
- return true;
+ return Status::Success();
#endif
}
@@ -4085,21 +4117,21 @@ int SystemTools::GetTerminalWidth()
return width;
}
-bool SystemTools::GetPermissions(const char* file, mode_t& mode)
+Status SystemTools::GetPermissions(const char* file, mode_t& mode)
{
if (!file) {
- return false;
+ return Status::POSIX(EINVAL);
}
return SystemTools::GetPermissions(std::string(file), mode);
}
-bool SystemTools::GetPermissions(const std::string& file, mode_t& mode)
+Status SystemTools::GetPermissions(std::string const& file, mode_t& mode)
{
#if defined(_WIN32)
DWORD attr =
GetFileAttributesW(Encoding::ToWindowsExtendedPath(file).c_str());
if (attr == INVALID_FILE_ATTRIBUTES) {
- return false;
+ return Status::Windows_GetLastError();
}
if ((attr & FILE_ATTRIBUTE_READONLY) != 0) {
mode = (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6));
@@ -4122,27 +4154,27 @@ bool SystemTools::GetPermissions(const std::string& file, mode_t& mode)
#else
struct stat st;
if (stat(file.c_str(), &st) < 0) {
- return false;
+ return Status::POSIX_errno();
}
mode = st.st_mode;
#endif
- return true;
+ return Status::Success();
}
-bool SystemTools::SetPermissions(const char* file, mode_t mode,
- bool honor_umask)
+Status SystemTools::SetPermissions(const char* file, mode_t mode,
+ bool honor_umask)
{
if (!file) {
- return false;
+ return Status::POSIX(EINVAL);
}
return SystemTools::SetPermissions(std::string(file), mode, honor_umask);
}
-bool SystemTools::SetPermissions(const std::string& file, mode_t mode,
- bool honor_umask)
+Status SystemTools::SetPermissions(std::string const& file, mode_t mode,
+ bool honor_umask)
{
if (!SystemTools::PathExists(file)) {
- return false;
+ return Status::POSIX(ENOENT);
}
if (honor_umask) {
mode_t currentMask = umask(0);
@@ -4155,10 +4187,10 @@ bool SystemTools::SetPermissions(const std::string& file, mode_t mode,
if (chmod(file.c_str(), mode) < 0)
#endif
{
- return false;
+ return Status::POSIX_errno();
}
- return true;
+ return Status::Success();
}
std::string SystemTools::GetParentDirectory(const std::string& fileOrDir)
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index a7b1288..e5d115e 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -4,6 +4,7 @@
#define @KWSYS_NAMESPACE@_SystemTools_hxx
#include <@KWSYS_NAMESPACE@/Configure.hxx>
+#include <@KWSYS_NAMESPACE@/Status.hxx>
#include <iosfwd>
#include <map>
@@ -339,7 +340,7 @@ public:
/**
Change the modification time or create a file
*/
- static bool Touch(const std::string& filename, bool create);
+ static Status Touch(std::string const& filename, bool create);
/**
* Compare file modification times.
@@ -347,8 +348,8 @@ public:
* When true is returned, result has -1, 0, +1 for
* f1 older, same, or newer than f2.
*/
- static bool FileTimeCompare(const std::string& f1, const std::string& f2,
- int* result);
+ static Status FileTimeCompare(std::string const& f1, std::string const& f2,
+ int* result);
/**
* Get the file extension (including ".") needed for an executable
@@ -507,7 +508,7 @@ public:
* For windows return the short path for the given path,
* Unix just a pass through
*/
- static bool GetShortPath(const std::string& path, std::string& result);
+ static Status GetShortPath(std::string const& path, std::string& result);
/**
* Read line from file. Make sure to read a full line and truncates it if
@@ -553,16 +554,16 @@ public:
* can make a full path even if none of the directories existed
* prior to calling this function.
*/
- static bool MakeDirectory(const char* path, const mode_t* mode = nullptr);
- static bool MakeDirectory(const std::string& path,
- const mode_t* mode = nullptr);
+ static Status MakeDirectory(const char* path, const mode_t* mode = nullptr);
+ static Status MakeDirectory(std::string const& path,
+ const mode_t* mode = nullptr);
/**
* Copy the source file to the destination file only
* if the two files differ.
*/
- static bool CopyFileIfDifferent(const std::string& source,
- const std::string& destination);
+ static Status CopyFileIfDifferent(std::string const& source,
+ std::string const& destination);
/**
* Compare the contents of two files. Return true if different
@@ -580,13 +581,13 @@ public:
/**
* Blockwise copy source to destination file
*/
- static bool CopyFileContentBlockwise(const std::string& source,
- const std::string& destination);
+ static Status CopyFileContentBlockwise(std::string const& source,
+ std::string const& destination);
/**
* Clone the source file to the destination file
*/
- static bool CloneFileContent(const std::string& source,
- const std::string& destination);
+ static Status CloneFileContent(std::string const& source,
+ std::string const& destination);
/**
* Return true if the two files are the same file
@@ -596,16 +597,16 @@ public:
/**
* Copy a file.
*/
- static bool CopyFileAlways(const std::string& source,
- const std::string& destination);
+ static Status CopyFileAlways(std::string const& source,
+ std::string const& destination);
/**
* Copy a file. If the "always" argument is true the file is always
* copied. If it is false, the file is copied only if it is new or
* has changed.
*/
- static bool CopyAFile(const std::string& source,
- const std::string& destination, bool always = true);
+ static Status CopyAFile(std::string const& source,
+ std::string const& destination, bool always = true);
/**
* Copy content directory to another directory with all files and
@@ -613,19 +614,19 @@ public:
* always copied. If it is false, only files that have changed or
* are new are copied.
*/
- static bool CopyADirectory(const std::string& source,
- const std::string& destination,
- bool always = true);
+ static Status CopyADirectory(std::string const& source,
+ std::string const& destination,
+ bool always = true);
/**
* Remove a file
*/
- static bool RemoveFile(const std::string& source);
+ static Status RemoveFile(std::string const& source);
/**
* Remove a directory
*/
- static bool RemoveADirectory(const std::string& source);
+ static Status RemoveADirectory(std::string const& source);
/**
* Get the maximum full file path length
@@ -719,14 +720,14 @@ public:
* Create a symbolic link if the platform supports it. Returns whether
* creation succeeded.
*/
- static bool CreateSymlink(const std::string& origName,
- const std::string& newName);
+ static Status CreateSymlink(std::string const& origName,
+ std::string const& newName);
/**
* Read the contents of a symbolic link. Returns whether reading
* succeeded.
*/
- static bool ReadSymlink(const std::string& newName, std::string& origName);
+ static Status ReadSymlink(std::string const& newName, std::string& origName);
/**
* Try to locate the file 'filename' in the directory 'dir'.
@@ -776,12 +777,12 @@ public:
* WARNING: A non-thread-safe method is currently used to get the umask
* if a honor_umask parameter is set to true.
*/
- static bool GetPermissions(const char* file, mode_t& mode);
- static bool GetPermissions(const std::string& file, mode_t& mode);
- static bool SetPermissions(const char* file, mode_t mode,
- bool honor_umask = false);
- static bool SetPermissions(const std::string& file, mode_t mode,
- bool honor_umask = false);
+ static Status GetPermissions(const char* file, mode_t& mode);
+ static Status GetPermissions(std::string const& file, mode_t& mode);
+ static Status SetPermissions(const char* file, mode_t mode,
+ bool honor_umask = false);
+ static Status SetPermissions(std::string const& file, mode_t mode,
+ bool honor_umask = false);
/** -----------------------------------------------------------------
* Time Manipulation Routines
@@ -878,7 +879,7 @@ public:
/**
* Change directory to the directory specified
*/
- static int ChangeDirectory(const std::string& dir);
+ static Status ChangeDirectory(std::string const& dir);
/**
* Get the result of strerror(errno)
diff --git a/Source/kwsys/testDirectory.cxx b/Source/kwsys/testDirectory.cxx
index eb3ca32..06a22dc 100644
--- a/Source/kwsys/testDirectory.cxx
+++ b/Source/kwsys/testDirectory.cxx
@@ -88,7 +88,7 @@ int _nonExistentDirectoryTest()
errorMessage = "foo";
// Increment res failure if directory lists
- res += testdir.Load(testdirpath, &errorMessage);
+ res += testdir.Load(testdirpath, &errorMessage) ? 1 : 0;
#if !defined(_WIN32) || defined(__CYGWIN__)
// Increment res failure if errorMessage is unmodified
res += (errorMessage == "foo");
@@ -120,7 +120,7 @@ int _copyDirectoryTest()
std::cerr << destination << " shouldn't exist before test" << std::endl;
return 2;
}
- const bool copysuccess = SystemTools::CopyADirectory(source, destination);
+ const Status copysuccess = SystemTools::CopyADirectory(source, destination);
const bool destinationexists = SystemTools::PathExists(destination);
if (copysuccess) {
std::cerr << "CopyADirectory should have returned false" << std::endl;
diff --git a/Source/kwsys/testStatus.cxx b/Source/kwsys/testStatus.cxx
new file mode 100644
index 0000000..f85ef42
--- /dev/null
+++ b/Source/kwsys/testStatus.cxx
@@ -0,0 +1,117 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(Status.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Status.hxx.in"
+#endif
+
+#include <cerrno>
+#include <iostream>
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+int testStatus(int, char* [])
+{
+ bool res = true;
+ {
+ kwsys::Status status;
+ if (status.GetKind() != kwsys::Status::Kind::Success) {
+ std::cerr << "Status default constructor does not produce Success\n";
+ res = false;
+ }
+
+ status = kwsys::Status::Success();
+ if (status.GetKind() != kwsys::Status::Kind::Success) {
+ std::cerr << "Status Success constructor does not produce Success\n";
+ res = false;
+ }
+ if (!status) {
+ std::cerr << "Status Success kind is not true\n";
+ res = false;
+ }
+ if (status.GetPOSIX() != 0) {
+ std::cerr << "Status Success kind does not return POSIX 0\n";
+ res = false;
+ }
+#ifdef _WIN32
+ if (status.GetWindows() != 0) {
+ std::cerr << "Status Success kind does not return Windows 0\n";
+ res = false;
+ }
+#endif
+ if (status.GetString() != "Success") {
+ std::cerr << "Status Success kind does not return \"Success\" string\n";
+ res = false;
+ }
+
+ status = kwsys::Status::POSIX(EINVAL);
+ if (status.GetKind() != kwsys::Status::Kind::POSIX) {
+ std::cerr << "Status POSIX constructor does not produce POSIX\n";
+ res = false;
+ }
+ if (status) {
+ std::cerr << "Status POSIX kind is not false\n";
+ res = false;
+ }
+ if (status.GetPOSIX() != EINVAL) {
+ std::cerr << "Status POSIX kind does not preserve POSIX value\n";
+ res = false;
+ }
+#ifdef _WIN32
+ if (status.GetWindows() != 0) {
+ std::cerr << "Status POSIX kind does not return Windows 0\n";
+ res = false;
+ }
+#endif
+ if (status.GetString().empty()) {
+ std::cerr << "Status POSIX kind returns empty string\n";
+ res = false;
+ }
+ errno = ENOENT;
+ status = kwsys::Status::POSIX_errno();
+ if (status.GetPOSIX() != ENOENT) {
+ std::cerr << "Status POSIX_errno did not use errno\n";
+ res = false;
+ }
+ errno = 0;
+
+#ifdef _WIN32
+ status = kwsys::Status::Windows(ERROR_INVALID_PARAMETER);
+ if (status.GetKind() != kwsys::Status::Kind::Windows) {
+ std::cerr << "Status Windows constructor does not produce Windows\n";
+ res = false;
+ }
+ if (status) {
+ std::cerr << "Status Windows kind is not false\n";
+ res = false;
+ }
+ if (status.GetWindows() != ERROR_INVALID_PARAMETER) {
+ std::cerr << "Status Windows kind does not preserve Windows value\n";
+ res = false;
+ }
+ if (status.GetPOSIX() != 0) {
+ std::cerr << "Status Windows kind does not return POSIX 0\n";
+ res = false;
+ }
+ if (status.GetString().empty()) {
+ std::cerr << "Status Windows kind returns empty string\n";
+ res = false;
+ }
+
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ status = kwsys::Status::Windows_GetLastError();
+ if (status.GetWindows() != ERROR_FILE_NOT_FOUND) {
+ std::cerr << "Status Windows_GetLastError did not use GetLastError()\n";
+ res = false;
+ }
+ SetLastError(ERROR_SUCCESS);
+#endif
+ }
+ return res ? 0 : 1;
+}