Patchwork [5,of,5] mpatch: write a cffi version of mpatch.patches

login
register
mail settings
Submitter Maciej Fijalkowski
Date July 25, 2016, 1:10 p.m.
Message ID <a1892edea7f58fc97730.1469452259@brick.arcode.com>
Download mbox | patch
Permalink /patch/15983/
State Deferred
Headers show

Comments

Maciej Fijalkowski - July 25, 2016, 1:10 p.m.
# HG changeset patch
# User Maciej Fijalkowski <fijall@gmail.com>
# Date 1469452252 -7200
#      Mon Jul 25 15:10:52 2016 +0200
# Node ID a1892edea7f58fc97730db354877ae590446b292
# Parent  8e2d1b2d5248620ff4ccfcb61e1b383cf0e4e204
mpatch: write a cffi version of mpatch.patches
Augie Fackler - Aug. 4, 2016, 2:29 p.m.
On Mon, Jul 25, 2016 at 03:10:59PM +0200, Maciej Fijalkowski wrote:
> # HG changeset patch
> # User Maciej Fijalkowski <fijall@gmail.com>
> # Date 1469452252 -7200
> #      Mon Jul 25 15:10:52 2016 +0200
> # Node ID a1892edea7f58fc97730db354877ae590446b292
> # Parent  8e2d1b2d5248620ff4ccfcb61e1b383cf0e4e204
> mpatch: write a cffi version of mpatch.patches

Queued these, thanks!

>
> diff --git a/mercurial/pure/mpatch.py b/mercurial/pure/mpatch.py
> --- a/mercurial/pure/mpatch.py
> +++ b/mercurial/pure/mpatch.py
> @@ -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 --git a/setup.py b/setup.py
> --- a/setup.py
> +++ b/setup.py
> @@ -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
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Yuya Nishihara - Aug. 13, 2016, 9:45 a.m.
On Mon, 25 Jul 2016 15:10:59 +0200, Maciej Fijalkowski wrote:
> # HG changeset patch
> # User Maciej Fijalkowski <fijall@gmail.com>
> # Date 1469452252 -7200
> #      Mon Jul 25 15:10:52 2016 +0200
> # Node ID a1892edea7f58fc97730db354877ae590446b292
> # Parent  8e2d1b2d5248620ff4ccfcb61e1b383cf0e4e204
> mpatch: write a cffi version of mpatch.patches

> --- a/setup.py
> +++ b/setup.py
> @@ -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()]

setup_mpatch_cffi.py appears missing.

Patch

diff --git a/mercurial/pure/mpatch.py b/mercurial/pure/mpatch.py
--- a/mercurial/pure/mpatch.py
+++ b/mercurial/pure/mpatch.py
@@ -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 --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -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