mercurial/cext/bdiff.c
author Yuya Nishihara <yuya@tcha.org>
Thu, 12 Jul 2018 23:07:29 +0900
changeset 38705 e4b270a32ba8
parent 38318 93b812d5b818
child 38784 ad76032d27da
permissions -rw-r--r--
revset: special case commonancestors(none()) to be empty set This matches the behavior of ancestor(none()). From an implementation perspective, ancestor() and commonancestors() are intersection, and ancestors() is union, so it would make some sense that commonancestors(none()) returned all revisions. However, ancestor(none()) isn't implemented as such, which breaks ancestor(x) == max(commonancestors(x)). From a user perspective, ancestors of nothing is nothing whichever type of operation the ancestor predicate does.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     1
/*
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     2
 bdiff.c - efficient binary diff extension for Mercurial
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     3
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     4
 Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     5
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     6
 This software may be used and distributed according to the terms of
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     7
 the GNU General Public License, incorporated herein by reference.
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     8
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
     9
 Based roughly on Python difflib
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    10
*/
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    11
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    12
#define PY_SSIZE_T_CLEAN
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    13
#include <Python.h>
34439
b90e8da190da cext: reorder #include
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32408
diff changeset
    14
#include <limits.h>
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    15
#include <stdlib.h>
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    16
#include <string.h>
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    17
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    18
#include "bdiff.h"
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    19
#include "bitmanipulation.h"
36704
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
    20
#include "thirdparty/xdiff/xdiff.h"
30170
15635d8b17e0 bdiff: include util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29541
diff changeset
    21
