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

Function parseHunks

apps/lib/diff/gitdiff.cpp:241–309  ·  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 * --- a/SOURCE_PATH * +++ b/T

Source from the content-addressed store, hash-verified

239 * generates them anyway for files with unresolved conflicts.
240 */
241static std::vector<DiffHunk> parseHunks(VcsDiff &diff)
242{
243 std::vector<DiffHunk> ret;
244 int lineNo = -1;
245 QString curSrcFileName, curTgtFileName;
246 QStringListIterator lines(diff.diff().split(u'\n'));
247 while (lines.hasNext()) {
248 lineNo++;
249 auto curln = lines.next();
250 auto m = DIFF_FILENAME_RE->match(curln);
251 if (m.hasMatch()) {
252 if (curln.startsWith(u'-'))
253 curSrcFileName = m.captured(1);
254 else if (curln.startsWith(u'+'))
255 curTgtFileName = m.captured(1);
256 continue;
257 }
258 m = HUNK_HEADER_RE->match(curln);
259 if (!m.hasMatch())
260 continue;
261 const auto oldRange = parseRange(m.captured(1));
262 const auto newRange = parseRange(m.captured(2));
263 const auto heading = m.captured(3);
264 uint firstLineIdx = lineNo;
265 QStringList hunkLines;
266 while (lines.hasNext() && (CONFLICT_START_RE->match(lines.peekNext()).hasMatch() || !META_LINE_RE->match(lines.peekNext()).hasMatch())) {
267 // Consume the conflict
268 if (CONFLICT_START_RE->match(lines.peekNext()).hasMatch()) {
269 lineNo++;
270 hunkLines << lines.next();
271 while (lines.hasNext() && !CONFLICT_END_RE->match(lines.peekNext()).hasMatch()) {
272 lineNo++;
273 hunkLines << lines.next();
274 }
275 if (!CONFLICT_END_RE->match(lines.peekNext()).hasMatch()) {
276 qWarning("Invalid diff format, end of file reached before conflict finished");
277 qDebug("%ls", qUtf16Printable(diff.diff()));
278 break;
279 }
280 }
281 lineNo++;
282 hunkLines << lines.next();
283 }
284
285 // The number of filenames present in the diff should match the number
286 // of hunks
287 ret.push_back(DiffHunk{.srcStart = oldRange.line,
288 .srcCount = oldRange.count,
289 .tgtStart = newRange.line,
290 .tgtCount = newRange.count,
291 .headingLineIdx = firstLineIdx,
292 .srcFile = curSrcFileName,
293 .tgtFile = curTgtFileName,
294 .heading = heading,
295 .lines = hunkLines});
296 }
297
298 // If the diff ends with a newline, for the last hunk, when splitting into lines above

Callers 1

setDiffMethod · 0.85

Calls 4

diffMethod · 0.80
matchMethod · 0.80
sizeMethod · 0.80
parseRangeFunction · 0.70

Tested by

no test coverage detected