author | Raphaël Gomès <rgomes@octobus.net> |
Wed, 11 Jan 2023 16:29:29 +0100 | |
changeset 49980 | 95ffa065204e |
parent 49284 | d44e3c45f0e4 |
child 51863 | f4733654f144 |
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 |
# |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents:
45154
diff
changeset
|
3 |
# Copyright 2009 Olivia Mackall <olivia@selenic.com> and others |
7702
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 |
|
37573
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
9 |
from .i18n import _ |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
10 |
|
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
11 |
from . import ( |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
12 |
error, |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
13 |
) |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
14 |
|
45154
10f48720ef95
diff: move no-eol text constant to a common location
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents:
43077
diff
changeset
|
15 |
MISSING_NEWLINE_MARKER = b'\\ No newline at end of file\n' |
10f48720ef95
diff: move no-eol text constant to a common location
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents:
43077
diff
changeset
|
16 |
|
43075
57875cf423c9
style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents:
38783
diff
changeset
|
17 |
|
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
18 |
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
|
19 |
"""Read lines from fp into the hunk |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
20 |
|
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
21 |
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
|
22 |
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
|
23 |
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
|
24 |
""" |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
25 |
while True: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
26 |
todoa = lena - len(a) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
27 |
todob = lenb - len(b) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
28 |
num = max(todoa, todob) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
29 |
if num == 0: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
30 |
break |
49284
d44e3c45f0e4
py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents:
48875
diff
changeset
|
31 |
for i in range(num): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
32 |
s = fp.readline() |
37573
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
33 |
if not s: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
34 |
raise error.ParseError(_(b'incomplete hunk')) |
45154
10f48720ef95
diff: move no-eol text constant to a common location
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents:
43077
diff
changeset
|
35 |
if s == MISSING_NEWLINE_MARKER: |
37570
c4c8d0d1267f
diffhelpers: naming and whitespace cleanup
Yuya Nishihara <yuya@tcha.org>
parents:
37567
diff
changeset
|
36 |
fixnewline(hunk, a, b) |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
37 |
continue |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
38 |
if s == b'\n' or s == b'\r\n': |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
39 |
# Some patches may be missing the control char |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
40 |
# on empty lines. Supply a leading space. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
41 |
s = b' ' + s |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
42 |
hunk.append(s) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
43 |
if s.startswith(b'+'): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
44 |
b.append(s[1:]) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
45 |
elif s.startswith(b'-'): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
46 |
a.append(s) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
47 |
else: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
48 |
b.append(s[1:]) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
49 |
a.append(s) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
50 |
|
43075
57875cf423c9
style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents:
38783
diff
changeset
|
51 |
|
37570
c4c8d0d1267f
diffhelpers: naming and whitespace cleanup
Yuya Nishihara <yuya@tcha.org>
parents:
37567
diff
changeset
|
52 |
def fixnewline(hunk, a, b): |
37567
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
53 |
"""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
|
54 |
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
|
55 |
# tolerate CRLF in last line |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
56 |
if l.endswith(b'\r\n'): |
10551
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[:-2] |
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
58 |
else: |
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
59 |
hline = l[:-1] |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
60 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
61 |
if hline.startswith((b' ', b'+')): |
10551
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
62 |
b[-1] = hline[1:] |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
63 |
if hline.startswith((b' ', b'-')): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
64 |
a[-1] = hline |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
65 |
hunk[-1] = hline |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
66 |
|
43075
57875cf423c9
style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents:
38783
diff
changeset
|
67 |
|
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
68 |
def testhunk(a, b, bstart): |
37567
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
69 |
"""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
|
70 |
|
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
71 |
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
|
72 |
is ignored in the compare. |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
73 |
""" |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
74 |
alen = len(a) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
75 |
blen = len(b) |
37802
090c89a8db32
diffhelpers: backport 9e40bc4c1bde from C implementation
Yuya Nishihara <yuya@tcha.org>
parents:
37575
diff
changeset
|
76 |
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
|
77 |
return False |
49284
d44e3c45f0e4
py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents:
48875
diff
changeset
|
78 |
for i in range(alen): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
79 |
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
|
80 |
return False |
a1bcc7ff0eac
diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents:
37573
diff
changeset
|
81 |
return True |