226
static void recurse(struct line *a, struct line *b, struct pos *pos,
227
int a1, int a2, int b1, int b2, struct hunklist *l)
224
static struct hunk *recurse(struct line *a, struct line *b, struct pos *pos,
225
int a1, int a2, int b1, int b2, struct hunk *l)
232
230
/* find the longest match in this chunk */
233
231
k = longest_match(a, b, pos, a1, a2, b1, b2, &i, &j);
237
235
/* and recurse on the remaining chunks on either side */
238
recurse(a, b, pos, a1, i, b1, j, l);
244
/* tail-recursion didn't happen, so doing equivalent iteration */
236
l = recurse(a, b, pos, a1, i, b1, j, l);
240
l->next = (struct hunk *)malloc(sizeof(struct hunk));
251
/* tail-recursion didn't happen, so do equivalent iteration */
250
static struct hunklist diff(struct line *a, int an, struct line *b, int bn)
257
static int diff(struct line *a, int an, struct line *b, int bn,
253
260
struct hunk *curr;
257
264
/* allocate and fill arrays */
258
265
t = equatelines(a, an, b, bn);
259
266
pos = (struct pos *)calloc(bn ? bn : 1, sizeof(struct pos));
260
/* we can't have more matches than lines in the shorter file */
261
l.head = l.base = (struct hunk *)malloc(sizeof(struct hunk) *
262
((an<bn ? an:bn) + 1));
264
if (pos && l.base && t) {
265
269
/* generate the matching block list */
266
recurse(a, b, pos, 0, an, 0, bn, &l);
267
l.head->a1 = l.head->a2 = an;
268
l.head->b1 = l.head->b2 = bn;
271
curr = recurse(a, b, pos, 0, an, 0, bn, base);
275
/* sentinel end hunk */
276
curr->next = (struct hunk *)malloc(sizeof(struct hunk));
280
curr->a1 = curr->a2 = an;
281
curr->b1 = curr->b2 = bn;
274
287
/* normalize the hunk list, try to push each hunk towards the end */
275
for (curr = l.base; curr != l.head; curr++) {
276
struct hunk *next = curr + 1;
288
for (curr = base->next; curr; curr = curr->next) {
289
struct hunk *next = curr->next;
282
295
if (curr->a2 == next->a1)
297
310
next->a1 += shift;
313
for (curr = base->next; curr; curr = curr->next)
318
static void freehunks(struct hunk *l)
303
327
static PyObject *blocks(PyObject *self, PyObject *args)
305
329
PyObject *sa, *sb, *rl = NULL, *m;
306
330
struct line *a, *b;
307
struct hunklist l = {NULL, NULL};
332
int an, bn, count, pos = 0;
311
334
if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb))
320
l = diff(a, an, b, bn);
321
rl = PyList_New(l.head - l.base);
325
for (h = l.base; h != l.head; h++) {
344
count = diff(a, an, b, bn, &l);
348
rl = PyList_New(count);
352
for (h = l.next; h; h = h->next) {
326
353
m = Py_BuildValue("iiii", h->a1, h->a2, h->b1, h->b2);
327
354
PyList_SetItem(rl, pos, m);
341
368
PyObject *result = NULL;
342
369
struct line *al, *bl;
343
struct hunklist l = {NULL, NULL};
345
371
char encode[12], *rb;
346
int an, bn, len = 0, la, lb;
372
int an, bn, len = 0, la, lb, count;
348
374
if (!PyArg_ParseTuple(args, "s#s#:bdiff", &sa, &la, &sb, &lb))
356
l = diff(al, an, bl, bn);
383
count = diff(al, an, bl, bn, &l);
360
387
/* calculate length of output */
362
for (h = l.base; h != l.head; h++) {
389
for (h = l.next; h; h = h->next) {
363
390
if (h->a1 != la || h->b1 != lb)
364
391
len += 12 + bl[h->b1].l - bl[lb].l;