# HG changeset patch # User Maciej Fijalkowski # Date 1469452252 -7200 # Node ID f2846d54664567083fdd8e400b8021e09b498c48 # Parent 55dd12204b8e15e6f64ab676115655ff52880709 mpatch: write a cffi version of mpatch.patches diff -r 55dd12204b8e -r f2846d546645 mercurial/pure/mpatch.py --- a/mercurial/pure/mpatch.py Fri Jul 22 17:28:05 2016 +0200 +++ b/mercurial/pure/mpatch.py Mon Jul 25 15:10:52 2016 +0200 @@ -9,8 +9,10 @@ import struct -from . import pycompat +from . import policy, pycompat stringio = pycompat.stringio +modulepolicy = policy.policy +policynocffi = policy.policynocffi class mpatchError(Exception): """error raised when a delta cannot be decoded @@ -125,3 +127,44 @@ outlen += orig - last return outlen + +if modulepolicy not in policynocffi: + try: + from _mpatch_cffi import ffi, lib + except ImportError: + if modulepolicy == 'cffi': # strict cffi import + raise + else: + @ffi.def_extern() + def cffi_get_next_item(arg, pos): + all, bins = ffi.from_handle(arg) + container = ffi.new("struct mpatch_flist*[1]") + to_pass = ffi.new("char[]", str(bins[pos])) + all.append(to_pass) + r = lib.mpatch_decode(to_pass, len(to_pass) - 1, container) + if r < 0: + return ffi.NULL + return container[0] + + def patches(text, bins): + lgt = len(bins) + all = [] + if not lgt: + return text + arg = (all, bins) + patch = lib.mpatch_fold(ffi.new_handle(arg), + lib.cffi_get_next_item, 0, lgt) + if not patch: + raise mpatchError("cannot decode chunk") + outlen = lib.mpatch_calcsize(len(text), patch) + if outlen < 0: + lib.mpatch_lfree(patch) + raise mpatchError("inconsistency detected") + buf = ffi.new("char[]", outlen) + if lib.mpatch_apply(buf, text, len(text), patch) < 0: + lib.mpatch_lfree(patch) + raise mpatchError("error applying patches") + res = ffi.buffer(buf, outlen)[:] + lib.mpatch_lfree(patch) + return res + diff -r 55dd12204b8e -r f2846d546645 setup.py --- a/setup.py Fri Jul 22 17:28:05 2016 +0200 +++ b/setup.py Mon Jul 25 15:10:52 2016 +0200 @@ -318,7 +318,8 @@ if self.distribution.pure: self.distribution.ext_modules = [] elif self.distribution.cffi: - exts = [] + import setup_mpatch_cffi + exts = [setup_mpatch_cffi.ffi.distutils_extension()] # cffi modules go here if sys.platform == 'darwin': import setup_osutil_cffi