summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2018-11-02 02:35:45 -0400
committerJunio C Hamano <gitster@pobox.com>2018-11-02 20:43:02 +0900
commit9346d6d14dddc7989ba879839d58f6c2426cffbb (patch)
tree6255724677334f2267490a6a171f7073b17ea997
parent611e42a5980a3a9f8bb3b1b49c1abde63c7a191e (diff)
downloadgit-9346d6d14dddc7989ba879839d58f6c2426cffbb.tar.gz
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>
-rw-r--r--combine-diff.c4
-rw-r--r--diff.c20
-rw-r--r--diffcore-pickaxe.c2
-rw-r--r--range-diff.c2
-rw-r--r--xdiff-interface.c30
-rw-r--r--xdiff-interface.h10
6 files changed, 48 insertions, 20 deletions
diff --git a/combine-diff.c b/combine-diff.c
index de7695e728..195054b87a 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -419,8 +419,8 @@ static void combine_diff(const struct object_id *parent, unsigned int mode,
state.num_parent = num_parent;
state.n = n;
- if (xdi_diff_outf(&parent_file, result_file, consume_line, &state,
- &xpp, &xecfg))
+ if (xdi_diff_outf(&parent_file, result_file, NULL, consume_line,
+ &state, &xpp, &xecfg))
die("unable to generate combined diff for %s",
oid_to_hex(parent));
free(parent_file.ptr);
diff --git a/diff.c b/diff.c
index 145cfbae59..f9b9adc545 100644
--- a/diff.c
+++ b/diff.c
@@ -2045,8 +2045,8 @@ static void diff_words_show(struct diff_words_data *diff_words)
xpp.flags = 0;
/* as only the hunk header will be parsed, we need a 0-context */
xecfg.ctxlen = 0;
- if (xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
- &xpp, &xecfg))
+ if (xdi_diff_outf(&minus, &plus, NULL, fn_out_diff_words_aux,
+ diff_words, &xpp, &xecfg))
die("unable to generate word diff");
free(minus.ptr);
free(plus.ptr);
@@ -3495,8 +3495,8 @@ static void builtin_diff(const char *name_a,
xecfg.ctxlen = strtoul(v, NULL, 10);
if (o->word_diff)
init_diff_words_data(&ecbdata, o, one, two);
- if (xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
- &xpp, &xecfg))
+ if (xdi_diff_outf(&mf1, &mf2, NULL, fn_out_consume,
+ &ecbdata, &xpp, &xecfg))
die("unable to generate diff for %s", one->path);
if (o->word_diff)
free_diff_words_data(&ecbdata);
@@ -3604,8 +3604,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
xpp.anchors_nr = o->anchors_nr;
xecfg.ctxlen = o->context;
xecfg.interhunkctxlen = o->interhunkcontext;
- if (xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
- &xpp, &xecfg))
+ if (xdi_diff_outf(&mf1, &mf2, NULL, diffstat_consume,
+ diffstat, &xpp, &xecfg))
die("unable to generate diffstat for %s", one->path);
}
@@ -3652,8 +3652,8 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
memset(&xecfg, 0, sizeof(xecfg));
xecfg.ctxlen = 1; /* at least one context line */
xpp.flags = 0;
- if (xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
- &xpp, &xecfg))
+ if (xdi_diff_outf(&mf1, &mf2, NULL, checkdiff_consume,
+ &data, &xpp, &xecfg))
die("unable to generate checkdiff for %s", one->path);
if (data.ws_rule & WS_BLANK_AT_EOF) {
@@ -5712,8 +5712,8 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
xpp.flags = 0;
xecfg.ctxlen = 3;
xecfg.flags = 0;
- if (xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
- &xpp, &xecfg))
+ if (xdi_diff_outf(&mf1, &mf2, NULL, patch_id_consume,
+ &data, &xpp, &xecfg))
return error("unable to generate patch-id diff for %s",
p->one->path);
}
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index 800a899c86..7609bb4fe1 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -62,7 +62,7 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
ecbdata.hit = 0;
xecfg.ctxlen = o->context;
xecfg.interhunkctxlen = o->interhunkcontext;
- if (xdi_diff_outf(one, two, diffgrep_consume, &ecbdata, &xpp, &xecfg))
+ if (xdi_diff_outf(one, two, NULL, diffgrep_consume, &ecbdata, &xpp, &xecfg))
return 0;
return ecbdata.hit;
}
diff --git a/range-diff.c b/range-diff.c
index b6b9abac26..0f4ce140dc 100644
--- a/range-diff.c
+++ b/range-diff.c
@@ -190,7 +190,7 @@ static int diffsize(const char *a, const char *b)
mf2.size = strlen(b);
cfg.ctxlen = 3;
- if (!xdi_diff_outf(&mf1, &mf2, diffsize_consume, &count, &pp, &cfg))
+ if (!xdi_diff_outf(&mf1, &mf2, NULL, diffsize_consume, &count, &pp, &cfg))
return count;
error(_("failed to generate diff"));
diff --git a/xdiff-interface.c b/xdiff-interface.c
index 88d96d78e6..eb9c05a1e3 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);
diff --git a/xdiff-interface.h b/xdiff-interface.h
index 135fc05d72..2dbe2feb19 100644
--- a/xdiff-interface.h
+++ b/xdiff-interface.h
@@ -11,11 +11,17 @@
*/
#define MAX_XDIFF_SIZE (1024UL * 1024 * 1023)
-typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long);
+typedef void (*xdiff_emit_line_fn)(void *, char *, unsigned long);
+typedef void (*xdiff_emit_hunk_fn)(void *data,
+ long old_begin, long old_nr,
+ long new_begin, long new_nr,
+ const char *func, long funclen);
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,
+ 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 parse_hunk_header(char *line, int len,
int *ob, int *on,