[PATCH 4/5] add xdi_diff_hunks() for callers that only need hunk lengths
From: René Scharfe <hidden>
Date: 2016-06-15 22:45:31
Subsystem:
the rest · Maintainer:
Linus Torvalds
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 <redacted> --- xdiff-interface.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- xdiff-interface.h | 4 ++++ 2 files changed, 52 insertions(+), 1 deletions(-)
diff --git a/xdiff-interface.c b/xdiff-interface.c
index 49e06af..e8ef46d 100644
--- a/xdiff-interface.c
+++ b/xdiff-interface.c@@ -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;
diff --git a/xdiff-interface.h b/xdiff-interface.h
index eaf9cd3..7352b9a 100644
--- a/xdiff-interface.h
+++ b/xdiff-interface.h@@ -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);
--
1.6.0.3.514.g2f91b