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 <tobias.hunger@digia.com>
This commit is contained in:
Orgad Shaneh
2013-08-02 12:15:04 +03:00
committed by Orgad Shaneh
parent 1b13122cd1
commit 208aeb79ed
8 changed files with 43 additions and 27 deletions

View File

@@ -476,8 +476,8 @@ void SynchronousProcess::stdErrReady()
QString SynchronousProcess::convertOutput(const QByteArray &ba) const QString SynchronousProcess::convertOutput(const QByteArray &ba) const
{ {
QString output = d->m_codec ? d->m_codec->toUnicode(ba) : QString::fromLocal8Bit(ba.constData(), ba.size()); return normalizeNewlines(d->m_codec ? d->m_codec->toUnicode(ba)
return output.remove(QLatin1Char('\r')); : QString::fromLocal8Bit(ba.constData(), ba.size()));
} }
void SynchronousProcess::processStdOut(bool emitSignals) void SynchronousProcess::processStdOut(bool emitSignals)
@@ -676,6 +676,25 @@ QString SynchronousProcess::locateBinary(const QString &path, const QString &bin
return QString(); 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) QString SynchronousProcess::locateBinary(const QString &binary)
{ {
const QByteArray path = qgetenv("PATH"); const QByteArray path = qgetenv("PATH");

View File

@@ -138,6 +138,8 @@ public:
static QString locateBinary(const QString &binary); static QString locateBinary(const QString &binary);
static QString locateBinary(const QString &path, const QString &binary); static QString locateBinary(const QString &path, const QString &binary);
static QString normalizeNewlines(const QString &text);
signals: signals:
void stdOut(const QByteArray &data, bool firstTime); void stdOut(const QByteArray &data, bool firstTime);
void stdErr(const QByteArray &data, bool firstTime); void stdErr(const QByteArray &data, bool firstTime);

View File

@@ -33,6 +33,8 @@
#include "coreconstants.h" #include "coreconstants.h"
#include "icore.h" #include "icore.h"
#include <utils/synchronousprocess.h>
#include <QAction> #include <QAction>
#include <QScrollBar> #include <QScrollBar>
@@ -200,8 +202,7 @@ void OutputWindow::setMaxLineCount(int count)
void OutputWindow::appendMessage(const QString &output, OutputFormat format) void OutputWindow::appendMessage(const QString &output, OutputFormat format)
{ {
QString out = output; const QString out = Utils::SynchronousProcess::normalizeNewlines(output);
out.remove(QLatin1Char('\r'));
setMaximumBlockCount(m_maxLineCount); setMaximumBlockCount(m_maxLineCount);
const bool atBottom = isScrollbarAtBottom(); const bool atBottom = isScrollbarAtBottom();
@@ -251,8 +252,7 @@ void OutputWindow::appendMessage(const QString &output, OutputFormat format)
// TODO rename // TODO rename
void OutputWindow::appendText(const QString &textIn, const QTextCharFormat &format) void OutputWindow::appendText(const QString &textIn, const QTextCharFormat &format)
{ {
QString text = textIn; const QString text = Utils::SynchronousProcess::normalizeNewlines(textIn);
text.remove(QLatin1Char('\r'));
if (m_maxLineCount > 0 && document()->blockCount() >= m_maxLineCount) if (m_maxLineCount > 0 && document()->blockCount() >= m_maxLineCount)
return; return;
const bool atBottom = isScrollbarAtBottom(); const bool atBottom = isScrollbarAtBottom();

View File

@@ -744,9 +744,7 @@ Core::IEditor *locateEditor(const char *property, const QString &entry)
// Return converted command output, remove '\r' read on Windows // Return converted command output, remove '\r' read on Windows
static inline QString commandOutputFromLocal8Bit(const QByteArray &a) static inline QString commandOutputFromLocal8Bit(const QByteArray &a)
{ {
QString output = QString::fromLocal8Bit(a); return Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(a));
output.remove(QLatin1Char('\r'));
return output;
} }
// Return converted command output split into lines // Return converted command output split into lines
@@ -3398,7 +3396,7 @@ QString GitClient::readConfig(const QString &workingDirectory, const QStringList
VcsBasePlugin::SuppressCommandLogging)) VcsBasePlugin::SuppressCommandLogging))
return QString(); return QString();
if (Utils::HostOsInfo::isWindowsHost()) if (Utils::HostOsInfo::isWindowsHost())
return QString::fromUtf8(outputText).remove(QLatin1Char('\r')); return Utils::SynchronousProcess::normalizeNewlines(QString::fromUtf8(outputText));
return commandOutputFromLocal8Bit(outputText); return commandOutputFromLocal8Bit(outputText);
} }

