File indexing completed on 2024-04-28 13:39:50
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 #include <QRegularExpression> 0010 0011 #include <komparediffdebug.h> 0012 #include "diffmodel.h" 0013 0014 using namespace Diff2; 0015 0016 PerforceParser::PerforceParser(const KompareModelList* list, const QStringList& diff) : ParserBase(list, diff) 0017 { 0018 m_contextDiffHeader1.setPattern(QRegularExpression::anchoredPattern(QStringLiteral("==== (.*) - (.*) ====\\n"))); 0019 m_contextDiffHeader1.setPatternOptions(QRegularExpression::InvertedGreedinessOption); 0020 m_normalDiffHeader.setPattern(QRegularExpression::anchoredPattern(QStringLiteral("==== (.*) - (.*) ====\\n"))); 0021 m_normalDiffHeader.setPatternOptions(QRegularExpression::InvertedGreedinessOption); 0022 m_rcsDiffHeader.setPattern(QRegularExpression::anchoredPattern(QStringLiteral("==== (.*) - (.*) ====\\n"))); 0023 m_rcsDiffHeader.setPatternOptions(QRegularExpression::InvertedGreedinessOption); 0024 m_unifiedDiffHeader1.setPattern(QRegularExpression::anchoredPattern(QStringLiteral("==== (.*) - (.*) ====\\n"))); 0025 m_unifiedDiffHeader1.setPatternOptions(QRegularExpression::InvertedGreedinessOption); 0026 } 0027 0028 PerforceParser::~PerforceParser() 0029 { 0030 } 0031 0032 enum Kompare::Format PerforceParser::determineFormat() 0033 { 0034 qCDebug(LIBKOMPAREDIFF2) << "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 QStringList::ConstIterator it = m_diffLines.begin(); 0043 0044 while (it != m_diffLines.end()) 0045 { 0046 if (it->indexOf(unifiedRE, 0) == 0) 0047 { 0048 qCDebug(LIBKOMPAREDIFF2) << "Difflines are from a Unified diff..."; 0049 return Kompare::Unified; 0050 } 0051 else if (it->indexOf(contextRE, 0) == 0) 0052 { 0053 qCDebug(LIBKOMPAREDIFF2) << "Difflines are from a Context diff..."; 0054 return Kompare::Context; 0055 } 0056 else if (it->indexOf(normalRE, 0) == 0) 0057 { 0058 qCDebug(LIBKOMPAREDIFF2) << "Difflines are from a Normal diff..."; 0059 return Kompare::Normal; 0060 } 0061 else if (it->indexOf(rcsRE, 0) == 0) 0062 { 0063 qCDebug(LIBKOMPAREDIFF2) << "Difflines are from a RCS diff..."; 0064 return Kompare::RCS; 0065 } 0066 ++it; 0067 } 0068 qCDebug(LIBKOMPAREDIFF2) << "Difflines are from an unknown diff..."; 0069 return Kompare::UnknownFormat; 0070 } 0071 0072 bool PerforceParser::parseContextDiffHeader() 0073 { 0074 // qCDebug(LIBKOMPAREDIFF2) << "ParserBase::parseContextDiffHeader()"; 0075 bool result = false; 0076 0077 QStringList::ConstIterator itEnd = m_diffLines.end(); 0078 0079 const QRegularExpression sourceFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(\\d+)"))); 0080 const QRegularExpression destinationFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(|\\d+)"))); 0081 0082 while (m_diffIterator != itEnd) 0083 { 0084 const auto contextDiffHeader1Match = m_contextDiffHeader1.match(*(m_diffIterator)++); 0085 if (contextDiffHeader1Match.hasMatch()) 0086 { 0087 // qCDebug(LIBKOMPAREDIFF2) << "Matched length Header1 = " << contextDiffHeader1Match.capturedLength(); 0088 // qCDebug(LIBKOMPAREDIFF2) << "Matched string Header1 = " << contextDiffHeader1Match.captured( 0 ); 0089 // qCDebug(LIBKOMPAREDIFF2) << "First capture Header1 = " << contextDiffHeader1Match.captured( 1 ); 0090 // qCDebug(LIBKOMPAREDIFF2) << "Second capture Header1 = " << contextDiffHeader1Match.captured( 2 ); 0091 0092 m_currentModel = new DiffModel(); 0093 const auto sourceFileREMatch = sourceFileRE.match(contextDiffHeader1Match.captured(1)); 0094 const auto destinationFileREMatch = destinationFileRE.match(contextDiffHeader1Match.captured(2)); 0095 qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << sourceFileREMatch.capturedLength(); 0096 qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << destinationFileREMatch.capturedLength(); 0097 qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << sourceFileREMatch.capturedTexts(); 0098 qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << destinationFileREMatch.capturedTexts(); 0099 qCDebug(LIBKOMPAREDIFF2) << "Source File : " << sourceFileREMatch.captured(1); 0100 qCDebug(LIBKOMPAREDIFF2) << "Destination File : " << destinationFileREMatch.captured(1); 0101 m_currentModel->setSourceFile(sourceFileREMatch.captured(1)); 0102 m_currentModel->setDestinationFile(destinationFileREMatch.captured(1)); 0103 0104 result = true; 0105 0106 break; 0107 } 0108 else 0109 { 0110 qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << contextDiffHeader1Match.capturedLength(); 0111 qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << contextDiffHeader1Match.capturedTexts(); 0112 } 0113 } 0114 0115 return result; 0116 } 0117 0118 bool PerforceParser::parseNormalDiffHeader() 0119 { 0120 bool result = false; 0121 0122 QStringList::ConstIterator itEnd = m_diffLines.end(); 0123 0124 QRegularExpression sourceFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(\\d+)"))); 0125 QRegularExpression destinationFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(|\\d+)"))); 0126 0127 while (m_diffIterator != itEnd) 0128 { 0129 qCDebug(LIBKOMPAREDIFF2) << "Line = " << *m_diffIterator; 0130 qCDebug(LIBKOMPAREDIFF2) << "String length = " << (*m_diffIterator).length(); 0131 const auto normalDiffHeaderMatch = m_normalDiffHeader.match(*(m_diffIterator)++); 0132 if (normalDiffHeaderMatch.hasMatch()) 0133 { 0134 qCDebug(LIBKOMPAREDIFF2) << "Matched length Header1 = " << normalDiffHeaderMatch.capturedLength(); 0135 qCDebug(LIBKOMPAREDIFF2) << "Matched string Header1 = " << normalDiffHeaderMatch.captured(0); 0136 qCDebug(LIBKOMPAREDIFF2) << "First capture Header1 = \"" << normalDiffHeaderMatch.captured(1) << "\""; 0137 qCDebug(LIBKOMPAREDIFF2) << "Second capture Header1 = \"" << normalDiffHeaderMatch.captured(2) << "\""; 0138 0139 m_currentModel = new DiffModel(); 0140 const auto sourceFileREMatch = sourceFileRE.match(normalDiffHeaderMatch.captured(1)); 0141 const auto destinationFileREMatch = destinationFileRE.match(normalDiffHeaderMatch.captured(2)); 0142 qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << sourceFileREMatch.capturedLength(); 0143 qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << destinationFileREMatch.capturedLength(); 0144 qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << sourceFileREMatch.capturedTexts(); 0145 qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << destinationFileREMatch.capturedTexts(); 0146 qCDebug(LIBKOMPAREDIFF2) << "Source File : " << sourceFileREMatch.captured(1); 0147 qCDebug(LIBKOMPAREDIFF2) << "Destination File : " << destinationFileREMatch.captured(1); 0148 m_currentModel->setSourceFile(sourceFileREMatch.captured(1)); 0149 m_currentModel->setDestinationFile(destinationFileREMatch.captured(1)); 0150 0151 result = true; 0152 0153 break; 0154 } 0155 else 0156 { 0157 qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << normalDiffHeaderMatch.capturedLength(); 0158 qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << normalDiffHeaderMatch.capturedTexts(); 0159 } 0160 } 0161 0162 return result; 0163 } 0164 0165 bool PerforceParser::parseRCSDiffHeader() 0166 { 0167 return false; 0168 } 0169 0170 bool PerforceParser::parseUnifiedDiffHeader() 0171 { 0172 bool result = false; 0173 0174 QStringList::ConstIterator itEnd = m_diffLines.end(); 0175 0176 QRegularExpression sourceFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(\\d+)"))); 0177 QRegularExpression destinationFileRE(QRegularExpression::anchoredPattern(QStringLiteral("([^\\#]+)#(|\\d+)"))); 0178 0179 while (m_diffIterator != itEnd) 0180 { 0181 // qCDebug(LIBKOMPAREDIFF2) << "Line = " << *m_diffIterator; 0182 // qCDebug(LIBKOMPAREDIFF2) << "String length = " << (*m_diffIterator).length(); 0183 const auto unifiedDiffHeader1Match = m_unifiedDiffHeader1.match(*(m_diffIterator)++); 0184 if (unifiedDiffHeader1Match.hasMatch()) 0185 { 0186 // qCDebug(LIBKOMPAREDIFF2) << "Matched length Header1 = " << unifiedDiffHeader1Match.capturedLength(); 0187 // qCDebug(LIBKOMPAREDIFF2) << "Matched string Header1 = " << unifiedDiffHeader1Match.captured( 0 ); 0188 // qCDebug(LIBKOMPAREDIFF2) << "First capture Header1 = \"" << unifiedDiffHeader1Match.captured( 1 ) << "\""; 0189 // qCDebug(LIBKOMPAREDIFF2) << "Second capture Header1 = \"" << unifiedDiffHeader1Match.captured( 2 ) << "\""; 0190 0191 m_currentModel = new DiffModel(); 0192 const auto sourceFileREMatch = sourceFileRE.match(unifiedDiffHeader1Match.captured(1)); 0193 const auto destinationFileREMatch = destinationFileRE.match(unifiedDiffHeader1Match.captured(2)); 0194 // qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << sourceFileREMatch.capturedLength(); 0195 // qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << destinationFileREMatch.capturedLength(); 0196 // qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << sourceFileREMatch.capturedTexts(); 0197 // qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << destinationFileREMatch.capturedTexts(); 0198 // qCDebug(LIBKOMPAREDIFF2) << "Source File : " << sourceFileREMatch.captured( 1 ); 0199 // qCDebug(LIBKOMPAREDIFF2) << "Destination File : " << destinationFileREMatch.captured( 1 ); 0200 m_currentModel->setSourceFile(sourceFileREMatch.captured(1)); 0201 m_currentModel->setDestinationFile(destinationFileREMatch.captured(1)); 0202 0203 result = true; 0204 0205 break; 0206 } 0207 else 0208 { 0209 // qCDebug(LIBKOMPAREDIFF2) << "Matched length = " << unifiedDiffHeader1Match.capturedLength(); 0210 // qCDebug(LIBKOMPAREDIFF2) << "Captured texts = " << unifiedDiffHeader1Match.capturedTexts(); 0211 } 0212 } 0213 0214 return result; 0215 } 0216