summaryrefslogtreecommitdiff
path: root/xdiff-interface.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2018-11-02 06:35:45 (GMT)
committerJunio C Hamano <gitster@pobox.com>2018-11-02 11:43:02 (GMT)
commit9346d6d14dddc7989ba879839d58f6c2426cffbb (patch)
tree6255724677334f2267490a6a171f7073b17ea997 /xdiff-interface.c
parent611e42a5980a3a9f8bb3b1b49c1abde63c7a191e (diff)
downloadgit-9346d6d14dddc7989ba879839d58f6c2426cffbb.zip
git-9346d6d14dddc7989ba879839d58f6c2426cffbb.tar.gz
git-9346d6d14dddc7989ba879839d58f6c2426cffbb.tar.bz2
xdiff-interface: provide a separate consume callback for hunks
The previous commit taught xdiff to optionally provide the hunk header data to a specialized callback. But most users of xdiff actually use our more convenient xdi_diff_outf() helper, which ensures that our callbacks are always fed whole lines. Let's plumb the special hunk-callback through this interface, too. It will follow the same rule as xdiff when the hunk callback is NULL (i.e., continue to pass a stringified hunk header to the line callback). Since we add NULL to each caller, there should be no behavior change yet. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'xdiff-interface.c')
-rw-r--r--xdiff-interface.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/xdiff-interface.c b/xdiff-interface.c
index 88d96d7..eb9c05a 100644
--- a/xdiff-interface.c
+++ b/xdiff-interface.c
@@ -9,7 +9,8 @@
#include "xdiff/xutils.h"
struct xdiff_emit_state {
- xdiff_emit_consume_fn consume;
+ xdiff_emit_hunk_fn hunk_fn;
+ xdiff_emit_line_fn line_fn;
void *consume_callback_data;
struct strbuf remainder;
};
@@ -59,6 +60,22 @@ int parse_hunk_header(char *line, int len,
return -!!memcmp(cp, " @@", 3);
}
+static int xdiff_out_hunk(void *priv_,
+ long old_begin, long old_nr,
+ long new_begin, long new_nr,
+ const char *func, long funclen)
+{
+ struct xdiff_emit_state *priv = priv_;
+
+ if (priv->remainder.len)
+ BUG("xdiff emitted hunk in the middle of a line");
+
+ priv->hunk_fn(priv->consume_callback_data,
+ old_begin, old_nr, new_begin, new_nr,
+ func, funclen);
+ return 0;
+}
+
static void consume_one(void *priv_, char *s, unsigned long size)
{
struct xdiff_emit_state *priv = priv_;
@@ -67,7 +84,7 @@ static void consume_one(void *priv_, char *s, unsigned long size)
unsigned long this_size;
ep = memchr(s, '\n', size);
this_size = (ep == NULL) ? size : (ep - s + 1);
- priv->consume(priv->consume_callback_data, s, this_size);
+ priv->line_fn(priv->consume_callback_data, s, this_size);
size -= this_size;
s += this_size;
}
@@ -141,7 +158,9 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co
}
int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
- xdiff_emit_consume_fn fn, void *consume_callback_data,
+ xdiff_emit_hunk_fn hunk_fn,
+ xdiff_emit_line_fn line_fn,
+ void *consume_callback_data,
xpparam_t const *xpp, xdemitconf_t const *xecfg)
{
int ret;
@@ -149,9 +168,12 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
xdemitcb_t ecb;
memset(&state, 0, sizeof(state));
- state.consume = fn;
+ state.hunk_fn = hunk_fn;
+ state.line_fn = line_fn;
state.consume_callback_data = consume_callback_data;
memset(&ecb, 0, sizeof(ecb));
+ if (hunk_fn)
+ ecb.out_hunk = xdiff_out_hunk;
ecb.out_line = xdiff_outf;
ecb.priv = &state;
strbuf_init(&state.remainder, 0);