diff --git a/SystemTools.cxx b/SystemTools.cxx index c5160a993a8971cd80f143407fb230605cdb707d..c635b6b2b72863497c3d254faf9d9568532559b3 100644 --- a/SystemTools.cxx +++ b/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 */ diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in index 8d1f78cf73aa8dce7734b3f5fc0f1ec8f66e4060..1967860ab405dd5c253920b33df2746d05e50d11 100644 --- a/SystemTools.hxx.in +++ b/SystemTools.hxx.in @@ -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 */ diff --git a/testSystemTools.cxx b/testSystemTools.cxx index 0477d5937a6b51198f5734a07bbb09e176482482..9a40b53302e0869813d593d9223aa71438480f5e 100644 --- a/testSystemTools.cxx +++ b/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; }