static int diff(struct line *a, int an, struct line *b, int bn, struct hunk *base) { struct hunk *curr; struct pos *pos; int t, count = 0; /* allocate and fill arrays */ t = equatelines(a, an, b, bn); pos = (struct pos *)calloc(bn ? bn : 1, sizeof(struct pos)); if (pos && t) { /* generate the matching block list */ curr = recurse(a, b, pos, 0, an, 0, bn, base); if (!curr) return -1; /* sentinel end hunk */ curr->next = (struct hunk *)malloc(sizeof(struct hunk)); if (!curr->next) return -1; curr = curr->next; curr->a1 = curr->a2 = an; curr->b1 = curr->b2 = bn; curr->next = NULL; } free(pos); /* normalize the hunk list, try to push each hunk towards the end */ for (curr = base->next; curr; curr = curr->next) { struct hunk *next = curr->next; int shift = 0; if (!next) break; if (curr->a2 == next->a1) while (curr->a2 + shift < an && curr->b2 + shift < bn && !cmp(a + curr->a2 + shift, b + curr->b2 + shift)) shift++; else if (curr->b2 == next->b1) while (curr->b2 + shift < bn && curr->a2 + shift < an && !cmp(b + curr->b2 + shift, a + curr->a2 + shift)) shift++; if (!shift) continue; curr->b2 += shift; next->b1 += shift; curr->a2 += shift; next->a1 += shift; } for (curr = base->next; curr; curr = curr->next) count++; return count; }
static struct hunklist diff(struct line *a, int an, struct line *b, int bn) { struct hunklist l; struct hunk *curr; struct pos *pos; int t; /* allocate and fill arrays */ t = equatelines(a, an, b, bn); pos = (struct pos *)calloc(bn ? bn : 1, sizeof(struct pos)); /* we can't have more matches than lines in the shorter file */ l.head = l.base = (struct hunk *)malloc(sizeof(struct hunk) * ((an<bn ? an:bn) + 1)); if (pos && l.base && t) { /* generate the matching block list */ recurse(a, b, pos, 0, an, 0, bn, &l); l.head->a1 = l.head->a2 = an; l.head->b1 = l.head->b2 = bn; l.head++; } free(pos); /* normalize the hunk list, try to push each hunk towards the end */ for (curr = l.base; curr != l.head; curr++) { struct hunk *next = curr+1; int shift = 0; if (next == l.head) break; if (curr->a2 == next->a1) while (curr->a2+shift < an && curr->b2+shift < bn && !cmp(a+curr->a2+shift, b+curr->b2+shift)) shift++; else if (curr->b2 == next->b1) while (curr->b2+shift < bn && curr->a2+shift < an && !cmp(b+curr->b2+shift, a+curr->a2+shift)) shift++; if (!shift) continue; curr->b2 += shift; next->b1 += shift; curr->a2 += shift; next->a1 += shift; } return l; }