[PATCH 08/10] xdiff: add XDL_EMIT_MOREHUNKHEADS
From: David A. Dalrymple (and Bhushan G. Lodha) <hidden>
Date: 2016-06-15 23:00:33
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: "Bhushan G. Lodha & David A. Dalrymple" <redacted> For filtering by function names, it's useful to split hunks whenever a function line is encountered, so that each function name being deleted or inserted gets its own hunk header (which then can be easily detected by the filter). This adds a flag, XDL_EMIT_MOREHUNKHEADS, which triggers this nonstandard behavior, and enables it only in case the --function-name option is being used. Signed-off-by: David Dalrymple (on zayin) <redacted> --- diff.c | 3 ++- diffcore-pickaxe.c | 3 ++- xdiff/xdiff.h | 1 + xdiff/xdiffi.c | 2 +- xdiff/xemit.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- xdiff/xemit.h | 4 +++- 6 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/diff.c b/diff.c
index 914b4a2..a86206c 100644
--- a/diff.c
+++ b/diff.c@@ -2381,7 +2381,8 @@ static void builtin_diff(const char *name_a, xecfg.interhunkctxlen = o->interhunkcontext; xecfg.flags = XDL_EMIT_FUNCNAMES; if (o->funcname) - xecfg.flags |= XDL_EMIT_MOREFUNCNAMES; + xecfg.flags |= XDL_EMIT_MOREFUNCNAMES + | XDL_EMIT_MOREHUNKHEADS; if (DIFF_OPT_TST(o, FUNCCONTEXT)) xecfg.flags |= XDL_EMIT_FUNCCONTEXT; if (pe)
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index ab31c18..d9f4c30 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c@@ -164,7 +164,8 @@ static int diff_funcname_filter(mmfile_t *one, mmfile_t *two, xecfg.interhunkctxlen = o->interhunkcontext; if (!(one && two)) xecfg.flags = XDL_EMIT_FUNCCONTEXT; - xecfg.flags |= XDL_EMIT_FUNCNAMES | XDL_EMIT_MOREFUNCNAMES; + xecfg.flags |= XDL_EMIT_FUNCNAMES | XDL_EMIT_MOREFUNCNAMES + | XDL_EMIT_MOREHUNKHEADS; xdi_diff_outf(one, two, match_funcname, &ecbdata, &xpp, &xecfg); return ecbdata.hit; }
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 469bded..787c376 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h@@ -45,6 +45,7 @@ #define XDL_EMIT_COMMON (1 << 1) #define XDL_EMIT_FUNCCONTEXT (1 << 2) #define XDL_EMIT_MOREFUNCNAMES (1 << 3) +#define XDL_EMIT_MOREHUNKHEADS (1 << 4) #define XDL_MMB_READONLY (1 << 0)
diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c
index 2358a2d..c29804e 100644
--- a/xdiff/xdiffi.c
+++ b/xdiff/xdiffi.c@@ -545,7 +545,7 @@ static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, xdchange_t *xch, *xche; for (xch = xscr; xch; xch = xche->next) { - xche = xdl_get_hunk(&xch, xecfg); + xche = xdl_get_hunk(xe, &xch, xecfg); if (!xch) break; if (xecfg->hunk_func(xch->i1, xche->i1 + xche->chg1 - xch->i1,
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index 0ddb094..f49eaaf 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c@@ -29,6 +29,9 @@ struct func_line { }; +static long get_func_line(xdfile_t *xdf, xdemitconf_t const *xecfg, + struct func_line *func_line, long start, long limit); + static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec); static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb);
@@ -62,7 +65,7 @@ static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t * * inside the differential hunk according to the specified configuration. * Also advance xscr if the first changes must be discarded. */ -xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) +xdchange_t *xdl_get_hunk(xdfenv_t *xe, xdchange_t **xscr, xdemitconf_t const *xecfg) { xdchange_t *xch, *xchp, *lxch; long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;
@@ -83,6 +86,59 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) lxch = *xscr; + if (xecfg->flags & XDL_EMIT_MOREHUNKHEADS) + for (xch = *xscr; xch; xch=xch->next) { + /* + * If a current change contains a func_line, end this + * hunk immediately before and create a new hunk + * starting from that line. + */ + long fl_in_xch1 = get_func_line(&xe->xdf1, xecfg, NULL, + xch->i1, xch->i1+xch->chg1); + long fl_in_xch2 = get_func_line(&xe->xdf2, xecfg, NULL, + xch->i2, xch->i2+xch->chg2); + if (fl_in_xch1 >= xch->i1 && fl_in_xch2 >= xch->i2) { + xdchange_t *new_next = + (xdchange_t *)xdl_malloc(sizeof(xdchange_t)); + new_next->i1 = xch->i1+xch->chg1; + new_next->chg1 = 0; + new_next->i2 = xch->i2; + new_next->chg2 = xch->chg2; + new_next->ignore = xch->ignore; + new_next->next = xch->next; + xch->next = new_next; + xch->chg2 = 0; + return xch; + } + if (fl_in_xch1 > xch->i1) { + xdchange_t *new_next = + (xdchange_t *)xdl_malloc(sizeof(xdchange_t)); + new_next->i1 = fl_in_xch1; + new_next->chg1 = (xch->i1+xch->chg1)-fl_in_xch1; + new_next->i2 = xch->i2; + new_next->chg2 = xch->chg2; + new_next->ignore = xch->ignore; + new_next->next = xch->next; + xch->next = new_next; + xch->chg1 = fl_in_xch1 - xch->i1; + xch->chg2 = 0; + return xch; + } + if (fl_in_xch2 > xch->i2) { + xdchange_t *new_next = + (xdchange_t *)xdl_malloc(sizeof(xdchange_t)); + new_next->i2 = fl_in_xch2; + new_next->chg2 = (xch->i2+xch->chg2)-fl_in_xch2; + new_next->i1 = xch->i1+xch->chg1; + new_next->chg1 = 0; + new_next->ignore = xch->ignore; + new_next->next = xch->next; + xch->next = new_next; + xch->chg2 = fl_in_xch2 - xch->i2; + return xch; + } + } + for (xchp = *xscr, xch = xchp->next; xch; xchp = xch, xch = xch->next) { long distance = xch->i1 - (xchp->i1 + xchp->chg1); if (distance > max_common)
@@ -173,7 +229,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, return xdl_emit_common(xe, xscr, ecb, xecfg); for (xch = xscr; xch; xch = xche->next) { - xche = xdl_get_hunk(&xch, xecfg); + xche = xdl_get_hunk(xe, &xch, xecfg); if (!xch) break;
diff --git a/xdiff/xemit.h b/xdiff/xemit.h
index d297107..4d584f5 100644
--- a/xdiff/xemit.h
+++ b/xdiff/xemit.h@@ -27,7 +27,9 @@ typedef int (*emit_func_t)(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, xdemitconf_t const *xecfg); -xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg); +xdchange_t *xdl_get_hunk(xdfenv_t *xe, xdchange_t **xscr, + xdemitconf_t const *xecfg); + int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, xdemitconf_t const *xecfg);
--
1.7.12.4 (Apple Git-37)