1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * @brief Implementation file for DiffList class
19 * @brief Swap diff sides.
21 void DIFFRANGE::swap_sides(int index1, int index2)
23 swap(begin[index1], begin[index2]);
24 swap(end[index1], end[index2]);
25 swap(blank[index1], blank[index2]);
29 * @brief Initialize DiffMap.
30 * @param [in] nlines Lines to add to the list.
32 void DiffMap::InitDiffMap(int nlines)
34 // sentry value so we can check later that we set them all
35 m_map.assign(nlines, BAD_MAP_ENTRY);
40 * @brief Default constructor, initialises difflist to 64 items.
43 : m_firstSignificant(-1)
44 , m_lastSignificant(-1)
45 , m_firstSignificantLeftMiddle(-1)
46 , m_firstSignificantLeftRight(-1)
47 , m_firstSignificantMiddleRight(-1)
48 , m_firstSignificantLeftOnly(-1)
49 , m_firstSignificantMiddleOnly(-1)
50 , m_firstSignificantRightOnly(-1)
51 , m_firstSignificantConflict(-1)
52 , m_lastSignificantLeftMiddle(-1)
53 , m_lastSignificantLeftRight(-1)
54 , m_lastSignificantMiddleRight(-1)
55 , m_lastSignificantLeftOnly(-1)
56 , m_lastSignificantMiddleOnly(-1)
57 , m_lastSignificantRightOnly(-1)
58 , m_lastSignificantConflict(-1)
60 m_diffs.reserve(64); // Reserve some initial space to avoid allocations.
64 * @brief Removes all diffs from list.
66 void DiffList::Clear()
69 m_firstSignificant = -1;
70 m_lastSignificant = -1;
71 m_firstSignificantLeftMiddle = -1;
72 m_firstSignificantLeftRight = -1;
73 m_firstSignificantMiddleRight = -1;
74 m_firstSignificantLeftOnly = -1;
75 m_firstSignificantMiddleOnly = -1;
76 m_firstSignificantRightOnly = -1;
77 m_firstSignificantConflict = -1;
78 m_lastSignificantLeftMiddle = -1;
79 m_lastSignificantLeftRight = -1;
80 m_lastSignificantMiddleRight = -1;
81 m_lastSignificantLeftOnly = -1;
82 m_lastSignificantMiddleOnly = -1;
83 m_lastSignificantRightOnly = -1;
84 m_lastSignificantConflict = -1;
88 * @brief Returns count of significant diffs in the list.
89 * This function returns total count of significant diffs in list. So returned
90 * count doesn't include non-significant diffs.
91 * @return Count of significant differences.
93 int DiffList::GetSignificantDiffs() const
95 int nSignificants = 0;
96 const int nDiffCount = (int) m_diffs.size();
98 for (int i = 0; i < nDiffCount; i++)
100 const DIFFRANGE * dfi = DiffRangeAt(i);
101 if (dfi->op != OP_TRIVIAL)
106 return nSignificants;
110 * @brief Adds given diff to end of the list.
111 * Adds given difference to end of the list (append).
112 * @param [in] di Difference to add.
114 void DiffList::AddDiff(const DIFFRANGE & di)
116 DiffRangeInfo dri(di);
118 // Allocate memory for new items exponentially
119 if (m_diffs.size() == m_diffs.capacity())
120 m_diffs.reserve(m_diffs.size() * 2);
121 m_diffs.push_back(dri);
125 * @brief Checks if diff in given list index is significant or not.
126 * @param [in] nDiff Index of DIFFRANGE to check.
127 * @return true if diff is significant, false if not.
129 bool DiffList::IsDiffSignificant(int nDiff) const
131 const DIFFRANGE * dfi = DiffRangeAt(nDiff);
132 if (dfi->op != OP_TRIVIAL)
139 * @brief Get significant difference index of the diff.
140 * This function returns the index of diff when only significant differences
142 * @param [in] nDiff Index of difference to check.
143 * @return Significant difference index of the diff.
145 int DiffList::GetSignificantIndex(int nDiff) const
147 int significants = -1;
149 for (int i = 0; i <= nDiff; i++)
151 const DIFFRANGE * dfi = DiffRangeAt(i);
152 if (dfi->op != OP_TRIVIAL)
161 * @brief Returns copy of DIFFRANGE from diff-list.
162 * @param [in] nDiff Index of DIFFRANGE to return.
163 * @param [out] di DIFFRANGE returned (empty if error)
164 * @return true if DIFFRANGE found from given index.
166 bool DiffList::GetDiff(int nDiff, DIFFRANGE & di) const
168 const DIFFRANGE * dfi = DiffRangeAt(nDiff);
180 * @brief Return constant pointer to requested diff.
181 * This function returns constant pointer to DIFFRANGE at given index.
182 * @param [in] nDiff Index of DIFFRANGE to return.
183 * @return Constant pointer to DIFFRANGE.
185 const DIFFRANGE * DiffList::DiffRangeAt(int nDiff) const
187 if (nDiff >= 0 && nDiff < (int) m_diffs.size())
189 return &m_diffs[nDiff];
199 * @brief Replaces diff in list in given index with given diff.
200 * @param [in] nDiff Index (0-based) of diff to be replaced
201 * @param [in] di Diff to put in list.
202 * @return true if index was valid and diff put to list.
204 bool DiffList::SetDiff(int nDiff, const DIFFRANGE & di)
206 if (nDiff < (int) m_diffs.size())
208 m_diffs[nDiff] = DiffRangeInfo(di);
216 * @brief Checks if line is before, inside or after diff
217 * @param [in] nLine Linenumber to text buffer (not "real" number)
218 * @param [in] nDiff Index to diff table
219 * @return -1 if line is before diff, 0 if line is in diff and
220 * 1 if line is after diff.
222 int DiffList::LineRelDiff(int nLine, int nDiff) const
224 const DIFFRANGE * dfi = DiffRangeAt(nDiff);
225 if (static_cast<int>(nLine) < dfi->dbegin)
227 else if (static_cast<int>(nLine) > dfi->dend)
234 * @brief Checks if line is inside given diff
235 * @param [in] nLine Linenumber to text buffer (not "real" number)
236 * @param [in] nDiff Index to diff table
237 * @return true if line is inside given difference.
239 bool DiffList::LineInDiff(int nLine, int nDiff) const
241 const DIFFRANGE * dfi = DiffRangeAt(nDiff);
242 if (static_cast<int>(nLine) >= dfi->dbegin && static_cast<int>(nLine) <= dfi->dend)
249 * @brief Returns diff index for given line.
250 * @param [in] nLine Linenumber, 0-based.
251 * @return Index to diff table, -1 if line is not inside any diff.
253 int DiffList::LineToDiff(int nLine) const
255 const int nDiffCount = static_cast<int>(m_diffs.size());
259 // First check line is not before first or after last diff
260 if (nLine < DiffRangeAt(0)->dbegin)
262 if (nLine > DiffRangeAt(nDiffCount-1)->dend)
265 // Use binary search to search for a diff.
266 int left = 0; // Left limit
267 int right = nDiffCount - 1; // Right limit
269 while (left <= right)
271 int middle = (left + right) / 2; // Compared item
272 int result = LineRelDiff(nLine, middle);
275 case -1: // Line is before diff in file
278 case 0: // Line is in diff
281 case 1: // Line is after diff in file
287 s << "Invalid return value " << result << " from LineRelDiff(): -1, 0 or 1 expected!";
296 * @brief Return previous diff from given line.
297 * @param [in] nLine First line searched.
298 * @param [out] nDiff Index of diff found.
299 * @return true if line is inside diff, false otherwise.
301 bool DiffList::GetPrevDiff(int nLine, int & nDiff) const
304 int numDiff = LineToDiff(nLine);
306 // Line not inside diff
310 const int size = (int) m_diffs.size();
311 for (int i = (int) size - 1; i >= 0 ; i--)
313 if ((int)DiffRangeAt(i)->dend <= nLine)
325 * @brief Return next difference from given line.
326 * This function finds next difference from given line. If line is inside
327 * difference, that difference is returned. If next difference is not found
328 * param @p nDiff is set to -1.
329 * @param [in] nLine First line searched.
330 * @param [out] nDiff Index of diff found.
331 * @return true if line is inside diff, false otherwise.
333 bool DiffList::GetNextDiff(int nLine, int & nDiff) const
336 int numDiff = LineToDiff(nLine);
338 // Line not inside diff
342 const int nDiffCount = (int) m_diffs.size();
343 for (int i = 0; i < nDiffCount; i++)
345 if ((int)DiffRangeAt(i)->dbegin >= nLine)
357 * @brief Return previous diff index from given line.
358 * @param [in] nLine First line searched.
359 * @return Index for next difference or -1 if no difference is found.
361 int DiffList::PrevSignificantDiffFromLine(int nLine) const
364 const int size = (int) m_diffs.size();
366 for (int i = size - 1; i >= 0 ; i--)
368 const DIFFRANGE * dfi = DiffRangeAt(i);
369 if (dfi->op != OP_TRIVIAL && dfi->dend <= static_cast<int>(nLine))
379 * @brief Return next diff index from given line.
380 * @param [in] nLine First line searched.
381 * @return Index for previous difference or -1 if no difference is found.
383 int DiffList::NextSignificantDiffFromLine(int nLine) const
386 const int nDiffCount = static_cast<int>(m_diffs.size());
388 for (int i = 0; i < nDiffCount; i++)
390 const DIFFRANGE * dfi = DiffRangeAt(i);
391 if (dfi->op != OP_TRIVIAL && dfi->dbegin >= static_cast<int>(nLine))
401 * @brief Construct the doubly-linked chain of significant differences
403 void DiffList::ConstructSignificantChain()
405 m_firstSignificant = -1;
406 m_lastSignificant = -1;
407 m_firstSignificantLeftMiddle = -1;
408 m_firstSignificantLeftRight = -1;
409 m_firstSignificantMiddleRight = -1;
410 m_firstSignificantConflict = -1;
411 m_lastSignificantLeftMiddle = -1;
412 m_lastSignificantLeftRight = -1;
413 m_lastSignificantMiddleRight = -1;
414 m_lastSignificantConflict = -1;
416 const ptrdiff_t size = (int) m_diffs.size();
418 // must be called after diff list is entirely populated
419 for (int i = 0; i < size; ++i)
421 if (m_diffs[i].op == OP_TRIVIAL)
423 m_diffs[i].prev = -1;
424 m_diffs[i].next = -1;
428 m_diffs[i].prev = prev;
430 m_diffs[prev].next = (size_t) i;
432 if (m_firstSignificant == -1)
433 m_firstSignificant = i;
434 m_lastSignificant = i;
435 if (m_diffs[i].op != OP_TRIVIAL && m_diffs[i].op != OP_3RDONLY)
437 if (m_firstSignificantLeftMiddle == -1)
438 m_firstSignificantLeftMiddle = i;
439 m_lastSignificantLeftMiddle = i;
441 if (m_diffs[i].op != OP_TRIVIAL && m_diffs[i].op != OP_2NDONLY)
443 if (m_firstSignificantLeftRight == -1)
444 m_firstSignificantLeftRight = i;
445 m_lastSignificantLeftRight = i;
447 if (m_diffs[i].op != OP_TRIVIAL && m_diffs[i].op != OP_1STONLY)
449 if (m_firstSignificantMiddleRight == -1)
450 m_firstSignificantMiddleRight = i;
451 m_lastSignificantMiddleRight = i;
453 if (m_diffs[i].op == OP_1STONLY)
455 if (m_firstSignificantLeftOnly == -1)
456 m_firstSignificantLeftOnly = i;
457 m_lastSignificantLeftOnly = i;
459 if (m_diffs[i].op == OP_2NDONLY)
461 if (m_firstSignificantMiddleOnly == -1)
462 m_firstSignificantMiddleOnly = i;
463 m_lastSignificantMiddleOnly = i;
465 if (m_diffs[i].op == OP_3RDONLY)
467 if (m_firstSignificantRightOnly == -1)
468 m_firstSignificantRightOnly = i;
469 m_lastSignificantRightOnly = i;
471 if (m_diffs[i].op == OP_DIFF)
473 if (m_firstSignificantConflict == -1)
474 m_firstSignificantConflict = i;
475 m_lastSignificantConflict = i;
483 * @brief Return pointer to first significant diff.
484 * @return Constant pointer to first significant difference.
486 const DIFFRANGE * DiffList::FirstSignificantDiffRange() const
488 if (m_firstSignificant == -1)
490 return DiffRangeAt(m_firstSignificant);
494 * @brief Return pointer to last significant diff.
495 * @return Constant pointer to last significant difference.
497 const DIFFRANGE * DiffList::LastSignificantDiffRange() const
499 if (m_lastSignificant == -1)
501 return DiffRangeAt(m_lastSignificant);
506 * @brief Return previous diff index from given line.
507 * @param [in] nLine First line searched.
508 * @return Index for next difference or -1 if no difference is found.
510 int DiffList::PrevSignificant3wayDiffFromLine(int nLine, int nDiffType) const
512 for (int i = static_cast<int>(m_diffs.size()) - 1; i >= 0 ; i--)
514 const DIFFRANGE * dfi = DiffRangeAt(i);
517 case THREEWAYDIFFTYPE_LEFTMIDDLE:
518 if (dfi->op != OP_TRIVIAL && dfi->op != OP_3RDONLY && dfi->dend <= static_cast<int>(nLine))
521 case THREEWAYDIFFTYPE_LEFTRIGHT:
522 if (dfi->op != OP_TRIVIAL && dfi->op != OP_2NDONLY && dfi->dend <= static_cast<int>(nLine))
525 case THREEWAYDIFFTYPE_MIDDLERIGHT:
526 if (dfi->op != OP_TRIVIAL && dfi->op != OP_1STONLY && dfi->dend <= static_cast<int>(nLine))
529 case THREEWAYDIFFTYPE_LEFTONLY:
530 if (dfi->op == OP_1STONLY && dfi->dend <= static_cast<int>(nLine))
533 case THREEWAYDIFFTYPE_MIDDLEONLY:
534 if (dfi->op == OP_2NDONLY && dfi->dend <= static_cast<int>(nLine))
537 case THREEWAYDIFFTYPE_RIGHTONLY:
538 if (dfi->op == OP_3RDONLY && dfi->dend <= static_cast<int>(nLine))
541 case THREEWAYDIFFTYPE_CONFLICT:
542 if (dfi->op == OP_DIFF && dfi->dend <= nLine)
551 * @brief Return next diff index from given line.
552 * @param [in] nLine First line searched.
553 * @return Index for previous difference or -1 if no difference is found.
555 int DiffList::NextSignificant3wayDiffFromLine(int nLine, int nDiffType) const
557 const int nDiffCount = static_cast<int>(m_diffs.size());
559 for (int i = 0; i < nDiffCount; i++)
561 const DIFFRANGE * dfi = DiffRangeAt(i);
564 case THREEWAYDIFFTYPE_LEFTMIDDLE:
565 if (dfi->op != OP_TRIVIAL && dfi->op != OP_3RDONLY && dfi->dbegin >= static_cast<int>(nLine))
568 case THREEWAYDIFFTYPE_LEFTRIGHT:
569 if (dfi->op != OP_TRIVIAL && dfi->op != OP_2NDONLY && dfi->dbegin >= static_cast<int>(nLine))
572 case THREEWAYDIFFTYPE_MIDDLERIGHT:
573 if (dfi->op != OP_TRIVIAL && dfi->op != OP_1STONLY && dfi->dbegin >= static_cast<int>(nLine))
576 case THREEWAYDIFFTYPE_LEFTONLY:
577 if (dfi->op == OP_1STONLY && dfi->dbegin >= static_cast<int>(nLine))
580 case THREEWAYDIFFTYPE_MIDDLEONLY:
581 if (dfi->op == OP_2NDONLY && dfi->dbegin >= static_cast<int>(nLine))
584 case THREEWAYDIFFTYPE_RIGHTONLY:
585 if (dfi->op == OP_3RDONLY && dfi->dbegin >= static_cast<int>(nLine))
588 case THREEWAYDIFFTYPE_CONFLICT:
589 if (dfi->op == OP_DIFF && dfi->dbegin >= nLine)
598 * @brief Return index to first significant difference.
599 * @return Index of first significant difference.
601 int DiffList::FirstSignificant3wayDiff(int nDiffType) const
605 case THREEWAYDIFFTYPE_LEFTMIDDLE:
606 return m_firstSignificantLeftMiddle;
607 case THREEWAYDIFFTYPE_LEFTRIGHT:
608 return m_firstSignificantLeftRight;
609 case THREEWAYDIFFTYPE_MIDDLERIGHT:
610 return m_firstSignificantMiddleRight;
611 case THREEWAYDIFFTYPE_LEFTONLY:
612 return m_firstSignificantLeftOnly;
613 case THREEWAYDIFFTYPE_MIDDLEONLY:
614 return m_firstSignificantLeftOnly;
615 case THREEWAYDIFFTYPE_RIGHTONLY:
616 return m_firstSignificantRightOnly;
617 case THREEWAYDIFFTYPE_CONFLICT:
618 return m_firstSignificantConflict;
624 * @brief Return index of next significant diff.
625 * @param [in] nDiff Index to start looking for next diff.
626 * @return Index of next significant difference.
628 int DiffList::NextSignificant3wayDiff(int nDiff, int nDiffType) const
630 while (m_diffs[nDiff].next != -1)
632 nDiff = static_cast<int>(m_diffs[nDiff].next);
635 case THREEWAYDIFFTYPE_LEFTMIDDLE:
636 if (m_diffs[nDiff].op != OP_3RDONLY)
639 case THREEWAYDIFFTYPE_LEFTRIGHT:
640 if (m_diffs[nDiff].op != OP_2NDONLY)
643 case THREEWAYDIFFTYPE_MIDDLERIGHT:
644 if (m_diffs[nDiff].op != OP_1STONLY)
647 case THREEWAYDIFFTYPE_LEFTONLY:
648 if (m_diffs[nDiff].op == OP_1STONLY)
651 case THREEWAYDIFFTYPE_MIDDLEONLY:
652 if (m_diffs[nDiff].op == OP_2NDONLY)
655 case THREEWAYDIFFTYPE_RIGHTONLY:
656 if (m_diffs[nDiff].op == OP_3RDONLY)
659 case THREEWAYDIFFTYPE_CONFLICT:
660 if (m_diffs[nDiff].op == OP_DIFF)
669 * @brief Return index of previous significant diff.
670 * @param [in] nDiff Index to start looking for previous diff.
671 * @return Index of previous significant difference.
673 int DiffList::PrevSignificant3wayDiff(int nDiff, int nDiffType) const
675 while (m_diffs[nDiff].prev != -1)
677 nDiff = static_cast<int>(m_diffs[nDiff].prev);
680 case THREEWAYDIFFTYPE_LEFTMIDDLE:
681 if (m_diffs[nDiff].op != OP_3RDONLY)
684 case THREEWAYDIFFTYPE_LEFTRIGHT:
685 if (m_diffs[nDiff].op != OP_2NDONLY)
688 case THREEWAYDIFFTYPE_MIDDLERIGHT:
689 if (m_diffs[nDiff].op != OP_1STONLY)
692 case THREEWAYDIFFTYPE_LEFTONLY:
693 if (m_diffs[nDiff].op == OP_1STONLY)
696 case THREEWAYDIFFTYPE_MIDDLEONLY:
697 if (m_diffs[nDiff].op == OP_2NDONLY)
700 case THREEWAYDIFFTYPE_RIGHTONLY:
701 if (m_diffs[nDiff].op == OP_3RDONLY)
704 case THREEWAYDIFFTYPE_CONFLICT:
705 if (m_diffs[nDiff].op == OP_DIFF)
714 * @brief Return index to last significant diff.
715 * @return Index of last significant difference.
717 int DiffList::LastSignificant3wayDiff(int nDiffType) const
721 case THREEWAYDIFFTYPE_LEFTMIDDLE:
722 return m_lastSignificantLeftMiddle;
723 case THREEWAYDIFFTYPE_LEFTRIGHT:
724 return m_lastSignificantLeftRight;
725 case THREEWAYDIFFTYPE_MIDDLERIGHT:
726 return m_lastSignificantMiddleRight;
727 case THREEWAYDIFFTYPE_LEFTONLY:
728 return m_lastSignificantLeftOnly;
729 case THREEWAYDIFFTYPE_MIDDLEONLY:
730 return m_lastSignificantLeftOnly;
731 case THREEWAYDIFFTYPE_RIGHTONLY:
732 return m_lastSignificantRightOnly;
733 case THREEWAYDIFFTYPE_CONFLICT:
734 return m_lastSignificantRightOnly;
740 * @brief Return pointer to first significant diff.
741 * @return Constant pointer to first significant difference.
743 const DIFFRANGE * DiffList::FirstSignificant3wayDiffRange(int nDiffType) const
747 case THREEWAYDIFFTYPE_LEFTMIDDLE:
748 if (m_firstSignificantLeftMiddle == -1) return nullptr;
749 return DiffRangeAt(m_firstSignificantLeftMiddle);
750 case THREEWAYDIFFTYPE_LEFTRIGHT:
751 if (m_firstSignificantLeftRight == -1) return nullptr;
752 return DiffRangeAt(m_firstSignificantLeftRight);
753 case THREEWAYDIFFTYPE_MIDDLERIGHT:
754 if (m_firstSignificantMiddleRight == -1) return nullptr;
755 return DiffRangeAt(m_firstSignificantMiddleRight);
756 case THREEWAYDIFFTYPE_LEFTONLY:
757 if (m_firstSignificantLeftOnly == -1) return nullptr;
758 return DiffRangeAt(m_firstSignificantLeftOnly);
759 case THREEWAYDIFFTYPE_MIDDLEONLY:
760 if (m_firstSignificantMiddleOnly == -1) return nullptr;
761 return DiffRangeAt(m_firstSignificantMiddleOnly);
762 case THREEWAYDIFFTYPE_RIGHTONLY:
763 if (m_firstSignificantRightOnly == -1) return nullptr;
764 return DiffRangeAt(m_firstSignificantRightOnly);
765 case THREEWAYDIFFTYPE_CONFLICT:
766 if (m_firstSignificantConflict == -1) return nullptr;
767 return DiffRangeAt(m_firstSignificantConflict);
773 * @brief Return pointer to last significant diff.
774 * @return Constant pointer to last significant difference.
776 const DIFFRANGE * DiffList::LastSignificant3wayDiffRange(int nDiffType) const
780 case THREEWAYDIFFTYPE_LEFTMIDDLE:
781 if (m_lastSignificantLeftMiddle == -1) return nullptr;
782 return DiffRangeAt(m_lastSignificantLeftMiddle);
783 case THREEWAYDIFFTYPE_LEFTRIGHT:
784 if (m_lastSignificantLeftRight == -1) return nullptr;
785 return DiffRangeAt(m_lastSignificantLeftRight);
786 case THREEWAYDIFFTYPE_MIDDLERIGHT:
787 if (m_lastSignificantMiddleRight == -1) return nullptr;
788 return DiffRangeAt(m_lastSignificantMiddleRight);
789 case THREEWAYDIFFTYPE_LEFTONLY:
790 if (m_lastSignificantLeftOnly == -1) return nullptr;
791 return DiffRangeAt(m_lastSignificantLeftOnly);
792 case THREEWAYDIFFTYPE_MIDDLEONLY:
793 if (m_lastSignificantMiddleOnly == -1) return nullptr;
794 return DiffRangeAt(m_lastSignificantMiddleOnly);
795 case THREEWAYDIFFTYPE_RIGHTONLY:
796 if (m_lastSignificantRightOnly == -1) return nullptr;
797 return DiffRangeAt(m_lastSignificantRightOnly);
798 case THREEWAYDIFFTYPE_CONFLICT:
799 if (m_lastSignificantConflict == -1) return nullptr;
800 return DiffRangeAt(m_lastSignificantConflict);
806 * @brief Swap sides of diffrange
808 void DiffList::Swap(int index1, int index2)
810 vector<DiffRangeInfo>::iterator iter = m_diffs.begin();
811 vector<DiffRangeInfo>::const_iterator iterEnd = m_diffs.end();
812 while (iter != iterEnd)
814 (*iter).swap_sides(index1, index2);
820 * @brief Count number of lines to add to sides (because of synch).
821 * @param [out] nLeftLines Number of lines to add to left side.
822 * @param [out] nRightLines Number of lines to add to right side.
824 void DiffList::GetExtraLinesCounts(int nFiles, int extras[3])
829 const int nDiffCount = GetSize();
831 for (int nDiff = 0; nDiff < nDiffCount; ++nDiff)
834 GetDiff(nDiff, curDiff);
836 // this guarantees that all the diffs are synchronized
837 assert(curDiff.begin[0]+extras[0] == curDiff.begin[1]+extras[1]);
838 assert(nFiles<3 || curDiff.begin[0]+extras[0] == curDiff.begin[2]+extras[2]);
839 int nline[3] = { 0,0,0 };
842 for (file = 0; file < nFiles; file++)
844 nline[file] = curDiff.end[file]-curDiff.begin[file]+1;
845 nmaxline = std::max(nmaxline, nline[file]);
847 for (file = 0; file < nFiles; file++)
848 extras[file] += nmaxline - nline[file];
852 void DiffList::AppendDiffList(const DiffList& list, const int offset[] /*= nullptr*/, int doffset /*= 0*/)
854 for (std::vector<DiffRangeInfo>::const_iterator it = list.m_diffs.begin(); it != list.m_diffs.end(); ++it)
856 DiffRangeInfo dr = *it;
857 for (int file = 0; file < 3; ++file)
859 if (offset != nullptr)
861 dr.begin[file] += offset[file];
862 dr.end[file] += offset[file];
865 dr.blank[file] += doffset;
869 dr.dbegin += doffset;
876 int DiffList::GetMergeableSrcIndex(int nDiff, int nDestIndex) const
878 const DIFFRANGE *pdr = DiffRangeAt(nDiff);
883 if (pdr->op == OP_2NDONLY)
887 if (pdr->op == OP_1STONLY || pdr->op == OP_2NDONLY)
889 else if (pdr->op == OP_3RDONLY)