| 620 | } |
| 621 | |
| 622 | void DiffList::runDiff(const std::shared_ptr<LineDataVector>& p1, const size_t index1, LineRef size1, const std::shared_ptr<LineDataVector>& p2, const size_t index2, LineRef size2) |
| 623 | { |
| 624 | ProgressScope pp; |
| 625 | static GnuDiff gnuDiff; // All values are initialized with zeros. |
| 626 | |
| 627 | ProgressProxy::setCurrent(0); |
| 628 | |
| 629 | clear(); |
| 630 | if(p1->empty() || (*p1)[index1].getBuffer() == nullptr || p2->empty() || (*p2)[index2].getBuffer() == nullptr || size1 == 0 || size2 == 0) |
| 631 | { |
| 632 | if(!p1->empty() && !p2->empty() && (*p1)[index1].getBuffer() == nullptr && (*p2)[index2].getBuffer() == nullptr && size1 == size2) |
| 633 | push_back(Diff(size1, 0, 0)); |
| 634 | else |
| 635 | { |
| 636 | push_back(Diff(0, size1, size2)); |
| 637 | } |
| 638 | } |
| 639 | else |
| 640 | { |
| 641 | assert((size_t)size1 < p1->size() && (size_t)size2 < p2->size()); |
| 642 | |
| 643 | GnuDiff::comparison comparisonInput; |
| 644 | memset(&comparisonInput, 0, sizeof(comparisonInput)); |
| 645 | comparisonInput.parent = nullptr; |
| 646 | comparisonInput.file[0].buffer = (*p1)[index1].getBuffer()->unicode() + (*p1)[index1].getOffset(); //ptr to buffer |
| 647 | comparisonInput.file[0].buffered = ((*p1)[index1 + size1 - 1].getOffset() + (*p1)[index1 + size1 - 1].size() - (*p1)[index1].getOffset()); // size of buffer |
| 648 | comparisonInput.file[1].buffer = (*p2)[index2].getBuffer()->unicode() + (*p2)[index2].getOffset(); //ptr to buffer |
| 649 | comparisonInput.file[1].buffered = ((*p2)[index2 + size2 - 1].getOffset() + (*p2)[index2 + size2 - 1].size() - (*p2)[index2].getOffset()); // size of buffer |
| 650 | |
| 651 | gnuDiff.ignore_white_space = GnuDiff::IGNORE_ALL_SPACE; // I think nobody needs anything else ... |
| 652 | gnuDiff.bIgnoreWhiteSpace = true; |
| 653 | gnuDiff.bIgnoreNumbers = gOptions->m_bIgnoreNumbers; |
| 654 | gnuDiff.minimal = gOptions->m_bTryHard; |
| 655 | gnuDiff.ignore_case = false; |
| 656 | GnuDiff::change* script = gnuDiff.diff_2_files(&comparisonInput); |
| 657 | |
| 658 | LineRef equalLinesAtStart = (LineRef)comparisonInput.file[0].prefix_lines; |
| 659 | LineRef currentLine1 = 0; |
| 660 | LineRef currentLine2 = 0; |
| 661 | GnuDiff::change* p = nullptr; |
| 662 | for(GnuDiff::change* e = script; e; e = p) |
| 663 | { |
| 664 | Diff d((LineType)(e->line0 - currentLine1), e->deleted, e->inserted); |
| 665 | assert(d.numberOfEquals() == e->line1 - currentLine2); |
| 666 | |
| 667 | currentLine1 += LineRef((quint64)d.numberOfEquals() + d.diff1()); |
| 668 | currentLine2 += LineRef((quint64)d.numberOfEquals() + d.diff2()); |
| 669 | assert(currentLine1 <= size1 && currentLine2 <= size2); |
| 670 | push_back(d); |
| 671 | |
| 672 | p = e->link; |
| 673 | free(e); |
| 674 | } |
| 675 | |
| 676 | if(empty()) |
| 677 | { |
| 678 | LineType numofEquals = std::min(size1, size2); |
| 679 | Diff d(numofEquals, size1 - numofEquals, size2 - numofEquals); |