Show More
@@ -180,16 +180,66 b' nomem:' | |||
|
180 | 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 | 231 | static char mdiff_doc[] = "Efficient binary diff."; |
|
184 | 232 | |
|
185 | 233 | static PyMethodDef methods[] = { |
|
186 | 234 | {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"}, |
|
187 | 235 | {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"}, |
|
188 | 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 | 239 | {NULL, NULL}, |
|
190 | 240 | }; |
|
191 | 241 | |
|
192 |
static const int version = |
|
|
242 | static const int version = 2; | |
|
193 | 243 | |
|
194 | 244 | #ifdef IS_PY3K |
|
195 | 245 | static struct PyModuleDef bdiff_module = { |
@@ -29,16 +29,7 b' fixws = bdiff.fixws' | |||
|
29 | 29 | patches = mpatch.patches |
|
30 | 30 | patchedsize = mpatch.patchedsize |
|
31 | 31 | textdiff = bdiff.bdiff |
|
32 | ||
|
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 | |
|
32 | splitnewlines = bdiff.splitnewlines | |
|
42 | 33 | |
|
43 | 34 | class diffopts(object): |
|
44 | 35 | '''context is the number of context lines |
@@ -71,7 +71,7 b' def _importfrom(pkgname, modname):' | |||
|
71 | 71 | # keep in sync with "version" in C modules |
|
72 | 72 | _cextversions = { |
|
73 | 73 | (r'cext', r'base85'): 1, |
|
74 |
(r'cext', r'bdiff'): |
|
|
74 | (r'cext', r'bdiff'): 2, | |
|
75 | 75 | (r'cext', r'diffhelpers'): 1, |
|
76 | 76 | (r'cext', r'mpatch'): 1, |
|
77 | 77 | (r'cext', r'osutil'): 3, |
@@ -90,3 +90,13 b' def fixws(text, allws):' | |||
|
90 | 90 | text = re.sub('[ \t\r]+', ' ', text) |
|
91 | 91 | text = text.replace(' \n', '\n') |
|
92 | 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