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 size_t diff10count = diff10.size();
13 size_t diff12count = diff12.size();
19 bool firstDiffBlockIsDiff12;
21 Element dr3, dr10, dr12, dr10first, dr10last, dr12first, dr12last;
29 if (diff10i >= diff10count && diff12i >= diff12count)
33 * merge overlapped diff blocks
34 * diff10 is diff blocks between file1 and file0.
35 * diff12 is diff blocks between file1 and file2.
40 * firstDiffBlock | | | |
45 * lastDiffBlock | | | |
49 if (diff10i >= diff10count && diff12i < diff12count)
51 dr12first = diff12.at(diff12i);
53 firstDiffBlockIsDiff12 = true;
55 else if (diff10i < diff10count && diff12i >= diff12count)
57 dr10first = diff10.at(diff10i);
59 firstDiffBlockIsDiff12 = false;
63 dr10first = diff10.at(diff10i);
64 dr12first = diff12.at(diff12i);
67 if (dr12first.begin[0] <= dr10first.begin[0])
68 firstDiffBlockIsDiff12 = true;
70 firstDiffBlockIsDiff12 = false;
72 bool lastDiffBlockIsDiff12 = firstDiffBlockIsDiff12;
74 size_t diff10itmp = diff10i;
75 size_t diff12itmp = diff12i;
78 if (diff10itmp >= diff10count || diff12itmp >= diff12count)
81 dr10 = diff10.at(diff10itmp);
82 dr12 = diff12.at(diff12itmp);
84 if (dr10.end[0] == dr12.end[0])
87 lastDiffBlockIsDiff12 = true;
94 if (lastDiffBlockIsDiff12)
96 if (std::max(dr12.begin[0], dr12.end[0]) < dr10.begin[0])
101 if (std::max(dr10.begin[0], dr10.end[0]) < dr12.begin[0])
105 if (dr12.end[0] > dr10.end[0])
108 lastDiffBlockIsDiff12 = true;
113 lastDiffBlockIsDiff12 = false;
120 if (lastDiffBlockIsDiff12)
125 if (firstDiffBlockIsDiff12)
127 dr3.begin[1] = dr12first.begin[0];
128 dr3.begin[2] = dr12first.begin[1];
129 if (diff10itmp == diff10i)
130 dr3.begin[0] = dr3.begin[1] - linelast1 + linelast0;
132 dr3.begin[0] = dr3.begin[1] - dr10first.begin[0] + dr10first.begin[1];
136 dr3.begin[0] = dr10first.begin[1];
137 dr3.begin[1] = dr10first.begin[0];
138 if (diff12itmp == diff12i)
139 dr3.begin[2] = dr3.begin[1] - linelast1 + linelast2;
141 dr3.begin[2] = dr3.begin[1] - dr12first.begin[0] + dr12first.begin[1];
144 if (lastDiffBlockIsDiff12)
146 dr3.end[1] = dr12last.end[0];
147 dr3.end[2] = dr12last.end[1];
148 if (diff10itmp == diff10i)
149 dr3.end[0] = dr3.end[1] - linelast1 + linelast0;
151 dr3.end[0] = dr3.end[1] - dr10last.end[0] + dr10last.end[1];
155 dr3.end[0] = dr10last.end[1];
156 dr3.end[1] = dr10last.end[0];
157 if (diff12itmp == diff12i)
158 dr3.end[2] = dr3.end[1] - linelast1 + linelast2;
160 dr3.end[2] = dr3.end[1] - dr12last.end[0] + dr12last.end[1];
163 linelast0 = dr3.end[0] + 1;
164 linelast1 = dr3.end[1] + 1;
165 linelast2 = dr3.end[2] + 1;
167 if (diff10i == diff10itmp)
169 else if (diff12i == diff12itmp)
179 if (has_trivial_diffs)
181 bool bTrivialDiff10 = true;
182 bool bTrivialDiff12 = true;
185 for (i = diff10i; i < diff10itmp; i++)
188 if (dr10.op != OP_TRIVIAL)
190 bTrivialDiff10 = false;
195 for (i = diff12i; i < diff12itmp; i++)
198 if (dr12.op != OP_TRIVIAL)
200 bTrivialDiff12 = false;
205 if (bTrivialDiff10 && bTrivialDiff12)
209 diff3.push_back(dr3);
212 diff10i = diff10itmp;
213 diff12i = diff12itmp;
216 for (size_t i = 0; i < diff3i; i++)
218 Element& dr3r = diff3.at(i);
221 Element& dr3next = diff3.at(i + 1);
222 for (int j = 0; j < 3; j++)
224 if (dr3r.end[j] >= dr3next.begin[j])
225 dr3r.end[j] = dr3next.begin[j] - 1;