diff --git a/Src/CompareEngines/ByteComparator.cpp b/Src/CompareEngines/ByteComparator.cpp index e6d7a72ddf0..60c15efc1aa 100644 --- a/Src/CompareEngines/ByteComparator.cpp +++ b/Src/CompareEngines/ByteComparator.cpp @@ -111,6 +111,7 @@ ByteComparator::ByteComparator(const QuickCompareOptions * options) , m_ignore_eol_diff(options->m_bIgnoreEOLDifference) , m_ignore_blank_lines(options->m_bIgnoreBlankLines) , m_ignore_numbers(options->m_bIgnoreNumbers) + , m_ignore_eof_newline_presence(options->m_bIgnoreEofNewlinePresence) // state , m_wsflag(false) , m_eol0(false) @@ -353,6 +354,8 @@ ByteComparator::COMP_RESULT ByteComparator::CompareBuffers( if ((!m_eol0 || !m_eol1) && (orig0 == end0 || orig1 == end1)) { // one side had an end-of-line, but the other didn't + if (m_ignore_eof_newline_presence) + continue; result = RESULT_DIFF; goto exit; } @@ -379,6 +382,20 @@ ByteComparator::COMP_RESULT ByteComparator::CompareBuffers( if (ptr0 == end0 || ptr1 == end1) { + if (m_ignore_eof_newline_presence) + { + if (eof0 || eof1) + { + HandleSide0Eol((char **) &ptr0, end0, eof0); + HandleSide1Eol((char **) &ptr1, end1, eof1); + + if (m_cr0 || m_cr1) + { + // these flags mean possible split CR/LF + goto need_more; + } + } + } if (ptr0 == end0 && ptr1 == end1) { if (!eof0 || !eof1) diff --git a/Src/CompareEngines/ByteComparator.h b/Src/CompareEngines/ByteComparator.h index cf7ec209324..23c60b2c95d 100644 --- a/Src/CompareEngines/ByteComparator.h +++ b/Src/CompareEngines/ByteComparator.h @@ -54,6 +54,7 @@ class ByteComparator bool m_ignore_all_space; /**< Ignore all whitespace changes */ bool m_ignore_eol_diff; /**< Ignore differences in EOL bytes */ bool m_ignore_blank_lines; /**< Ignore blank lines */ + bool m_ignore_eof_newline_presence; /**< Ignore end-of-file newline presence */ // state bool m_wsflag; /**< ignore_space_change & in a whitespace area */ bool m_eol0; /**< 0-side has an eol */ diff --git a/Testing/GoogleTest/ByteCompare/ByteCompare_test.cpp b/Testing/GoogleTest/ByteCompare/ByteCompare_test.cpp index 5fcc2c55bab..1c1c6b23857 100644 --- a/Testing/GoogleTest/ByteCompare/ByteCompare_test.cpp +++ b/Testing/GoogleTest/ByteCompare/ByteCompare_test.cpp @@ -594,4 +594,210 @@ namespace } + TEST_F(ByteCompareTest, IgnoreEofNewlinePresence) + { + CompareEngines::ByteCompare bc; + QuickCompareOptions option; + std::string filename_left = "_tmp_.txt"; + std::string filename_right = "_tmp_2.txt"; + + option.m_bIgnoreEofNewlinePresence = true; + bc.SetCompareOptions(option); + + for (int i = 0; i < 3; i++) + { + {// same left: LF - right: no EOL + std::vector buf_left(WMCMPBUFF * 2 + i); + std::vector buf_right(WMCMPBUFF * 2 - 1 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_left[buf_left.size() - 1] = '\n'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::SAME, bc.CompareFiles(&pair.diffData)); + } + + {// same left: no EOL - right: LF + std::vector buf_left(WMCMPBUFF * 2 - 1 + i); + std::vector buf_right(WMCMPBUFF * 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_right[buf_right.size() - 1] = '\n'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::SAME, bc.CompareFiles(&pair.diffData)); + } + } + + for (int i = 0; i < 3; i++) + { + {// same left: CRLF - right: no EOL + std::vector buf_left(WMCMPBUFF * 2 + i); + std::vector buf_right(WMCMPBUFF * 2 - 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_left[buf_left.size() - 2] = '\r'; + buf_left[buf_left.size() - 1] = '\n'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::SAME, bc.CompareFiles(&pair.diffData)); + } + + {// same left: no EOL - right: CRLF + std::vector buf_left(WMCMPBUFF * 2 - 2 + i); + std::vector buf_right(WMCMPBUFF * 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_right[buf_right.size() - 2] = '\r'; + buf_right[buf_right.size() - 1] = '\n'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::SAME, bc.CompareFiles(&pair.diffData)); + } + } + + for (int i = 0; i < 3; i++) + { + {// diff left: CR+A - right: no EOL + std::vector buf_left(WMCMPBUFF * 2 + i); + std::vector buf_right(WMCMPBUFF * 2 - 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_left[buf_left.size() - 2] = '\r'; + buf_left[buf_left.size() - 1] = 'A'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData)); + } + + {// diff left: no EOL - right: CR+A + std::vector buf_left(WMCMPBUFF * 2 - 2 + i); + std::vector buf_right(WMCMPBUFF * 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_right[buf_right.size() - 2] = '\r'; + buf_right[buf_right.size() - 1] = 'A'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData)); + } + } + + for (int i = 0; i < 3; i++) + { + {// diff left: LF+LF - right: no EOL + std::vector buf_left(WMCMPBUFF * 2 + i); + std::vector buf_right(WMCMPBUFF * 2 - 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_left[buf_left.size() - 2] = '\n'; + buf_left[buf_left.size() - 1] = '\n'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData)); + } + + {// diff left: no EOL - right: LF+LF + std::vector buf_left(WMCMPBUFF * 2 - 2 + i); + std::vector buf_right(WMCMPBUFF * 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_right[buf_right.size() - 2] = '\n'; + buf_right[buf_right.size() - 1] = '\n'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData)); + } + } + + for (int i = 0; i < 3; i++) + { + {// diff left: CR+CR - right: no EOL + std::vector buf_left(WMCMPBUFF * 2 + i); + std::vector buf_right(WMCMPBUFF * 2 - 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_left[buf_left.size() - 2] = '\r'; + buf_left[buf_left.size() - 1] = '\r'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData)); + } + + {// diff left: no EOL - right: CR+CR + std::vector buf_left(WMCMPBUFF * 2 - 2 + i); + std::vector buf_right(WMCMPBUFF * 2 + i); + + memset(buf_left.data(), 'A', buf_left.size()); + memset(buf_right.data(), 'A', buf_right.size()); + + buf_right[buf_right.size() - 2] = '\r'; + buf_right[buf_right.size() - 1] = '\r'; + + TempFile file_left(filename_left, buf_left.data(), buf_left.size()); + TempFile file_right(filename_right, buf_right.data(), buf_right.size()); + + FilePair pair(filename_left, filename_right); + + EXPECT_EQ(DIFFCODE::TEXT | DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData)); + } + } + + } + + } // namespace