ref: 8fe1d622b5b46dee51db6581282ec1fba76782b1
parent: aa7c8cac1145d0cd6e9117deaa1f8c9f418bca17
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Sep 21 05:40:42 EDT 2020
diff: support unified diff via -u The format produced by `diff -u` is inferior to that produced by `diff -c`, but it's what ape/patch and unix patch expect, so it's useful to generate it. This patch adds `diff -u`.
--- a/sys/man/1/diff
+++ b/sys/man/1/diff
@@ -4,7 +4,7 @@
.SH SYNOPSIS
.B diff
[
-.B -abcefmnrw
+.B -abcefmnruw
]
.I file1 ... file2
.SH DESCRIPTION
@@ -142,6 +142,24 @@
The
.B -a
flag displays the entire file as context.
+.PP
+The
+.B -u
+option provides a unix-compatible unified diff.
+This format is similar to that provided by
+.BR -c .
+However, the
+.L +
+and
+.L -
+prefixes are not separated from the rest of the line by spaces,
+and the file header is in the following format:
+.IP
+.EX
+--- filename.old
++++ filename.new
+@@ -line,len +line,len @@
+.EE
.PP
Except in rare circumstances,
.I diff
--- a/sys/src/cmd/diff/diff.h
+++ b/sys/src/cmd/diff/diff.h
@@ -22,5 +22,6 @@
void panic(int, char *, ...);
void check(Biobuf *, Biobuf *);
void change(int, int, int, int);
+void fileheader(void);
void flushchanges(void);
--- a/sys/src/cmd/diff/diffio.c
+++ b/sys/src/cmd/diff/diffio.c
@@ -303,6 +303,7 @@
break;
case 'c':
case 'a':
+ case 'u':
if(nchanges%1024 == 0)
changes = erealloc(changes, (nchanges+1024)*sizeof(changes[0]));
ch = &changes[nchanges++];
@@ -339,6 +340,15 @@
}
void
+fileheader(void)
+{
+ if(mode != 'u')
+ return;
+ Bprint(&stdout, "--- %s\n", file1);
+ Bprint(&stdout, "+++ %s\n", file2);
+}
+
+void
flushchanges(void)
{
int a, b, c, d, at;
@@ -368,20 +378,24 @@
d = len[1];
j = nchanges;
}
- Bprint(&stdout, "%s:", file1);
- range(a, b, ",");
- Bprint(&stdout, " - ");
- Bprint(&stdout, "%s:", file2);
- range(c, d, ",");
- Bputc(&stdout, '\n');
+ if(mode == 'u'){
+ Bprint(&stdout, "@@ -%d,%d +%d,%d @@\n", a, b-a+1, c, d-c+1);
+ }else{
+ Bprint(&stdout, "%s:", file1);
+ range(a, b, ",");
+ Bprint(&stdout, " - ");
+ Bprint(&stdout, "%s:", file2);
+ range(c, d, ",");
+ Bputc(&stdout, '\n');
+ }
at = a;
for(; i<j; i++){
- fetch(ixold, at, changes[i].a-1, input[0], " ");
- fetch(ixold, changes[i].a, changes[i].b, input[0], "- ");
- fetch(ixnew, changes[i].c, changes[i].d, input[1], "+ ");
+ fetch(ixold, at, changes[i].a-1, input[0], mode == 'u' ? " " : " ");
+ fetch(ixold, changes[i].a, changes[i].b, input[0], mode == 'u' ? "-" : "- ");
+ fetch(ixnew, changes[i].c, changes[i].d, input[1], mode == 'u' ? "+" : "- ");
at = changes[i].b+1;
}
- fetch(ixold, at, b, input[0], " ");
+ fetch(ixold, at, b, input[0], mode == 'u' ? " " : " ");
}
nchanges = 0;
}
--- a/sys/src/cmd/diff/diffreg.c
+++ b/sys/src/cmd/diff/diffreg.c
@@ -285,6 +285,7 @@
m = len[0];
J[0] = 0;
J[m+1] = len[1]+1;
+ fileheader();
if (mode != 'e') {
for (i0 = 1; i0 <= m; i0 = i1+1) {
while (i0 <= m && J[i0] == J[i0-1]+1)
--- a/sys/src/cmd/diff/main.c
+++ b/sys/src/cmd/diff/main.c
@@ -192,6 +192,7 @@
case 'n':
case 'c':
case 'a':
+ case 'u':
mode = *p;
break;