diff options
-rw-r--r-- | doc/src/projects/creator-projects-compilers.qdoc | 8 | ||||
-rw-r--r-- | src/plugins/projectexplorer/customparser.cpp | 301 | ||||
-rw-r--r-- | src/plugins/projectexplorer/customparser.h | 76 | ||||
-rw-r--r-- | src/plugins/projectexplorer/customparserconfigdialog.cpp | 246 | ||||
-rw-r--r-- | src/plugins/projectexplorer/customparserconfigdialog.h | 36 | ||||
-rw-r--r-- | src/plugins/projectexplorer/customparserconfigdialog.ui | 576 | ||||
-rw-r--r-- | src/plugins/projectexplorer/customtoolchain.cpp | 56 |
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>&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>&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>&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>&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>&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>&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>&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>&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&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>&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>&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>&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&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; |