summaryrefslogtreecommitdiffstats
path: root/Source/kwsys
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2019-01-24 14:52:25 (GMT)
committerBrad King <brad.king@kitware.com>2019-01-24 14:52:25 (GMT)
commitd67ce0a61e6a4c8b639cb19f575b4f0a5b2d033f (patch)
treebbc71ae1f140a3f99bd7398829c5d9ee3f1d410c /Source/kwsys
parent1d02491950b0aa05d2053e7fa32b39dca31e537b (diff)
parentbee32e96b392ff4e0f2baf8fdc831a9e5240c7d9 (diff)
downloadCMake-d67ce0a61e6a4c8b639cb19f575b4f0a5b2d033f.zip
CMake-d67ce0a61e6a4c8b639cb19f575b4f0a5b2d033f.tar.gz
CMake-d67ce0a61e6a4c8b639cb19f575b4f0a5b2d033f.tar.bz2
Merge branch 'upstream-KWSys' into update-kwsys
* upstream-KWSys: KWSys 2019-01-24 (b9dd1636)
Diffstat (limited to 'Source/kwsys')
-rw-r--r--Source/kwsys/CMakeLists.txt8
-rw-r--r--Source/kwsys/SystemTools.cxx58
-rw-r--r--Source/kwsys/SystemTools.hxx.in7
-rw-r--r--Source/kwsys/testSystemTools.cxx46
4 files changed, 114 insertions, 5 deletions
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index a2fcc16..b33aa80 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -454,6 +454,10 @@ ELSE()
SET(KWSYS_LIBRARY_TYPE STATIC)
ENDIF()
+if(NOT DEFINED KWSYS_BUILD_PIC)
+ set(KWSYS_BUILD_PIC 0)
+endif()
+
#-----------------------------------------------------------------------------
# Configure some implementation details.
@@ -870,7 +874,7 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
SET(KWSYS_LINK_DEPENDENCY INTERFACE)
ADD_LIBRARY(${KWSYS_TARGET_OBJECT} OBJECT
${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
- IF(KWSYS_BUILD_SHARED)
+ IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
SET_PROPERTY(TARGET ${KWSYS_TARGET_OBJECT} PROPERTY
POSITION_INDEPENDENT_CODE TRUE)
ENDIF()
@@ -965,7 +969,7 @@ IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
${KWSYS_TARGET_C_INTERFACE} ${KWSYS_TARGET_C_LINK})
SET(KWSYS_LINK_DEPENDENCY INTERFACE)
ADD_LIBRARY(${KWSYS_TARGET_C_OBJECT} OBJECT ${KWSYS_C_SRCS})
- IF(KWSYS_BUILD_SHARED)
+ IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
SET_PROPERTY(TARGET ${KWSYS_TARGET_C_OBJECT} PROPERTY
POSITION_INDEPENDENT_CODE TRUE)
ENDIF()
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index c5160a9..cbdfe11 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2161,6 +2161,32 @@ bool SystemTools::FilesDiffer(const std::string& source,
return false;
}
+bool SystemTools::TextFilesDiffer(const std::string& path1,
+ const std::string& path2)
+{
+ kwsys::ifstream if1(path1.c_str());
+ kwsys::ifstream if2(path2.c_str());
+ if (!if1 || !if2) {
+ return true;
+ }
+
+ for (;;) {
+ std::string line1, line2;
+ bool hasData1 = GetLineFromStream(if1, line1);
+ bool hasData2 = GetLineFromStream(if2, line2);
+ if (hasData1 != hasData2) {
+ return true;
+ }
+ if (!hasData1) {
+ break;
+ }
+ if (line1 != line2) {
+ return true;
+ }
+ }
+ return false;
+}
+
/**
* Blockwise copy source to destination file
*/
@@ -2979,10 +3005,36 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32)
- DWORD attr =
- GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str());
+ std::wstring path = Encoding::ToWindowsExtendedPath(name);
+ DWORD attr = GetFileAttributesW(path.c_str());
if (attr != INVALID_FILE_ATTRIBUTES) {
- return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
+ if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
+ // FILE_ATTRIBUTE_REPARSE_POINT means:
+ // * a file or directory that has an associated reparse point, or
+ // * a file that is a symbolic link.
+ HANDLE hFile = CreateFileW(
+ path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+ byte buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ DWORD bytesReturned = 0;
+ if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer,
+ MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned,
+ NULL)) {
+ CloseHandle(hFile);
+ // Since FILE_ATTRIBUTE_REPARSE_POINT is set this file must be
+ // a symbolic link if it is not a reparse point.
+ return GetLastError() == ERROR_NOT_A_REPARSE_POINT;
+ }
+ CloseHandle(hFile);
+ ULONG reparseTag =
+ reinterpret_cast<PREPARSE_GUID_DATA_BUFFER>(&buffer[0])->ReparseTag;
+ return (reparseTag == IO_REPARSE_TAG_SYMLINK) ||
+ (reparseTag == IO_REPARSE_TAG_MOUNT_POINT);
+ }
+ return false;
} else {
return false;
}
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 8d1f78c..1967860 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -579,6 +579,13 @@ public:
const std::string& destination);
/**
+ * Compare the contents of two files, ignoring line ending differences.
+ * Return true if different
+ */
+ static bool TextFilesDiffer(const std::string& path1,
+ const std::string& path2);
+
+ /**
* Return true if the two files are the same file
*/
static bool SameFile(const std::string& file1, const std::string& file2);
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 0477d59..9a40b53 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -984,6 +984,50 @@ static bool CheckGetLineFromStreamLongLine()
return true;
}
+static bool writeFile(const char* fileName, const char* data)
+{
+ kwsys::ofstream out(fileName, std::ios::binary);
+ out << data;
+ if (!out) {
+ std::cerr << "Failed to write file: " << fileName << std::endl;
+ return false;
+ }
+ return true;
+}
+
+static bool CheckTextFilesDiffer()
+{
+ struct
+ {
+ const char* a;
+ const char* b;
+ bool differ;
+ } test_cases[] = { { "one", "one", false },
+ { "one", "two", true },
+ { "", "", false },
+ { "\n", "\r\n", false },
+ { "one\n", "one\n", false },
+ { "one\r\n", "one\n", false },
+ { "one\n", "one", false },
+ { "one\ntwo", "one\ntwo", false },
+ { "one\ntwo", "one\r\ntwo", false } };
+ const int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+ for (int i = 0; i < num_test_cases; ++i) {
+ if (!writeFile("file_a", test_cases[i].a) ||
+ !writeFile("file_b", test_cases[i].b)) {
+ return false;
+ }
+ if (kwsys::SystemTools::TextFilesDiffer("file_a", "file_b") !=
+ test_cases[i].differ) {
+ std::cerr << "Incorrect TextFilesDiffer result for test case " << i + 1
+ << "." << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
int testSystemTools(int, char* [])
{
bool res = true;
@@ -1027,5 +1071,7 @@ int testSystemTools(int, char* [])
res &= CheckGetFilenameName();
+ res &= CheckTextFilesDiffer();
+
return res ? 0 : 1;
}