diff options
Diffstat (limited to 'mercurial/bdiff.c')
-rw-r--r-- | mercurial/bdiff.c | 110 |
1 files changed, 41 insertions, 69 deletions
diff --git a/mercurial/bdiff.c b/mercurial/bdiff.c index be38b53..9d39d7e 100644 --- a/mercurial/bdiff.c +++ b/mercurial/bdiff.c @@ -9,17 +9,47 @@ Based roughly on Python difflib */ -#define PY_SSIZE_T_CLEAN #include <Python.h> #include <stdlib.h> #include <string.h> #include <limits.h> +#if defined __hpux || defined __SUNPRO_C || defined _AIX +#define inline +#endif + +#ifdef __linux +#define inline __inline +#endif + +#ifdef _WIN32 +#ifdef _MSC_VER +#define inline __inline +typedef unsigned long uint32_t; +#else +#include <stdint.h> +#endif +static uint32_t htonl(uint32_t x) +{ + return ((x & 0x000000ffUL) << 24) | + ((x & 0x0000ff00UL) << 8) | + ((x & 0x00ff0000UL) >> 8) | + ((x & 0xff000000UL) >> 24); +} +#else +#include <sys/types.h> +#if defined __BEOS__ && !defined __HAIKU__ +#include <ByteOrder.h> +#else +#include <arpa/inet.h> +#endif +#include <inttypes.h> +#endif + #include "util.h" struct line { - int hash, n, e; - Py_ssize_t len; + int hash, len, n, e; const char *l; }; @@ -33,7 +63,7 @@ struct hunk { struct hunk *next; }; -static int splitlines(const char *a, Py_ssize_t len, struct line **lr) +static int splitlines(const char *a, int len, struct line **lr) { unsigned hash; int i; @@ -336,18 +366,16 @@ nomem: static PyObject *bdiff(PyObject *self, PyObject *args) { - char *sa, *sb, *rb; + char *sa, *sb; PyObject *result = NULL; struct line *al, *bl; struct hunk l, *h; - int an, bn, count; - Py_ssize_t len = 0, la, lb; - PyThreadState *_save; + char encode[12], *rb; + int an, bn, len = 0, la, lb, count; if (!PyArg_ParseTuple(args, "s#s#:bdiff", &sa, &la, &sb, &lb)) return NULL; - _save = PyEval_SaveThread(); an = splitlines(sa, la, &al); bn = splitlines(sb, lb, &bl); if (!al || !bl) @@ -366,8 +394,6 @@ static PyObject *bdiff(PyObject *self, PyObject *args) la = h->a2; lb = h->b2; } - PyEval_RestoreThread(_save); - _save = NULL; result = PyBytes_FromStringAndSize(NULL, len); @@ -381,18 +407,10 @@ static PyObject *bdiff(PyObject *self, PyObject *args) for (h = l.next; h; h = h->next) { if (h->a1 != la || h->b1 != lb) { len = bl[h->b1].l - bl[lb].l; - -#define checkputbe32(__x, __c) \ - if (__x > UINT_MAX) { \ - PyErr_SetString(PyExc_ValueError, \ - "bdiff: value too large for putbe32"); \ - goto nomem; \ - } \ - putbe32((uint32_t)(__x), __c); - - checkputbe32(al[la].l - al->l, rb); - checkputbe32(al[h->a1].l - al->l, rb + 4); - checkputbe32(len, rb + 8); + *(uint32_t *)(encode) = htonl(al[la].l - al->l); + *(uint32_t *)(encode + 4) = htonl(al[h->a1].l - al->l); + *(uint32_t *)(encode + 8) = htonl(len); + memcpy(rb, encode, 12); memcpy(rb + 12, bl[lb].l, len); rb += 12 + len; } @@ -401,63 +419,17 @@ static PyObject *bdiff(PyObject *self, PyObject *args) } nomem: - if (_save) - PyEval_RestoreThread(_save); free(al); free(bl); freehunks(l.next); 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; - Py_ssize_t 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 ? rlen : 1); - 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} }; |