Skip to content

Commit 9ba149b

Browse files
author
Neil Fraser
committed
Fix empty diff operations in cleanupMerge
Python was creating invalid diffs. Java was fine. Other languages were creating sub-optimal diffs.
1 parent d939a32 commit 9ba149b

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

objectivec/DiffMatchPatch.m

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -949,22 +949,20 @@ - (void)diff_cleanupMerge:(NSMutableArray *)diffs;
949949
}
950950
}
951951
// Delete the offending records and add the merged ones.
952-
if (count_delete == 0) {
953-
splice(diffs, thisPointer - count_insert,
954-
count_delete + count_insert,
955-
[NSMutableArray arrayWithObject:[Diff diffWithOperation:DIFF_INSERT andText:text_insert]]);
956-
} else if (count_insert == 0) {
957-
splice(diffs, thisPointer - count_delete,
958-
count_delete + count_insert,
959-
[NSMutableArray arrayWithObject:[Diff diffWithOperation:DIFF_DELETE andText:text_delete]]);
960-
} else {
961-
splice(diffs, thisPointer - count_delete - count_insert,
962-
count_delete + count_insert,
963-
[NSMutableArray arrayWithObjects:[Diff diffWithOperation:DIFF_DELETE andText:text_delete],
964-
[Diff diffWithOperation:DIFF_INSERT andText:text_insert], nil]);
952+
thisPointer -= count_delete + count_insert;
953+
954+
splice(diffs, thisPointer, count_delete + count_insert, nil);
955+
if ([text_delete length] != 0) {
956+
splice(diffs, thisPointer, 0,
957+
[NSMutableArray arrayWithObject:[Diff diffWithOperation:DIFF_DELETE andText:text_delete]]);
958+
thisPointer++;
959+
}
960+
if ([text_insert length] != 0) {
961+
splice(diffs, thisPointer, 0,
962+
[NSMutableArray arrayWithObject:[Diff diffWithOperation:DIFF_INSERT andText:text_insert]]);
963+
thisPointer++;
965964
}
966-
thisPointer = thisPointer - count_delete - count_insert +
967-
(count_delete != 0 ? 1 : 0) + (count_insert != 0 ? 1 : 0) + 1;
965+
thisPointer++;
968966
} else if (thisPointer != 0 && prevDiff.operation == DIFF_EQUAL) {
969967
// Merge this equality with the previous one.
970968
prevDiff.text = [prevDiff.text stringByAppendingString:thisDiff.text];
@@ -993,7 +991,10 @@ - (void)diff_cleanupMerge:(NSMutableArray *)diffs;
993991
if (prevDiff.operation == DIFF_EQUAL &&
994992
nextDiff.operation == DIFF_EQUAL) {
995993
// This is a single edit surrounded by equalities.
996-
if ([thisDiff.text hasSuffix:prevDiff.text]) {
994+
if ([prevDiff.text length] == 0) {
995+
splice(diffs, thisPointer - 1, 1, nil);
996+
changes = YES;
997+
} else if ([thisDiff.text hasSuffix:prevDiff.text]) {
997998
// Shift the edit over the previous equality.
998999
thisDiff.text = [prevDiff.text stringByAppendingString:
9991000
[thisDiff.text substringWithRange:NSMakeRange(0, thisDiff.text.length - prevDiff.text.length)]];
@@ -2048,7 +2049,7 @@ - (NSMutableArray *)patch_makeFromOldString:(NSString *)text1
20482049
[patches addObject:patch];
20492050
patch = [[Patch new] autorelease];
20502051
// Unlike Unidiff, our patch lists have a rolling context.
2051-
// http://code.google.com/p/google-diff-match-patch/wiki/Unidiff
2052+
// https://github.com/google/diff-match-patch/wiki/Unidiff
20522053
// Update prepatch text & pos to reflect the application of the
20532054
// just completed patch.
20542055
[prepatch_text release];

objectivec/DiffMatchPatchCFUtilities.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ Boolean diff_regExMatch(CFStringRef text, const regex_t *re) {
153153
* @return The number of characters common to the start of each string.
154154
*/
155155
CFIndex diff_commonPrefix(CFStringRef text1, CFStringRef text2) {
156-
// Performance analysis: http://neil.fraser.name/news/2007/10/09/
156+
// Performance analysis: https://neil.fraser.name/news/2007/10/09/
157157
CFIndex text1_length = CFStringGetLength(text1);
158158
CFIndex text2_length = CFStringGetLength(text2);
159159

@@ -183,7 +183,7 @@ CFIndex diff_commonPrefix(CFStringRef text1, CFStringRef text2) {
183183
* @return The number of characters common to the end of each string.
184184
*/
185185
CFIndex diff_commonSuffix(CFStringRef text1, CFStringRef text2) {
186-
// Performance analysis: http://neil.fraser.name/news/2007/10/09/
186+
// Performance analysis: https://neil.fraser.name/news/2007/10/09/
187187
CFIndex text1_length = CFStringGetLength(text1);
188188
CFIndex text2_length = CFStringGetLength(text2);
189189

@@ -253,7 +253,7 @@ CFIndex diff_commonOverlap(CFStringRef text1, CFStringRef text2) {
253253
} else {
254254
// Start by looking for a single character match
255255
// and increase length until no match is found.
256-
// Performance analysis: http://neil.fraser.name/news/2010/11/04/
256+
// Performance analysis: https://neil.fraser.name/news/2010/11/04/
257257
CFIndex best = 0;
258258
CFIndex length = 1;
259259
while (true) {

objectivec/Tests/DiffMatchPatchTest.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,18 @@ - (void)test_diff_cleanupMergeTest {
317317
expectedResult = [NSMutableArray arrayWithObjects:[Diff diffWithOperation:DIFF_EQUAL andText:@"xca"], [Diff diffWithOperation:DIFF_DELETE andText:@"cba"], nil];
318318
XCTAssertEqualObjects(expectedResult, diffs, @"Slide edit right recursive.");
319319

320+
// Empty merge.
321+
diffs = [NSMutableArray arrayWithObjects:[Diff diffWithOperation:DIFF_DELETE andText:@"b"], [Diff diffWithOperation:DIFF_INSERT andText:@"ab"], [Diff diffWithOperation:DIFF_EQUAL andText:@"c"], nil];
322+
[dmp diff_cleanupMerge:diffs];
323+
expectedResult = [NSMutableArray arrayWithObjects:[Diff diffWithOperation:DIFF_INSERT andText:@"a"], [Diff diffWithOperation:DIFF_EQUAL andText:@"bc"], nil];
324+
XCTAssertEqualObjects(expectedResult, diffs, @"Empty merge.");
325+
326+
// Empty equality.
327+
diffs = [NSMutableArray arrayWithObjects:[Diff diffWithOperation:DIFF_EQUAL andText:@""], [Diff diffWithOperation:DIFF_INSERT andText:@"a"], [Diff diffWithOperation:DIFF_EQUAL andText:@"b"], nil];
328+
[dmp diff_cleanupMerge:diffs];
329+
expectedResult = [NSMutableArray arrayWithObjects:[Diff diffWithOperation:DIFF_INSERT andText:@"a"], [Diff diffWithOperation:DIFF_EQUAL andText:@"b"], nil];
330+
XCTAssertEqualObjects(expectedResult, diffs, @"Empty equality.");
331+
320332
[dmp release];
321333
}
322334

0 commit comments

Comments
 (0)