annotate mercurial/cext/mpatch.c @ 44413:4cabeea6d214

hgext: start building a library for simple hooks Many workflows depend on hooks to enforce certain policies, e.g. to prevent forced pushes. The Mercurial Guide includes some cases and Google can help finding others, but it can save users a lot of time if hg itself has a couple of examples for further customization. Differential Revision: https://phab.mercurial-scm.org/D6825
author Joerg Sonnenberger <joerg@bec.de>
date Sat, 07 Sep 2019 14:50:39 +0200
parents 763b45bc4483
children d4ba4d51f85f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
1 /*
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
2 mpatch.c - efficient binary patching for Mercurial
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
3
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
4 This implements a patch algorithm that's O(m + nlog n) where m is the
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
5 size of the output and n is the number of patches.
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
6
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
7 Given a list of binary patches, it unpacks each into a hunk list,
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
8 then combines the hunk lists with a treewise recursion to form a
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
9 single hunk list. This hunk list is then applied to the original
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
10 text.
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
11
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
12 The text (or binary) fragments are copied directly from their source
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
13 Python objects into a preallocated output string to avoid the
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
14 allocation of intermediate Python objects. Working memory is about 2x
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
15 the total number of hunks.
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
16
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2543
diff changeset
17 Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
18
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
19 This software may be used and distributed according to the terms
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
20 of the GNU General Public License, incorporated herein by reference.
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
21 */
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
22
16758
9a8ab5c47f84 mpatch: use Py_ssize_t for string length
Adrian Buehlmann <adrian@cadifra.com>
parents: 16757
diff changeset
23 #define PY_SSIZE_T_CLEAN
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
24 #include <Python.h>
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
25 #include <stdlib.h>
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
26 #include <string.h>
2468
1ac0574f1768 mac os x: fixes for 10.2 from chris monson <monpublic@gmail.com>
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2083
diff changeset
27
29444
284d742e5611 internals: move the bitmanipulation routines into its own file
Maciej Fijalkowski <fijall@gmail.com>
parents: 28782
diff changeset
28 #include "bitmanipulation.h"
29691
e9a0bcc9314d mpatch: change Py_ssize_t to ssize_t in places that will be later copied
Maciej Fijalkowski <fijall@gmail.com>
parents: 29444
diff changeset
29 #include "compat.h"
29693
b9b9f9a92481 mpatch: split mpatch into two files
Maciej Fijalkowski <fijall@gmail.com>
parents: 29692
diff changeset
30 #include "mpatch.h"
34438
b90e8da190da cext: reorder #include
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32371
diff changeset
31 #include "util.h"
11360
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
32
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
33 static char mpatch_doc[] = "Efficient binary patching.";
1722
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
34 static PyObject *mpatch_Error;
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
35
29749
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
36 static void setpyerr(int r)
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
37 {
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
38 switch (r) {
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
39 case MPATCH_ERR_NO_MEM:
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
40 PyErr_NoMemory();
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
41 break;
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
42 case MPATCH_ERR_CANNOT_BE_DECODED:
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
43 PyErr_SetString(mpatch_Error, "patch cannot be decoded");
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
44 break;
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
45 case MPATCH_ERR_INVALID_PATCH:
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
46 PyErr_SetString(mpatch_Error, "invalid patch");
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
47 break;
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
48 }
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
49 }
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
50
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
51 struct mpatch_flist *cpygetitem(void *bins, ssize_t pos)
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
52 {
39992
ec3c06a1c554 cext: use modern buffer protocol in mpatch_flist()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39991
diff changeset
53 Py_buffer buffer;
ec3c06a1c554 cext: use modern buffer protocol in mpatch_flist()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39991
diff changeset
54 struct mpatch_flist *res = NULL;
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
55 int r;
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
56
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
57 PyObject *tmp = PyList_GetItem((PyObject *)bins, pos);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
58 if (!tmp) {
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
59 return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
60 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
61 if (PyObject_GetBuffer(tmp, &buffer, PyBUF_CONTIG_RO)) {
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
62 return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
63 }
39992
ec3c06a1c554 cext: use modern buffer protocol in mpatch_flist()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39991
diff changeset
64 if ((r = mpatch_decode(buffer.buf, buffer.len, &res)) < 0) {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
65 if (!PyErr_Occurred()) {
29749
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
66 setpyerr(r);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
67 }
39992
ec3c06a1c554 cext: use modern buffer protocol in mpatch_flist()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39991
diff changeset
68 res = NULL;
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
69 }
39992
ec3c06a1c554 cext: use modern buffer protocol in mpatch_flist()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39991
diff changeset
70
ec3c06a1c554 cext: use modern buffer protocol in mpatch_flist()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39991
diff changeset
71 PyBuffer_Release(&buffer);
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
72 return res;
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
73 }
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
74
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
75 static PyObject *patches(PyObject *self, PyObject *args)
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
76 {
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
77 PyObject *text, *bins, *result;
29692
6b3a8d034b69 mpatch: provide things that will be exported later with a prefixed name
Maciej Fijalkowski <fijall@gmail.com>
parents: 29691
diff changeset
78 struct mpatch_flist *patch;
39991
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
79 Py_buffer buffer;
29742
b410e26692a4 mpatch: silence warning about maybe-uninitialized variable
Yuya Nishihara <yuya@tcha.org>
parents: 29740
diff changeset
80 int r = 0;
5444
a0952e4e52eb mpatch: allow buffer objects for input
Matt Mackall <mpm@selenic.com>
parents: 4377
diff changeset
81 char *out;
39991
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
82 Py_ssize_t len, outlen;
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
83
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
84 if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins)) {
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
85 return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
86 }
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
87
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
88 len = PyList_Size(bins);
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
89 if (!len) {
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
90 /* nothing to do */
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
91 Py_INCREF(text);
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
92 return text;
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
93 }
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
94
39991
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
95 if (PyObject_GetBuffer(text, &buffer, PyBUF_CONTIG_RO)) {
5444
a0952e4e52eb mpatch: allow buffer objects for input
Matt Mackall <mpm@selenic.com>
parents: 4377
diff changeset
96 return NULL;
39991
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
97 }
5444
a0952e4e52eb mpatch: allow buffer objects for input
Matt Mackall <mpm@selenic.com>
parents: 4377
diff changeset
98
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
99 patch = mpatch_fold(bins, cpygetitem, 0, len);
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
100 if (!patch) { /* error already set or memory error */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
101 if (!PyErr_Occurred()) {
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
102 PyErr_NoMemory();
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
103 }
39991
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
104 result = NULL;
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
105 goto cleanup;
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
106 }
128
d6afb6dbf9f2 Add safety checking to mpatch
mpm@selenic.com
parents: 82
diff changeset
107
39991
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
108 outlen = mpatch_calcsize(buffer.len, patch);
1722
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
109 if (outlen < 0) {
29694
55dd12204b8e mpatch: remove dependency on Python.h in mpatch.c
Maciej Fijalkowski <fijall@gmail.com>
parents: 29693
diff changeset
110 r = (int)outlen;
1722
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
111 result = NULL;
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
112 goto cleanup;
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
113 }
11360
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
114 result = PyBytes_FromStringAndSize(NULL, outlen);
1722
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
115 if (!result) {
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
116 result = NULL;
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
117 goto cleanup;
128
d6afb6dbf9f2 Add safety checking to mpatch
mpm@selenic.com
parents: 82
diff changeset
118 }
11360
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
119 out = PyBytes_AsString(result);
36361
a2d11d23bb25 patches: release the GIL while applying the patch
Boris Feld <boris.feld@octobus.net>
parents: 36227
diff changeset
120 /* clang-format off */
a2d11d23bb25 patches: release the GIL while applying the patch
Boris Feld <boris.feld@octobus.net>
parents: 36227
diff changeset
121 {
a2d11d23bb25 patches: release the GIL while applying the patch
Boris Feld <boris.feld@octobus.net>
parents: 36227
diff changeset
122 Py_BEGIN_ALLOW_THREADS
39991
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
123 r = mpatch_apply(out, buffer.buf, buffer.len, patch);
36361
a2d11d23bb25 patches: release the GIL while applying the patch
Boris Feld <boris.feld@octobus.net>
parents: 36227
diff changeset
124 Py_END_ALLOW_THREADS
a2d11d23bb25 patches: release the GIL while applying the patch
Boris Feld <boris.feld@octobus.net>
parents: 36227
diff changeset
125 }
a2d11d23bb25 patches: release the GIL while applying the patch
Boris Feld <boris.feld@octobus.net>
parents: 36227
diff changeset
126 /* clang-format on */
35941
3028a3215a2e patches: move assignment outside the conditional
Boris Feld <boris.feld@octobus.net>
parents: 34438
diff changeset
127 if (r < 0) {
1722
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
128 Py_DECREF(result);
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
129 result = NULL;
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
130 }
681c5c211b92 catch errors and throw exception with invalid binary patch data
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 597
diff changeset
131 cleanup:
29692
6b3a8d034b69 mpatch: provide things that will be exported later with a prefixed name
Maciej Fijalkowski <fijall@gmail.com>
parents: 29691
diff changeset
132 mpatch_lfree(patch);
39991
77492c10a35b cext: use modern buffer protocol in patches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36620
diff changeset
133 PyBuffer_Release(&buffer);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
134 if (!result && !PyErr_Occurred()) {
29749
155f0cc3f813 mpatch: raise MemoryError instead of mpatchError if lalloc() failed
Yuya Nishihara <yuya@tcha.org>
parents: 29742
diff changeset
135 setpyerr(r);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
136 }
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
137 return result;
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
138 }
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
139
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
140 /* calculate size of a patched file directly */
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
141 static PyObject *patchedsize(PyObject *self, PyObject *args)
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
142 {
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 16758
diff changeset
143 long orig, start, end, len, outlen = 0, last = 0, pos = 0;
16758
9a8ab5c47f84 mpatch: use Py_ssize_t for string length
Adrian Buehlmann <adrian@cadifra.com>
parents: 16757
diff changeset
144 Py_ssize_t patchlen;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 16758
diff changeset
145 char *bin;
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
146
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
147 if (!PyArg_ParseTuple(args, PY23("ls#", "ly#"), &orig, &bin,
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
148 &patchlen)) {
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
149 return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
150 }
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
151
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 16758
diff changeset
152 while (pos >= 0 && pos < patchlen) {
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 16758
diff changeset
153 start = getbe32(bin + pos);
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 16758
diff changeset
154 end = getbe32(bin + pos + 4);
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 16758
diff changeset
155 len = getbe32(bin + pos + 8);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
156 if (start > end) {
4358
11dc22eb8e8d Fix segfaults when parsing bdiff hunks in mpatch.decode() and .patchedsize()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3138
diff changeset
157 break; /* sanity check */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
158 }
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 16758
diff changeset
159 pos += 12 + len;
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
160 outlen += start - last;
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
161 last = end;
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
162 outlen += len;
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
163 }
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
164
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 16758
diff changeset
165 if (pos != patchlen) {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
166 if (!PyErr_Occurred()) {
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
167 PyErr_SetString(mpatch_Error,
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
168 "patch cannot be decoded");
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 39992
diff changeset
169 }
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
170 return NULL;
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
171 }
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
172
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
173 outlen += orig - last;
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
174 return Py_BuildValue("l", outlen);
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
175 }
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 1978
diff changeset
176
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
177 static PyMethodDef methods[] = {
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
178 {"patches", patches, METH_VARARGS, "apply a series of patches\n"},
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
179 {"patchedsize", patchedsize, METH_VARARGS, "calculed patched size\n"},
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
180 {NULL, NULL},
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
181 };
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
182
32358
5fc3459d0493 mpatch: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 29749
diff changeset
183 static const int version = 1;
5fc3459d0493 mpatch: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 29749
diff changeset
184
11360
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
185 #ifdef IS_PY3K
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
186 static struct PyModuleDef mpatch_module = {
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
187 PyModuleDef_HEAD_INIT, "mpatch", mpatch_doc, -1, methods,
11360
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
188 };
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
189
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
190 PyMODINIT_FUNC PyInit_mpatch(void)
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
191 {
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
192 PyObject *m;
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
193
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
194 m = PyModule_Create(&mpatch_module);
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
195 if (m == NULL)
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
196 return NULL;
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
197
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
198 mpatch_Error =
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
199 PyErr_NewException("mercurial.cext.mpatch.mpatchError", NULL, NULL);
11360
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
200 Py_INCREF(mpatch_Error);
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
201 PyModule_AddObject(m, "mpatchError", mpatch_Error);
32358
5fc3459d0493 mpatch: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 29749
diff changeset
202 PyModule_AddIntConstant(m, "version", version);
11360
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
203
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
204 return m;
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
205 }
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
206 #else
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
207 PyMODINIT_FUNC initmpatch(void)
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
208 {
32358
5fc3459d0493 mpatch: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 29749
diff changeset
209 PyObject *m;
5fc3459d0493 mpatch: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 29749
diff changeset
210 m = Py_InitModule3("mpatch", methods, mpatch_doc);
36227
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
211 mpatch_Error =
69080ee1fb0e mpatch: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 35941
diff changeset
212 PyErr_NewException("mercurial.cext.mpatch.mpatchError", NULL, NULL);
32358
5fc3459d0493 mpatch: add version to help detect breaking binary changes
Jun Wu <quark@fb.com>
parents: 29749
diff changeset
213 PyModule_AddIntConstant(m, "version", version);
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents:
diff changeset
214 }
11360
2ac98313b26c mpatch.c: Added preliminary support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
215 #endif