Mercurial > hg
annotate mercurial/cext/bdiff.c @ 45095:8e04607023e5
procutil: ensure that procutil.std{out,err}.write() writes all bytes
Python 3 offers different kind of streams and it’s not guaranteed for all of
them that calling write() writes all bytes.
When Python is started in unbuffered mode, sys.std{out,err}.buffer are
instances of io.FileIO, whose write() can write less bytes for
platform-specific reasons (e.g. Linux has a 0x7ffff000 bytes maximum and could
write less if interrupted by a signal; when writing to Windows consoles, it’s
limited to 32767 bytes to avoid the "not enough space" error). This can lead to
silent loss of data, both when using sys.std{out,err}.buffer (which may in fact
not be a buffered stream) and when using the text streams sys.std{out,err}
(I’ve created a CPython bug report for that:
https://bugs.python.org/issue41221).
Python may fix the problem at some point. For now, we implement our own wrapper
for procutil.std{out,err} that calls the raw stream’s write() method until all
bytes have been written. We don’t use sys.std{out,err} for larger writes, so I
think it’s not worth the effort to patch them.
author | Manuel Jacob <me@manueljacob.de> |
---|---|
date | Fri, 10 Jul 2020 12:27:58 +0200 |
parents | 763b45bc4483 |
children | d4ba4d51f85f |
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 |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
32 if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb)) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
33 return NULL; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
34 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
35 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
36 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
|
37 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
|
38 |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
39 if (!a || !b) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
40 goto nomem; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
41 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
42 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
43 count = bdiff_diff(a, an, b, bn, &l); |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
44 if (count < 0) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
45 goto nomem; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
46 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
47 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
48 rl = PyList_New(count); |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
49 if (!rl) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
50 goto nomem; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
51 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
52 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
53 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
|
54 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
|
55 PyList_SetItem(rl, pos, m); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
56 pos++; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
57 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
58 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
59 nomem: |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
60 free(a); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
61 free(b); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
62 bdiff_freehunks(l.next); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
63 return rl ? rl : PyErr_NoMemory(); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
64 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
65 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
66 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
|
67 { |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
68 Py_buffer ba, bb; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
69 char *rb, *ia, *ib; |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
70 PyObject *result = NULL; |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
71 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
|
72 struct bdiff_hunk l, *h; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
73 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
|
74 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
|
75 PyThreadState *_save = NULL; |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
76 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
77 l.next = NULL; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
78 |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
79 if (!PyArg_ParseTuple(args, PY23("s*s*:bdiff", "y*y*:bdiff"), &ba, |
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
80 &bb)) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
81 return NULL; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
82 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
83 |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
84 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
|
85 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
|
86 goto cleanup; |
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 |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
89 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
|
90 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
|
91 goto cleanup; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
92 } |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
93 |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
94 la = ba.len; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
95 lb = bb.len; |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
96 |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
97 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
|
98 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
|
99 goto cleanup; |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
100 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
101 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
102 _save = PyEval_SaveThread(); |
30561
7c0c722d568d
bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents:
30170
diff
changeset
|
103 |
7c0c722d568d
bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents:
30170
diff
changeset
|
104 lmax = la > lb ? lb : la; |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
105 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
|
106 ++li, ++ia, ++ib) { |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
107 if (*ia == '\n') { |
30561
7c0c722d568d
bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents:
30170
diff
changeset
|
108 lcommon = li + 1; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
109 } |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
110 } |
30561
7c0c722d568d
bdiff: early pruning of common prefix before doing expensive computations
Mads Kiilerich <madski@unity3d.com>
parents:
30170
diff
changeset
|
111 /* 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
|
112 |
36681
340e4b711df7
bdiff: avoid pointer arithmetic on void*
Matt Harbison <matt_harbison@yahoo.com>
parents:
36675
diff
changeset
|
113 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
|
114 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
|
115 if (!al || !bl) { |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
116 PyErr_NoMemory(); |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
117 goto cleanup; |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
118 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
119 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
120 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
|
121 if (count < 0) { |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
122 PyErr_NoMemory(); |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
123 goto cleanup; |
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
124 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
125 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
126 /* calculate length of output */ |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
127 la = lb = 0; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
128 for (h = l.next; h; h = h->next) { |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
129 if (h->a1 != la || h->b1 != lb) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
130 len += 12 + bl[h->b1].l - bl[lb].l; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
131 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
132 la = h->a2; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
133 lb = h->b2; |
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 PyEval_RestoreThread(_save); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
136 _save = NULL; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
137 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
138 result = PyBytes_FromStringAndSize(NULL, len); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
139 |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
140 if (!result) { |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
141 goto cleanup; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
142 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
143 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
144 /* build binary patch */ |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
145 rb = PyBytes_AsString(result); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
146 la = lb = 0; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
147 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
148 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
|
149 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
|
150 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
|
151 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
|
152 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
|
153 rb + 4); |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
154 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
|
155 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
|
156 rb += 12 + len; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
157 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
158 la = h->a2; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
159 lb = h->b2; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
160 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
161 |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
162 cleanup: |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
163 if (_save) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
164 PyEval_RestoreThread(_save); |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
165 } |
36655
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
166 PyBuffer_Release(&ba); |
68026dd7c4f9
cext: accept arguments as Py_buffer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36654
diff
changeset
|
167 PyBuffer_Release(&bb); |
38301
d9e87566f879
cext: stop worrying and love the free(NULL)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
37980
diff
changeset
|
168 free(al); |
d9e87566f879
cext: stop worrying and love the free(NULL)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
37980
diff
changeset
|
169 free(bl); |
38309
93b812d5b818
bdiff: one more safe call of bdiff_freehunks(NULL)
Yuya Nishihara <yuya@tcha.org>
parents:
38301
diff
changeset
|
170 bdiff_freehunks(l.next); |
36654
b864f4536ca8
cext: refactor cleanup code in bdiff()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36620
diff
changeset
|
171 return result; |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
172 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
173 |
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 * 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
|
176 * 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
|
177 * from end of lines. |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
178 */ |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
179 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
|
180 { |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
181 PyObject *s, *result = NULL; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
182 char allws, c; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
183 const char *r; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
184 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
|
185 char *w; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
186 |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
187 if (!PyArg_ParseTuple(args, "Sb:fixws", &s, &allws)) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
188 return NULL; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
189 } |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
190 r = PyBytes_AsString(s); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
191 rlen = PyBytes_Size(s); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
192 |
31467
08ecec297521
bdiff: use Python memory allocator in fixws
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30561
diff
changeset
|
193 w = (char *)PyMem_Malloc(rlen ? rlen : 1); |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
194 if (!w) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
195 goto nomem; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
196 } |
29541
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 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
|
199 c = r[i]; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
200 if (c == ' ' || c == '\t' || c == '\r') { |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
201 if (!allws && (wlen == 0 || w[wlen - 1] != ' ')) { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
202 w[wlen++] = ' '; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
203 } |
36055
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
204 } else if (c == '\n' && !allws && wlen > 0 && |
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
205 w[wlen - 1] == ' ') { |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
206 w[wlen - 1] = '\n'; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
207 } else { |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
208 w[wlen++] = c; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
209 } |
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 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
212 result = PyBytes_FromStringAndSize(w, wlen); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
213 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
214 nomem: |
31467
08ecec297521
bdiff: use Python memory allocator in fixws
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30561
diff
changeset
|
215 PyMem_Free(w); |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
216 return result ? result : PyErr_NoMemory(); |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
217 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
218 |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
219 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
|
220 const char *source, Py_ssize_t len) |
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 PyObject *sliced = PyBytes_FromStringAndSize(source, len); |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
223 if (sliced == NULL) { |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
224 return false; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
225 } |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
226 PyList_SET_ITEM(list, destidx, sliced); |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
227 return true; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
228 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
229 |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
230 static PyObject *splitnewlines(PyObject *self, PyObject *args) |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
231 { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
232 const char *text; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
233 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
|
234 PyObject *result = NULL; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
235 |
36620
186c6df3a373
py3: bulk-replace 'const char*' format specifier passed to PyArg_ParseTuple*()
Yuya Nishihara <yuya@tcha.org>
parents:
36146
diff
changeset
|
236 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
|
237 goto abort; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
238 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
239 if (!size) { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
240 return PyList_New(0); |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
241 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
242 /* 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
|
243 * 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
|
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 ++nelts; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
247 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
248 } |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
249 if ((result = PyList_New(nelts + 1)) == NULL) { |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
250 goto abort; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
251 } |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
252 nelts = 0; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
253 for (i = 0; i < size - 1; ++i) { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
254 if (text[i] == '\n') { |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
255 if (!sliceintolist(result, nelts++, text + start, |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
256 i - start + 1)) { |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
257 goto abort; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
258 } |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
259 start = i + 1; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
260 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
261 } |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
262 if (!sliceintolist(result, nelts++, text + start, size - start)) { |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
263 goto abort; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
264 } |
36146
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
265 return result; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
266 abort: |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
267 Py_XDECREF(result); |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
268 return NULL; |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
269 } |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
270 |
36916
1b9f6440506b
bdiff: convert more longs to int64_t
Matt Harbison <matt_harbison@yahoo.com>
parents:
36763
diff
changeset
|
271 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
|
272 void *priv) |
36675 | 273 { |
274 PyObject *rl = (PyObject *)priv; | |
37980
273ea09f6550
bdiff: fix yet more fallout from xdiff long/int64 conversion (issue5885)
Julien Cristau <jcristau@debian.org>
parents:
36916
diff
changeset
|
275 PyObject *m = Py_BuildValue("LLLL", a1, a2, b1, b2); |
39421
ad76032d27da
xdiff: fix leak in hunk_consumer()
Yuya Nishihara <yuya@tcha.org>
parents:
38309
diff
changeset
|
276 int r; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
277 if (!m) { |
36675 | 278 return -1; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
279 } |
39421
ad76032d27da
xdiff: fix leak in hunk_consumer()
Yuya Nishihara <yuya@tcha.org>
parents:
38309
diff
changeset
|
280 r = PyList_Append(rl, m); |
ad76032d27da
xdiff: fix leak in hunk_consumer()
Yuya Nishihara <yuya@tcha.org>
parents:
38309
diff
changeset
|
281 Py_DECREF(m); |
ad76032d27da
xdiff: fix leak in hunk_consumer()
Yuya Nishihara <yuya@tcha.org>
parents:
38309
diff
changeset
|
282 return r; |
36675 | 283 } |
284 | |
285 static PyObject *xdiffblocks(PyObject *self, PyObject *args) | |
286 { | |
287 Py_ssize_t la, lb; | |
288 mmfile_t a, b; | |
289 PyObject *rl; | |
290 | |
291 xpparam_t xpp = { | |
292 XDF_INDENT_HEURISTIC, /* flags */ | |
293 }; | |
294 xdemitconf_t xecfg = { | |
295 XDL_EMIT_BDIFFHUNK, /* flags */ | |
296 hunk_consumer, /* hunk_consume_func */ | |
297 }; | |
298 xdemitcb_t ecb = { | |
299 NULL, /* priv */ | |
300 }; | |
301 | |
302 if (!PyArg_ParseTuple(args, PY23("s#s#", "y#y#"), &a.ptr, &la, &b.ptr, | |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
303 &lb)) { |
36675 | 304 return NULL; |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
305 } |
36675 | 306 |
307 a.size = la; | |
308 b.size = lb; | |
309 | |
310 rl = PyList_New(0); | |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
311 if (!rl) { |
36675 | 312 return PyErr_NoMemory(); |
41336
763b45bc4483
cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents:
39421
diff
changeset
|
313 } |
36675 | 314 |
315 ecb.priv = rl; | |
316 | |
317 if (xdl_diff(&a, &b, &xpp, &xecfg, &ecb) != 0) { | |
318 Py_DECREF(rl); | |
319 return PyErr_NoMemory(); | |
320 } | |
321 | |
322 return rl; | |
323 } | |
324 | |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
325 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
|
326 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
327 static PyMethodDef methods[] = { |
36055
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
328 {"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
|
329 {"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
|
330 {"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
|
331 {"splitnewlines", splitnewlines, METH_VARARGS, |
29dd37a418aa
bdiff: write a native version of splitnewlines
Augie Fackler <augie@google.com>
parents:
36055
diff
changeset
|
332 "like str.splitlines, but only split on newlines\n"}, |
36675 | 333 {"xdiffblocks", xdiffblocks, METH_VARARGS, |
334 "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
|
335 {NULL, NULL}, |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
336 }; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
337 |
36675 | 338 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
|
339 |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
340 #ifdef IS_PY3K |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
341 static struct PyModuleDef bdiff_module = { |
36055
b4fdc6177b29
bdiff: add to clang-format oversight
Augie Fackler <augie@google.com>
parents:
34438
diff
changeset
|
342 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
|
343 }; |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
344 |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
345 PyMODINIT_FUNC PyInit_bdiff(void) |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
346 { |
32355
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
347 PyObject *m; |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
348 m = PyModule_Create(&bdiff_module); |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
349 PyModule_AddIntConstant(m, "version", version); |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
350 return m; |
29541
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
351 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
352 #else |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
353 PyMODINIT_FUNC initbdiff(void) |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
354 { |
32355
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
355 PyObject *m; |
4195b84940e9
bdiff: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents:
31467
diff
changeset
|
356 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
|
357 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
|
358 } |
9631ff5ebbeb
bdiff: split bdiff into cpy-aware and cpy-agnostic part
Maciej Fijalkowski <fijall@gmail.com>
parents:
diff
changeset
|
359 #endif |