File indexing completed on 2024-04-21 05:44:10

0001 /*
0002     SPDX-FileCopyrightText: 2002-2004 Otto Bruggeman <otto.bruggeman@home.nl>
0003     SPDX-FileCopyrightText: 2010 Kevin Kofler <kevin.kofler@chello.at>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "parser.h"
0009 
0010 // lib
0011 #include "cvsdiffparser.h"
0012 #include "diffmodel.h"
0013 #include "diffmodellist.h"
0014 #include "diffparser.h"
0015 #include "perforceparser.h"
0016 #include <komparediff2_logging.h>
0017 
0018 using namespace KompareDiff2;
0019 
0020 Parser::Parser(const ModelList *list)
0021     : m_list(list)
0022 {
0023 }
0024 
0025 Parser::~Parser() = default;
0026 
0027 int Parser::cleanUpCrap(QStringList &diffLines)
0028 {
0029     QStringList::Iterator it = diffLines.begin();
0030 
0031     int nol = 0;
0032 
0033     QLatin1String noNewLine("\\ No newline");
0034 
0035     for (; it != diffLines.end(); ++it) {
0036         if ((*it).startsWith(noNewLine)) {
0037             it = diffLines.erase(it);
0038             // correcting the advance of the iterator because of the remove
0039             --it;
0040             QString temp(*it);
0041             temp.truncate(temp.indexOf(QLatin1Char('\n')));
0042             *it = temp;
0043             ++nol;
0044         }
0045     }
0046 
0047     return nol;
0048 }
0049 
0050 DiffModelList *Parser::parse(QStringList &diffLines, bool *malformed)
0051 {
0052     /* Basically determine the generator then call the parse method */
0053     std::unique_ptr<ParserBase> parser;
0054 
0055     m_generator = determineGenerator(diffLines);
0056 
0057     int nol = cleanUpCrap(diffLines);
0058     qCDebug(KOMPAREDIFF2_LOG) << "Cleaned up " << nol << " line(s) of crap from the diff...";
0059 
0060     switch (m_generator) {
0061     case CVSDiff:
0062         qCDebug(KOMPAREDIFF2_LOG) << "It is a CVS generated diff...";
0063         parser = std::make_unique<CVSDiffParser>(m_list, diffLines);
0064         break;
0065     case Diff:
0066         qCDebug(KOMPAREDIFF2_LOG) << "It is a diff generated diff...";
0067         parser = std::make_unique<DiffParser>(m_list, diffLines);
0068         break;
0069     case Perforce:
0070         qCDebug(KOMPAREDIFF2_LOG) << "It is a Perforce generated diff...";
0071         parser = std::make_unique<PerforceParser>(m_list, diffLines);
0072         break;
0073     default:
0074         // Nothing to delete, just leave...
0075         return nullptr;
0076     }
0077 
0078     m_format = parser->format();
0079     DiffModelList *modelList = parser->parse(malformed);
0080     if (modelList) {
0081         qCDebug(KOMPAREDIFF2_LOG) << "Modelcount: " << modelList->count();
0082         for (const DiffModel *model : std::as_const(*modelList)) {
0083             qCDebug(KOMPAREDIFF2_LOG) << "Hunkcount:  " << model->hunkCount();
0084             qCDebug(KOMPAREDIFF2_LOG) << "Diffcount:  " << model->differenceCount();
0085         }
0086     }
0087 
0088     return modelList;
0089 }
0090 
0091 Generator Parser::determineGenerator(const QStringList &diffLines)
0092 {
0093     // Shit have to duplicate some code with this method and the ParserBase derived classes
0094     QLatin1String cvsDiff("Index: ");
0095     QLatin1String perforceDiff("==== ");
0096 
0097     for (const QString &diffLine : diffLines) {
0098         if (diffLine.startsWith(cvsDiff)) {
0099             qCDebug(KOMPAREDIFF2_LOG) << "Diff is a CVSDiff";
0100             return CVSDiff;
0101         }
0102         if (diffLine.startsWith(perforceDiff)) {
0103             qCDebug(KOMPAREDIFF2_LOG) << "Diff is a Perforce Diff";
0104             return Perforce;
0105         }
0106     }
0107 
0108     qCDebug(KOMPAREDIFF2_LOG) << "We'll assume it is a diff Diff";
0109 
0110     // For now we'll assume it is a diff file diff, later we might
0111     // try to really determine if it is a diff file diff.
0112     return Diff;
0113 }