| 1006 | } |
| 1007 | |
| 1008 | void DiffWidget::parseAndShowDiffUnified(const QByteArray &raw) |
| 1009 | { |
| 1010 | // printf("show diff:\n%s\n================================", raw.constData()); |
| 1011 | const QStringList text = QString::fromUtf8(raw).replace(QStringLiteral("\r\n"), QStringLiteral("\n")).split(u'\n', Qt::SkipEmptyParts); |
| 1012 | |
| 1013 | static const QRegularExpression HUNK_HEADER_RE(QStringLiteral("^@@ -([0-9,]+) \\+([0-9,]+) @@(.*)")); |
| 1014 | static const QRegularExpression DIFF_FILENAME_RE(QStringLiteral("^[-+]{3} [ab]/(.*)")); |
| 1015 | |
| 1016 | // Actual lines that will get added to the text editor |
| 1017 | QStringList lines; |
| 1018 | |
| 1019 | // Highlighting data for modified lines |
| 1020 | std::vector<LineHighlight> hlts; |
| 1021 | |
| 1022 | // Line numbers that will be shown in the editor |
| 1023 | std::vector<int> lineNumsA; |
| 1024 | std::vector<int> lineNumsB; |
| 1025 | |
| 1026 | // Changed lines of hunk, used to determine differences between two lines |
| 1027 | HunkChangedLines hunkChangedLinesA; |
| 1028 | HunkChangedLines hunkChangedLinesB; |
| 1029 | |
| 1030 | // viewLine => rawDiffLine |
| 1031 | std::vector<ViewLineToDiffLine> lineToRawDiffLine; |
| 1032 | // for Folding/stage/unstage hunk |
| 1033 | std::vector<ViewLineToDiffLine> linesWithHunkHeading; |
| 1034 | // Lines containing filename |
| 1035 | std::vector<int> linesWithFileName; |
| 1036 | |
| 1037 | QSet<QString> fileExtensions; |
| 1038 | QString srcFile; |
| 1039 | QString tgtFile; |
| 1040 | |
| 1041 | int maxLineNoFound = 0; |
| 1042 | int lineNo = 0; |
| 1043 | |
| 1044 | for (int i = 0; i < text.size(); ++i) { |
| 1045 | const QString &line = text.at(i); |
| 1046 | auto match = DIFF_FILENAME_RE.match(line); |
| 1047 | if ((match.hasMatch() || line == QLatin1String("--- /dev/null")) && i + 1 < text.size()) { |
| 1048 | srcFile = match.hasMatch() ? match.captured(1) : QString(); |
| 1049 | if (!srcFile.isEmpty()) { |
| 1050 | fileExtensions.insert(QFileInfo(srcFile).suffix()); |
| 1051 | } |
| 1052 | auto tgtMatch = DIFF_FILENAME_RE.match(text.at(i + 1)); |
| 1053 | |
| 1054 | if (tgtMatch.hasMatch() || text.at(i + 1) == QLatin1String("--- /dev/null")) { |
| 1055 | tgtFile = tgtMatch.hasMatch() ? tgtMatch.captured(1) : QString(); |
| 1056 | if (!tgtFile.isEmpty()) { |
| 1057 | fileExtensions.insert(QFileInfo(tgtFile).suffix()); |
| 1058 | } |
| 1059 | } |
| 1060 | i++; |
| 1061 | |
| 1062 | if (m_params.flags.testFlag(DiffParams::ShowFileName)) { |
| 1063 | if (srcFile.isEmpty() && !tgtFile.isEmpty()) { |
| 1064 | lines.append(i18n("New file %1", Utils::fileNameFromPath(tgtFile))); |
| 1065 | } else if (!srcFile.isEmpty() && tgtFile.isEmpty()) { |
nothing calls this directly
no test coverage detected