aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/baremetal/keilparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/baremetal/keilparser.cpp')
-rw-r--r--src/plugins/baremetal/keilparser.cpp223
1 files changed, 97 insertions, 126 deletions
diff --git a/src/plugins/baremetal/keilparser.cpp b/src/plugins/baremetal/keilparser.cpp
index 1a09a68b2d..d1589e87e9 100644
--- a/src/plugins/baremetal/keilparser.cpp
+++ b/src/plugins/baremetal/keilparser.cpp
@@ -28,9 +28,6 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/task.h>
-#include <texteditor/fontsettings.h>
-#include <texteditor/texteditorsettings.h>
-
#include <QRegularExpression>
using namespace ProjectExplorer;
@@ -59,46 +56,26 @@ KeilParser::KeilParser()
setObjectName("KeilParser");
}
-Core::Id KeilParser::id()
+Utils::Id KeilParser::id()
{
return "BareMetal.OutputParser.Keil";
}
void KeilParser::newTask(const Task &task)
{
- doFlush();
+ flush();
m_lastTask = task;
m_lines = 1;
}
-void KeilParser::amendDescription()
-{
- while (!m_snippets.isEmpty()) {
- const QString snippet = m_snippets.takeFirst();
-
- const int start = m_lastTask.description.count() + 1;
- m_lastTask.description.append('\n');
- m_lastTask.description.append(snippet);
-
- QTextLayout::FormatRange fr;
- fr.start = start;
- fr.length = m_lastTask.description.count() + 1;
- fr.format.setFont(TextEditor::TextEditorSettings::fontSettings().font());
- fr.format.setFontStyleHint(QFont::Monospace);
- m_lastTask.formats.append(fr);
-
- ++m_lines;
- }
-}
-
// ARM compiler specific parsers.
-bool KeilParser::parseArmWarningOrErrorDetailsMessage(const QString &lne)
+OutputLineParser::Result KeilParser::parseArmWarningOrErrorDetailsMessage(const QString &lne)
{
const QRegularExpression re("^\"(.+)\", line (\\d+).*:\\s+(Warning|Error):(\\s+|.+)([#|L].+)$");
const QRegularExpressionMatch match = re.match(lne);
if (!match.hasMatch())
- return false;
+ return Status::NotHandled;
enum CaptureIndex { FilePathIndex = 1, LineNumberIndex,
MessageTypeIndex, MessageNoteIndex, DescriptionIndex };
const Utils::FilePath fileName = Utils::FilePath::fromUserInput(
@@ -106,8 +83,11 @@ bool KeilParser::parseArmWarningOrErrorDetailsMessage(const QString &lne)
const int lineno = match.captured(LineNumberIndex).toInt();
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const QString descr = match.captured(DescriptionIndex);
- newTask(CompileTask(type, descr, fileName, lineno));
- return true;
+ newTask(CompileTask(type, descr, absoluteFilePath(fileName), lineno));
+ LinkSpecs linkSpecs;
+ addLinkSpecForAbsoluteFilePath(linkSpecs, m_lastTask.file, m_lastTask.line, match,
+ FilePathIndex);
+ return {Status::InProgress, linkSpecs};
}
bool KeilParser::parseArmErrorOrFatalErorrMessage(const QString &lne)
@@ -125,12 +105,12 @@ bool KeilParser::parseArmErrorOrFatalErorrMessage(const QString &lne)
// MCS51 compiler specific parsers.
-bool KeilParser::parseMcs51WarningOrErrorDetailsMessage1(const QString &lne)
+OutputLineParser::Result KeilParser::parseMcs51WarningOrErrorDetailsMessage1(const QString &lne)
{
const QRegularExpression re("^\\*{3} (WARNING|ERROR) (\\w+) IN LINE (\\d+) OF (.+\\.\\S+): (.+)$");
const QRegularExpressionMatch match = re.match(lne);
if (!match.hasMatch())
- return false;
+ return Status::NotHandled;
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex, LineNumberIndex,
FilePathIndex, MessageTextIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
@@ -139,16 +119,19 @@ bool KeilParser::parseMcs51WarningOrErrorDetailsMessage1(const QString &lne)
match.captured(FilePathIndex));
const QString descr = QString("%1: %2").arg(match.captured(MessageCodeIndex),
match.captured(MessageTextIndex));
- newTask(CompileTask(type, descr, fileName, lineno));
- return true;
+ newTask(CompileTask(type, descr, absoluteFilePath(fileName), lineno));
+ LinkSpecs linkSpecs;
+ addLinkSpecForAbsoluteFilePath(linkSpecs, m_lastTask.file, m_lastTask.line, match,
+ FilePathIndex);
+ return {Status::InProgress, linkSpecs};
}
-bool KeilParser::parseMcs51WarningOrErrorDetailsMessage2(const QString &lne)
+OutputLineParser::Result KeilParser::parseMcs51WarningOrErrorDetailsMessage2(const QString &lne)
{
const QRegularExpression re("^\\*{3} (WARNING|ERROR) (#\\w+) IN (\\d+) \\((.+), LINE \\d+\\): (.+)$");
const QRegularExpressionMatch match = re.match(lne);
if (!match.hasMatch())
- return false;
+ return Status::NotHandled;
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex, LineNumberIndex,
FilePathIndex, MessageTextIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
@@ -157,8 +140,11 @@ bool KeilParser::parseMcs51WarningOrErrorDetailsMessage2(const QString &lne)
match.captured(FilePathIndex));
const QString descr = QString("%1: %2").arg(match.captured(MessageCodeIndex),
match.captured(MessageTextIndex));
- newTask(CompileTask(type, descr, fileName, lineno));
- return true;
+ newTask(CompileTask(type, descr, absoluteFilePath(fileName), lineno));
+ LinkSpecs linkSpecs;
+ addLinkSpecForAbsoluteFilePath(linkSpecs, m_lastTask.file, m_lastTask.line, match,
+ FilePathIndex);
+ return {Status::InProgress, linkSpecs};
}
bool KeilParser::parseMcs51WarningOrFatalErrorMessage(const QString &lne)
@@ -190,26 +176,6 @@ bool KeilParser::parseMcs51FatalErrorMessage2(const QString &lne)
return true;
}
-void KeilParser::stdError(const QString &line)
-{
- IOutputParser::stdError(line);
-
- const QString lne = rightTrimmed(line);
-
- // Check for ARM compiler specific patterns.
- if (parseArmWarningOrErrorDetailsMessage(lne))
- return;
- if (parseArmErrorOrFatalErorrMessage(lne))
- return;
-
- if (lne.startsWith(' ')) {
- m_snippets.push_back(lne);
- return;
- }
-
- doFlush();
-}
-
static bool hasDetailsEntry(const QString &trimmedLine)
{
const QRegularExpression re("^([0-9A-F]{4})");
@@ -226,58 +192,76 @@ static bool hasDetailsPointer(const QString &trimmedLine)
return trimmedLine.contains('_');
}
-void KeilParser::stdOutput(const QString &line)
+OutputLineParser::Result KeilParser::handleLine(const QString &line, OutputFormat type)
{
- IOutputParser::stdOutput(line);
-
QString lne = rightTrimmed(line);
-
- // Check for MSC51 compiler specific patterns.
- const bool parsed = parseMcs51WarningOrErrorDetailsMessage1(lne)
- || parseMcs51WarningOrErrorDetailsMessage2(lne);
- if (!parsed) {
+ if (type == StdOutFormat) {
+ // Check for MSC51 compiler specific patterns.
+ Result res = parseMcs51WarningOrErrorDetailsMessage1(lne);
+ if (res.status != Status::NotHandled)
+ return res;
+ res = parseMcs51WarningOrErrorDetailsMessage2(lne);
+ if (res.status != Status::NotHandled)
+ return res;
if (parseMcs51WarningOrFatalErrorMessage(lne))
- return;
+ return Status::InProgress;
if (parseMcs51FatalErrorMessage2(lne))
- return;
+ return Status::InProgress;
+
+ if (m_lastTask.isNull()) {
+ // Check for details, which are comes on a previous
+ // lines, before the message.
+
+ // This code handles the details in a form like:
+ // 0000 24 ljmp usb_stub_isr ; (00) Setup data available.
+ // *** _____________________________________^
+ // 003C 54 ljmp usb_stub_isr ; (3C) EP8 in/out.
+ // *** _____________________________________^
+ if (hasDetailsEntry(lne) || hasDetailsPointer(lne)) {
+ lne.replace(0, 4, " ");
+ m_snippets.push_back(lne);
+ return Status::InProgress;
+ }
+ } else {
+ // Check for details, which are comes on a next
+ // lines, after the message.
+ if (lne.startsWith(' ')) {
+ m_snippets.push_back(lne);
+ return Status::InProgress;
+ }
+ }
+ flush();
+ return Status::NotHandled;
}
- if (m_lastTask.isNull()) {
- // Check for details, which are comes on a previous
- // lines, before the message.
-
- // This code handles the details in a form like:
- // 0000 24 ljmp usb_stub_isr ; (00) Setup data available.
- // *** _____________________________________^
- // 003C 54 ljmp usb_stub_isr ; (3C) EP8 in/out.
- // *** _____________________________________^
- if (hasDetailsEntry(lne) || hasDetailsPointer(lne)) {
- lne.replace(0, 4, " ");
- m_snippets.push_back(lne);
- return;
- }
- } else {
- // Check for details, which are comes on a next
- // lines, after the message.
- if (lne.startsWith(' ')) {
- m_snippets.push_back(lne);
- return;
- }
+ // Check for ARM compiler specific patterns.
+ const Result res = parseArmWarningOrErrorDetailsMessage(lne);
+ if (res.status != Status::NotHandled)
+ return res;
+ if (parseArmErrorOrFatalErorrMessage(lne))
+ return Status::InProgress;
+
+ if (lne.startsWith(' ')) {
+ m_snippets.push_back(lne);
+ return Status::InProgress;
}
- doFlush();
+ flush();
+ return Status::NotHandled;
}
-void KeilParser::doFlush()
+void KeilParser::flush()
{
if (m_lastTask.isNull())
return;
- amendDescription();
-
+ m_lastTask.details = m_snippets;
+ m_snippets.clear();
+ m_lines += m_lastTask.details.count();
+ setDetailsFormat(m_lastTask);
Task t = m_lastTask;
m_lastTask.clear();
- emit addTask(t, m_lines, 1);
+ scheduleTask(t, m_lines, 1);
m_lines = 0;
}
@@ -320,7 +304,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
<< QString::fromLatin1("\"c:\\foo\\main.c\", line 63: Warning: #1234: Some warning")
<< OutputParserTester::STDERR
<< QString()
- << QString::fromLatin1("\"c:\\foo\\main.c\", line 63: Warning: #1234: Some warning\n")
+ << QString()
<< (Tasks() << CompileTask(Task::Warning,
"#1234: Some warning",
FilePath::fromUserInput("c:\\foo\\main.c"),
@@ -333,9 +317,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
" ^")
<< OutputParserTester::STDERR
<< QString()
- << QString::fromLatin1("\"c:\\foo\\main.c\", line 63: Warning: #1234: Some warning\n"
- " int f;\n"
- " ^\n")
+ << QString()
<< (Tasks() << CompileTask(Task::Warning,
"#1234: Some warning\n"
" int f;\n"
@@ -348,7 +330,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
<< QString::fromLatin1("\"c:\\foo\\main.c\", line 63: Error: #1234: Some error")
<< OutputParserTester::STDERR
<< QString()
- << QString::fromLatin1("\"c:\\foo\\main.c\", line 63: Error: #1234: Some error\n")
+ << QString()
<< (Tasks() << CompileTask(Task::Error,
"#1234: Some error",
FilePath::fromUserInput("c:\\foo\\main.c"),
@@ -359,7 +341,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
<< QString::fromLatin1("\"flash.sct\", line 51 (column 20): Error: L1234: Some error")
<< OutputParserTester::STDERR
<< QString()
- << QString::fromLatin1("\"flash.sct\", line 51 (column 20): Error: L1234: Some error\n")
+ << QString()
<< (Tasks() << CompileTask(Task::Error,
"L1234: Some error",
FilePath::fromUserInput("flash.sct"),
@@ -372,9 +354,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
" ^")
<< OutputParserTester::STDERR
<< QString()
- << QString::fromLatin1("\"c:\\foo\\main.c\", line 63: Error: #1234: Some error\n"
- " int f;\n"
- " ^\n")
+ << QString()
<< (Tasks() << CompileTask(Task::Error,
"#1234: Some error\n"
" int f;\n"
@@ -387,7 +367,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
<< QString::fromLatin1("\"c:\\foo\\main.c\", line 71: Error: At end of source: #40: Some error")
<< OutputParserTester::STDERR
<< QString()
- << QString::fromLatin1("\"c:\\foo\\main.c\", line 71: Error: At end of source: #40: Some error\n")
+ << QString()
<< (Tasks() << CompileTask(Task::Error,
"#40: Some error",
FilePath::fromUserInput("c:\\foo\\main.c"),
@@ -398,7 +378,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
<< QString::fromLatin1("Error: L6226E: Some error.")
<< OutputParserTester::STDERR
<< QString()
- << QString::fromLatin1("Error: L6226E: Some error.\n")
+ << QString()
<< (Tasks() << CompileTask(Task::Error,
"L6226E: Some error."))
<< QString();
@@ -409,7 +389,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
QTest::newRow("MCS51: Assembler simple warning")
<< QString::fromLatin1("*** WARNING #A9 IN 15 (c:\\foo\\dscr.a51, LINE 15): Some warning")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** WARNING #A9 IN 15 (c:\\foo\\dscr.a51, LINE 15): Some warning\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Warning,
"#A9: Some warning",
@@ -420,7 +400,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
QTest::newRow("MCS51: Assembler simple error")
<< QString::fromLatin1("*** ERROR #A9 IN 15 (c:\\foo\\dscr.a51, LINE 15): Some error")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** ERROR #A9 IN 15 (c:\\foo\\dscr.a51, LINE 15): Some error\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Error,
"#A9: Some error",
@@ -433,9 +413,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
" Some detail 1\n"
" Some detail N")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("A51 FATAL ERROR -\n"
- " Some detail 1\n"
- " Some detail N\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Error,
"Assembler fatal error\n"
@@ -448,9 +426,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
"*** ___^\n"
"*** ERROR #A45 IN 28 (d:\\foo.a51, LINE 28): Some error")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("01AF Some detail\n"
- "*** ___^\n"
- "*** ERROR #A45 IN 28 (d:\\foo.a51, LINE 28): Some error\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Error,
"#A45: Some error\n"
@@ -464,7 +440,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
QTest::newRow("MCS51: Compiler simple warning")
<< QString::fromLatin1("*** WARNING C123 IN LINE 13 OF c:\\foo.c: Some warning")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** WARNING C123 IN LINE 13 OF c:\\foo.c: Some warning\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Warning,
"C123: Some warning",
@@ -475,7 +451,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
QTest::newRow("MCS51: Compiler extended warning")
<< QString::fromLatin1("*** WARNING C123 IN LINE 13 OF c:\\foo.c: Some warning : 'extended text'")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** WARNING C123 IN LINE 13 OF c:\\foo.c: Some warning : 'extended text'\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Warning,
"C123: Some warning : 'extended text'",
@@ -486,7 +462,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
QTest::newRow("MCS51: Compiler simple error")
<< QString::fromLatin1("*** ERROR C123 IN LINE 13 OF c:\\foo.c: Some error")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** ERROR C123 IN LINE 13 OF c:\\foo.c: Some error\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Error,
"C123: Some error",
@@ -497,7 +473,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
QTest::newRow("MCS51: Compiler extended error")
<< QString::fromLatin1("*** ERROR C123 IN LINE 13 OF c:\\foo.c: Some error : 'extended text'")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** ERROR C123 IN LINE 13 OF c:\\foo.c: Some error : 'extended text'\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Error,
"C123: Some error : 'extended text'",
@@ -510,9 +486,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
" Some detail 1\n"
" Some detail N")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("C51 FATAL-ERROR -\n"
- " Some detail 1\n"
- " Some detail N\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Error,
"Compiler fatal error\n"
@@ -525,8 +499,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
<< QString::fromLatin1("*** WARNING L16: Some warning\n"
" Some detail 1")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** WARNING L16: Some warning\n"
- " Some detail 1\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Warning,
"L16: Some warning\n"
@@ -536,7 +509,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
QTest::newRow("MCS51: Linker simple fatal error")
<< QString::fromLatin1("*** FATAL ERROR L456: Some error")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** FATAL ERROR L456: Some error\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Error,
"L456: Some error"))
@@ -547,9 +520,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
" Some detail 1\n"
" Some detail N")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("*** FATAL ERROR L456: Some error\n"
- " Some detail 1\n"
- " Some detail N\n")
+ << QString()
<< QString()
<< (Tasks() << CompileTask(Task::Error,
"L456: Some error\n"
@@ -561,7 +532,7 @@ void BareMetalPlugin::testKeilOutputParsers_data()
void BareMetalPlugin::testKeilOutputParsers()
{
OutputParserTester testbench;
- testbench.appendOutputParser(new KeilParser);
+ testbench.addLineParser(new KeilParser);
QFETCH(QString, input);
QFETCH(OutputParserTester::Channel, inputChannel);
QFETCH(Tasks, tasks);