[RFC] Add "rcs format diff" support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Al was asking for the "diff -n" format, which is the old RCS format, and 
which is really easy to parse.

Now, we can't use the "-n" flag, because we use that for something else, 
and quite frankly, I don't know what to do about the diff _header_ (RCS 
format doesn't have a header, afaik), but this implements the actual core 
"xdiff" rcs-format patch emit logic, and exposes it with the 
XDL_EMIT_RCSFORMAT flag. 

(In order to get valid diffs, you also have to set the context to zero 
when you set the RCSFORMAT flag).

It also adds a "--rcs-format" flag to the git diff option parsing, so you 
can test it out, but as mentioned, we will still emit the full git header.

Davide - I think the "xdiff/" sub-part of the patch should apply fine to 
the standard xdiff sources, but I'm not sure you're really interested. The 
header issue doesn't matter there, of course, since xdiff doesn't output 
any headers (ie that is an issue for the higher-level user).

The biggest issue for the xdiff library was that I needed to pass down 
the xecfg parameter deeper into the call-chain (ie down to xdl_emit_record 
& co). The rest is pretty trivial.

Al - feel free to play with this. I didn't test it heavily, but it gave 
the right output for the one case I compared with "diff -n". This patch is 
on top of my previous patch to parse "-U" and "--unified".

Junio - this is not really meant for applying, although I don't think 
there is any real down-side to this either. 

		Linus

---
diff --git a/diff.c b/diff.c
index be925a3..fd8f454 100644
--- a/diff.c
+++ b/diff.c
@@ -568,6 +568,10 @@ static void builtin_diff(const char *nam
 			xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
 		ecb.outf = fn_out;
 		ecb.priv = &ecbdata;
+		if (o->rcs_format) {
+			xecfg.flags |= XDL_EMIT_RCSFORMAT;
+			xecfg.ctxlen = 0;
+		}
 		xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
 	}
 
@@ -1277,6 +1281,8 @@ int diff_opt_parse(struct diff_options *
 		options->output_format = DIFF_FORMAT_PATCH;
 	else if (opt_arg(arg, 'U', "unified", &options->context))
 		options->output_format = DIFF_FORMAT_PATCH;
+	else if (!strcmp(arg, "--rcs-format"))
+		options->rcs_format = 1;
 	else if (!strcmp(arg, "--patch-with-raw")) {
 		options->output_format = DIFF_FORMAT_PATCH;
 		options->with_raw = 1;
diff --git a/diff.h b/diff.h
index bef586d..953beb9 100644
--- a/diff.h
+++ b/diff.h
@@ -29,6 +29,7 @@ struct diff_options {
 		 with_stat:1,
 		 tree_in_recursive:1,
 		 binary:1,
+		 rcs_format:1,
 		 full_index:1,
 		 silent_on_remove:1,
 		 find_copies_harder:1;
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 2540e8a..a52359e 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -36,6 +36,7 @@ #define XDL_PATCH_MODEMASK ((1 << 8) - 1
 #define XDL_PATCH_IGNOREBSPACE (1 << 8)
 
 #define XDL_EMIT_FUNCNAMES (1 << 0)
+#define XDL_EMIT_RCSFORMAT (1 << 1)
 
 #define XDL_MMB_READONLY (1 << 0)
 
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index ad5bfb1..e127469 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -26,7 +26,7 @@ #include "xinclude.h"
 
 
 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);
+static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb, xdemitconf_t const *xecfg);
 static xdchange_t *xdl_get_hunk(xdchange_t *xscr, xdemitconf_t const *xecfg);
 
 
@@ -40,12 +40,13 @@ static long xdl_get_rec(xdfile_t *xdf, l
 }
 
 
-static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) {
+static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre,
+	xdemitcb_t *ecb, xdemitconf_t const *xecfg) {
 	long size, psize = strlen(pre);
 	char const *rec;
 
 	size = xdl_get_rec(xdf, ri, &rec);
-	if (xdl_emit_diffrec(rec, size, pre, psize, ecb) < 0) {
+	if (xdl_emit_diffrec(rec, size, pre, psize, ecb, xecfg) < 0) {
 
 		return -1;
 	}
@@ -129,14 +130,14 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange
 				      sizeof(funcbuf), &funclen);
 		}
 		if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
-				      funcbuf, funclen, ecb) < 0)
+				      funcbuf, funclen, ecb, xecfg) < 0)
 			return -1;
 
 		/*
 		 * Emit pre-context.
 		 */
 		for (; s1 < xch->i1; s1++)
