1 /////////////////////////////////////////////////////////////////////////////
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 2 of the License, or (at
6 // your option) any later version.
8 // This program is distributed in the hope that it will be useful, but
9 // WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 /////////////////////////////////////////////////////////////////////////////
20 * @brief Implementation file for DiffList class
33 * @brief Swap diff sides.
35 void DIFFRANGE::swap_sides(int index1, int index2)
37 swap(begin[index1], begin[index2]);
38 swap(end[index1], end[index2]);
39 swap(blank[index1], blank[index2]);
43 * @brief Initialize DiffMap.
44 * @param [in] nlines Lines to add to the list.
46 void DiffMap::InitDiffMap(int nlines)
48 // sentry value so we can check later that we set them all
49 m_map.assign(nlines, BAD_MAP_ENTRY);
54 * @brief Default constructor, initialises difflist to 64 items.
57 : m_firstSignificant(-1)
58 , m_lastSignificant(-1)
59 , m_firstSignificantLeftMiddle(-1)
60 , m_firstSignificantLeftRight(-1)
61 , m_firstSignificantMiddleRight(-1)
62 , m_firstSignificantLeftOnly(-1)
63 , m_firstSignificantMiddleOnly(-1)
64 , m_firstSignificantRightOnly(-1)
65 , m_firstSignificantConflict(-1)
66 , m_lastSignificantLeftMiddle(-1)
67 , m_lastSignificantLeftRight(-1)
68 , m_lastSignificantMiddleRight(-1)
69 , m_lastSignificantLeftOnly(-1)
70 , m_lastSignificantMiddleOnly(-1)
71 , m_lastSignificantRightOnly(-1)
72 , m_lastSignificantConflict(-1)
74 m_diffs.reserve(64); // Reserve some initial space to avoid allocations.
78 * @brief Removes all diffs from list.
80 void DiffList::Clear()
83 m_firstSignificant = -1;
84 m_lastSignificant = -1;
85 m_firstSignificantLeftMiddle = -1;
86 m_firstSignificantLeftRight = -1;
87 m_firstSignificantMiddleRight = -1;
88 m_firstSignificantLeftOnly = -1;
89 m_firstSignificantMiddleOnly = -1;
90 m_firstSignificantRightOnly = -1;
91 m_firstSignificantConflict = -1;
92 m_lastSignificantLeftMiddle = -1;
93 m_lastSignificantLeftRight = -1;
94 m_lastSignificantMiddleRight = -1;
95 m_lastSignificantLeftOnly = -1;
96 m_lastSignificantMiddleOnly = -1;
97 m_lastSignificantRightOnly = -1;
98 m_lastSignificantConflict = -1;
102 * @brief Returns count of items in diff list.
103 * This function returns total amount of items (diffs) in list. So returned
104 * count includes significant and non-significant diffs.
105 * @note Use GetSignificantDiffs() to get count of non-ignored diffs.
107 int DiffList::GetSize() const
109 return (int) m_diffs.size();
113 * @brief Returns count of significant diffs in the list.
114 * This function returns total count of significant diffs in list. So returned
115 * count doesn't include non-significant diffs.
116 * @return Count of significant differences.
118 int DiffList::GetSignificantDiffs() const
120 int nSignificants = 0;
121 const int nDiffCount = (int) m_diffs.size();
123 for (int i = 0; i < nDiffCount; i++)
125 const DIFFRANGE * dfi = DiffRangeAt(i);
126 if (dfi->op != OP_TRIVIAL)
131 return nSignificants;
135 * @brief Adds given diff to end of the list.
136 * Adds given difference to end of the list (append).
137 * @param [in] di Difference to add.
139 void DiffList::AddDiff(const DIFFRANGE & di)
141 DiffRangeInfo dri(di);
143 // Allocate memory for new items exponentially
144 if (m_diffs.size() == m_diffs.capacity())
145 m_diffs.reserve(m_diffs.size() * 2);
146 m_diffs.push_back(dri);
150 * @brief Checks if diff in given list index is significant or not.
151 * @param [in] nDiff Index of DIFFRANGE to check.
152 * @return true if diff is significant, false if not.
154 bool DiffList::IsDiffSignificant(int nDiff) const
156 const DIFFRANGE * dfi = DiffRangeAt(nDiff);
157 if (dfi->op != OP_TRIVIAL)
164 * @brief Get significant difference index of the diff.
165 * This function returns the index of diff when only significant differences
167 * @param [in] nDiff Index of difference to check.
168 * @return Significant difference index of the diff.
170 int DiffList::GetSignificantIndex(int nDiff) const
172 int significants = -1;
174 for (int i = 0; i <= nDiff; i++)
176 const DIFFRANGE * dfi = DiffRangeAt(i);
177 if (dfi->op != OP_TRIVIAL)
186 * @brief Returns copy of DIFFRANGE from diff-list.
187 * @param [in] nDiff Index of DIFFRANGE to return.
188 * @param [out] di DIFFRANGE returned (empty if error)
189 * @return true if DIFFRANGE found from given index.
191 bool DiffList::GetDiff(int nDiff, DIFFRANGE & di) const
193 const DIFFRANGE * dfi = DiffRangeAt(nDiff);
205 * @brief Return constant pointer to requested diff.
206 * This function returns constant pointer to DIFFRANGE at given index.
207 * @param [in] nDiff Index of DIFFRANGE to return.
208 * @return Constant pointer to DIFFRANGE.
210 const DIFFRANGE * DiffList::DiffRangeAt(int nDiff) const
212 if (nDiff >= 0 && nDiff < (int) m_diffs.size())
214 return &m_diffs[nDiff];
224 * @brief Replaces diff in list in given index with given diff.
225 * @param [in] nDiff Index (0-based) of diff to be replaced
226 * @param [in] di Diff to put in list.
227 * @return true if index was valid and diff put to list.
229 bool DiffList::SetDiff(int nDiff, const DIFFRANGE & di)
231 if (nDiff < (int) m_diffs.size())
233 m_diffs[nDiff] = DiffRangeInfo(di);
241 * @brief Checks if line is before, inside or after diff
242 * @param [in] nLine Linenumber to text buffer (not "real" number)
243 * @param [in] nDiff Index to diff table
244 * @return -1 if line is before diff, 0 if line is in diff and
245 * 1 if line is after diff.
247 int DiffList::LineRelDiff(int nLine, int nDiff) const
249 const DIFFRANGE * dfi = DiffRangeAt(nDiff);
250 if (static_cast<int>(nLine) < dfi->dbegin)
252 else if (static_cast<int>(nLine) > dfi->dend)
259 * @brief Checks if line is inside given diff
260 * @param [in] nLine Linenumber to text buffer (not "real" number)
261 * @param [in] nDiff Index to diff table
262 * @return true if line is inside given difference.
264 bool DiffList::LineInDiff(int nLine, int nDiff) const
266 const DIFFRANGE * dfi = DiffRangeAt(nDiff);
267 if (static_cast<int>(nLine) >= dfi->dbegin && static_cast<int>(nLine) <= dfi->dend)
274 * @brief Returns diff index for given line.
275 * @param [in] nLine Linenumber, 0-based.
276 * @return Index to diff table, -1 if line is not inside any diff.
278 int DiffList::LineToDiff(int nLine) const
280 const int nDiffCount = static_cast<int>(m_diffs.size());
284 // First check line is not before first or after last diff
285 if (nLine < DiffRangeAt(0)->dbegin)
287 if (nLine > DiffRangeAt(nDiffCount-1)->dend)
290 // Use binary search to search for a diff.
291 int left = 0; // Left limit
292 int right = nDiffCount - 1; // Right limit
294 while (left <= right)
296 int middle = (left + right) / 2; // Compared item
297 int result = LineRelDiff(nLine, middle);
300 case -1: // Line is before diff in file
303 case 0: // Line is in diff
306 case 1: // Line is after diff in file
312 s << "Invalid return value " << result << " from LineRelDiff(): -1, 0 or 1 expected!";
321 * @brief Return previous diff from given line.
322 * @param [in] nLine First line searched.
323 * @param [out] nDiff Index of diff found.
324 * @return true if line is inside diff, false otherwise.
326 bool DiffList::GetPrevDiff(int nLine, int & nDiff) const
329 int numDiff = LineToDiff(nLine);
331 // Line not inside diff
335 const int size = (int) m_diffs.size();
336 for (int i = (int) size - 1; i >= 0 ; i--)
338 if ((int)DiffRangeAt(i)->dend <= nLine)
350 * @brief Return next difference from given line.
351 * This function finds next difference from given line. If line is inside
352 * difference, that difference is returned. If next difference is not found
353 * param @p nDiff is set to -1.
354 * @param [in] nLine First line searched.
355 * @param [out] nDiff Index of diff found.
356 * @return true if line is inside diff, false otherwise.
358 bool DiffList::GetNextDiff(int nLine, int & nDiff) const
361 int numDiff = LineToDiff(nLine);
363 // Line not inside diff
367 const int nDiffCount = (int) m_diffs.size();
368 for (int i = 0; i < nDiffCount; i++)
370 if ((int)DiffRangeAt(i)->dbegin >= nLine)
382 * @brief Check if diff-list contains significant diffs.
383 * @return true if list has significant diffs, false otherwise.
385 bool DiffList::HasSignificantDiffs() const
387 if (m_firstSignificant == -1)
393 * @brief Return previous diff index from given line.
394 * @param [in] nLine First line searched.
395 * @return Index for next difference or -1 if no difference is found.
397 int DiffList::PrevSignificantDiffFromLine(int nLine) const
400 const int size = (int) m_diffs.size();
402 for (int i = size - 1; i >= 0 ; i--)
404 const DIFFRANGE * dfi = DiffRangeAt(i);
405 if (dfi->op != OP_TRIVIAL && dfi->dend <= static_cast<int>(nLine))
415 * @brief Return next diff index from given line.
416 * @param [in] nLine First line searched.
417 * @return Index for previous difference or -1 if no difference is found.
419 int DiffList::NextSignificantDiffFromLine(int nLine) const
422 const int nDiffCount = static_cast<int>(m_diffs.size());
424 for (int i = 0; i < nDiffCount; i++)
426 const DIFFRANGE * dfi = DiffRangeAt(i);
427 if (dfi->op != OP_TRIVIAL && dfi->dbegin >= static_cast<int>(nLine))
437 * @brief Construct the doubly-linked chain of significant differences
439 void DiffList::ConstructSignificantChain()
441 m_firstSignificant = -1;
442 m_lastSignificant = -1;
443 m_firstSignificantLeftMiddle = -1;
444 m_firstSignificantLeftRight = -1;
445 m_firstSignificantMiddleRight = -1;
446 m_firstSignificantConflict = -1;
447 m_lastSignificantLeftMiddle = -1;
448 m_lastSignificantLeftRight = -1;
449 m_lastSignificantMiddleRight = -1;
450 m_lastSignificantConflict = -1;
452 const ptrdiff_t size = (int) m_diffs.size();
454 // must be called after diff list is entirely populated
455 for (int i = 0; i < size; ++i)
457 if (m_diffs[i].op == OP_TRIVIAL)
459 m_diffs[i].prev = -1;
460 m_diffs[i].next = -1;
464 m_diffs[i].prev = prev;
466 m_diffs[prev].next = (size_t) i;
468 if (m_firstSignificant == -1)
469 m_firstSignificant = i;
470 m_lastSignificant = i;
471 if (m_diffs[i].op != OP_TRIVIAL && m_diffs[i].op != OP_3RDONLY)
473 if (m_firstSignificantLeftMiddle == -1)
474 m_firstSignificantLeftMiddle = i;
475 m_lastSignificantLeftMiddle = i;
477 if (m_diffs[i].op != OP_TRIVIAL && m_diffs[i].op != OP_2NDONLY)
479 if (m_firstSignificantLeftRight == -1)
480 m_firstSignificantLeftRight = i;
481 m_lastSignificantLeftRight = i;
483 if (m_diffs[i].op != OP_TRIVIAL && m_diffs[i].op != OP_1STONLY)
485 if (m_firstSignificantMiddleRight == -1)
486 m_firstSignificantMiddleRight = i;
487 m_lastSignificantMiddleRight = i;
489 if (m_diffs[i].op == OP_1STONLY)
491 if (m_firstSignificantLeftOnly == -1)
492 m_firstSignificantLeftOnly = i;
493 m_lastSignificantLeftOnly = i;
495 if (m_diffs[i].op == OP_2NDONLY)
497 if (m_firstSignificantMiddleOnly == -1)
498 m_firstSignificantMiddleOnly = i;
499 m_lastSignificantMiddleOnly = i;
501 if (m_diffs[i].op == OP_3RDONLY)
503 if (m_firstSignificantRightOnly == -1)
504 m_firstSignificantRightOnly = i;
505 m_lastSignificantRightOnly = i;
507 if (m_diffs[i].op == OP_DIFF)
509 if (m_firstSignificantConflict == -1)
510 m_firstSignificantConflict = i;
511 m_lastSignificantConflict = i;
518 * @brief Return index to first significant difference.
519 * @return Index of first significant difference.
521 int DiffList::FirstSignificantDiff() const
523 return m_firstSignificant;
527 * @brief Return index of next significant diff.
528 * @param [in] nDiff Index to start looking for next diff.
529 * @return Index of next significant difference.
531 int DiffList::NextSignificantDiff(int nDiff) const
533 return (int)m_diffs[nDiff].next;
537 * @brief Return index of previous significant diff.
538 * @param [in] nDiff Index to start looking for previous diff.
539 * @return Index of previous significant difference.
541 int DiffList::PrevSignificantDiff(int nDiff) const
543 return (int)m_diffs[nDiff].prev;
547 * @brief Return index to last significant diff.
548 * @return Index of last significant difference.
550 int DiffList::LastSignificantDiff() const
552 return m_lastSignificant;
556 * @brief Return pointer to first significant diff.
557 * @return Constant pointer to first significant difference.
559 const DIFFRANGE * DiffList::FirstSignificantDiffRange() const
561 if (m_firstSignificant == -1)
563 return DiffRangeAt(m_firstSignificant);
567 * @brief Return pointer to last significant diff.
568 * @return Constant pointer to last significant difference.
570 const DIFFRANGE * DiffList::LastSignificantDiffRange() const
572 if (m_lastSignificant == -1)
574 return DiffRangeAt(m_lastSignificant);
579 * @brief Return previous diff index from given line.
580 * @param [in] nLine First line searched.
581 * @return Index for next difference or -1 if no difference is found.
583 int DiffList::PrevSignificant3wayDiffFromLine(int nLine, int nDiffType) const
585 for (int i = static_cast<int>(m_diffs.size()) - 1; i >= 0 ; i--)
587 const DIFFRANGE * dfi = DiffRangeAt(i);
590 case THREEWAYDIFFTYPE_LEFTMIDDLE:
591 if (dfi->op != OP_TRIVIAL && dfi->op != OP_3RDONLY && dfi->dend <= static_cast<int>(nLine))
594 case THREEWAYDIFFTYPE_LEFTRIGHT:
595 if (dfi->op != OP_TRIVIAL && dfi->op != OP_2NDONLY && dfi->dend <= static_cast<int>(nLine))
598 case THREEWAYDIFFTYPE_MIDDLERIGHT:
599 if (dfi->op != OP_TRIVIAL && dfi->op != OP_1STONLY && dfi->dend <= static_cast<int>(nLine))
602 case THREEWAYDIFFTYPE_LEFTONLY:
603 if (dfi->op == OP_1STONLY && dfi->dend <= static_cast<int>(nLine))
606 case THREEWAYDIFFTYPE_MIDDLEONLY:
607 if (dfi->op == OP_2NDONLY && dfi->dend <= static_cast<int>(nLine))
610 case THREEWAYDIFFTYPE_RIGHTONLY:
611 if (dfi->op == OP_3RDONLY && dfi->dend <= static_cast<int>(nLine))
614 case THREEWAYDIFFTYPE_CONFLICT:
615 if (dfi->op == OP_DIFF && dfi->dend <= nLine)
624 * @brief Return next diff index from given line.
625 * @param [in] nLine First line searched.
626 * @return Index for previous difference or -1 if no difference is found.
628 int DiffList::NextSignificant3wayDiffFromLine(int nLine, int nDiffType) const
630 const int nDiffCount = static_cast<int>(m_diffs.size());
632 for (int i = 0; i < nDiffCount; i++)
634 const DIFFRANGE * dfi = DiffRangeAt(i);
637 case THREEWAYDIFFTYPE_LEFTMIDDLE:
638 if (dfi->op != OP_TRIVIAL && dfi->op != OP_3RDONLY && dfi->dbegin >= static_cast<int>(nLine))
641 case THREEWAYDIFFTYPE_LEFTRIGHT:
642 if (dfi->op != OP_TRIVIAL && dfi->op != OP_2NDONLY && dfi->dbegin >= static_cast<int>(nLine))
645 case THREEWAYDIFFTYPE_MIDDLERIGHT:
646 if (dfi->op != OP_TRIVIAL && dfi->op != OP_1STONLY && dfi->dbegin >= static_cast<int>(nLine))
649 case THREEWAYDIFFTYPE_LEFTONLY:
650 if (dfi->op == OP_1STONLY && dfi->dbegin >= static_cast<int>(nLine))
653 case THREEWAYDIFFTYPE_MIDDLEONLY:
654 if (dfi->op == OP_2NDONLY && dfi->dbegin >= static_cast<int>(nLine))
657 case THREEWAYDIFFTYPE_RIGHTONLY:
658 if (dfi->op == OP_3RDONLY && dfi->dbegin >= static_cast<int>(nLine))
661 case THREEWAYDIFFTYPE_CONFLICT:
662 if (dfi->op == OP_DIFF && dfi->dbegin >= nLine)
671 * @brief Return index to first significant difference.
672 * @return Index of first significant difference.
674 int DiffList::FirstSignificant3wayDiff(int nDiffType) const
678 case THREEWAYDIFFTYPE_LEFTMIDDLE:
679 return m_firstSignificantLeftMiddle;
680 case THREEWAYDIFFTYPE_LEFTRIGHT:
681 return m_firstSignificantLeftRight;
682 case THREEWAYDIFFTYPE_MIDDLERIGHT:
683 return m_firstSignificantMiddleRight;
684 case THREEWAYDIFFTYPE_LEFTONLY:
685 return m_firstSignificantLeftOnly;
686 case THREEWAYDIFFTYPE_MIDDLEONLY:
687 return m_firstSignificantLeftOnly;
688 case THREEWAYDIFFTYPE_RIGHTONLY:
689 return m_firstSignificantRightOnly;
690 case THREEWAYDIFFTYPE_CONFLICT:
691 return m_firstSignificantConflict;
697 * @brief Return index of next significant diff.
698 * @param [in] nDiff Index to start looking for next diff.
699 * @return Index of next significant difference.
701 int DiffList::NextSignificant3wayDiff(int nDiff, int nDiffType) const
703 while (m_diffs[nDiff].next != -1)
705 nDiff = static_cast<int>(m_diffs[nDiff].next);
708 case THREEWAYDIFFTYPE_LEFTMIDDLE:
709 if (m_diffs[nDiff].op != OP_3RDONLY)
712 case THREEWAYDIFFTYPE_LEFTRIGHT:
713 if (m_diffs[nDiff].op != OP_2NDONLY)
716 case THREEWAYDIFFTYPE_MIDDLERIGHT:
717 if (m_diffs[nDiff].op != OP_1STONLY)
720 case THREEWAYDIFFTYPE_LEFTONLY:
721 if (m_diffs[nDiff].op == OP_1STONLY)
724 case THREEWAYDIFFTYPE_MIDDLEONLY:
725 if (m_diffs[nDiff].op == OP_2NDONLY)
728 case THREEWAYDIFFTYPE_RIGHTONLY:
729 if (m_diffs[nDiff].op == OP_3RDONLY)
732 case THREEWAYDIFFTYPE_CONFLICT:
733 if (m_diffs[nDiff].op == OP_DIFF)
742 * @brief Return index of previous significant diff.
743 * @param [in] nDiff Index to start looking for previous diff.
744 * @return Index of previous significant difference.
746 int DiffList::PrevSignificant3wayDiff(int nDiff, int nDiffType) const
748 while (m_diffs[nDiff].prev != -1)
750 nDiff = static_cast<int>(m_diffs[nDiff].prev);
753 case THREEWAYDIFFTYPE_LEFTMIDDLE:
754 if (m_diffs[nDiff].op != OP_3RDONLY)
757 case THREEWAYDIFFTYPE_LEFTRIGHT:
758 if (m_diffs[nDiff].op != OP_2NDONLY)
761 case THREEWAYDIFFTYPE_MIDDLERIGHT:
762 if (m_diffs[nDiff].op != OP_1STONLY)
765 case THREEWAYDIFFTYPE_LEFTONLY:
766 if (m_diffs[nDiff].op == OP_1STONLY)
769 case THREEWAYDIFFTYPE_MIDDLEONLY:
770 if (m_diffs[nDiff].op == OP_2NDONLY)
773 case THREEWAYDIFFTYPE_RIGHTONLY:
774 if (m_diffs[nDiff].op == OP_3RDONLY)
777 case THREEWAYDIFFTYPE_CONFLICT:
778 if (m_diffs[nDiff].op == OP_DIFF)
787 * @brief Return index to last significant diff.
788 * @return Index of last significant difference.
790 int DiffList::LastSignificant3wayDiff(int nDiffType) const
794 case THREEWAYDIFFTYPE_LEFTMIDDLE:
795 return m_lastSignificantLeftMiddle;
796 case THREEWAYDIFFTYPE_LEFTRIGHT:
797 return m_lastSignificantLeftRight;
798 case THREEWAYDIFFTYPE_MIDDLERIGHT:
799 return m_lastSignificantMiddleRight;
800 case THREEWAYDIFFTYPE_LEFTONLY:
801 return m_lastSignificantLeftOnly;
802 case THREEWAYDIFFTYPE_MIDDLEONLY:
803 return m_lastSignificantLeftOnly;
804 case THREEWAYDIFFTYPE_RIGHTONLY:
805 return m_lastSignificantRightOnly;
806 case THREEWAYDIFFTYPE_CONFLICT:
807 return m_lastSignificantRightOnly;
813 * @brief Return pointer to first significant diff.
814 * @return Constant pointer to first significant difference.
816 const DIFFRANGE * DiffList::FirstSignificant3wayDiffRange(int nDiffType) const
820 case THREEWAYDIFFTYPE_LEFTMIDDLE:
821 if (m_firstSignificantLeftMiddle == -1) return NULL;
822 return DiffRangeAt(m_firstSignificantLeftMiddle);
823 case THREEWAYDIFFTYPE_LEFTRIGHT:
824 if (m_firstSignificantLeftRight == -1) return NULL;
825 return DiffRangeAt(m_firstSignificantLeftRight);
826 case THREEWAYDIFFTYPE_MIDDLERIGHT:
827 if (m_firstSignificantMiddleRight == -1) return NULL;
828 return DiffRangeAt(m_firstSignificantMiddleRight);
829 case THREEWAYDIFFTYPE_LEFTONLY:
830 if (m_firstSignificantLeftOnly == -1) return NULL;
831 return DiffRangeAt(m_firstSignificantLeftOnly);
832 case THREEWAYDIFFTYPE_MIDDLEONLY:
833 if (m_firstSignificantMiddleOnly == -1) return NULL;
834 return DiffRangeAt(m_firstSignificantMiddleOnly);
835 case THREEWAYDIFFTYPE_RIGHTONLY:
836 if (m_firstSignificantRightOnly == -1) return NULL;
837 return DiffRangeAt(m_firstSignificantRightOnly);
838 case THREEWAYDIFFTYPE_CONFLICT:
839 if (m_firstSignificantConflict == -1) return NULL;
840 return DiffRangeAt(m_firstSignificantConflict);
846 * @brief Return pointer to last significant diff.
847 * @return Constant pointer to last significant difference.
849 const DIFFRANGE * DiffList::LastSignificant3wayDiffRange(int nDiffType) const
853 case THREEWAYDIFFTYPE_LEFTMIDDLE:
854 if (m_lastSignificantLeftMiddle == -1) return NULL;
855 return DiffRangeAt(m_lastSignificantLeftMiddle);
856 case THREEWAYDIFFTYPE_LEFTRIGHT:
857 if (m_lastSignificantLeftRight == -1) return NULL;
858 return DiffRangeAt(m_lastSignificantLeftRight);
859 case THREEWAYDIFFTYPE_MIDDLERIGHT:
860 if (m_lastSignificantMiddleRight == -1) return NULL;
861 return DiffRangeAt(m_lastSignificantMiddleRight);
862 case THREEWAYDIFFTYPE_LEFTONLY:
863 if (m_lastSignificantLeftOnly == -1) return NULL;
864 return DiffRangeAt(m_lastSignificantLeftOnly);
865 case THREEWAYDIFFTYPE_MIDDLEONLY:
866 if (m_lastSignificantMiddleOnly == -1) return NULL;
867 return DiffRangeAt(m_lastSignificantMiddleOnly);
868 case THREEWAYDIFFTYPE_RIGHTONLY:
869 if (m_lastSignificantRightOnly == -1) return NULL;
870 return DiffRangeAt(m_lastSignificantRightOnly);
871 case THREEWAYDIFFTYPE_CONFLICT:
872 if (m_lastSignificantConflict == -1) return NULL;
873 return DiffRangeAt(m_lastSignificantConflict);
879 * @brief Swap sides of diffrange
881 void DiffList::Swap(int index1, int index2)
883 vector<DiffRangeInfo>::iterator iter = m_diffs.begin();
884 vector<DiffRangeInfo>::const_iterator iterEnd = m_diffs.end();
885 while (iter != iterEnd)
887 (*iter).swap_sides(index1, index2);
893 * @brief Count number of lines to add to sides (because of synch).
894 * @param [out] nLeftLines Number of lines to add to left side.
895 * @param [out] nRightLines Number of lines to add to right side.
897 void DiffList::GetExtraLinesCounts(int nFiles, int extras[3])
902 const int nDiffCount = GetSize();
904 for (int nDiff = 0; nDiff < nDiffCount; ++nDiff)
907 GetDiff(nDiff, curDiff);
909 // this guarantees that all the diffs are synchronized
910 assert(curDiff.begin[0]+extras[0] == curDiff.begin[1]+extras[1]);
911 assert(nFiles<3 || curDiff.begin[0]+extras[0] == curDiff.begin[2]+extras[2]);
912 int nline[3] = { 0,0,0 };
915 for (file = 0; file < nFiles; file++)
917 nline[file] = curDiff.end[file]-curDiff.begin[file]+1;
918 nmaxline = std::max(nmaxline, nline[file]);
920 for (file = 0; file < nFiles; file++)
921 extras[file] += nmaxline - nline[file];
925 void DiffList::AppendDiffList(const DiffList& list, int offset[], int doffset)
927 for (std::vector<DiffRangeInfo>::const_iterator it = list.m_diffs.begin(); it != list.m_diffs.end(); ++it)
930 for (int file = 0; file < 3; ++file)
934 dr.begin[file] += offset[file];
935 dr.end[file] += offset[file];
938 dr.blank[file] += doffset;
942 dr.dbegin += doffset;
949 int DiffList::GetMergeableSrcIndex(int nDiff, int nDestIndex) const
951 const DIFFRANGE *pdr = DiffRangeAt(nDiff);
956 if (pdr->op == OP_2NDONLY)
960 if (pdr->op == OP_1STONLY || pdr->op == OP_2NDONLY)
962 else if (pdr->op == OP_3RDONLY)