58 return rl ? rl : PyErr_NoMemory(); |
58 return rl ? rl : PyErr_NoMemory(); |
59 } |
59 } |
60 |
60 |
61 static PyObject *bdiff(PyObject *self, PyObject *args) |
61 static PyObject *bdiff(PyObject *self, PyObject *args) |
62 { |
62 { |
63 char *sa, *sb, *rb, *ia, *ib; |
63 Py_buffer ba, bb; |
|
64 char *rb, *ia, *ib; |
64 PyObject *result = NULL; |
65 PyObject *result = NULL; |
65 struct bdiff_line *al = NULL, *bl = NULL; |
66 struct bdiff_line *al = NULL, *bl = NULL; |
66 struct bdiff_hunk l, *h; |
67 struct bdiff_hunk l, *h; |
67 int an, bn, count; |
68 int an, bn, count; |
68 Py_ssize_t len = 0, la, lb, li = 0, lcommon = 0, lmax; |
69 Py_ssize_t len = 0, la, lb, li = 0, lcommon = 0, lmax; |
69 PyThreadState *_save = NULL; |
70 PyThreadState *_save = NULL; |
70 |
71 |
71 l.next = NULL; |
72 l.next = NULL; |
72 |
73 |
73 if (!PyArg_ParseTuple(args, PY23("s#s#:bdiff", "y#y#:bdiff"), &sa, &la, |
74 if (!PyArg_ParseTuple(args, PY23("s*s*:bdiff", "y*y*:bdiff"), &ba, &bb)) |
74 &sb, &lb)) |
|
75 return NULL; |
75 return NULL; |
|
76 |
|
77 if (!PyBuffer_IsContiguous(&ba, 'C') || ba.ndim > 1) { |
|
78 PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous"); |
|
79 goto cleanup; |
|
80 } |
|
81 |
|
82 if (!PyBuffer_IsContiguous(&bb, 'C') || bb.ndim > 1) { |
|
83 PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous"); |
|
84 goto cleanup; |
|
85 } |
|
86 |
|
87 la = ba.len; |
|
88 lb = bb.len; |
76 |
89 |
77 if (la > UINT_MAX || lb > UINT_MAX) { |
90 if (la > UINT_MAX || lb > UINT_MAX) { |
78 PyErr_SetString(PyExc_ValueError, "bdiff inputs too large"); |
91 PyErr_SetString(PyExc_ValueError, "bdiff inputs too large"); |
79 return NULL; |
92 goto cleanup; |
80 } |
93 } |
81 |
94 |
82 _save = PyEval_SaveThread(); |
95 _save = PyEval_SaveThread(); |
83 |
96 |
84 lmax = la > lb ? lb : la; |
97 lmax = la > lb ? lb : la; |
85 for (ia = sa, ib = sb; li < lmax && *ia == *ib; ++li, ++ia, ++ib) |
98 for (ia = ba.buf, ib = bb.buf; li < lmax && *ia == *ib; |
|
99 ++li, ++ia, ++ib) { |
86 if (*ia == '\n') |
100 if (*ia == '\n') |
87 lcommon = li + 1; |
101 lcommon = li + 1; |
|
102 } |
88 /* we can almost add: if (li == lmax) lcommon = li; */ |
103 /* we can almost add: if (li == lmax) lcommon = li; */ |
89 |
104 |
90 an = bdiff_splitlines(sa + lcommon, la - lcommon, &al); |
105 an = bdiff_splitlines(ba.buf + lcommon, la - lcommon, &al); |
91 bn = bdiff_splitlines(sb + lcommon, lb - lcommon, &bl); |
106 bn = bdiff_splitlines(bb.buf + lcommon, lb - lcommon, &bl); |
92 if (!al || !bl) { |
107 if (!al || !bl) { |
93 PyErr_NoMemory(); |
108 PyErr_NoMemory(); |
94 goto cleanup; |
109 goto cleanup; |
95 } |
110 } |
96 |
111 |