summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/projects/creator-projects-compilers.qdoc8
-rw-r--r--src/plugins/projectexplorer/customparser.cpp301
-rw-r--r--src/plugins/projectexplorer/customparser.h76
-rw-r--r--src/plugins/projectexplorer/customparserconfigdialog.cpp246
-rw-r--r--src/plugins/projectexplorer/customparserconfigdialog.h36
-rw-r--r--src/plugins/projectexplorer/customparserconfigdialog.ui576
-rw-r--r--src/plugins/projectexplorer/customtoolchain.cpp56
7 files changed, 960 insertions, 339 deletions
diff --git a/doc/src/projects/creator-projects-compilers.qdoc b/doc/src/projects/creator-projects-compilers.qdoc
index 62965634e4..1f1c94d25c 100644
--- a/doc/src/projects/creator-projects-compilers.qdoc
+++ b/doc/src/projects/creator-projects-compilers.qdoc
@@ -150,6 +150,10 @@
\image qtcreator-custom-parser.png
+ The custom error parser enables you to capture errors and warnings separately.
+ You can configure the error parser in the \uicontrol Error tab and the warning
+ parser in the \uicontrol Warning tab:
+
\list 1
\li In the \uicontrol {Error message capture pattern} field, specify
@@ -163,6 +167,10 @@
expression groups to \uicontrol {File name}, \uicontrol {Line number},
and \uicontrol Message.
+ \li In the \uicontrol {Capture Output Channels} field, specify whether
+ messages from standard output, standard error, or both channels
+ should be captured.
+
\li In the \uicontrol {Test} group, you can test how the message that
you enter in the \uicontrol {Error message} field is matched when
using the current settings.
diff --git a/src/plugins/projectexplorer/customparser.cpp b/src/plugins/projectexplorer/customparser.cpp
index 2ded638f01..d11780fc9f 100644
--- a/src/plugins/projectexplorer/customparser.cpp
+++ b/src/plugins/projectexplorer/customparser.cpp
@@ -40,115 +40,147 @@
using namespace Utils;
using namespace ProjectExplorer;
-CustomParserSettings::CustomParserSettings() :
- fileNameCap(1),
- lineNumberCap(2),
- messageCap(3)
-{ }
+bool CustomParserExpression::operator ==(const CustomParserExpression &other) const
+{
+ return pattern() == other.pattern() && fileNameCap() == other.fileNameCap()
+ && lineNumberCap() == other.lineNumberCap() && messageCap() == other.messageCap()
+ && channel() == other.channel() && example() == other.example();
+}
-bool CustomParserSettings::operator ==(const CustomParserSettings &other) const
+QString CustomParserExpression::pattern() const
{
- return errorPattern == other.errorPattern && fileNameCap == other.fileNameCap
- && lineNumberCap == other.lineNumberCap && messageCap == other.messageCap;
+ return m_regExp.pattern();
}
-CustomParser::CustomParser(const CustomParserSettings &settings) :
- m_parserChannels(ParseBothChannels)
+void ProjectExplorer::CustomParserExpression::setPattern(const QString &pattern)
{
- setObjectName(QLatin1String("CustomParser"));
+ m_regExp.setPattern(pattern);
+ QTC_CHECK(m_regExp.isValid());
+}
- setSettings(settings);
+CustomParserExpression::CustomParserChannel CustomParserExpression::channel() const
+{
+ return m_channel;
}
-CustomParser::~CustomParser()
+void CustomParserExpression::setChannel(CustomParserExpression::CustomParserChannel channel)
{
+ QTC_ASSERT(channel > ParseNoChannel && channel <= ParseBothChannels,
+ channel = ParseBothChannels);
+
+ m_channel = channel;
}
-void CustomParser::setErrorPattern(const QString &errorPattern)
+QString CustomParserExpression::example() const
{
- m_errorRegExp.setPattern(errorPattern);
- QTC_CHECK(m_errorRegExp.isValid());
+ return m_example;
}
-QString CustomParser::errorPattern() const
+void CustomParserExpression::setExample(const QString &example)
{
- return m_errorRegExp.pattern();
+ m_example = example;
}
-int CustomParser::lineNumberCap() const
+int CustomParserExpression::messageCap() const
+{
+ return m_messageCap;
+}
+
+void CustomParserExpression::setMessageCap(int messageCap)
+{
+ m_messageCap = messageCap;
+}
+
+int CustomParserExpression::lineNumberCap() const
{
return m_lineNumberCap;
}
-void CustomParser::setLineNumberCap(int lineNumberCap)
+void CustomParserExpression::setLineNumberCap(int lineNumberCap)
{
m_lineNumberCap = lineNumberCap;
}
-int CustomParser::fileNameCap() const
+int CustomParserExpression::fileNameCap() const
{
return m_fileNameCap;
}
-void CustomParser::setFileNameCap(int fileNameCap)
+void CustomParserExpression::setFileNameCap(int fileNameCap)
{
m_fileNameCap = fileNameCap;
}
-int CustomParser::messageCap() const
+bool CustomParserSettings::operator ==(const CustomParserSettings &other) const
{
- return m_messageCap;
+ return error == other.error && warning == other.warning;
}
-void CustomParser::setMessageCap(int messageCap)
+CustomParser::CustomParser(const CustomParserSettings &settings)
+{
+ setObjectName(QLatin1String("CustomParser"));
+
+ setSettings(settings);
+}
+
+CustomParser::~CustomParser()
{
- m_messageCap = messageCap;
}
void CustomParser::stdError(const QString &line)
{
- if (m_parserChannels & ParseStdErrChannel)
- if (parseLine(line))
- return;
+ if (parseLine(line, CustomParserExpression::ParseStdErrChannel))
+ return;
IOutputParser::stdError(line);
}
void CustomParser::stdOutput(const QString &line)
{
- if (m_parserChannels & ParseStdOutChannel)
- if (parseLine(line))
- return;
+ if (parseLine(line, CustomParserExpression::ParseStdOutChannel))
+ return;
IOutputParser::stdOutput(line);
}
void CustomParser::setSettings(const CustomParserSettings &settings)
{
- setErrorPattern(settings.errorPattern);
- setFileNameCap(settings.fileNameCap);
- setLineNumberCap(settings.lineNumberCap);
- setMessageCap(settings.messageCap);
+ m_error = settings.error;
+ m_warning = settings.warning;
}
-bool CustomParser::parseLine(const QString &rawLine)
+bool CustomParser::hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel,
+ const CustomParserExpression &expression, Task::TaskType taskType)
{
- if (m_errorRegExp.pattern().isEmpty())
+ if (!(channel & expression.channel()))
+ return false;
+
+ if (expression.pattern().isEmpty())
return false;
- const QRegularExpressionMatch match = m_errorRegExp.match(rawLine.trimmed());
+ const QRegularExpressionMatch match = expression.match(line);
if (!match.hasMatch())
return false;
- const FileName fileName = FileName::fromUserInput(match.captured(m_fileNameCap));
- const int lineNumber = match.captured(m_lineNumberCap).toInt();
- const QString message = match.captured(m_messageCap);
+ const FileName fileName = FileName::fromUserInput(match.captured(expression.fileNameCap()));
+ const int lineNumber = match.captured(expression.lineNumberCap()).toInt();
+ const QString message = match.captured(expression.messageCap());
- Task task = Task(Task::Error, message, fileName, lineNumber, Constants::TASK_CATEGORY_COMPILE);
+ const Task task = Task(taskType, message, fileName, lineNumber, Constants::TASK_CATEGORY_COMPILE);
emit addTask(task, 1);
return true;
}
+bool CustomParser::parseLine(const QString &rawLine, CustomParserExpression::CustomParserChannel channel)
+{
+ const QString line = rawLine.trimmed();
+
+ if (hasMatch(line, channel, m_error, Task::Error))
+ return true;
+
+ return hasMatch(line, channel, m_warning, Task::Warning);
+}
+
// Unit tests:
#ifdef WITH_TESTS
@@ -162,10 +194,16 @@ void ProjectExplorerPlugin::testCustomOutputParsers_data()
{
QTest::addColumn<QString>("input");
QTest::addColumn<OutputParserTester::Channel>("inputChannel");
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<int>("fileNameCap");
- QTest::addColumn<int>("lineNumberCap");
- QTest::addColumn<int>("messageCap");
+ QTest::addColumn<CustomParserExpression::CustomParserChannel>("filterErrorChannel");
+ QTest::addColumn<CustomParserExpression::CustomParserChannel>("filterWarningChannel");
+ QTest::addColumn<QString>("errorPattern");
+ QTest::addColumn<int>("errorFileNameCap");
+ QTest::addColumn<int>("errorLineNumberCap");
+ QTest::addColumn<int>("errorMessageCap");
+ QTest::addColumn<QString>("warningPattern");
+ QTest::addColumn<int>("warningFileNameCap");
+ QTest::addColumn<int>("warningLineNumberCap");
+ QTest::addColumn<int>("warningMessageCap");
QTest::addColumn<QString>("childStdOutLines");
QTest::addColumn<QString>("childStdErrLines");
QTest::addColumn<QList<Task> >("tasks");
@@ -175,11 +213,12 @@ void ProjectExplorerPlugin::testCustomOutputParsers_data()
const QString simplePattern = QLatin1String("^([a-z]+\\.[a-z]+):(\\d+): error: ([^\\s].+)$");
const FileName fileName = FileName::fromUserInput(QLatin1String("main.c"));
- QTest::newRow("empty pattern")
+ QTest::newRow("empty patterns")
<< QString::fromLatin1("Sometext")
<< OutputParserTester::STDOUT
- << QString::fromLatin1("")
- << 1 << 2 << 3
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << QString() << 1 << 2 << 3
+ << QString() << 1 << 2 << 3
<< QString::fromLatin1("Sometext\n") << QString()
<< QList<Task>()
<< QString();
@@ -187,8 +226,9 @@ void ProjectExplorerPlugin::testCustomOutputParsers_data()
QTest::newRow("pass-through stdout")
<< QString::fromLatin1("Sometext")
<< OutputParserTester::STDOUT
- << simplePattern
- << 1 << 2 << 3
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << simplePattern << 1 << 2 << 3
+ << QString() << 1 << 2 << 3
<< QString::fromLatin1("Sometext\n") << QString()
<< QList<Task>()
<< QString();
@@ -196,35 +236,59 @@ void ProjectExplorerPlugin::testCustomOutputParsers_data()
QTest::newRow("pass-through stderr")
<< QString::fromLatin1("Sometext")
<< OutputParserTester::STDERR
- << simplePattern
- << 1 << 2 << 3
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << simplePattern << 1 << 2 << 3
+ << QString() << 1 << 2 << 3
<< QString() << QString::fromLatin1("Sometext\n")
<< QList<Task>()
<< QString();
const QString simpleError = QLatin1String("main.c:9: error: `sfasdf' undeclared (first use this function)");
+ const QString simpleErrorPassThrough = simpleError + QLatin1Char('\n');
const QString message = QLatin1String("`sfasdf' undeclared (first use this function)");
QTest::newRow("simple error")
<< simpleError
<< OutputParserTester::STDERR
- << simplePattern
- << 1 << 2 << 3
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << simplePattern << 1 << 2 << 3
+ << QString() << 0 << 0 << 0
<< QString() << QString()
<< (QList<Task>()
<< Task(Task::Error, message, fileName, 9, categoryCompile)
)
<< QString();
- const QString simpleError2 = QLatin1String("Error: main.c:19: `sfasdf' undeclared (first use this function)");
- const QString simplePattern2 = QLatin1String("^Error: ([a-z]+\\.[a-z]+):(\\d+): ([^\\s].+)$");
+ QTest::newRow("simple error on wrong channel")
+ << simpleError
+ << OutputParserTester::STDOUT
+ << CustomParserExpression::ParseStdErrChannel << CustomParserExpression::ParseBothChannels
+ << simplePattern << 1 << 2 << 3
+ << QString() << 0 << 0 << 0
+ << simpleErrorPassThrough << QString()
+ << QList<Task>()
+ << QString();
+
+ QTest::newRow("simple error on other wrong channel")
+ << simpleError
+ << OutputParserTester::STDERR
+ << CustomParserExpression::ParseStdOutChannel << CustomParserExpression::ParseBothChannels
+ << simplePattern << 1 << 2 << 3
+ << QString() << 0 << 0 << 0
+ << QString() << simpleErrorPassThrough
+ << QList<Task>()
+ << QString();
+
+ const QString simpleError2 = QLatin1String("Error: Line 19 in main.c: `sfasdf' undeclared (first use this function)");
+ const QString simplePattern2 = QLatin1String("^Error: Line (\\d+) in ([a-z]+\\.[a-z]+): ([^\\s].+)$");
const int lineNumber2 = 19;
QTest::newRow("another simple error on stderr")
<< simpleError2
<< OutputParserTester::STDERR
- << simplePattern2
- << 1 << 2 << 3
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << simplePattern2 << 2 << 1 << 3
+ << QString() << 1 << 2 << 3
<< QString() << QString()
<< (QList<Task>()
<< Task(Task::Error, message, fileName, lineNumber2, categoryCompile)
@@ -234,14 +298,91 @@ void ProjectExplorerPlugin::testCustomOutputParsers_data()
QTest::newRow("another simple error on stdout")
<< simpleError2
<< OutputParserTester::STDOUT
- << simplePattern2
- << 1 << 2 << 3
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << simplePattern2 << 2 << 1 << 3
+ << QString() << 1 << 2 << 3
<< QString() << QString()
<< (QList<Task>()
<< Task(Task::Error, message, fileName, lineNumber2, categoryCompile)
)
<< QString();
+ const QString simpleWarningPattern = QLatin1String("^([a-z]+\\.[a-z]+):(\\d+): warning: ([^\\s].+)$");
+ const QString simpleWarning = QLatin1String("main.c:1234: warning: `helloWorld' declared but not used");
+ const QString warningMessage = QLatin1String("`helloWorld' declared but not used");
+
+ QTest::newRow("simple warning")
+ << simpleWarning
+ << OutputParserTester::STDERR
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << QString() << 1 << 2 << 3
+ << simpleWarningPattern << 1 << 2 << 3
+ << QString() << QString()
+ << (QList<Task>()
+ << Task(Task::Warning, warningMessage, fileName, 1234, categoryCompile)
+ )
+ << QString();
+
+ const QString simpleWarning2 = QLatin1String("Warning: `helloWorld' declared but not used (main.c:19)");
+ const QString simpleWarningPassThrough2 = simpleWarning2 + QLatin1Char('\n');
+ const QString simpleWarningPattern2 = QLatin1String("^Warning: (.*) \\(([a-z]+\\.[a-z]+):(\\d+)\\)$");
+
+ QTest::newRow("another simple warning on stdout")
+ << simpleWarning2
+ << OutputParserTester::STDOUT
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseStdOutChannel
+ << simplePattern2 << 1 << 2 << 3
+ << simpleWarningPattern2 << 2 << 3 << 1
+ << QString() << QString()
+ << (QList<Task>()
+ << Task(Task::Warning, warningMessage, fileName, lineNumber2, categoryCompile)
+ )
+ << QString();
+
+ QTest::newRow("warning on wrong channel")
+ << simpleWarning2
+ << OutputParserTester::STDOUT
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseStdErrChannel
+ << QString() << 1 << 2 << 3
+ << simpleWarningPattern2 << 2 << 3 << 1
+ << simpleWarningPassThrough2 << QString()
+ << QList<Task>()
+ << QString();
+
+ QTest::newRow("warning on other wrong channel")
+ << simpleWarning2
+ << OutputParserTester::STDERR
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseStdOutChannel
+ << QString() << 1 << 2 << 3
+ << simpleWarningPattern2 << 2 << 3 << 1
+ << QString() << simpleWarningPassThrough2
+ << QList<Task>()
+ << QString();
+
+ QTest::newRow("error and *warning*")
+ << simpleWarning
+ << OutputParserTester::STDERR
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << simplePattern << 1 << 2 << 3
+ << simpleWarningPattern << 1 << 2 << 3
+ << QString() << QString()
+ << (QList<Task>()
+ << Task(Task::Warning, warningMessage, fileName, 1234, categoryCompile)
+ )
+ << QString();
+
+ QTest::newRow("*error* when equal pattern")
+ << simpleError
+ << OutputParserTester::STDERR
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << simplePattern << 1 << 2 << 3
+ << simplePattern << 1 << 2 << 3
+ << QString() << QString()
+ << (QList<Task>()
+ << Task(Task::Error, message, fileName, 9, categoryCompile)
+ )
+ << QString();
+
const QString unitTestError = QLatin1String("../LedDriver/LedDriverTest.c:63: FAIL: Expected 0x0080 Was 0xffff");
const FileName unitTestFileName = FileName::fromUserInput(QLatin1String("../LedDriver/LedDriverTest.c"));
const QString unitTestMessage = QLatin1String("Expected 0x0080 Was 0xffff");
@@ -251,8 +392,9 @@ void ProjectExplorerPlugin::testCustomOutputParsers_data()
QTest::newRow("unit test error")
<< unitTestError
<< OutputParserTester::STDOUT
- << unitTestPattern
- << 1 << 2 << 3
+ << CustomParserExpression::ParseBothChannels << CustomParserExpression::ParseBothChannels
+ << unitTestPattern << 1 << 2 << 3
+ << QString() << 1 << 2 << 3
<< QString() << QString()
<< (QList<Task>()
<< Task(Task::Error, unitTestMessage, unitTestFileName, unitTestLineNumber, categoryCompile)
@@ -264,20 +406,35 @@ void ProjectExplorerPlugin::testCustomOutputParsers()
{
QFETCH(QString, input);
QFETCH(OutputParserTester::Channel, inputChannel);
- QFETCH(QString, pattern);
- QFETCH(int, fileNameCap);
- QFETCH(int, lineNumberCap);
- QFETCH(int, messageCap);
+ QFETCH(CustomParserExpression::CustomParserChannel, filterErrorChannel);
+ QFETCH(CustomParserExpression::CustomParserChannel, filterWarningChannel);
+ QFETCH(QString, errorPattern);
+ QFETCH(int, errorFileNameCap);
+ QFETCH(int, errorLineNumberCap);
+ QFETCH(int, errorMessageCap);
+ QFETCH(QString, warningPattern);
+ QFETCH(int, warningFileNameCap);
+ QFETCH(int, warningLineNumberCap);
+ QFETCH(int, warningMessageCap);
QFETCH(QString, childStdOutLines);
QFETCH(QString, childStdErrLines);
QFETCH(QList<Task>, tasks);
QFETCH(QString, outputLines);
+ CustomParserSettings settings;
+ settings.error.setPattern(errorPattern);
+ settings.error.setFileNameCap(errorFileNameCap);
+ settings.error.setLineNumberCap(errorLineNumberCap);
+ settings.error.setMessageCap(errorMessageCap);
+ settings.error.setChannel(filterErrorChannel);
+ settings.warning.setPattern(warningPattern);
+ settings.warning.setFileNameCap(warningFileNameCap);
+ settings.warning.setLineNumberCap(warningLineNumberCap);
+ settings.warning.setMessageCap(warningMessageCap);
+ settings.warning.setChannel(filterWarningChannel);
+
CustomParser *parser = new CustomParser;
- parser->setErrorPattern(pattern);
- parser->setFileNameCap(fileNameCap);
- parser->setLineNumberCap(lineNumberCap);
- parser->setMessageCap(messageCap);
+ parser->setSettings(settings);
OutputParserTester testbench;
testbench.appendOutputParser(parser);
diff --git a/src/plugins/projectexplorer/customparser.h b/src/plugins/projectexplorer/customparser.h
index 235ad5219b..82e3b3ed92 100644
--- a/src/plugins/projectexplorer/customparser.h
+++ b/src/plugins/projectexplorer/customparser.h
@@ -39,39 +39,28 @@
namespace ProjectExplorer {
-class CustomParserSettings
-{
-public:
- CustomParserSettings();
-
- bool operator ==(const CustomParserSettings &other) const;
- bool operator !=(const CustomParserSettings &other) const { return !operator==(other); }
-
- QString errorPattern;
- int fileNameCap;
- int lineNumberCap;
- int messageCap;
-};
-
-class CustomParser : public ProjectExplorer::IOutputParser
+class CustomParserExpression
{
public:
- enum CustomParserChannels {
+ enum CustomParserChannel {
ParseNoChannel = 0,
ParseStdErrChannel = 1,
ParseStdOutChannel = 2,
ParseBothChannels = 3
};
- CustomParser(const CustomParserSettings &settings = CustomParserSettings());
- ~CustomParser();
- void stdError(const QString &line);
- void stdOutput(const QString &line);
+ bool operator ==(const CustomParserExpression &other) const;
- void setSettings(const CustomParserSettings &settings);
+ QString pattern() const;
+ void setPattern(const QString &pattern);
+ QRegularExpressionMatch match(const QString &line) const { return m_regExp.match(line); }
+
+ CustomParserExpression::CustomParserChannel channel() const;
+ void setChannel(CustomParserExpression::CustomParserChannel channel);
+
+ QString example() const;
+ void setExample(const QString &example);
- void setErrorPattern(const QString &errorPattern);
- QString errorPattern() const;
int fileNameCap() const;
void setFileNameCap(int fileNameCap);
int lineNumberCap() const;
@@ -80,16 +69,45 @@ public:
void setMessageCap(int messageCap);
private:
- bool parseLine(const QString &rawLine);
+ QRegularExpression m_regExp;
+ CustomParserExpression::CustomParserChannel m_channel = ParseBothChannels;
+ QString m_example;
+ int m_fileNameCap = 1;
+ int m_lineNumberCap = 2;
+ int m_messageCap = 3;
+};
+
+class CustomParserSettings
+{
+public:
+ bool operator ==(const CustomParserSettings &other) const;
+ bool operator !=(const CustomParserSettings &other) const { return !operator==(other); }
- QRegularExpression m_errorRegExp;
- int m_fileNameCap;
- int m_lineNumberCap;
- int m_messageCap;
+ CustomParserExpression error;
+ CustomParserExpression warning;
+};
- CustomParserChannels m_parserChannels;
+class CustomParser : public ProjectExplorer::IOutputParser
+{
+public:
+ CustomParser(const CustomParserSettings &settings = CustomParserSettings());
+ ~CustomParser();
+ void stdError(const QString &line);
+ void stdOutput(const QString &line);
+
+ void setSettings(const CustomParserSettings &settings);
+
+private:
+ bool hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel,
+ const CustomParserExpression &expression, Task::TaskType taskType);
+ bool parseLine(const QString &rawLine, CustomParserExpression::CustomParserChannel channel);
+
+ CustomParserExpression m_error;
+ CustomParserExpression m_warning;
};
} // namespace ProjectExplorer
+Q_DECLARE_METATYPE(ProjectExplorer::CustomParserExpression::CustomParserChannel);
+
#endif // CUSTOMPARSER_H
diff --git a/src/plugins/projectexplorer/customparserconfigdialog.cpp b/src/plugins/projectexplorer/customparserconfigdialog.cpp
index 667b38bc68..ecae3f7e48 100644
--- a/src/plugins/projectexplorer/customparserconfigdialog.cpp
+++ b/src/plugins/projectexplorer/customparserconfigdialog.cpp
@@ -31,6 +31,7 @@
#include "customparserconfigdialog.h"
#include "ui_customparserconfigdialog.h"
+#include <QLineEdit>
#include <QPushButton>
#include <QRegularExpression>
@@ -44,10 +45,15 @@ CustomParserConfigDialog::CustomParserConfigDialog(QDialog *parent) :
ui->setupUi(this);
connect(ui->errorPattern, SIGNAL(textChanged(QString)), this, SLOT(changed()));
- connect(ui->errorMessage, SIGNAL(textChanged(QString)), this, SLOT(changed()));
- connect(ui->fileNameCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
- connect(ui->lineNumberCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
- connect(ui->messageCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+ connect(ui->errorOutputMessage, SIGNAL(textChanged(QString)), this, SLOT(changed()));
+ connect(ui->errorFileNameCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+ connect(ui->errorLineNumberCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+ connect(ui->errorMessageCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+ connect(ui->warningPattern, SIGNAL(textChanged(QString)), this, SLOT(changed()));
+ connect(ui->warningOutputMessage, SIGNAL(textChanged(QString)), this, SLOT(changed()));
+ connect(ui->warningFileNameCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+ connect(ui->warningLineNumberCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+ connect(ui->warningMessageCap, SIGNAL(valueChanged(int)), this, SLOT(changed()));
changed();
m_dirty = false;
@@ -60,33 +66,58 @@ CustomParserConfigDialog::~CustomParserConfigDialog()
void CustomParserConfigDialog::setExampleSettings()
{
- setErrorPattern(QLatin1String("#error (.*):(\\d+): (.*)$"));
- setFileNameCap(1);
- setLineNumberCap(2);
- setMessageCap(3);
- ui->errorMessage->setText(QLatin1String("#error /home/user/src/test.c:891: Unknown identifier `test`"));
+ setErrorPattern(QLatin1String("#error (.*):(\\d+): (.*)"));
+ setErrorFileNameCap(1);
+ setErrorLineNumberCap(2);
+ setErrorMessageCap(3);
+ setErrorChannel(CustomParserExpression::ParseBothChannels);
+ setWarningPattern(QLatin1String("#warning (.*):(\\d+): (.*)"));
+ setWarningFileNameCap(1);
+ setWarningLineNumberCap(2);
+ setWarningMessageCap(3);
+ setWarningChannel(CustomParserExpression::ParseBothChannels);
+ ui->errorOutputMessage->setText(
+ QLatin1String("#error /home/user/src/test.c:891: Unknown identifier `test`"));
+ ui->warningOutputMessage->setText(
+ QLatin1String("#warning /home/user/src/test.c:49: Unreferenced variable `test`"));
}
void CustomParserConfigDialog::setSettings(const CustomParserSettings &settings)
{
- if (settings.errorPattern.isEmpty()) {
+ if (settings.error.pattern().isEmpty() && settings.warning.pattern().isEmpty()) {
setExampleSettings();
return;
}
- setErrorPattern(settings.errorPattern);
- setFileNameCap(settings.fileNameCap);
- setLineNumberCap(settings.lineNumberCap);
- setMessageCap(settings.messageCap);
+ setErrorPattern(settings.error.pattern());
+ setErrorFileNameCap(settings.error.fileNameCap());
+ setErrorLineNumberCap(settings.error.lineNumberCap());
+ setErrorMessageCap(settings.error.messageCap());
+ setErrorChannel(settings.error.channel());
+ setErrorExample(settings.error.example());
+ setWarningPattern(settings.warning.pattern());
+ setWarningFileNameCap(settings.warning.fileNameCap());
+ setWarningLineNumberCap(settings.warning.lineNumberCap());
+ setWarningMessageCap(settings.warning.messageCap());
+ setWarningChannel(settings.warning.channel());
+ setWarningExample(settings.warning.example());
}
CustomParserSettings CustomParserConfigDialog::settings() const
{
CustomParserSettings result;
- result.errorPattern = errorPattern();
- result.fileNameCap = fileNameCap();
- result.lineNumberCap = lineNumberCap();
- result.messageCap = messageCap();
+ result.error.setPattern(errorPattern());
+ result.error.setFileNameCap(errorFileNameCap());
+ result.error.setLineNumberCap(errorLineNumberCap());
+ result.error.setMessageCap(errorMessageCap());
+ result.error.setChannel(errorChannel());
+ result.error.setExample(errorExample());
+ result.warning.setPattern(warningPattern());
+ result.warning.setFileNameCap(warningFileNameCap());
+ result.warning.setLineNumberCap(warningLineNumberCap());
+ result.warning.setMessageCap(warningMessageCap());
+ result.warning.setChannel(warningChannel());
+ result.warning.setExample(warningExample());
return result;
}
@@ -100,34 +131,128 @@ QString CustomParserConfigDialog::errorPattern() const
return ui->errorPattern->text();
}
-void CustomParserConfigDialog::setFileNameCap(int fileNameCap)
+void CustomParserConfigDialog::setErrorFileNameCap(int fileNameCap)
{
- ui->fileNameCap->setValue(fileNameCap);
+ ui->errorFileNameCap->setValue(fileNameCap);
}
-int CustomParserConfigDialog::fileNameCap() const
+int CustomParserConfigDialog::errorFileNameCap() const
{
- return ui->fileNameCap->value();
+ return ui->errorFileNameCap->value();
}
-void CustomParserConfigDialog::setLineNumberCap(int lineNumberCap)
+void CustomParserConfigDialog::setErrorLineNumberCap(int lineNumberCap)
{
- ui->lineNumberCap->setValue(lineNumberCap);
+ ui->errorLineNumberCap->setValue(lineNumberCap);
}
-int CustomParserConfigDialog::lineNumberCap() const
+int CustomParserConfigDialog::errorLineNumberCap() const
{
- return ui->lineNumberCap->value();
+ return ui->errorLineNumberCap->value();
}
-void CustomParserConfigDialog::setMessageCap(int messageCap)
+void CustomParserConfigDialog::setErrorMessageCap(int messageCap)
{
- ui->messageCap->setValue(messageCap);
+ ui->errorMessageCap->setValue(messageCap);
}
-int CustomParserConfigDialog::messageCap() const
+int CustomParserConfigDialog::errorMessageCap() const
{
- return ui->messageCap->value();
+ return ui->errorMessageCap->value();
+}
+
+void CustomParserConfigDialog::setErrorChannel(CustomParserExpression::CustomParserChannel errorChannel)
+{
+ ui->errorStdErrChannel->setChecked(
+ errorChannel & static_cast<int>(CustomParserExpression::ParseStdErrChannel));
+ ui->errorStdOutChannel->setChecked(
+ errorChannel & static_cast<int>(CustomParserExpression::ParseStdOutChannel));
+}
+
+CustomParserExpression::CustomParserChannel CustomParserConfigDialog::errorChannel() const
+{
+ if (ui->errorStdErrChannel->isChecked() && !ui->errorStdOutChannel->isChecked())
+ return CustomParserExpression::ParseStdErrChannel;
+ if (ui->errorStdOutChannel->isChecked() && !ui->errorStdErrChannel->isChecked())
+ return CustomParserExpression::ParseStdOutChannel;
+ return CustomParserExpression::ParseBothChannels;
+}
+
+void CustomParserConfigDialog::setErrorExample(const QString &errorExample)
+{
+ ui->errorOutputMessage->setText(errorExample);
+}
+
+QString CustomParserConfigDialog::errorExample() const
+{
+ return ui->errorOutputMessage->text();
+}
+
+void CustomParserConfigDialog::setWarningPattern(const QString &warningPattern)
+{
+ ui->warningPattern->setText(warningPattern);
+}
+
+QString CustomParserConfigDialog::warningPattern() const
+{
+ return ui->warningPattern->text();
+}
+
+void CustomParserConfigDialog::setWarningFileNameCap(int warningFileNameCap)
+{
+ ui->warningFileNameCap->setValue(warningFileNameCap);
+}
+
+int CustomParserConfigDialog::warningFileNameCap() const
+{
+ return ui->warningFileNameCap->value();
+}
+
+void CustomParserConfigDialog::setWarningLineNumberCap(int warningLineNumberCap)
+{
+ ui->warningLineNumberCap->setValue(warningLineNumberCap);
+}
+
+int CustomParserConfigDialog::warningLineNumberCap() const
+{
+ return ui->warningLineNumberCap->value();
+}
+
+void CustomParserConfigDialog::setWarningMessageCap(int warningMessageCap)
+{
+ ui->warningMessageCap->setValue(warningMessageCap);
+}
+
+int CustomParserConfigDialog::warningMessageCap() const
+{
+ return ui->warningMessageCap->value();
+}
+
+void CustomParserConfigDialog::setWarningChannel(CustomParserExpression::CustomParserChannel warningChannel)
+{
+ ui->warningStdErrChannel->setChecked(
+ warningChannel & static_cast<int>(CustomParserExpression::ParseStdErrChannel));
+ ui->warningStdOutChannel->setChecked(
+ warningChannel & static_cast<int>(CustomParserExpression::ParseStdOutChannel));
+}
+
+CustomParserExpression::CustomParserChannel CustomParserConfigDialog::warningChannel() const
+{
+ if (ui->warningStdErrChannel->isChecked() && !ui->warningStdOutChannel->isChecked())
+ return CustomParserExpression::ParseStdErrChannel;
+ if (ui->warningStdOutChannel->isChecked() && !ui->warningStdErrChannel->isChecked())
+ return CustomParserExpression::ParseStdOutChannel;
+ return CustomParserExpression::ParseBothChannels;
+}
+
+void CustomParserConfigDialog::setWarningExample(const QString &warningExample)
+{
+ ui->warningOutputMessage->setText(warningExample);
+}
+
+QString CustomParserConfigDialog::warningExample() const
+{
+ return ui->warningOutputMessage->text();
}
bool CustomParserConfigDialog::isDirty() const
@@ -135,37 +260,60 @@ bool CustomParserConfigDialog::isDirty() const
return m_dirty;
}
-void CustomParserConfigDialog::changed()
+bool CustomParserConfigDialog::checkPattern(QLineEdit *pattern, const QString &outputText,
+ QString *errorMessage, QRegularExpressionMatch *match)
{
QRegularExpression rx;
- rx.setPattern(ui->errorPattern->text());
+ rx.setPattern(pattern->text());
QPalette palette;
palette.setColor(QPalette::Text, rx.isValid() ? Qt::black : Qt::red);
- ui->errorPattern->setPalette(palette);
- ui->errorPattern->setToolTip(rx.isValid() ? QString() : rx.errorString());
+ pattern->setPalette(palette);
+ pattern->setToolTip(rx.isValid() ? QString() : rx.errorString());
- const QRegularExpressionMatch match = rx.match(ui->errorMessage->text());
- if (rx.pattern().isEmpty() || !rx.isValid() || !match.hasMatch()) {
- QString error = QLatin1String("<font color=\"red\">") + tr("Not applicable:") + QLatin1Char(' ');
+ *match = rx.match(outputText);
+ if (rx.pattern().isEmpty() || !rx.isValid() || !match->hasMatch()) {
+ *errorMessage = QLatin1String("<font color=\"red\">") + tr("Not applicable:") + QLatin1Char(' ');
if (rx.pattern().isEmpty())
- error += tr("Pattern is empty.");
+ *errorMessage += tr("Pattern is empty.");
else if (!rx.isValid())
- error += rx.errorString();
+ *errorMessage += rx.errorString();
+ else if (outputText.isEmpty())
+ *errorMessage += tr("No message given.");
else
- error += tr("Pattern does not match the message.");
+ *errorMessage += tr("Pattern does not match the message.");
- ui->fileNameTest->setText(error);
- ui->lineNumberTest->setText(error);
- ui->messageTest->setText(error);
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
- return;
+ return false;
+ }
+
+ errorMessage->clear();
+ return true;
+}
+
+void CustomParserConfigDialog::changed()
+{
+ QRegularExpressionMatch match;
+ QString errorMessage;
+
+ if (checkPattern(ui->errorPattern, ui->errorOutputMessage->text(), &errorMessage, &match)) {
+ ui->errorFileNameTest->setText(match.captured(ui->errorFileNameCap->value()));
+ ui->errorLineNumberTest->setText(match.captured(ui->errorLineNumberCap->value()));
+ ui->errorMessageTest->setText(match.captured(ui->errorMessageCap->value()));
+ } else {
+ ui->errorFileNameTest->setText(errorMessage);
+ ui->errorLineNumberTest->setText(errorMessage);
+ ui->errorMessageTest->setText(errorMessage);
}
- ui->fileNameTest->setText(match.captured(ui->fileNameCap->value()));
- ui->lineNumberTest->setText(match.captured(ui->lineNumberCap->value()));
- ui->messageTest->setText(match.captured(ui->messageCap->value()));
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
+ if (checkPattern(ui->warningPattern, ui->warningOutputMessage->text(), &errorMessage, &match)) {
+ ui->warningFileNameTest->setText(match.captured(ui->warningFileNameCap->value()));
+ ui->warningLineNumberTest->setText(match.captured(ui->warningLineNumberCap->value()));
+ ui->warningMessageTest->setText(match.captured(ui->warningMessageCap->value()));
+ } else {
+ ui->warningFileNameTest->setText(errorMessage);
+ ui->warningLineNumberTest->setText(errorMessage);
+ ui->warningMessageTest->setText(errorMessage);
+ }
m_dirty = true;
}
diff --git a/src/plugins/projectexplorer/customparserconfigdialog.h b/src/plugins/projectexplorer/customparserconfigdialog.h
index 8c8118badc..b272ff5204 100644
--- a/src/plugins/projectexplorer/customparserconfigdialog.h
+++ b/src/plugins/projectexplorer/customparserconfigdialog.h
@@ -35,6 +35,10 @@
#include <QDialog>
+QT_BEGIN_NAMESPACE
+class QLineEdit;
+QT_END_NAMESPACE
+
namespace ProjectExplorer {
namespace Internal {
@@ -53,18 +57,38 @@ public:
CustomParserSettings settings() const;
void setErrorPattern(const QString &errorPattern);
QString errorPattern() const;
- void setFileNameCap(int fileNameCap);
- int fileNameCap() const;
- void setLineNumberCap(int lineNumberCap);
- int lineNumberCap() const;
- void setMessageCap(int messageCap);
- int messageCap() const;
+ void setErrorFileNameCap(int errorFileNameCap);
+ int errorFileNameCap() const;
+ void setErrorLineNumberCap(int errorLineNumberCap);
+ int errorLineNumberCap() const;
+ void setErrorMessageCap(int errorMessageCap);
+ int errorMessageCap() const;
+ void setErrorChannel(CustomParserExpression::CustomParserChannel errorChannel);
+ CustomParserExpression::CustomParserChannel errorChannel() const;
+ void setErrorExample(const QString &errorExample);
+ QString errorExample() const;
+ void setWarningPattern(const QString &warningPattern);
+ QString warningPattern() const;
+ void setWarningFileNameCap(int warningFileNameCap);
+ int warningFileNameCap() const;
+ void setWarningLineNumberCap(int warningLineNumberCap);
+ int warningLineNumberCap() const;
+ void setWarningMessageCap(int warningMessageCap);
+ int warningMessageCap() const;
+ void setWarningChannel(CustomParserExpression::CustomParserChannel warningChannel);
+ CustomParserExpression::CustomParserChannel warningChannel() const;
+ void setWarningExample(const QString &warningExample);
+ QString warningExample() const;
+
bool isDirty() const;
private slots:
void changed();
private:
+ bool checkPattern(QLineEdit *pattern, const QString &outputText,
+ QString *errorMessage, QRegularExpressionMatch *match);
+
Ui::CustomParserConfigDialog *ui;
bool m_dirty;
};
diff --git a/src/plugins/projectexplorer/customparserconfigdialog.ui b/src/plugins/projectexplorer/customparserconfigdialog.ui
index 86f8bde762..b79dbe3285 100644
--- a/src/plugins/projectexplorer/customparserconfigdialog.ui
+++ b/src/plugins/projectexplorer/customparserconfigdialog.ui
@@ -6,188 +6,414 @@
<rect>
<x>0</x>
<y>0</y>
- <width>470</width>
- <height>368</height>
+ <width>516</width>
+ <height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>Custom Parser</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>&amp;Error message capture pattern:</string>
- </property>
- <property name="buddy">
- <cstring>errorPattern</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="errorPattern">
- <property name="text">
- <string>#error (.*):(\d+): (.*)$</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QGroupBox" name="capturePositionsGroup">
- <property name="title">
- <string>Capture Positions</string>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
</property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>&amp;File name:</string>
- </property>
- <property name="buddy">
- <cstring>fileNameCap</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>&amp;Line number:</string>
- </property>
- <property name="buddy">
- <cstring>lineNumberCap</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>&amp;Message:</string>
- </property>
- <property name="buddy">
- <cstring>messageCap</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QSpinBox" name="fileNameCap">
- <property name="maximum">
- <number>9</number>
- </property>
- <property name="value">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="lineNumberCap">
- <property name="maximum">
- <number>9</number>
- </property>
- <property name="value">
- <number>2</number>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QSpinBox" name="messageCap">
- <property name="maximum">
- <number>9</number>
- </property>
- <property name="value">
- <number>3</number>
- </property>
- </widget>
- </item>
- </layout>
+ <widget class="QWidget" name="tabError">
+ <attribute name="title">
+ <string>Error</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>&amp;Error message capture pattern:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorPattern</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="errorPattern">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="errorCapturePositionsGroup">
+ <property name="title">
+ <string>Capture Positions</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>&amp;File name:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorFileNameCap</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>&amp;Line number:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorLineNumberCap</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>&amp;Message:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorMessageCap</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QSpinBox" name="errorFileNameCap">
+ <property name="maximum">
+ <number>9</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="errorLineNumberCap">
+ <property name="maximum">
+ <number>9</number>
+ </property>
+ <property name="value">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QSpinBox" name="errorMessageCap">
+ <property name="maximum">
+ <number>9</number>
+ </property>
+ <property name="value">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="errorCaptureChannelsGroup">
+ <property name="title">
+ <string>Capture Output Channels</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QCheckBox" name="errorStdOutChannel">
+ <property name="text">
+ <string>Standard output</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="errorStdErrChannel">
+ <property name="text">
+ <string>Standard error</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="errorTestGroup">
+ <property name="title">
+ <string>Test</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>E&amp;rror message:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorOutputMessage</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="errorOutputMessage">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>File name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="errorFileNameTest">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Line number:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="errorLineNumberTest">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Message:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="errorMessageTest">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabWarning">
+ <attribute name="title">
+ <string>Warning</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Warning message capture pattern:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="warningPattern">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="warningCapturePositionsGroup">
+ <property name="title">
+ <string>Capture Positions</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="2" column="2">
+ <widget class="QSpinBox" name="warningLineNumberCap">
+ <property name="maximum">
+ <number>9</number>
+ </property>
+ <property name="value">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4">
+ <widget class="QSpinBox" name="warningMessageCap">
+ <property name="maximum">
+ <number>9</number>
+ </property>
+ <property name="value">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>&amp;Line number:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorLineNumberCap</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>&amp;File name:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorFileNameCap</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QSpinBox" name="warningFileNameCap">
+ <property name="maximum">
+ <number>9</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>&amp;Message:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorMessageCap</cstring>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="warningOutputChannelsGroup">
+ <property name="title">
+ <string>Capture Output Channels</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="warningStdOutChannel">
+ <property name="text">
+ <string>Standard output</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="warningStdErrChannel">
+ <property name="text">
+ <string>Standard error</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="warningTestGroup">
+ <property name="title">
+ <string>Test</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Warning message:</string>
+ </property>
+ <property name="buddy">
+ <cstring>errorOutputMessage</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="warningOutputMessage">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>File name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="warningFileNameTest">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string>Line number:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="warningLineNumberTest">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_17">
+ <property name="text">
+ <string>Message:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="warningMessageTest">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
- <widget class="QGroupBox" name="testGroup">
- <property name="title">
- <string>Test</string>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>E&amp;rror message:</string>
- </property>
- <property name="buddy">
- <cstring>errorMessage</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="errorMessage">
- <property name="text">
- <string>#error /home/user/src/test.c:891: Unknown identifier `test`</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>File name:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="fileNameTest">
- <property name="text">
- <string>TextLabel</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>Line number:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="lineNumberTest">
- <property name="text">
- <string>TextLabel</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>Message:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="messageTest">
- <property name="text">
- <string>TextLabel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>22</height>
+ </size>
+ </property>
+ </spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
@@ -200,10 +426,10 @@
</widget>
<tabstops>
<tabstop>errorPattern</tabstop>
- <tabstop>fileNameCap</tabstop>
- <tabstop>lineNumberCap</tabstop>
- <tabstop>messageCap</tabstop>
- <tabstop>errorMessage</tabstop>
+ <tabstop>errorFileNameCap</tabstop>
+ <tabstop>errorLineNumberCap</tabstop>
+ <tabstop>errorMessageCap</tabstop>
+ <tabstop>errorOutputMessage</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp
index b2a71d27a9..ccec636c09 100644
--- a/src/plugins/projectexplorer/customtoolchain.cpp
+++ b/src/plugins/projectexplorer/customtoolchain.cpp
@@ -69,6 +69,19 @@ static const char cxx11FlagsKeyC[] = "ProjectExplorer.CustomToolChain.Cxx11Flags
static const char mkspecsKeyC[] = "ProjectExplorer.CustomToolChain.Mkspecs";
static const char outputParserKeyC[] = "ProjectExplorer.CustomToolChain.OutputParser";
static const char errorPatternKeyC[] = "ProjectExplorer.CustomToolChain.ErrorPattern";
+static const char errorLineNumberCapKeyC[] = "ProjectExplorer.CustomToolChain.ErrorLineNumberCap";
+static const char errorFileNameCapKeyC[] = "ProjectExplorer.CustomToolChain.ErrorFileNameCap";
+static const char errorMessageCapKeyC[] = "ProjectExplorer.CustomToolChain.ErrorMessageCap";
+static const char errorChannelKeyC[] = "ProjectExplorer.CustomToolChain.ErrorChannel";
+static const char errorExampleKeyC[] = "ProjectExplorer.CustomToolChain.ErrorExample";
+static const char warningPatternKeyC[] = "ProjectExplorer.CustomToolChain.WarningPattern";
+static const char warningLineNumberCapKeyC[] = "ProjectExplorer.CustomToolChain.WarningLineNumberCap";
+static const char warningFileNameCapKeyC[] = "ProjectExplorer.CustomToolChain.WarningFileNameCap";
+static const char warningMessageCapKeyC[] = "ProjectExplorer.CustomToolChain.WarningMessageCap";
+static const char warningChannelKeyC[] = "ProjectExplorer.CustomToolChain.WarningChannel";
+static const char warningExampleKeyC[] = "ProjectExplorer.CustomToolChain.WarningExample";
+
+// TODO Creator 4.1: remove (added in 3.7 for compatibility)
static const char lineNumberCapKeyC[] = "ProjectExplorer.CustomToolChain.LineNumberCap";
static const char fileNameCapKeyC[] = "ProjectExplorer.CustomToolChain.FileNameCap";
static const char messageCapKeyC[] = "ProjectExplorer.CustomToolChain.MessageCap";
@@ -282,10 +295,18 @@ QVariantMap CustomToolChain::toMap() const
data.insert(QLatin1String(cxx11FlagsKeyC), m_cxx11Flags);
data.insert(QLatin1String(mkspecsKeyC), mkspecs());
data.insert(QLatin1String(outputParserKeyC), m_outputParser);
- data.insert(QLatin1String(errorPatternKeyC), m_customParserSettings.errorPattern);
- data.insert(QLatin1String(fileNameCapKeyC), m_customParserSettings.fileNameCap);
- data.insert(QLatin1String(lineNumberCapKeyC), m_customParserSettings.lineNumberCap);
- data.insert(QLatin1String(messageCapKeyC), m_customParserSettings.messageCap);
+ data.insert(QLatin1String(errorPatternKeyC), m_customParserSettings.error.pattern());
+ data.insert(QLatin1String(errorFileNameCapKeyC), m_customParserSettings.error.fileNameCap());
+ data.insert(QLatin1String(errorLineNumberCapKeyC), m_customParserSettings.error.lineNumberCap());
+ data.insert(QLatin1String(errorMessageCapKeyC), m_customParserSettings.error.messageCap());
+ data.insert(QLatin1String(errorChannelKeyC), m_customParserSettings.error.channel());
+ data.insert(QLatin1String(errorExampleKeyC), m_customParserSettings.error.example());
+ data.insert(QLatin1String(warningPatternKeyC), m_customParserSettings.warning.pattern());
+ data.insert(QLatin1String(warningFileNameCapKeyC), m_customParserSettings.warning.fileNameCap());
+ data.insert(QLatin1String(warningLineNumberCapKeyC), m_customParserSettings.warning.lineNumberCap());
+ data.insert(QLatin1String(warningMessageCapKeyC), m_customParserSettings.warning.messageCap());
+ data.insert(QLatin1String(warningChannelKeyC), m_customParserSettings.warning.channel());
+ data.insert(QLatin1String(warningExampleKeyC), m_customParserSettings.warning.example());
return data;
}
@@ -303,10 +324,29 @@ bool CustomToolChain::fromMap(const QVariantMap &data)
m_cxx11Flags = data.value(QLatin1String(cxx11FlagsKeyC)).toStringList();
setMkspecs(data.value(QLatin1String(mkspecsKeyC)).toString());
m_outputParser = (OutputParser)data.value(QLatin1String(outputParserKeyC)).toInt();
- m_customParserSettings.errorPattern = data.value(QLatin1String(errorPatternKeyC)).toString();
- m_customParserSettings.fileNameCap = data.value(QLatin1String(fileNameCapKeyC)).toInt();
- m_customParserSettings.lineNumberCap = data.value(QLatin1String(lineNumberCapKeyC)).toInt();
- m_customParserSettings.messageCap = data.value(QLatin1String(messageCapKeyC)).toInt();
+ m_customParserSettings.error.setPattern(data.value(QLatin1String(errorPatternKeyC)).toString());
+ m_customParserSettings.error.setFileNameCap(data.value(QLatin1String(errorFileNameCapKeyC)).toInt());
+ m_customParserSettings.error.setLineNumberCap(data.value(QLatin1String(errorLineNumberCapKeyC)).toInt());
+ m_customParserSettings.error.setMessageCap(data.value(QLatin1String(errorMessageCapKeyC)).toInt());
+ m_customParserSettings.error.setChannel(
+ static_cast<CustomParserExpression::CustomParserChannel>(data.value(QLatin1String(errorChannelKeyC)).toInt()));
+ m_customParserSettings.error.setExample(data.value(QLatin1String(errorExampleKeyC)).toString());
+ m_customParserSettings.warning.setPattern(data.value(QLatin1String(warningPatternKeyC)).toString());
+ m_customParserSettings.warning.setFileNameCap(data.value(QLatin1String(warningFileNameCapKeyC)).toInt());
+ m_customParserSettings.warning.setLineNumberCap(data.value(QLatin1String(warningLineNumberCapKeyC)).toInt());
+ m_customParserSettings.warning.setMessageCap(data.value(QLatin1String(warningMessageCapKeyC)).toInt());
+ m_customParserSettings.warning.setChannel(
+ static_cast<CustomParserExpression::CustomParserChannel>(data.value(QLatin1String(warningChannelKeyC)).toInt()));
+ m_customParserSettings.warning.setExample(data.value(QLatin1String(warningExampleKeyC)).toString());
+
+ // TODO Creator 4.1: remove (added in 3.7 for compatibility)
+ if (m_customParserSettings.error.fileNameCap() == 0)
+ m_customParserSettings.error.setFileNameCap(data.value(QLatin1String(fileNameCapKeyC)).toInt());
+ if (m_customParserSettings.error.lineNumberCap() == 0)
+ m_customParserSettings.error.setLineNumberCap(data.value(QLatin1String(lineNumberCapKeyC)).toInt());
+ if (m_customParserSettings.error.messageCap() == 0)
+ m_customParserSettings.error.setMessageCap(data.value(QLatin1String(messageCapKeyC)).toInt());
+
QTC_ASSERT(m_outputParser >= Gcc && m_outputParser < OutputParserCount, return false);
return true;