##// END OF EJS Templates
bdiff: implement cffi version of blocks
Maciej Fijalkowski -
r29833:a8933d99 default
parent child Browse files
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