Mercurial > hg
annotate mercurial/cffi/bdiff.py @ 52152:de4b9ea2fa34 default tip
branching: merge stable into default
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Tue, 29 Oct 2024 09:38:48 +0100 |
parents | 09f3a6790e56 |
children |
rev | line source |
---|---|
32512
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
1 # bdiff.py - CFFI implementation of bdiff.c |
7703
9044d3567f6d
pure Python implementation of bdiff.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
2 # |
32512
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
3 # Copyright 2016 Maciej Fijalkowski <fijall@gmail.com> |
7703
9044d3567f6d
pure Python implementation of bdiff.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:
7944
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. |
7703
9044d3567f6d
pure Python implementation of bdiff.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
7 |
51863
f4733654f144
typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents:
51792
diff
changeset
|
8 from __future__ import annotations |
27335
c4e3ff497f89
bdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
15530
diff
changeset
|
9 |
c4e3ff497f89
bdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
15530
diff
changeset
|
10 import struct |
51934
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
11 import typing |
7944
e9b48afd0e78
pure/bdiff: fix circular import
Matt Mackall <mpm@selenic.com>
parents:
7703
diff
changeset
|
12 |
49598
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
13 from typing import ( |
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
14 List, |
51934
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
15 Optional, |
49598
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
16 Tuple, |
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
17 ) |
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
18 |
32512
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
19 from ..pure.bdiff import * |
51934
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
20 |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
21 from ..interfaces import ( |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
22 modules as intmod, |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
23 ) |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
24 |
46785
521ac0d7047f
typing: disable import error warnings that are already handled
Matt Harbison <matt_harbison@yahoo.com>
parents:
43077
diff
changeset
|
25 from . import _bdiff # pytype: disable=import-error |
7703
9044d3567f6d
pure Python implementation of bdiff.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
26 |
32512
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
27 ffi = _bdiff.ffi |
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
28 lib = _bdiff.lib |
7703
9044d3567f6d
pure Python implementation of bdiff.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
29 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
30 |
49598
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
31 def blocks(sa: bytes, sb: bytes) -> List[Tuple[int, int, int, int]]: |
51790
ecc3a893979d
cffi: pass C type and attribute names as str instead of bytes
Manuel Jacob <me@manueljacob.de>
parents:
49598
diff
changeset
|
32 a = ffi.new("struct bdiff_line**") |
ecc3a893979d
cffi: pass C type and attribute names as str instead of bytes
Manuel Jacob <me@manueljacob.de>
parents:
49598
diff
changeset
|
33 b = ffi.new("struct bdiff_line**") |
51792
472699b5ddb3
cffi: pass bytes instead of str to ffi.new("char[]", …)
Manuel Jacob <me@manueljacob.de>
parents:
51791
diff
changeset
|
34 ac = ffi.new("char[]", bytes(sa)) |
472699b5ddb3
cffi: pass bytes instead of str to ffi.new("char[]", …)
Manuel Jacob <me@manueljacob.de>
parents:
51791
diff
changeset
|
35 bc = ffi.new("char[]", bytes(sb)) |
51790
ecc3a893979d
cffi: pass C type and attribute names as str instead of bytes
Manuel Jacob <me@manueljacob.de>
parents:
49598
diff
changeset
|
36 l = ffi.new("struct bdiff_hunk*") |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
37 try: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
38 an = lib.bdiff_splitlines(ac, len(sa), a) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
39 bn = lib.bdiff_splitlines(bc, len(sb), b) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
40 if not a[0] or not b[0]: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
41 raise MemoryError |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
42 count = lib.bdiff_diff(a[0], an, b[0], bn, l) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
43 if count < 0: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
44 raise MemoryError |
49597
b2666e767029
cffi: adjust the list returned by bdiff.blocks to never have a None entry
Matt Harbison <matt_harbison@yahoo.com>
parents:
48875
diff
changeset
|
45 rl = [(0, 0, 0, 0)] * count |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
46 h = l.next |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
47 i = 0 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
48 while h: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
49 rl[i] = (h.a1, h.a2, h.b1, h.b2) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
50 h = h.next |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
51 i += 1 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
52 finally: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
53 lib.free(a[0]) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
54 lib.free(b[0]) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
55 lib.bdiff_freehunks(l.next) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
56 return rl |
29834
1ea77b75d266
bdiff: implement cffi version of bdiff
Maciej Fijalkowski <fijall@gmail.com>
parents:
29833
diff
changeset
|
57 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
58 |
49598
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
59 def bdiff(sa: bytes, sb: bytes) -> bytes: |
51790
ecc3a893979d
cffi: pass C type and attribute names as str instead of bytes
Manuel Jacob <me@manueljacob.de>
parents:
49598
diff
changeset
|
60 a = ffi.new("struct bdiff_line**") |
ecc3a893979d
cffi: pass C type and attribute names as str instead of bytes
Manuel Jacob <me@manueljacob.de>
parents:
49598
diff
changeset
|
61 b = ffi.new("struct bdiff_line**") |
51792
472699b5ddb3
cffi: pass bytes instead of str to ffi.new("char[]", …)
Manuel Jacob <me@manueljacob.de>
parents:
51791
diff
changeset
|
62 ac = ffi.new("char[]", bytes(sa)) |
472699b5ddb3
cffi: pass bytes instead of str to ffi.new("char[]", …)
Manuel Jacob <me@manueljacob.de>
parents:
51791
diff
changeset
|
63 bc = ffi.new("char[]", bytes(sb)) |
51790
ecc3a893979d
cffi: pass C type and attribute names as str instead of bytes
Manuel Jacob <me@manueljacob.de>
parents:
49598
diff
changeset
|
64 l = ffi.new("struct bdiff_hunk*") |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
65 try: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
66 an = lib.bdiff_splitlines(ac, len(sa), a) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
67 bn = lib.bdiff_splitlines(bc, len(sb), b) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
68 if not a[0] or not b[0]: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
69 raise MemoryError |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
70 count = lib.bdiff_diff(a[0], an, b[0], bn, l) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
71 if count < 0: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
72 raise MemoryError |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
73 rl = [] |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
74 h = l.next |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
75 la = lb = 0 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
76 while h: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
77 if h.a1 != la or h.b1 != lb: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
78 lgt = (b[0] + h.b1).l - (b[0] + lb).l |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
79 rl.append( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
80 struct.pack( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
81 b">lll", |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
82 (a[0] + la).l - a[0].l, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
83 (a[0] + h.a1).l - a[0].l, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
84 lgt, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
85 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
86 ) |
51791
6d7fdf90aa96
cffi: call bytes() instead of str() on CFFI buffer instances
Manuel Jacob <me@manueljacob.de>
parents:
51790
diff
changeset
|
87 rl.append(bytes(ffi.buffer((b[0] + lb).l, lgt))) |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
88 la = h.a2 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
89 lb = h.b2 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
90 h = h.next |
29834
1ea77b75d266
bdiff: implement cffi version of bdiff
Maciej Fijalkowski <fijall@gmail.com>
parents:
29833
diff
changeset
|
91 |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
92 finally: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
93 lib.free(a[0]) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
94 lib.free(b[0]) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
95 lib.bdiff_freehunks(l.next) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
96 return b"".join(rl) |
51934
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
97 |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
98 |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
99 # In order to adhere to the module protocol, these functions must be visible to |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
100 # the type checker, though they aren't actually implemented by this |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
101 # implementation of the module protocol. Callers are responsible for |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
102 # checking that the implementation is available before using them. |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
103 if typing.TYPE_CHECKING: |
09f3a6790e56
interfaces: add the optional `bdiff.xdiffblocks()` method
Matt Harbison <matt_harbison@yahoo.com>
parents:
51863
diff
changeset
|
104 xdiffblocks: Optional[intmod.BDiffBlocksFnc] = None |