| 711 | |
| 712 | |
| 713 | void diff_match_patch::diff_cleanupSemantic(QList<Diff> &diffs) { |
| 714 | if (diffs.isEmpty()) { |
| 715 | return; |
| 716 | } |
| 717 | bool changes = false; |
| 718 | QStack<Diff> equalities; // Stack of equalities. |
| 719 | QString lastequality; // Always equal to equalities.lastElement().text |
| 720 | QMutableListIterator<Diff> pointer(diffs); |
| 721 | // Number of characters that changed prior to the equality. |
| 722 | int length_insertions1 = 0; |
| 723 | int length_deletions1 = 0; |
| 724 | // Number of characters that changed after the equality. |
| 725 | int length_insertions2 = 0; |
| 726 | int length_deletions2 = 0; |
| 727 | Diff *thisDiff = pointer.hasNext() ? &pointer.next() : NULL; |
| 728 | while (thisDiff != NULL) { |
| 729 | if (thisDiff->operation == EQUAL) { |
| 730 | // Equality found. |
| 731 | equalities.push(*thisDiff); |
| 732 | length_insertions1 = length_insertions2; |
| 733 | length_deletions1 = length_deletions2; |
| 734 | length_insertions2 = 0; |
| 735 | length_deletions2 = 0; |
| 736 | lastequality = thisDiff->text; |
| 737 | } else { |
| 738 | // An insertion or deletion. |
| 739 | if (thisDiff->operation == INSERT) { |
| 740 | length_insertions2 += thisDiff->text.length(); |
| 741 | } else { |
| 742 | length_deletions2 += thisDiff->text.length(); |
| 743 | } |
| 744 | // Eliminate an equality that is smaller or equal to the edits on both |
| 745 | // sides of it. |
| 746 | if (!lastequality.isNull() |
| 747 | && (lastequality.length() |
| 748 | <= std::max(length_insertions1, length_deletions1)) |
| 749 | && (lastequality.length() |
| 750 | <= std::max(length_insertions2, length_deletions2))) { |
| 751 | // printf("Splitting: '%s'\n", qPrintable(lastequality)); |
| 752 | // Walk back to offending equality. |
| 753 | while (*thisDiff != equalities.top()) { |
| 754 | thisDiff = &pointer.previous(); |
| 755 | } |
| 756 | pointer.next(); |
| 757 | |
| 758 | // Replace equality with a delete. |
| 759 | pointer.setValue(Diff(DELETE, lastequality)); |
| 760 | // Insert a corresponding an insert. |
| 761 | pointer.insert(Diff(INSERT, lastequality)); |
| 762 | |
| 763 | equalities.pop(); // Throw away the equality we just deleted. |
| 764 | if (!equalities.isEmpty()) { |
| 765 | // Throw away the previous equality (it needs to be reevaluated). |
| 766 | equalities.pop(); |
| 767 | } |
| 768 | if (equalities.isEmpty()) { |
| 769 | // There are no previous equalities, walk back to the start. |
| 770 | while (pointer.hasPrevious()) { |