diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp index 83618487eaa..4ee666e570a 100644 --- a/src/libs/utils/stringutils.cpp +++ b/src/libs/utils/stringutils.cpp @@ -387,11 +387,20 @@ QTCREATOR_UTILS_EXPORT QStringView chopIfEndsWith(QStringView str, QChar c) QTCREATOR_UTILS_EXPORT QString normalizeNewlines(const QString &text) { QString res = text; - const auto newEnd = std::unique(res.begin(), res.end(), [](const QChar c1, const QChar c2) { - return c1 == '\r' && c2 == '\r'; // QTCREATORBUG-24556 + const auto newEnd = std::unique(res.rbegin(), res.rend(), [](const QChar c1, const QChar c2) { + return c1 == '\n' && c2 == '\r'; // QTCREATORBUG-24556 }); - res.chop(std::distance(newEnd, res.end())); - res.replace("\r\n", "\n"); + res.remove(0, std::distance(newEnd, res.rend())); + return res; +} + +QTCREATOR_UTILS_EXPORT QByteArray normalizeNewlines(const QByteArray &text) +{ + QByteArray res = text; + const auto newEnd = std::unique(res.rbegin(), res.rend(), [](const char c1, const char c2) { + return c1 == '\n' && c2 == '\r'; // QTCREATORBUG-24556 + }); + res.remove(0, std::distance(newEnd, res.rend())); return res; } diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h index 7b21f869fff..b58e30de050 100644 --- a/src/libs/utils/stringutils.h +++ b/src/libs/utils/stringutils.h @@ -90,6 +90,7 @@ QTCREATOR_UTILS_EXPORT QString chopIfEndsWith(QString str, QChar c); QTCREATOR_UTILS_EXPORT QStringView chopIfEndsWith(QStringView str, QChar c); QTCREATOR_UTILS_EXPORT QString normalizeNewlines(const QString &text); +QTCREATOR_UTILS_EXPORT QByteArray normalizeNewlines(const QByteArray &text); // Skips empty parts - see QTBUG-110900 QTCREATOR_UTILS_EXPORT QString joinStrings(const QStringList &strings, QChar separator); diff --git a/tests/auto/utils/stringutils/tst_stringutils.cpp b/tests/auto/utils/stringutils/tst_stringutils.cpp index b69aca4ba7b..81126c21980 100644 --- a/tests/auto/utils/stringutils/tst_stringutils.cpp +++ b/tests/auto/utils/stringutils/tst_stringutils.cpp @@ -30,6 +30,8 @@ private slots: void testSplitAtFirst(); void testAsciify_data(); void testAsciify(); + void testNormalizeNewlinesInString(); + void testNormalizeNewlinesInByteArray(); }; void tst_StringUtils::testWithTildeHomePath() @@ -355,6 +357,27 @@ void tst_StringUtils::testAsciify() QCOMPARE(asciified, expected); } +void tst_StringUtils::testNormalizeNewlinesInString() +{ + const QString input = "asd\r\r\nfoo\r\nbar\nfoo\r"; + const QString expected = "asd\nfoo\nbar\nfoo\r"; + + const QString normalized = Utils::normalizeNewlines(input); + + QCOMPARE(normalized, expected); +} + +void tst_StringUtils::testNormalizeNewlinesInByteArray() +{ + const QByteArray input = "asd\r\r\nfoo\r\nbar\nfoo\r"; + const QByteArray expected = "asd\nfoo\nbar\nfoo\r"; + + const QByteArray normalized = Utils::normalizeNewlines(input); + + QCOMPARE(normalized, expected); +} + + QTEST_GUILESS_MAIN(tst_StringUtils) #include "tst_stringutils.moc"