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>

Jeff King committed Nov 2, 2018 at 02:35 UTC 9346d6d14dddc7989ba879839d58f6c2426cffbb
6 files changed +48 -20
combine-diff.c
+2 -2
@@ -419,8 +419,8 @@ static void combine_diff(const struct object_id *parent, unsigned int mode,
419 state.num_parent = num_parent;
420 state.n = n;
421
422 - if (xdi_diff_outf(&parent_file, result_file, consume_line, &state,
423 - &xpp, &xecfg))
422 + if (xdi_diff_outf(&parent_file, result_file, NULL, consume_line,
423 + &state, &xpp, &xecfg))
424 die("unable to generate combined diff for %s",
425 oid_to_hex(parent));
426 free(parent_file.ptr);
diff.c
+10 -10
@@ -2045,8 +2045,8 @@ static void diff_words_show(struct diff_words_data *diff_words)
2045 xpp.flags = 0;
2046 /* as only the hunk header will be parsed, we need a 0-context */
2047 xecfg.ctxlen = 0;
2048 - if (xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
2049 - &xpp, &xecfg))
2048 + if (xdi_diff_outf(&minus, &plus, NULL, fn_out_diff_words_aux,
2049 + diff_words, &xpp, &xecfg))
2050 die("unable to generate word diff");
2051 free(minus.ptr);
2052 free(plus.ptr);
@@ -3495,8 +3495,8 @@ static void builtin_diff(const char *name_a,
3495 xecfg.ctxlen = strtoul(v, NULL, 10);
3496 if (o->word_diff)
3497 init_diff_words_data(&ecbdata, o, one, two);
3498 - if (xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
3499 - &xpp, &xecfg))
3498 + if (xdi_diff_outf(&mf1, &mf2, NULL, fn_out_consume,
3499 + &ecbdata, &xpp, &xecfg))
3500 die("unable to generate diff for %s", one->path);
3501 if (o->word_diff)
3502 free_diff_words_data(&ecbdata);
@@ -3604,8 +3604,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
3604 xpp.anchors_nr = o->anchors_nr;
3605 xecfg.ctxlen = o->context;
3606 xecfg.interhunkctxlen = o->interhunkcontext;
3607 - if (xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
3608 - &xpp, &xecfg))
3607 + if (xdi_diff_outf(&mf1, &mf2, NULL, diffstat_consume,
3608 + diffstat, &xpp, &xecfg))
3609 die("unable to generate diffstat for %s", one->path);
3610 }
3611
@@ -3652,8 +3652,8 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
3652 memset(&xecfg, 0, sizeof(xecfg));
3653 xecfg.ctxlen = 1; /* at least one context line */
3654 xpp.flags = 0;
3655 - if (xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
3656 - &xpp, &xecfg))
3655 + if (xdi_diff_outf(&mf1, &mf2, NULL, checkdiff_consume,
3656 + &data, &xpp, &xecfg))
3657 die("unable to generate checkdiff for %s", one->path);
3658
3659 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
5712 xpp.flags = 0;
5713 xecfg.ctxlen = 3;
5714 xecfg.flags = 0;
5715 - if (xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
5716 - &xpp, &xecfg))
5715 + if (xdi_diff_outf(&mf1, &mf2, NULL, patch_id_consume,
5716 + &data, &xpp, &xecfg))
5717 return error("unable to generate patch-id diff for %s",
5718 p->one->path);
5719 }
diffcore-pickaxe.c
+1 -1
@@ -62,7 +62,7 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
62 ecbdata.hit = 0;
63 xecfg.ctxlen = o->context;
64 xecfg.interhunkctxlen = o->interhunkcontext;
65 - if (xdi_diff_outf(one, two, diffgrep_consume, &ecbdata, &xpp, &xecfg))
65 + if (xdi_diff_outf(one, two, NULL, diffgrep_consume, &ecbdata, &xpp, &xecfg))
66 return 0;
67 return ecbdata.hit;
68 }
range-diff.c
+1 -1
@@ -190,7 +190,7 @@ static int diffsize(const char *a, const char *b)
190 mf2.size = strlen(b);
191
192 cfg.ctxlen = 3;
193 - if (!xdi_diff_outf(&mf1, &mf2, diffsize_consume, &count, &pp, &cfg))
193 + if (!xdi_diff_outf(&mf1, &mf2, NULL, diffsize_consume, &count, &pp, &cfg))
194 return count;
195
196 error(_("failed to generate diff"));
xdiff-interface.c
+26 -4
@@ -9,7 +9,8 @@
9 #include "xdiff/xutils.h"
10
11 struct xdiff_emit_state {
12 - xdiff_emit_consume_fn consume;
12 + xdiff_emit_hunk_fn hunk_fn;
13 + xdiff_emit_line_fn line_fn;
14 void *consume_callback_data;
15 struct strbuf remainder;
16 };
@@ -59,6 +60,22 @@ int parse_hunk_header(char *line, int len,
60 return -!!memcmp(cp, " @@", 3);
61 }
62
63 +static int xdiff_out_hunk(void *priv_,
64 + long old_begin, long old_nr,
65 + long new_begin, long new_nr,
66 + const char *func, long funclen)
67 +{
68 + struct xdiff_emit_state *priv = priv_;
69 +
70 + if (priv->remainder.len)
71 + BUG("xdiff emitted hunk in the middle of a line");
72 +
73 + priv->hunk_fn(priv->consume_callback_data,
74 + old_begin, old_nr, new_begin, new_nr,
75 + func, funclen);
76 + return 0;
77 +}
78 +
79 static void consume_one(void *priv_, char *s, unsigned long size)
80 {
81 struct xdiff_emit_state *priv = priv_;
@@ -67,7 +84,7 @@ static void consume_one(void *priv_, char *s, unsigned long size)
84 unsigned long this_size;
85 ep = memchr(s, '\n', size);
86 this_size = (ep == NULL) ? size : (ep - s + 1);
70 - priv->consume(priv->consume_callback_data, s, this_size);
87 + priv->line_fn(priv->consume_callback_data, s, this_size);
88 size -= this_size;
89 s += this_size;
90 }
@@ -141,7 +158,9 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co
158 }
159
160 int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
144 - xdiff_emit_consume_fn fn, void *consume_callback_data,
161 + xdiff_emit_hunk_fn hunk_fn,
162 + xdiff_emit_line_fn line_fn,
163 + void *consume_callback_data,
164 xpparam_t const *xpp, xdemitconf_t const *xecfg)
165 {
166 int ret;
@@ -149,9 +168,12 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
168 xdemitcb_t ecb;
169
170 memset(&state, 0, sizeof(state));
152 - state.consume = fn;
171 + state.hunk_fn = hunk_fn;
172 + state.line_fn = line_fn;
173 state.consume_callback_data = consume_callback_data;
174 memset(&ecb, 0, sizeof(ecb));
175 + if (hunk_fn)
176 + ecb.out_hunk = xdiff_out_hunk;
177 ecb.out_line = xdiff_outf;
178 ecb.priv = &state;
179 strbuf_init(&state.remainder, 0);
xdiff-interface.h
+8 -2
@@ -11,11 +11,17 @@
11 */
12 #define MAX_XDIFF_SIZE (1024UL * 1024 * 1023)
13
14 -typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long);
14 +typedef void (*xdiff_emit_line_fn)(void *, char *, unsigned long);
15 +typedef void (*xdiff_emit_hunk_fn)(void *data,
16 + long old_begin, long old_nr,
17 + long new_begin, long new_nr,
18 + const char *func, long funclen);
19
20 int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb);
21 int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
18 - xdiff_emit_consume_fn fn, void *consume_callback_data,
22 + xdiff_emit_hunk_fn hunk_fn,
23 + xdiff_emit_line_fn line_fn,
24 + void *consume_callback_data,
25 xpparam_t const *xpp, xdemitconf_t const *xecfg);
26 int parse_hunk_header(char *line, int len,
27 int *ob, int *on,