diff options
Diffstat (limited to 'src/plugins/baremetal/keilparser.cpp')
-rw-r--r-- | src/plugins/baremetal/keilparser.cpp | 223 |
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); |