#include "util.h"
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    22
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    23
static PyObject *blocks(PyObject *self, PyObject *args)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    24
{
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    25
	PyObject *sa, *sb, *rl = NULL, *m;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    26
	struct bdiff_line *a, *b;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    27
	struct bdiff_hunk l, *h;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    28
	int an, bn, count, pos = 0;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    29
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    30
	l.next = NULL;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    31
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    32
	if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb))
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    33
		return NULL;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    34
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    35
	an = bdiff_splitlines(PyBytes_AsString(sa), PyBytes_Size(sa), &a);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    36
	bn = bdiff_splitlines(PyBytes_AsString(sb), PyBytes_Size(sb), &b);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    37
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    38
	if (!a || !b)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    39
		goto nomem;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    40
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    41
	count = bdiff_diff(a, an, b, bn, &l);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    42
	if (count < 0)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    43
		goto nomem;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    44
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    45
	rl = PyList_New(count);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    46
	if (!rl)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    47
		goto nomem;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    48
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    49
	for (h = l.next; h; h = h->next) {
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    50
		m = Py_BuildValue("iiii", h->a1, h->a2, h->b1, h->b2);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    51
		PyList_SetItem(rl, pos, m);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    52
		pos++;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    53
	}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    54
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    55
nomem:
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    56
	free(a);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    57
	free(b);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    58
	bdiff_freehunks(l.next);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    59
	return rl ? rl : PyErr_NoMemory();
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    60
}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    61
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    62
static PyObject *bdiff(PyObject *self, PyObject *args)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    63
{
36684
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    64
	Py_buffer ba, bb;
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    65
	char *rb, *ia, *ib;
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    66
	PyObject *result = NULL;
36683
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
    67
	struct bdiff_line *al = NULL, *bl = NULL;
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    68
	struct bdiff_hunk l, *h;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    69
	int an, bn, count;
30566
7c0c722d568d bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents: 30170
diff changeset
    70
	Py_ssize_t len = 0, la, lb, li = 0, lcommon = 0, lmax;
36683
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
    71
	PyThreadState *_save = NULL;
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    72
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    73
	l.next = NULL;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    74
36684
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    75
	if (!PyArg_ParseTuple(args, PY23("s*s*:bdiff", "y*y*:bdiff"), &ba, &bb))
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    76
		return NULL;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    77
36684
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    78
	if (!PyBuffer_IsContiguous(&ba, 'C') || ba.ndim > 1) {
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    79
		PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous");
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    80
		goto cleanup;
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    81
	}
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    82
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    83
	if (!PyBuffer_IsContiguous(&bb, 'C') || bb.ndim > 1) {
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    84
		PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous");
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    85
		goto cleanup;
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    86
	}
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    87
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    88
	la = ba.len;
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    89
	lb = bb.len;
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    90
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    91
	if (la > UINT_MAX || lb > UINT_MAX) {
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    92
		PyErr_SetString(PyExc_ValueError, "bdiff inputs too large");
36684
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    93
		goto cleanup;
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    94
	}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    95
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
    96
	_save = PyEval_SaveThread();
30566
7c0c722d568d bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents: 30170
diff changeset
    97
7c0c722d568d bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents: 30170
diff changeset
    98
	lmax = la > lb ? lb : la;
36684
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
    99
	for (ia = ba.buf, ib = bb.buf; li < lmax && *ia == *ib;
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
   100
	     ++li, ++ia, ++ib) {
30566
7c0c722d568d bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents: 30170
diff changeset
   101
		if (*ia == '\n')
7c0c722d568d bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents: 30170
diff changeset
   102
			lcommon = li + 1;
36684
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
   103
	}
30566
7c0c722d568d bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents: 30170
diff changeset
   104
	/* we can almost add: if (li == lmax) lcommon = li; */
7c0c722d568d bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents: 30170
diff changeset
   105
36710
340e4b711df7 bdiff: avoid pointer arithmetic on void*
Matt Harbison <matt_harbison@yahoo.com>
parents: 36704
diff changeset
   106
	an = bdiff_splitlines((char *)ba.buf + lcommon, la - lcommon, &al);
340e4b711df7 bdiff: avoid pointer arithmetic on void*
Matt Harbison <matt_harbison@yahoo.com>
parents: 36704
diff changeset
   107
	bn = bdiff_splitlines((char *)bb.buf + lcommon, lb - lcommon, &bl);
36683
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   108
	if (!al || !bl) {
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   109
		PyErr_NoMemory();
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   110
		goto cleanup;
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   111
	}
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   112
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   113
	count = bdiff_diff(al, an, bl, bn, &l);
36683
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   114
	if (count < 0) {
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   115
		PyErr_NoMemory();
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   116
		goto cleanup;
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   117
	}
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   118
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   119
	/* calculate length of output */
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   120
	la = lb = 0;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   121
	for (h = l.next; h; h = h->next) {
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   122
		if (h->a1 != la || h->b1 != lb)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   123
			len += 12 + bl[h->b1].l - bl[lb].l;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   124
		la = h->a2;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   125
		lb = h->b2;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   126
	}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   127
	PyEval_RestoreThread(_save);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   128
	_save = NULL;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   129
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   130
	result = PyBytes_FromStringAndSize(NULL, len);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   131
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   132
	if (!result)
36683
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   133
		goto cleanup;
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   134
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   135
	/* build binary patch */
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   136
	rb = PyBytes_AsString(result);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   137
	la = lb = 0;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   138
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   139
	for (h = l.next; h; h = h->next) {
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   140
		if (h->a1 != la || h->b1 != lb) {
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   141
			len = bl[h->b1].l - bl[lb].l;
30566
7c0c722d568d bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents: 30170
diff changeset
   142
			putbe32((uint32_t)(al[la].l + lcommon - al->l), rb);
36093
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   143
			putbe32((uint32_t)(al[h->a1].l + lcommon - al->l),
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   144
			        rb + 4);
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   145
			putbe32((uint32_t)len, rb + 8);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   146
			memcpy(rb + 12, bl[lb].l, len);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   147
			rb += 12 + len;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   148
		}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   149
		la = h->a2;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   150
		lb = h->b2;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   151
	}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   152
36683
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   153
cleanup:
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   154
	if (_save)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   155
		PyEval_RestoreThread(_save);
36684
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
   156
	PyBuffer_Release(&ba);
68026dd7c4f9 cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36683
diff changeset
   157
	PyBuffer_Release(&bb);
37873
d9e87566f879 cext: stop worrying and love the free(NULL)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 37840
diff changeset
   158
	free(al);
d9e87566f879 cext: stop worrying and love the free(NULL)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 37840
diff changeset
   159
	free(bl);
38318
93b812d5b818 bdiff: one more safe call of bdiff_freehunks(NULL)
Yuya Nishihara <yuya@tcha.org>
parents: 37873
diff changeset
   160
	bdiff_freehunks(l.next);
36683
b864f4536ca8 cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36649
diff changeset
   161
	return result;
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   162
}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   163
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   164
/*
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   165
 * If allws != 0, remove all whitespace (' ', \t and \r). Otherwise,
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   166
 * reduce whitespace sequences to a single space and trim remaining whitespace
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   167
 * from end of lines.
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   168
 */
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   169
static PyObject *fixws(PyObject *self, PyObject *args)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   170
{
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   171
	PyObject *s, *result = NULL;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   172
	char allws, c;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   173
	const char *r;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   174
	Py_ssize_t i, rlen, wlen = 0;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   175
	char *w;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   176
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   177
	if (!PyArg_ParseTuple(args, "Sb:fixws", &s, &allws))
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   178
		return NULL;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   179
	r = PyBytes_AsString(s);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   180
	rlen = PyBytes_Size(s);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   181
31476
08ecec297521 bdiff: use Python memory allocator in fixws
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30566
diff changeset
   182
	w = (char *)PyMem_Malloc(rlen ? rlen : 1);
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   183
	if (!w)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   184
		goto nomem;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   185
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   186
	for (i = 0; i != rlen; i++) {
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   187
		c = r[i];
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   188
		if (c == ' ' || c == '\t' || c == '\r') {
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   189
			if (!allws && (wlen == 0 || w[wlen - 1] != ' '))
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   190
				w[wlen++] = ' ';
36093
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   191
		} else if (c == '\n' && !allws && wlen > 0 &&
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   192
		           w[wlen - 1] == ' ') {
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   193
			w[wlen - 1] = '\n';
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   194
		} else {
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   195
			w[wlen++] = c;
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   196
		}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   197
	}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   198
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   199
	result = PyBytes_FromStringAndSize(w, wlen);
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   200
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   201
nomem:
31476
08ecec297521 bdiff: use Python memory allocator in fixws
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30566
diff changeset
   202
	PyMem_Free(w);
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   203
	return result ? result : PyErr_NoMemory();
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   204
}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   205
36184
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   206
static bool sliceintolist(PyObject *list, Py_ssize_t destidx,
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   207
                          const char *source, Py_ssize_t len)
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   208
{
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   209
	PyObject *sliced = PyBytes_FromStringAndSize(source, len);
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   210
	if (sliced == NULL)
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   211
		return false;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   212
	PyList_SET_ITEM(list, destidx, sliced);
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   213
	return true;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   214
}
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   215
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   216
static PyObject *splitnewlines(PyObject *self, PyObject *args)
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   217
{
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   218
	const char *text;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   219
	Py_ssize_t nelts = 0, size, i, start = 0;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   220
	PyObject *result = NULL;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   221
36649
186c6df3a373 py3: bulk-replace 'const char*' format specifier passed to PyArg_ParseTuple*()
Yuya Nishihara <yuya@tcha.org>
parents: 36184
diff changeset
   222
	if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &size)) {
36184
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   223
		goto abort;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   224
	}
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   225
	if (!size) {
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   226
		return PyList_New(0);
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   227
	}
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   228
	/* This loops to size-1 because if the last byte is a newline,
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   229
	 * we don't want to perform a split there. */
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   230
	for (i = 0; i < size - 1; ++i) {
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   231
		if (text[i] == '\n') {
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   232
			++nelts;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   233
		}
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   234
	}
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   235
	if ((result = PyList_New(nelts + 1)) == NULL)
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   236
		goto abort;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   237
	nelts = 0;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   238
	for (i = 0; i < size - 1; ++i) {
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   239
		if (text[i] == '\n') {
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   240
			if (!sliceintolist(result, nelts++, text + start,
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   241
			                   i - start + 1))
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   242
				goto abort;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   243
			start = i + 1;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   244
		}
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   245
	}
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   246
	if (!sliceintolist(result, nelts++, text + start, size - start))
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   247
		goto abort;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   248
	return result;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   249