-			if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+			if (xdl_emit_record(&xe->xdf1, s1, " ", ecb, xecfg) < 0)
 				return -1;
 
 		for (s1 = xch->i1, s2 = xch->i2;; xch = xch->next) {
@@ -144,21 +145,21 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange
 			 * Merge previous with current change atom.
 			 */
 			for (; s1 < xch->i1 && s2 < xch->i2; s1++, s2++)
-				if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+				if (xdl_emit_record(&xe->xdf1, s1, " ", ecb, xecfg) < 0)
 					return -1;
 
 			/*
 			 * Removes lines from the first file.
 			 */
 			for (s1 = xch->i1; s1 < xch->i1 + xch->chg1; s1++)
-				if (xdl_emit_record(&xe->xdf1, s1, "-", ecb) < 0)
+				if (xdl_emit_record(&xe->xdf1, s1, "-", ecb, xecfg) < 0)
 					return -1;
 
 			/*
 			 * Adds lines from the second file.
 			 */
 			for (s2 = xch->i2; s2 < xch->i2 + xch->chg2; s2++)
-				if (xdl_emit_record(&xe->xdf2, s2, "+", ecb) < 0)
+				if (xdl_emit_record(&xe->xdf2, s2, "+", ecb, xecfg) < 0)
 					return -1;
 
 			if (xch == xche)
@@ -171,7 +172,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange
 		 * Emit post-context.
 		 */
 		for (s1 = xche->i1 + xche->chg1; s1 < e1; s1++)
-			if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+			if (xdl_emit_record(&xe->xdf1, s1, " ", ecb, xecfg) < 0)
 				return -1;
 	}
 
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index 21ab8e7..b0d075a 100644
--- a/xdiff/xutils.c
+++ b/xdiff/xutils.c
@@ -43,10 +43,20 @@ long xdl_bogosqrt(long n) {
 
 
 int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
-		     xdemitcb_t *ecb) {
+		     xdemitcb_t *ecb, xdemitconf_t const *xecfg) {
 	mmbuffer_t mb[3];
 	int i;
 
+	if (xecfg->flags & XDL_EMIT_RCSFORMAT) {
+		if (*pre != '+')
+			return 0;
+		mb[0].ptr = (char *) rec;
+		mb[0].size = size;
+		if (ecb->outf(ecb->priv, mb, 1) < 0)
+			return -1;
+		return 0;
+	}
+
 	mb[0].ptr = (char *) pre;
 	mb[0].size = psize;
 	mb[1].ptr = (char *) rec;
@@ -249,11 +259,34 @@ long xdl_atol(char const *str, char cons
 
 
 int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
-		      const char *func, long funclen, xdemitcb_t *ecb) {
+		      const char *func, long funclen,
+		      xdemitcb_t *ecb, xdemitconf_t const *xecfg) {
 	int nb = 0;
 	mmbuffer_t mb;
 	char buf[128];
 
+	if (xecfg->flags & XDL_EMIT_RCSFORMAT) {
+		if (c1) {
+			buf[nb++] = 'd';
+			nb += xdl_num_out(buf + nb, s1);
+			buf[nb++] = ' ';
+			nb += xdl_num_out(buf + nb, c1);
+			buf[nb++] = '\n';
+		}
+		if (c2) {
+			buf[nb++] = 'a';
+			nb += xdl_num_out(buf + nb, s2);
+			buf[nb++] = ' ';
+			nb += xdl_num_out(buf + nb, c2);
+			buf[nb++] = '\n';
+		}
+		mb.ptr = buf;
+		mb.size = nb;
+		if (ecb->outf(ecb->priv, &mb, 1) < 0)
+			return -1;
+		return 0;
+	}
+
 	memcpy(buf, "@@ -", 4);
 	nb += 4;
 
diff --git a/xdiff/xutils.h b/xdiff/xutils.h
index ea38ee9..e5c6ed0 100644
--- a/xdiff/xutils.h
+++ b/xdiff/xutils.h
@@ -26,7 +26,7 @@ #define XUTILS_H
 
 long xdl_bogosqrt(long n);
 int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
-		     xdemitcb_t *ecb);
+		     xdemitcb_t *ecb, xdemitconf_t const *xecfg);
 int xdl_cha_init(chastore_t *cha, long isize, long icount);
 void xdl_cha_free(chastore_t *cha);
 void *xdl_cha_alloc(chastore_t *cha);
@@ -38,7 +38,8 @@ unsigned int xdl_hashbits(unsigned int s
 int xdl_num_out(char *out, long val);
 long xdl_atol(char const *str, char const **next);
 int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
-		      const char *func, long funclen, xdemitcb_t *ecb);
+		      const char *func, long funclen,
+		      xdemitcb_t *ecb, xdemitconf_t const *xecfg);
 
 
 
-
: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]