summary refs log tree commit diff
path: root/xdiff-interface.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2018-11-13 22:37:27 +0900
committerJunio C Hamano <gitster@pobox.com>2018-11-13 22:37:27 +0900
commit39d23dfa409e51844ddda99599927092c8300f12 (patch)
treef4975a66a1fb9c33a875fe72042e9b7c75519597 /xdiff-interface.c
parentf22838aa7a6dcf308a3307ba17f8afa40989ad3a (diff)
parent5eade0746e1daf659a9559d804068f9f31614625 (diff)
Merge branch 'jk/xdiff-interface'
The interface into "xdiff" library used to discover the offset and
size of a generated patch hunk by first formatting it into the
textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
out.  A new interface has been introduced to allow callers a more
direct access to them.

* jk/xdiff-interface:
  xdiff-interface: drop parse_hunk_header()
  range-diff: use a hunk callback
  diff: convert --check to use a hunk callback
  combine-diff: use an xdiff hunk callback
  diff: use hunk callback for word-diff
  diff: discard hunk headers for patch-ids earlier
  diff: avoid generating unused hunk header lines
  xdiff-interface: provide a separate consume callback for hunks
  xdiff: provide a separate emit callback for hunks
Diffstat (limited to 'xdiff-interface.c')
-rw-r--r--xdiff-interface.c76
1 files changed, 31 insertions, 45 deletions
diff --git a/xdiff-interface.c b/xdiff-interface.c
index e7af95db86..80f060d278 100644
--- a/xdiff-interface.c
+++ b/xdiff-interface.c
@@ -9,54 +9,26 @@
 #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;
 };
 
-static int parse_num(char **cp_p, int *num_p)
+static int xdiff_out_hunk(void *priv_,
+			  long old_begin, long old_nr,
+			  long new_begin, long new_nr,
+			  const char *func, long funclen)
 {
-	char *cp = *cp_p;
-	int num = 0;
+	struct xdiff_emit_state *priv = priv_;
 
-	while ('0' <= *cp && *cp <= '9')
-		num = num * 10 + *cp++ - '0';
-	if (!(cp - *cp_p))
-		return -1;
-	*cp_p = cp;
-	*num_p = num;
-	return 0;
-}
+	if (priv->remainder.len)
+		BUG("xdiff emitted hunk in the middle of a line");
 
-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);
+	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)
@@ -67,7 +39,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;
 	}
@@ -78,6 +50,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 */
@@ -140,8 +115,16 @@ 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_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,10 +132,13 @@ 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));
-	ecb.outf = xdiff_outf;
+	if (hunk_fn)
+		ecb.out_hunk = xdiff_out_hunk;
+	ecb.out_line = xdiff_outf;
 	ecb.priv = &state;
 	strbuf_init(&state.remainder, 0);
 	ret = xdi_diff(mf1, mf2, xpp, xecfg, &ecb);