forked from qt-creator/qt-creator
Custom Error Parser
Allow setting the following items from outside: * capture regular expression, * file name, line number and message capture position and * whether to parse stdout, stderr or both The parser functions can be unit-tested by running (Debug build of Qt Creator needed): qtcreator -test ProjectExplorer,testCustomOutputParsers The data is passed to the custom parser in CustomToolChain::outputParser(). The parser information is stored in toolchains.xml together with the custom toolchain. A configuration widget is provided to set up and test the regular expression against a sample error message. Change-Id: I6191df3c44432943e0aeb16c48d8e79d35845d2e Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
committed by
André Hartmann
parent
9249175a4b
commit
4bc61ecac4
295
src/plugins/projectexplorer/customparser.cpp
Normal file
295
src/plugins/projectexplorer/customparser.cpp
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Andre Hartmann.
|
||||||
|
** Contact: aha_1980@gmx.de
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "customparser.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "projectexplorerconstants.h"
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
|
CustomParserSettings::CustomParserSettings() :
|
||||||
|
fileNameCap(1),
|
||||||
|
lineNumberCap(2),
|
||||||
|
messageCap(3)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool CustomParserSettings::operator !=(const CustomParserSettings &other) const
|
||||||
|
{
|
||||||
|
if (errorPattern == other.errorPattern)
|
||||||
|
return false;
|
||||||
|
if (fileNameCap == other.fileNameCap)
|
||||||
|
return false;
|
||||||
|
if (lineNumberCap == other.lineNumberCap)
|
||||||
|
return false;
|
||||||
|
if (messageCap == other.messageCap)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomParser::CustomParser(const CustomParserSettings &settings) :
|
||||||
|
m_parserChannels(ParseBothChannels)
|
||||||
|
{
|
||||||
|
setObjectName(QLatin1String("CustomParser"));
|
||||||
|
|
||||||
|
setSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomParser::~CustomParser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParser::setErrorPattern(const QString &errorPattern)
|
||||||
|
{
|
||||||
|
m_errorRegExp.setPattern(errorPattern);
|
||||||
|
m_errorRegExp.setMinimal(true);
|
||||||
|
QTC_CHECK(m_errorRegExp.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CustomParser::errorPattern() const
|
||||||
|
{
|
||||||
|
return m_errorRegExp.pattern();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CustomParser::lineNumberCap() const
|
||||||
|
{
|
||||||
|
return m_lineNumberCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParser::setLineNumberCap(int lineNumberCap)
|
||||||
|
{
|
||||||
|
m_lineNumberCap = lineNumberCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CustomParser::fileNameCap() const
|
||||||
|
{
|
||||||
|
return m_fileNameCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParser::setFileNameCap(int fileNameCap)
|
||||||
|
{
|
||||||
|
m_fileNameCap = fileNameCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CustomParser::messageCap() const
|
||||||
|
{
|
||||||
|
return m_messageCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParser::setMessageCap(int messageCap)
|
||||||
|
{
|
||||||
|
m_messageCap = messageCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParser::stdError(const QString &line)
|
||||||
|
{
|
||||||
|
if (m_parserChannels & ParseStdErrChannel)
|
||||||
|
if (parseLine(line))
|
||||||
|
return;
|
||||||
|
|
||||||
|
IOutputParser::stdError(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParser::stdOutput(const QString &line)
|
||||||
|
{
|
||||||
|
if (m_parserChannels & ParseStdOutChannel)
|
||||||
|
if (parseLine(line))
|
||||||
|
return;
|
||||||
|
|
||||||
|
IOutputParser::stdOutput(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParser::setSettings(const CustomParserSettings &settings)
|
||||||
|
{
|
||||||
|
setErrorPattern(settings.errorPattern);
|
||||||
|
setFileNameCap(settings.fileNameCap);
|
||||||
|
setLineNumberCap(settings.lineNumberCap);
|
||||||
|
setMessageCap(settings.messageCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CustomParser::parseLine(const QString &rawLine)
|
||||||
|
{
|
||||||
|
if (m_errorRegExp.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_errorRegExp.indexIn(rawLine.trimmed()) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const Utils::FileName fileName =
|
||||||
|
Utils::FileName::fromUserInput(m_errorRegExp.cap(m_fileNameCap));
|
||||||
|
const int lineNumber = m_errorRegExp.cap(m_lineNumberCap).toInt();
|
||||||
|
const QString message = m_errorRegExp.cap(m_messageCap);
|
||||||
|
|
||||||
|
emit addTask(Task(Task::Error, message, fileName, lineNumber, Constants::TASK_CATEGORY_COMPILE));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unit tests:
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
# include <QTest>
|
||||||
|
|
||||||
|
# include "projectexplorer.h"
|
||||||
|
# include "metatypedeclarations.h"
|
||||||
|
# include "outputparser_test.h"
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
|
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<QString>("childStdOutLines");
|
||||||
|
QTest::addColumn<QString>("childStdErrLines");
|
||||||
|
QTest::addColumn<QList<ProjectExplorer::Task> >("tasks");
|
||||||
|
QTest::addColumn<QString>("outputLines");
|
||||||
|
|
||||||
|
const Core::Id categoryCompile = Core::Id(Constants::TASK_CATEGORY_COMPILE);
|
||||||
|
const QString simplePattern = QLatin1String("^([a-z]+\\.[a-z]+):(\\d+): error: ([^\\s].+)$");
|
||||||
|
const Utils::FileName fileName = Utils::FileName::fromUserInput(QLatin1String("main.c"));
|
||||||
|
|
||||||
|
QTest::newRow("empty pattern")
|
||||||
|
<< QString::fromLatin1("Sometext")
|
||||||
|
<< OutputParserTester::STDOUT
|
||||||
|
<< QString::fromLatin1("")
|
||||||
|
<< 1 << 2 << 3
|
||||||
|
<< QString::fromLatin1("Sometext\n") << QString()
|
||||||
|
<< QList<ProjectExplorer::Task>()
|
||||||
|
<< QString();
|
||||||
|
|
||||||
|
QTest::newRow("pass-through stdout")
|
||||||
|
<< QString::fromLatin1("Sometext")
|
||||||
|
<< OutputParserTester::STDOUT
|
||||||
|
<< simplePattern
|
||||||
|
<< 1 << 2 << 3
|
||||||
|
<< QString::fromLatin1("Sometext\n") << QString()
|
||||||
|
<< QList<ProjectExplorer::Task>()
|
||||||
|
<< QString();
|
||||||
|
|
||||||
|
QTest::newRow("pass-through stderr")
|
||||||
|
<< QString::fromLatin1("Sometext")
|
||||||
|
<< OutputParserTester::STDERR
|
||||||
|
<< simplePattern
|
||||||
|
<< 1 << 2 << 3
|
||||||
|
<< QString() << QString::fromLatin1("Sometext\n")
|
||||||
|
<< QList<ProjectExplorer::Task>()
|
||||||
|
<< QString();
|
||||||
|
|
||||||
|
const QString simpleError = QLatin1String("main.c:9: error: `sfasdf' undeclared (first use this function)");
|
||||||
|
const QString message = QLatin1String("`sfasdf' undeclared (first use this function)");
|
||||||
|
|
||||||
|
QTest::newRow("simple error")
|
||||||
|
<< simpleError
|
||||||
|
<< OutputParserTester::STDERR
|
||||||
|
<< simplePattern
|
||||||
|
<< 1 << 2 << 3
|
||||||
|
<< QString() << QString()
|
||||||
|
<< (QList<ProjectExplorer::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].+)$");
|
||||||
|
const int lineNumber2 = 19;
|
||||||
|
|
||||||
|
QTest::newRow("another simple error on stderr")
|
||||||
|
<< simpleError2
|
||||||
|
<< OutputParserTester::STDERR
|
||||||
|
<< simplePattern2
|
||||||
|
<< 1 << 2 << 3
|
||||||
|
<< QString() << QString()
|
||||||
|
<< (QList<ProjectExplorer::Task>()
|
||||||
|
<< Task(Task::Error, message, fileName, lineNumber2, categoryCompile)
|
||||||
|
)
|
||||||
|
<< QString();
|
||||||
|
|
||||||
|
QTest::newRow("another simple error on stdout")
|
||||||
|
<< simpleError2
|
||||||
|
<< OutputParserTester::STDOUT
|
||||||
|
<< simplePattern2
|
||||||
|
<< 1 << 2 << 3
|
||||||
|
<< QString() << QString()
|
||||||
|
<< (QList<ProjectExplorer::Task>()
|
||||||
|
<< Task(Task::Error, message, fileName, lineNumber2, 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");
|
||||||
|
const QString unitTestPattern = QLatin1String("^([^:]+):(\\d+): FAIL: ([^\\s].+)$");
|
||||||
|
const int unitTestLineNumber = 63;
|
||||||
|
|
||||||
|
QTest::newRow("unit test error")
|
||||||
|
<< unitTestError
|
||||||
|
<< OutputParserTester::STDOUT
|
||||||
|
<< unitTestPattern
|
||||||
|
<< 1 << 2 << 3
|
||||||
|
<< QString() << QString()
|
||||||
|
<< (QList<ProjectExplorer::Task>()
|
||||||
|
<< Task(Task::Error, unitTestMessage, unitTestFileName, unitTestLineNumber, categoryCompile)
|
||||||
|
)
|
||||||
|
<< QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectExplorerPlugin::testCustomOutputParsers()
|
||||||
|
{
|
||||||
|
QFETCH(QString, input);
|
||||||
|
QFETCH(OutputParserTester::Channel, inputChannel);
|
||||||
|
QFETCH(QString, pattern);
|
||||||
|
QFETCH(int, fileNameCap);
|
||||||
|
QFETCH(int, lineNumberCap);
|
||||||
|
QFETCH(int, messageCap);
|
||||||
|
QFETCH(QString, childStdOutLines);
|
||||||
|
QFETCH(QString, childStdErrLines);
|
||||||
|
QFETCH(QList<Task>, tasks);
|
||||||
|
QFETCH(QString, outputLines);
|
||||||
|
|
||||||
|
CustomParser *parser = new CustomParser;
|
||||||
|
parser->setErrorPattern(pattern);
|
||||||
|
parser->setFileNameCap(fileNameCap);
|
||||||
|
parser->setLineNumberCap(lineNumberCap);
|
||||||
|
parser->setMessageCap(messageCap);
|
||||||
|
|
||||||
|
OutputParserTester testbench;
|
||||||
|
testbench.appendOutputParser(parser);
|
||||||
|
testbench.testParsing(input, inputChannel,
|
||||||
|
tasks, childStdOutLines, childStdErrLines,
|
||||||
|
outputLines);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
93
src/plugins/projectexplorer/customparser.h
Normal file
93
src/plugins/projectexplorer/customparser.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Andre Hartmann.
|
||||||
|
** Contact: aha_1980@gmx.de
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CUSTOMPARSER_H
|
||||||
|
#define CUSTOMPARSER_H
|
||||||
|
|
||||||
|
#include "ioutputparser.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/task.h>
|
||||||
|
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
|
class CustomParserSettings
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CustomParserSettings();
|
||||||
|
|
||||||
|
bool operator !=(const CustomParserSettings &other) const;
|
||||||
|
|
||||||
|
QString errorPattern;
|
||||||
|
int fileNameCap;
|
||||||
|
int lineNumberCap;
|
||||||
|
int messageCap;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CustomParser : public ProjectExplorer::IOutputParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum CustomParserChannels {
|
||||||
|
ParseNoChannel = 0,
|
||||||
|
ParseStdErrChannel = 1,
|
||||||
|
ParseStdOutChannel = 2,
|
||||||
|
ParseBothChannels = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
CustomParser(const CustomParserSettings &settings = CustomParserSettings());
|
||||||
|
~CustomParser();
|
||||||
|
void stdError(const QString &line);
|
||||||
|
void stdOutput(const QString &line);
|
||||||
|
|
||||||
|
void setSettings(const CustomParserSettings &settings);
|
||||||
|
|
||||||
|
void setErrorPattern(const QString &errorPattern);
|
||||||
|
QString errorPattern() const;
|
||||||
|
int fileNameCap() const;
|
||||||
|
void setFileNameCap(int fileNameCap);
|
||||||
|
int lineNumberCap() const;
|
||||||
|
void setLineNumberCap(int lineNumberCap);
|
||||||
|
int messageCap() const;
|
||||||
|
void setMessageCap(int messageCap);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool parseLine(const QString &rawLine);
|
||||||
|
|
||||||
|
QRegExp m_errorRegExp;
|
||||||
|
int m_fileNameCap;
|
||||||
|
int m_lineNumberCap;
|
||||||
|
int m_messageCap;
|
||||||
|
|
||||||
|
CustomParserChannels m_parserChannels;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ProjectExplorer
|
||||||
|
|
||||||
|
#endif // CUSTOMPARSER_H
|
||||||
167
src/plugins/projectexplorer/customparserconfigdialog.cpp
Normal file
167
src/plugins/projectexplorer/customparserconfigdialog.cpp
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Andre Hartmann.
|
||||||
|
** Contact: aha_1980@gmx.de
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "customparserconfigdialog.h"
|
||||||
|
#include "ui_customparserconfigdialog.h"
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
|
CustomParserConfigDialog::CustomParserConfigDialog(QDialog *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::CustomParserConfigDialog)
|
||||||
|
{
|
||||||
|
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()));
|
||||||
|
|
||||||
|
changed();
|
||||||
|
m_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomParserConfigDialog::~CustomParserConfigDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
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`"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParserConfigDialog::setSettings(const ProjectExplorer::CustomParserSettings &settings)
|
||||||
|
{
|
||||||
|
if (settings.errorPattern.isEmpty()) {
|
||||||
|
setExampleSettings();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setErrorPattern(settings.errorPattern);
|
||||||
|
setFileNameCap(settings.fileNameCap);
|
||||||
|
setLineNumberCap(settings.lineNumberCap);
|
||||||
|
setMessageCap(settings.messageCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectExplorer::CustomParserSettings CustomParserConfigDialog::settings() const
|
||||||
|
{
|
||||||
|
ProjectExplorer::CustomParserSettings result;
|
||||||
|
result.errorPattern = errorPattern();
|
||||||
|
result.fileNameCap = fileNameCap();
|
||||||
|
result.lineNumberCap = lineNumberCap();
|
||||||
|
result.messageCap = messageCap();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParserConfigDialog::setErrorPattern(const QString &errorPattern)
|
||||||
|
{
|
||||||
|
ui->errorPattern->setText(errorPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CustomParserConfigDialog::errorPattern() const
|
||||||
|
{
|
||||||
|
return ui->errorPattern->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParserConfigDialog::setFileNameCap(int fileNameCap)
|
||||||
|
{
|
||||||
|
ui->fileNameCap->setValue(fileNameCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CustomParserConfigDialog::fileNameCap() const
|
||||||
|
{
|
||||||
|
return ui->fileNameCap->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParserConfigDialog::setLineNumberCap(int lineNumberCap)
|
||||||
|
{
|
||||||
|
ui->lineNumberCap->setValue(lineNumberCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CustomParserConfigDialog::lineNumberCap() const
|
||||||
|
{
|
||||||
|
return ui->lineNumberCap->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParserConfigDialog::setMessageCap(int messageCap)
|
||||||
|
{
|
||||||
|
ui->messageCap->setValue(messageCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CustomParserConfigDialog::messageCap() const
|
||||||
|
{
|
||||||
|
return ui->messageCap->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CustomParserConfigDialog::isDirty() const
|
||||||
|
{
|
||||||
|
return m_dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomParserConfigDialog::changed()
|
||||||
|
{
|
||||||
|
QRegExp rx;
|
||||||
|
rx.setPattern(ui->errorPattern->text());
|
||||||
|
rx.setMinimal(true);
|
||||||
|
|
||||||
|
QPalette palette;
|
||||||
|
palette.setColor(QPalette::Text, rx.isValid() ? Qt::black : Qt::red);
|
||||||
|
ui->errorPattern->setPalette(palette);
|
||||||
|
ui->errorPattern->setToolTip(rx.isValid() ? QString() : rx.errorString());
|
||||||
|
|
||||||
|
int pos = rx.indexIn(ui->errorMessage->text());
|
||||||
|
if (rx.isEmpty() || !rx.isValid() || pos < 0) {
|
||||||
|
QString error = QLatin1String("<font color=\"red\">") + tr("Not applicable: ");
|
||||||
|
if (rx.isEmpty())
|
||||||
|
error += tr("Pattern is empty.");
|
||||||
|
else if (!rx.isValid())
|
||||||
|
error += rx.errorString();
|
||||||
|
else
|
||||||
|
error += tr("Pattern does not match the error message.");
|
||||||
|
|
||||||
|
ui->fileNameTest->setText(error);
|
||||||
|
ui->lineNumberTest->setText(error);
|
||||||
|
ui->messageTest->setText(error);
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->fileNameTest->setText(rx.cap(ui->fileNameCap->value()));
|
||||||
|
ui->lineNumberTest->setText(rx.cap(ui->lineNumberCap->value()));
|
||||||
|
ui->messageTest->setText(rx.cap(ui->messageCap->value()));
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||||
|
m_dirty = true;
|
||||||
|
}
|
||||||
70
src/plugins/projectexplorer/customparserconfigdialog.h
Normal file
70
src/plugins/projectexplorer/customparserconfigdialog.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Andre Hartmann.
|
||||||
|
** Contact: aha_1980@gmx.de
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CUSTOMPARSERCONFIGDIALOG_H
|
||||||
|
#define CUSTOMPARSERCONFIGDIALOG_H
|
||||||
|
|
||||||
|
#include "customparser.h"
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CustomParserConfigDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomParserConfigDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CustomParserConfigDialog(QDialog *parent = 0);
|
||||||
|
~CustomParserConfigDialog();
|
||||||
|
|
||||||
|
void setExampleSettings();
|
||||||
|
void setSettings(const ProjectExplorer::CustomParserSettings &settings);
|
||||||
|
ProjectExplorer::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;
|
||||||
|
bool isDirty() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void changed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::CustomParserConfigDialog *ui;
|
||||||
|
bool m_dirty;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CUSTOMPARSERCONFIGDIALOG_H
|
||||||
244
src/plugins/projectexplorer/customparserconfigdialog.ui
Normal file
244
src/plugins/projectexplorer/customparserconfigdialog.ui
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CustomParserConfigDialog</class>
|
||||||
|
<widget class="QDialog" name="CustomParserConfigDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>470</width>
|
||||||
|
<height>368</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Custom Parser</string>
|
||||||
|
</property>
|
||||||
|
<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>#error (.*):(\d+): (.*)$</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="capturePositionsGroup">
|
||||||
|
<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>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>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="testGroup">
|
||||||
|
<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>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>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>errorPattern</tabstop>
|
||||||
|
<tabstop>fileNameCap</tabstop>
|
||||||
|
<tabstop>lineNumberCap</tabstop>
|
||||||
|
<tabstop>messageCap</tabstop>
|
||||||
|
<tabstop>errorMessage</tabstop>
|
||||||
|
<tabstop>buttonBox</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>CustomParserConfigDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>320</x>
|
||||||
|
<y>341</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>386</x>
|
||||||
|
<y>289</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>CustomParserConfigDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>277</x>
|
||||||
|
<y>350</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>421</x>
|
||||||
|
<y>255</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
@@ -33,6 +33,8 @@
|
|||||||
#include "clangparser.h"
|
#include "clangparser.h"
|
||||||
#include "linuxiccparser.h"
|
#include "linuxiccparser.h"
|
||||||
#include "msvcparser.h"
|
#include "msvcparser.h"
|
||||||
|
#include "customparser.h"
|
||||||
|
#include "customparserconfigdialog.h"
|
||||||
#include "projectexplorerconstants.h"
|
#include "projectexplorerconstants.h"
|
||||||
#include "toolchainmanager.h"
|
#include "toolchainmanager.h"
|
||||||
|
|
||||||
@@ -44,7 +46,9 @@
|
|||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
@@ -63,6 +67,10 @@ static const char headerPathsKeyC[] = "ProjectExplorer.CustomToolChain.HeaderPat
|
|||||||
static const char cxx11FlagsKeyC[] = "ProjectExplorer.CustomToolChain.Cxx11Flags";
|
static const char cxx11FlagsKeyC[] = "ProjectExplorer.CustomToolChain.Cxx11Flags";
|
||||||
static const char mkspecsKeyC[] = "ProjectExplorer.CustomToolChain.Mkspecs";
|
static const char mkspecsKeyC[] = "ProjectExplorer.CustomToolChain.Mkspecs";
|
||||||
static const char outputParserKeyC[] = "ProjectExplorer.CustomToolChain.OutputParser";
|
static const char outputParserKeyC[] = "ProjectExplorer.CustomToolChain.OutputParser";
|
||||||
|
static const char errorPatternKeyC[] = "ProjectExplorer.CustomToolChain.ErrorPattern";
|
||||||
|
static const char lineNumberCapKeyC[] = "ProjectExplorer.CustomToolChain.LineNumberCap";
|
||||||
|
static const char fileNameCapKeyC[] = "ProjectExplorer.CustomToolChain.FileNameCap";
|
||||||
|
static const char messageCapKeyC[] = "ProjectExplorer.CustomToolChain.MessageCap";
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// CustomToolChain
|
// CustomToolChain
|
||||||
@@ -204,6 +212,7 @@ IOutputParser *CustomToolChain::outputParser() const
|
|||||||
#if defined(QT_OS_WIN)
|
#if defined(QT_OS_WIN)
|
||||||
case Msvc: return new MsvcParser;
|
case Msvc: return new MsvcParser;
|
||||||
#endif
|
#endif
|
||||||
|
case Custom: return new CustomParser(m_customParserSettings);
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,6 +303,10 @@ QVariantMap CustomToolChain::toMap() const
|
|||||||
data.insert(QLatin1String(cxx11FlagsKeyC), m_cxx11Flags);
|
data.insert(QLatin1String(cxx11FlagsKeyC), m_cxx11Flags);
|
||||||
data.insert(QLatin1String(mkspecsKeyC), mkspecs());
|
data.insert(QLatin1String(mkspecsKeyC), mkspecs());
|
||||||
data.insert(QLatin1String(outputParserKeyC), m_outputParser);
|
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);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@@ -311,6 +324,10 @@ bool CustomToolChain::fromMap(const QVariantMap &data)
|
|||||||
m_cxx11Flags = data.value(QLatin1String(cxx11FlagsKeyC)).toStringList();
|
m_cxx11Flags = data.value(QLatin1String(cxx11FlagsKeyC)).toStringList();
|
||||||
setMkspecs(data.value(QLatin1String(mkspecsKeyC)).toString());
|
setMkspecs(data.value(QLatin1String(mkspecsKeyC)).toString());
|
||||||
m_outputParser = (OutputParser)data.value(QLatin1String(outputParserKeyC)).toInt();
|
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();
|
||||||
QTC_ASSERT(m_outputParser >= Gcc && m_outputParser < OutputParserCount, return false);
|
QTC_ASSERT(m_outputParser >= Gcc && m_outputParser < OutputParserCount, return false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -339,6 +356,16 @@ void CustomToolChain::setOutputParserType(CustomToolChain::OutputParser parser)
|
|||||||
m_outputParser = parser;
|
m_outputParser = parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CustomParserSettings CustomToolChain::customParserSettings() const
|
||||||
|
{
|
||||||
|
return m_customParserSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomToolChain::setCustomParserSettings(const CustomParserSettings &settings)
|
||||||
|
{
|
||||||
|
m_customParserSettings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
QString CustomToolChain::parserName(CustomToolChain::OutputParser parser)
|
QString CustomToolChain::parserName(CustomToolChain::OutputParser parser)
|
||||||
{
|
{
|
||||||
switch (parser) {
|
switch (parser) {
|
||||||
@@ -348,6 +375,7 @@ QString CustomToolChain::parserName(CustomToolChain::OutputParser parser)
|
|||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
case Msvc: return tr("MSVC");
|
case Msvc: return tr("MSVC");
|
||||||
#endif
|
#endif
|
||||||
|
case Custom: return tr("Custom");
|
||||||
default: return QString();
|
default: return QString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,13 +488,17 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) :
|
|||||||
m_headerDetails(new TextEditDetailsWidget(m_headerPaths)),
|
m_headerDetails(new TextEditDetailsWidget(m_headerPaths)),
|
||||||
m_cxx11Flags(new QLineEdit),
|
m_cxx11Flags(new QLineEdit),
|
||||||
m_mkspecs(new QLineEdit),
|
m_mkspecs(new QLineEdit),
|
||||||
m_errorParserComboBox(new QComboBox)
|
m_errorParserComboBox(new QComboBox),
|
||||||
|
m_customParserSettingsButton(new QPushButton(tr("Custom Parser Settings...")))
|
||||||
{
|
{
|
||||||
Q_ASSERT(tc);
|
Q_ASSERT(tc);
|
||||||
|
|
||||||
for (int i = 0; i < CustomToolChain::OutputParserCount; ++i)
|
for (int i = 0; i < CustomToolChain::OutputParserCount; ++i)
|
||||||
m_errorParserComboBox->addItem(CustomToolChain::parserName((CustomToolChain::OutputParser)i));
|
m_errorParserComboBox->addItem(CustomToolChain::parserName((CustomToolChain::OutputParser)i));
|
||||||
|
|
||||||
|
QWidget *parserLayoutWidget = new QWidget;
|
||||||
|
QHBoxLayout *parserLayout = new QHBoxLayout(parserLayoutWidget);
|
||||||
|
parserLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
m_predefinedMacros->setTabChangesFocus(true);
|
m_predefinedMacros->setTabChangesFocus(true);
|
||||||
m_predefinedMacros->setToolTip(tr("Each line defines a macro. Format is MACRO[=VALUE]"));
|
m_predefinedMacros->setToolTip(tr("Each line defines a macro. Format is MACRO[=VALUE]"));
|
||||||
m_headerPaths->setTabChangesFocus(true);
|
m_headerPaths->setTabChangesFocus(true);
|
||||||
@@ -482,7 +514,9 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) :
|
|||||||
m_mainLayout->addRow(tr("&Header paths:"), m_headerDetails);
|
m_mainLayout->addRow(tr("&Header paths:"), m_headerDetails);
|
||||||
m_mainLayout->addRow(tr("C++11 &flags:"), m_cxx11Flags);
|
m_mainLayout->addRow(tr("C++11 &flags:"), m_cxx11Flags);
|
||||||
m_mainLayout->addRow(tr("&Qt mkspecs:"), m_mkspecs);
|
m_mainLayout->addRow(tr("&Qt mkspecs:"), m_mkspecs);
|
||||||
m_mainLayout->addRow(tr("&Error Parser:"), m_errorParserComboBox);
|
parserLayout->addWidget(m_errorParserComboBox);
|
||||||
|
parserLayout->addWidget(m_customParserSettingsButton);
|
||||||
|
m_mainLayout->addRow(tr("&Error parser:"), parserLayoutWidget);
|
||||||
addErrorLabel();
|
addErrorLabel();
|
||||||
|
|
||||||
setFromToolchain();
|
setFromToolchain();
|
||||||
@@ -494,6 +528,8 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) :
|
|||||||
connect(m_headerPaths, SIGNAL(textChanged()), this, SLOT(updateSummaries()));
|
connect(m_headerPaths, SIGNAL(textChanged()), this, SLOT(updateSummaries()));
|
||||||
connect(m_errorParserComboBox, SIGNAL(currentIndexChanged(int)),
|
connect(m_errorParserComboBox, SIGNAL(currentIndexChanged(int)),
|
||||||
this, SLOT(errorParserChanged(int)));
|
this, SLOT(errorParserChanged(int)));
|
||||||
|
connect(m_customParserSettingsButton, SIGNAL(clicked()),
|
||||||
|
this, SLOT(openCustomParserSettingsDialog()));
|
||||||
errorParserChanged(m_errorParserComboBox->currentIndex());
|
errorParserChanged(m_errorParserComboBox->currentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,10 +543,22 @@ void CustomToolChainConfigWidget::updateSummaries()
|
|||||||
|
|
||||||
void CustomToolChainConfigWidget::errorParserChanged(int index)
|
void CustomToolChainConfigWidget::errorParserChanged(int index)
|
||||||
{
|
{
|
||||||
Q_UNUSED(index);
|
m_customParserSettingsButton->setEnabled(index == m_errorParserComboBox->count() - 1);
|
||||||
emit dirty();
|
emit dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CustomToolChainConfigWidget::openCustomParserSettingsDialog()
|
||||||
|
{
|
||||||
|
CustomParserConfigDialog dialog;
|
||||||
|
dialog.setSettings(m_customParserSettings);
|
||||||
|
|
||||||
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
|
m_customParserSettings = dialog.settings();
|
||||||
|
if (dialog.isDirty())
|
||||||
|
emit dirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CustomToolChainConfigWidget::applyImpl()
|
void CustomToolChainConfigWidget::applyImpl()
|
||||||
{
|
{
|
||||||
if (toolChain()->isAutoDetected())
|
if (toolChain()->isAutoDetected())
|
||||||
@@ -528,6 +576,7 @@ void CustomToolChainConfigWidget::applyImpl()
|
|||||||
tc->setMkspecs(m_mkspecs->text());
|
tc->setMkspecs(m_mkspecs->text());
|
||||||
tc->setDisplayName(displayName); // reset display name
|
tc->setDisplayName(displayName); // reset display name
|
||||||
tc->setOutputParserType((CustomToolChain::OutputParser)m_errorParserComboBox->currentIndex());
|
tc->setOutputParserType((CustomToolChain::OutputParser)m_errorParserComboBox->currentIndex());
|
||||||
|
tc->setCustomParserSettings(m_customParserSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomToolChainConfigWidget::setFromToolchain()
|
void CustomToolChainConfigWidget::setFromToolchain()
|
||||||
@@ -543,6 +592,7 @@ void CustomToolChainConfigWidget::setFromToolchain()
|
|||||||
m_cxx11Flags->setText(tc->cxx11Flags().join(QLatin1String(",")));
|
m_cxx11Flags->setText(tc->cxx11Flags().join(QLatin1String(",")));
|
||||||
m_mkspecs->setText(tc->mkspecs());
|
m_mkspecs->setText(tc->mkspecs());
|
||||||
m_errorParserComboBox->setCurrentIndex(tc->outputParserType());
|
m_errorParserComboBox->setCurrentIndex(tc->outputParserType());
|
||||||
|
m_customParserSettings = tc->customParserSettings();
|
||||||
blockSignals(blocked);
|
blockSignals(blocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,7 +607,8 @@ bool CustomToolChainConfigWidget::isDirtyImpl() const
|
|||||||
|| m_headerDetails->entries() != tc->headerPathsList()
|
|| m_headerDetails->entries() != tc->headerPathsList()
|
||||||
|| m_cxx11Flags->text().split(QLatin1Char(',')) != tc->cxx11Flags()
|
|| m_cxx11Flags->text().split(QLatin1Char(',')) != tc->cxx11Flags()
|
||||||
|| m_mkspecs->text() != tc->mkspecs()
|
|| m_mkspecs->text() != tc->mkspecs()
|
||||||
|| m_errorParserComboBox->currentIndex() == tc->outputParserType();
|
|| m_errorParserComboBox->currentIndex() == tc->outputParserType()
|
||||||
|
|| m_customParserSettings != tc->customParserSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomToolChainConfigWidget::makeReadOnlyImpl()
|
void CustomToolChainConfigWidget::makeReadOnlyImpl()
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "projectexplorer_export.h"
|
#include "projectexplorer_export.h"
|
||||||
|
|
||||||
#include "abi.h"
|
#include "abi.h"
|
||||||
|
#include "customparser.h"
|
||||||
#include "headerpath.h"
|
#include "headerpath.h"
|
||||||
#include "toolchain.h"
|
#include "toolchain.h"
|
||||||
#include "toolchainconfigwidget.h"
|
#include "toolchainconfigwidget.h"
|
||||||
@@ -43,6 +44,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QPlainTextEdit;
|
class QPlainTextEdit;
|
||||||
class QTextEdit;
|
class QTextEdit;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
|
class QPushButton;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Utils { class PathChooser; }
|
namespace Utils { class PathChooser; }
|
||||||
@@ -69,6 +71,7 @@ public:
|
|||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
Msvc = 3,
|
Msvc = 3,
|
||||||
#endif
|
#endif
|
||||||
|
Custom,
|
||||||
OutputParserCount
|
OutputParserCount
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,7 +117,10 @@ public:
|
|||||||
|
|
||||||
OutputParser outputParserType() const;
|
OutputParser outputParserType() const;
|
||||||
void setOutputParserType(OutputParser parser);
|
void setOutputParserType(OutputParser parser);
|
||||||
|
CustomParserSettings customParserSettings() const;
|
||||||
|
void setCustomParserSettings(const CustomParserSettings &settings);
|
||||||
static QString parserName(OutputParser parser);
|
static QString parserName(OutputParser parser);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CustomToolChain(const QString &id, bool autodetect);
|
CustomToolChain(const QString &id, bool autodetect);
|
||||||
CustomToolChain(const CustomToolChain &);
|
CustomToolChain(const CustomToolChain &);
|
||||||
@@ -132,6 +138,8 @@ private:
|
|||||||
QList<Utils::FileName> m_mkspecs;
|
QList<Utils::FileName> m_mkspecs;
|
||||||
|
|
||||||
OutputParser m_outputParser;
|
OutputParser m_outputParser;
|
||||||
|
CustomParserSettings m_customParserSettings;
|
||||||
|
|
||||||
friend class Internal::CustomToolChainFactory;
|
friend class Internal::CustomToolChainFactory;
|
||||||
friend class ToolChainFactory;
|
friend class ToolChainFactory;
|
||||||
};
|
};
|
||||||
@@ -176,6 +184,7 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void updateSummaries();
|
void updateSummaries();
|
||||||
void errorParserChanged(int index);
|
void errorParserChanged(int index);
|
||||||
|
void openCustomParserSettingsDialog();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void applyImpl();
|
void applyImpl();
|
||||||
@@ -195,6 +204,9 @@ protected:
|
|||||||
QLineEdit *m_cxx11Flags;
|
QLineEdit *m_cxx11Flags;
|
||||||
QLineEdit *m_mkspecs;
|
QLineEdit *m_mkspecs;
|
||||||
QComboBox *m_errorParserComboBox;
|
QComboBox *m_errorParserComboBox;
|
||||||
|
QPushButton *m_customParserSettingsButton;
|
||||||
|
|
||||||
|
CustomParserSettings m_customParserSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -246,6 +246,9 @@ private slots:
|
|||||||
void testGccOutputParsers_data();
|
void testGccOutputParsers_data();
|
||||||
void testGccOutputParsers();
|
void testGccOutputParsers();
|
||||||
|
|
||||||
|
void testCustomOutputParsers_data();
|
||||||
|
void testCustomOutputParsers();
|
||||||
|
|
||||||
void testClangOutputParser_data();
|
void testClangOutputParser_data();
|
||||||
void testClangOutputParser();
|
void testClangOutputParser();
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,9 @@ HEADERS += projectexplorer.h \
|
|||||||
deploymentdata.h \
|
deploymentdata.h \
|
||||||
buildtargetinfo.h \
|
buildtargetinfo.h \
|
||||||
customtoolchain.h \
|
customtoolchain.h \
|
||||||
projectmacroexpander.h
|
projectmacroexpander.h \
|
||||||
|
customparser.h \
|
||||||
|
customparserconfigdialog.h
|
||||||
|
|
||||||
SOURCES += projectexplorer.cpp \
|
SOURCES += projectexplorer.cpp \
|
||||||
abi.cpp \
|
abi.cpp \
|
||||||
@@ -246,7 +248,9 @@ SOURCES += projectexplorer.cpp \
|
|||||||
devicesupport/desktopdeviceconfigurationwidget.cpp \
|
devicesupport/desktopdeviceconfigurationwidget.cpp \
|
||||||
deployablefile.cpp \
|
deployablefile.cpp \
|
||||||
customtoolchain.cpp \
|
customtoolchain.cpp \
|
||||||
projectmacroexpander.cpp
|
projectmacroexpander.cpp \
|
||||||
|
customparser.cpp \
|
||||||
|
customparserconfigdialog.cpp
|
||||||
|
|
||||||
FORMS += processstep.ui \
|
FORMS += processstep.ui \
|
||||||
editorsettingspropertiespage.ui \
|
editorsettingspropertiespage.ui \
|
||||||
@@ -260,7 +264,8 @@ FORMS += processstep.ui \
|
|||||||
devicesupport/devicefactoryselectiondialog.ui \
|
devicesupport/devicefactoryselectiondialog.ui \
|
||||||
devicesupport/devicesettingswidget.ui \
|
devicesupport/devicesettingswidget.ui \
|
||||||
devicesupport/devicetestdialog.ui \
|
devicesupport/devicetestdialog.ui \
|
||||||
devicesupport/desktopdeviceconfigurationwidget.ui
|
devicesupport/desktopdeviceconfigurationwidget.ui \
|
||||||
|
customparserconfigdialog.ui
|
||||||
|
|
||||||
WINSOURCES += \
|
WINSOURCES += \
|
||||||
windebuginterface.cpp \
|
windebuginterface.cpp \
|
||||||
|
|||||||
@@ -74,6 +74,11 @@ QtcPlugin {
|
|||||||
"currentprojectfilter.h",
|
"currentprojectfilter.h",
|
||||||
"currentprojectfind.cpp",
|
"currentprojectfind.cpp",
|
||||||
"currentprojectfind.h",
|
"currentprojectfind.h",
|
||||||
|
"customparser.cpp",
|
||||||
|
"customparser.h",
|
||||||
|
"customparserconfigdialog.cpp",
|
||||||
|
"customparserconfigdialog.h",
|
||||||
|
"customparserconfigdialog.ui",
|
||||||
"customtoolchain.cpp",
|
"customtoolchain.cpp",
|
||||||
"customtoolchain.h",
|
"customtoolchain.h",
|
||||||
"dependenciespanel.cpp",
|
"dependenciespanel.cpp",
|
||||||
|
|||||||
Reference in New Issue
Block a user