Commit bee32e96 authored by Kitware Robot's avatar Kitware Robot Committed by Brad King

KWSys 2019-01-24 (b9dd1636)

Code extracted from:

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

at commit b9dd1636e50ea43cd33bed8c6ffbbe7161618b54 (master).

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

Ben Boeckel (1):
      28db6989 cmake: add an option for building with PIC

Taylor Braun-Jones (1):
      3f35954d SystemTools: Add TextFilesDiffer method

Tobias Kloss (1):
      aa1f7f7c SystemTools: Fix FileIsSymlink with Windows data deduplication
parent 3068a0d0
......@@ -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()
......
......@@ -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;
}
......
......@@ -578,6 +578,13 @@ public:
static bool FilesDiffer(const std::string& source,
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
*/
......
......@@ -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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment