diff3: fix merge mode
Make the merge mode compatible with GNU diff3 Add tests for all the changes, those tests are extracted from the etcupdate testsuite. This version passes the etcupdate testsuite and the diffutils diff3 test suite. MFC After: 1 week
This commit is contained in:
+25
-26
@@ -150,7 +150,7 @@ static void repos(int);
|
||||
static void separate(const char *);
|
||||
static void edscript(int) __dead2;
|
||||
static void Ascript(int) __dead2;
|
||||
static void mergescript(int) __dead2;
|
||||
static void mergescript(int, int) __dead2;
|
||||
static void increase(void);
|
||||
static void usage(void);
|
||||
static void printrange(FILE *, struct range *);
|
||||
@@ -361,12 +361,13 @@ merge(int m1, int m2)
|
||||
{
|
||||
struct diff *d1, *d2, *d3;
|
||||
int j, t1, t2;
|
||||
int f1f3delta;
|
||||
bool dup = false;
|
||||
|
||||
d1 = d13;
|
||||
d2 = d23;
|
||||
j = 0;
|
||||
int f1f3delta = 0;
|
||||
f1f3delta = 0;
|
||||
|
||||
for (;;) {
|
||||
t1 = (d1 < d13 + m1);
|
||||
@@ -382,6 +383,12 @@ merge(int m1, int m2)
|
||||
change(1, &d1->old, false);
|
||||
keep(2, &d1->new);
|
||||
change(3, &d1->new, false);
|
||||
} else if (mflag) {
|
||||
j++;
|
||||
de[j].type = DIFF_TYPE1;
|
||||
de[j].old = d1->old;
|
||||
de[j].new = d1->new;
|
||||
overlap[j] = 0;
|
||||
} else if (eflag == EFLAG_OVERLAP) {
|
||||
j = edit(d2, dup, j, DIFF_TYPE1);
|
||||
}
|
||||
@@ -437,6 +444,14 @@ merge(int m1, int m2)
|
||||
change(2, &d2->old, false);
|
||||
d3 = d1->old.to > d1->old.from ? d1 : d2;
|
||||
change(3, &d3->new, false);
|
||||
} else if (mflag) {
|
||||
j++;
|
||||
de[j].type = DIFF_TYPE3;
|
||||
de[j].old = d1->old;
|
||||
de[j].new = d1->new;
|
||||
overlap[j] = !dup;
|
||||
if (!dup)
|
||||
overlapcnt++;
|
||||
} else {
|
||||
j = edit(d1, dup, j, DIFF_TYPE3);
|
||||
}
|
||||
@@ -468,7 +483,7 @@ merge(int m1, int m2)
|
||||
}
|
||||
|
||||
if (mflag)
|
||||
mergescript(j);
|
||||
mergescript(j, f1f3delta);
|
||||
else if (Aflag)
|
||||
Ascript(j);
|
||||
else if (eflag)
|
||||
@@ -701,7 +716,7 @@ edscript(int n)
|
||||
if (iflag)
|
||||
printf("w\nq\n");
|
||||
|
||||
exit(eflag == EFLAG_NONE ? overlapcnt : 0);
|
||||
exit(oflag ? overlapcnt > 0 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -795,11 +810,10 @@ Ascript(int n)
|
||||
* inbetween lines.
|
||||
*/
|
||||
static void
|
||||
mergescript(int i)
|
||||
mergescript(int i, int f1f3delta)
|
||||
{
|
||||
struct range r, *new, *old;
|
||||
int n;
|
||||
bool delete = false;
|
||||
|
||||
r.from = 1;
|
||||
r.to = 1;
|
||||
@@ -812,13 +826,9 @@ mergescript(int i)
|
||||
* Print any lines leading up to here. If we are merging don't
|
||||
* print deleted ranges.
|
||||
*/
|
||||
delete = (new->from == new->to);
|
||||
if (de[n].type == DIFF_TYPE1 && delete)
|
||||
r.to = new->from - 1;
|
||||
else if (de[n].type == DIFF_TYPE3 && (old->from == old->to)) {
|
||||
r.from = old->from - 1;
|
||||
r.to = new->from;
|
||||
} else if (de[n].type == DIFF_TYPE2)
|
||||
if (de[n].type == DIFF_TYPE1)
|
||||
r.to = old->to;
|
||||
else if (de[n].type == DIFF_TYPE2)
|
||||
r.to = new->from + de_delta[n];
|
||||
else
|
||||
r.to = old->from;
|
||||
@@ -826,9 +836,7 @@ mergescript(int i)
|
||||
printrange(fp[0], &r);
|
||||
switch (de[n].type) {
|
||||
case DIFF_TYPE1:
|
||||
/* If this isn't a delete print it */
|
||||
if (!delete)
|
||||
printrange(fp[2], new);
|
||||
/* Content included in "between" printing from fp[0] */
|
||||
break;
|
||||
case DIFF_TYPE2:
|
||||
printf("%s %s\n", oldmark, f2mark);
|
||||
@@ -870,8 +878,6 @@ mergescript(int i)
|
||||
|
||||
if (de[n].type == DIFF_TYPE2)
|
||||
r.from = new->to + de_delta[n];
|
||||
else if (old->from == old->to)
|
||||
r.from = new->to;
|
||||
else
|
||||
r.from = old->to;
|
||||
}
|
||||
@@ -879,18 +885,11 @@ mergescript(int i)
|
||||
/*
|
||||
* Print from the final range to the end of 'myfile'. Any deletions or
|
||||
* additions to this file should have been handled by now.
|
||||
*
|
||||
* If the ranges are the same we need to rewind a line.
|
||||
* If the new range is 0 length (from == to), we need to use the new
|
||||
* range.
|
||||
*/
|
||||
new = &de[n-1].new;
|
||||
old = &de[n-1].old;
|
||||
|
||||
if (old->from == new->from && old->to == new->to)
|
||||
r.from--;
|
||||
else if (new->from == new->to)
|
||||
r.from = new->from;
|
||||
r.from -= f1f3delta;
|
||||
|
||||
r.to = INT_MAX;
|
||||
printrange(fp[2], &r);
|
||||
|
||||
@@ -23,6 +23,20 @@ ${PACKAGE}FILES+= \
|
||||
long-A.out \
|
||||
long-merge.out \
|
||||
fbsdid1.txt \
|
||||
fbsdid2.txt
|
||||
fbsdid2.txt \
|
||||
conflict1.txt \
|
||||
conflict2.txt \
|
||||
conflict3.txt \
|
||||
conflict-merge.out \
|
||||
simple1.txt \
|
||||
simple2.txt \
|
||||
simple3.txt \
|
||||
simple-merge.out \
|
||||
simple-Em.out \
|
||||
conflict-Em.out \
|
||||
passwd-test.txt \
|
||||
passwd-old.txt \
|
||||
passwd-new.txt \
|
||||
passwd-Em.out
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# root: me@my.domain
|
||||
|
||||
# Basic system aliases -- these MUST be present
|
||||
MAILER-DAEMON: postmaster
|
||||
postmaster: root
|
||||
@@ -0,0 +1,9 @@
|
||||
#root:me@my.domain
|
||||
|
||||
#Basicsystemaliases--theseMUSTbepresent
|
||||
MAILER-DAEMON:postmaster
|
||||
postmaster:root
|
||||
|
||||
#Generalredirectionsforpseudoaccounts
|
||||
_dhcp:root
|
||||
_pflogd:root
|
||||
@@ -0,0 +1,5 @@
|
||||
root:someone@example.com
|
||||
|
||||
#Basicsystemaliases--theseMUSTbepresent
|
||||
MAILER-DAEMON:postmaster
|
||||
postmaster:root
|
||||
@@ -5,6 +5,11 @@ atf_test_case diff3_ed
|
||||
atf_test_case diff3_A
|
||||
atf_test_case diff3_merge
|
||||
atf_test_case diff3_E_merge
|
||||
atf_test_case diff3_merge_conflict
|
||||
atf_test_case diff3_merge_simple
|
||||
atf_test_case diff3_Em_simple
|
||||
atf_test_case diff3_Em_conflict
|
||||
atf_test_case diff3_Em_insert
|
||||
|
||||
diff3_body()
|
||||
{
|
||||
@@ -20,10 +25,10 @@ diff3_body()
|
||||
atf_check -o file:$(atf_get_srcdir)/2.out \
|
||||
diff3 -e $(atf_get_srcdir)/1.txt $(atf_get_srcdir)/2.txt $(atf_get_srcdir)/3.txt
|
||||
|
||||
atf_check -o file:$(atf_get_srcdir)/3.out \
|
||||
atf_check -s exit:1 -o file:$(atf_get_srcdir)/3.out \
|
||||
diff3 -E -L 1 -L 2 -L 3 $(atf_get_srcdir)/1.txt $(atf_get_srcdir)/2.txt $(atf_get_srcdir)/3.txt
|
||||
|
||||
atf_check -o file:$(atf_get_srcdir)/4.out \
|
||||
atf_check -s exit:1 -o file:$(atf_get_srcdir)/4.out \
|
||||
diff3 -X -L 1 -L 2 -L 3 $(atf_get_srcdir)/1.txt $(atf_get_srcdir)/2.txt $(atf_get_srcdir)/3.txt
|
||||
|
||||
atf_check -o file:$(atf_get_srcdir)/5.out \
|
||||
@@ -75,7 +80,6 @@ expected="<<<<<<< 2
|
||||
=======
|
||||
# \$FreeBSD: head/local 12345 jhb \$
|
||||
>>>>>>> 3
|
||||
# \$FreeBSD: head/local 12345 jhb \$
|
||||
|
||||
this is a file
|
||||
|
||||
@@ -97,6 +101,36 @@ these are some local mods to the file
|
||||
}
|
||||
|
||||
|
||||
diff3_merge_conflict_body()
|
||||
{
|
||||
atf_check -s exit:1 -o file:$(atf_get_srcdir)/conflict-merge.out \
|
||||
diff3 -m -L conflict3.txt -L conflict1.txt -L conflict2.txt $(atf_get_srcdir)/conflict3.txt $(atf_get_srcdir)/conflict1.txt $(atf_get_srcdir)/conflict2.txt
|
||||
}
|
||||
|
||||
diff3_merge_simple_body()
|
||||
{
|
||||
atf_check -s exit:0 -o file:$(atf_get_srcdir)/simple-merge.out \
|
||||
diff3 -m $(atf_get_srcdir)/simple3.txt $(atf_get_srcdir)/simple1.txt $(atf_get_srcdir)/simple2.txt
|
||||
}
|
||||
|
||||
diff3_Em_simple_body()
|
||||
{
|
||||
atf_check -s exit:0 -o file:$(atf_get_srcdir)/simple-Em.out \
|
||||
diff3 -E -m $(atf_get_srcdir)/simple3.txt $(atf_get_srcdir)/simple1.txt $(atf_get_srcdir)/simple2.txt
|
||||
}
|
||||
|
||||
diff3_Em_conflict_body()
|
||||
{
|
||||
atf_check -s exit:1 -o file:$(atf_get_srcdir)/conflict-Em.out \
|
||||
diff3 -E -m -L conflict3.txt -L conflict1.txt -L conflict2.txt $(atf_get_srcdir)/conflict3.txt $(atf_get_srcdir)/conflict1.txt $(atf_get_srcdir)/conflict2.txt
|
||||
}
|
||||
|
||||
diff3_Em_insert_body()
|
||||
{
|
||||
atf_check -s exit:0 -o file:$(atf_get_srcdir)/passwd-Em.out \
|
||||
diff3 -E -m $(atf_get_srcdir)/passwd-test.txt $(atf_get_srcdir)/passwd-old.txt $(atf_get_srcdir)/passwd-new.txt
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case diff3
|
||||
@@ -105,4 +139,9 @@ atf_init_test_cases()
|
||||
atf_add_test_case diff3_A
|
||||
atf_add_test_case diff3_merge
|
||||
atf_add_test_case diff3_E_merge
|
||||
atf_add_test_case diff3_merge_conflict
|
||||
atf_add_test_case diff3_merge_simple
|
||||
atf_add_test_case diff3_Em_simple
|
||||
atf_add_test_case diff3_Em_conflict
|
||||
atf_add_test_case diff3_Em_insert
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#
|
||||
root:<rpass>:0:0::0:0:Charlie &:/root:/bin/csh
|
||||
toor:*:0:0::0:0:Bourne-again Superuser:/root:
|
||||
daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
|
||||
operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
|
||||
_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
|
||||
uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
|
||||
pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
|
||||
auditdistd:*:78:77::0:0:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin
|
||||
www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
|
||||
hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
|
||||
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
|
||||
john:<password>:1001:1001::0:0:John Baldwin:/home/john:/bin/tcsh
|
||||
messagebus:*:556:556::0:0:D-BUS Daemon User:/nonexistent:/usr/sbin/nologin
|
||||
polkit:*:562:562::0:0:PolicyKit User:/nonexistent:/usr/sbin/nologin
|
||||
haldaemon:*:560:560::0:0:HAL Daemon User:/nonexistent:/usr/sbin/nologin
|
||||
@@ -0,0 +1,12 @@
|
||||
#
|
||||
root::0:0::0:0:Charlie &:/root:/bin/csh
|
||||
toor:*:0:0::0:0:Bourne-again Superuser:/root:
|
||||
daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
|
||||
operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
|
||||
_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
|
||||
uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
|
||||
pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
|
||||
auditdistd:*:78:77::0:0:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin
|
||||
www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
|
||||
hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
|
||||
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
|
||||
@@ -0,0 +1,11 @@
|
||||
#
|
||||
root::0:0::0:0:Charlie &:/root:/bin/csh
|
||||
toor:*:0:0::0:0:Bourne-again Superuser:/root:
|
||||
daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
|
||||
operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
|
||||
_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
|
||||
uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
|
||||
pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
|
||||
www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
|
||||
hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
|
||||
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
|
||||
@@ -0,0 +1,15 @@
|
||||
#
|
||||
root:<rpass>:0:0::0:0:Charlie &:/root:/bin/csh
|
||||
toor:*:0:0::0:0:Bourne-again Superuser:/root:
|
||||
daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
|
||||
operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
|
||||
_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
|
||||
uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
|
||||
pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
|
||||
www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
|
||||
hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
|
||||
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
|
||||
john:<password>:1001:1001::0:0:John Baldwin:/home/john:/bin/tcsh
|
||||
messagebus:*:556:556::0:0:D-BUS Daemon User:/nonexistent:/usr/sbin/nologin
|
||||
polkit:*:562:562::0:0:PolicyKit User:/nonexistent:/usr/sbin/nologin
|
||||
haldaemon:*:560:560::0:0:HAL Daemon User:/nonexistent:/usr/sbin/nologin
|
||||
@@ -0,0 +1,3 @@
|
||||
this is an new line
|
||||
|
||||
this is a local line
|
||||
@@ -0,0 +1,3 @@
|
||||
this is an new line
|
||||
|
||||
this is a local line
|
||||
@@ -0,0 +1,2 @@
|
||||
this is an old line
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
this is an new line
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
this is an old line
|
||||
|
||||
this is a local line
|
||||
Reference in New Issue
Block a user