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:
parent
aa7c8cac11
commit
8fe1d622b5
5 changed files with 46 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -192,6 +192,7 @@ main(int argc, char *argv[])
|
|||
case 'n':
|
||||
case 'c':
|
||||
case 'a':
|
||||
case 'u':
|
||||
mode = *p;
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in a new issue