View File

@@ -187,8 +187,8 @@ QStringList MercurialClient::parentRevisionsSync(const QString &workingDirectory
QByteArray outputData; QByteArray outputData;
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData)) if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
return QStringList(); return QStringList();
QString output = QString::fromLocal8Bit(outputData); const QString output = Utils::SynchronousProcess::normalizeNewlines(
output.remove(QLatin1Char('\r')); QString::fromLocal8Bit(outputData));
/* Looks like: \code /* Looks like: \code
changeset: 0:031a48610fba changeset: 0:031a48610fba
user: ... user: ...
@@ -230,8 +230,7 @@ QString MercurialClient::shortDescriptionSync(const QString &workingDirectory,
QByteArray outputData; QByteArray outputData;
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData)) if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
return revision; return revision;
description = QString::fromLocal8Bit(outputData); description = Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(outputData));
description.remove(QLatin1Char('\r'));
if (description.endsWith(QLatin1Char('\n'))) if (description.endsWith(QLatin1Char('\n')))
description.truncate(description.size() - 1); description.truncate(description.size() - 1);
return description; return description;

View File

@@ -253,15 +253,14 @@ void Command::run()
exitCode = process->exitCode(); 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_lastExecSuccess = ok;
d->m_lastExecExitCode = exitCode; d->m_lastExecExitCode = exitCode;
if (ok) if (ok) {
emit output(stdOutS); emit output(Utils::SynchronousProcess::normalizeNewlines(
d->m_codec ? d->m_codec->toUnicode(stdOut)
: QString::fromLocal8Bit(stdOut.constData(), stdOut.size())));
}
if (!error.isEmpty()) if (!error.isEmpty())
emit errorText(error); emit errorText(error);

View File

@@ -189,9 +189,8 @@ bool VcsBaseClient::synchronousCreateRepository(const QString &workingDirectory,
QByteArray outputData; QByteArray outputData;
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData)) if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
return false; return false;
QString output = QString::fromLocal8Bit(outputData); ::vcsOutputWindow()->append(
output.remove(QLatin1Char('\r')); Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(outputData)));
::vcsOutputWindow()->append(output);
resetCachedVcsInfo(workingDirectory); resetCachedVcsInfo(workingDirectory);

View File

@@ -863,15 +863,15 @@ static SynchronousProcessResponse runVcsFullySynchronously(const QString &workin
&stdOut, &stdErr, true); &stdOut, &stdErr, true);
if (!stdErr.isEmpty()) { if (!stdErr.isEmpty()) {
response.stdErr = (outputCodec ? outputCodec->toUnicode(stdErr) : QString::fromLocal8Bit(stdErr)); response.stdErr = Utils::SynchronousProcess::normalizeNewlines(
response.stdErr.remove(QLatin1Char('\r')); outputCodec ? outputCodec->toUnicode(stdErr) : QString::fromLocal8Bit(stdErr));
if (!(flags & VcsBasePlugin::SuppressStdErrInLogWindow)) if (!(flags & VcsBasePlugin::SuppressStdErrInLogWindow))
outputWindow->append(response.stdErr); outputWindow->append(response.stdErr);
} }
if (!stdOut.isEmpty()) { if (!stdOut.isEmpty()) {
response.stdOut = (outputCodec ? outputCodec->toUnicode(stdOut) : QString::fromLocal8Bit(stdOut)); response.stdOut = Utils::SynchronousProcess::normalizeNewlines(
response.stdOut.remove(QLatin1Char('\r')); outputCodec ? outputCodec->toUnicode(stdOut) : QString::fromLocal8Bit(stdOut));
if (flags & VcsBasePlugin::ShowStdOutInLogWindow) { if (flags & VcsBasePlugin::ShowStdOutInLogWindow) {
if (flags & VcsBasePlugin::SilentOutput) if (flags & VcsBasePlugin::SilentOutput)
outputWindow->appendSilently(response.stdOut); outputWindow->appendSilently(response.stdOut);