diff --git a/src/plugins/qt4projectmanager/qt-s60/s60publisherovi.cpp b/src/plugins/qt4projectmanager/qt-s60/s60publisherovi.cpp index d1d91a0575254c52a76d0c76b3ec8d0082ae316b..efd08e525b60c03f5dc306da5a945b588c25c86d 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60publisherovi.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60publisherovi.cpp @@ -264,10 +264,9 @@ void S60PublisherOvi::updateProFile(const QString &var, const QString &values) return; } - //todo: after ossi has added scope profile writing, make sure the following works - //QString scope("symbian"); ProWriter::putVarValues(profile, &lines, QStringList() << values, var, - ProWriter::ReplaceValues | ProWriter::OneLine | ProWriter::AssignOperator); + ProWriter::ReplaceValues | ProWriter::OneLine | ProWriter::AssignOperator, + "symbian"); if (qfile.open(QIODevice::WriteOnly | QIODevice::Text)) { qfile.write(lines.join("\n").toLocal8Bit()); diff --git a/src/shared/proparser/prowriter.cpp b/src/shared/proparser/prowriter.cpp index 8bc1a13b63cd32e25e381279896c8818247f30c4..2edbddbb935cd061acaeacb7ec4dd479fdfc494a 100644 --- a/src/shared/proparser/prowriter.cpp +++ b/src/shared/proparser/prowriter.cpp @@ -174,23 +174,44 @@ static const ushort *skipToken(ushort tok, const ushort *&tokPtr, int &lineNo) return 0; } -bool ProWriter::locateVarValues(const ushort *tokPtr, const QString &var, int *bestLine) +bool ProWriter::locateVarValues(const ushort *tokPtr, + const QString &scope, const QString &var, int *scopeStart, int *bestLine) { - int lineNo = 0; + const bool inScope = scope.isEmpty(); + int lineNo = *scopeStart + 1; QString tmp; const ushort *lastXpr = 0; + bool fresh = true; while (ushort tok = *tokPtr++) { - if (tok == TokAssign || tok == TokAppend || tok == TokAppendUnique) { + if (inScope && (tok == TokAssign || tok == TokAppend || tok == TokAppendUnique)) { if (getLiteral(lastXpr, tokPtr - 1, tmp) && var == tmp) { *bestLine = lineNo - 1; return true; } skipExpression(++tokPtr, lineNo); + fresh = true; } else { - lastXpr = skipToken(tok, tokPtr, lineNo); + if (!inScope && tok == TokCondition && *tokPtr == TokBranch + && getLiteral(lastXpr, tokPtr - 1, tmp) && scope == tmp) { + *scopeStart = lineNo - 1; + if (locateVarValues(tokPtr + 3, QString(), var, scopeStart, bestLine)) + return true; + } + const ushort *oTokPtr = skipToken(tok, tokPtr, lineNo); + if (tok != TokLine) { + if (oTokPtr) { + if (fresh) + lastXpr = oTokPtr; + } else if (tok == TokNot || tok == TokAnd || tok == TokOr) { + fresh = false; + } else { + fresh = true; + } + } } } - *bestLine = qMax(lineNo - 1, 0); + if (inScope || *scopeStart < 0) + *bestLine = qMax(lineNo - 1, 0); return false; } @@ -219,10 +240,11 @@ static int skipContLines(QStringList *lines, int lineNo, bool addCont) } void ProWriter::putVarValues(ProFile *profile, QStringList *lines, - const QStringList &values, const QString &var, PutFlags flags) + const QStringList &values, const QString &var, PutFlags flags, const QString &scope) { - int lineNo; - if (locateVarValues(profile->tokPtr(), var, &lineNo)) { + QString indent = scope.isEmpty() ? QString() : QLatin1String(" "); + int scopeStart = -1, lineNo; + if (locateVarValues(profile->tokPtr(), scope, var, &scopeStart, &lineNo)) { if (flags & ReplaceValues) { // remove continuation lines with old values int lNo = skipContLines(lines, lineNo, false); @@ -234,24 +256,38 @@ void ProWriter::putVarValues(ProFile *profile, QStringList *lines, line.truncate(eqs + 1); // put new values foreach (const QString &v, values) - line += ((flags & MultiLine) ? QLatin1String(" \\\n ") : QLatin1String(" ")) + v; + line += ((flags & MultiLine) ? QLatin1String(" \\\n ") + indent : QString::fromLatin1(" ")) + v; } else { lineNo = skipContLines(lines, lineNo, true); QString added; foreach (const QString &v, values) - added += QLatin1String(" ") + v + QLatin1String(" \\\n"); + added += QLatin1String(" ") + indent + v + QLatin1String(" \\\n"); added.chop(3); lines->insert(lineNo, added); } } else { // Create & append new variable item QString added; + if (!scope.isEmpty()) { + if (scopeStart < 0) { + added = QLatin1Char('\n') + scope + QLatin1String(" {"); + } else { + QRegExp rx(QLatin1String("(\\s*") + scope + QLatin1String("\\s*:\\s*).*")); + if (rx.exactMatch(lines->at(scopeStart))) { + (*lines)[scopeStart].replace(0, rx.cap(1).length(), + QString(scope + QLatin1String(" {\n "))); + scopeStart = -1; + } + } + } int lNo = skipContLines(lines, lineNo, false); - if (lNo) + if (lNo != scopeStart + 1) added += QLatin1Char('\n'); - added += var + QLatin1String((flags & AppendOperator) ? " +=" : " ="); + added += indent + var + QLatin1String((flags & AppendOperator) ? " +=" : " ="); foreach (const QString &v, values) - added += ((flags & MultiLine) ? QLatin1String(" \\\n ") : QLatin1String(" ")) + v; + added += ((flags & MultiLine) ? QLatin1String(" \\\n ") + indent : QString::fromLatin1(" ")) + v; + if (!scope.isEmpty() && scopeStart < 0) + added += QLatin1String("\n}"); lines->insert(lNo, added); } } diff --git a/src/shared/proparser/prowriter.h b/src/shared/proparser/prowriter.h index d10c52b71c46feb241d571fba634d125de007550..c6ab1591847f2499a1bf75b3a99622fd1f3152ca 100644 --- a/src/shared/proparser/prowriter.h +++ b/src/shared/proparser/prowriter.h @@ -60,7 +60,8 @@ public: Q_DECLARE_FLAGS(PutFlags, PutFlag) static void putVarValues(ProFile *profile, QStringList *lines, - const QStringList &values, const QString &var, PutFlags flags); + const QStringList &values, const QString &var, PutFlags flags, + const QString &scope = QString()); static QList<int> removeVarValues(ProFile *profile, QStringList *lines, const QStringList &values, const QStringList &vars); @@ -70,7 +71,8 @@ public: const QDir &proFileDir, const QStringList &filePaths, const QStringList &vars); private: - static bool locateVarValues(const ushort *tokPtr, const QString &var, int *bestLine); + static bool locateVarValues(const ushort *tokPtr, + const QString &scope, const QString &var, int *scopeStart, int *bestLine); }; Q_DECLARE_OPERATORS_FOR_FLAGS(ProWriter::PutFlags) diff --git a/tests/auto/profilewriter/tst_profilewriter.cpp b/tests/auto/profilewriter/tst_profilewriter.cpp index 49097f4b9f614069e6cf37c0482c6a0a6ab7e557..34d0ee70bbdabab9336e93e96937cf454cad5a52 100644 --- a/tests/auto/profilewriter/tst_profilewriter.cpp +++ b/tests/auto/profilewriter/tst_profilewriter.cpp @@ -86,6 +86,7 @@ void tst_ProFileWriter::adds_data() { QTest::addColumn<int>("flags"); QTest::addColumn<QStringList>("values"); + QTest::addColumn<QString>("scope"); QTest::addColumn<QString>("input"); QTest::addColumn<QString>("output"); @@ -93,6 +94,7 @@ void tst_ProFileWriter::adds_data() int flags; const char *title; const char * const *values; + const char *scope; const char *input; const char *output; }; @@ -102,14 +104,14 @@ void tst_ProFileWriter::adds_data() static const Case cases[] = { { PW::AppendValues|PW::AppendOperator|PW::MultiLine, - "add new append multi", f_foo, + "add new append multi", f_foo, 0, "", "SOURCES += \\\n" " foo" }, { PW::AppendValues|PW::AppendOperator|PW::MultiLine, - "add new append multi after comment", f_foo, + "add new append multi after comment", f_foo, 0, "# test file", "# test file\n" "\n" @@ -118,7 +120,7 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AppendOperator|PW::MultiLine, - "add new append multi before newlines", f_foo, + "add new append multi before newlines", f_foo, 0, "\n" "\n" "\n", @@ -130,7 +132,7 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AppendOperator|PW::MultiLine, - "add new append multi after comment before newlines", f_foo, + "add new append multi after comment before newlines", f_foo, 0, "# test file\n" "\n" "\n" @@ -145,7 +147,7 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AssignOperator|PW::MultiLine, - "add new assign multi", f_foo, + "add new assign multi", f_foo, 0, "# test file", "# test file\n" "\n" @@ -154,7 +156,7 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AppendOperator|PW::OneLine, - "add new append oneline", f_foo, + "add new append oneline", f_foo, 0, "# test file", "# test file\n" "\n" @@ -162,7 +164,7 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AssignOperator|PW::OneLine, - "add new assign oneline", f_foo, + "add new assign oneline", f_foo, 0, "# test file", "# test file\n" "\n" @@ -170,7 +172,7 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AssignOperator|PW::OneLine, - "add new assign oneline after existing", f_foo, + "add new assign oneline after existing", f_foo, 0, "# test file\n" "\n" "HEADERS = foo", @@ -182,7 +184,7 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AppendOperator|PW::MultiLine, - "add new ignoring scoped", f_foo, + "add new ignoring scoped", f_foo, 0, "unix:SOURCES = some files", "unix:SOURCES = some files\n" "\n" @@ -191,21 +193,21 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AppendOperator|PW::MultiLine, - "add to existing", f_foo, + "add to existing (wrong operator)", f_foo, 0, "SOURCES = some files", "SOURCES = some files \\\n" " foo" }, { PW::AppendValues|PW::AppendOperator|PW::MultiLine, - "add to existing after comment", f_foo, + "add to existing after comment (wrong operator)", f_foo, 0, "SOURCES = some files # comment", "SOURCES = some files \\ # comment\n" " foo" }, { PW::AppendValues|PW::AppendOperator|PW::MultiLine, - "add to existing after comment line", f_foo, + "add to existing after comment line (wrong operator)", f_foo, 0, "SOURCES = some \\\n" " # comment\n" " files", @@ -216,14 +218,14 @@ void tst_ProFileWriter::adds_data() }, { PW::AppendValues|PW::AssignOperator|PW::MultiLine, - "add to existing", f_foo, + "add to existing", f_foo, 0, "SOURCES = some files", "SOURCES = some files \\\n" " foo" }, { PW::ReplaceValues|PW::AssignOperator|PW::MultiLine, - "replace existing multi", f_foo_bar, + "replace existing multi", f_foo_bar, 0, "SOURCES = some files", "SOURCES = \\\n" " foo \\\n" @@ -231,13 +233,13 @@ void tst_ProFileWriter::adds_data() }, { PW::ReplaceValues|PW::AssignOperator|PW::OneLine, - "replace existing oneline", f_foo_bar, + "replace existing oneline", f_foo_bar, 0, "SOURCES = some files", "SOURCES = foo bar" }, { PW::ReplaceValues|PW::AssignOperator|PW::OneLine, - "replace existing complex last", f_foo_bar, + "replace existing complex last", f_foo_bar, 0, "SOURCES = some \\\n" " # comment\n" " files", @@ -245,7 +247,7 @@ void tst_ProFileWriter::adds_data() }, { PW::ReplaceValues|PW::AssignOperator|PW::OneLine, - "replace existing complex middle 1", f_foo_bar, + "replace existing complex middle 1", f_foo_bar, 0, "SOURCES = some \\\n" " # comment\n" " files\n" @@ -255,7 +257,7 @@ void tst_ProFileWriter::adds_data() }, { PW::ReplaceValues|PW::AssignOperator|PW::OneLine, - "replace existing complex middle 2", f_foo_bar, + "replace existing complex middle 2", f_foo_bar, 0, "SOURCES = some \\\n" " # comment\n" " files\n" @@ -267,7 +269,7 @@ void tst_ProFileWriter::adds_data() }, { PW::ReplaceValues|PW::AssignOperator|PW::OneLine, - "replace existing complex middle 3", f_foo_bar, + "replace existing complex middle 3", f_foo_bar, 0, "SOURCES = some \\\n" " # comment\n" " files \\\n" @@ -277,6 +279,95 @@ void tst_ProFileWriter::adds_data() "\n" "HEADERS = blubb" }, + { + PW::AppendValues|PW::AppendOperator|PW::OneLine, + "scoped new / new scope", f_foo, "dog", + "# test file\n" + "SOURCES = yo", + "# test file\n" + "SOURCES = yo\n" + "\n" + "dog {\n" + " SOURCES += foo\n" + "}" + }, + { + PW::AppendValues|PW::AppendOperator|PW::OneLine, + "scoped new / extend scope", f_foo, "dog", + "# test file\n" + "dog {\n" + " HEADERS += yo\n" + "}", + "# test file\n" + "dog {\n" + " HEADERS += yo\n" + "\n" + " SOURCES += foo\n" + "}" + }, + { + PW::AppendValues|PW::AppendOperator|PW::OneLine, + "scoped new / extend elongated scope", f_foo, "dog", + "# test file\n" + "dog {\n" + " HEADERS += \\\n" + " yo \\\n" + " blubb\n" + "}", + "# test file\n" + "dog {\n" + " HEADERS += \\\n" + " yo \\\n" + " blubb\n" + "\n" + " SOURCES += foo\n" + "}" + }, + { + PW::AppendValues|PW::AppendOperator|PW::OneLine, + "scoped new / extend empty scope", f_foo, "dog", + "# test file\n" + "dog {\n" + "}", + "# test file\n" + "dog {\n" + " SOURCES += foo\n" + "}" + }, + { + PW::AppendValues|PW::AppendOperator|PW::OneLine, + "scoped new / extend oneline scope", f_foo, "dog", + "# test file\n" + "dog:HEADERS += yo", + "# test file\n" + "dog {\n" + " HEADERS += yo\n" + "\n" + " SOURCES += foo\n" + "}" + }, + { + PW::AppendValues|PW::AppendOperator|PW::MultiLine, + "scoped append", f_foo, "dog", + "# test file\n" + "dog:SOURCES = yo", + "# test file\n" + "dog:SOURCES = yo \\\n" + " foo" + }, + { + PW::AppendValues|PW::AppendOperator|PW::MultiLine, + "complex scoped append", f_foo, "dog", + "# test file\n" + "animal:!dog:SOURCES = yo", + "# test file\n" + "animal:!dog:SOURCES = yo\n" + "\n" + "dog {\n" + " SOURCES += \\\n" + " foo\n" + "}" + }, }; for (uint i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { @@ -284,6 +375,7 @@ void tst_ProFileWriter::adds_data() QTest::newRow(_case->title) << _case->flags << strList(_case->values) + << QString::fromLatin1(_case->scope) << QString::fromLatin1(_case->input) << QString::fromLatin1(_case->output); } @@ -293,6 +385,7 @@ void tst_ProFileWriter::adds() { QFETCH(int, flags); QFETCH(QStringList, values); + QFETCH(QString, scope); QFETCH(QString, input); QFETCH(QString, output); @@ -302,7 +395,7 @@ void tst_ProFileWriter::adds() ProFileParser parser(0, &parseHandler); ProFile *proFile = parser.parsedProFile(QLatin1String(BASE_DIR "/test.pro"), false, &input); QVERIFY(proFile); - PW::putVarValues(proFile, &lines, values, var, PW::PutFlags(flags)); + PW::putVarValues(proFile, &lines, values, var, PW::PutFlags(flags), scope); QCOMPARE(lines.join(QLatin1String("\n")), output); }