diffhelper.py
82 lines
| 2.3 KiB
| text/x-python
|
PythonLexer
/ mercurial / diffhelper.py
Yuya Nishihara
|
r37821 | # diffhelper.py - helper routines for patch | ||
# | ||||
Raphaël Gomès
|
r47575 | # Copyright 2009 Olivia Mackall <olivia@selenic.com> and others | ||
Yuya Nishihara
|
r37821 | # | ||
# This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | ||||
Matt Harbison
|
r52756 | from __future__ import annotations | ||
Yuya Nishihara
|
r37821 | |||
from .i18n import _ | ||||
from . import ( | ||||
error, | ||||
) | ||||
Rodrigo Damazio Bovendorp
|
r45714 | MISSING_NEWLINE_MARKER = b'\\ No newline at end of file\n' | ||
Augie Fackler
|
r43345 | |||
Yuya Nishihara
|
r37821 | def addlines(fp, hunk, lena, lenb, a, b): | ||
"""Read lines from fp into the hunk | ||||
The hunk is parsed into two arrays, a and b. a gets the old state of | ||||
the text, b gets the new state. The control char from the hunk is saved | ||||
when inserting into a, but not b (for performance while deleting files.) | ||||
""" | ||||
while True: | ||||
todoa = lena - len(a) | ||||
todob = lenb - len(b) | ||||
num = max(todoa, todob) | ||||
if num == 0: | ||||
break | ||||
Manuel Jacob
|
r50179 | for i in range(num): | ||
Yuya Nishihara
|
r37821 | s = fp.readline() | ||
if not s: | ||||
Augie Fackler
|
r43347 | raise error.ParseError(_(b'incomplete hunk')) | ||
Rodrigo Damazio Bovendorp
|
r45714 | if s == MISSING_NEWLINE_MARKER: | ||
Yuya Nishihara
|
r37821 | fixnewline(hunk, a, b) | ||
continue | ||||
Augie Fackler
|
r43347 | if s == b'\n' or s == b'\r\n': | ||
Yuya Nishihara
|
r37821 | # Some patches may be missing the control char | ||
# on empty lines. Supply a leading space. | ||||
Augie Fackler
|
r43347 | s = b' ' + s | ||
Yuya Nishihara
|
r37821 | hunk.append(s) | ||
Augie Fackler
|
r43347 | if s.startswith(b'+'): | ||
Yuya Nishihara
|
r37821 | b.append(s[1:]) | ||
Augie Fackler
|
r43347 | elif s.startswith(b'-'): | ||
Yuya Nishihara
|
r37821 | a.append(s) | ||
else: | ||||
b.append(s[1:]) | ||||
a.append(s) | ||||
Augie Fackler
|
r43345 | |||
Yuya Nishihara
|
r37821 | def fixnewline(hunk, a, b): | ||
"""Fix up the last lines of a and b when the patch has no newline at EOF""" | ||||
l = hunk[-1] | ||||
# tolerate CRLF in last line | ||||
Augie Fackler
|
r43347 | if l.endswith(b'\r\n'): | ||
Yuya Nishihara
|
r37821 | hline = l[:-2] | ||
else: | ||||
hline = l[:-1] | ||||
Augie Fackler
|
r43347 | if hline.startswith((b' ', b'+')): | ||
Yuya Nishihara
|
r37821 | b[-1] = hline[1:] | ||
Augie Fackler
|
r43347 | if hline.startswith((b' ', b'-')): | ||
Yuya Nishihara
|
r37821 | a[-1] = hline | ||
hunk[-1] = hline | ||||
Augie Fackler
|
r43345 | |||
Yuya Nishihara
|
r37821 | def testhunk(a, b, bstart): | ||
"""Compare the lines in a with the lines in b | ||||
a is assumed to have a control char at the start of each line, this char | ||||
is ignored in the compare. | ||||
""" | ||||
alen = len(a) | ||||
blen = len(b) | ||||
if alen > blen - bstart or bstart < 0: | ||||
return False | ||||
Manuel Jacob
|
r50179 | for i in range(alen): | ||
Yuya Nishihara
|
r37821 | if a[i][1:] != b[i + bstart]: | ||
return False | ||||
return True | ||||