From bab67e2db06fde689b6a7a09c25a6a409dd67257 Mon Sep 17 00:00:00 2001 From: Takashi Sawanaka Date: Sun, 15 Jan 2023 22:03:18 +0900 Subject: [PATCH] Ignore numbers when the "Ignore numbers" comparison option is specified --- src/WinWebDiffLib/DiffHighlighter.hpp | 39 +++++++++++++++++++++++---- src/WinWebDiffTest/WinWebDiffTest.cpp | 26 ++++++++++++++++-- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/WinWebDiffLib/DiffHighlighter.hpp b/src/WinWebDiffLib/DiffHighlighter.hpp index 4bcadf5..1c6f2cf 100644 --- a/src/WinWebDiffLib/DiffHighlighter.hpp +++ b/src/WinWebDiffLib/DiffHighlighter.hpp @@ -130,7 +130,7 @@ struct TextSegments return true; } } - void Make(const std::wstring& text) + void Make(const std::wstring& text, bool ignoreNumbers) { allText = text; int charTypePrev = -1; @@ -143,6 +143,8 @@ struct TextSegments charType = 1; else if (isWordBreak(ch)) charType = 2; + else if (ignoreNumbers && iswdigit(ch)) + charType = 3; if (charType == 2 || charType != charTypePrev) { if (i > 0) @@ -200,7 +202,7 @@ class DataForDiff bool equals(const char* scanline1, unsigned size1, const char* scanline2, unsigned size2) const { - if (!m_diffOptions.ignoreCase && m_diffOptions.ignoreWhitespace == 0) + if (!m_diffOptions.ignoreCase && m_diffOptions.ignoreWhitespace == 0 && !m_diffOptions.ignoreNumbers) { if (size1 != size2) return false; @@ -223,6 +225,13 @@ class DataForDiff i1++; while (i2 < s2 && iswspace(l2[i2])) i2++; + if (m_diffOptions.ignoreNumbers) + { + while (i1 < s1 && iswdigit(l1[i1])) + i1++; + while (i2 < s2 && iswdigit(l2[i2])) + i2++; + } } } else if (m_diffOptions.ignoreWhitespace == 1) @@ -238,6 +247,15 @@ class DataForDiff i2++; continue; } + if (m_diffOptions.ignoreNumbers) + { + while (i1 < s1 && iswdigit(l1[i1])) + i1++; + while (i2 < s2 && iswdigit(l2[i2])) + i2++; + if (i1 >= s1 || i2 >= s2) + continue; + } if (!match_a_wchar(l1[i1++], l2[i2++])) return false; } @@ -246,6 +264,15 @@ class DataForDiff { while (i1 < s1 && i2 < s2) { + if (m_diffOptions.ignoreNumbers) + { + while (i1 < s1 && iswdigit(l1[i1])) + i1++; + while (i2 < s2 && iswdigit(l2[i2])) + i2++; + if (i1 >= s1 || i2 >= s2) + continue; + } if (!match_a_wchar(l1[i1++], l2[i2++])) return false; } @@ -265,7 +292,7 @@ class DataForDiff const wchar_t* begin = reinterpret_cast(scanline); const wchar_t* end = reinterpret_cast(this->next(scanline)); - if (!m_diffOptions.ignoreCase && m_diffOptions.ignoreWhitespace == 0) + if (!m_diffOptions.ignoreCase && m_diffOptions.ignoreWhitespace == 0 && !m_diffOptions.ignoreNumbers) { for (const auto* ptr = begin; ptr < end; ptr++) { @@ -289,6 +316,8 @@ class DataForDiff } continue; } + if (m_diffOptions.ignoreNumbers && iswdigit(*ptr)) + continue; ha += (ha << 5); ha ^= hash_a_wchar(*ptr); } @@ -676,9 +705,9 @@ class Highlighter std::pair pair = domutils::findNodeId(m_documents[pane][L"root"], diffInfo.nodeIds[pane]); pvalues[pane] = pair.first; if (diffInfo.nodePos[pane] == 0 && pvalues[pane]) - textSegments[pane].Make((*pvalues[pane])[L"nodeValue"].GetString()); + textSegments[pane].Make((*pvalues[pane])[L"nodeValue"].GetString(), m_diffOptions.ignoreNumbers); else - textSegments[pane].Make(L""); + textSegments[pane].Make(L"", m_diffOptions.ignoreNumbers); } if (m_showWordDifferences) wordDiffInfoList = Comparer::compare(m_diffOptions, textSegments); diff --git a/src/WinWebDiffTest/WinWebDiffTest.cpp b/src/WinWebDiffTest/WinWebDiffTest.cpp index 795be95..677fcb6 100644 --- a/src/WinWebDiffTest/WinWebDiffTest.cpp +++ b/src/WinWebDiffTest/WinWebDiffTest.cpp @@ -278,8 +278,8 @@ const wchar_t* json2 = LR"( TEST_METHOD(TestMethod3) { std::vector textSegments(2); - textSegments[0].Make(L"abc"); - textSegments[1].Make(L"abc "); + textSegments[0].Make(L"abc", false); + textSegments[1].Make(L"abc ", false); IWebDiffWindow::DiffOptions diffOptions1{}; std::vector diffInfos1 = Comparer::compare(diffOptions1, textSegments); @@ -289,7 +289,29 @@ const wchar_t* json2 = LR"( diffOptions2.ignoreWhitespace = 2; std::vector diffInfos2 = Comparer::compare(diffOptions2, textSegments); Assert::AreEqual((size_t)0, diffInfos2.size()); + } + + TEST_METHOD(TestMethod4) + { + std::vector textSegments(2); + textSegments[0].Make(L"123AB", true); + textSegments[1].Make(L"456AB ", true); + + IWebDiffWindow::DiffOptions diffOptions1{}; + std::vector diffInfos1 = Comparer::compare(diffOptions1, textSegments); + Assert::AreEqual((size_t)2, diffInfos1.size()); + + IWebDiffWindow::DiffOptions diffOptions2{}; + diffOptions2.ignoreWhitespace = 1; + diffOptions2.ignoreNumbers = true; + std::vector diffInfos2 = Comparer::compare(diffOptions2, textSegments); + Assert::AreEqual((size_t)1, diffInfos2.size()); + IWebDiffWindow::DiffOptions diffOptions3{}; + diffOptions3.ignoreWhitespace = 2; + diffOptions3.ignoreNumbers = true; + std::vector diffInfos3 = Comparer::compare(diffOptions3, textSegments); + Assert::AreEqual((size_t)0, diffInfos3.size()); } }; }