From 208aeb79edc63b597c0a968f2c3ee7726c6d049b Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Fri, 2 Aug 2013 12:15:04 +0300 Subject: [PATCH] Introduce Utils::SynchronousProcess::normalizeNewlines Replaces \r\n? with \n. Some console applications (e.g. git-push, git-rebase) use \r alone to move the cursor to the line's beginning. This should be replaced by \n rather than just be erased. Change-Id: I8d614d2b471e59decdbfa7f173ffa7fbdb11759b Reviewed-by: Tobias Hunger --- src/libs/utils/synchronousprocess.cpp | 23 +++++++++++++++++++++-- src/libs/utils/synchronousprocess.h | 2 ++ src/plugins/coreplugin/outputwindow.cpp | 8 ++++---- src/plugins/git/gitclient.cpp | 6 ++---- src/plugins/mercurial/mercurialclient.cpp | 7 +++---- src/plugins/vcsbase/command.cpp | 11 +++++------ src/plugins/vcsbase/vcsbaseclient.cpp | 5 ++--- src/plugins/vcsbase/vcsbaseplugin.cpp | 8 ++++---- 8 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp index 52033ff0bd3..ba68b087100 100644 --- a/src/libs/utils/synchronousprocess.cpp +++ b/src/libs/utils/synchronousprocess.cpp @@ -476,8 +476,8 @@ void SynchronousProcess::stdErrReady() QString SynchronousProcess::convertOutput(const QByteArray &ba) const { - QString output = d->m_codec ? d->m_codec->toUnicode(ba) : QString::fromLocal8Bit(ba.constData(), ba.size()); - return output.remove(QLatin1Char('\r')); + return normalizeNewlines(d->m_codec ? d->m_codec->toUnicode(ba) + : QString::fromLocal8Bit(ba.constData(), ba.size())); } void SynchronousProcess::processStdOut(bool emitSignals) @@ -676,6 +676,25 @@ QString SynchronousProcess::locateBinary(const QString &path, const QString &bin return QString(); } +QString SynchronousProcess::normalizeNewlines(const QString &text) +{ + const QChar cr(QLatin1Char('\r')); + const QChar lf(QLatin1Char('\n')); + QString res; + res.reserve(text.size()); + for (int i = 0, count = text.size(); i < count; ++i) { + const QChar c = text.at(i); + if (c == cr) { + res += lf; + if (i + 1 < count && text.at(i + 1) == lf) + ++i; + } else { + res += c; + } + } + return res; +} + QString SynchronousProcess::locateBinary(const QString &binary) { const QByteArray path = qgetenv("PATH"); diff --git a/src/libs/utils/synchronousprocess.h b/src/libs/utils/synchronousprocess.h index 6db6e86841d..9172d8be58b 100644 --- a/src/libs/utils/synchronousprocess.h +++ b/src/libs/utils/synchronousprocess.h @@ -138,6 +138,8 @@ public: static QString locateBinary(const QString &binary); static QString locateBinary(const QString &path, const QString &binary); + static QString normalizeNewlines(const QString &text); + signals: void stdOut(const QByteArray &data, bool firstTime); void stdErr(const QByteArray &data, bool firstTime); diff --git a/src/plugins/coreplugin/outputwindow.cpp b/src/plugins/coreplugin/outputwindow.cpp index 2c5499571ef..8e70dea29b4 100644 --- a/src/plugins/coreplugin/outputwindow.cpp +++ b/src/plugins/coreplugin/outputwindow.cpp @@ -33,6 +33,8 @@ #include "coreconstants.h" #include "icore.h" +#include + #include #include @@ -200,8 +202,7 @@ void OutputWindow::setMaxLineCount(int count) void OutputWindow::appendMessage(const QString &output, OutputFormat format) { - QString out = output; - out.remove(QLatin1Char('\r')); + const QString out = Utils::SynchronousProcess::normalizeNewlines(output); setMaximumBlockCount(m_maxLineCount); const bool atBottom = isScrollbarAtBottom(); @@ -251,8 +252,7 @@ void OutputWindow::appendMessage(const QString &output, OutputFormat format) // TODO rename void OutputWindow::appendText(const QString &textIn, const QTextCharFormat &format) { - QString text = textIn; - text.remove(QLatin1Char('\r')); + const QString text = Utils::SynchronousProcess::normalizeNewlines(textIn); if (m_maxLineCount > 0 && document()->blockCount() >= m_maxLineCount) return; const bool atBottom = isScrollbarAtBottom(); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 7dab68eba60..c7fe23bc01a 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -744,9 +744,7 @@ Core::IEditor *locateEditor(const char *property, const QString &entry) // Return converted command output, remove '\r' read on Windows static inline QString commandOutputFromLocal8Bit(const QByteArray &a) { - QString output = QString::fromLocal8Bit(a); - output.remove(QLatin1Char('\r')); - return output; + return Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(a)); } // Return converted command output split into lines @@ -3398,7 +3396,7 @@ QString GitClient::readConfig(const QString &workingDirectory, const QStringList VcsBasePlugin::SuppressCommandLogging)) return QString(); if (Utils::HostOsInfo::isWindowsHost()) - return QString::fromUtf8(outputText).remove(QLatin1Char('\r')); + return Utils::SynchronousProcess::normalizeNewlines(QString::fromUtf8(outputText)); return commandOutputFromLocal8Bit(outputText); } diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index 3bb4ea9e55d..274cd57a651 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -187,8 +187,8 @@ QStringList MercurialClient::parentRevisionsSync(const QString &workingDirectory QByteArray outputData; if (!vcsFullySynchronousExec(workingDirectory, args, &outputData)) return QStringList(); - QString output = QString::fromLocal8Bit(outputData); - output.remove(QLatin1Char('\r')); + const QString output = Utils::SynchronousProcess::normalizeNewlines( + QString::fromLocal8Bit(outputData)); /* Looks like: \code changeset: 0:031a48610fba user: ... @@ -230,8 +230,7 @@ QString MercurialClient::shortDescriptionSync(const QString &workingDirectory, QByteArray outputData; if (!vcsFullySynchronousExec(workingDirectory, args, &outputData)) return revision; - description = QString::fromLocal8Bit(outputData); - description.remove(QLatin1Char('\r')); + description = Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(outputData)); if (description.endsWith(QLatin1Char('\n'))) description.truncate(description.size() - 1); return description; diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp index 55eb8b9f5ce..ed0291075b9 100644 --- a/src/plugins/vcsbase/command.cpp +++ b/src/plugins/vcsbase/command.cpp @@ -253,15 +253,14 @@ void Command::run() exitCode = process->exitCode(); } - QString stdOutS = d->m_codec ? d->m_codec->toUnicode(stdOut) - : QString::fromLocal8Bit(stdOut.constData(), stdOut.size()); - stdOutS.remove(QLatin1Char('\r')); - d->m_lastExecSuccess = ok; d->m_lastExecExitCode = exitCode; - if (ok) - emit output(stdOutS); + if (ok) { + emit output(Utils::SynchronousProcess::normalizeNewlines( + d->m_codec ? d->m_codec->toUnicode(stdOut) + : QString::fromLocal8Bit(stdOut.constData(), stdOut.size()))); + } if (!error.isEmpty()) emit errorText(error); diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 32030abb5e6..99002213031 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -189,9 +189,8 @@ bool VcsBaseClient::synchronousCreateRepository(const QString &workingDirectory, QByteArray outputData; if (!vcsFullySynchronousExec(workingDirectory, args, &outputData)) return false; - QString output = QString::fromLocal8Bit(outputData); - output.remove(QLatin1Char('\r')); - ::vcsOutputWindow()->append(output); + ::vcsOutputWindow()->append( + Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(outputData))); resetCachedVcsInfo(workingDirectory); diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp index 703b79f5bbd..9d1905ccc7c 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.cpp +++ b/src/plugins/vcsbase/vcsbaseplugin.cpp @@ -863,15 +863,15 @@ static SynchronousProcessResponse runVcsFullySynchronously(const QString &workin &stdOut, &stdErr, true); if (!stdErr.isEmpty()) { - response.stdErr = (outputCodec ? outputCodec->toUnicode(stdErr) : QString::fromLocal8Bit(stdErr)); - response.stdErr.remove(QLatin1Char('\r')); + response.stdErr = Utils::SynchronousProcess::normalizeNewlines( + outputCodec ? outputCodec->toUnicode(stdErr) : QString::fromLocal8Bit(stdErr)); if (!(flags & VcsBasePlugin::SuppressStdErrInLogWindow)) outputWindow->append(response.stdErr); } if (!stdOut.isEmpty()) { - response.stdOut = (outputCodec ? outputCodec->toUnicode(stdOut) : QString::fromLocal8Bit(stdOut)); - response.stdOut.remove(QLatin1Char('\r')); + response.stdOut = Utils::SynchronousProcess::normalizeNewlines( + outputCodec ? outputCodec->toUnicode(stdOut) : QString::fromLocal8Bit(stdOut)); if (flags & VcsBasePlugin::ShowStdOutInLogWindow) { if (flags & VcsBasePlugin::SilentOutput) outputWindow->appendSilently(response.stdOut);