KWSys 2022-01-22 (16e180ad)

Code extracted from:

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

at commit 16e180ad8ae26f896adf1c30929b1d53b3e13dac (master).

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

Brad King (2):
      929b6c6c Glob: Revert "Optimize directory/symlink checks on Windows"
      4b552447 Directory: Replace FileData with methods accepting file index

Clemens Wasser (5):
      43ce7a20 SystemTools: Factor out FileIsSymlinkWithAttr helper
      d078f9e6 Directory: Store FIND_DATA for files in Directory
      7573b0fd Directory: Add Is{Directory,Symlink} to FileData
      99c7831e Glob: Optimize directory/symlink checks on Windows
      d4c5ed92 Glob: Optimize directory/symlink checks on Windows

Markus87 (1):
      5f2dcc13 SystemTools: Fix FilesDiffer 32-bit signed integer overflow on Windows
This commit is contained in:
KWSys Upstream
2022-01-22 05:51:23 -05:00
committed by Brad King
parent 6e8a2de4cb
commit ca03a9be6c
6 changed files with 123 additions and 24 deletions
+1
View File
@@ -192,6 +192,7 @@ endif()
if(KWSYS_USE_Directory) if(KWSYS_USE_Directory)
set(KWSYS_USE_Encoding 1) set(KWSYS_USE_Encoding 1)
set(KWSYS_USE_Status 1) set(KWSYS_USE_Status 1)
set(KWSYS_USE_SystemTools 1)
endif() endif()
if(KWSYS_USE_DynamicLoader) if(KWSYS_USE_DynamicLoader)
set(KWSYS_USE_Encoding 1) set(KWSYS_USE_Encoding 1)
+75 -15
View File
@@ -7,6 +7,8 @@
#include KWSYS_HEADER(Encoding.hxx) #include KWSYS_HEADER(Encoding.hxx)
#include KWSYS_HEADER(SystemTools.hxx)
// Work-around CMake dependency scanning limitation. This must // Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers. // duplicate the above list of headers.
#if 0 #if 0
@@ -16,15 +18,48 @@
#endif #endif
#include <string> #include <string>
#include <utility>
#include <vector> #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 { namespace KWSYS_NAMESPACE {
class DirectoryInternals class DirectoryInternals
{ {
public: 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 // Array of Files
std::vector<std::string> Files; std::vector<FileData> Files;
// Path to Open'ed directory // Path to Open'ed directory
std::string Path; std::string Path;
@@ -59,10 +94,45 @@ unsigned long Directory::GetNumberOfFiles() const
const char* Directory::GetFile(unsigned long dindex) const const char* Directory::GetFile(unsigned long dindex) const
{ {
if (dindex >= this->Internal->Files.size()) { return this->Internal->Files[dindex].Name.c_str();
return nullptr; }
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 const char* Directory::GetPath() const
@@ -81,16 +151,6 @@ void Directory::Clear()
// First Windows platforms // First Windows platforms
#if defined(_WIN32) && !defined(__CYGWIN__) #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 { namespace KWSYS_NAMESPACE {
@@ -133,7 +193,7 @@ Status Directory::Load(std::string const& name, std::string* errorMessage)
// Loop through names // Loop through names
do { 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); } while (_wfindnext(srchHandle, &data) != -1);
this->Internal->Path = name; this->Internal->Path = name;
if (_findclose(srchHandle) == -1) { if (_findclose(srchHandle) == -1) {
+21
View File
@@ -6,6 +6,7 @@
#include <@KWSYS_NAMESPACE@/Configure.h> #include <@KWSYS_NAMESPACE@/Configure.h>
#include <@KWSYS_NAMESPACE@/Status.hxx> #include <@KWSYS_NAMESPACE@/Status.hxx>
#include <cstddef>
#include <string> #include <string>
namespace @KWSYS_NAMESPACE@ { namespace @KWSYS_NAMESPACE@ {
@@ -54,6 +55,26 @@ public:
*/ */
const char* GetFile(unsigned long) const; 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 * Return the path to Open'ed directory
*/ */
+2 -2
View File
@@ -213,8 +213,8 @@ bool Glob::RecurseDirectory(std::string::size_type start,
fname = kwsys::SystemTools::LowerCase(fname); fname = kwsys::SystemTools::LowerCase(fname);
#endif #endif
bool isDir = kwsys::SystemTools::FileIsDirectory(realname); bool isDir = d.FileIsDirectory(cc);
bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname); bool isSymLink = d.FileIsSymlink(cc);
if (isDir && (!isSymLink || this->RecurseThroughSymlinks)) { if (isDir && (!isSymLink || this->RecurseThroughSymlinks)) {
if (isSymLink) { if (isSymLink) {
+14 -7
View File
@@ -2287,7 +2287,7 @@ bool SystemTools::FilesDiffer(const std::string& source,
if (statSource.nFileSizeHigh == 0 && statSource.nFileSizeLow == 0) { if (statSource.nFileSizeHigh == 0 && statSource.nFileSizeLow == 0) {
return false; return false;
} }
off_t nleft = auto nleft =
((__int64)statSource.nFileSizeHigh << 32) + statSource.nFileSizeLow; ((__int64)statSource.nFileSizeHigh << 32) + statSource.nFileSizeLow;
#else #else
@@ -3085,11 +3085,10 @@ bool SystemTools::FileIsExecutable(const std::string& name)
return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE); return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE);
} }
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32) #if defined(_WIN32)
std::wstring path = Encoding::ToWindowsExtendedPath(name); bool SystemTools::FileIsSymlinkWithAttr(const std::wstring& path,
DWORD attr = GetFileAttributesW(path.c_str()); unsigned long attr)
{
if (attr != INVALID_FILE_ATTRIBUTES) { if (attr != INVALID_FILE_ATTRIBUTES) {
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
// FILE_ATTRIBUTE_REPARSE_POINT means: // FILE_ATTRIBUTE_REPARSE_POINT means:
@@ -3118,9 +3117,17 @@ bool SystemTools::FileIsSymlink(const std::string& name)
(reparseTag == IO_REPARSE_TAG_MOUNT_POINT); (reparseTag == IO_REPARSE_TAG_MOUNT_POINT);
} }
return false; 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 #else
struct stat fs; struct stat fs;
if (lstat(name.c_str(), &fs) == 0) { if (lstat(name.c_str(), &fs) == 0) {
+10
View File
@@ -688,6 +688,16 @@ public:
*/ */
static bool FileIsExecutable(const std::string& name); 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 * Return true if the file is a symlink
*/ */