xdiff: provide a separate emit callback for hunks

The xdiff library always emits hunk header lines to our callbacks as formatted strings like "@@ -a,b +c,d @@\n". This is convenient if we're going to output a diff, but less so if we actually need to compute using those numbers, which requires re-parsing the line. In preparation for moving away from this, let's teach xdiff a new callback function which gets the broken-out hunk information. To help callers that don't want to use this new callback, if it's NULL we'll continue to format the hunk header into a string. Note that this function renames the "outf" callback to "out_line", as well. This isn't strictly necessary, but helps in two ways: 1. Now that there are two callbacks, it's nice to use more descriptive names. 2. Many callers did not zero the emit_callback_data struct, and needed to be modified to set ecb.out_hunk to NULL. By changing the name of the existing struct member, that guarantees that any new callers from in-flight topics will break the build and be examined manually. 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 611e42a5980a3a9f8bb3b1b49c1abde63c7a191e
5 files changed +27 -8
builtin/merge-tree.c
+2 -1
@@ -110,7 +110,8 @@ static void show_diff(struct merge_list *entry)
110 xpp.flags = 0;
111 memset(&xecfg, 0, sizeof(xecfg));
112 xecfg.ctxlen = 3;
113 - ecb.outf = show_outf;
113 + ecb.out_hunk = NULL;
114 + ecb.out_line = show_outf;
115 ecb.priv = NULL;
116
117 src.ptr = origin(entry, &size);
builtin/rerere.c
+2 -1
@@ -41,7 +41,8 @@ static int diff_two(const char *file1, const char *label1,
41 xpp.flags = 0;
42 memset(&xecfg, 0, sizeof(xecfg));
43 xecfg.ctxlen = 3;
44 - ecb.outf = outf;
44 + ecb.out_hunk = NULL;
45 + ecb.out_line = outf;
46 ret = xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
47
48 free(minus.ptr);
xdiff-interface.c
+1 -1
@@ -152,7 +152,7 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
152 state.consume = fn;
153 state.consume_callback_data = consume_callback_data;
154 memset(&ecb, 0, sizeof(ecb));
155 - ecb.outf = xdiff_outf;
155 + ecb.out_line = xdiff_outf;
156 ecb.priv = &state;
157 strbuf_init(&state.remainder, 0);
158 ret = xdi_diff(mf1, mf2, xpp, xecfg, &ecb);
xdiff/xdiff.h
+5 -1
@@ -86,7 +86,11 @@ typedef struct s_xpparam {
86
87 typedef struct s_xdemitcb {
88 void *priv;
89 - int (*outf)(void *, mmbuffer_t *, int);
89 + int (*out_hunk)(void *,
90 + long old_begin, long old_nr,
91 + long new_begin, long new_nr,
92 + const char *func, long funclen);
93 + int (*out_line)(void *, mmbuffer_t *, int);
94 } xdemitcb_t;
95
96 typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv);
xdiff/xutils.c
+17 -4
@@ -54,7 +54,7 @@ int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
54 mb[2].size = strlen(mb[2].ptr);
55 i++;
56 }
57 - if (ecb->outf(ecb->priv, mb, i) < 0) {
57 + if (ecb->out_line(ecb->priv, mb, i) < 0) {
58
59 return -1;
60 }
@@ -344,8 +344,9 @@ int xdl_num_out(char *out, long val) {
344 return str - out;
345 }
346
347 -int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
348 - const char *func, long funclen, xdemitcb_t *ecb) {
347 +static int xdl_format_hunk_hdr(long s1, long c1, long s2, long c2,
348 + const char *func, long funclen,
349 + xdemitcb_t *ecb) {
350 int nb = 0;
351 mmbuffer_t mb;
352 char buf[128];
@@ -387,9 +388,21 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
388
389 mb.ptr = buf;
390 mb.size = nb;
390 - if (ecb->outf(ecb->priv, &mb, 1) < 0)
391 + if (ecb->out_line(ecb->priv, &mb, 1) < 0)
392 return -1;
393 + return 0;
394 +}
395
396 +int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
397 + const char *func, long funclen,
398 + xdemitcb_t *ecb) {
399 + if (!ecb->out_hunk)
400 + return xdl_format_hunk_hdr(s1, c1, s2, c2, func, funclen, ecb);
401 + if (ecb->out_hunk(ecb->priv,
402 + c1 ? s1 : s1 - 1, c1,
403 + c2 ? s2 : s2 - 1, c2,
404 + func, funclen) < 0)
405 + return -1;
406 return 0;
407 }
408