author | Martin von Zweigbergk <martinvonz@google.com> |
Wed, 03 Apr 2019 16:03:41 -0700 | |
changeset 42093 | edbcf5b239f9 |
parent 38783 | e7aa113b14f7 |
child 43075 | 57875cf423c9 |
permissions | -rw-r--r-- |
37803
72f6498c040b
diffhelper: rename module to avoid conflicts with ancient C module (issue5846)
Yuya Nishihara <yuya@tcha.org>
parents:
37802
diff
changeset
|
1 |
# diffhelper.py - helper routines for patch |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
2 |
# |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
3 |
# Copyright 2009 Matt Mackall <mpm@selenic.com> and others |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
4 |
# |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7702
diff
changeset
|
5 |
# This software may be used and distributed according to the terms of the |
10263 | 6 |
# GNU General Public License version 2 or any later version. |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
7 |
|
27336
80214358ac88
diffhelpers: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
12387
diff
changeset
|
8 |
from __future__ import absolute_import |
80214358ac88
diffhelpers: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
12387
diff
changeset
|
9 |
|
37573
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
10 |
from .i18n import _ |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
11 |
|
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
12 |
from . import ( |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
13 |
error, |
38783
e7aa113b14f7
global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37836
diff
changeset
|
14 |
pycompat, |
37573
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
15 |
) |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
16 |
|
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
17 |
def addlines(fp, hunk, lena, lenb, a, b): |
37567
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
18 |
"""Read lines from fp into the hunk |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
19 |
|
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
20 |
The hunk is parsed into two arrays, a and b. a gets the old state of |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
21 |
the text, b gets the new state. The control char from the hunk is saved |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
22 |
when inserting into a, but not b (for performance while deleting files.) |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
23 |
""" |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
24 |
while True: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
25 |
todoa = lena - len(a) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
26 |
todob = lenb - len(b) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
27 |
num = max(todoa, todob) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
28 |
if num == 0: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
29 |
break |
38783
e7aa113b14f7
global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37836
diff
changeset
|
30 |
for i in pycompat.xrange(num): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
31 |
s = fp.readline() |
37573
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
32 |
if not s: |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
33 |
raise error.ParseError(_('incomplete hunk')) |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
34 |
if s == "\\ No newline at end of file\n": |
37570
c4c8d0d1267f
diffhelpers: naming and whitespace cleanup
Yuya Nishihara <yuya@tcha.org>
parents:
37567
diff
changeset
|
35 |
fixnewline(hunk, a, b) |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
36 |
continue |
37575
230eb9594150
diffhelpers: be more tolerant for stripped empty lines of CRLF ending
Yuya Nishihara <yuya@tcha.org>
parents:
37574
diff
changeset
|
37 |
if s == '\n' or s == '\r\n': |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
38 |
# Some patches may be missing the control char |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
39 |
# on empty lines. Supply a leading space. |
37575
230eb9594150
diffhelpers: be more tolerant for stripped empty lines of CRLF ending
Yuya Nishihara <yuya@tcha.org>
parents:
37574
diff
changeset
|
40 |
s = ' ' + s |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
41 |
hunk.append(s) |
37566
f53b55b162f4
py3: get rid of character access from pure.diffhelpers
Yuya Nishihara <yuya@tcha.org>
parents:
27336
diff
changeset
|
42 |
if s.startswith('+'): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
43 |
b.append(s[1:]) |
37566
f53b55b162f4
py3: get rid of character access from pure.diffhelpers
Yuya Nishihara <yuya@tcha.org>
parents:
27336
diff
changeset
|
44 |
elif s.startswith('-'): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
45 |
a.append(s) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
46 |
else: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
47 |
b.append(s[1:]) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
48 |
a.append(s) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
49 |
|
37570
c4c8d0d1267f
diffhelpers: naming and whitespace cleanup
Yuya Nishihara <yuya@tcha.org>
parents:
37567
diff
changeset
|
50 |
def fixnewline(hunk, a, b): |
37567
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
51 |
"""Fix up the last lines of a and b when the patch has no newline at EOF""" |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
52 |
l = hunk[-1] |
10551
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
53 |
# tolerate CRLF in last line |
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
54 |
if l.endswith('\r\n'): |
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
55 |
hline = l[:-2] |
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
56 |
else: |
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
57 |
hline = l[:-1] |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
58 |
|
37566
f53b55b162f4
py3: get rid of character access from pure.diffhelpers
Yuya Nishihara <yuya@tcha.org>
parents:
27336
diff
changeset
|
59 |
if hline.startswith((' ', '+')): |
10551
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
60 |
b[-1] = hline[1:] |
37566
f53b55b162f4
py3: get rid of character access from pure.diffhelpers
Yuya Nishihara <yuya@tcha.org>
parents:
27336
diff
changeset
|
61 |
if hline.startswith((' ', '-')): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
62 |
a[-1] = hline |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
63 |
hunk[-1] = hline |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
64 |
|
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
65 |
def testhunk(a, b, bstart): |
37567
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
66 |
"""Compare the lines in a with the lines in b |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
67 |
|
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
68 |
a is assumed to have a control char at the start of each line, this char |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
69 |
is ignored in the compare. |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
70 |
""" |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
71 |
alen = len(a) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
72 |
blen = len(b) |
37802
090c89a8db32
diffhelpers: backport 9e40bc4c1bde from C implementation
Yuya Nishihara <yuya@tcha.org>
parents:
37575
diff
changeset
|
73 |
if alen > blen - bstart or bstart < 0: |
37574
a1bcc7ff0eac
diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents:
37573
diff
changeset
|
74 |
return False |
38783
e7aa113b14f7
global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37836
diff
changeset
|
75 |
for i in pycompat.xrange(alen): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
76 |
if a[i][1:] != b[i + bstart]: |
37574
a1bcc7ff0eac
diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents:
37573
diff
changeset
|
77 |
return False |
a1bcc7ff0eac
diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents:
37573
diff
changeset
|
78 |
return True |