Mercurial > hg
annotate mercurial/cext/bdiff.c @ 37056:861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Previously, when told that a response was ready, the server reactor
would instruct the caller to send frames immediately. This was OK
as an initial implementation. But it would not work for half-duplex
connections where the sender can't receive until all data has been
transmitted - such as httplib based clients.
In this commit, we teach the reactor that output frames should
be buffered until end of input is seen. This required a new
event to inform the reactor of end of input. The result from that
event will instruct the consumer to send all buffered frames.
The HTTP server is buffered by default.
This change effectively hides the complexity of buffering within
the reactor so that transports need not be concerned about it.
This helps keep the transports "dumb" and will make implementing
multiple requests-responses per atomic exchange (like an HTTP
request) much simpler.
Differential Revision: https://phab.mercurial-scm.org/D2860
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 14 Mar 2018 14:01:16 -0700 |
parents | 1b9f6440506b |
children | 273ea09f6550 |
rev | line source |
---|---|
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> |
34438
b90e8da190da
cext: reorder #include
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32369
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" |
36675 | 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 { |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
64 Py_buffer ba, bb; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
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; |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
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; |
30561
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; |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
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 |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
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 |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
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:
36654
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:
36654
diff
changeset
|
80 goto cleanup; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
81 } |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
82 |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
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:
36654
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:
36654
diff
changeset
|
85 goto cleanup; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
86 } |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
87 |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
88 la = ba.len; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
89 lb = bb.len; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
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"); |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
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(); |
30561
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; |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
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:
36654
diff
changeset
|
100 ++li, ++ia, ++ib) { |
30561
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; |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
103 } |
30561
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 |
36681
340e4b711df7
bdiff: avoid pointer arithmetic on void*
Matt Harbison <matt_harbison@yahoo.com>
parents:
36675
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:
36675
diff
changeset
|
107 bn = bdiff_splitlines((char *)bb.buf + lcommon, lb - lcommon, &bl); |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
108 if (!al || !bl) { |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
109 PyErr_NoMemory(); |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
110 goto cleanup; |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
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); |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
114 if (count < 0) { |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
115 PyErr_NoMemory(); |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
116 goto cleanup; |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
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) |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
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; |
30561
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); |
36055
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
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:
34438
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 |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
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); |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
156 PyBuffer_Release(&ba); |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
157 PyBuffer_Release(&bb); |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
158 if (al) { |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
159 free(al); |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
160 } |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
161 if (bl) { |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
162 free(bl); |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
163 } |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
164 if (l.next) { |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
165 bdiff_freehunks(l.next); |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
166 } |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
167 return result; |
29541
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 |
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 * 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
|
172 * 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
|
173 * from end of lines. |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
174 */ |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
175 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
|
176 { |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
177 PyObject *s, *result = NULL; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
178 char allws, c; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
179 const char *r; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
180 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
|
181 char *w; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
182 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
183 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
|
184 return NULL; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
185 r = PyBytes_AsString(s); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
186 rlen = PyBytes_Size(s); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
187 |
31467
08ecec297521
bdiff: use Python memory allocator in fixws
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30561
diff
changeset
|
188 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
|
189 if (!w) |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
190 goto nomem; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
191 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
192 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
|
193 c = r[i]; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
194 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
|
195 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
|
196 w[wlen++] = ' '; |
36055
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
197 } else if (c == '\n' && !allws && wlen > 0 && |
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
198 w[wlen - 1] == ' ') { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
199 w[wlen - 1] = '\n'; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
200 } else { |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
201 w[wlen++] = c; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
202 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
203 } |
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 result = PyBytes_FromStringAndSize(w, wlen); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
206 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
207 nomem: |
31467
08ecec297521
bdiff: use Python memory allocator in fixws
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30561
diff
changeset
|
208 PyMem_Free(w); |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
209 return result ? result : PyErr_NoMemory(); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
210 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
211 |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
212 static bool sliceintolist(PyObject *list, Py_ssize_t destidx, |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
213 const char *source, Py_ssize_t len) |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
214 { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
215 PyObject *sliced = PyBytes_FromStringAndSize(source, len); |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
216 if (sliced == NULL) |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
217 return false; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
218 PyList_SET_ITEM(list, destidx, sliced); |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
219 return true; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
220 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
221 |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
222 static PyObject *splitnewlines(PyObject *self, PyObject *args) |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
223 { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
224 const char *text; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
225 Py_ssize_t nelts = 0, size, i, start = 0; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
226 PyObject *result = NULL; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
227 |
36620
186c6df3a373
py3: bulk-replace 'const char*' format specifier passed to PyArg_ParseTuple*()
Yuya Nishihara <yuya@tcha.org>
parents:
36146
diff
changeset
|
228 if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &size)) { |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
229 goto abort; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
230 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
231 if (!size) { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
232 return PyList_New(0); |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
233 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
234 /* 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:
36055
diff
changeset
|
235 * we don't want to perform a split there. */ |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
236 for (i = 0; i < size - 1; ++i) { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
237 if (text[i] == '\n') { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
238 ++nelts; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
239 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
240 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
241 if ((result = PyList_New(nelts + 1)) == NULL) |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
242 goto abort; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
243 nelts = 0; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
244 for (i = 0; i < size - 1; ++i) { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
245 if (text[i] == '\n') { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
246 if (!sliceintolist(result, nelts++, text + start, |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
247 i - start + 1)) |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
248 goto abort; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
249 start = i + 1; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
250 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
251 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
252 if (!sliceintolist(result, nelts++, text + start, size - start)) |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
253 goto abort; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
254 return result; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
255 abort: |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
256 Py_XDECREF(result); |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
257 return NULL; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
258 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
259 |
36916
1b9f6440506b
bdiff: convert more longs to int64_t
Matt Harbison <matt_harbison@yahoo.com>
parents:
36763
diff
changeset
|
260 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:
36763
diff
changeset
|
261 void *priv) |
36675 | 262 { |
263 PyObject *rl = (PyObject *)priv; | |
264 PyObject *m = Py_BuildValue("llll", a1, a2, b1, b2); | |
265 if (!m) | |
266 return -1; | |
267 if (PyList_Append(rl, m) != 0) { | |
268 Py_DECREF(m); | |
269 return -1; | |
270 } | |
271 return 0; | |
272 } | |
273 | |
274 static PyObject *xdiffblocks(PyObject *self, PyObject *args) | |
275 { | |
276 Py_ssize_t la, lb; | |
277 mmfile_t a, b; | |
278 PyObject *rl; | |
279 | |
280 xpparam_t xpp = { | |
281 XDF_INDENT_HEURISTIC, /* flags */ | |
282 }; | |
283 xdemitconf_t xecfg = { | |
284 XDL_EMIT_BDIFFHUNK, /* flags */ | |
285 hunk_consumer, /* hunk_consume_func */ | |
286 }; | |
287 xdemitcb_t ecb = { | |
288 NULL, /* priv */ | |
289 }; | |
290 | |
291 if (!PyArg_ParseTuple(args, PY23("s#s#", "y#y#"), &a.ptr, &la, &b.ptr, | |
292 &lb)) | |
293 return NULL; | |
294 | |
295 a.size = la; | |
296 b.size = lb; | |
297 | |
298 rl = PyList_New(0); | |
299 if (!rl) | |
300 return PyErr_NoMemory(); | |
301 | |
302 ecb.priv = rl; | |
303 | |
304 if (xdl_diff(&a, &b, &xpp, &xecfg, &ecb) != 0) { | |
305 Py_DECREF(rl); | |
306 return PyErr_NoMemory(); | |
307 } | |
308 | |
309 return rl; | |
310 } | |
311 | |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
312 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
|
313 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
314 static PyMethodDef methods[] = { |
36055
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
315 {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"}, |
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
316 {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"}, |
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
317 {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"}, |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
318 {"splitnewlines", splitnewlines, METH_VARARGS, |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
319 "like str.splitlines, but only split on newlines\n"}, |
36675 | 320 {"xdiffblocks", xdiffblocks, METH_VARARGS, |
321 "find a list of matching lines using xdiff algorithm\n"}, | |
36055
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
322 {NULL, NULL}, |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
323 }; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
324 |
36675 | 325 static const int version = 3; |
32355
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
326 |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
327 #ifdef IS_PY3K |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
328 static struct PyModuleDef bdiff_module = { |
36055
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
329 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
|
330 }; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
331 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
332 PyMODINIT_FUNC PyInit_bdiff(void) |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
333 { |
32355
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
334 PyObject *m; |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
335 m = PyModule_Create(&bdiff_module); |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
336 PyModule_AddIntConstant(m, "version", version); |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
337 return m; |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
338 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
339 #else |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
340 PyMODINIT_FUNC initbdiff(void) |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
341 { |
32355
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
342 PyObject *m; |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
343 m = Py_InitModule3("bdiff", methods, mdiff_doc); |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
344 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
|
345 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
346 #endif |