Show More
@@ -0,0 +1,31 b'' | |||||
|
1 | from __future__ import absolute_import | |||
|
2 | ||||
|
3 | import cffi | |||
|
4 | import os | |||
|
5 | ||||
|
6 | ffi = cffi.FFI() | |||
|
7 | ffi.set_source("_bdiff_cffi", | |||
|
8 | open(os.path.join(os.path.join(os.path.dirname(__file__), 'mercurial'), | |||
|
9 | 'bdiff.c')).read(), include_dirs=['mercurial']) | |||
|
10 | ffi.cdef(""" | |||
|
11 | struct bdiff_line { | |||
|
12 | int hash, n, e; | |||
|
13 | ssize_t len; | |||
|
14 | const char *l; | |||
|
15 | }; | |||
|
16 | ||||
|
17 | struct bdiff_hunk; | |||
|
18 | struct bdiff_hunk { | |||
|
19 | int a1, a2, b1, b2; | |||
|
20 | struct bdiff_hunk *next; | |||
|
21 | }; | |||
|
22 | ||||
|
23 | int bdiff_splitlines(const char *a, ssize_t len, struct bdiff_line **lr); | |||
|
24 | int bdiff_diff(struct bdiff_line *a, int an, struct bdiff_line *b, int bn, | |||
|
25 | struct bdiff_hunk *base); | |||
|
26 | void bdiff_freehunks(struct bdiff_hunk *l); | |||
|
27 | void free(void*); | |||
|
28 | """) | |||
|
29 | ||||
|
30 | if __name__ == '__main__': | |||
|
31 | ffi.compile() |
@@ -12,6 +12,10 b' import difflib' | |||||
12 | import re |
|
12 | import re | |
13 | import struct |
|
13 | import struct | |
14 |
|
14 | |||
|
15 | from . import policy | |||
|
16 | policynocffi = policy.policynocffi | |||
|
17 | modulepolicy = policy.policy | |||
|
18 | ||||
15 | def splitnewlines(text): |
|
19 | def splitnewlines(text): | |
16 | '''like str.splitlines, but only split on newlines.''' |
|
20 | '''like str.splitlines, but only split on newlines.''' | |
17 | lines = [l + '\n' for l in text.split('\n')] |
|
21 | lines = [l + '\n' for l in text.split('\n')] | |
@@ -96,3 +100,37 b' def fixws(text, allws):' | |||||
96 | text = re.sub('[ \t\r]+', ' ', text) |
|
100 | text = re.sub('[ \t\r]+', ' ', text) | |
97 | text = text.replace(' \n', '\n') |
|
101 | text = text.replace(' \n', '\n') | |
98 | return text |
|
102 | return text | |
|
103 | ||||
|
104 | if modulepolicy not in policynocffi: | |||
|
105 | try: | |||
|
106 | from _bdiff_cffi import ffi, lib | |||
|
107 | except ImportError: | |||
|
108 | if modulepolicy == 'cffi': # strict cffi import | |||
|
109 | raise | |||
|
110 | else: | |||
|
111 | def blocks(sa, sb): | |||
|
112 | a = ffi.new("struct bdiff_line**") | |||
|
113 | b = ffi.new("struct bdiff_line**") | |||
|
114 | ac = ffi.new("char[]", sa) | |||
|
115 | bc = ffi.new("char[]", sb) | |||
|
116 | try: | |||
|
117 | an = lib.bdiff_splitlines(ac, len(sa), a) | |||
|
118 | bn = lib.bdiff_splitlines(bc, len(sb), b) | |||
|
119 | if not a[0] or not b[0]: | |||
|
120 | raise MemoryError | |||
|
121 | l = ffi.new("struct bdiff_hunk*") | |||
|
122 | count = lib.bdiff_diff(a[0], an, b[0], bn, l) | |||
|
123 | if count < 0: | |||
|
124 | raise MemoryError | |||
|
125 | rl = [None] * count | |||
|
126 | h = l.next | |||
|
127 | i = 0 | |||
|
128 | while h: | |||
|
129 | rl[i] = (h.a1, h.a2, h.b1, h.b2) | |||
|
130 | h = h.next | |||
|
131 | i += 1 | |||
|
132 | finally: | |||
|
133 | lib.free(a[0]) | |||
|
134 | lib.free(b[0]) | |||
|
135 | lib.bdiff_freehunks(l.next) | |||
|
136 | return rl |
@@ -319,7 +319,9 b' class hgbuildpy(build_py):' | |||||
319 | self.distribution.ext_modules = [] |
|
319 | self.distribution.ext_modules = [] | |
320 | elif self.distribution.cffi: |
|
320 | elif self.distribution.cffi: | |
321 | import setup_mpatch_cffi |
|
321 | import setup_mpatch_cffi | |
322 | exts = [setup_mpatch_cffi.ffi.distutils_extension()] |
|
322 | import setup_bdiff_cffi | |
|
323 | exts = [setup_mpatch_cffi.ffi.distutils_extension(), | |||
|
324 | setup_bdiff_cffi.ffi.distutils_extension()] | |||
323 | # cffi modules go here |
|
325 | # cffi modules go here | |
324 | if sys.platform == 'darwin': |
|
326 | if sys.platform == 'darwin': | |
325 | import setup_osutil_cffi |
|
327 | import setup_osutil_cffi |
General Comments 0
You need to be logged in to leave comments.
Login now