summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/kwsys/CMakeLists.txt1
-rw-r--r--Source/kwsys/Directory.cxx90
-rw-r--r--Source/kwsys/Directory.hxx.in21
-rw-r--r--Source/kwsys/Glob.cxx4
-rw-r--r--Source/kwsys/SystemTools.cxx21
-rw-r--r--Source/kwsys/SystemTools.hxx.in10
6 files changed, 123 insertions, 24 deletions
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 7da5971..2253a83 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -192,6 +192,7 @@ endif()
if(KWSYS_USE_Directory)
set(KWSYS_USE_Encoding 1)
set(KWSYS_USE_Status 1)
+ set(KWSYS_USE_SystemTools 1)
endif()
if(KWSYS_USE_DynamicLoader)
set(KWSYS_USE_Encoding 1)
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index 6e31cbf..d520c14 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -7,6 +7,8 @@
#include KWSYS_HEADER(Encoding.hxx)
+#include KWSYS_HEADER(SystemTools.hxx)
+
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
@@ -16,15 +18,48 @@
#endif
#include <string>
+#include <utility>
#include <vector>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+
+# include <ctype.h>
+# include <fcntl.h>
+# include <io.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <sys/stat.h>
+# include <sys/types.h>
+#endif
+
namespace KWSYS_NAMESPACE {
class DirectoryInternals
{
public:
+ struct FileData
+ {
+ std::string Name;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ _wfinddata_t FindData;
+#endif
+ FileData(std::string name
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ ,
+ _wfinddata_t data
+#endif
+ )
+ : Name(std::move(name))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ , FindData(std::move(data))
+#endif
+ {
+ }
+ };
// Array of Files
- std::vector<std::string> Files;
+ std::vector<FileData> Files;
// Path to Open'ed directory
std::string Path;
@@ -59,10 +94,45 @@ unsigned long Directory::GetNumberOfFiles() const
const char* Directory::GetFile(unsigned long dindex) const
{
- if (dindex >= this->Internal->Files.size()) {
- return nullptr;
+ return this->Internal->Files[dindex].Name.c_str();
+}
+
+std::string const& Directory::GetFileName(std::size_t i) const
+{
+ return this->Internal->Files[i].Name;
+}
+
+std::string Directory::GetFilePath(std::size_t i) const
+{
+ std::string abs = this->Internal->Path;
+ if (!abs.empty() && abs.back() != '/') {
+ abs += '/';
}
- return this->Internal->Files[dindex].c_str();
+ abs += this->Internal->Files[i].Name;
+ return abs;
+}
+
+bool Directory::FileIsDirectory(std::size_t i) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ _wfinddata_t const& data = this->Internal->Files[i].FindData;
+ return (data.attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
+#else
+ std::string const& path = this->GetFilePath(i);
+ return kwsys::SystemTools::FileIsDirectory(path);
+#endif
+}
+
+bool Directory::FileIsSymlink(std::size_t i) const
+{
+ std::string const& path = this->GetFilePath(i);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ _wfinddata_t const& data = this->Internal->Files[i].FindData;
+ return kwsys::SystemTools::FileIsSymlinkWithAttr(
+ Encoding::ToWindowsExtendedPath(path), data.attrib);
+#else
+ return kwsys::SystemTools::FileIsSymlink(path);
+#endif
}
const char* Directory::GetPath() const
@@ -81,16 +151,6 @@ void Directory::Clear()
// First Windows platforms
#if defined(_WIN32) && !defined(__CYGWIN__)
-# include <windows.h>
-
-# include <ctype.h>
-# include <fcntl.h>
-# include <io.h>
-# include <stdio.h>
-# include <stdlib.h>
-# include <string.h>
-# include <sys/stat.h>
-# include <sys/types.h>
namespace KWSYS_NAMESPACE {
@@ -133,7 +193,7 @@ Status Directory::Load(std::string const& name, std::string* errorMessage)
// Loop through names
do {
- this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
+ this->Internal->Files.emplace_back(Encoding::ToNarrow(data.name), data);
} while (_wfindnext(srchHandle, &data) != -1);
this->Internal->Path = name;
if (_findclose(srchHandle) == -1) {
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index d501116..9d0f462 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -6,6 +6,7 @@
#include <@KWSYS_NAMESPACE@/Configure.h>
#include <@KWSYS_NAMESPACE@/Status.hxx>
+#include <cstddef>
#include <string>
namespace @KWSYS_NAMESPACE@ {
@@ -55,6 +56,26 @@ public:
const char* GetFile(unsigned long) const;
/**
+ * Return the name of the file at the given 0-based index.
+ */
+ std::string const& GetFileName(std::size_t i) const;
+
+ /**
+ * Return the absolute path to the file at the given 0-based index.
+ */
+ std::string GetFilePath(std::size_t i) const;
+
+ /**
+ * Return whether the file at the given 0-based index is a directory.
+ */
+ bool FileIsDirectory(std::size_t i) const;
+
+ /**
+ * Return whether the file at the given 0-based index is a symlink.
+ */
+ bool FileIsSymlink(std::size_t i) const;
+
+ /**
* Return the path to Open'ed directory
*/
const char* GetPath() const;
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index c6d4b19..fa2c295 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -213,8 +213,8 @@ bool Glob::RecurseDirectory(std::string::size_type start,
fname = kwsys::SystemTools::LowerCase(fname);
#endif
- bool isDir = kwsys::SystemTools::FileIsDirectory(realname);
- bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname);
+ bool isDir = d.FileIsDirectory(cc);
+ bool isSymLink = d.FileIsSymlink(cc);
if (isDir && (!isSymLink || this->RecurseThroughSymlinks)) {
if (isSymLink) {
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index c339fd5..c38b456 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2287,7 +2287,7 @@ bool SystemTools::FilesDiffer(const std::string& source,
if (statSource.nFileSizeHigh == 0 && statSource.nFileSizeLow == 0) {
return false;
}
- off_t nleft =
+ auto nleft =
((__int64)statSource.nFileSizeHigh << 32) + statSource.nFileSizeLow;
#else
@@ -3085,11 +3085,10 @@ bool SystemTools::FileIsExecutable(const std::string& name)
return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE);
}
-bool SystemTools::FileIsSymlink(const std::string& name)
-{
#if defined(_WIN32)
- std::wstring path = Encoding::ToWindowsExtendedPath(name);
- DWORD attr = GetFileAttributesW(path.c_str());
+bool SystemTools::FileIsSymlinkWithAttr(const std::wstring& path,
+ unsigned long attr)
+{
if (attr != INVALID_FILE_ATTRIBUTES) {
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
// FILE_ATTRIBUTE_REPARSE_POINT means:
@@ -3118,9 +3117,17 @@ bool SystemTools::FileIsSymlink(const std::string& name)
(reparseTag == IO_REPARSE_TAG_MOUNT_POINT);
}
return false;
- } else {
- return false;
}
+
+ return false;
+}
+#endif
+
+bool SystemTools::FileIsSymlink(const std::string& name)
+{
+#if defined(_WIN32)
+ std::wstring path = Encoding::ToWindowsExtendedPath(name);
+ return FileIsSymlinkWithAttr(path, GetFileAttributesW(path.c_str()));
#else
struct stat fs;
if (lstat(name.c_str(), &fs) == 0) {
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 6684695..acce015 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -688,6 +688,16 @@ public:
*/
static bool FileIsExecutable(const std::string& name);
+#if defined(_WIN32)
+ /**
+ * Return true if the file with FileAttributes `attr` is a symlink
+ * Only available on Windows. This avoids an expensive `GetFileAttributesW`
+ * call.
+ */
+ static bool FileIsSymlinkWithAttr(const std::wstring& path,
+ unsigned long attr);
+#endif
+
/**
* Return true if the file is a symlink
*/