Commit ade1762a authored by Tobias Hunger's avatar Tobias Hunger
Browse files

Improve MSVC parser

 * Add unit test
 * Do not depend on magic error codes to decide whether we see an
   error or a warning. Instead us "error" or "warning" in the message

   Rationale: The heuristic that was used to decide on error/warning
   is just wrong going by the msvc documentation as it does not take the
   kind of error into account.

Task-number: QTCREATORBUG-2048
parent 04f0504b
......@@ -34,7 +34,7 @@ using namespace ProjectExplorer;
MsvcParser::MsvcParser()
{
m_compileRegExp.setPattern("^([^\\(]+)\\((\\d+)\\)+\\s:[^:\\d]+(\\d+):(.*)$");
m_compileRegExp.setPattern("^([^\\(]+)\\((\\d+)\\)+\\s:([^:\\d]+)\\s([A-Z]+(\\d+):.*)$");
m_compileRegExp.setMinimal(true);
m_linkRegExp.setPattern("^([^\\(]+)\\s:[^:\\d]+(\\d+):(.*)$");
m_linkRegExp.setMinimal(true);
......@@ -43,15 +43,25 @@ MsvcParser::MsvcParser()
void MsvcParser::stdOutput(const QString &line)
{
QString lne = line.trimmed();
if (m_compileRegExp.indexIn(lne) > -1 && m_compileRegExp.numCaptures() == 4) {
emit addTask(Task(toType(m_compileRegExp.cap(3).toInt()) /* task type */,
m_compileRegExp.cap(4) /* description */,
m_compileRegExp.cap(1) /* filename */,
m_compileRegExp.cap(2).toInt() /* linenumber */,
Constants::TASK_CATEGORY_COMPILE));
qDebug() << "LINE:" << lne;
if (m_compileRegExp.indexIn(lne) > -1 && m_compileRegExp.numCaptures() == 5) {
qDebug() << " MATCHED compileRegExp!";
Task task(Task::Unknown,
m_compileRegExp.cap(4) /* description */,
m_compileRegExp.cap(1) /* filename */,
m_compileRegExp.cap(2).toInt() /* linenumber */,
Constants::TASK_CATEGORY_COMPILE);
if (m_compileRegExp.cap(3) == QLatin1String(" warning"))
task.type = Task::Warning;
else if (m_compileRegExp.cap(3) == QLatin1String(" error"))
task.type = Task::Error;
else
task.type = toType(m_compileRegExp.cap(5).toInt());
addTask(task);
return;
}
if (m_linkRegExp.indexIn(lne) > -1 && m_linkRegExp.numCaptures() == 3) {
qDebug() << " MATCHED linkRegExp!";
QString fileName = m_linkRegExp.cap(1);
if (fileName.contains(QLatin1String("LINK"), Qt::CaseSensitive))
fileName.clear();
......@@ -68,6 +78,8 @@ void MsvcParser::stdOutput(const QString &line)
Task::TaskType MsvcParser::toType(int number)
{
// This is unfortunately not true for all possible kinds of errors, but better
// than not having a fallback at all!
if (number == 0)
return Task::Unknown;
else if (number > 4000 && number < 5000)
......@@ -75,3 +87,73 @@ Task::TaskType MsvcParser::toType(int number)
else
return Task::Error;
}
// Unit tests:
#ifdef WITH_TESTS
# include <QTest>
# include "projectexplorer.h"
# include "projectexplorer/outputparser_test.h"
using namespace ProjectExplorer::Internal;
void ProjectExplorerPlugin::testMsvcOutputParsers_data()
{
QTest::addColumn<QString>("input");
QTest::addColumn<OutputParserTester::Channel>("inputChannel");
QTest::addColumn<QString>("childStdOutLines");
QTest::addColumn<QString>("childStdErrLines");
QTest::addColumn<QList<ProjectExplorer::Task> >("tasks");
QTest::addColumn<QString>("outputLines");
QTest::newRow("pass-through stdout")
<< QString::fromLatin1("Sometext") << OutputParserTester::STDOUT
<< QString::fromLatin1("Sometext") << QString()
<< QList<ProjectExplorer::Task>()
<< QString();
QTest::newRow("pass-through stderr")
<< QString::fromLatin1("Sometext") << OutputParserTester::STDERR
<< QString() << QString::fromLatin1("Sometext")
<< QList<ProjectExplorer::Task>()
<< QString();
QTest::newRow("labeled error")
<< QString::fromLatin1("qmlstandalone\\main.cpp(54) : error C4716: 'findUnresolvedModule' : must return a value") << OutputParserTester::STDOUT
<< QString() << QString()
<< (QList<ProjectExplorer::Task>() << Task(Task::Error,
QLatin1String("C4716: 'findUnresolvedModule' : must return a value"),
QLatin1String("qmlstandalone\\main.cpp"), 54,
QLatin1String(ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)))
<< QString();
QTest::newRow("labeled warning")
<< QString::fromLatin1("x:\\src\\plugins\\projectexplorer\\msvcparser.cpp(69) : warning C4100: 'something' : unreferenced formal parameter") << OutputParserTester::STDOUT
<< QString() << QString()
<< (QList<ProjectExplorer::Task>() << Task(Task::Warning,
QLatin1String("C4100: 'something' : unreferenced formal parameter"),
QLatin1String("x:\\src\\plugins\\projectexplorer\\msvcparser.cpp"), 69,
QLatin1String(ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)))
<< QString();
}
void ProjectExplorerPlugin::testMsvcOutputParsers()
{
OutputParserTester testbench;
testbench.appendOutputParser(new MsvcParser);
QFETCH(QString, input);
QFETCH(OutputParserTester::Channel, inputChannel);
QFETCH(QList<Task>, tasks);
QFETCH(QString, childStdOutLines);
QFETCH(QString, childStdErrLines);
QFETCH(QString, outputLines);
testbench.testParsing(input, inputChannel,
tasks, childStdOutLines, childStdErrLines,
outputLines);
}
#endif
......@@ -205,6 +205,9 @@ private slots:
void testGnuMakeParserParsing();
void testGnuMakeParserTaskMangling_data();
void testGnuMakeParserTaskMangling();
void testMsvcOutputParsers_data();
void testMsvcOutputParsers();
#endif
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment