Revision: 7220
http://winmerge.svn.sourceforge.net/winmerge/?rev=7220&view=rev
Author: kimmov
Date: 2010-07-04 09:57:53 +0000 (Sun, 04 Jul 2010)
Log Message:
-----------
PATCH: #3022014 Stingdiffs more detail on char level
Submitted by Matthias Mayer.
Modified Paths:
--------------
trunk/Docs/Users/ChangeLog.txt
trunk/Src/stringdiffs.cpp
trunk/Src/stringdiffsi.h
trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_adds.cpp
trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_bugs.cpp
trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_bytelevel.cpp
Modified: trunk/Docs/Users/ChangeLog.txt
===================================================================
--- trunk/Docs/Users/ChangeLog.txt 2010-07-03 13:02:59 UTC (rev 7219)
+++ trunk/Docs/Users/ChangeLog.txt 2010-07-04 09:57:53 UTC (rev 7220)
@@ -6,6 +6,7 @@
WinMerge 2.13.14
Update to PCRE 8.10 (r7210)
Update SCEW to 1.1.2 (r7212)
+ In-line difference highlighting improvement (#3022014)
WinMerge 2.13.13 - 2010-06-19 (r7205)
Improve editing of linefilter regular expressions (#3015416)
Modified: trunk/Src/stringdiffs.cpp
===================================================================
--- trunk/Src/stringdiffs.cpp 2010-07-03 13:02:59 UTC (rev 7219)
+++ trunk/Src/stringdiffs.cpp 2010-07-04 09:57:53 UTC (rev 7220)
@@ -100,6 +100,7 @@
, m_whitespace(whitespace)
, m_breakType(breakType)
, m_pDiffs(pDiffs)
+, m_matchblock(true) // Change to false to get word to word compare
{
}
@@ -134,11 +135,9 @@
void
stringdiffs::BuildWordDiffList()
{
- bool m_matchblock (true); // Change to false to get word to word compare
BuildWordsArray(m_str1, &m_words1);
BuildWordsArray(m_str2, &m_words2);
- int i = 0; // Number of fixed records of word2
int start = 0;
int end = 0;
#ifdef STRINGDIFF_LOGGING
@@ -153,24 +152,24 @@
// Remove a leading whitespace
if (((int) m_words1.size() > 0) && (IsSpace(*m_words1[0])))
{
- RemoveItem1(0);
+ RemoveItem(m_words1,0);
}
if ((int)m_words1.size() > 0)
{
// Remove a ending whitespace
if (IsSpace(*m_words1[m_words1.size() - 1]))
- RemoveItem1(m_words1.size() - 1);
+ RemoveItem(m_words1,m_words1.size() - 1);
}
// Remove a leading whitespace
if (((int)m_words2.size() > 0) && (IsSpace(*m_words2[0])))
{
- RemoveItem2(0);
+ RemoveItem(m_words2,0);
}
if ((int)m_words2.size() > 0)
{
// Remove a ending whitespace
if (IsSpace(*m_words2[m_words2.size() - 1]))
- RemoveItem2(m_words2.size() - 1);
+ RemoveItem(m_words2,m_words2.size() - 1);
}
}
// Look for a match of word2 in word1
@@ -195,12 +194,12 @@
{
if (IsSpace(*m_words1[bw1]))
{
- RemoveItem1(bw1);
+ RemoveItem(m_words1,bw1);
lbreak = true;
}
if (IsSpace(*m_words2[bw2]))
{
- RemoveItem2(bw2);
+ RemoveItem(m_words2,bw2);
lbreak = true;
}
if (lbreak)
@@ -208,9 +207,9 @@
}
// Are we looking for a spacebreak, so just look for word->bBreak
if (IsSpace(*m_words2[bw2]))
- w1 = FindNextSpaceInWords1(bw1);
+ w1 = FindNextSpaceInWords(m_words1, bw1);
else
- w1 = FindNextMatchInWords1(*m_words2[bw2], bw1);
+ w1 = FindNextMatchInWords(m_words1, *m_words2[bw2], bw1,1);
// Found at same position, so go on with next word
if (w1 == bw1)
{
@@ -224,9 +223,9 @@
{
// Are we looking for a spacebreak, so just look for word->bBreak
if (IsSpace(*m_words1[bw1]))
- w2 = FindNextSpaceInWords2(bw2);
+ w2 = FindNextSpaceInWords(m_words2, bw2);
else
- w2 = FindNextMatchInWords2(*m_words1[bw1], bw2);
+ w2 = FindNextMatchInWords(m_words2,*m_words1[bw1], bw2, 2);
// Execption both are not found in other string
// so all between keep as a differ
if (w1 == -1 && w2 == -1)
@@ -245,8 +244,8 @@
m_words2[bw2]->end = m_words2[bw2 + 2]->end;
m_words2[bw1]->hash = m_words1[bw1]->hash;
// Now remove the detected blocks on side2.
- RemoveItem2(bw2 + 1);
- RemoveItem2(bw2 + 1);
+ RemoveItem(m_words2,bw2 + 1);
+ RemoveItem(m_words2,bw2 + 1);
bw1++;
bw2++;
continue;
@@ -265,8 +264,8 @@
m_words1[bw1]->end = m_words1[bw1 + 2]->end;
m_words1[bw1]->hash = m_words2[bw1]->hash;
// Now remove the detected blocks on side2.
- RemoveItem1(bw1 + 1);
- RemoveItem1(bw1 + 1);
+ RemoveItem(m_words1,bw1 + 1);
+ RemoveItem(m_words1,bw1 + 1);
bw1++;
bw2++;
continue;
@@ -312,7 +311,8 @@
}
// distance from word1 to word2 is too far away on both side
// or too far away and not found on the other side
- const int maxDistance = 4;
+ const int maxDistance = 6;
+ const bool ok = (w2 - bw2 > maxDistance);
if (((w1 - bw1 > maxDistance) && (w2 - bw2 > maxDistance))
|| ((w1 - bw1 > maxDistance) && (w2 == -1))
|| ((w2 - bw2 > maxDistance) && (w1 == -1)))
@@ -383,7 +383,6 @@
{
if ((int)m_words1.size() != (int)m_words2.size())
{
- i = 0;
int length1 = (int)m_words1.size() - 1;
int length2 = (int)m_words2.size() - 1;
@@ -436,10 +435,10 @@
bw2 = (int)m_words2.size() - 1; // start position in m_words2
if (m_matchblock && bw1 > 0 && bw2 > 0)
{
- while (bw1 > 0 && bw2 > 0)
+ while (bw1 > 1 && bw2 > 1)
{
if (AreWordsSame(*m_words1[bw1], *m_words2[bw2])
- || IsSpace(*m_words1[bw1]) || IsSpace(*m_words2[bw2]))
+ || (IsSpace(*m_words1[bw1]) && IsSpace(*m_words2[bw2])))
{
bw1--;
bw2--;
@@ -450,9 +449,9 @@
// Normaly we synchronise with a *word2 to a match in word1
// If it is an Insert in word2 so look for a *word1 in word2
if (IsInsert(*m_words2[bw2]))
- w2 = FindPreMatchInWords2(*m_words1[bw1], bw2);
+ w2 = FindPreMatchInWords(m_words2, *m_words1[bw1], bw2,2);
else
- w1 = FindPreMatchInWords1(*m_words2[bw2], bw1);
+ w1 = FindPreMatchInWords(m_words1, *m_words2[bw2], bw1,1);
// check all between are inserts
// if so, so exchange the position
if (w1 >= 0)
@@ -468,22 +467,22 @@
// all are inserts so k==0
if ((k - l) == 0)
{
- word *wd = new word(m_words1[w1]->start, m_words1[w1]->end, m_words1[w1]->bBreak, m_words1[w1]->hash);
- RemoveItem1(w1);
- vector<word*>::iterator iter = m_words1.begin() + bw1;
- m_words1.insert(iter, wd);
- // Correct the start-end pointer
- const int istart = m_words1[bw1]->start;
- const int iend =istart - 1;
+ MoveInWordsUp(m_words1, w1, bw1);
bw1--;
bw2--;
- for (l = 0; l < k ; l++)
- {
- m_words1[bw1 - l]->start = istart;
- m_words1[bw1 - l]->end = iend;
- }
continue;
}
+ else if (((k - l) == 1) && !AreWordsSame(*m_words1[bw1-l], *m_words2[bw2-l]))
+ {
+ MoveInWordsUp(m_words1, bw2-l, bw1);
+ MoveInWordsUp(m_words1, w1, bw1-1);
+ //insert a record before in words1 , after in words2
+ InsertInWords(m_words2, bw2);
+ InsertInWords(m_words1, w1);
+ bw1--;
+ bw2--;
+ continue;
+ }
}
if (w2 >= 0)
{
@@ -498,34 +497,124 @@
// all are inserts so k==0
if ((k - l) == 0)
{
- word *wd = new word(m_words2[w2]->start, m_words2[w2]->end, m_words2[w2]->bBreak, m_words2[w2]->hash);
- RemoveItem2(w2);
- vector<word*>::iterator iter = m_words2.begin() + bw2;
- m_words2.insert(iter, wd);
- // Correct the start-end pointer
- const int istart = m_words2[bw1]->start;
- const int iend = istart - 1;
+ MoveInWordsUp(m_words2, w2, bw2);
bw1--;
bw2--;
- for (l = 0; l < k ; l++)
+ continue;
+ }
+ else if (((k - l) == 1) && !AreWordsSame(*m_words1[bw1-l], *m_words2[bw2-l]))
+ {
+ MoveInWordsUp(m_words2, bw1-l, bw2);
+ MoveInWordsUp(m_words2, w2, bw2-1);
+ //insert a record before in words2 , after in words1
+ InsertInWords(m_words1, bw1);
+ InsertInWords(m_words2, w2);
+ bw1--;
+ bw2--;
+ continue;
+ }
+ }
+ // otherwise go on
+ // check for an insert on both side
+ // if so move next preblock to this position
+ if (IsInsert(*m_words1[bw1]))
+ {
+ int k = FindPreNoInsertInWords(m_words1,bw1);
+ if (k == 1)
+ {
+ bw1--;
+ bw2--;
+ continue;
+ }
+ bool ok =false;
+ if (k >=0 )
+ {
+ if (k > 0)
{
- m_words2[bw2 - l]->start = istart;
- m_words2[bw2 - l]->end = iend;
+ ok = !(AreWordsSame(*m_words1[k], *m_words2[k]) &&
+ AreWordsSame(*m_words1[k - 1], *m_words2[k - 1]));
}
+ else
+ ok = !(AreWordsSame(*m_words1[k], *m_words2[k]));
+ }
+ if(ok)
+ {
+ MoveInWordsUp(m_words1, k, bw1);
+ }
+ }
+ if (IsInsert(*m_words2[bw2]))
+ {
+ int k = FindPreNoInsertInWords(m_words2,bw2);
+ if (k == 1)
+ {
+ bw1--;
+ bw2--;
continue;
}
+ bool ok =false;
+ if (k >=0 )
+ {
+ if (k > 0)
+ ok = !(AreWordsSame(*m_words1[k], *m_words2[k]) &&
+ AreWordsSame(*m_words1[k - 1], *m_words2[k - 1]));
+ else
+ ok = !(AreWordsSame(*m_words1[k], *m_words2[k]));
+ }
+ if(ok) {
+ MoveInWordsUp(m_words2, k, bw2);
+ }
}
- // otherwise go on
bw1--;
bw2--;
continue;
}
}
+// I care about consistency and I think most apps will highlight the space
+// after the word so that would be my preference.
+// to get this we need a thirt run, only look for inserts now!
+ w1 = 0, w2 = 0; // position found in array
+ bw1 = 0; // start position in m_words1
+ bw2 = 0; // start position in m_words2
+ while (w1 >= 0 || w2 >= 0)
+ {
+ w1 = FindNextInsertInWords(m_words1,bw1);
+ w2 = FindNextInsertInWords(m_words2,bw2);
+ if (w1 == w2)
+ {
+ bw1++;
+ bw2++;
+ }
+ // word1 is first
+ else if(w1 >= 0 && (w1 < w2 || w2 == -1))
+ {
+ bw1 = FindNextNoInsertInWords(m_words1,w1);
+
+ if (bw1 >=0 && !AreWordsSame(*m_words1[bw1], *m_words2[bw1]))
+ {
+ // Move block to actual position
+ MoveInWordsDown(m_words1, bw1, w1);
+ }
+ bw1 = ++w1;
+ bw2 = bw1;
+ }
+ else if(w2 >= 0 && (w2 < w1 || w1 == -1))
+ {
+ bw2 = FindNextNoInsertInWords(m_words2,w2);
+ if (bw2 >=0 && !AreWordsSame(*m_words1[bw2], *m_words2[bw2]))
+ {
+ // Move block to actual position
+ MoveInWordsDown(m_words2, bw2, w2);
+ }
+ bw1 = ++w2;
+ bw2 = bw1;
+ }
+ }
+
// Remove empty records on both side
#ifdef STRINGDIFF_LOGGING
OutputDebugString(_T("remove empty records on both side \n"));
#endif
- i = 0;
+ int i = 0;
while ((i < (int)m_words1.size()) && (i < (int)m_words2.size()))
{
#ifdef STRINGDIFF_LOGGING
@@ -536,8 +625,8 @@
if (IsInsert(*m_words1[i]) && AreWordsSame(*m_words1[i], *m_words2[i]))
{
- RemoveItem1(i);
- RemoveItem2(i);
+ RemoveItem(m_words1,i);
+ RemoveItem(m_words2,i);
continue;
}
i++;
@@ -550,14 +639,14 @@
{
if (IsInsert(*m_words1[i]) && IsInsert(*m_words2[i + 1]))
{
- RemoveItem1(i);
- RemoveItem2(i + 1);
+ RemoveItem(m_words1,i);
+ RemoveItem(m_words2,i + 1);
continue;
}
if (IsInsert(*m_words1[i + 1]) && IsInsert(*m_words2[i]))
{
- RemoveItem1(i + 1);
- RemoveItem2(i);
+ RemoveItem(m_words1,i + 1);
+ RemoveItem(m_words2,i);
continue;
}
i++;
@@ -570,8 +659,8 @@
{
if (AreWordsSame(*m_words1[i], *m_words2[i]))
{
- RemoveItem1(i);
- RemoveItem2(i);
+ RemoveItem(m_words1,i);
+ RemoveItem(m_words2,i);
continue;
}
i++;
@@ -586,8 +675,8 @@
{
if (IsSpace(*m_words1[i]) && IsSpace(*m_words2[i]) )
{
- RemoveItem1(i);
- RemoveItem2(i);
+ RemoveItem(m_words1,i);
+ RemoveItem(m_words2,i);
continue;
}
i++;
@@ -605,8 +694,8 @@
if ((m_words2[i]->end +1 ) == (m_words2[i + 1]->start))
{
m_words2[i]->end = m_words2[i + 1]->end;
- RemoveItem1(i + 1);
- RemoveItem2(i + 1);
+ RemoveItem(m_words1,i + 1);
+ RemoveItem(m_words2,i + 1);
continue;
}
}
@@ -621,8 +710,8 @@
if ((m_words1[i]->end +1 ) == (m_words1[i + 1]->start))
{
m_words1[i]->end = m_words1[i + 1]->end;
- RemoveItem1(i + 1);
- RemoveItem2(i + 1);
+ RemoveItem(m_words1,i + 1);
+ RemoveItem(m_words2,i + 1);
continue;
}
}
@@ -711,149 +800,205 @@
}
}
}
+/**
+ * @brief Insert a new block in words)
+ */
+void
+stringdiffs::InsertInWords(std::vector<word*> &words, int bw)
+{
+ // Remember last start end
+ int end, start;
+ if (bw)
+ {
+ end = words[bw - 1]->end;
+ }
+ else
+ {
+ end = -1;
+ }
+ start = end + 1;
+ vector<word*>::iterator iter = words.begin() + bw;
+ word *wd = new word(start, end, dlinsert, 0);
+ words.insert(iter, wd);
+}
/**
- * @brief Find pre word in m_words1 (starting at bw1) that matches needword2 (in m_words2)
+ * @brief Find pre word in m_words2 (starting at bw2) that matches needword1 (in m_words1)
*/
int
-stringdiffs::FindPreMatchInWords1(const word & needword2, int bw1) const
+stringdiffs::FindPreMatchInWords(std::vector<word*> words, const word & needword, int bw, int side) const
{
- while (bw1 >= 0)
+ while (bw >= 0)
{
- if (AreWordsSame(*m_words1[bw1], needword2))
- return bw1;
- --bw1;
+ if (side == 1)
+ {
+ if (AreWordsSame(*words[bw], needword))
+ return bw;
+ }
+ else
+ {
+ if (AreWordsSame(needword, *words[bw]))
+ return bw;
+ } --bw;
}
return -1;
}
/**
- * @brief Find next word in m_words1 (starting at bw1) that matches needword2 (in m_words2)
+ * @brief Find next word in words (starting at bw) that matches needword1 (in m_words1)
*/
int
-stringdiffs::FindNextMatchInWords1(const word & needword2, int bw1) const
+stringdiffs::FindNextMatchInWords(std::vector<word*> words, const word & needword, int bw, int side) const
{
- const int iSize = (int) m_words1.size();
- while (bw1 < iSize)
+ const int iSize = (int) words.size();
+ while (bw < iSize)
{
- if (AreWordsSame(*m_words1[bw1], needword2))
- return bw1;
- ++bw1;
+ if (side == 1)
+ {
+ if (AreWordsSame(*words[bw], needword))
+ return bw;
+ }
+ else
+ {
+ if (AreWordsSame(needword, *words[bw]))
+ return bw;
+ }
+ ++bw;
}
return -1;
}
-
/**
- * @brief Find pre word in m_words2 (starting at bw2) that matches needword1 (in m_words1)
+ * @brief Find pre space in m_words (starting at bw)
*/
int
-stringdiffs::FindPreMatchInWords2(const word & needword1, int bw2) const
+stringdiffs::FindPreSpaceInWords(std::vector<word*> words, int bw) const
{
- while (bw2 >= 0)
+ while (bw >= 0)
{
- if (AreWordsSame(needword1, *m_words2[bw2]))
- return bw2;
- --bw2;
+ if (IsSpace(*words[bw]))
+ return bw;
+ --bw;
}
return -1;
}
+
/**
- * @brief Find next word in m_words2 (starting at bw2) that matches needword1 (in m_words1)
+ * @brief Find next space in m_words (starting at bw)
*/
int
-stringdiffs::FindNextMatchInWords2(const word & needword1, int bw2) const
+stringdiffs::FindNextSpaceInWords(std::vector<word*> words, int bw) const
{
- const int iSize = (int) m_words2.size();
- while (bw2 < iSize)
+ const int iSize = (int) words.size();
+ while (bw < iSize)
{
- if (AreWordsSame(needword1, *m_words2[bw2]))
- return bw2;
- ++bw2;
+ if (IsSpace(*words[bw]))
+ return bw;
+ ++bw;
}
return -1;
}
/**
- * @brief Find pre space in m_words1 (starting at bw1)
+ * @brief Find next pre noinsert in words (starting at bw)
*/
int
-stringdiffs::FindPreSpaceInWords1(int bw1) const
+stringdiffs::FindPreNoInsertInWords(std::vector<word*> words, int bw) const
{
- while (bw1 >= 0)
+ while (bw >= 0)
{
- if (IsSpace(*m_words1[bw1]))
- return bw1;
- --bw1;
+ if (!IsInsert(*words[bw]))
+ return bw;
+ --bw;
}
return -1;
}
-
/**
- * @brief Find next space in m_words1 (starting at bw1)
+ * @brief Find next insert in m_words (starting at bw)
*/
int
-stringdiffs::FindNextSpaceInWords1(int bw1) const
+stringdiffs::FindNextInsertInWords(std::vector<word*> words, int bw) const
{
- const int iSize = (int) m_words1.size();
- while (bw1 < iSize)
+ const int iSize = (int) words.size();
+ while (bw < iSize)
{
- if (IsSpace(*m_words1[bw1]))
- return bw1;
- ++bw1;
+ if (IsInsert(*words[bw]))
+ return bw;
+ ++bw;
}
return -1;
}
/**
- * @brief Find next space in m_words2 (starting at bw2)
+ * @brief Find next noinsert in m_words (starting at bw)
*/
int
-stringdiffs::FindNextSpaceInWords2(int bw2) const
+stringdiffs::FindNextNoInsertInWords(std::vector<word*> words, int bw) const
{
- const int iSize = (int) m_words2.size();
- while (bw2 < iSize)
+ const int iSize = (int) words.size();
+ while (bw < iSize)
{
- if (IsSpace(*m_words2[bw2]))
- return bw2;
- ++bw2;
+ if (!IsInsert(*words[bw]))
+ return bw;
+ ++bw;
}
return -1;
}
/**
- * @brief erase an item in m_words1
+ * @brief Move word to new position (starting at bw)
*/
-bool
-stringdiffs::RemoveItem1(int bw1)
+void
+stringdiffs::MoveInWordsUp(std::vector<word*> &words, int source, int target) const
{
- if ((int)m_words1.size()== bw1 + 1)
+ word *wd = new word(words[source]->start, words[source]->end, words[source]->bBreak, words[source]->hash);
+ RemoveItem(words, source);
+ vector<word*>::iterator iter = words.begin() + target;
+ words.insert(iter, wd);
+ // Correct the start-end pointer
+ const int istart = words[target]->start;
+ const int iend =istart - 1;
+ for (; source < target ; source++)
{
- delete m_words1.back();
- m_words1.pop_back();
+ words[source]->start = istart;
+ words[source]->end = iend;
}
- else
+}
+/**
+ * @brief Move word to new position (starting at bw)
+ */
+void
+stringdiffs::MoveInWordsDown(std::vector<word*> &words, int source, int target) const
+{
+ word *wd = new word(words[source]->start, words[source]->end, words[source]->bBreak, words[source]->hash);
+ RemoveItem(words, source);
+ vector<word*>::iterator iter = words.begin() + target;
+ words.insert(iter, wd);
+ // Correct the start-end pointer
+ const int istart = words[target]->end + 1;
+ const int iend =istart - 1;
+ target++;
+ for (; target < source + 1; target++)
{
- vector<word*>::iterator iter = m_words1.begin() + bw1 ;
- delete *iter;
- *m_words1.erase(iter);
+ words[target]->start = istart;
+ words[target]->end = iend;
}
- return true;
}
/**
- * @brief erase an item in m_words2
+ * @brief erase an item in words
*/
bool
-stringdiffs::RemoveItem2(int bw1)
+stringdiffs::RemoveItem(std::vector<word*> &words,int bw) const
{
- if ((int)m_words2.size()== bw1 + 1)
+ if ((int)words.size()== bw + 1)
{
- delete m_words2.back();
- m_words2.pop_back();
+ delete words.back();
+ words.pop_back();
}
else
{
- vector<word*>::iterator iter = m_words2.begin() + bw1 ;
+ vector<word*>::iterator iter = words.begin() + bw ;
delete *iter;
- *m_words2.erase(iter);
+ *words.erase(iter);
}
return true;
}
+
/**
* @brief Break line into constituent words
*/
@@ -1565,8 +1710,6 @@
const String& str2, bool casitive, int xwhite)
{
bool bRepeat = true;
- int iLen1 = 0;
- int iLen2 = 0;
String str1_2, str2_2;
int s1 = 0,e1 = 0,s2 = 0,e2 = 0;
Modified: trunk/Src/stringdiffsi.h
===================================================================
--- trunk/Src/stringdiffsi.h 2010-07-03 13:02:59 UTC (rev 7219)
+++ trunk/Src/stringdiffsi.h 2010-07-04 09:57:53 UTC (rev 7220)
@@ -64,13 +64,16 @@
private:
void BuildWordsArray(const String & str, std::vector<word*> * words);
- int FindPreMatchInWords1(const word & needword2, int bw1) const;
- int FindNextMatchInWords1(const word & needword2, int bw1) const;
- int FindPreMatchInWords2(const word & needword1, int bw2) const;
- int FindNextMatchInWords2(const word & needword1, int bw2) const;
- int FindPreSpaceInWords1(int bw1) const;
- int FindNextSpaceInWords1(int bw1) const;
- int FindNextSpaceInWords2(int bw2) const;
+ void InsertInWords(std::vector<word*> &words, int bw);
+ int FindPreMatchInWords(std::vector<word*> words,const word & needword, int bw, int side) const;
+ int FindNextMatchInWords(std::vector<word*> words,const word & needword, int bw, int side) const;
+ int FindPreSpaceInWords(std::vector<word*> words, int bw) const;
+ int FindNextSpaceInWords(std::vector<word*> words, int bw) const;
+ int FindPreNoInsertInWords(std::vector<word*> words, int bw) const;
+ int FindNextInsertInWords(std::vector<word*> words, int bw) const;
+ int FindNextNoInsertInWords(std::vector<word*> words, int bw) const;
+ void MoveInWordsUp(std::vector<word*> &words, int source, int target) const;
+ void MoveInWordsDown(std::vector<word*> &words, int source, int target) const;
UINT Hash(const String & str, int begin, int end, UINT h ) const;
bool AreWordsSame(const word & word1, const word & word2) const;
bool IsWord(const word & word1) const;
@@ -78,10 +81,8 @@
bool IsBreak(const word & word1) const;
bool IsInsert(const word & word1) const;
bool caseMatch(TCHAR ch1, TCHAR ch2) const;
- bool RemoveItem1(int bw1);
- bool RemoveItem2(int bw1);
+ bool RemoveItem(std::vector<word*> &words, int bw) const;
-
// Implementation data
private:
const String & m_str1;
Modified: trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_adds.cpp
===================================================================
--- trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_adds.cpp 2010-07-03 13:02:59 UTC (rev 7219)
+++ trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_adds.cpp 2010-07-04 09:57:53 UTC (rev 7220)
@@ -255,10 +255,10 @@
EXPECT_EQ(3, pDiff->end[0]);
EXPECT_EQ(3, pDiff->end[1]);
pDiff = diffs[1];
- EXPECT_EQ(9, pDiff->start[0]);
- EXPECT_EQ(9, pDiff->start[1]);
- EXPECT_EQ(8, pDiff->end[0]);
- EXPECT_EQ(9, pDiff->end[1]);
+ EXPECT_EQ(8, pDiff->start[0]);
+ EXPECT_EQ(8, pDiff->start[1]);
+ EXPECT_EQ(7, pDiff->end[0]);
+ EXPECT_EQ(8, pDiff->end[1]);
pDiff = diffs[2];
EXPECT_EQ(30, pDiff->start[0]);
EXPECT_EQ(33, pDiff->start[1]);
@@ -288,10 +288,10 @@
EXPECT_EQ(3, pDiff->end[0]);
EXPECT_EQ(3, pDiff->end[1]);
pDiff = diffs[1];
- EXPECT_EQ(9, pDiff->start[0]);
- EXPECT_EQ(9, pDiff->start[1]);
- EXPECT_EQ(9, pDiff->end[0]);
- EXPECT_EQ(8, pDiff->end[1]);
+ EXPECT_EQ(8, pDiff->start[0]);
+ EXPECT_EQ(8, pDiff->start[1]);
+ EXPECT_EQ(8, pDiff->end[0]);
+ EXPECT_EQ(7, pDiff->end[1]);
pDiff = diffs[2];
EXPECT_EQ(33, pDiff->start[0]);
EXPECT_EQ(30, pDiff->start[1]);
@@ -304,5 +304,39 @@
EXPECT_EQ(34, pDiff->end[1]);
}
}
-
+ // new option third run
+ TEST_F(StringDiffsAddsTest, RunThird)
+ {
+ std::vector<wdiff*> diffs;
+ sd_SetBreakChars(".,;:()[]{}!@#\"$%^&*~+-=<>\'/\\|");
+ sd_ComputeWordDiffs("(sizeof *new);",
+ "sizeof(*newob));",
+ false, 1, 0, true, &diffs);
+ EXPECT_EQ(3, diffs.size());
+ wdiff *pDiff;
+ if (diffs.size() >= 1)
+ {
+ pDiff = diffs[0];
+ EXPECT_EQ(0, pDiff->start[0]);
+ EXPECT_EQ(0, pDiff->start[1]);
+ EXPECT_EQ(0, pDiff->end[0]);
+ EXPECT_EQ(-1, pDiff->end[1]);
+ }
+ if (diffs.size() >= 2)
+ {
+ pDiff = diffs[1];
+ EXPECT_EQ(7, pDiff->start[0]);
+ EXPECT_EQ(6, pDiff->start[1]);
+ EXPECT_EQ(6, pDiff->end[0]);
+ EXPECT_EQ(15, pDiff->end[1]);
+ }
+ if (diffs.size() >= 3)
+ {
+ pDiff = diffs[2];
+ EXPECT_EQ(7, pDiff->start[0]);
+ EXPECT_EQ(16, pDiff->start[1]);
+ EXPECT_EQ(13, pDiff->end[0]);
+ EXPECT_EQ(15, pDiff->end[1]);
+ }
+ }
} // namespace
Modified: trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_bugs.cpp
===================================================================
--- trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_bugs.cpp 2010-07-03 13:02:59 UTC (rev 7219)
+++ trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_bugs.cpp 2010-07-04 09:57:53 UTC (rev 7220)
@@ -104,14 +104,14 @@
sd_ComputeWordDiffs("[overlay_oid_origin, overlay_oid_target], [nil, nil]",
"[overlay_oid_origin, overlay_oid_target, origin_file_name, target_file_name], [nil, nil, \"origin.txt\", \"target.txt\"]",
false, 0, 1, true, &diffs);
- EXPECT_EQ(5, diffs.size());
+ EXPECT_EQ(6, diffs.size());
if (diffs.size() > 0)
{
wdiff *pDiff = diffs[0];
- EXPECT_EQ(39, pDiff->start[0]);
- EXPECT_EQ(21, pDiff->start[1]);
- EXPECT_EQ(39, pDiff->end[0]);
- EXPECT_EQ(20, pDiff->end[1]);
+ EXPECT_EQ(19, pDiff->start[0]);
+ EXPECT_EQ(19, pDiff->start[1]);
+ EXPECT_EQ(18, pDiff->end[0]);
+ EXPECT_EQ(81, pDiff->end[1]);
}
}
@@ -123,14 +123,14 @@
sd_ComputeWordDiffs("[overlay_oid_origin, overlay_oid_target], [nil, nil]",
"[overlay_oid_origin, overlay_oid_target, origin_file_name, target_file_name], [nil, nil, \"origin.txt\", \"target.txt\"]",
false, 0, 1, false, &diffs);
- EXPECT_EQ(4, diffs.size());
+ EXPECT_EQ(6, diffs.size());
if (diffs.size() > 0)
{
wdiff *pDiff = diffs[0];
- EXPECT_EQ(21, pDiff->start[0]);
- EXPECT_EQ(21, pDiff->start[1]);
- EXPECT_EQ(39, pDiff->end[0]);
- EXPECT_EQ(38, pDiff->end[1]);
+ EXPECT_EQ(19, pDiff->start[0]);
+ EXPECT_EQ(19, pDiff->start[1]);
+ EXPECT_EQ(18, pDiff->end[0]);
+ EXPECT_EQ(81, pDiff->end[1]);
}
}
@@ -242,10 +242,10 @@
if (diffs.size() > 0)
{
wdiff *pDiff = diffs[0];
- EXPECT_EQ(12, pDiff->start[0]);
- EXPECT_EQ(12, pDiff->start[1]);
- EXPECT_EQ(11, pDiff->end[0]);
- EXPECT_EQ(17, pDiff->end[1]);
+ EXPECT_EQ(11, pDiff->start[0]);
+ EXPECT_EQ(11, pDiff->start[1]);
+ EXPECT_EQ(10, pDiff->end[0]);
+ EXPECT_EQ(16, pDiff->end[1]);
}
}
@@ -262,10 +262,10 @@
if (diffs.size() > 0)
{
wdiff *pDiff = diffs[0];
- EXPECT_EQ(12, pDiff->start[0]);
- EXPECT_EQ(12, pDiff->start[1]);
- EXPECT_EQ(11, pDiff->end[0]);
- EXPECT_EQ(17, pDiff->end[1]);
+ EXPECT_EQ(11, pDiff->start[0]);
+ EXPECT_EQ(11, pDiff->start[1]);
+ EXPECT_EQ(10, pDiff->end[0]);
+ EXPECT_EQ(16, pDiff->end[1]);
}
}
@@ -378,10 +378,10 @@
EXPECT_EQ(30, pDiff->end[0]);
EXPECT_EQ(29, pDiff->end[1]);
pDiff = diffs[1];
- EXPECT_EQ(43, pDiff->start[0]);
- EXPECT_EQ(42, pDiff->start[1]);
- EXPECT_EQ(42, pDiff->end[0]);
- EXPECT_EQ(47, pDiff->end[1]);
+ EXPECT_EQ(42, pDiff->start[0]);
+ EXPECT_EQ(41, pDiff->start[1]);
+ EXPECT_EQ(41, pDiff->end[0]);
+ EXPECT_EQ(46, pDiff->end[1]);
}
}
@@ -408,10 +408,10 @@
if (diffs.size() > 1)
{
pDiff = diffs[1];
- EXPECT_EQ(43, pDiff->start[0]);
- EXPECT_EQ(42, pDiff->start[1]);
- EXPECT_EQ(42, pDiff->end[0]);
- EXPECT_EQ(47, pDiff->end[1]);
+ EXPECT_EQ(42, pDiff->start[0]);
+ EXPECT_EQ(41, pDiff->start[1]);
+ EXPECT_EQ(41, pDiff->end[0]);
+ EXPECT_EQ(46, pDiff->end[1]);
}
if (diffs.size() > 2)
{
@@ -436,20 +436,20 @@
if (diffs.size() > 2)
{
wdiff *pDiff = diffs[0];
- EXPECT_EQ(8, pDiff->start[0]);
- EXPECT_EQ(8, pDiff->start[1]);
- EXPECT_EQ(7, pDiff->end[0]);
- EXPECT_EQ(11, pDiff->end[1]);
+ EXPECT_EQ(7, pDiff->start[0]);
+ EXPECT_EQ(7, pDiff->start[1]);
+ EXPECT_EQ(6, pDiff->end[0]);
+ EXPECT_EQ(10, pDiff->end[1]);
pDiff = diffs[1];
+ EXPECT_EQ(27, pDiff->start[0]);
+ EXPECT_EQ(31, pDiff->start[1]);
+ EXPECT_EQ(26, pDiff->end[0]);
+ EXPECT_EQ(37, pDiff->end[1]);
+ pDiff = diffs[2];
EXPECT_EQ(28, pDiff->start[0]);
- EXPECT_EQ(32, pDiff->start[1]);
- EXPECT_EQ(30, pDiff->end[0]);
- EXPECT_EQ(34, pDiff->end[1]);
- pDiff = diffs[2];
- EXPECT_EQ(32, pDiff->start[0]);
- EXPECT_EQ(36, pDiff->start[1]);
- EXPECT_EQ(31, pDiff->end[0]);
- EXPECT_EQ(40, pDiff->end[1]);
+ EXPECT_EQ(39, pDiff->start[1]);
+ EXPECT_EQ(29, pDiff->end[0]);
+ EXPECT_EQ(38, pDiff->end[1]);
}
}
@@ -466,20 +466,20 @@
if (diffs.size() > 2)
{
wdiff *pDiff = diffs[0];
- EXPECT_EQ(8, pDiff->start[0]);
- EXPECT_EQ(8, pDiff->start[1]);
- EXPECT_EQ(7, pDiff->end[0]);
- EXPECT_EQ(11, pDiff->end[1]);
+ EXPECT_EQ(7, pDiff->start[0]);
+ EXPECT_EQ(7, pDiff->start[1]);
+ EXPECT_EQ(6, pDiff->end[0]);
+ EXPECT_EQ(10, pDiff->end[1]);
pDiff = diffs[1];
+ EXPECT_EQ(27, pDiff->start[0]);
+ EXPECT_EQ(31, pDiff->start[1]);
+ EXPECT_EQ(26, pDiff->end[0]);
+ EXPECT_EQ(37, pDiff->end[1]);
+ pDiff = diffs[2];
EXPECT_EQ(28, pDiff->start[0]);
- EXPECT_EQ(32, pDiff->start[1]);
+ EXPECT_EQ(39, pDiff->start[1]);
EXPECT_EQ(30, pDiff->end[0]);
- EXPECT_EQ(34, pDiff->end[1]);
- pDiff = diffs[2];
- EXPECT_EQ(32, pDiff->start[0]);
- EXPECT_EQ(36, pDiff->start[1]);
- EXPECT_EQ(31, pDiff->end[0]);
- EXPECT_EQ(40, pDiff->end[1]);
+ EXPECT_EQ(39, pDiff->end[1]);
}
}
Modified: trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_bytelevel.cpp
===================================================================
--- trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_bytelevel.cpp 2010-07-03 13:02:59 UTC (rev 7219)
+++ trunk/Testing/GoogleTest/StringDiffs/stringdiffs_test_bytelevel.cpp 2010-07-04 09:57:53 UTC (rev 7220)
@@ -62,7 +62,7 @@
sd_ComputeWordDiffs( " wsprintf(buf, _T(left= %s, %d,%d, right= %s, %d,%d ),",
" if (len2 < 50)",
true, 0, 1, true, &diffs);
- EXPECT_EQ(11, diffs.size());
+ EXPECT_EQ(9, diffs.size());
}
// Identical strings, case sensitivity, no whitespace, punctuations, byte-level
@@ -124,9 +124,9 @@
{
std::vector<wdiff*> diffs;
sd_SetBreakChars(".,;:()[]{}!@#\"$%^&*~+-=<>\'/\\|");
- sd_ComputeWordDiffs("/**", " // remove empty records on both side",
+ sd_ComputeWordDiffs("", " // remove empty records on both side",
true, 0, 1, true, &diffs);
- EXPECT_EQ(4, diffs.size());
+ EXPECT_EQ(1, diffs.size());
wdiff *pDiff;
if (diffs.size() >= 1 )
{
@@ -134,30 +134,6 @@
EXPECT_EQ(0, pDiff->start[0]);
EXPECT_EQ(-1, pDiff->end[0]);
EXPECT_EQ(0, pDiff->start[1]);
- EXPECT_EQ(1, pDiff->end[1]);
- }
- if (diffs.size() >=2 )
- {
- pDiff = diffs[1];
- EXPECT_EQ(1, pDiff->start[0]);
- EXPECT_EQ(1, pDiff->end[0]);
- EXPECT_EQ(3, pDiff->start[1]);
- EXPECT_EQ(3, pDiff->end[1]);
- }
- if (diffs.size() >=3 )
- {
- pDiff = diffs[2];
- EXPECT_EQ(2, pDiff->start[0]);
- EXPECT_EQ(2, pDiff->end[0]);
- EXPECT_EQ(4, pDiff->start[1]);
- EXPECT_EQ(4, pDiff->end[1]);
- }
- if (diffs.size() >=4 )
- {
- pDiff = diffs[3];
- EXPECT_EQ(3, pDiff->start[0]);
- EXPECT_EQ(2, pDiff->end[0]);
- EXPECT_EQ(5, pDiff->start[1]);
EXPECT_EQ(37, pDiff->end[1]);
}
}
@@ -175,10 +151,10 @@
if (diffs.size() >= 1 )
{
pDiff = diffs[0];
- EXPECT_EQ(15, pDiff->start[0]);
- EXPECT_EQ(18, pDiff->end[0]);
- EXPECT_EQ(15, pDiff->start[1]);
- EXPECT_EQ(14, pDiff->end[1]);
+ EXPECT_EQ(14, pDiff->start[0]);
+ EXPECT_EQ(17, pDiff->end[0]);
+ EXPECT_EQ(14, pDiff->start[1]);
+ EXPECT_EQ(13, pDiff->end[1]);
}
if (diffs.size() >=2 )
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|