mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-29 10:39:28 -05:00
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:
committed by
Brad King
parent
6e8a2de4cb
commit
ca03a9be6c
@@ -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
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user