aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/mesonprojectmanager/project/outputparsers/mesonoutputparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/mesonprojectmanager/project/outputparsers/mesonoutputparser.cpp')
-rw-r--r--src/plugins/mesonprojectmanager/project/outputparsers/mesonoutputparser.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/plugins/mesonprojectmanager/project/outputparsers/mesonoutputparser.cpp b/src/plugins/mesonprojectmanager/project/outputparsers/mesonoutputparser.cpp
new file mode 100644
index 0000000000..6cd631d464
--- /dev/null
+++ b/src/plugins/mesonprojectmanager/project/outputparsers/mesonoutputparser.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Alexis Jeandet.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "mesonoutputparser.h"
+#include <projectexplorer/task.h>
+#include <projectexplorer/taskhub.h>
+namespace MesonProjectManager {
+namespace Internal {
+
+struct WarningRegex
+{
+ const int lineCnt;
+ const QRegularExpression regex;
+};
+
+static const WarningRegex multiLineWarnings[] = {
+ WarningRegex{ 3, QRegularExpression{R"!(WARNING: Unknown options:)!"}},
+ WarningRegex{ 2, QRegularExpression{
+ R"!(WARNING: Project specifies a minimum meson_version|WARNING: Deprecated features used:)!"}},
+ WarningRegex{ 1, QRegularExpression{R"!(WARNING: )!"}}};
+
+inline void MesonOutputParser::addTask(ProjectExplorer::Task task)
+{
+#ifndef MESONPARSER_DISABLE_TASKS_FOR_TESTS // small hack to allow unit testing without the banana/monkey/jungle
+ ProjectExplorer::TaskHub::addTask(task);
+#else
+ Q_UNUSED(task);
+#endif
+}
+
+inline void MesonOutputParser::addTask(ProjectExplorer::Task::TaskType type, const QString &line)
+{
+#ifndef MESONPARSER_DISABLE_TASKS_FOR_TESTS // small hack to allow unit testing without the banana/monkey/jungle
+ auto task = ProjectExplorer::BuildSystemTask(type, QString("Meson build:%1").arg(line));
+ addTask(task);
+#else
+ Q_UNUSED(type);
+ Q_UNUSED(line);
+#endif
+}
+
+inline Utils::OutputLineParser::LinkSpecs MesonOutputParser::addTask(
+ ProjectExplorer::Task::TaskType type,
+ const QString &line,
+ const QRegularExpressionMatch &match,
+ int fileCapIndex,
+ int lineNumberCapIndex)
+{
+ LinkSpecs linkSpecs;
+#ifndef MESONPARSER_DISABLE_TASKS_FOR_TESTS // small hack to allow unit testing without the banana/monkey/jungle
+ auto fileName = absoluteFilePath(Utils::FilePath::fromString(match.captured(fileCapIndex)));
+ auto task = ProjectExplorer::BuildSystemTask(type,
+ QString("Meson build:%1").arg(line),
+ fileName,
+ match.captured(lineNumberCapIndex).toInt());
+ addTask(task);
+ addLinkSpecForAbsoluteFilePath(linkSpecs, task.file, task.line, match, 1);
+#else
+ Q_UNUSED(type);
+ Q_UNUSED(line);
+ Q_UNUSED(match);
+ Q_UNUSED(fileCapIndex);
+ Q_UNUSED(lineNumberCapIndex);
+#endif
+ return linkSpecs;
+}
+
+void MesonOutputParser::pushLine(const QString &line)
+{
+ m_remainingLines--;
+ m_pending.append(line);
+ if (m_remainingLines == 0) {
+ addTask(ProjectExplorer::Task::TaskType::Warning, m_pending.join('\n'));
+ m_pending.clear();
+ }
+}
+
+Utils::OutputLineParser::Result MesonOutputParser::processErrors(const QString &line)
+{
+ auto optionsErrors = m_errorOptionRegex.match(line);
+ if (optionsErrors.hasMatch()) {
+ addTask(ProjectExplorer::Task::TaskType::Error, line);
+ return ProjectExplorer::OutputTaskParser::Status::Done;
+ }
+ auto locatedErrors = m_errorFileLocRegex.match(line);
+ if (locatedErrors.hasMatch()) {
+ auto linkSpecs = addTask(ProjectExplorer::Task::TaskType::Error, line, locatedErrors, 1, 2);
+ return {ProjectExplorer::OutputTaskParser::Status::Done, linkSpecs};
+ }
+ return ProjectExplorer::OutputTaskParser::Status::NotHandled;
+}
+
+Utils::OutputLineParser::Result MesonOutputParser::processWarnings(const QString &line)
+{
+ for (const auto &warning : multiLineWarnings) {
+ const auto match = warning.regex.match(line);
+ if (match.hasMatch()) {
+ m_remainingLines = warning.lineCnt;
+ pushLine(line);
+ return ProjectExplorer::OutputTaskParser::Status::Done;
+ }
+ }
+ return ProjectExplorer::OutputTaskParser::Status::NotHandled;
+}
+
+MesonOutputParser::MesonOutputParser()
+ : ProjectExplorer::OutputTaskParser{}
+{}
+
+Utils::OutputLineParser::Result MesonOutputParser::handleLine(const QString &line,
+ Utils::OutputFormat type)
+{
+ if (type != Utils::OutputFormat::StdOutFormat)
+ return ProjectExplorer::OutputTaskParser::Status::NotHandled;
+ if (m_remainingLines) {
+ pushLine(line);
+ return ProjectExplorer::OutputTaskParser::Status::Done;
+ }
+ auto result = processErrors(line);
+ if (result.status == ProjectExplorer::OutputTaskParser::Status::Done)
+ return result;
+ return processWarnings(line);
+}
+
+void MesonOutputParser::readStdo(const QByteArray &data)
+{
+ auto str = QString::fromLocal8Bit(data);
+ for (const auto &line : str.split('\n'))
+ handleLine(line, Utils::OutputFormat::StdOutFormat);
+}
+
+void MesonOutputParser::setSourceDirectory(const Utils::FilePath &sourceDir)
+{
+ emit addSearchDir(sourceDir);
+}
+
+} // namespace Internal
+} // namespace MesonProjectManager