File indexing completed on 2024-04-14 05:37:15

0001 /*
0002     SPDX-FileCopyrightText: 2002-2004 Otto Bruggeman <otto.bruggeman@home.nl>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "perforceparser.h"
0008 
0009 // lib
0010 #include "diffmodel.h"
0011 #include <komparediff2_logging.h>
0012 // Qt
0013 #include <QRegularExpression>
0014 
0015 using namespace KompareDiff2;
0016 
0017 PerforceParser::PerforceParser(const ModelList *list, const QStringList &diff)
0018     : ParserBase(list, diff)
0019 {
0020     m_contextDiffHeader1.setPattern(QRegularExpression::anchoredPattern(QStringLiteral("==== (.*) - (.*) ====\\n")));
0021     m_contextDiffHeader1.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
0022     m_normalDiffHeader.setPattern(QRegularExpression::anchoredPattern(QStringLiteral("==== (.*) - (.*) ====\\n")));
0023     m_normalDiffHeader.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
0024     m_rcsDiffHeader.setPattern(QRegularExpression::anchoredPattern(QStringLiteral("==== (.*) - (.*) ====\\n")));
0025     m_rcsDiffHeader.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
0026     m_unifiedDiffHeader1.setPattern(QRegularExpression::anchoredPattern(QStringLiteral("==== (.*) - (.*) ====\\n")));
0027     m_unifiedDiffHeader1.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
0028 }
0029 
0030 PerforceParser::~PerforceParser() = default;
0031 
0032 Format PerforceParser::determineFormat()
0033 {
0034     qCDebug(KOMPAREDIFF2_LOG) << "Determining the format of the Perforce Diff";
0035 
0036     QRegularExpression unifiedRE(QStringLiteral("^@@"));
0037     QRegularExpression contextRE(QStringLiteral("^\\*{15}"));
0038     QRegularExpression normalRE(QStringLiteral("^\\d+(|,\\d+)[acd]\\d+(|,\\d+)"));
0039     QRegularExpression rcsRE(QStringLiteral("^[acd]\\d+ \\d+"));
0040     // Summary is not supported since it gives no useful parsable info
0041 
0042     for (const QString &diffLine : std::as_const(m_diffLines)) {
0043         if (diffLine.indexOf(unifiedRE, 0) == 0) {
0044             qCDebug(KOMPAREDIFF2_LOG) << "Difflines are from a Unified diff...";
0045             return Unified;
0046         }
0047         if (diffLine.indexOf(contextRE, 0) == 0) {
0048             qCDebug(KOMPAREDIFF2_LOG) << "Difflines are from a Context diff...";
0049             return Context;
0050         }
0051         if (diffLine.indexOf(normalRE, 0) == 0) {
0052             qCDebug(KOMPAREDIFF2_LOG) << "Difflines are from a Normal diff...";
0053             return Normal;
0054         }
0055         if (diffLine.indexOf(rcsRE, 0) == 0) {
0056             qCDebug(KOMPAREDIFF2_LOG) << "Difflines are from a RCS diff...";
0057             return RCS;
0058         }
0059     }
0060     qCDebug(KOMPAREDIFF2_LOG) << "Difflines are from an unknown diff...";
0061     return UnknownFormat;
0062 }
0063 
0064 bool PerforceParser::parseContextDiffHeader()
0065 {
0066 //     qCDebug(KOMPAREDIFF2_LOG) << "ParserBase::parseContextDiffHeader()";
0067     bool result = false;
0068 
0069     QStringList::ConstIterator itEnd = m_diffLines.end();
0070 
0071     const QRegularExpression sourceFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(\\d+)")));
0072     const QRegularExpression destinationFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(|\\d+)")));
0073 
0074     while (m_diffIterator != itEnd) {
0075         const auto contextDiffHeader1Match = m_contextDiffHeader1.match(*(m_diffIterator)++);
0076         if (contextDiffHeader1Match.hasMatch()) {
0077 //             qCDebug(KOMPAREDIFF2_LOG) << "Matched length Header1 = " << contextDiffHeader1Match.capturedLength();
0078 //             qCDebug(KOMPAREDIFF2_LOG) << "Matched string Header1 = " << contextDiffHeader1Match.captured( 0 );
0079 //             qCDebug(KOMPAREDIFF2_LOG) << "First capture  Header1 = " << contextDiffHeader1Match.captured( 1 );
0080 //             qCDebug(KOMPAREDIFF2_LOG) << "Second capture Header1 = " << contextDiffHeader1Match.captured( 2 );
0081 
0082             m_currentModel = new DiffModel();
0083             const auto sourceFileREMatch = sourceFileRE.match(contextDiffHeader1Match.captured(1));
0084             const auto destinationFileREMatch = destinationFileRE.match(contextDiffHeader1Match.captured(2));
0085             qCDebug(KOMPAREDIFF2_LOG) << "Matched length   = " << sourceFileREMatch.capturedLength();
0086             qCDebug(KOMPAREDIFF2_LOG) << "Matched length   = " << destinationFileREMatch.capturedLength();
0087             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts   = " << sourceFileREMatch.capturedTexts();
0088             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts   = " << destinationFileREMatch.capturedTexts();
0089             qCDebug(KOMPAREDIFF2_LOG) << "Source File      : " << sourceFileREMatch.captured(1);
0090             qCDebug(KOMPAREDIFF2_LOG) << "Destination File : " << destinationFileREMatch.captured(1);
0091             m_currentModel->setSourceFile(sourceFileREMatch.captured(1));
0092             m_currentModel->setDestinationFile(destinationFileREMatch.captured(1));
0093 
0094             result = true;
0095 
0096             break;
0097         } else {
0098             qCDebug(KOMPAREDIFF2_LOG) << "Matched length = " << contextDiffHeader1Match.capturedLength();
0099             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts = " << contextDiffHeader1Match.capturedTexts();
0100         }
0101     }
0102 
0103     return result;
0104 }
0105 
0106 bool PerforceParser::parseNormalDiffHeader()
0107 {
0108     bool result = false;
0109 
0110     QStringList::ConstIterator itEnd = m_diffLines.end();
0111 
0112     QRegularExpression sourceFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(\\d+)")));
0113     QRegularExpression destinationFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(|\\d+)")));
0114 
0115     while (m_diffIterator != itEnd) {
0116         qCDebug(KOMPAREDIFF2_LOG) << "Line = " << *m_diffIterator;
0117         qCDebug(KOMPAREDIFF2_LOG) << "String length  = " << (*m_diffIterator).length();
0118         const auto normalDiffHeaderMatch = m_normalDiffHeader.match(*(m_diffIterator)++);
0119         if (normalDiffHeaderMatch.hasMatch()) {
0120             qCDebug(KOMPAREDIFF2_LOG) << "Matched length Header1 = " << normalDiffHeaderMatch.capturedLength();
0121             qCDebug(KOMPAREDIFF2_LOG) << "Matched string Header1 = " << normalDiffHeaderMatch.captured(0);
0122             qCDebug(KOMPAREDIFF2_LOG) << "First  capture Header1 = \"" << normalDiffHeaderMatch.captured(1) << "\"";
0123             qCDebug(KOMPAREDIFF2_LOG) << "Second capture Header1 = \"" << normalDiffHeaderMatch.captured(2) << "\"";
0124 
0125             m_currentModel = new DiffModel();
0126             const auto sourceFileREMatch = sourceFileRE.match(normalDiffHeaderMatch.captured(1));
0127             const auto destinationFileREMatch = destinationFileRE.match(normalDiffHeaderMatch.captured(2));
0128             qCDebug(KOMPAREDIFF2_LOG) << "Matched length   = " << sourceFileREMatch.capturedLength();
0129             qCDebug(KOMPAREDIFF2_LOG) << "Matched length   = " << destinationFileREMatch.capturedLength();
0130             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts   = " << sourceFileREMatch.capturedTexts();
0131             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts   = " << destinationFileREMatch.capturedTexts();
0132             qCDebug(KOMPAREDIFF2_LOG) << "Source File      : " << sourceFileREMatch.captured(1);
0133             qCDebug(KOMPAREDIFF2_LOG) << "Destination File : " << destinationFileREMatch.captured(1);
0134             m_currentModel->setSourceFile(sourceFileREMatch.captured(1));
0135             m_currentModel->setDestinationFile(destinationFileREMatch.captured(1));
0136 
0137             result = true;
0138 
0139             break;
0140         } else {
0141             qCDebug(KOMPAREDIFF2_LOG) << "Matched length = " << normalDiffHeaderMatch.capturedLength();
0142             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts = " << normalDiffHeaderMatch.capturedTexts();
0143         }
0144     }
0145 
0146     return result;
0147 }
0148 
0149 bool PerforceParser::parseRCSDiffHeader()
0150 {
0151     return false;
0152 }
0153 
0154 bool PerforceParser::parseUnifiedDiffHeader()
0155 {
0156     bool result = false;
0157 
0158     QStringList::ConstIterator itEnd = m_diffLines.end();
0159 
0160     QRegularExpression sourceFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(\\d+)")));
0161     QRegularExpression destinationFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(|\\d+)")));
0162 
0163     while (m_diffIterator != itEnd) {
0164 //         qCDebug(KOMPAREDIFF2_LOG) << "Line = " << *m_diffIterator;
0165 //         qCDebug(KOMPAREDIFF2_LOG) << "String length  = " << (*m_diffIterator).length();
0166         const auto unifiedDiffHeader1Match = m_unifiedDiffHeader1.match(*(m_diffIterator)++);
0167         if (unifiedDiffHeader1Match.hasMatch()) {
0168 //             qCDebug(KOMPAREDIFF2_LOG) << "Matched length Header1 = " << unifiedDiffHeader1Match.capturedLength();
0169 //             qCDebug(KOMPAREDIFF2_LOG) << "Matched string Header1 = " << unifiedDiffHeader1Match.captured( 0 );
0170 //             qCDebug(KOMPAREDIFF2_LOG) << "First  capture Header1 = \"" << unifiedDiffHeader1Match.captured( 1 ) << "\"";
0171 //             qCDebug(KOMPAREDIFF2_LOG) << "Second capture Header1 = \"" << unifiedDiffHeader1Match.captured( 2 ) << "\"";
0172 
0173             m_currentModel = new DiffModel();
0174             const auto sourceFileREMatch = sourceFileRE.match(unifiedDiffHeader1Match.captured(1));
0175             const auto destinationFileREMatch = destinationFileRE.match(unifiedDiffHeader1Match.captured(2));
0176 //             qCDebug(KOMPAREDIFF2_LOG) << "Matched length   = " << sourceFileREMatch.capturedLength();
0177 //             qCDebug(KOMPAREDIFF2_LOG) << "Matched length   = " << destinationFileREMatch.capturedLength();
0178 //             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts   = " << sourceFileREMatch.capturedTexts();
0179 //             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts   = " << destinationFileREMatch.capturedTexts();
0180 //             qCDebug(KOMPAREDIFF2_LOG) << "Source File      : " << sourceFileREMatch.captured( 1 );
0181 //             qCDebug(KOMPAREDIFF2_LOG) << "Destination File : " << destinationFileREMatch.captured( 1 );
0182             m_currentModel->setSourceFile(sourceFileREMatch.captured(1));
0183             m_currentModel->setDestinationFile(destinationFileREMatch.captured(1));
0184 
0185             result = true;
0186 
0187             break;
0188         } else {
0189 //             qCDebug(KOMPAREDIFF2_LOG) << "Matched length = " << unifiedDiffHeader1Match.capturedLength();
0190 //             qCDebug(KOMPAREDIFF2_LOG) << "Captured texts = " << unifiedDiffHeader1Match.capturedTexts();
0191         }
0192     }
0193 
0194     return result;
0195 }