diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/kwsys/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/kwsys/Directory.cxx | 90 | ||||
-rw-r--r-- | Source/kwsys/Directory.hxx.in | 21 | ||||
-rw-r--r-- | Source/kwsys/Glob.cxx | 4 | ||||
-rw-r--r-- | Source/kwsys/SystemTools.cxx | 21 | ||||
-rw-r--r-- | Source/kwsys/SystemTools.hxx.in | 10 |
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 */ |