Show More
@@ -180,16 +180,66 b' nomem:' | |||||
180 | return result ? result : PyErr_NoMemory(); |
|
180 | return result ? result : PyErr_NoMemory(); | |
181 | } |
|
181 | } | |
182 |
|
182 | |||
|
183 | static bool sliceintolist(PyObject *list, Py_ssize_t destidx, | |||
|
184 | const char *source, Py_ssize_t len) | |||
|
185 | { | |||
|
186 | PyObject *sliced = PyBytes_FromStringAndSize(source, len); | |||
|
187 | if (sliced == NULL) | |||
|
188 | return false; | |||
|
189 | PyList_SET_ITEM(list, destidx, sliced); | |||
|
190 | return true; | |||
|
191 | } | |||
|
192 | ||||
|
193 | static PyObject *splitnewlines(PyObject *self, PyObject *args) | |||
|
194 | { | |||
|
195 | const char *text; | |||
|
196 | Py_ssize_t nelts = 0, size, i, start = 0; | |||
|
197 | PyObject *result = NULL; | |||
|
198 | ||||
|
199 | if (!PyArg_ParseTuple(args, "s#", &text, &size)) { | |||
|
200 | goto abort; | |||
|
201 | } | |||
|
202 | if (!size) { | |||
|
203 | return PyList_New(0); | |||
|
204 | } | |||
|
205 | /* This loops to size-1 because if the last byte is a newline, | |||
|
206 | * we don't want to perform a split there. */ | |||
|
207 | for (i = 0; i < size - 1; ++i) { | |||
|
208 | if (text[i] == '\n') { | |||
|
209 | ++nelts; | |||
|
210 | } | |||
|
211 | } | |||
|
212 | if ((result = PyList_New(nelts + 1)) == NULL) | |||
|
213 | goto abort; | |||
|
214 | nelts = 0; | |||
|
215 | for (i = 0; i < size - 1; ++i) { | |||
|
216 | if (text[i] == '\n') { | |||
|
217 | if (!sliceintolist(result, nelts++, text + start, | |||
|
218 | i - start + 1)) | |||
|
219 | goto abort; | |||
|
220 | start = i + 1; | |||
|
221 | } | |||
|
222 | } | |||
|
223 | if (!sliceintolist(result, nelts++, text + start, size - start)) | |||
|
224 | goto abort; | |||
|
225 | return result; | |||
|
226 | abort: | |||
|
227 | Py_XDECREF(result); | |||
|
228 | return NULL; | |||
|
229 | } | |||
|
230 | ||||
183 | static char mdiff_doc[] = "Efficient binary diff."; |
|
231 | static char mdiff_doc[] = "Efficient binary diff."; | |
184 |
|
232 | |||
185 | static PyMethodDef methods[] = { |
|
233 | static PyMethodDef methods[] = { | |
186 | {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"}, |
|
234 | {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"}, | |
187 | {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"}, |
|
235 | {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"}, | |
188 | {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"}, |
|
236 | {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"}, | |
|
237 | {"splitnewlines", splitnewlines, METH_VARARGS, | |||
|
238 | "like str.splitlines, but only split on newlines\n"}, | |||
189 | {NULL, NULL}, |
|
239 | {NULL, NULL}, | |
190 | }; |
|
240 | }; | |
191 |
|
241 | |||
192 |
static const int version = |
|
242 | static const int version = 2; | |
193 |
|
243 | |||
194 | #ifdef IS_PY3K |
|
244 | #ifdef IS_PY3K | |
195 | static struct PyModuleDef bdiff_module = { |
|
245 | static struct PyModuleDef bdiff_module = { |
@@ -29,16 +29,7 b' fixws = bdiff.fixws' | |||||
29 | patches = mpatch.patches |
|
29 | patches = mpatch.patches | |
30 | patchedsize = mpatch.patchedsize |
|
30 | patchedsize = mpatch.patchedsize | |
31 | textdiff = bdiff.bdiff |
|
31 | textdiff = bdiff.bdiff | |
32 |
|
32 | splitnewlines = bdiff.splitnewlines | ||
33 | def splitnewlines(text): |
|
|||
34 | '''like str.splitlines, but only split on newlines.''' |
|
|||
35 | lines = [l + '\n' for l in text.split('\n')] |
|
|||
36 | if lines: |
|
|||
37 | if lines[-1] == '\n': |
|
|||
38 | lines.pop() |
|
|||
39 | else: |
|
|||
40 | lines[-1] = lines[-1][:-1] |
|
|||
41 | return lines |
|
|||
42 |
|
33 | |||
43 | class diffopts(object): |
|
34 | class diffopts(object): | |
44 | '''context is the number of context lines |
|
35 | '''context is the number of context lines |
@@ -71,7 +71,7 b' def _importfrom(pkgname, modname):' | |||||
71 | # keep in sync with "version" in C modules |
|
71 | # keep in sync with "version" in C modules | |
72 | _cextversions = { |
|
72 | _cextversions = { | |
73 | (r'cext', r'base85'): 1, |
|
73 | (r'cext', r'base85'): 1, | |
74 |
(r'cext', r'bdiff'): |
|
74 | (r'cext', r'bdiff'): 2, | |
75 | (r'cext', r'diffhelpers'): 1, |
|
75 | (r'cext', r'diffhelpers'): 1, | |
76 | (r'cext', r'mpatch'): 1, |
|
76 | (r'cext', r'mpatch'): 1, | |
77 | (r'cext', r'osutil'): 3, |
|
77 | (r'cext', r'osutil'): 3, |
@@ -90,3 +90,13 b' def fixws(text, allws):' | |||||
90 | text = re.sub('[ \t\r]+', ' ', text) |
|
90 | text = re.sub('[ \t\r]+', ' ', text) | |
91 | text = text.replace(' \n', '\n') |
|
91 | text = text.replace(' \n', '\n') | |
92 | return text |
|
92 | return text | |
|
93 | ||||
|
94 | def splitnewlines(text): | |||
|
95 | '''like str.splitlines, but only split on newlines.''' | |||
|
96 | lines = [l + '\n' for l in text.split('\n')] | |||
|
97 | if lines: | |||
|
98 | if lines[-1] == '\n': | |||
|
99 | lines.pop() | |||
|
100 | else: | |||
|
101 | lines[-1] = lines[-1][:-1] | |||
|
102 | return lines |
General Comments 0
You need to be logged in to leave comments.
Login now