git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 08/10] xdiff: add XDL_EMIT_MOREHUNKHEADS

From
DLDavid A. Dalrymple (and Bhushan G. Lodha) <dad-bgl@mit.edu>
Date
Mar 27, 2014, 18:50 UTC
Message-ID
<2c07e06fbb17bfb6d9d51733df0ce5755bbe97f5.1395942768.git.davidad@alum.mit.edu>
In-Reply-To
<1395946256-67124-1-git-send-email-dad-bgl@mit.edu>
From: "Bhushan G. Lodha & David A. Dalrymple" <dad-bgl@mit.edu>

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) <davidad@alum.mit.edu>
---
 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)
Previous: David A. Dalrymple (and Bhushan G. Lodha)Next: David A. Dalrymple (and Bhushan G. Lodha)
Message 15 of 23 in “[RFC] pickaxe for function names”
  1. 00/10 [RFC] pickaxe for function namesDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  2. 01/10 .gitattributes: specify the language usedDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  3. 02/10 diffcore-pickaxe.c: refactor regex compilationDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  4. 03/10 diffcore-pickaxe.c: Refactor pickaxe_fn signatureDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  5. Jakub NarębskiApr 4, 2014
  6. 04/10 diff.c/diff.h: expose userdiff_funcnameDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  7. 05/10 diffcore-pickaxe.c: set up funcname patternDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  8. 06/10 log: --function-name pickaxeDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  9. René ScharfeApr 3, 2014
  10. Junio C HamanoApr 3, 2014
  11. Jakub NarębskiApr 4, 2014
  12. Junio C HamanoApr 4, 2014
  13. Bhushan LodhaApr 28, 2014
  14. 07/10 xdiff: add XDL_EMIT_MOREFUNCNAMESDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  15. 08/10 xdiff: add XDL_EMIT_MOREHUNKHEADSDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  16. 09/10 t4213: test --function-name optionDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  17. Johannes SixtMar 28, 2014
  18. Eric SunshineMar 28, 2014
  19. Johannes SixtMar 28, 2014
  20. Jakub NarębskiApr 4, 2014
  21. 10/10 Documentation: Document --function-name usageDavid A. Dalrymple (and Bhushan G. Lodha), Mar 27, 2014
  22. Eric SunshineMar 28, 2014
  23. Jeff KingMar 27, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.