MCPcopy Create free account
hub / github.com/KDE/kdevelop / parseHunks

Function parseHunks

kdevplatform/vcs/vcsdiff.cpp:224–288  ·  view source on GitHub ↗

* Parses a unified diff into a list of "diff hunks" (each hunk starts with a * line starting with @@ and represents a collection of localized changes). * * @param diff a diff in git's unified diff format * @returns a list of hunk structures * * The diff is assumed to be a collection of hunks, where each hunk has the * following structure: * * METADATA

Source from the content-addressed store, hash-verified

222 * generates them anyway for files with unresolved conflicts.
223 */
224 std::vector<DiffHunk> parseHunks(VcsDiff& diff)
225 {
226 std::vector<DiffHunk> ret;
227 int lineNo = -1;
228 QString curSrcFileName, curTgtFileName;
229 QStringListIterator lines(diff.diff().split(QLatin1Char('\n')));
230 while (lines.hasNext()) {
231 lineNo++;
232 auto curln = lines.next();
233 auto m = DIFF_FILENAME_RE->match(curln);
234 if (m.hasMatch()) {
235 if (curln.startsWith(QLatin1Char('-')))
236 curSrcFileName = m.captured(1);
237 else if (curln.startsWith(QLatin1Char('+')))
238 curTgtFileName = m.captured(1);
239 continue;
240 }
241 m = HUNK_HEADER_RE->match(curln);
242 if (!m.hasMatch())
243 continue;
244 const auto [oldStart, oldCount] = parseRange(m.capturedView(1));
245 const auto [newStart, newCount] = parseRange(m.capturedView(2));
246 auto heading = m.captured(3);
247 uint firstLineIdx = lineNo;
248 QStringList hunkLines;
249 while (lines.hasNext()
250 && (CONFLICT_START_RE->match(lines.peekNext()).hasMatch()
251 || !META_LINE_RE->match(lines.peekNext()).hasMatch())) {
252 // Consume the conflict
253 if (CONFLICT_START_RE->match(lines.peekNext()).hasMatch()) {
254 lineNo++;
255 hunkLines << lines.next();
256 while (lines.hasNext() && !CONFLICT_END_RE->match(lines.peekNext()).hasMatch()) {
257 lineNo++;
258 hunkLines << lines.next();
259 }
260 if (!CONFLICT_END_RE->match(lines.peekNext()).hasMatch()) {
261 qCWarning(VCS) << "Invalid diff format, end of file reached before conflict finished";
262 qCDebug(VCS) << diff.diff();
263 break;
264 }
265 }
266 lineNo++;
267 hunkLines << lines.next();
268 }
269
270 // The number of filenames present in the diff should match the number
271 // of hunks
272 ret.push_back({ oldStart, oldCount, newStart, newCount, firstLineIdx, curSrcFileName, curTgtFileName,
273 heading, hunkLines });
274 }
275
276 // If the diff ends with a newline, for the last hunk, when splitting into lines above
277 // we will always get an empty string at the end, which we now remove
278 if (diff.diff().endsWith(QLatin1Char('\n'))) {
279 if (ret.size() > 0 && ret.back().lines.size() > 0) {
280 ret.back().lines.pop_back();
281 } else {

Callers 1

setDiffMethod · 0.85

Calls 12

parseRangeFunction · 0.85
hasMatchMethod · 0.80
peekNextMethod · 0.80
endsWithMethod · 0.80
splitMethod · 0.45
diffMethod · 0.45
hasNextMethod · 0.45
nextMethod · 0.45
matchMethod · 0.45
push_backMethod · 0.45
sizeMethod · 0.45
backMethod · 0.45

Tested by

no test coverage detected