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,