diff --git a/contrib/check-code.py b/contrib/check-code.py --- a/contrib/check-code.py +++ b/contrib/check-code.py @@ -249,7 +249,8 @@ (r"[^_]_\([ \t\n]*(?:'[^']+'[ \t\n+]*)+%", "don't use % inside _()"), (r'(\w|\)),\w', "missing whitespace after ,"), (r'(\w|\))[+/*\-<>]\w', "missing whitespace in expression"), - (r'^\s+(\w|\.)+=\w[^,()\n]*$', "missing whitespace in assignment"), +# false positive on multi-line keyword arguments +# (r'^\s+(\w|\.)+=\w[^,()\n]*$', "missing whitespace in assignment"), (r'\w\s=\s\s+\w', "gratuitous whitespace after ="), (( # a line ending with a colon, potentially with trailing comments diff --git a/mercurial/thirdparty/xdiff.c b/mercurial/thirdparty/xdiff.c new file mode 100644 --- /dev/null +++ b/mercurial/thirdparty/xdiff.c @@ -0,0 +1,96 @@ +/* + xdiff.c: simple Python wrapper for xdiff library + + Copyright (c) 2018 Facebook, Inc. + + This software may be used and distributed according to the terms of the + GNU General Public License version 2 or any later version. +*/ + +#include "xdiff.h" +#include "Python.h" + +static int hunk_consumer(long a1, long a2, long b1, long b2, void *priv) +{ + PyObject *rl = (PyObject *)priv; + PyObject *m = Py_BuildValue("llll", a1, a2, b1, b2); + if (!m) + return -1; + if (PyList_Append(rl, m) != 0) { + Py_DECREF(m); + return -1; + } + return 0; +} + +static PyObject *blocks(PyObject *self, PyObject *args) +{ + char *sa, *sb; + int na, nb; + + if (!PyArg_ParseTuple(args, "s#s#", &sa, &na, &sb, &nb)) + return NULL; + + mmfile_t a = {sa, na}, b = {sb, nb}; + + PyObject *rl = PyList_New(0); + if (!rl) + return PyErr_NoMemory(); + + xpparam_t xpp = { + 0, /* flags */ + NULL, /* anchors */ + 0, /* anchors_nr */ + }; + xdemitconf_t xecfg = { + 0, /* ctxlen */ + 0, /* interhunkctxlen */ + XDL_EMIT_BDIFFHUNK, /* flags */ + NULL, /* find_func */ + NULL, /* find_func_priv */ + hunk_consumer, /* hunk_consume_func */ + }; + xdemitcb_t ecb = { + rl, /* priv */ + NULL, /* outf */ + }; + + if (xdl_diff(&a, &b, &xpp, &xecfg, &ecb) != 0) { + Py_DECREF(rl); + return PyErr_NoMemory(); + } + + return rl; +} + +static char xdiff_doc[] = "xdiff wrapper"; + +static PyMethodDef methods[] = { + {"blocks", blocks, METH_VARARGS, + "(a: str, b: str) -> List[(a1, a2, b1, b2)].\n" + "Yield matched blocks. (a1, a2, b1, b2) are line numbers.\n"}, + {NULL, NULL}, +}; + +static const int version = 1; + +#ifdef IS_PY3K +static struct PyModuleDef bdiff_module = { + PyModuleDef_HEAD_INIT, "bdiff", xdiff_doc, -1, methods, +}; + +PyMODINIT_FUNC PyInit_xdiff(void) +{ + PyObject *m; + m = PyModule_Create(&xdiff_module); + PyModule_AddIntConstant(m, "version", version); + return m; +} +#else +PyMODINIT_FUNC initxdiff(void) +{ + PyObject *m; + m = Py_InitModule3("xdiff", methods, xdiff_doc); + PyModule_AddIntConstant(m, "version", version); +} +#endif diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -220,7 +220,7 @@ py2exe.Distribution # silence unused import warning py2exeloaded = True # import py2exe's patched Distribution class - from distutils.core import Distribution + from distutils.core import Distribution # noqa: F811 except ImportError: py2exeloaded = False @@ -874,6 +874,28 @@ extra_compile_args=osutil_cflags, extra_link_args=osutil_ldflags, depends=common_depends), + Extension('mercurial.cext.xdiff', + sources=[ + 'mercurial/thirdparty/xdiff/xdiffi.c', + 'mercurial/thirdparty/xdiff/xemit.c', + 'mercurial/thirdparty/xdiff/xmerge.c', + 'mercurial/thirdparty/xdiff/xprepare.c', + 'mercurial/thirdparty/xdiff/xutils.c', + 'mercurial/thirdparty/xdiff.c', + ], + include_dirs=common_include_dirs + [ + 'mercurial/thirdparty/xdiff', + ], + depends=common_depends + [ + 'mercurial/thirdparty/xdiff/xdiff.h', + 'mercurial/thirdparty/xdiff/xdiffi.h', + 'mercurial/thirdparty/xdiff/xemit.h', + 'mercurial/thirdparty/xdiff/xinclude.h', + 'mercurial/thirdparty/xdiff/xmacros.h', + 'mercurial/thirdparty/xdiff/xprepare.h', + 'mercurial/thirdparty/xdiff/xtypes.h', + 'mercurial/thirdparty/xdiff/xutils.h', + ]), Extension('hgext.fsmonitor.pywatchman.bser', ['hgext/fsmonitor/pywatchman/bser.c']), ]