add xdi_diff_hunks() for callers that only need hunk lengths
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>
Sat, 25 Oct 2008 13:31:15 +0000 (15:31 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sat, 25 Oct 2008 19:09:31 +0000 (12:09 -0700)
Based on a patch by Brian Downing, this uses the xdiff emit_func feature
to implement xdi_diff_hunks().  It's a function that calls a callback for
each hunk of a diff, passing its lengths.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
xdiff-interface.c
xdiff-interface.h

index f3f6db3297e4fd367d7af05a4755037aaf2aaf42..70794c71fcbf198c7425a49789a912369fba28ad 100644 (file)
@@ -1,6 +1,9 @@
 #include "cache.h"
 #include "xdiff-interface.h"
-#include "strbuf.h"
+#include "xdiff/xtypes.h"
+#include "xdiff/xdiffi.h"
+#include "xdiff/xemit.h"
+#include "xdiff/xmacros.h"
 
 struct xdiff_emit_state {
        xdiff_emit_consume_fn consume;
@@ -153,6 +156,50 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
        return ret;
 }
 
+struct xdiff_emit_hunk_state {
+       xdiff_emit_hunk_consume_fn consume;
+       void *consume_callback_data;
+};
+
+static int process_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+                       xdemitconf_t const *xecfg)
+{
+       long s1, s2, same, p_next, t_next;
+       xdchange_t *xch, *xche;
+       struct xdiff_emit_hunk_state *state = ecb->priv;
+       xdiff_emit_hunk_consume_fn fn = state->consume;
+       void *consume_callback_data = state->consume_callback_data;
+
+       for (xch = xscr; xch; xch = xche->next) {
+               xche = xdl_get_hunk(xch, xecfg);
+
+               s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0);
+               s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);
+               same = s2 + XDL_MAX(xch->i1 - s1, 0);
+               p_next = xche->i1 + xche->chg1;
+               t_next = xche->i2 + xche->chg2;
+
+               fn(consume_callback_data, same, p_next, t_next);
+       }
+       return 0;
+}
+
+int xdi_diff_hunks(mmfile_t *mf1, mmfile_t *mf2,
+                  xdiff_emit_hunk_consume_fn fn, void *consume_callback_data,
+                  xpparam_t const *xpp, xdemitconf_t *xecfg)
+{
+       struct xdiff_emit_hunk_state state;
+       xdemitcb_t ecb;
+
+       memset(&state, 0, sizeof(state));
+       memset(&ecb, 0, sizeof(ecb));
+       state.consume = fn;
+       state.consume_callback_data = consume_callback_data;
+       xecfg->emit_func = (void (*)())process_diff;
+       ecb.priv = &state;
+       return xdi_diff(mf1, mf2, xpp, xecfg, &ecb);
+}
+
 int read_mmfile(mmfile_t *ptr, const char *filename)
 {
        struct stat st;
index eaf9cd34981695fc8d12fd35d01ceae93b22254d..7352b9a9c204c2b1d4ca9df5ce040fe22d6f521c 100644 (file)
@@ -4,12 +4,16 @@
 #include "xdiff/xdiff.h"
 
 typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long);
+typedef void (*xdiff_emit_hunk_consume_fn)(void *, long, long, long);
 
 int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb);
 int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
                  xdiff_emit_consume_fn fn, void *consume_callback_data,
                  xpparam_t const *xpp,
                  xdemitconf_t const *xecfg, xdemitcb_t *xecb);
+int xdi_diff_hunks(mmfile_t *mf1, mmfile_t *mf2,
+                  xdiff_emit_hunk_consume_fn fn, void *consume_callback_data,
+                  xpparam_t const *xpp, xdemitconf_t *xecfg);
 int parse_hunk_header(char *line, int len,
                      int *ob, int *on,
                      int *nb, int *nn);