diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2020-03-31 14:34:08 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2020-04-07 08:13:58 +0000 |
commit | b15d1951a21e3d0f3c2f41a32f9e26b473f60ddf (patch) | |
tree | 65a49851baf637a30b3c683e8e7bfa6176567027 /src/plugins/projectexplorer/abstractprocessstep.cpp | |
parent | 45e7b78dc3a25c42f19d4275e7b678cfbd4c5771 (diff) | |
download | qt-creator-b15d1951a21e3d0f3c2f41a32f9e26b473f60ddf.tar.gz |
ProjectExplorer: Let IOutputParser handle newlines
This makes IOutputParser structurally more similar to
Utils::OutputFormatter, which makes it simpler to explore possibilities
of somehow uniting these two related classes.
Task-number: QTCREATORBUG-22665
Change-Id: Ibb12ab6c8c785d863b9a921102a929864d0a5251
Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins/projectexplorer/abstractprocessstep.cpp')
-rw-r--r-- | src/plugins/projectexplorer/abstractprocessstep.cpp | 78 |
1 files changed, 20 insertions, 58 deletions
diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index c4d8ae8dc4..b8902ea98a 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -45,6 +45,7 @@ #include <QDir> #include <QHash> #include <QPair> +#include <QTextDecoder> #include <QUrl> #include <algorithm> @@ -108,15 +109,11 @@ public: std::unique_ptr<IOutputParser> m_outputParserChain; ProcessParameters m_param; Utils::FileInProjectFinder m_fileFinder; - QByteArray deferredText; bool m_ignoreReturnValue = false; bool m_skipFlush = false; bool m_lowPriority = false; - - void readData(void (AbstractProcessStep::*func)(const QString &), bool isUtf8 = false); - void processLine(const QByteArray &data, - void (AbstractProcessStep::*func)(const QString &), - bool isUtf8 = false); + std::unique_ptr<QTextDecoder> stdoutStream; + std::unique_ptr<QTextDecoder> stderrStream; }; AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, Core::Id id) : @@ -224,6 +221,10 @@ void AbstractProcessStep::doRun() return; } + d->stdoutStream = std::make_unique<QTextDecoder>(buildEnvironment().hasKey("VSLANG") + ? QTextCodec::codecForName("UTF-8") : QTextCodec::codecForLocale()); + d->stderrStream = std::make_unique<QTextDecoder>(QTextCodec::codecForLocale()); + d->m_process.reset(new Utils::QtcProcess()); d->m_process->setUseCtrlCStub(Utils::HostOsInfo::isWindowsHost()); d->m_process->setWorkingDirectory(wd.absolutePath()); @@ -347,40 +348,7 @@ void AbstractProcessStep::processReadyReadStdOutput() { if (!d->m_process) return; - d->m_process->setReadChannel(QProcess::StandardOutput); - const bool utf8Output = buildEnvironment().hasKey("VSLANG"); - d->readData(&AbstractProcessStep::stdOutput, utf8Output); -} - -void AbstractProcessStep::Private::readData(void (AbstractProcessStep::*func)(const QString &), - bool isUtf8) -{ - while (m_process->bytesAvailable()) { - const bool hasLine = m_process->canReadLine(); - const QByteArray data = hasLine ? m_process->readLine() : m_process->readAll(); - int startPos = 0; - int crPos = -1; - while ((crPos = data.indexOf('\r', startPos)) >= 0) { - if (data.size() > crPos + 1 && data.at(crPos + 1) == '\n') - break; - processLine(data.mid(startPos, crPos - startPos + 1), func, isUtf8); - startPos = crPos + 1; - } - if (hasLine) - processLine(data.mid(startPos), func, isUtf8); - else if (startPos < data.count()) - deferredText += data.mid(startPos); - } -} - -void AbstractProcessStep::Private::processLine(const QByteArray &data, - void (AbstractProcessStep::*func)(const QString &), - bool isUtf8) -{ - const QByteArray text = deferredText + data; - deferredText.clear(); - const QString line = isUtf8 ? QString::fromUtf8(text) : QString::fromLocal8Bit(text); - (q->*func)(line); + stdOutput(d->stdoutStream->toUnicode(d->m_process->readAllStandardOutput())); } /*! @@ -389,19 +357,18 @@ void AbstractProcessStep::Private::processLine(const QByteArray &data, The default implementation adds the line to the application output window. */ -void AbstractProcessStep::stdOutput(const QString &line) +void AbstractProcessStep::stdOutput(const QString &output) { if (d->m_outputParserChain) - d->m_outputParserChain->stdOutput(line); - emit addOutput(line, BuildStep::OutputFormat::Stdout, BuildStep::DontAppendNewline); + d->m_outputParserChain->handleStdout(output); + emit addOutput(output, BuildStep::OutputFormat::Stdout, BuildStep::DontAppendNewline); } void AbstractProcessStep::processReadyReadStdError() { if (!d->m_process) return; - d->m_process->setReadChannel(QProcess::StandardError); - d->readData(&AbstractProcessStep::stdError); + stdError(d->stderrStream->toUnicode(d->m_process->readAllStandardError())); } /*! @@ -410,11 +377,11 @@ void AbstractProcessStep::processReadyReadStdError() The default implementation adds the line to the application output window. */ -void AbstractProcessStep::stdError(const QString &line) +void AbstractProcessStep::stdError(const QString &output) { if (d->m_outputParserChain) - d->m_outputParserChain->stdError(line); - emit addOutput(line, BuildStep::OutputFormat::Stderr, BuildStep::DontAppendNewline); + d->m_outputParserChain->handleStderr(output); + emit addOutput(output, BuildStep::OutputFormat::Stderr, BuildStep::DontAppendNewline); } void AbstractProcessStep::finish(bool success) @@ -432,7 +399,7 @@ void AbstractProcessStep::taskAdded(const Task &task, int linkedOutputLines, int // flush out any pending tasks before proceeding: if (!d->m_skipFlush && d->m_outputParserChain) { d->m_skipFlush = true; - d->m_outputParserChain->flush(); + d->m_outputParserChain->flushTasks(); d->m_skipFlush = false; } @@ -463,15 +430,10 @@ void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus) QProcess *process = d->m_process.get(); if (!process) // Happens when the process was canceled and handed over to the Reaper. process = qobject_cast<QProcess *>(sender()); // The process was canceled! - - const QString stdErrLine = process ? QString::fromLocal8Bit(process->readAllStandardError()) : QString(); - for (const QString &l : stdErrLine.split('\n')) - stdError(l); - - const QString stdOutLine = process ? QString::fromLocal8Bit(process->readAllStandardOutput()) : QString(); - for (const QString &l : stdOutLine.split('\n')) - stdOutput(l); - + if (process) { + stdError(d->stderrStream->toUnicode(process->readAllStandardError())); + stdOutput(d->stdoutStream->toUnicode(process->readAllStandardOutput())); + } cleanUp(process); } |