summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@digia.com>2013-05-03 16:08:00 +0200
committerTobias Hunger <tobias.hunger@digia.com>2013-05-06 10:04:38 +0200
commit8bbad43019af98e342d6a5b311016fa20198e4cf (patch)
tree0727f9ffd34dd0d6dfd221558e2aa69b295f4742 /src
parent14763118a58bf526f873b6750c3785f8752e4d7e (diff)
downloadqt-creator-8bbad43019af98e342d6a5b311016fa20198e4cf.tar.gz
OutputParser: Allow to flush pending tasks.
Add a way to flush out tasks from the outputparsers. This is necessary to make parsers that keep state more robust. Flush parsers (once) before adding any new task. This keeps the sequence intact. Flush all parsers once the parsing is done to make sure there is no task queued somewhere. Task-number: QTCREATORBUG-9195 Change-Id: Icd37df1f470cb73123ad286d6900ad1047a1d512 Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/projectexplorer/abstractprocessstep.cpp14
-rw-r--r--src/plugins/projectexplorer/abstractprocessstep.h1
-rw-r--r--src/plugins/projectexplorer/clangparser.cpp12
-rw-r--r--src/plugins/projectexplorer/gccparser.cpp47
-rw-r--r--src/plugins/projectexplorer/gccparser.h6
-rw-r--r--src/plugins/projectexplorer/gnumakeparser.cpp18
-rw-r--r--src/plugins/projectexplorer/ioutputparser.cpp21
-rw-r--r--src/plugins/projectexplorer/ioutputparser.h6
-rw-r--r--src/plugins/projectexplorer/linuxiccparser.cpp15
-rw-r--r--src/plugins/projectexplorer/linuxiccparser.h3
-rw-r--r--src/plugins/projectexplorer/msvcparser.cpp14
-rw-r--r--src/plugins/projectexplorer/msvcparser.h4
-rw-r--r--src/plugins/projectexplorer/outputparser_test.cpp1
13 files changed, 93 insertions, 69 deletions
diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp
index a025d03a0c..2c31d5c61e 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.cpp
+++ b/src/plugins/projectexplorer/abstractprocessstep.cpp
@@ -88,7 +88,7 @@ using namespace ProjectExplorer;
AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, const Core::Id id) :
BuildStep(bsl, id), m_timer(0), m_futureInterface(0),
m_ignoreReturnValue(false), m_process(0),
- m_outputParserChain(0)
+ m_outputParserChain(0), m_skipFlush(false)
{
}
@@ -96,7 +96,7 @@ AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl,
AbstractProcessStep *bs) :
BuildStep(bsl, bs), m_timer(0), m_futureInterface(0),
m_ignoreReturnValue(bs->m_ignoreReturnValue),
- m_process(0), m_outputParserChain(0)
+ m_process(0), m_outputParserChain(0), m_skipFlush(false)
{
}
@@ -261,6 +261,9 @@ void AbstractProcessStep::processStarted()
void AbstractProcessStep::processFinished(int exitCode, QProcess::ExitStatus status)
{
+ if (m_outputParserChain)
+ m_outputParserChain->flush();
+
QString command = QDir::toNativeSeparators(m_param.effectiveCommand());
if (status == QProcess::NormalExit && exitCode == 0) {
emit addOutput(tr("The process \"%1\" exited normally.").arg(command),
@@ -367,6 +370,13 @@ void AbstractProcessStep::taskAdded(const ProjectExplorer::Task &task)
if (m_ignoreReturnValue)
return;
+ // flush out any pending tasks before proceeding:
+ if (!m_skipFlush && m_outputParserChain) {
+ m_skipFlush = true;
+ m_outputParserChain->flush();
+ m_skipFlush = false;
+ }
+
Task editable(task);
QString filePath = task.file.toString();
if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
diff --git a/src/plugins/projectexplorer/abstractprocessstep.h b/src/plugins/projectexplorer/abstractprocessstep.h
index 307787f1a8..9ad22574de 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.h
+++ b/src/plugins/projectexplorer/abstractprocessstep.h
@@ -101,6 +101,7 @@ private:
QEventLoop *m_eventLoop;
ProjectExplorer::IOutputParser *m_outputParserChain;
bool m_killProcess;
+ bool m_skipFlush;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/clangparser.cpp b/src/plugins/projectexplorer/clangparser.cpp
index 0832d283d9..cc55157358 100644
--- a/src/plugins/projectexplorer/clangparser.cpp
+++ b/src/plugins/projectexplorer/clangparser.cpp
@@ -52,7 +52,7 @@ void ClangParser::stdError(const QString &line)
{
const QString lne = rightTrimmed(line);
if (m_summaryRegExp.indexIn(lne) > -1) {
- emitTask();
+ doFlush();
m_expectSnippet = false;
return;
}
@@ -74,11 +74,11 @@ void ClangParser::stdError(const QString &line)
if (m_inLineRegExp.indexIn(lne) > -1) {
m_expectSnippet = true;
- newTask(Task::Unknown,
- lne.trimmed(),
- Utils::FileName::fromUserInput(m_inLineRegExp.cap(2)), /* filename */
- m_inLineRegExp.cap(3).toInt(), /* line */
- Core::Id(Constants::TASK_CATEGORY_COMPILE));
+ newTask(Task(Task::Unknown,
+ lne.trimmed(),
+ Utils::FileName::fromUserInput(m_inLineRegExp.cap(2)), /* filename */
+ m_inLineRegExp.cap(3).toInt(), /* line */
+ Core::Id(Constants::TASK_CATEGORY_COMPILE)));
return;
}
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index c31f93e0e4..1cd2b725c4 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -60,11 +60,6 @@ GccParser::GccParser()
appendOutputParser(new LdParser);
}
-GccParser::~GccParser()
-{
- emitTask();
-}
-
void GccParser::stdError(const QString &line)
{
QString lne = rightTrimmed(line);
@@ -79,11 +74,11 @@ void GccParser::stdError(const QString &line)
// Handle misc issues:
if (lne.startsWith(QLatin1String("ERROR:")) ||
lne == QLatin1String("* cpp failed")) {
- newTask(Task::Error,
- lne /* description */,
- Utils::FileName() /* filename */,
- -1 /* linenumber */,
- Core::Id(Constants::TASK_CATEGORY_COMPILE));
+ newTask(Task(Task::Error,
+ lne /* description */,
+ Utils::FileName() /* filename */,
+ -1 /* linenumber */,
+ Core::Id(Constants::TASK_CATEGORY_COMPILE)));
return;
} else if (m_regExpGccNames.indexIn(lne) > -1) {
QString description = lne.mid(m_regExpGccNames.matchedLength());
@@ -121,44 +116,40 @@ void GccParser::stdError(const QString &line)
newTask(task);
return;
} else if (m_regExpIncluded.indexIn(lne) > -1) {
- newTask(Task::Unknown,
- lne.trimmed() /* description */,
- Utils::FileName::fromUserInput(m_regExpIncluded.cap(1)) /* filename */,
- m_regExpIncluded.cap(3).toInt() /* linenumber */,
- Core::Id(Constants::TASK_CATEGORY_COMPILE));
+ newTask(Task(Task::Unknown,
+ lne.trimmed() /* description */,
+ Utils::FileName::fromUserInput(m_regExpIncluded.cap(1)) /* filename */,
+ m_regExpIncluded.cap(3).toInt() /* linenumber */,
+ Core::Id(Constants::TASK_CATEGORY_COMPILE)));
return;
} else if (lne.startsWith(QLatin1Char(' '))) {
amendDescription(lne, true);
return;
}
- emitTask();
+ doFlush();
IOutputParser::stdError(line);
}
void GccParser::stdOutput(const QString &line)
{
- emitTask();
+ doFlush();
IOutputParser::stdOutput(line);
}
void GccParser::newTask(const Task &task)
{
- emitTask();
+ doFlush();
m_currentTask = task;
}
-void GccParser::newTask(Task::TaskType type_, const QString &description_,
- const Utils::FileName &file_, int line_, const Core::Id &category_)
-{
- newTask(Task(type_, description_, file_, line_, category_));
-}
-
-void GccParser::emitTask()
+void GccParser::doFlush()
{
- if (!m_currentTask.isNull())
- emit addTask(m_currentTask);
- m_currentTask = Task();
+ if (m_currentTask.isNull())
+ return;
+ Task t = m_currentTask;
+ m_currentTask.clear();
+ emit addTask(t);
}
void GccParser::amendDescription(const QString &desc, bool monospaced)
diff --git a/src/plugins/projectexplorer/gccparser.h b/src/plugins/projectexplorer/gccparser.h
index fcb2108fe9..015b53f053 100644
--- a/src/plugins/projectexplorer/gccparser.h
+++ b/src/plugins/projectexplorer/gccparser.h
@@ -44,15 +44,13 @@ class GccParser : public ProjectExplorer::IOutputParser
public:
GccParser();
- ~GccParser();
+
void stdError(const QString &line);
void stdOutput(const QString &line);
protected:
void newTask(const Task &task);
- void newTask(Task::TaskType type_, const QString &description_,
- const Utils::FileName &file_, int line_, const Core::Id &category_);
- void emitTask();
+ void doFlush();
void amendDescription(const QString &desc, bool monospaced);
diff --git a/src/plugins/projectexplorer/gnumakeparser.cpp b/src/plugins/projectexplorer/gnumakeparser.cpp
index 37ca5b380a..c8f028633e 100644
--- a/src/plugins/projectexplorer/gnumakeparser.cpp
+++ b/src/plugins/projectexplorer/gnumakeparser.cpp
@@ -90,11 +90,11 @@ void GnuMakeParser::stdError(const QString &line)
++m_fatalErrorCount;
if (!m_suppressIssues) {
m_suppressIssues = true;
- addTask(Task(Task::Error,
- m_makefileError.cap(3),
- Utils::FileName::fromUserInput(m_makefileError.cap(1)),
- m_makefileError.cap(2).toInt(),
- Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)));
+ emit addTask(Task(Task::Error,
+ m_makefileError.cap(3),
+ Utils::FileName::fromUserInput(m_makefileError.cap(1)),
+ m_makefileError.cap(2).toInt(),
+ Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)));
}
return;
}
@@ -110,10 +110,10 @@ void GnuMakeParser::stdError(const QString &line)
type = Task::Warning;
}
- addTask(Task(type, description,
- Utils::FileName() /* filename */,
- -1, /* line */
- Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)));
+ emit addTask(Task(type, description,
+ Utils::FileName() /* filename */,
+ -1, /* line */
+ Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)));
}
return;
}
diff --git a/src/plugins/projectexplorer/ioutputparser.cpp b/src/plugins/projectexplorer/ioutputparser.cpp
index b996a560fb..fc5882e5f2 100644
--- a/src/plugins/projectexplorer/ioutputparser.cpp
+++ b/src/plugins/projectexplorer/ioutputparser.cpp
@@ -108,6 +108,17 @@
This method can be overwritten to change the task.
*/
+/*!
+ \fn void ProjectExplorer::IOutputParser::doFlush()
+
+ \brief This method is called whenever a parser is supposed to flush his state.
+ Parsers may have state (e.g. because they need to aggregate several lines into one task). This
+ method is called when this state needs to be flushed out to be visible.
+
+ doFlush() is called by flush(). flush() is called on childparsers whenever a new task is added.
+ It is also called once when all input has been parsed.
+*/
+
namespace ProjectExplorer {
IOutputParser::IOutputParser() : m_parser(0)
@@ -180,6 +191,9 @@ void IOutputParser::taskAdded(const ProjectExplorer::Task &task)
emit addTask(task);
}
+void IOutputParser::doFlush()
+{ }
+
bool IOutputParser::hasFatalErrors() const
{
return false || (m_parser && m_parser->hasFatalErrors());
@@ -191,6 +205,13 @@ void IOutputParser::setWorkingDirectory(const QString &workingDirectory)
m_parser->setWorkingDirectory(workingDirectory);
}
+void IOutputParser::flush()
+{
+ doFlush();
+ if (m_parser)
+ m_parser->flush();
+}
+
QString IOutputParser::rightTrimmed(const QString &in)
{
int pos = in.length();
diff --git a/src/plugins/projectexplorer/ioutputparser.h b/src/plugins/projectexplorer/ioutputparser.h
index 53200c1be3..aadde37485 100644
--- a/src/plugins/projectexplorer/ioutputparser.h
+++ b/src/plugins/projectexplorer/ioutputparser.h
@@ -44,7 +44,7 @@ class PROJECTEXPLORER_EXPORT IOutputParser : public QObject
Q_OBJECT
public:
IOutputParser();
- virtual ~IOutputParser();
+ ~IOutputParser();
virtual void appendOutputParser(IOutputParser *parser);
@@ -60,6 +60,8 @@ public:
// For GnuMakeParser
virtual void setWorkingDirectory(const QString &workingDirectory);
+ void flush(); // flush out pending tasks
+
static QString rightTrimmed(const QString &in);
signals:
@@ -71,6 +73,8 @@ public slots:
virtual void taskAdded(const ProjectExplorer::Task &task);
private:
+ virtual void doFlush();
+
IOutputParser *m_parser;
};
diff --git a/src/plugins/projectexplorer/linuxiccparser.cpp b/src/plugins/projectexplorer/linuxiccparser.cpp
index bdbe37835c..bdd6f3ac1f 100644
--- a/src/plugins/projectexplorer/linuxiccparser.cpp
+++ b/src/plugins/projectexplorer/linuxiccparser.cpp
@@ -58,12 +58,6 @@ LinuxIccParser::LinuxIccParser()
appendOutputParser(new LdParser);
}
-LinuxIccParser::~LinuxIccParser()
-{
- if (!m_temporary.isNull())
- addTask(m_temporary);
-}
-
void LinuxIccParser::stdError(const QString &line)
{
if (m_expectFirstLine && m_firstLine.indexIn(line) != -1) {
@@ -107,6 +101,15 @@ void LinuxIccParser::stdError(const QString &line)
}
}
+void LinuxIccParser::doFlush()
+{
+ if (m_temporary.isNull())
+ return;
+ Task t = m_temporary;
+ m_temporary.clear();
+ emit addTask(t);
+}
+
#ifdef WITH_TESTS
# include <QTest>
# include "projectexplorer.h"
diff --git a/src/plugins/projectexplorer/linuxiccparser.h b/src/plugins/projectexplorer/linuxiccparser.h
index fd985b8b75..e3e13a6b43 100644
--- a/src/plugins/projectexplorer/linuxiccparser.h
+++ b/src/plugins/projectexplorer/linuxiccparser.h
@@ -43,11 +43,12 @@ class LinuxIccParser : public ProjectExplorer::IOutputParser
public:
LinuxIccParser();
- ~LinuxIccParser();
void stdError(const QString &line);
private:
+ void doFlush();
+
QRegExp m_firstLine;
QRegExp m_continuationLines;
QRegExp m_caretLine;
diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp
index 7c572cec0b..9596e5ce0a 100644
--- a/src/plugins/projectexplorer/msvcparser.cpp
+++ b/src/plugins/projectexplorer/msvcparser.cpp
@@ -69,11 +69,6 @@ MsvcParser::MsvcParser()
m_additionalInfoRegExp.setMinimal(true);
}
-MsvcParser::~MsvcParser()
-{
- sendQueuedTask();
-}
-
void MsvcParser::stdOutput(const QString &line)
{
int infoPos = m_additionalInfoRegExp.indexIn(line);
@@ -141,7 +136,7 @@ void MsvcParser::stdError(const QString &line)
bool MsvcParser::processCompileLine(const QString &line)
{
- sendQueuedTask();
+ doFlush();
if (m_compileRegExp.indexIn(line) > -1) {
QPair<Utils::FileName, int> position = parseFileName( m_compileRegExp.cap(1));
@@ -159,13 +154,14 @@ bool MsvcParser::processCompileLine(const QString &line)
return false;
}
-void MsvcParser::sendQueuedTask()
+void MsvcParser::doFlush()
{
if (m_lastTask.isNull())
return;
- addTask(m_lastTask);
- m_lastTask = Task();
+ Task t = m_lastTask;
+ m_lastTask.clear();
+ emit addTask(t);
}
// Unit tests:
diff --git a/src/plugins/projectexplorer/msvcparser.h b/src/plugins/projectexplorer/msvcparser.h
index 1f9d5bc8af..e67547d53c 100644
--- a/src/plugins/projectexplorer/msvcparser.h
+++ b/src/plugins/projectexplorer/msvcparser.h
@@ -44,14 +44,12 @@ class MsvcParser : public ProjectExplorer::IOutputParser
public:
MsvcParser();
- ~MsvcParser();
void stdOutput(const QString &line);
void stdError(const QString &line);
- void flush();
private:
- void sendQueuedTask();
+ void doFlush();
bool processCompileLine(const QString &line);
QRegExp m_compileRegExp;
diff --git a/src/plugins/projectexplorer/outputparser_test.cpp b/src/plugins/projectexplorer/outputparser_test.cpp
index 5bb324a1ec..0b5ab36600 100644
--- a/src/plugins/projectexplorer/outputparser_test.cpp
+++ b/src/plugins/projectexplorer/outputparser_test.cpp
@@ -58,6 +58,7 @@ void OutputParserTester::testParsing(const QString &lines,
else
childParser()->stdError(input + QLatin1Char('\n'));
}
+ childParser()->flush();
// first disconnect ourselves from the end of the parser chain again
IOutputParser * parser = this;