--- a/contrib/check-py3-compat.py Sat Aug 13 12:15:49 2016 +0900
+++ b/contrib/check-py3-compat.py Sat Aug 13 12:18:58 2016 +0900
@@ -17,7 +17,6 @@
# Modules that have both Python and C implementations.
_dualmodules = (
- 'mpatch.py',
'parsers.py',
)
--- a/contrib/import-checker.py Sat Aug 13 12:15:49 2016 +0900
+++ b/contrib/import-checker.py Sat Aug 13 12:18:58 2016 +0900
@@ -26,7 +26,6 @@
# Modules that have both Python and C implementations.
_dualmodules = (
- 'mpatch.py',
'parsers.py',
)
--- a/contrib/wix/dist.wxs Sat Aug 13 12:15:49 2016 +0900
+++ b/contrib/wix/dist.wxs Sat Aug 13 12:18:58 2016 +0900
@@ -15,7 +15,7 @@
<File Name="mercurial.cext.base85.pyd" />
<File Name="mercurial.cext.bdiff.pyd" />
<File Name="mercurial.cext.diffhelpers.pyd" />
- <File Name="mercurial.mpatch.pyd" />
+ <File Name="mercurial.cext.mpatch.pyd" />
<File Name="mercurial.cext.osutil.pyd" />
<File Name="mercurial.parsers.pyd" />
<File Name="pyexpat.pyd" />
--- a/mercurial/__init__.py Sat Aug 13 12:15:49 2016 +0900
+++ b/mercurial/__init__.py Sat Aug 13 12:18:58 2016 +0900
@@ -23,7 +23,6 @@
# Modules that have both Python and C implementations. See also the
# set of .py files under mercurial/pure/.
_dualmodules = {
- 'mercurial.mpatch',
'mercurial.parsers',
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cext/mpatch.c Sat Aug 13 12:18:58 2016 +0900
@@ -0,0 +1,200 @@
+/*
+ mpatch.c - efficient binary patching for Mercurial
+
+ This implements a patch algorithm that's O(m + nlog n) where m is the
+ size of the output and n is the number of patches.
+
+ Given a list of binary patches, it unpacks each into a hunk list,
+ then combines the hunk lists with a treewise recursion to form a
+ single hunk list. This hunk list is then applied to the original
+ text.
+
+ The text (or binary) fragments are copied directly from their source
+ Python objects into a preallocated output string to avoid the
+ allocation of intermediate Python objects. Working memory is about 2x
+ the total number of hunks.
+
+ Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+
+ This software may be used and distributed according to the terms
+ of the GNU General Public License, incorporated herein by reference.
+*/
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+#include "bitmanipulation.h"
+#include "compat.h"
+#include "mpatch.h"
+
+static char mpatch_doc[] = "Efficient binary patching.";
+static PyObject *mpatch_Error;
+
+static void setpyerr(int r)
+{
+ switch (r) {
+ case MPATCH_ERR_NO_MEM:
+ PyErr_NoMemory();
+ break;
+ case MPATCH_ERR_CANNOT_BE_DECODED:
+ PyErr_SetString(mpatch_Error, "patch cannot be decoded");
+ break;
+ case MPATCH_ERR_INVALID_PATCH:
+ PyErr_SetString(mpatch_Error, "invalid patch");
+ break;
+ }
+}
+
+struct mpatch_flist *cpygetitem(void *bins, ssize_t pos)
+{
+ const char *buffer;
+ struct mpatch_flist *res;
+ ssize_t blen;
+ int r;
+
+ PyObject *tmp = PyList_GetItem((PyObject*)bins, pos);
+ if (!tmp)
+ return NULL;
+ if (PyObject_AsCharBuffer(tmp, &buffer, (Py_ssize_t*)&blen))
+ return NULL;
+ if ((r = mpatch_decode(buffer, blen, &res)) < 0) {
+ if (!PyErr_Occurred())
+ setpyerr(r);
+ return NULL;
+ }
+ return res;
+}
+
+static PyObject *
+patches(PyObject *self, PyObject *args)
+{
+ PyObject *text, *bins, *result;
+ struct mpatch_flist *patch;
+ const char *in;
+ int r = 0;
+ char *out;
+ Py_ssize_t len, outlen, inlen;
+
+ if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins))
+ return NULL;
+
+ len = PyList_Size(bins);
+ if (!len) {
+ /* nothing to do */
+ Py_INCREF(text);
+ return text;
+ }
+
+ if (PyObject_AsCharBuffer(text, &in, &inlen))
+ return NULL;
+
+ patch = mpatch_fold(bins, cpygetitem, 0, len);
+ if (!patch) { /* error already set or memory error */
+ if (!PyErr_Occurred())
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ outlen = mpatch_calcsize(inlen, patch);
+ if (outlen < 0) {
+ r = (int)outlen;
+ result = NULL;
+ goto cleanup;
+ }
+ result = PyBytes_FromStringAndSize(NULL, outlen);
+ if (!result) {
+ result = NULL;
+ goto cleanup;
+ }
+ out = PyBytes_AsString(result);
+ if ((r = mpatch_apply(out, in, inlen, patch)) < 0) {
+ Py_DECREF(result);
+ result = NULL;
+ }
+cleanup:
+ mpatch_lfree(patch);
+ if (!result && !PyErr_Occurred())
+ setpyerr(r);
+ return result;
+}
+
+/* calculate size of a patched file directly */
+static PyObject *
+patchedsize(PyObject *self, PyObject *args)
+{
+ long orig, start, end, len, outlen = 0, last = 0, pos = 0;
+ Py_ssize_t patchlen;
+ char *bin;
+
+ if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
+ return NULL;
+
+ while (pos >= 0 && pos < patchlen) {
+ start = getbe32(bin + pos);
+ end = getbe32(bin + pos + 4);
+ len = getbe32(bin + pos + 8);
+ if (start > end)
+ break; /* sanity check */
+ pos += 12 + len;
+ outlen += start - last;
+ last = end;
+ outlen += len;
+ }
+
+ if (pos != patchlen) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(mpatch_Error, "patch cannot be decoded");
+ return NULL;
+ }
+
+ outlen += orig - last;
+ return Py_BuildValue("l", outlen);
+}
+
+static PyMethodDef methods[] = {
+ {"patches", patches, METH_VARARGS, "apply a series of patches\n"},
+ {"patchedsize", patchedsize, METH_VARARGS, "calculed patched size\n"},
+ {NULL, NULL}
+};
+
+static const int version = 1;
+
+#ifdef IS_PY3K
+static struct PyModuleDef mpatch_module = {
+ PyModuleDef_HEAD_INIT,
+ "mpatch",
+ mpatch_doc,
+ -1,
+ methods
+};
+
+PyMODINIT_FUNC PyInit_mpatch(void)
+{
+ PyObject *m;
+
+ m = PyModule_Create(&mpatch_module);
+ if (m == NULL)
+ return NULL;
+
+ mpatch_Error = PyErr_NewException("mercurial.cext.mpatch.mpatchError",
+ NULL, NULL);
+ Py_INCREF(mpatch_Error);
+ PyModule_AddObject(m, "mpatchError", mpatch_Error);
+ PyModule_AddIntConstant(m, "version", version);
+
+ return m;
+}
+#else
+PyMODINIT_FUNC
+initmpatch(void)
+{
+ PyObject *m;
+ m = Py_InitModule3("mpatch", methods, mpatch_doc);
+ mpatch_Error = PyErr_NewException("mercurial.cext.mpatch.mpatchError",
+ NULL, NULL);
+ PyModule_AddIntConstant(m, "version", version);
+}
+#endif
--- a/mercurial/debugcommands.py Sat Aug 13 12:15:49 2016 +0900
+++ b/mercurial/debugcommands.py Sat Aug 13 12:18:58 2016 +0900
@@ -1025,12 +1025,10 @@
if policy.policy in ('c', 'allow'):
err = None
try:
- from . import (
- mpatch,
- )
from .cext import (
base85,
bdiff,
+ mpatch,
osutil,
)
dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
--- a/mercurial/mdiff.py Sat Aug 13 12:15:49 2016 +0900
+++ b/mercurial/mdiff.py Sat Aug 13 12:18:58 2016 +0900
@@ -14,13 +14,13 @@
from .i18n import _
from . import (
error,
- mpatch,
policy,
pycompat,
util,
)
bdiff = policy.importmod(r'bdiff')
+mpatch = policy.importmod(r'mpatch')
blocks = bdiff.blocks
fixws = bdiff.fixws
--- a/mercurial/mpatch_module.c Sat Aug 13 12:15:49 2016 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- mpatch.c - efficient binary patching for Mercurial
-
- This implements a patch algorithm that's O(m + nlog n) where m is the
- size of the output and n is the number of patches.
-
- Given a list of binary patches, it unpacks each into a hunk list,
- then combines the hunk lists with a treewise recursion to form a
- single hunk list. This hunk list is then applied to the original
- text.
-
- The text (or binary) fragments are copied directly from their source
- Python objects into a preallocated output string to avoid the
- allocation of intermediate Python objects. Working memory is about 2x
- the total number of hunks.
-
- Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-*/
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "util.h"
-#include "bitmanipulation.h"
-#include "compat.h"
-#include "mpatch.h"
-
-static char mpatch_doc[] = "Efficient binary patching.";
-static PyObject *mpatch_Error;
-
-static void setpyerr(int r)
-{
- switch (r) {
- case MPATCH_ERR_NO_MEM:
- PyErr_NoMemory();
- break;
- case MPATCH_ERR_CANNOT_BE_DECODED:
- PyErr_SetString(mpatch_Error, "patch cannot be decoded");
- break;
- case MPATCH_ERR_INVALID_PATCH:
- PyErr_SetString(mpatch_Error, "invalid patch");
- break;
- }
-}
-
-struct mpatch_flist *cpygetitem(void *bins, ssize_t pos)
-{
- const char *buffer;
- struct mpatch_flist *res;
- ssize_t blen;
- int r;
-
- PyObject *tmp = PyList_GetItem((PyObject*)bins, pos);
- if (!tmp)
- return NULL;
- if (PyObject_AsCharBuffer(tmp, &buffer, (Py_ssize_t*)&blen))
- return NULL;
- if ((r = mpatch_decode(buffer, blen, &res)) < 0) {
- if (!PyErr_Occurred())
- setpyerr(r);
- return NULL;
- }
- return res;
-}
-
-static PyObject *
-patches(PyObject *self, PyObject *args)
-{
- PyObject *text, *bins, *result;
- struct mpatch_flist *patch;
- const char *in;
- int r = 0;
- char *out;
- Py_ssize_t len, outlen, inlen;
-
- if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins))
- return NULL;
-
- len = PyList_Size(bins);
- if (!len) {
- /* nothing to do */
- Py_INCREF(text);
- return text;
- }
-
- if (PyObject_AsCharBuffer(text, &in, &inlen))
- return NULL;
-
- patch = mpatch_fold(bins, cpygetitem, 0, len);
- if (!patch) { /* error already set or memory error */
- if (!PyErr_Occurred())
- PyErr_NoMemory();
- return NULL;
- }
-
- outlen = mpatch_calcsize(inlen, patch);
- if (outlen < 0) {
- r = (int)outlen;
- result = NULL;
- goto cleanup;
- }
- result = PyBytes_FromStringAndSize(NULL, outlen);
- if (!result) {
- result = NULL;
- goto cleanup;
- }
- out = PyBytes_AsString(result);
- if ((r = mpatch_apply(out, in, inlen, patch)) < 0) {
- Py_DECREF(result);
- result = NULL;
- }
-cleanup:
- mpatch_lfree(patch);
- if (!result && !PyErr_Occurred())
- setpyerr(r);
- return result;
-}
-
-/* calculate size of a patched file directly */
-static PyObject *
-patchedsize(PyObject *self, PyObject *args)
-{
- long orig, start, end, len, outlen = 0, last = 0, pos = 0;
- Py_ssize_t patchlen;
- char *bin;
-
- if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
- return NULL;
-
- while (pos >= 0 && pos < patchlen) {
- start = getbe32(bin + pos);
- end = getbe32(bin + pos + 4);
- len = getbe32(bin + pos + 8);
- if (start > end)
- break; /* sanity check */
- pos += 12 + len;
- outlen += start - last;
- last = end;
- outlen += len;
- }
-
- if (pos != patchlen) {
- if (!PyErr_Occurred())
- PyErr_SetString(mpatch_Error, "patch cannot be decoded");
- return NULL;
- }
-
- outlen += orig - last;
- return Py_BuildValue("l", outlen);
-}
-
-static PyMethodDef methods[] = {
- {"patches", patches, METH_VARARGS, "apply a series of patches\n"},
- {"patchedsize", patchedsize, METH_VARARGS, "calculed patched size\n"},
- {NULL, NULL}
-};
-
-static const int version = 1;
-
-#ifdef IS_PY3K
-static struct PyModuleDef mpatch_module = {
- PyModuleDef_HEAD_INIT,
- "mpatch",
- mpatch_doc,
- -1,
- methods
-};
-
-PyMODINIT_FUNC PyInit_mpatch(void)
-{
- PyObject *m;
-
- m = PyModule_Create(&mpatch_module);
- if (m == NULL)
- return NULL;
-
- mpatch_Error = PyErr_NewException("mercurial.mpatch.mpatchError",
- NULL, NULL);
- Py_INCREF(mpatch_Error);
- PyModule_AddObject(m, "mpatchError", mpatch_Error);
- PyModule_AddIntConstant(m, "version", version);
-
- return m;
-}
-#else
-PyMODINIT_FUNC
-initmpatch(void)
-{
- PyObject *m;
- m = Py_InitModule3("mpatch", methods, mpatch_doc);
- mpatch_Error = PyErr_NewException("mercurial.mpatch.mpatchError",
- NULL, NULL);
- PyModule_AddIntConstant(m, "version", version);
-}
-#endif
--- a/mercurial/pure/mpatch.py Sat Aug 13 12:15:49 2016 +0900
+++ b/mercurial/pure/mpatch.py Sat Aug 13 12:18:58 2016 +0900
@@ -9,7 +9,7 @@
import struct
-from . import policy, pycompat
+from .. import policy, pycompat
stringio = pycompat.stringio
modulepolicy = policy.policy
policynocffi = policy.policynocffi
@@ -167,4 +167,3 @@
res = ffi.buffer(buf, outlen)[:]
lib.mpatch_lfree(patch)
return res
-
--- a/setup.py Sat Aug 13 12:15:49 2016 +0900
+++ b/setup.py Sat Aug 13 12:18:58 2016 +0900
@@ -631,8 +631,8 @@
Extension('mercurial.cext.diffhelpers', ['mercurial/cext/diffhelpers.c'],
include_dirs=common_include_dirs,
depends=common_depends),
- Extension('mercurial.mpatch', ['mercurial/mpatch.c',
- 'mercurial/mpatch_module.c'],
+ Extension('mercurial.cext.mpatch', ['mercurial/mpatch.c',
+ 'mercurial/cext/mpatch.c'],
include_dirs=common_include_dirs,
depends=common_depends),
Extension('mercurial.parsers', ['mercurial/dirs.c',
--- a/tests/test-revlog.t Sat Aug 13 12:15:49 2016 +0900
+++ b/tests/test-revlog.t Sat Aug 13 12:18:58 2016 +0900
@@ -12,4 +12,4 @@
0 0 19 -1 2 99e0332bd498 000000000000 000000000000
1 19 12 0 3 6674f57a23d8 99e0332bd498 000000000000
$ hg debugdata a.i 1 2>&1 | egrep 'Error:.*decoded'
- (mercurial.mpatch.)?mpatchError: patch cannot be decoded (re)
+ (mercurial\.\w+\.mpatch\.)?mpatchError: patch cannot be decoded (re)