7 /* diff3 algorithm. It is almost the same as GNU diff3's algorithm */
8 template<typename Element, typename Comp02Func>
9 size_t Make3wayDiff(std::vector<Element>& diff3, const std::vector<Element>& diff10, const std::vector<Element>& diff12,
10 Comp02Func cmpfunc, bool has_trivial_diffs)
12 const size_t diff10count = diff10.size();
13 const size_t diff12count = diff12.size();
18 Element dr3, dr10, dr12, dr10first, dr10last, dr12first, dr12last;
24 bool firstDiffBlockIsDiff12;
29 * merge overlapped diff blocks
30 * diff10 is diff blocks between file1 and file0.
31 * diff12 is diff blocks between file1 and file2.
36 * firstDiffBlock | | | |
41 * lastDiffBlock | | | |
45 if (diff10i >= diff10count)
47 if (diff12i >= diff12count)
50 dr12last = dr12first = diff12[diff12i];
51 firstDiffBlockIsDiff12 = true;
53 else if (diff12i >= diff12count)
55 dr10last = dr10first = diff10[diff10i];
56 firstDiffBlockIsDiff12 = false;
60 dr10last = dr10first = diff10[diff10i];
61 dr12last = dr12first = diff12[diff12i];
62 firstDiffBlockIsDiff12 = (dr12first.begin[0] <= dr10first.begin[0]);
64 bool lastDiffBlockIsDiff12 = firstDiffBlockIsDiff12;
66 size_t diff10itmp = diff10i;
67 size_t diff12itmp = diff12i;
70 if (diff10itmp >= diff10count || diff12itmp >= diff12count)
73 dr10 = diff10[diff10itmp];
74 dr12 = diff12[diff12itmp];
76 if (dr10.end[0] == dr12.end[0])
79 lastDiffBlockIsDiff12 = true;
86 if (lastDiffBlockIsDiff12)
88 if (std::max(dr12.begin[0], dr12.end[0]) < dr10.begin[0])
93 if (std::max(dr10.begin[0], dr10.end[0]) < dr12.begin[0])
97 if (dr12.end[0] > dr10.end[0])
100 lastDiffBlockIsDiff12 = true;
105 lastDiffBlockIsDiff12 = false;
112 if (lastDiffBlockIsDiff12)
117 if (firstDiffBlockIsDiff12)
119 dr3.begin[1] = dr12first.begin[0];
120 dr3.begin[2] = dr12first.begin[1];
121 if (diff10itmp == diff10i)
122 dr3.begin[0] = dr3.begin[1] - linelast1 + linelast0;
124 dr3.begin[0] = dr3.begin[1] - dr10first.begin[0] + dr10first.begin[1];
128 dr3.begin[0] = dr10first.begin[1];
129 dr3.begin[1] = dr10first.begin[0];
130 if (diff12itmp == diff12i)
131 dr3.begin[2] = dr3.begin[1] - linelast1 + linelast2;
133 dr3.begin[2] = dr3.begin[1] - dr12first.begin[0] + dr12first.begin[1];
136 if (lastDiffBlockIsDiff12)
138 dr3.end[1] = dr12last.end[0];
139 dr3.end[2] = dr12last.end[1];
140 if (diff10itmp == diff10i)
141 dr3.end[0] = dr3.end[1] - linelast1 + linelast0;
143 dr3.end[0] = dr3.end[1] - dr10last.end[0] + dr10last.end[1];
147 dr3.end[0] = dr10last.end[1];
148 dr3.end[1] = dr10last.end[0];
149 if (diff12itmp == diff12i)
150 dr3.end[2] = dr3.end[1] - linelast1 + linelast2;
152 dr3.end[2] = dr3.end[1] - dr12last.end[0] + dr12last.end[1];
155 linelast0 = dr3.end[0] + 1;
156 linelast1 = dr3.end[1] + 1;
157 linelast2 = dr3.end[2] + 1;
159 if (diff10i == diff10itmp)
161 else if (diff12i == diff12itmp)
171 if (has_trivial_diffs)
173 bool bTrivialDiff10 = true;
174 bool bTrivialDiff12 = true;
177 for (i = diff10i; i < diff10itmp; i++)
180 if (dr10.op != OP_TRIVIAL)
182 bTrivialDiff10 = false;
187 for (i = diff12i; i < diff12itmp; i++)
190 if (dr12.op != OP_TRIVIAL)
192 bTrivialDiff12 = false;
197 if (bTrivialDiff10 && bTrivialDiff12)
201 diff10i = diff10itmp;
202 diff12i = diff12itmp;
204 diff3.push_back(dr3);
207 size_t cnt = diff3.size();
210 for (size_t i = 0; i != (cnt - 1); i++)
212 Element& dr3r = diff3[i];
213 Element& dr3next = diff3[i + 1];
214 for (int j = 0; j < 3; j++)
216 if (dr3r.end[j] >= dr3next.begin[j])
217 dr3r.end[j] = dr3next.begin[j] - 1;