14 #include "util.h" |
14 #include "util.h" |
15 |
15 |
16 static char diffhelpers_doc[] = "Efficient diff parsing"; |
16 static char diffhelpers_doc[] = "Efficient diff parsing"; |
17 static PyObject *diffhelpers_Error; |
17 static PyObject *diffhelpers_Error; |
18 |
18 |
19 |
|
20 /* fixup the last lines of a and b when the patch has no newline at eof */ |
19 /* fixup the last lines of a and b when the patch has no newline at eof */ |
21 static void _fix_newline(PyObject *hunk, PyObject *a, PyObject *b) |
20 static void _fix_newline(PyObject *hunk, PyObject *a, PyObject *b) |
22 { |
21 { |
23 Py_ssize_t hunksz = PyList_Size(hunk); |
22 Py_ssize_t hunksz = PyList_Size(hunk); |
24 PyObject *s = PyList_GET_ITEM(hunk, hunksz-1); |
23 PyObject *s = PyList_GET_ITEM(hunk, hunksz - 1); |
25 char *l = PyBytes_AsString(s); |
24 char *l = PyBytes_AsString(s); |
26 Py_ssize_t alen = PyList_Size(a); |
25 Py_ssize_t alen = PyList_Size(a); |
27 Py_ssize_t blen = PyList_Size(b); |
26 Py_ssize_t blen = PyList_Size(b); |
28 char c = l[0]; |
27 char c = l[0]; |
29 PyObject *hline; |
28 PyObject *hline; |
30 Py_ssize_t sz = PyBytes_GET_SIZE(s); |
29 Py_ssize_t sz = PyBytes_GET_SIZE(s); |
31 |
30 |
32 if (sz > 1 && l[sz-2] == '\r') |
31 if (sz > 1 && l[sz - 2] == '\r') |
33 /* tolerate CRLF in last line */ |
32 /* tolerate CRLF in last line */ |
34 sz -= 1; |
33 sz -= 1; |
35 |
34 |
36 hline = PyBytes_FromStringAndSize(l, sz-1); |
35 hline = PyBytes_FromStringAndSize(l, sz - 1); |
37 if (!hline) { |
36 if (!hline) { |
38 return; |
37 return; |
39 } |
38 } |
40 |
39 |
41 if (c == ' ' || c == '+') { |
40 if (c == ' ' || c == '+') { |
42 PyObject *rline = PyBytes_FromStringAndSize(l + 1, sz - 2); |
41 PyObject *rline = PyBytes_FromStringAndSize(l + 1, sz - 2); |
43 PyList_SetItem(b, blen-1, rline); |
42 PyList_SetItem(b, blen - 1, rline); |
44 } |
43 } |
45 if (c == ' ' || c == '-') { |
44 if (c == ' ' || c == '-') { |
46 Py_INCREF(hline); |
45 Py_INCREF(hline); |
47 PyList_SetItem(a, alen-1, hline); |
46 PyList_SetItem(a, alen - 1, hline); |
48 } |
47 } |
49 PyList_SetItem(hunk, hunksz-1, hline); |
48 PyList_SetItem(hunk, hunksz - 1, hline); |
50 } |
49 } |
51 |
50 |
52 /* python callable form of _fix_newline */ |
51 /* python callable form of _fix_newline */ |
53 static PyObject * |
52 static PyObject *fix_newline(PyObject *self, PyObject *args) |
54 fix_newline(PyObject *self, PyObject *args) |
|
55 { |
53 { |
56 PyObject *hunk, *a, *b; |
54 PyObject *hunk, *a, *b; |
57 if (!PyArg_ParseTuple(args, "OOO", &hunk, &a, &b)) |
55 if (!PyArg_ParseTuple(args, "OOO", &hunk, &a, &b)) |
58 return NULL; |
56 return NULL; |
59 _fix_newline(hunk, a, b); |
57 _fix_newline(hunk, a, b); |
70 * read lines from fp into the hunk. The hunk is parsed into two arrays |
68 * read lines from fp into the hunk. The hunk is parsed into two arrays |
71 * a and b. a gets the old state of the text, b gets the new state |
69 * a and b. a gets the old state of the text, b gets the new state |
72 * The control char from the hunk is saved when inserting into a, but not b |
70 * The control char from the hunk is saved when inserting into a, but not b |
73 * (for performance while deleting files) |
71 * (for performance while deleting files) |
74 */ |
72 */ |
75 static PyObject * |
73 static PyObject *addlines(PyObject *self, PyObject *args) |
76 addlines(PyObject *self, PyObject *args) |
|
77 { |
74 { |
78 |
75 |
79 PyObject *fp, *hunk, *a, *b, *x; |
76 PyObject *fp, *hunk, *a, *b, *x; |
80 Py_ssize_t i; |
77 Py_ssize_t i; |
81 Py_ssize_t lena, lenb; |
78 Py_ssize_t lena, lenb; |
82 Py_ssize_t num; |
79 Py_ssize_t num; |
83 Py_ssize_t todoa, todob; |
80 Py_ssize_t todoa, todob; |
84 char *s, c; |
81 char *s, c; |
85 PyObject *l; |
82 PyObject *l; |
86 if (!PyArg_ParseTuple(args, addlines_format, |
83 if (!PyArg_ParseTuple(args, addlines_format, &fp, &hunk, &lena, &lenb, |
87 &fp, &hunk, &lena, &lenb, &a, &b)) |
84 &a, &b)) |
88 return NULL; |
85 return NULL; |
89 |
86 |
90 while (1) { |
87 while (1) { |
91 todoa = lena - PyList_Size(a); |
88 todoa = lena - PyList_Size(a); |
92 todob = lenb - PyList_Size(b); |
89 todob = lenb - PyList_Size(b); |
93 num = todoa > todob ? todoa : todob; |
90 num = todoa > todob ? todoa : todob; |
94 if (num == 0) |
91 if (num == 0) |
95 break; |
92 break; |
96 for (i = 0; i < num; i++) { |
93 for (i = 0; i < num; i++) { |
97 x = PyFile_GetLine(fp, 0); |
94 x = PyFile_GetLine(fp, 0); |
98 s = PyBytes_AsString(x); |
95 s = PyBytes_AsString(x); |
99 c = *s; |
96 c = *s; |
100 if (strcmp(s, "\\ No newline at end of file\n") == 0) { |
97 if (strcmp(s, "\\ No newline at end of file\n") == 0) { |
156 } |
152 } |
157 return Py_BuildValue("l", 0); |
153 return Py_BuildValue("l", 0); |
158 } |
154 } |
159 |
155 |
160 static PyMethodDef methods[] = { |
156 static PyMethodDef methods[] = { |
161 {"addlines", addlines, METH_VARARGS, "add lines to a hunk\n"}, |
157 {"addlines", addlines, METH_VARARGS, "add lines to a hunk\n"}, |
162 {"fix_newline", fix_newline, METH_VARARGS, "fixup newline counters\n"}, |
158 {"fix_newline", fix_newline, METH_VARARGS, "fixup newline counters\n"}, |
163 {"testhunk", testhunk, METH_VARARGS, "test lines in a hunk\n"}, |
159 {"testhunk", testhunk, METH_VARARGS, "test lines in a hunk\n"}, |
164 {NULL, NULL} |
160 {NULL, NULL}}; |
165 }; |
|
166 |
161 |
167 static const int version = 1; |
162 static const int version = 1; |
168 |
163 |
169 #ifdef IS_PY3K |
164 #ifdef IS_PY3K |
170 static struct PyModuleDef diffhelpers_module = { |
165 static struct PyModuleDef diffhelpers_module = { |
171 PyModuleDef_HEAD_INIT, |
166 PyModuleDef_HEAD_INIT, "diffhelpers", diffhelpers_doc, -1, methods, |
172 "diffhelpers", |
|
173 diffhelpers_doc, |
|
174 -1, |
|
175 methods |
|
176 }; |
167 }; |
177 |
168 |
178 PyMODINIT_FUNC PyInit_diffhelpers(void) |
169 PyMODINIT_FUNC PyInit_diffhelpers(void) |
179 { |
170 { |
180 PyObject *m; |
171 PyObject *m; |
181 |
172 |
182 m = PyModule_Create(&diffhelpers_module); |
173 m = PyModule_Create(&diffhelpers_module); |
183 if (m == NULL) |
174 if (m == NULL) |
184 return NULL; |
175 return NULL; |
185 |
176 |
186 diffhelpers_Error = PyErr_NewException("diffhelpers.diffhelpersError", |
177 diffhelpers_Error = |
187 NULL, NULL); |
178 PyErr_NewException("diffhelpers.diffhelpersError", NULL, NULL); |
188 Py_INCREF(diffhelpers_Error); |
179 Py_INCREF(diffhelpers_Error); |
189 PyModule_AddObject(m, "diffhelpersError", diffhelpers_Error); |
180 PyModule_AddObject(m, "diffhelpersError", diffhelpers_Error); |
190 PyModule_AddIntConstant(m, "version", version); |
181 PyModule_AddIntConstant(m, "version", version); |
191 |
182 |
192 return m; |
183 return m; |
193 } |
184 } |
194 #else |
185 #else |
195 PyMODINIT_FUNC |
186 PyMODINIT_FUNC initdiffhelpers(void) |
196 initdiffhelpers(void) |
|
197 { |
187 { |
198 PyObject *m; |
188 PyObject *m; |
199 m = Py_InitModule3("diffhelpers", methods, diffhelpers_doc); |
189 m = Py_InitModule3("diffhelpers", methods, diffhelpers_doc); |
200 diffhelpers_Error = PyErr_NewException("diffhelpers.diffhelpersError", |
190 diffhelpers_Error = |
201 NULL, NULL); |
191 PyErr_NewException("diffhelpers.diffhelpersError", NULL, NULL); |
202 PyModule_AddIntConstant(m, "version", version); |
192 PyModule_AddIntConstant(m, "version", version); |
203 } |
193 } |
204 #endif |
194 #endif |