2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2019-03-15 16:51:23 +03:00
|
|
|
|
|
|
|
|
#include "iarewparser.h"
|
|
|
|
|
|
|
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
|
|
|
|
#include <projectexplorer/task.h>
|
|
|
|
|
|
|
|
|
|
#include <QRegularExpression>
|
|
|
|
|
|
|
|
|
|
using namespace ProjectExplorer;
|
2020-01-15 08:56:11 +01:00
|
|
|
using namespace Utils;
|
2019-03-15 16:51:23 +03:00
|
|
|
|
2022-10-10 14:36:17 +02:00
|
|
|
namespace BareMetal::Internal {
|
2019-03-15 16:51:23 +03:00
|
|
|
|
2019-05-08 13:49:19 +03:00
|
|
|
// Helpers:
|
|
|
|
|
|
2019-03-15 16:51:23 +03:00
|
|
|
static Task::TaskType taskType(const QString &msgType)
|
|
|
|
|
{
|
|
|
|
|
if (msgType == "Warning")
|
|
|
|
|
return Task::TaskType::Warning;
|
|
|
|
|
else if (msgType == "Error" || msgType == "Fatal error")
|
|
|
|
|
return Task::TaskType::Error;
|
|
|
|
|
return Task::TaskType::Unknown;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-08 13:49:19 +03:00
|
|
|
// IarParser
|
|
|
|
|
|
2019-03-15 16:51:23 +03:00
|
|
|
IarParser::IarParser()
|
|
|
|
|
{
|
|
|
|
|
setObjectName("IarParser");
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-26 13:59:38 +02:00
|
|
|
Utils::Id IarParser::id()
|
2019-03-15 16:51:23 +03:00
|
|
|
{
|
|
|
|
|
return "BareMetal.OutputParser.Iar";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IarParser::newTask(const Task &task)
|
|
|
|
|
{
|
2020-04-15 14:59:51 +02:00
|
|
|
flush();
|
2019-03-15 16:51:23 +03:00
|
|
|
m_lastTask = task;
|
|
|
|
|
m_lines = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IarParser::amendFilePath()
|
|
|
|
|
{
|
|
|
|
|
if (m_filePathParts.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
QString filePath;
|
|
|
|
|
while (!m_filePathParts.isEmpty())
|
|
|
|
|
filePath.append(m_filePathParts.takeFirst().trimmed());
|
2019-05-28 13:49:26 +02:00
|
|
|
m_lastTask.setFile(Utils::FilePath::fromUserInput(filePath));
|
2019-03-15 16:51:23 +03:00
|
|
|
m_expectFilePath = false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-25 12:00:39 +03:00
|
|
|
bool IarParser::parseErrorOrFatalErrorDetailsMessage1(const QString &lne)
|
|
|
|
|
{
|
|
|
|
|
const QRegularExpression re("^(Error|Fatal error)\\[(.+)\\]:\\s(.+)\\s\\[(.+)$");
|
|
|
|
|
const QRegularExpressionMatch match = re.match(lne);
|
|
|
|
|
if (!match.hasMatch())
|
|
|
|
|
return false;
|
|
|
|
|
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex,
|
|
|
|
|
DescriptionIndex, FilepathBeginIndex };
|
|
|
|
|
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
|
|
|
|
|
const QString descr = QString("[%1]: %2").arg(match.captured(MessageCodeIndex),
|
|
|
|
|
match.captured(DescriptionIndex));
|
|
|
|
|
// This task has a file path, but this patch are split on
|
|
|
|
|
// some lines, which will be received later.
|
2020-01-15 08:56:11 +01:00
|
|
|
newTask(CompileTask(type, descr));
|
2019-10-25 12:00:39 +03:00
|
|
|
// Prepare first part of a file path.
|
|
|
|
|
QString firstPart = match.captured(FilepathBeginIndex);
|
|
|
|
|
firstPart.remove("referenced from ");
|
|
|
|
|
m_filePathParts.push_back(firstPart);
|
|
|
|
|
m_expectFilePath = true;
|
|
|
|
|
m_expectSnippet = false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IarParser::parseErrorOrFatalErrorDetailsMessage2(const QString &lne)
|
|
|
|
|
{
|
|
|
|
|
const QRegularExpression re("^.*(Error|Fatal error)\\[(.+)\\]:\\s(.+)$");
|
|
|
|
|
const QRegularExpressionMatch match = re.match(lne);
|
|
|
|
|
if (!match.hasMatch())
|
|
|
|
|
return false;
|
|
|
|
|
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex,
|
|
|
|
|
DescriptionIndex };
|
|
|
|
|
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
|
|
|
|
|
const QString descr = QString("[%1]: %2").arg(match.captured(MessageCodeIndex),
|
|
|
|
|
match.captured(DescriptionIndex));
|
|
|
|
|
// This task has not a file path. The description details
|
|
|
|
|
// will be received later on the next lines.
|
2020-01-15 08:56:11 +01:00
|
|
|
newTask(CompileTask(type, descr));
|
2019-10-25 12:00:39 +03:00
|
|
|
m_expectSnippet = true;
|
|
|
|
|
m_expectFilePath = false;
|
|
|
|
|
m_expectDescription = false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 13:53:05 +02:00
|
|
|
OutputLineParser::Result IarParser::parseWarningOrErrorOrFatalErrorDetailsMessage1(const QString &lne)
|
2019-10-25 12:00:39 +03:00
|
|
|
{
|
|
|
|
|
const QRegularExpression re("^\"(.+)\",(\\d+)?\\s+(Warning|Error|Fatal error)\\[(.+)\\].+$");
|
|
|
|
|
const QRegularExpressionMatch match = re.match(lne);
|
|
|
|
|
if (!match.hasMatch())
|
2020-04-16 13:53:05 +02:00
|
|
|
return Status::NotHandled;
|
2019-10-25 12:00:39 +03:00
|
|
|
enum CaptureIndex { FilePathIndex = 1, LineNumberIndex,
|
|
|
|
|
MessageTypeIndex, MessageCodeIndex };
|
|
|
|
|
const Utils::FilePath fileName = Utils::FilePath::fromUserInput(
|
|
|
|
|
match.captured(FilePathIndex));
|
|
|
|
|
const int lineno = match.captured(LineNumberIndex).toInt();
|
|
|
|
|
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
|
|
|
|
|
// A full description will be received later on next lines.
|
2020-04-07 13:49:34 +02:00
|
|
|
newTask(CompileTask(type, {}, absoluteFilePath(fileName), lineno));
|
2019-10-25 12:00:39 +03:00
|
|
|
const QString firstPart = QString("[%1]: ").arg(match.captured(MessageCodeIndex));
|
|
|
|
|
m_descriptionParts.append(firstPart);
|
|
|
|
|
m_expectDescription = true;
|
|
|
|
|
m_expectSnippet = false;
|
|
|
|
|
m_expectFilePath = false;
|
2020-04-16 13:53:05 +02:00
|
|
|
LinkSpecs linkSpecs;
|
2024-05-31 12:32:33 +02:00
|
|
|
addLinkSpecForAbsoluteFilePath(
|
|
|
|
|
linkSpecs, m_lastTask.file, m_lastTask.line, m_lastTask.column, match, FilePathIndex);
|
2020-04-16 13:53:05 +02:00
|
|
|
return {Status::InProgress, linkSpecs};
|
2019-10-25 12:00:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IarParser::parseErrorInCommandLineMessage(const QString &lne)
|
|
|
|
|
{
|
|
|
|
|
if (!lne.startsWith("Error in command line"))
|
|
|
|
|
return false;
|
2020-01-15 08:56:11 +01:00
|
|
|
newTask(CompileTask(Task::TaskType::Error, lne.trimmed()));
|
2019-10-25 12:00:39 +03:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-25 12:20:38 +03:00
|
|
|
bool IarParser::parseErrorMessage1(const QString &lne)
|
|
|
|
|
{
|
|
|
|
|
const QRegularExpression re("^(Error)\\[(.+)\\]:\\s(.+)$");
|
|
|
|
|
const QRegularExpressionMatch match = re.match(lne);
|
|
|
|
|
if (!match.hasMatch())
|
|
|
|
|
return false;
|
|
|
|
|
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex, DescriptionIndex };
|
|
|
|
|
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
|
|
|
|
|
const QString descr = QString("[%1]: %2").arg(match.captured(MessageCodeIndex),
|
|
|
|
|
match.captured(DescriptionIndex));
|
|
|
|
|
// This task has not a file path and line number (as it is a linker message)
|
2020-01-15 08:56:11 +01:00
|
|
|
newTask(CompileTask(type, descr));
|
2019-10-25 12:20:38 +03:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 13:53:05 +02:00
|
|
|
OutputLineParser::Result IarParser::handleLine(const QString &line, OutputFormat type)
|
2020-04-08 09:42:51 +02:00
|
|
|
{
|
2019-03-15 16:51:23 +03:00
|
|
|
const QString lne = rightTrimmed(line);
|
2020-04-08 17:45:39 +02:00
|
|
|
if (type == StdOutFormat) {
|
|
|
|
|
// The call sequence has the meaning!
|
|
|
|
|
const bool leastOneParsed = parseErrorInCommandLineMessage(lne)
|
|
|
|
|
|| parseErrorMessage1(lne);
|
|
|
|
|
if (!leastOneParsed) {
|
2020-04-15 14:59:51 +02:00
|
|
|
flush();
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::NotHandled;
|
|
|
|
|
}
|
|
|
|
|
return Status::InProgress;
|
|
|
|
|
}
|
2019-03-15 16:51:23 +03:00
|
|
|
|
2019-10-25 12:00:39 +03:00
|
|
|
if (parseErrorOrFatalErrorDetailsMessage1(lne))
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::InProgress;
|
2019-10-25 12:00:39 +03:00
|
|
|
if (parseErrorOrFatalErrorDetailsMessage2(lne))
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::InProgress;
|
2020-04-16 13:53:05 +02:00
|
|
|
const Result res = parseWarningOrErrorOrFatalErrorDetailsMessage1(lne);
|
|
|
|
|
if (res.status != Status::NotHandled)
|
|
|
|
|
return res;
|
2019-03-15 16:51:23 +03:00
|
|
|
|
2020-04-08 17:45:39 +02:00
|
|
|
if (m_expectFilePath) {
|
2019-11-04 14:23:21 +03:00
|
|
|
if (lne.endsWith(']')) {
|
2019-03-15 16:51:23 +03:00
|
|
|
const QString lastPart = lne.left(lne.size() - 1);
|
|
|
|
|
m_filePathParts.push_back(lastPart);
|
2020-04-15 14:59:51 +02:00
|
|
|
flush();
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::Done;
|
2019-03-15 16:51:23 +03:00
|
|
|
} else {
|
|
|
|
|
m_filePathParts.push_back(lne);
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::InProgress;
|
2019-03-15 16:51:23 +03:00
|
|
|
}
|
2020-04-08 17:45:39 +02:00
|
|
|
}
|
|
|
|
|
if (m_expectSnippet && lne.startsWith(' ')) {
|
2019-03-15 16:51:23 +03:00
|
|
|
if (!lne.endsWith("Fatal error detected, aborting.")) {
|
|
|
|
|
m_snippets.push_back(lne);
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::InProgress;
|
2019-03-15 16:51:23 +03:00
|
|
|
}
|
|
|
|
|
} else if (m_expectDescription) {
|
|
|
|
|
if (!lne.startsWith(" ")) {
|
|
|
|
|
m_descriptionParts.push_back(lne.trimmed());
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::InProgress;
|
2019-03-15 16:51:23 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 17:45:39 +02:00
|
|
|
if (!m_lastTask.isNull()) {
|
2020-04-15 14:59:51 +02:00
|
|
|
flush();
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::Done;
|
|
|
|
|
}
|
2019-03-15 16:51:23 +03:00
|
|
|
|
2020-04-08 17:45:39 +02:00
|
|
|
return Status::NotHandled;
|
2019-03-15 16:51:23 +03:00
|
|
|
}
|
|
|
|
|
|
2020-04-15 14:59:51 +02:00
|
|
|
void IarParser::flush()
|
2019-03-15 16:51:23 +03:00
|
|
|
{
|
|
|
|
|
if (m_lastTask.isNull())
|
|
|
|
|
return;
|
|
|
|
|
|
2020-05-12 16:26:34 +02:00
|
|
|
while (!m_descriptionParts.isEmpty())
|
|
|
|
|
m_lastTask.summary.append(m_descriptionParts.takeFirst());
|
|
|
|
|
m_lastTask.details = m_snippets;
|
|
|
|
|
m_snippets.clear();
|
|
|
|
|
m_lines += m_lastTask.details.count();
|
GCC parser: Create fewer and better issues
Consider the following compiler warning:
In file included from qgroundcontrol/libs/mavlink/include/mavlink/v2.0/
ardupilotmega/ardupilotmega.h:946,
from qgroundcontrol/libs/mavlink/include/mavlink/v2.0/
ardupilotmega/mavlink.h:32,
from qgroundcontrol/src/comm/QGCMAVLink.h:24,
from qgroundcontrol/src/comm/LinkInterface.h:21,
from qgroundcontrol/src/comm/LinkManager.h:21,
from qgroundcontrol/src/QGCApplication.h:27,
from qgroundcontrol/src/QtLocationPlugin/
QGCMapUrlEngine.cpp:19:
qgroundcontrol/libs/mavlink/include/mavlink/v2.0/ardupilotmega/./
mavlink_msg_vision_position_delta.h: In function ‘uint16_t
mavlink_msg_vision_position_delta_encode(uint8_t, uint8_t,
mavlink_message_t*, const mavlink_vision_position_delta_t*)’:
qgroundcontrol/libs/mavlink/include/mavlink/v2.0/ardupilotmega/./
mavlink_msg_vision_position_delta.h:138:178: warning: taking address of
packed member of ‘__mavlink_vision_position_delta_t’ may result in an
unaligned pointer value [-Waddress-of-packed-member]
138 | return mavlink_msg_vision_position_delta_pack(system_id,
component_id, msg, vision_position_delta->time_usec,
vision_position_delta->time_delta_usec, vision_position_delta-
>angle_delta, vision_position_delta->position_delta,
vision_position_delta->confidence);
|
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
Before this patch, this output resulted in nine entries in the issues
pane, which defeats the purpose: The user is supposed to get a quick
overview of the build problems, but instead we basically just copied
over the contents of the compile window, which is of little help and
also slows things down by overloading the task model.
We now try harder to identify output lines that belong to the same issue
and create just one task for them. File paths are now linkified in the
detailed issue view, so that users can still navigate quickly to all
involved files.
Task-number: QTCREATORBUG-22914
Change-Id: I1aed2ffac7d363c02073ef318cb863754379cf6d
Reviewed-by: hjk <hjk@qt.io>
2020-05-11 15:31:00 +02:00
|
|
|
setDetailsFormat(m_lastTask);
|
2019-03-15 16:51:23 +03:00
|
|
|
amendFilePath();
|
|
|
|
|
|
|
|
|
|
m_expectSnippet = true;
|
|
|
|
|
m_expectFilePath = false;
|
|
|
|
|
m_expectDescription = false;
|
|
|
|
|
|
|
|
|
|
Task t = m_lastTask;
|
|
|
|
|
m_lastTask.clear();
|
2020-04-16 13:53:05 +02:00
|
|
|
scheduleTask(t, m_lines, 1);
|
2019-03-15 16:51:23 +03:00
|
|
|
m_lines = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-10 14:36:17 +02:00
|
|
|
} // BareMetal::Internal
|
2019-03-15 16:51:23 +03:00
|
|
|
|
|
|
|
|
// Unit tests:
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_TESTS
|
|
|
|
|
#include <projectexplorer/outputparser_test.h>
|
|
|
|
|
#include <QTest>
|
|
|
|
|
|
2023-11-17 11:19:40 +01:00
|
|
|
namespace BareMetal::Internal {
|
2019-03-15 16:51:23 +03:00
|
|
|
|
2024-01-12 15:48:22 +01:00
|
|
|
class IarParserTest final : public QObject
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
|
void testIarOutputParsers_data();
|
|
|
|
|
void testIarOutputParsers();
|
|
|
|
|
};
|
|
|
|
|
|
2023-11-17 11:19:40 +01:00
|
|
|
void IarParserTest::testIarOutputParsers_data()
|
2019-03-15 16:51:23 +03:00
|
|
|
{
|
|
|
|
|
QTest::addColumn<QString>("input");
|
|
|
|
|
QTest::addColumn<OutputParserTester::Channel>("inputChannel");
|
|
|
|
|
QTest::addColumn<QString>("childStdOutLines");
|
|
|
|
|
QTest::addColumn<QString>("childStdErrLines");
|
2019-05-27 16:09:44 +02:00
|
|
|
QTest::addColumn<Tasks >("tasks");
|
2019-03-15 16:51:23 +03:00
|
|
|
QTest::addColumn<QString>("outputLines");
|
|
|
|
|
|
|
|
|
|
QTest::newRow("pass-through stdout")
|
|
|
|
|
<< "Sometext" << OutputParserTester::STDOUT
|
|
|
|
|
<< "Sometext\n" << QString()
|
2019-05-27 16:09:44 +02:00
|
|
|
<< Tasks()
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
QTest::newRow("pass-through stderr")
|
|
|
|
|
<< "Sometext" << OutputParserTester::STDERR
|
|
|
|
|
<< QString() << "Sometext\n"
|
2019-05-27 16:09:44 +02:00
|
|
|
<< Tasks()
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
// For std out.
|
|
|
|
|
QTest::newRow("Error in command line")
|
|
|
|
|
<< QString::fromLatin1("Error in command line: Some error")
|
|
|
|
|
<< OutputParserTester::STDOUT
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Error,
|
|
|
|
|
"Error in command line: Some error"))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
2019-10-25 12:20:38 +03:00
|
|
|
QTest::newRow("Linker error")
|
|
|
|
|
<< QString::fromLatin1("Error[e46]: Some error")
|
|
|
|
|
<< OutputParserTester::STDOUT
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2019-10-25 12:20:38 +03:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Error,
|
|
|
|
|
"[e46]: Some error"))
|
2019-10-25 12:20:38 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
2019-03-15 16:51:23 +03:00
|
|
|
// For std error.
|
|
|
|
|
QTest::newRow("No details warning")
|
|
|
|
|
<< QString::fromLatin1("\"c:\\foo\\main.c\",63 Warning[Pe223]:\n"
|
|
|
|
|
" Some warning \"foo\" bar")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Warning,
|
|
|
|
|
"[Pe223]: Some warning \"foo\" bar",
|
|
|
|
|
Utils::FilePath::fromUserInput("c:\\foo\\main.c"),
|
|
|
|
|
63))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Details warning")
|
|
|
|
|
<< QString::fromLatin1(" some_detail;\n"
|
|
|
|
|
" ^\n"
|
|
|
|
|
"\"c:\\foo\\main.c\",63 Warning[Pe223]:\n"
|
|
|
|
|
" Some warning")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Warning,
|
|
|
|
|
"[Pe223]: Some warning\n"
|
|
|
|
|
" some_detail;\n"
|
|
|
|
|
" ^",
|
|
|
|
|
FilePath::fromUserInput("c:\\foo\\main.c"),
|
|
|
|
|
63))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
QTest::newRow("No details split-description warning")
|
|
|
|
|
<< QString::fromLatin1("\"c:\\foo\\main.c\",63 Warning[Pe223]:\n"
|
|
|
|
|
" Some warning\n"
|
|
|
|
|
" , split")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Warning,
|
|
|
|
|
"[Pe223]: Some warning, split",
|
|
|
|
|
FilePath::fromUserInput("c:\\foo\\main.c"),
|
|
|
|
|
63))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
QTest::newRow("No details error")
|
|
|
|
|
<< QString::fromLatin1("\"c:\\foo\\main.c\",63 Error[Pe223]:\n"
|
|
|
|
|
" Some error")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Error,
|
|
|
|
|
"[Pe223]: Some error",
|
|
|
|
|
FilePath::fromUserInput("c:\\foo\\main.c"),
|
|
|
|
|
63))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
QTest::newRow("Details error")
|
|
|
|
|
<< QString::fromLatin1(" some_detail;\n"
|
|
|
|
|
" ^\n"
|
|
|
|
|
"\"c:\\foo\\main.c\",63 Error[Pe223]:\n"
|
|
|
|
|
" Some error")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Error,
|
|
|
|
|
"[Pe223]: Some error\n"
|
|
|
|
|
" some_detail;\n"
|
|
|
|
|
" ^",
|
|
|
|
|
FilePath::fromUserInput("c:\\foo\\main.c"),
|
|
|
|
|
63))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
QTest::newRow("No details split-description error")
|
|
|
|
|
<< QString::fromLatin1("\"c:\\foo\\main.c\",63 Error[Pe223]:\n"
|
|
|
|
|
" Some error\n"
|
|
|
|
|
" , split")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Error,
|
|
|
|
|
"[Pe223]: Some error, split",
|
|
|
|
|
FilePath::fromUserInput("c:\\foo\\main.c"),
|
|
|
|
|
63))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
QTest::newRow("No definition for")
|
|
|
|
|
<< QString::fromLatin1("Error[Li005]: Some error \"foo\" [referenced from c:\\fo\n"
|
|
|
|
|
" o\\bar\\mai\n"
|
|
|
|
|
" n.c.o\n"
|
|
|
|
|
"]")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Error,
|
|
|
|
|
"[Li005]: Some error \"foo\"",
|
|
|
|
|
FilePath::fromUserInput("c:\\foo\\bar\\main.c.o")))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
QTest::newRow("More than one source file specified")
|
|
|
|
|
<< QString::fromLatin1("Fatal error[Su011]: Some error:\n"
|
|
|
|
|
" c:\\foo.c\n"
|
|
|
|
|
" c:\\bar.c\n"
|
|
|
|
|
"Fatal error detected, aborting.")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Error,
|
|
|
|
|
"[Su011]: Some error:\n"
|
|
|
|
|
" c:\\foo.c\n"
|
|
|
|
|
" c:\\bar.c"))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
|
|
|
|
|
QTest::newRow("At end of source")
|
|
|
|
|
<< QString::fromLatin1("At end of source Error[Pe040]: Some error \";\"")
|
|
|
|
|
<< OutputParserTester::STDERR
|
|
|
|
|
<< QString()
|
2020-04-08 17:45:39 +02:00
|
|
|
<< QString()
|
2020-01-15 08:56:11 +01:00
|
|
|
<< (Tasks() << CompileTask(Task::Error,
|
|
|
|
|
"[Pe040]: Some error \";\""))
|
2019-03-15 16:51:23 +03:00
|
|
|
<< QString();
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-17 11:19:40 +01:00
|
|
|
void IarParserTest::testIarOutputParsers()
|
2019-03-15 16:51:23 +03:00
|
|
|
{
|
|
|
|
|
OutputParserTester testbench;
|
2020-04-08 17:45:39 +02:00
|
|
|
testbench.addLineParser(new IarParser);
|
2019-03-15 16:51:23 +03:00
|
|
|
QFETCH(QString, input);
|
|
|
|
|
QFETCH(OutputParserTester::Channel, inputChannel);
|
2019-05-27 16:09:44 +02:00
|
|
|
QFETCH(Tasks, tasks);
|
2019-03-15 16:51:23 +03:00
|
|
|
QFETCH(QString, childStdOutLines);
|
|
|
|
|
QFETCH(QString, childStdErrLines);
|
|
|
|
|
QFETCH(QString, outputLines);
|
|
|
|
|
|
|
|
|
|
testbench.testParsing(input, inputChannel,
|
|
|
|
|
tasks, childStdOutLines, childStdErrLines,
|
|
|
|
|
outputLines);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-12 16:54:25 +01:00
|
|
|
QObject *createIarParserTest()
|
|
|
|
|
{
|
|
|
|
|
return new IarParserTest;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-17 11:19:40 +01:00
|
|
|
} // BareMetal::Internal
|
2019-03-15 16:51:23 +03:00
|
|
|
|
|
|
|
|
#endif // WITH_TESTS
|
2024-01-12 15:48:22 +01:00
|
|
|
|
|
|
|
|
#include "iarewparser.moc"
|