Mercurial > public > mercurial-scm > hg-stable
diff mercurial/bdiff.c @ 15530:eeac5e179243
mdiff: replace wscleanup() regexps with C loops
On my system it reduces:
hg annotate -w mercurial/commands.py
from 36s to less than 8s, to be compared with 6.3s when run without whitespace
options.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Fri, 18 Nov 2011 14:23:03 +0100 |
parents | 73015301db86 |
children | 8134ec8627e7 |
line wrap: on
line diff
--- a/mercurial/bdiff.c Fri Nov 18 14:16:47 2011 +0100 +++ b/mercurial/bdiff.c Fri Nov 18 14:23:03 2011 +0100 @@ -425,11 +425,55 @@ return result ? result : PyErr_NoMemory(); } +/* + * If allws != 0, remove all whitespace (' ', \t and \r). Otherwise, + * reduce whitespace sequences to a single space and trim remaining whitespace + * from end of lines. + */ +static PyObject *fixws(PyObject *self, PyObject *args) +{ + PyObject *s, *result = NULL; + char allws, c; + const char *r; + int i, rlen, wlen = 0; + char *w; + + if (!PyArg_ParseTuple(args, "Sb:fixws", &s, &allws)) + return NULL; + r = PyBytes_AsString(s); + rlen = PyBytes_Size(s); + + w = (char *)malloc(rlen); + if (!w) + goto nomem; + + for (i = 0; i != rlen; i++) { + c = r[i]; + if (c == ' ' || c == '\t' || c == '\r') { + if (!allws && (wlen == 0 || w[wlen - 1] != ' ')) + w[wlen++] = ' '; + } else if (c == '\n' && !allws + && wlen > 0 && w[wlen - 1] == ' ') { + w[wlen - 1] = '\n'; + } else { + w[wlen++] = c; + } + } + + result = PyBytes_FromStringAndSize(w, wlen); + +nomem: + free(w); + return result ? result : PyErr_NoMemory(); +} + + static char mdiff_doc[] = "Efficient binary diff."; static PyMethodDef methods[] = { {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"}, {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"}, + {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"}, {NULL, NULL} };