@Nullable private PatchHunk readNextHunkContext(ListIterator<String> iterator) throws PatchSyntaxException { while (iterator.hasNext()) { String curLine = iterator.next(); if (curLine.startsWith(CONTEXT_FILE_PREFIX)) { iterator.previous(); return null; } if (curLine.startsWith(CONTEXT_HUNK_PREFIX)) { break; } } if (!iterator.hasNext()) { return null; } Matcher beforeMatcher = ourContextBeforeHunkStartPattern.matcher(iterator.next()); if (!beforeMatcher.matches()) { throw new PatchSyntaxException( iterator.previousIndex(), "Unknown before hunk start syntax"); } List<String> beforeLines = readContextDiffLines(iterator); if (!iterator.hasNext()) { throw new PatchSyntaxException(iterator.previousIndex(), "Missing after hunk"); } Matcher afterMatcher = ourContextAfterHunkStartPattern.matcher(iterator.next()); if (!afterMatcher.matches()) { throw new PatchSyntaxException(iterator.previousIndex(), "Unknown after hunk start syntax"); } // if (! iterator.hasNext()) { // throw new PatchSyntaxException(iterator.previousIndex(), "Unexpected patch end"); // } List<String> afterLines = readContextDiffLines(iterator); int startLineBefore = Integer.parseInt(beforeMatcher.group(1)); int endLineBefore = Integer.parseInt(beforeMatcher.group(2)); int startLineAfter = Integer.parseInt(afterMatcher.group(1)); int endLineAfter = Integer.parseInt(afterMatcher.group(2)); PatchHunk hunk = new PatchHunk( startLineBefore - 1, endLineBefore - 1, startLineAfter - 1, endLineAfter - 1); int beforeLineIndex = 0; int afterLineIndex = 0; PatchLine lastBeforePatchLine = null; PatchLine lastAfterPatchLine = null; if (beforeLines.size() == 0) { for (String line : afterLines) { hunk.addLine(parsePatchLine(line, 2)); } } else if (afterLines.size() == 0) { for (String line : beforeLines) { hunk.addLine(parsePatchLine(line, 2)); } } else { while (beforeLineIndex < beforeLines.size() || afterLineIndex < afterLines.size()) { String beforeLine = beforeLineIndex >= beforeLines.size() ? null : beforeLines.get(beforeLineIndex); String afterLine = afterLineIndex >= afterLines.size() ? null : afterLines.get(afterLineIndex); if (startsWith(beforeLine, NO_NEWLINE_SIGNATURE) && lastBeforePatchLine != null) { lastBeforePatchLine.setSuppressNewLine(true); beforeLineIndex++; } else if (startsWith(afterLine, NO_NEWLINE_SIGNATURE) && lastAfterPatchLine != null) { lastAfterPatchLine.setSuppressNewLine(true); afterLineIndex++; } else if (startsWith(beforeLine, " ") && (startsWith(afterLine, " ") || afterLine == null /* handle some weird cases with line breaks truncated at EOF */)) { addContextDiffLine(hunk, beforeLine, PatchLine.Type.CONTEXT); beforeLineIndex++; afterLineIndex++; } else if (startsWith(beforeLine, "-")) { lastBeforePatchLine = addContextDiffLine(hunk, beforeLine, PatchLine.Type.REMOVE); beforeLineIndex++; } else if (startsWith(afterLine, "+")) { lastAfterPatchLine = addContextDiffLine(hunk, afterLine, PatchLine.Type.ADD); afterLineIndex++; } else if (startsWith(beforeLine, "!") && startsWith(afterLine, "!")) { while (beforeLineIndex < beforeLines.size() && beforeLines.get(beforeLineIndex).startsWith("! ")) { lastBeforePatchLine = addContextDiffLine(hunk, beforeLines.get(beforeLineIndex), PatchLine.Type.REMOVE); beforeLineIndex++; } while (afterLineIndex < afterLines.size() && afterLines.get(afterLineIndex).startsWith("! ")) { lastAfterPatchLine = addContextDiffLine(hunk, afterLines.get(afterLineIndex), PatchLine.Type.ADD); afterLineIndex++; } } else { throw new PatchSyntaxException(-1, "Unknown line prefix"); } } } return hunk; }
private static PatchLine addContextDiffLine( final PatchHunk hunk, final String line, final PatchLine.Type type) { final PatchLine patchLine = new PatchLine(type, line.length() < 2 ? "" : line.substring(2)); hunk.addLine(patchLine); return patchLine; }
@Nullable private PatchHunk readNextHunkUnified(ListIterator<String> iterator) throws PatchSyntaxException { String curLine = null; int numIncrements = 0; while (iterator.hasNext()) { curLine = iterator.next(); ++numIncrements; if (curLine.startsWith("--- ")) { for (int i = 0; i < numIncrements; i++) { iterator.previous(); } return null; } if (curLine.startsWith("@@ ")) { break; } } if (!iterator.hasNext()) return null; Matcher m = ourUnifiedHunkStartPattern.matcher(curLine); if (!m.matches()) { throw new PatchSyntaxException(iterator.previousIndex(), "Unknown hunk start syntax"); } int startLineBefore = Integer.parseInt(m.group(1)); final String linesBeforeText = m.group(3); int linesBefore = linesBeforeText == null ? 1 : Integer.parseInt(linesBeforeText); int startLineAfter = Integer.parseInt(m.group(4)); final String linesAfterText = m.group(6); int linesAfter = linesAfterText == null ? 1 : Integer.parseInt(linesAfterText); PatchHunk hunk = new PatchHunk( startLineBefore - 1, startLineBefore + linesBefore - 1, startLineAfter - 1, startLineAfter + linesAfter - 1); PatchLine lastLine = null; int before = 0; int after = 0; while (iterator.hasNext()) { String hunkCurLine = iterator.next(); if (lastLine != null && hunkCurLine.startsWith(NO_NEWLINE_SIGNATURE)) { lastLine.setSuppressNewLine(true); continue; } lastLine = parsePatchLine(hunkCurLine, 1, before < linesBefore || after < linesAfter); if (lastLine == null) { iterator.previous(); break; } switch (lastLine.getType()) { case CONTEXT: before++; after++; break; case ADD: after++; break; case REMOVE: before++; break; } hunk.addLine(lastLine); } return hunk; }