abort:
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   250
	Py_XDECREF(result);
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   251
	return NULL;
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   252
}
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   253
36922
1b9f6440506b bdiff: convert more longs to int64_t
Matt Harbison <matt_harbison@yahoo.com>
parents: 36771
diff changeset
   254
static int hunk_consumer(int64_t a1, int64_t a2, int64_t b1, int64_t b2,
1b9f6440506b bdiff: convert more longs to int64_t
Matt Harbison <matt_harbison@yahoo.com>
parents: 36771
diff changeset
   255
                         void *priv)
36704
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   256
{
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   257
	PyObject *rl = (PyObject *)priv;
37840
273ea09f6550 bdiff: fix yet more fallout from xdiff long/int64 conversion (issue5885)
Julien Cristau <jcristau@debian.org>
parents: 36922
diff changeset
   258
	PyObject *m = Py_BuildValue("LLLL", a1, a2, b1, b2);
36704
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   259
	if (!m)
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   260
		return -1;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   261
	if (PyList_Append(rl, m) != 0) {
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   262
		Py_DECREF(m);
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   263
		return -1;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   264
	}
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   265
	return 0;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   266
}
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   267
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   268
static PyObject *xdiffblocks(PyObject *self, PyObject *args)
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   269
{
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   270
	Py_ssize_t la, lb;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   271
	mmfile_t a, b;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   272
	PyObject *rl;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   273
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   274
	xpparam_t xpp = {
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   275
	    XDF_INDENT_HEURISTIC, /* flags */
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   276
	};
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   277
	xdemitconf_t xecfg = {
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   278
	    XDL_EMIT_BDIFFHUNK, /* flags */
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   279
	    hunk_consumer,      /* hunk_consume_func */
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   280
	};
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   281
	xdemitcb_t ecb = {
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   282
	    NULL, /* priv */
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   283
	};
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   284
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   285
	if (!PyArg_ParseTuple(args, PY23("s#s#", "y#y#"), &a.ptr, &la, &b.ptr,
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   286
	                      &lb))
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   287
		return NULL;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   288
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   289
	a.size = la;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   290
	b.size = lb;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   291
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   292
	rl = PyList_New(0);
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   293
	if (!rl)
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   294
		return PyErr_NoMemory();
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   295
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   296
	ecb.priv = rl;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   297
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   298
	if (xdl_diff(&a, &b, &xpp, &xecfg, &ecb) != 0) {
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   299
		Py_DECREF(rl);
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   300
		return PyErr_NoMemory();
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   301
	}
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   302
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   303
	return rl;
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   304
}
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   305
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   306
static char mdiff_doc[] = "Efficient binary diff.";
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   307
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   308
static PyMethodDef methods[] = {
36093
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   309
    {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"},
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   310
    {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"},
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   311
    {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"},
36184
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   312
    {"splitnewlines", splitnewlines, METH_VARARGS,
29dd37a418aa bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents: 36093
diff changeset
   313
     "like str.splitlines, but only split on newlines\n"},
36704
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   314
    {"xdiffblocks", xdiffblocks, METH_VARARGS,
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   315
     "find a list of matching lines using xdiff algorithm\n"},
36093
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   316
    {NULL, NULL},
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   317
};
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   318
36704
430fdb717549 bdiff: add a xdiffblocks method
Jun Wu <quark@fb.com>
parents: 36684
diff changeset
   319
static const int version = 3;
32394
4195b84940e9 bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 31476
diff changeset
   320
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   321
#ifdef IS_PY3K
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   322
static struct PyModuleDef bdiff_module = {
36093
b4fdc6177b29 bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents: 34439
diff changeset
   323
    PyModuleDef_HEAD_INIT, "bdiff", mdiff_doc, -1, methods,
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   324
};
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   325
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   326
PyMODINIT_FUNC PyInit_bdiff(void)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   327
{
32394
4195b84940e9 bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 31476
diff changeset
   328
	PyObject *m;
4195b84940e9 bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 31476
diff changeset
   329
	m = PyModule_Create(&bdiff_module);
4195b84940e9 bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 31476
diff changeset
   330
	PyModule_AddIntConstant(m, "version", version);
4195b84940e9 bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 31476
diff changeset
   331
	return m;
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   332
}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   333
#else
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   334
PyMODINIT_FUNC initbdiff(void)
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   335
{
32394
4195b84940e9 bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 31476
diff changeset
   336
	PyObject *m;
4195b84940e9 bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 31476
diff changeset
   337
	m = Py_InitModule3("bdiff", methods, mdiff_doc);
4195b84940e9 bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 31476
diff changeset
   338
	PyModule_AddIntConstant(m, "version", version);
29541
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   339
}
9631ff5ebbeb bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff changeset
   340
#endif