Mercurial > public > mercurial-scm > hg
diff mercurial/pure/bdiff.py @ 29833:a8933d992a71
bdiff: implement cffi version of blocks
author | Maciej Fijalkowski <fijall@gmail.com> |
---|---|
date | Thu, 28 Jul 2016 14:17:08 +0200 |
parents | 9ab45fbe045e |
children | 1ea77b75d266 |
line wrap: on
line diff
--- a/mercurial/pure/bdiff.py Fri Aug 19 13:30:40 2016 -0700 +++ b/mercurial/pure/bdiff.py Thu Jul 28 14:17:08 2016 +0200 @@ -12,6 +12,10 @@ import re import struct +from . import policy +policynocffi = policy.policynocffi +modulepolicy = policy.policy + def splitnewlines(text): '''like str.splitlines, but only split on newlines.''' lines = [l + '\n' for l in text.split('\n')] @@ -96,3 +100,37 @@ text = re.sub('[ \t\r]+', ' ', text) text = text.replace(' \n', '\n') return text + +if modulepolicy not in policynocffi: + try: + from _bdiff_cffi import ffi, lib + except ImportError: + if modulepolicy == 'cffi': # strict cffi import + raise + else: + def blocks(sa, sb): + a = ffi.new("struct bdiff_line**") + b = ffi.new("struct bdiff_line**") + ac = ffi.new("char[]", sa) + bc = ffi.new("char[]", sb) + try: + an = lib.bdiff_splitlines(ac, len(sa), a) + bn = lib.bdiff_splitlines(bc, len(sb), b) + if not a[0] or not b[0]: + raise MemoryError + l = ffi.new("struct bdiff_hunk*") + count = lib.bdiff_diff(a[0], an, b[0], bn, l) + if count < 0: + raise MemoryError + rl = [None] * count + h = l.next + i = 0 + while h: + rl[i] = (h.a1, h.a2, h.b1, h.b2) + h = h.next + i += 1 + finally: + lib.free(a[0]) + lib.free(b[0]) + lib.bdiff_freehunks(l.next) + return rl