From patchwork Fri Nov 2 06:35:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10664991 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9FEB246E4 for ; Fri, 2 Nov 2018 06:36:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6F93F2B8E4 for ; Fri, 2 Nov 2018 06:36:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 63EF02BB10; Fri, 2 Nov 2018 06:36:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 16EC92BC9F for ; Fri, 2 Nov 2018 06:36:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727982AbeKBPlI (ORCPT ); Fri, 2 Nov 2018 11:41:08 -0400 Received: from cloud.peff.net ([104.130.231.41]:37702 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727745AbeKBPlH (ORCPT ); Fri, 2 Nov 2018 11:41:07 -0400 Received: (qmail 29413 invoked by uid 109); 2 Nov 2018 06:35:03 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:35:03 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 927 invoked by uid 111); 2 Nov 2018 06:34:20 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:34:20 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:35:01 -0400 Date: Fri, 2 Nov 2018 02:35:01 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 1/9] xdiff: provide a separate emit callback for hunks Message-ID: <20181102063501.GA31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- builtin/merge-tree.c | 3 ++- builtin/rerere.c | 3 ++- xdiff-interface.c | 2 +- xdiff/xdiff.h | 6 +++++- xdiff/xutils.c | 21 +++++++++++++++++---- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 8fc108d305..70f6fc9167 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -110,7 +110,8 @@ static void show_diff(struct merge_list *entry) xpp.flags = 0; memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = 3; - ecb.outf = show_outf; + ecb.out_hunk = NULL; + ecb.out_line = show_outf; ecb.priv = NULL; src.ptr = origin(entry, &size); diff --git a/builtin/rerere.c b/builtin/rerere.c index e89ccbc524..d78eeaed32 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -41,7 +41,8 @@ static int diff_two(const char *file1, const char *label1, xpp.flags = 0; memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = 3; - ecb.outf = outf; + ecb.out_hunk = NULL; + ecb.out_line = outf; ret = xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb); free(minus.ptr); diff --git a/xdiff-interface.c b/xdiff-interface.c index e7af95db86..25c185aff4 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -152,7 +152,7 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2, state.consume = fn; state.consume_callback_data = consume_callback_data; memset(&ecb, 0, sizeof(ecb)); - ecb.outf = xdiff_outf; + ecb.out_line = xdiff_outf; ecb.priv = &state; strbuf_init(&state.remainder, 0); ret = xdi_diff(mf1, mf2, xpp, xecfg, &ecb); diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 2356da5f78..b158369020 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -86,7 +86,11 @@ typedef struct s_xpparam { typedef struct s_xdemitcb { void *priv; - int (*outf)(void *, mmbuffer_t *, int); + int (*out_hunk)(void *, + long old_begin, long old_nr, + long new_begin, long new_nr, + const char *func, long funclen); + int (*out_line)(void *, mmbuffer_t *, int); } xdemitcb_t; typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv); diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 88e5995535..963e1c58b9 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -54,7 +54,7 @@ int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize, mb[2].size = strlen(mb[2].ptr); i++; } - if (ecb->outf(ecb->priv, mb, i) < 0) { + if (ecb->out_line(ecb->priv, mb, i) < 0) { return -1; } @@ -344,8 +344,9 @@ int xdl_num_out(char *out, long val) { return str - out; } -int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, - const char *func, long funclen, xdemitcb_t *ecb) { +static int xdl_format_hunk_hdr(long s1, long c1, long s2, long c2, + const char *func, long funclen, + xdemitcb_t *ecb) { int nb = 0; mmbuffer_t mb; char buf[128]; @@ -387,9 +388,21 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, mb.ptr = buf; mb.size = nb; - if (ecb->outf(ecb->priv, &mb, 1) < 0) + if (ecb->out_line(ecb->priv, &mb, 1) < 0) return -1; + return 0; +} +int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, + const char *func, long funclen, + xdemitcb_t *ecb) { + if (!ecb->out_hunk) + return xdl_format_hunk_hdr(s1, c1, s2, c2, func, funclen, ecb); + if (ecb->out_hunk(ecb->priv, + c1 ? s1 : s1 - 1, c1, + c2 ? s2 : s2 - 1, c2, + func, funclen) < 0) + return -1; return 0; } From patchwork Fri Nov 2 06:35:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10664989 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5FE7F157A for ; Fri, 2 Nov 2018 06:36:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2BF722B8E4 for ; Fri, 2 Nov 2018 06:36:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 209332BCA1; Fri, 2 Nov 2018 06:36:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 431232B8E4 for ; Fri, 2 Nov 2018 06:36:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728331AbeKBPlw (ORCPT ); Fri, 2 Nov 2018 11:41:52 -0400 Received: from cloud.peff.net ([104.130.231.41]:37710 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727745AbeKBPlw (ORCPT ); Fri, 2 Nov 2018 11:41:52 -0400 Received: (qmail 29446 invoked by uid 109); 2 Nov 2018 06:35:47 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:35:47 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 943 invoked by uid 111); 2 Nov 2018 06:35:04 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:35:04 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:35:45 -0400 Date: Fri, 2 Nov 2018 02:35:45 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 2/9] xdiff-interface: provide a separate consume callback for hunks Message-ID: <20181102063545.GB31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- combine-diff.c | 4 ++-- diff.c | 20 ++++++++++---------- diffcore-pickaxe.c | 2 +- range-diff.c | 2 +- xdiff-interface.c | 30 ++++++++++++++++++++++++++---- xdiff-interface.h | 10 ++++++++-- 6 files changed, 48 insertions(+), 20 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index 10155e0ec8..3c479cfc3e 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -421,8 +421,8 @@ static void combine_diff(struct repository *r, 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 8647db3d30..07be5879e5 100644 --- a/diff.c +++ b/diff.c @@ -2074,8 +2074,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); @@ -3526,8 +3526,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); @@ -3637,8 +3637,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); } @@ -3686,8 +3686,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) { @@ -5771,8 +5771,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 d2361e06a1..58df35670a 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 bd8083f2d1..245fc17fee 100644 --- a/range-diff.c +++ b/range-diff.c @@ -210,7 +210,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 25c185aff4..16d37ce6be 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, From patchwork Fri Nov 2 06:36:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10664987 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2E4B317DF for ; Fri, 2 Nov 2018 06:36:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F13222BB10 for ; Fri, 2 Nov 2018 06:36:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E5D9B2BCAC; Fri, 2 Nov 2018 06:36:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6336A2BCA1 for ; Fri, 2 Nov 2018 06:36:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728351AbeKBPmN (ORCPT ); Fri, 2 Nov 2018 11:42:13 -0400 Received: from cloud.peff.net ([104.130.231.41]:37716 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727745AbeKBPmN (ORCPT ); Fri, 2 Nov 2018 11:42:13 -0400 Received: (qmail 29454 invoked by uid 109); 2 Nov 2018 06:36:08 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:36:08 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 949 invoked by uid 111); 2 Nov 2018 06:35:25 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:35:25 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:36:06 -0400 Date: Fri, 2 Nov 2018 02:36:06 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 3/9] diff: avoid generating unused hunk header lines Message-ID: <20181102063606.GC31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some callers of xdi_diff_outf() do not look at the generated hunk header lines at all. By plugging in a no-op hunk callback, this tells xdiff not to even bother formatting them. This patch introduces a stock no-op callback and uses it with a few callers whose line callbacks explicitly ignore hunk headers (because they look only for +/- lines). Signed-off-by: Jeff King --- diff.c | 4 ++-- diffcore-pickaxe.c | 3 ++- xdiff-interface.c | 6 ++++++ xdiff-interface.h | 6 ++++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/diff.c b/diff.c index 07be5879e5..d84356e007 100644 --- a/diff.c +++ b/diff.c @@ -3637,8 +3637,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, NULL, diffstat_consume, - diffstat, &xpp, &xecfg)) + if (xdi_diff_outf(&mf1, &mf2, discard_hunk_line, + diffstat_consume, diffstat, &xpp, &xecfg)) die("unable to generate diffstat for %s", one->path); } diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c index 58df35670a..69fc55ea1e 100644 --- a/diffcore-pickaxe.c +++ b/diffcore-pickaxe.c @@ -62,7 +62,8 @@ 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, NULL, diffgrep_consume, &ecbdata, &xpp, &xecfg)) + if (xdi_diff_outf(one, two, discard_hunk_line, diffgrep_consume, + &ecbdata, &xpp, &xecfg)) return 0; return ecbdata.hit; } diff --git a/xdiff-interface.c b/xdiff-interface.c index 16d37ce6be..2622981d97 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -157,6 +157,12 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co return xdl_diff(&a, &b, xpp, xecfg, xecb); } +void discard_hunk_line(void *priv, + long ob, long on, long nb, long nn, + const char *func, long funclen) +{ +} + int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2, xdiff_emit_hunk_fn hunk_fn, xdiff_emit_line_fn line_fn, diff --git a/xdiff-interface.h b/xdiff-interface.h index 2dbe2feb19..7b0ccbdd1d 100644 --- a/xdiff-interface.h +++ b/xdiff-interface.h @@ -35,6 +35,12 @@ extern void xdiff_clear_find_func(xdemitconf_t *xecfg); extern int git_xmerge_config(const char *var, const char *value, void *cb); extern int git_xmerge_style; +/* + * Can be used as a no-op hunk_fn for xdi_diff_outf(), since a NULL + * one just sends the hunk line to the line_fn callback). + */ +void discard_hunk_line(void *, long, long, long, long, const char *, long); + /* * Compare the strings l1 with l2 which are of size s1 and s2 respectively. * Returns 1 if the strings are deemed equal, 0 otherwise. From patchwork Fri Nov 2 06:36:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10664993 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 348EE17D4 for ; Fri, 2 Nov 2018 06:36:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 00B082B8E4 for ; Fri, 2 Nov 2018 06:36:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E54832BC9F; Fri, 2 Nov 2018 06:36:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 86E1C2B8E4 for ; Fri, 2 Nov 2018 06:36:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728414AbeKBPmn (ORCPT ); Fri, 2 Nov 2018 11:42:43 -0400 Received: from cloud.peff.net ([104.130.231.41]:37722 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1728409AbeKBPmn (ORCPT ); Fri, 2 Nov 2018 11:42:43 -0400 Received: (qmail 29460 invoked by uid 109); 2 Nov 2018 06:36:38 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:36:38 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 976 invoked by uid 111); 2 Nov 2018 06:35:55 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:35:55 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:36:36 -0400 Date: Fri, 2 Nov 2018 02:36:36 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 4/9] diff: discard hunk headers for patch-ids earlier Message-ID: <20181102063636.GD31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We do not include hunk header lines when computing patch-ids, since the line numbers would create false negatives. Rather than detect and skip them in our line callback, we can simply tell xdiff to avoid generating them. This is similar to the previous commit, but split out because it actually requires modifying the matching line callback. Signed-off-by: Jeff King --- diff.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/diff.c b/diff.c index d84356e007..8a83ce6058 100644 --- a/diff.c +++ b/diff.c @@ -5666,10 +5666,6 @@ static void patch_id_consume(void *priv, char *line, unsigned long len) struct patch_id_t *data = priv; int new_len; - /* Ignore line numbers when computing the SHA1 of the patch */ - if (starts_with(line, "@@ -")) - return; - new_len = remove_space(line, len); git_SHA1_Update(data->ctx, line, new_len); @@ -5771,8 +5767,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, NULL, patch_id_consume, - &data, &xpp, &xecfg)) + if (xdi_diff_outf(&mf1, &mf2, discard_hunk_line, + patch_id_consume, &data, &xpp, &xecfg)) return error("unable to generate patch-id diff for %s", p->one->path); } From patchwork Fri Nov 2 06:37:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10664995 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BD5B5157A for ; Fri, 2 Nov 2018 06:37:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C60D2B8E4 for ; Fri, 2 Nov 2018 06:37:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7D8722BC9F; Fri, 2 Nov 2018 06:37:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1F0062B8E4 for ; Fri, 2 Nov 2018 06:37:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728421AbeKBPnZ (ORCPT ); Fri, 2 Nov 2018 11:43:25 -0400 Received: from cloud.peff.net ([104.130.231.41]:37728 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727745AbeKBPnY (ORCPT ); Fri, 2 Nov 2018 11:43:24 -0400 Received: (qmail 29508 invoked by uid 109); 2 Nov 2018 06:37:20 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:37:20 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 992 invoked by uid 111); 2 Nov 2018 06:36:36 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:36:36 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:37:18 -0400 Date: Fri, 2 Nov 2018 02:37:18 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 5/9] diff: use hunk callback for word-diff Message-ID: <20181102063718.GE31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Our word-diff does not look at the -/+ lines generated by xdiff at all (because they are not real lines to show the user, but just the tokenized words split into lines). Instead we use the line numbers from the hunk headers to index our own data structure. As a result, our xdi_diff_outf() callback throws away all lines except hunk headers. We can instead use a hunk callback, which has two benefits: 1. We don't have to re-parse the generated hunk header line, but can use the passed parameters directly. 2. By setting our line callback to NULL, we can tell xdiff-interface that it does not even need to bother generating the other lines, saving a small amount of work. Signed-off-by: Jeff King --- diff.c | 12 +++++------- xdiff-interface.c | 3 +++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/diff.c b/diff.c index 8a83ce6058..37035110dc 100644 --- a/diff.c +++ b/diff.c @@ -1912,19 +1912,17 @@ static int color_words_output_graph_prefix(struct diff_words_data *diff_words) } } -static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len) +static void fn_out_diff_words_aux(void *priv, + long minus_first, long minus_len, + long plus_first, long plus_len, + const char *func, long funclen) { struct diff_words_data *diff_words = priv; struct diff_words_style *style = diff_words->style; - int minus_first, minus_len, plus_first, plus_len; const char *minus_begin, *minus_end, *plus_begin, *plus_end; struct diff_options *opt = diff_words->opt; const char *line_prefix; - if (line[0] != '@' || parse_hunk_header(line, len, - &minus_first, &minus_len, &plus_first, &plus_len)) - return; - assert(opt); line_prefix = diff_line_prefix(opt); @@ -2074,7 +2072,7 @@ 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, NULL, fn_out_diff_words_aux, + if (xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, NULL, diff_words, &xpp, &xecfg)) die("unable to generate word diff"); free(minus.ptr); diff --git a/xdiff-interface.c b/xdiff-interface.c index 2622981d97..f2a3d9a577 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -95,6 +95,9 @@ static int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf) struct xdiff_emit_state *priv = priv_; int i; + if (!priv->line_fn) + return 0; + for (i = 0; i < nbuf; i++) { if (mb[i].ptr[mb[i].size-1] != '\n') { /* Incomplete line */ From patchwork Fri Nov 2 06:38:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10664999 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 816FC157A for ; Fri, 2 Nov 2018 06:38:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4758328941 for ; Fri, 2 Nov 2018 06:38:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3435D28775; Fri, 2 Nov 2018 06:38:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE28F27DA4 for ; Fri, 2 Nov 2018 06:38:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728256AbeKBPo1 (ORCPT ); Fri, 2 Nov 2018 11:44:27 -0400 Received: from cloud.peff.net ([104.130.231.41]:37734 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727745AbeKBPo1 (ORCPT ); Fri, 2 Nov 2018 11:44:27 -0400 Received: (qmail 29541 invoked by uid 109); 2 Nov 2018 06:38:22 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:38:22 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 1008 invoked by uid 111); 2 Nov 2018 06:37:38 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:37:38 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:38:20 -0400 Date: Fri, 2 Nov 2018 02:38:20 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 6/9] combine-diff: use an xdiff hunk callback Message-ID: <20181102063820.GF31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A combined diff has to line up the hunks for all of the individual pairwise diffs, and thus needs to know their line numbers and sizes. We get that now by parsing the hunk header line that xdiff generates. However, now that xdiff supports a hunk callback, we can just use the values directly. Signed-off-by: Jeff King --- I learned to love --color-moved-ws=allow-indentation-change for this one. combine-diff.c | 67 +++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index 3c479cfc3e..ad7752ea6b 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -345,38 +345,43 @@ struct combine_diff_state { struct sline *lost_bucket; }; -static void consume_line(void *state_, char *line, unsigned long len) +static void consume_hunk(void *state_, + long ob, long on, + long nb, long nn, + const char *funcline, long funclen) { struct combine_diff_state *state = state_; - if (5 < len && !memcmp("@@ -", line, 4)) { - if (parse_hunk_header(line, len, - &state->ob, &state->on, - &state->nb, &state->nn)) - return; - state->lno = state->nb; - if (state->nn == 0) { - /* @@ -X,Y +N,0 @@ removed Y lines - * that would have come *after* line N - * in the result. Our lost buckets hang - * to the line after the removed lines, - * - * Note that this is correct even when N == 0, - * in which case the hunk removes the first - * line in the file. - */ - state->lost_bucket = &state->sline[state->nb]; - if (!state->nb) - state->nb = 1; - } else { - state->lost_bucket = &state->sline[state->nb-1]; - } - if (!state->sline[state->nb-1].p_lno) - state->sline[state->nb-1].p_lno = - xcalloc(state->num_parent, - sizeof(unsigned long)); - state->sline[state->nb-1].p_lno[state->n] = state->ob; - return; + + state->ob = ob; + state->on = on; + state->nb = nb; + state->nn = nn; + state->lno = state->nb; + if (state->nn == 0) { + /* @@ -X,Y +N,0 @@ removed Y lines + * that would have come *after* line N + * in the result. Our lost buckets hang + * to the line after the removed lines, + * + * Note that this is correct even when N == 0, + * in which case the hunk removes the first + * line in the file. + */ + state->lost_bucket = &state->sline[state->nb]; + if (!state->nb) + state->nb = 1; + } else { + state->lost_bucket = &state->sline[state->nb-1]; } + if (!state->sline[state->nb-1].p_lno) + state->sline[state->nb-1].p_lno = + xcalloc(state->num_parent, sizeof(unsigned long)); + state->sline[state->nb-1].p_lno[state->n] = state->ob; +} + +static void consume_line(void *state_, char *line, unsigned long len) +{ + struct combine_diff_state *state = state_; if (!state->lost_bucket) return; /* not in any hunk yet */ switch (line[0]) { @@ -421,8 +426,8 @@ static void combine_diff(struct repository *r, state.num_parent = num_parent; state.n = n; - if (xdi_diff_outf(&parent_file, result_file, NULL, consume_line, - &state, &xpp, &xecfg)) + if (xdi_diff_outf(&parent_file, result_file, consume_hunk, + consume_line, &state, &xpp, &xecfg)) die("unable to generate combined diff for %s", oid_to_hex(parent)); free(parent_file.ptr); From patchwork Fri Nov 2 06:39:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10665001 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 56ABC157A for ; Fri, 2 Nov 2018 06:39:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 275A22B9F2 for ; Fri, 2 Nov 2018 06:39:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1BB4D2BA33; Fri, 2 Nov 2018 06:39:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B4F272B9F2 for ; Fri, 2 Nov 2018 06:39:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728235AbeKBPpK (ORCPT ); Fri, 2 Nov 2018 11:45:10 -0400 Received: from cloud.peff.net ([104.130.231.41]:37740 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727745AbeKBPpK (ORCPT ); Fri, 2 Nov 2018 11:45:10 -0400 Received: (qmail 29587 invoked by uid 109); 2 Nov 2018 06:39:05 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:39:05 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 1024 invoked by uid 111); 2 Nov 2018 06:38:22 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:38:22 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:39:03 -0400 Date: Fri, 2 Nov 2018 02:39:03 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 7/9] diff: convert --check to use a hunk callback Message-ID: <20181102063903.GG31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The "diff --check" code needs to know the line number on which each hunk starts in order to generate its output. We get that now by parsing the hunk header line generated by xdiff, but it's much simpler to just pass it directly using a hunk callback. Signed-off-by: Jeff King --- diff.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/diff.c b/diff.c index 37035110dc..e38d1ecaf4 100644 --- a/diff.c +++ b/diff.c @@ -3128,6 +3128,15 @@ static int is_conflict_marker(const char *line, int marker_size, unsigned long l return 1; } +static void checkdiff_consume_hunk(void *priv, + long ob, long on, long nb, long nn, + const char *func, long funclen) + +{ + struct checkdiff_t *data = priv; + data->lineno = nb - 1; +} + static void checkdiff_consume(void *priv, char *line, unsigned long len) { struct checkdiff_t *data = priv; @@ -3163,12 +3172,6 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len) data->o->file, set, reset, ws); } else if (line[0] == ' ') { data->lineno++; - } else if (line[0] == '@') { - char *plus = strchr(line, '+'); - if (plus) - data->lineno = strtol(plus, NULL, 10) - 1; - else - die("invalid diff"); } } @@ -3684,8 +3687,9 @@ 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, NULL, checkdiff_consume, - &data, &xpp, &xecfg)) + if (xdi_diff_outf(&mf1, &mf2, checkdiff_consume_hunk, + checkdiff_consume, &data, + &xpp, &xecfg)) die("unable to generate checkdiff for %s", one->path); if (data.ws_rule & WS_BLANK_AT_EOF) { From patchwork Fri Nov 2 06:39:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10665003 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CDC8B157A for ; Fri, 2 Nov 2018 06:39:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9DF972BA77 for ; Fri, 2 Nov 2018 06:39:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 925162BAA1; Fri, 2 Nov 2018 06:39:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3BDAE2BA77 for ; Fri, 2 Nov 2018 06:39:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728271AbeKBPpr (ORCPT ); Fri, 2 Nov 2018 11:45:47 -0400 Received: from cloud.peff.net ([104.130.231.41]:37746 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727745AbeKBPpq (ORCPT ); Fri, 2 Nov 2018 11:45:46 -0400 Received: (qmail 29619 invoked by uid 109); 2 Nov 2018 06:39:41 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:39:41 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 1040 invoked by uid 111); 2 Nov 2018 06:38:58 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:38:58 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:39:40 -0400 Date: Fri, 2 Nov 2018 02:39:40 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 8/9] range-diff: use a hunk callback Message-ID: <20181102063939.GH31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When we count the lines in a diff, we don't actually care about the contents of each line. By using a hunk callback, we tell xdiff that it does not need to even bother generating a hunk header line, saving a small amount of work. Arguably we could even ignore the hunk headers completely, since we're just computing a cost function between patches. But doing it this way maintains the exact same behavior before and after. Signed-off-by: Jeff King --- This one might be going overboard. It can be dropped without affecting any of the other patches. range-diff.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/range-diff.c b/range-diff.c index 245fc17fee..3958720f00 100644 --- a/range-diff.c +++ b/range-diff.c @@ -197,6 +197,12 @@ static void diffsize_consume(void *data, char *line, unsigned long len) (*(int *)data)++; } +static void diffsize_hunk(void *data, long ob, long on, long nb, long nn, + const char *funcline, long funclen) +{ + diffsize_consume(data, NULL, 0); +} + static int diffsize(const char *a, const char *b) { xpparam_t pp = { 0 }; @@ -210,7 +216,9 @@ static int diffsize(const char *a, const char *b) mf2.size = strlen(b); cfg.ctxlen = 3; - if (!xdi_diff_outf(&mf1, &mf2, NULL, diffsize_consume, &count, &pp, &cfg)) + if (!xdi_diff_outf(&mf1, &mf2, + diffsize_hunk, diffsize_consume, &count, + &pp, &cfg)) return count; error(_("failed to generate diff")); From patchwork Fri Nov 2 06:40:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff King X-Patchwork-Id: 10665005 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E49CA3E9D for ; Fri, 2 Nov 2018 06:40:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B2BA52BAF6 for ; Fri, 2 Nov 2018 06:40:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A74692BB31; Fri, 2 Nov 2018 06:40:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 52F8B2BAF6 for ; Fri, 2 Nov 2018 06:40:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728422AbeKBPqV (ORCPT ); Fri, 2 Nov 2018 11:46:21 -0400 Received: from cloud.peff.net ([104.130.231.41]:37752 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727745AbeKBPqU (ORCPT ); Fri, 2 Nov 2018 11:46:20 -0400 Received: (qmail 29624 invoked by uid 109); 2 Nov 2018 06:40:15 -0000 Received: from Unknown (HELO peff.net) (10.0.1.2) by cloud.peff.net (qpsmtpd/0.94) with SMTP; Fri, 02 Nov 2018 06:40:15 +0000 Authentication-Results: cloud.peff.net; auth=none Received: (qmail 1057 invoked by uid 111); 2 Nov 2018 06:39:32 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.94) with (ECDHE-RSA-AES256-GCM-SHA384 encrypted) SMTP; Fri, 02 Nov 2018 02:39:32 -0400 Authentication-Results: peff.net; auth=none Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 02 Nov 2018 02:40:13 -0400 Date: Fri, 2 Nov 2018 02:40:13 -0400 From: Jeff King To: git@vger.kernel.org Subject: [PATCH 9/9] xdiff-interface: drop parse_hunk_header() Message-ID: <20181102064013.GI31216@sigill.intra.peff.net> References: <20181102063156.GA30252@sigill.intra.peff.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181102063156.GA30252@sigill.intra.peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This function was used only for parsing the hunk headers generated by xdiff. Now that we can use hunk callbacks to get that information directly, it has outlived its usefulness. Note to anyone who wants to resurrect it: the "len" parameter was totally unused, meaning that the function could read past the end of the "line" array. In practice this never happened, because we only used it to parse xdiff's generated header lines. But it would be dangerous to use it for other cases without fixing this defect. Signed-off-by: Jeff King --- xdiff-interface.c | 45 --------------------------------------------- xdiff-interface.h | 3 --- 2 files changed, 48 deletions(-) diff --git a/xdiff-interface.c b/xdiff-interface.c index f2a3d9a577..80f060d278 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -15,51 +15,6 @@ struct xdiff_emit_state { struct strbuf remainder; }; -static int parse_num(char **cp_p, int *num_p) -{ - char *cp = *cp_p; - int num = 0; - - while ('0' <= *cp && *cp <= '9') - num = num * 10 + *cp++ - '0'; - if (!(cp - *cp_p)) - return -1; - *cp_p = cp; - *num_p = num; - return 0; -} - -int parse_hunk_header(char *line, int len, - int *ob, int *on, - int *nb, int *nn) -{ - char *cp; - cp = line + 4; - if (parse_num(&cp, ob)) { - bad_line: - return error("malformed diff output: %s", line); - } - if (*cp == ',') { - cp++; - if (parse_num(&cp, on)) - goto bad_line; - } - else - *on = 1; - if (*cp++ != ' ' || *cp++ != '+') - goto bad_line; - if (parse_num(&cp, nb)) - goto bad_line; - if (*cp == ',') { - cp++; - if (parse_num(&cp, nn)) - goto bad_line; - } - else - *nn = 1; - return -!!memcmp(cp, " @@", 3); -} - static int xdiff_out_hunk(void *priv_, long old_begin, long old_nr, long new_begin, long new_nr, diff --git a/xdiff-interface.h b/xdiff-interface.h index 7b0ccbdd1d..971aa84b57 100644 --- a/xdiff-interface.h +++ b/xdiff-interface.h @@ -23,9 +23,6 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2, 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, - int *nb, int *nn); int read_mmfile(mmfile_t *ptr, const char *filename); void read_mmblob(mmfile_t *ptr, const struct object_id *oid); int buffer_is_binary(const char *ptr, unsigned long size);