]> git.ipfire.org Git - thirdparty/git.git/commitdiff
xdiff-interface: provide a separate consume callback for hunks
authorJeff King <peff@peff.net>
Fri, 2 Nov 2018 06:35:45 +0000 (02:35 -0400)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Nov 2018 11:43:02 +0000 (20:43 +0900)
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>
combine-diff.c
diff.c
diffcore-pickaxe.c
range-diff.c
xdiff-interface.c
xdiff-interface.h

index de7695e72824f6f041e0979e29302ded6e50d611..195054b87abc244f4026a9c0008d0bdc99696d92 100644 (file)
@@ -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 145cfbae5929c69224f9f9e5bc473f2a221603de..f9b9adc545c8cd04a9660ad49cae40be6c125fdf 100644 (file)
--- 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);
        }
index 800a899c8621eaeba7f4246139df0f289ceb6ee2..7609bb4fe1b1857ff395bb79b4bf98c8f33b2f5a 100644 (file)
@@ -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;
 }
index b6b9abac266f3a6a2abdfcdd815f80b7da930854..0f4ce140dc539eb7d257f5da8b8e4250395c0c09 100644 (file)
@@ -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"));
index 88d96d78e67e14570066d079f1570bc3688eb651..eb9c05a1e34d6d9921bcb379ff0bdf7fe6c643bf 100644 (file)
@@ -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);
index 135fc05d72e8f066a63902785d12485a656efa97..2dbe2feb196c4b568c0773784059b50f74640526 100644 (file)
  */
 #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,