cffi: split modules from pure
The copyright lines are updated per change history.
cffi/osutil.py isn't tested since I have no access to OS X machine right now,
sorry.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cffi/base85.py Tue May 02 21:15:31 2017 +0900
@@ -0,0 +1,10 @@
+# base85.py: pure python base85 codec
+#
+# Copyright (C) 2009 Brendan Cully <brendan@kublai.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+from ..pure.base85 import *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cffi/bdiff.py Tue May 02 21:15:31 2017 +0900
@@ -0,0 +1,78 @@
+# bdiff.py - CFFI implementation of bdiff.c
+#
+# Copyright 2016 Maciej Fijalkowski <fijall@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+import struct
+
+from ..pure.bdiff import *
+from . import _bdiff
+
+ffi = _bdiff.ffi
+lib = _bdiff.lib
+
+if True:
+ if True:
+ def blocks(sa, sb):
+ a = ffi.new("struct bdiff_line**")
+ b = ffi.new("struct bdiff_line**")
+ ac = ffi.new("char[]", str(sa))
+ bc = ffi.new("char[]", str(sb))
+ l = ffi.new("struct bdiff_hunk*")
+ try:
+ an = lib.bdiff_splitlines(ac, len(sa), a)
+ bn = lib.bdiff_splitlines(bc, len(sb), b)
+ if not a[0] or not b[0]:
+ raise MemoryError
+ count = lib.bdiff_diff(a[0], an, b[0], bn, l)
+ if count < 0:
+ raise MemoryError
+ rl = [None] * count
+ h = l.next
+ i = 0
+ while h:
+ rl[i] = (h.a1, h.a2, h.b1, h.b2)
+ h = h.next
+ i += 1
+ finally:
+ lib.free(a[0])
+ lib.free(b[0])
+ lib.bdiff_freehunks(l.next)
+ return rl
+
+ def bdiff(sa, sb):
+ a = ffi.new("struct bdiff_line**")
+ b = ffi.new("struct bdiff_line**")
+ ac = ffi.new("char[]", str(sa))
+ bc = ffi.new("char[]", str(sb))
+ l = ffi.new("struct bdiff_hunk*")
+ try:
+ an = lib.bdiff_splitlines(ac, len(sa), a)
+ bn = lib.bdiff_splitlines(bc, len(sb), b)
+ if not a[0] or not b[0]:
+ raise MemoryError
+ count = lib.bdiff_diff(a[0], an, b[0], bn, l)
+ if count < 0:
+ raise MemoryError
+ rl = []
+ h = l.next
+ la = lb = 0
+ while h:
+ if h.a1 != la or h.b1 != lb:
+ lgt = (b[0] + h.b1).l - (b[0] + lb).l
+ rl.append(struct.pack(">lll", (a[0] + la).l - a[0].l,
+ (a[0] + h.a1).l - a[0].l, lgt))
+ rl.append(str(ffi.buffer((b[0] + lb).l, lgt)))
+ la = h.a2
+ lb = h.b2
+ h = h.next
+
+ finally:
+ lib.free(a[0])
+ lib.free(b[0])
+ lib.bdiff_freehunks(l.next)
+ return "".join(rl)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cffi/diffhelpers.py Tue May 02 21:15:31 2017 +0900
@@ -0,0 +1,10 @@
+# diffhelpers.py - pure Python implementation of diffhelpers.c
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+from ..pure.diffhelpers import *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cffi/mpatch.py Tue May 02 21:15:31 2017 +0900
@@ -0,0 +1,50 @@
+# mpatch.py - CFFI implementation of mpatch.c
+#
+# Copyright 2016 Maciej Fijalkowski <fijall@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+from ..pure.mpatch import *
+from ..pure.mpatch import mpatchError # silence pyflakes
+from . import _mpatch
+
+ffi = _mpatch.ffi
+lib = _mpatch.lib
+
+if True:
+ if True:
+ @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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cffi/osutil.py Tue May 02 21:15:31 2017 +0900
@@ -0,0 +1,102 @@
+# osutil.py - CFFI version of osutil.c
+#
+# Copyright 2016 Maciej Fijalkowski <fijall@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+import os
+import stat as statmod
+
+from ..pure.osutil import *
+
+from .. import (
+ pycompat,
+)
+
+if pycompat.sysplatform == 'darwin':
+ from . import _osutil
+
+ ffi = _osutil.ffi
+ lib = _osutil.lib
+
+ listdir_batch_size = 4096
+ # tweakable number, only affects performance, which chunks
+ # of bytes do we get back from getattrlistbulk
+
+ attrkinds = [None] * 20 # we need the max no for enum VXXX, 20 is plenty
+
+ attrkinds[lib.VREG] = statmod.S_IFREG
+ attrkinds[lib.VDIR] = statmod.S_IFDIR
+ attrkinds[lib.VLNK] = statmod.S_IFLNK
+ attrkinds[lib.VBLK] = statmod.S_IFBLK
+ attrkinds[lib.VCHR] = statmod.S_IFCHR
+ attrkinds[lib.VFIFO] = statmod.S_IFIFO
+ attrkinds[lib.VSOCK] = statmod.S_IFSOCK
+
+ class stat_res(object):
+ def __init__(self, st_mode, st_mtime, st_size):
+ self.st_mode = st_mode
+ self.st_mtime = st_mtime
+ self.st_size = st_size
+
+ tv_sec_ofs = ffi.offsetof("struct timespec", "tv_sec")
+ buf = ffi.new("char[]", listdir_batch_size)
+
+ def listdirinternal(dfd, req, stat, skip):
+ ret = []
+ while True:
+ r = lib.getattrlistbulk(dfd, req, buf, listdir_batch_size, 0)
+ if r == 0:
+ break
+ if r == -1:
+ raise OSError(ffi.errno, os.strerror(ffi.errno))
+ cur = ffi.cast("val_attrs_t*", buf)
+ for i in range(r):
+ lgt = cur.length
+ assert lgt == ffi.cast('uint32_t*', cur)[0]
+ ofs = cur.name_info.attr_dataoffset
+ str_lgt = cur.name_info.attr_length
+ base_ofs = ffi.offsetof('val_attrs_t', 'name_info')
+ name = str(ffi.buffer(ffi.cast("char*", cur) + base_ofs + ofs,
+ str_lgt - 1))
+ tp = attrkinds[cur.obj_type]
+ if name == "." or name == "..":
+ continue
+ if skip == name and tp == statmod.S_ISDIR:
+ return []
+ if stat:
+ mtime = cur.mtime.tv_sec
+ mode = (cur.accessmask & ~lib.S_IFMT)| tp
+ ret.append((name, tp, stat_res(st_mode=mode, st_mtime=mtime,
+ st_size=cur.datalength)))
+ else:
+ ret.append((name, tp))
+ cur = ffi.cast("val_attrs_t*", int(ffi.cast("intptr_t", cur))
+ + lgt)
+ return ret
+
+ def listdir(path, stat=False, skip=None):
+ req = ffi.new("struct attrlist*")
+ req.bitmapcount = lib.ATTR_BIT_MAP_COUNT
+ req.commonattr = (lib.ATTR_CMN_RETURNED_ATTRS |
+ lib.ATTR_CMN_NAME |
+ lib.ATTR_CMN_OBJTYPE |
+ lib.ATTR_CMN_ACCESSMASK |
+ lib.ATTR_CMN_MODTIME)
+ req.fileattr = lib.ATTR_FILE_DATALENGTH
+ dfd = lib.open(path, lib.O_RDONLY, 0)
+ if dfd == -1:
+ raise OSError(ffi.errno, os.strerror(ffi.errno))
+
+ try:
+ ret = listdirinternal(dfd, req, stat, skip)
+ finally:
+ try:
+ lib.close(dfd)
+ except BaseException:
+ pass # we ignore all the errors from closing, not
+ # much we can do about that
+ return ret
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cffi/parsers.py Tue May 02 21:15:31 2017 +0900
@@ -0,0 +1,10 @@
+# parsers.py - Python implementation of parsers.c
+#
+# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+from ..pure.parsers import *
--- a/mercurial/policy.py Sun May 28 15:45:52 2017 +0900
+++ b/mercurial/policy.py Tue May 02 21:15:31 2017 +0900
@@ -28,8 +28,8 @@
# policy: (versioned package, pure package)
b'c': (r'cext', None),
b'allow': (r'cext', r'pure'),
- b'cffi': (None, r'pure'), # TODO: (r'cffi', None)
- b'cffi-allow': (None, r'pure'), # TODO: (r'cffi', r'pure')
+ b'cffi': (r'cffi', None),
+ b'cffi-allow': (r'cffi', r'pure'),
b'py': (None, r'pure'),
}
--- a/mercurial/pure/bdiff.py Sun May 28 15:45:52 2017 +0900
+++ b/mercurial/pure/bdiff.py Tue May 02 21:15:31 2017 +0900
@@ -11,10 +11,6 @@
import re
import struct
-from .. import policy
-policynocffi = policy.policynocffi
-modulepolicy = policy.policy
-
def splitnewlines(text):
'''like str.splitlines, but only split on newlines.'''
lines = [l + '\n' for l in text.split('\n')]
@@ -93,70 +89,3 @@
text = re.sub('[ \t\r]+', ' ', text)
text = text.replace(' \n', '\n')
return text
-
-if modulepolicy not in policynocffi:
- try:
- from ..cffi._bdiff import ffi, lib
- except ImportError:
- if modulepolicy == 'cffi': # strict cffi import
- raise
- else:
- def blocks(sa, sb):
- a = ffi.new("struct bdiff_line**")
- b = ffi.new("struct bdiff_line**")
- ac = ffi.new("char[]", str(sa))
- bc = ffi.new("char[]", str(sb))
- l = ffi.new("struct bdiff_hunk*")
- try:
- an = lib.bdiff_splitlines(ac, len(sa), a)
- bn = lib.bdiff_splitlines(bc, len(sb), b)
- if not a[0] or not b[0]:
- raise MemoryError
- count = lib.bdiff_diff(a[0], an, b[0], bn, l)
- if count < 0:
- raise MemoryError
- rl = [None] * count
- h = l.next
- i = 0
- while h:
- rl[i] = (h.a1, h.a2, h.b1, h.b2)
- h = h.next
- i += 1
- finally:
- lib.free(a[0])
- lib.free(b[0])
- lib.bdiff_freehunks(l.next)
- return rl
-
- def bdiff(sa, sb):
- a = ffi.new("struct bdiff_line**")
- b = ffi.new("struct bdiff_line**")
- ac = ffi.new("char[]", str(sa))
- bc = ffi.new("char[]", str(sb))
- l = ffi.new("struct bdiff_hunk*")
- try:
- an = lib.bdiff_splitlines(ac, len(sa), a)
- bn = lib.bdiff_splitlines(bc, len(sb), b)
- if not a[0] or not b[0]:
- raise MemoryError
- count = lib.bdiff_diff(a[0], an, b[0], bn, l)
- if count < 0:
- raise MemoryError
- rl = []
- h = l.next
- la = lb = 0
- while h:
- if h.a1 != la or h.b1 != lb:
- lgt = (b[0] + h.b1).l - (b[0] + lb).l
- rl.append(struct.pack(">lll", (a[0] + la).l - a[0].l,
- (a[0] + h.a1).l - a[0].l, lgt))
- rl.append(str(ffi.buffer((b[0] + lb).l, lgt)))
- la = h.a2
- lb = h.b2
- h = h.next
-
- finally:
- lib.free(a[0])
- lib.free(b[0])
- lib.bdiff_freehunks(l.next)
- return "".join(rl)
--- a/mercurial/pure/mpatch.py Sun May 28 15:45:52 2017 +0900
+++ b/mercurial/pure/mpatch.py Tue May 02 21:15:31 2017 +0900
@@ -9,10 +9,8 @@
import struct
-from .. import policy, pycompat
+from .. import pycompat
stringio = pycompat.stringio
-modulepolicy = policy.policy
-policynocffi = policy.policynocffi
class mpatchError(Exception):
"""error raised when a delta cannot be decoded
@@ -127,43 +125,3 @@
outlen += orig - last
return outlen
-
-if modulepolicy not in policynocffi:
- try:
- from ..cffi._mpatch 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/mercurial/pure/osutil.py Sun May 28 15:45:52 2017 +0900
+++ b/mercurial/pure/osutil.py Tue May 02 21:15:31 2017 +0900
@@ -14,13 +14,9 @@
import stat as statmod
from .. import (
- policy,
pycompat,
)
-modulepolicy = policy.policy
-policynocffi = policy.policynocffi
-
def _mode_to_kind(mode):
if statmod.S_ISREG(mode):
return statmod.S_IFREG
@@ -38,7 +34,7 @@
return statmod.S_IFSOCK
return mode
-def listdirpure(path, stat=False, skip=None):
+def listdir(path, stat=False, skip=None):
'''listdir(path, stat=False) -> list_of_tuples
Return a sorted list containing information about the entries
@@ -68,96 +64,6 @@
result.append((fn, _mode_to_kind(st.st_mode)))
return result
-ffi = None
-if modulepolicy not in policynocffi and pycompat.sysplatform == 'darwin':
- try:
- from ..cffi._osutil import ffi, lib
- except ImportError:
- if modulepolicy == 'cffi': # strict cffi import
- raise
-
-if pycompat.sysplatform == 'darwin' and ffi is not None:
- listdir_batch_size = 4096
- # tweakable number, only affects performance, which chunks
- # of bytes do we get back from getattrlistbulk
-
- attrkinds = [None] * 20 # we need the max no for enum VXXX, 20 is plenty
-
- attrkinds[lib.VREG] = statmod.S_IFREG
- attrkinds[lib.VDIR] = statmod.S_IFDIR
- attrkinds[lib.VLNK] = statmod.S_IFLNK
- attrkinds[lib.VBLK] = statmod.S_IFBLK
- attrkinds[lib.VCHR] = statmod.S_IFCHR
- attrkinds[lib.VFIFO] = statmod.S_IFIFO
- attrkinds[lib.VSOCK] = statmod.S_IFSOCK
-
- class stat_res(object):
- def __init__(self, st_mode, st_mtime, st_size):
- self.st_mode = st_mode
- self.st_mtime = st_mtime
- self.st_size = st_size
-
- tv_sec_ofs = ffi.offsetof("struct timespec", "tv_sec")
- buf = ffi.new("char[]", listdir_batch_size)
-
- def listdirinternal(dfd, req, stat, skip):
- ret = []
- while True:
- r = lib.getattrlistbulk(dfd, req, buf, listdir_batch_size, 0)
- if r == 0:
- break
- if r == -1:
- raise OSError(ffi.errno, os.strerror(ffi.errno))
- cur = ffi.cast("val_attrs_t*", buf)
- for i in range(r):
- lgt = cur.length
- assert lgt == ffi.cast('uint32_t*', cur)[0]
- ofs = cur.name_info.attr_dataoffset
- str_lgt = cur.name_info.attr_length
- base_ofs = ffi.offsetof('val_attrs_t', 'name_info')
- name = str(ffi.buffer(ffi.cast("char*", cur) + base_ofs + ofs,
- str_lgt - 1))
- tp = attrkinds[cur.obj_type]
- if name == "." or name == "..":
- continue
- if skip == name and tp == statmod.S_ISDIR:
- return []
- if stat:
- mtime = cur.mtime.tv_sec
- mode = (cur.accessmask & ~lib.S_IFMT)| tp
- ret.append((name, tp, stat_res(st_mode=mode, st_mtime=mtime,
- st_size=cur.datalength)))
- else:
- ret.append((name, tp))
- cur = ffi.cast("val_attrs_t*", int(ffi.cast("intptr_t", cur))
- + lgt)
- return ret
-
- def listdir(path, stat=False, skip=None):
- req = ffi.new("struct attrlist*")
- req.bitmapcount = lib.ATTR_BIT_MAP_COUNT
- req.commonattr = (lib.ATTR_CMN_RETURNED_ATTRS |
- lib.ATTR_CMN_NAME |
- lib.ATTR_CMN_OBJTYPE |
- lib.ATTR_CMN_ACCESSMASK |
- lib.ATTR_CMN_MODTIME)
- req.fileattr = lib.ATTR_FILE_DATALENGTH
- dfd = lib.open(path, lib.O_RDONLY, 0)
- if dfd == -1:
- raise OSError(ffi.errno, os.strerror(ffi.errno))
-
- try:
- ret = listdirinternal(dfd, req, stat, skip)
- finally:
- try:
- lib.close(dfd)
- except BaseException:
- pass # we ignore all the errors from closing, not
- # much we can do about that
- return ret
-else:
- listdir = listdirpure
-
if pycompat.osname != 'nt':
posixfile = open