--- 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
+
--- 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