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`.
This commit is contained in:
Ori Bernstein 2020-09-21 09:40:42 -07:00
parent aa7c8cac11
commit 8fe1d622b5
5 changed files with 46 additions and 11 deletions

View file

@ -4,7 +4,7 @@ diff \- differential file comparator
.SH SYNOPSIS
.B diff
[
.B -abcefmnrw
.B -abcefmnruw
]
.I file1 ... file2
.SH DESCRIPTION
@ -143,6 +143,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
finds a smallest sufficient set of file

View file

@ -22,5 +22,6 @@ Biobuf *prepare(int, char *);
void panic(int, char *, ...);
void check(Biobuf *, Biobuf *);
void change(int, int, int, int);
void fileheader(void);
void flushchanges(void);

View file

@ -303,6 +303,7 @@ change(int a, int b, int c, int d)
break;
case 'c':
case 'a':
case 'u':
if(nchanges%1024 == 0)
changes = erealloc(changes, (nchanges+1024)*sizeof(changes[0]));
ch = &changes[nchanges++];
@ -338,6 +339,15 @@ changeset(int i)
return nchanges;
}
void
fileheader(void)
{
if(mode != 'u')
return;
Bprint(&stdout, "--- %s\n", file1);
Bprint(&stdout, "+++ %s\n", file2);
}
void
flushchanges(void)
{
@ -368,20 +378,24 @@ flushchanges(void)
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;
}

View file

@ -285,6 +285,7 @@ output(void)
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)

View file

@ -192,6 +192,7 @@ main(int argc, char *argv[])
case 'n':
case 'c':
case 'a':
case 'u':
mode = *p;
break;