From a420374976a691fee6483c9419e78250a3a30b28 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 23 Jan 2019 17:30:52 +0100 Subject: [PATCH] QmakePM: Do a "sorted insert" when adding files Don't blindly append to the end of the list, but try to put files into the right place with regards to lexicographical order. We do not re-sort existing file lists, nor do we attempt to be fancy with strangely formatted project files. But lists conforming to our own style will stay sorted, in particular lists that have only ever been touched by Qt Creator. Fixes: QTCREATORBUG-553 Fixes: QTCREATORBUG-21807 Change-Id: I15db0e867a2d477fcf95e008f98ba468dcd83e45 Reviewed-by: Joerg Bornemann --- .../qmakeprojectmanager/qmakeparsernodes.cpp | 1 + src/shared/proparser/prowriter.cpp | 56 +++++++++++++------ .../auto/profilewriter/tst_profilewriter.cpp | 28 ++++++++++ 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index f4ba5369a5a..21d5627f0f0 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -542,6 +542,7 @@ bool QmakePriFile::addFiles(const QStringList &filePaths, QStringList *notAdded) if (!m_recursiveEnumerateFiles.contains(FileName::fromString(file))) uniqueFilePaths.append(file); } + uniqueFilePaths.sort(); changeFiles(type, uniqueFilePaths, &failedFiles, AddToProFile); if (notAdded) diff --git a/src/shared/proparser/prowriter.cpp b/src/shared/proparser/prowriter.cpp index 0d717d9ce9d..98547f89edb 100644 --- a/src/shared/proparser/prowriter.cpp +++ b/src/shared/proparser/prowriter.cpp @@ -244,23 +244,38 @@ bool ProWriter::locateVarValues(const ushort *tokPtr, const ushort *tokPtrEnd, return false; } +struct LineInfo +{ + int continuationPos = 0; + bool hasComment = false; +}; + +static LineInfo lineInfo(const QString &line) +{ + LineInfo li; + li.continuationPos = line.length(); + const int idx = line.indexOf('#'); + li.hasComment = idx >= 0; + if (li.hasComment) + li.continuationPos = idx; + for (int i = idx - 1; i >= 0 && (line.at(i) == ' ' || line.at(i) == '\t'); --i) + --li.continuationPos; + return li; +} + static int skipContLines(QStringList *lines, int lineNo, bool addCont) { for (; lineNo < lines->count(); lineNo++) { - QString line = lines->at(lineNo); - int idx = line.indexOf(QLatin1Char('#')); - if (idx >= 0) - line.truncate(idx); - while (line.endsWith(QLatin1Char(' ')) || line.endsWith(QLatin1Char('\t'))) - line.chop(1); - if (line.isEmpty()) { - if (idx >= 0) + const QString line = lines->at(lineNo); + LineInfo li = lineInfo(line); + if (li.continuationPos == 0) { + if (li.hasComment) continue; break; } - if (!line.endsWith(QLatin1Char('\\'))) { + if (line.at(li.continuationPos - 1) != '\\') { if (addCont) - (*lines)[lineNo].insert(line.length(), QLatin1String(" \\")); + (*lines)[lineNo].insert(li.continuationPos, " \\"); lineNo++; break; } @@ -287,12 +302,21 @@ void ProWriter::putVarValues(ProFile *profile, QStringList *lines, foreach (const QString &v, values) line += ((flags & MultiLine) ? QLatin1String(" \\\n ") + indent : QString::fromLatin1(" ")) + v; } else { - lineNo = skipContLines(lines, lineNo, true); - QString added; - foreach (const QString &v, values) - added += QLatin1String(" ") + indent + v + QLatin1String(" \\\n"); - added.chop(3); - lines->insert(lineNo, added); + int endLineNo = skipContLines(lines, lineNo, false); + for (const QString &v : values) { + int curLineNo = lineNo + 1; + while (curLineNo < endLineNo && v >= lines->at(curLineNo).trimmed()) + ++curLineNo; + QString newLine = " " + indent + v; + if (curLineNo == endLineNo) { + QString &oldLastLine = (*lines)[endLineNo - 1]; + oldLastLine.insert(lineInfo(oldLastLine).continuationPos, " \\"); + } else { + newLine += " \\"; + } + lines->insert(curLineNo, newLine); + ++endLineNo; + } } } else { // Create & append new variable item diff --git a/tests/auto/profilewriter/tst_profilewriter.cpp b/tests/auto/profilewriter/tst_profilewriter.cpp index 0e927e1e9a3..b820d6fdcf0 100644 --- a/tests/auto/profilewriter/tst_profilewriter.cpp +++ b/tests/auto/profilewriter/tst_profilewriter.cpp @@ -206,6 +206,34 @@ void tst_ProFileWriter::adds_data() "SOURCES = some files \\\n" " foo" }, + { + PW::AppendValues|PW::AppendOperator|PW::MultiLine, + "insert at end", f_foo_bar, 0, + "SOURCES = some files", + "SOURCES = some files \\\n" + " bar \\\n" + " foo" + }, + { + PW::AppendValues|PW::AppendOperator|PW::MultiLine, + "insert into empty", f_foo_bar, 0, + "SOURCES =", + "SOURCES = \\\n" + " bar \\\n" + " foo" + }, + { + PW::AppendValues|PW::AppendOperator|PW::MultiLine, + "insert into middle", f_foo_bar, 0, + "SOURCES = some files \\\n" + " aargh \\\n" + " zoo", + "SOURCES = some files \\\n" + " aargh \\\n" + " bar \\\n" + " foo \\\n" + " zoo" + }, { PW::AppendValues|PW::AppendOperator|PW::MultiLine, "add to existing after comment (wrong operator)", f_foo, 0,