forked from qt-creator/qt-creator
BareMetal: Handle details preceding it message in the KEIL parser
We need to handle a multi-line error messages from the KEIL A51 assembler: http://www.keil.com/support/man/docs/a51/a51_er_nonfatalerror.htm This assembler produces an error messages in the form like: 00B0 114 ljmp usb_stub_isr ; (B0) GPIF operation complete. *** _____________________________________^ *** ERROR #A45 IN 114 (autovec_keil.a51, LINE 114): UNDEFINED SYMBOL 00B4 116 ljmp usb_stub_isr ; (B4) GPIF waveform. *** _____________________________________^ *** ERROR #A45 IN 116 (autovec_keil.a51, LINE 116): UNDEFINED SYMBOL where the details places before than a main message text. This patch handles this error messages, but with an one limitation in that a details should start with a four hexadecimal letters (in a common case it can not contains that letters at all). Change-Id: I0c9bf7ab72e1aef32498af5a1ef29c9221c185d5 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -70,20 +70,24 @@ void KeilParser::newTask(const Task &task)
|
||||
m_lines = 1;
|
||||
}
|
||||
|
||||
void KeilParser::amendDescription(const QString &desc)
|
||||
void KeilParser::amendDescription()
|
||||
{
|
||||
const int start = m_lastTask.description.count() + 1;
|
||||
m_lastTask.description.append(QLatin1Char('\n'));
|
||||
m_lastTask.description.append(desc);
|
||||
while (!m_snippets.isEmpty()) {
|
||||
const QString snippet = m_snippets.takeFirst();
|
||||
|
||||
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);
|
||||
const int start = m_lastTask.description.count() + 1;
|
||||
m_lastTask.description.append('\n');
|
||||
m_lastTask.description.append(snippet);
|
||||
|
||||
++m_lines;
|
||||
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.
|
||||
@@ -205,18 +209,34 @@ void KeilParser::stdError(const QString &line)
|
||||
return;
|
||||
|
||||
if (lne.startsWith(QLatin1Char(' '))) {
|
||||
amendDescription(lne);
|
||||
m_snippets.push_back(lne);
|
||||
return;
|
||||
}
|
||||
|
||||
doFlush();
|
||||
}
|
||||
|
||||
static bool hasDetailsEntry(const QString &trimmedLine)
|
||||
{
|
||||
const QRegularExpression re("^([0-9A-F]{4})");
|
||||
const QRegularExpressionMatch match = re.match(trimmedLine);
|
||||
return match.hasMatch();
|
||||
}
|
||||
|
||||
static bool hasDetailsPointer(const QString &trimmedLine)
|
||||
{
|
||||
if (!trimmedLine.startsWith("*** "))
|
||||
return false;
|
||||
if (!trimmedLine.endsWith('^'))
|
||||
return false;
|
||||
return trimmedLine.contains('_');
|
||||
}
|
||||
|
||||
void KeilParser::stdOutput(const QString &line)
|
||||
{
|
||||
IOutputParser::stdOutput(line);
|
||||
|
||||
const QString lne = rightTrimmed(line);
|
||||
QString lne = rightTrimmed(line);
|
||||
|
||||
// Check for MSC51 compiler specific patterns.
|
||||
const bool parsed = parseMcs51WarningOrErrorDetailsMessage1(lne)
|
||||
@@ -228,9 +248,27 @@ void KeilParser::stdOutput(const QString &line)
|
||||
return;
|
||||
}
|
||||
|
||||
if (lne.startsWith(QLatin1Char(' '))) {
|
||||
amendDescription(lne);
|
||||
return;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
doFlush();
|
||||
@@ -241,6 +279,8 @@ void KeilParser::doFlush()
|
||||
if (m_lastTask.isNull())
|
||||
return;
|
||||
|
||||
amendDescription();
|
||||
|
||||
Task t = m_lastTask;
|
||||
m_lastTask.clear();
|
||||
emit addTask(t, m_lines, 1);
|
||||
@@ -425,6 +465,24 @@ void BareMetalPlugin::testKeilOutputParsers_data()
|
||||
categoryCompile))
|
||||
<< QString();
|
||||
|
||||
QTest::newRow("MCS51: Assembler details error")
|
||||
<< QString::fromLatin1("01AF Some detail\n"
|
||||
"*** ___^\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()
|
||||
<< (Tasks() << Task(Task::Error,
|
||||
QLatin1String("#A45: Some error\n"
|
||||
" Some detail\n"
|
||||
" ___^"),
|
||||
Utils::FilePath::fromUserInput(QLatin1String("d:\\foo.a51")),
|
||||
28,
|
||||
categoryCompile))
|
||||
<< QString();
|
||||
|
||||
// Compiler messages.
|
||||
QTest::newRow("MCS51: Compiler simple warning")
|
||||
<< QString::fromLatin1("*** WARNING C123 IN LINE 13 OF c:\\foo.c: Some warning")
|
||||
|
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
private:
|
||||
void newTask(const ProjectExplorer::Task &task);
|
||||
void amendDescription(const QString &desc);
|
||||
void amendDescription();
|
||||
|
||||
// ARM compiler specific parsers.
|
||||
bool parseArmWarningOrErrorDetailsMessage(const QString &lne);
|
||||
@@ -61,6 +61,7 @@ private:
|
||||
|
||||
ProjectExplorer::Task m_lastTask;
|
||||
int m_lines = 0;
|
||||
QStringList m_snippets;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
Reference in New Issue
Block a user