Utils::Environment: Consider target OS type when sorting

That is, use case-insensitive sorting on Windows, so that e.g. "Path"
will not appear after "PROCESSOR_REVISION".

Fixes: QTCREATORBUG-22786
Change-Id: I42d469b6079037d1062dbd5b273f5aa8ade25e79
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2019-08-16 16:42:14 +02:00
parent c1e2720bed
commit 567a0db6dd
7 changed files with 47 additions and 27 deletions

View File

@@ -175,7 +175,7 @@ QProcessEnvironment ProcessCreator::processEnvironment() const
const Utils::Environment &env = m_environment;
for (auto it = env.constBegin(); it != env.constEnd(); ++it) {
if (env.isEnabled(it))
processEnvironment.insert(it.key(), env.expandedValueForKey(env.key(it)));
processEnvironment.insert(env.key(it), env.expandedValueForKey(env.key(it)));
}
return processEnvironment;

View File

@@ -46,7 +46,7 @@ QProcessEnvironment Environment::toProcessEnvironment() const
QProcessEnvironment result;
for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
if (it.value().second)
result.insert(it.key(), expandedValueForKey(key(it)));
result.insert(it.key().name, expandedValueForKey(key(it)));
}
return result;
}
@@ -68,7 +68,7 @@ void Environment::appendOrSet(const QString &key, const QString &value, const QS
QTC_ASSERT(!key.contains('='), return );
const auto it = findKey(key);
if (it == m_values.end()) {
m_values.insert(key, qMakePair(value, true));
m_values.insert(DictKey(key, nameCaseSensitivity()), qMakePair(value, true));
} else {
// Append unless it is already there
const QString toAppend = sep + value;
@@ -82,7 +82,7 @@ void Environment::prependOrSet(const QString &key, const QString &value, const Q
QTC_ASSERT(!key.contains('='), return );
const auto it = findKey(key);
if (it == m_values.end()) {
m_values.insert(key, qMakePair(value, true));
m_values.insert(DictKey(key, nameCaseSensitivity()), qMakePair(value, true));
} else {
// Prepend unless it is already there
const QString toPrepend = value + sep;
@@ -361,7 +361,7 @@ QString Environment::expandVariables(const QString &input) const
}
} else if (state == BRACEDVARIABLE) {
if (c == '}') {
const_iterator it = m_values.constFind(result.mid(vStart, i - 1 - vStart));
const_iterator it = constFind(result.mid(vStart, i - 1 - vStart));
if (it != constEnd()) {
result.replace(vStart - 2, i - vStart + 2, it->first);
i = vStart - 2 + it->first.length();
@@ -370,7 +370,7 @@ QString Environment::expandVariables(const QString &input) const
}
} else if (state == VARIABLE) {
if (!c.isLetterOrNumber() && c != '_') {
const_iterator it = m_values.constFind(result.mid(vStart, i - vStart - 1));
const_iterator it = constFind(result.mid(vStart, i - vStart - 1));
if (it != constEnd()) {
result.replace(vStart - 1, i - vStart, it->first);
i = vStart - 1 + it->first.length();
@@ -380,7 +380,7 @@ QString Environment::expandVariables(const QString &input) const
}
}
if (state == VARIABLE) {
const_iterator it = m_values.constFind(result.mid(vStart));
const_iterator it = constFind(result.mid(vStart));
if (it != constEnd())
result.replace(vStart - 1, result.length() - vStart + 1, it->first);
}

View File

@@ -55,7 +55,7 @@ NameValueDictionary::NameValueDictionary(const NameValuePairs &nameValues)
NameValueMap::iterator NameValueDictionary::findKey(const QString &key)
{
for (auto it = m_values.begin(); it != m_values.end(); ++it) {
if (key.compare(it.key(), nameCaseSensitivity()) == 0)
if (key.compare(it.key().name, nameCaseSensitivity()) == 0)
return it;
}
return m_values.end();
@@ -64,7 +64,7 @@ NameValueMap::iterator NameValueDictionary::findKey(const QString &key)
NameValueMap::const_iterator NameValueDictionary::findKey(const QString &key) const
{
for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
if (key.compare(it.key(), nameCaseSensitivity()) == 0)
if (key.compare(it.key().name, nameCaseSensitivity()) == 0)
return it;
}
return m_values.constEnd();
@@ -75,7 +75,7 @@ QStringList NameValueDictionary::toStringList() const
QStringList result;
for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
if (it.value().second)
result.append(it.key() + '=' + it.value().first);
result.append(it.key().name + '=' + it.value().first);
}
return result;
}
@@ -86,7 +86,7 @@ void NameValueDictionary::set(const QString &key, const QString &value, bool ena
const auto it = findKey(key);
const auto valuePair = qMakePair(value, enabled);
if (it == m_values.end())
m_values.insert(key, valuePair);
m_values.insert(DictKey(key, nameCaseSensitivity()), valuePair);
else
it.value() = valuePair;
}
@@ -136,17 +136,17 @@ NameValueItems NameValueDictionary::diff(const NameValueDictionary &other, bool
NameValueItems result;
while (thisIt != constEnd() || otherIt != other.constEnd()) {
if (thisIt == constEnd()) {
result.append({otherIt.key(), otherIt.value().first,
result.append({other.key(otherIt), other.value(otherIt),
otherIt.value().second ? NameValueItem::SetEnabled : NameValueItem::SetDisabled});
++otherIt;
} else if (otherIt == other.constEnd()) {
result.append(NameValueItem(thisIt.key(), QString(), NameValueItem::Unset));
result.append(NameValueItem(key(thisIt), QString(), NameValueItem::Unset));
++thisIt;
} else if (thisIt.key() < otherIt.key()) {
result.append(NameValueItem(thisIt.key(), QString(), NameValueItem::Unset));
result.append(NameValueItem(key(thisIt), QString(), NameValueItem::Unset));
++thisIt;
} else if (thisIt.key() > otherIt.key()) {
result.append({otherIt.key(), otherIt.value().first,
result.append({other.key(otherIt), otherIt.value().first,
otherIt.value().second ? NameValueItem::SetEnabled : NameValueItem::SetDisabled});
++otherIt;
} else {
@@ -160,15 +160,15 @@ NameValueItems NameValueDictionary::diff(const NameValueDictionary &other, bool
QString appended = newValue.right(newValue.size() - oldValue.size());
if (appended.startsWith(OsSpecificAspects::pathListSeparator(osType())))
appended.remove(0, 1);
result.append(NameValueItem(otherIt.key(), appended, NameValueItem::Append));
result.append(NameValueItem(other.key(otherIt), appended, NameValueItem::Append));
} else if (checkAppendPrepend && newValue.endsWith(oldValue)
&& oldEnabled == newEnabled) {
QString prepended = newValue.left(newValue.size() - oldValue.size());
if (prepended.endsWith(OsSpecificAspects::pathListSeparator(osType())))
prepended.chop(1);
result.append(NameValueItem(otherIt.key(), prepended, NameValueItem::Prepend));
result.append(NameValueItem(other.key(otherIt), prepended, NameValueItem::Prepend));
} else {
result.append({otherIt.key(), newValue, newEnabled
result.append({other.key(otherIt), newValue, newEnabled
? NameValueItem::SetEnabled : NameValueItem::SetDisabled});
}
}
@@ -181,7 +181,7 @@ NameValueItems NameValueDictionary::diff(const NameValueDictionary &other, bool
bool NameValueDictionary::hasKey(const QString &key) const
{
return m_values.contains(key);
return findKey(key) != constEnd();
}
OsType NameValueDictionary::osType() const

View File

@@ -31,9 +31,23 @@
namespace Utils {
class QTCREATOR_UTILS_EXPORT DictKey
{
public:
DictKey(const QString &name, Qt::CaseSensitivity cs) : name(name), caseSensitivity(cs) {}
QString name;
Qt::CaseSensitivity caseSensitivity;
};
inline bool operator<(const DictKey &k1, const DictKey &k2)
{
return k1.name.compare(k2.name, k1.caseSensitivity) < 0;
}
inline bool operator>(const DictKey &k1, const DictKey &k2) { return k2 < k1; }
using NameValuePair = std::pair<QString, QString>;
using NameValuePairs = QVector<NameValuePair>;
using NameValueMap = QMap<QString, QPair<QString, bool>>;
using NameValueMap = QMap<DictKey, QPair<QString, bool>>;
class QTCREATOR_UTILS_EXPORT NameValueDictionary
{
@@ -62,7 +76,7 @@ public:
void clear();
int size() const;
QString key(const_iterator it) const { return it.key(); }
QString key(const_iterator it) const { return it.key().name; }
QString value(const_iterator it) const { return it.value().first; }
bool isEnabled(const_iterator it) const { return it.value().second; }

View File

@@ -57,8 +57,10 @@ public:
int findInChanges(const QString &name) const
{
for (int i = 0; i < m_items.size(); ++i)
if (m_items.at(i).name == name)
if (m_items.at(i).name.compare(name,
m_baseNameValueDictionary.nameCaseSensitivity()) == 0) {
return i;
}
return -1;
}
@@ -69,7 +71,7 @@ public:
for (it = m_resultNameValueDictionary.constBegin();
it != m_resultNameValueDictionary.constEnd();
++it, ++i)
if (m_resultNameValueDictionary.key(it) > name)
if (it.key() > DictKey(name, m_resultNameValueDictionary.nameCaseSensitivity()))
return i;
return m_resultNameValueDictionary.size();
}
@@ -81,8 +83,10 @@ public:
for (it = m_resultNameValueDictionary.constBegin();
it != m_resultNameValueDictionary.constEnd();
++it, ++i)
if (m_resultNameValueDictionary.key(it) == name)
if (m_resultNameValueDictionary.key(it)
.compare(name, m_resultNameValueDictionary.nameCaseSensitivity()) == 0) {
return i;
}
return -1;
}

View File

@@ -139,8 +139,10 @@ bool MakeInstallStep::init()
if (cmd.environment.size() > 0) {
Environment env = processParameters()->environment();
for (auto it = cmd.environment.constBegin(); it != cmd.environment.constEnd(); ++it) {
if (cmd.environment.isEnabled(it))
env.set(it.key(), cmd.environment.expandedValueForKey(cmd.environment.key(it)));
if (cmd.environment.isEnabled(it)) {
const QString key = cmd.environment.key(it);
env.set(key, cmd.environment.expandedValueForKey(key));
}
}
processParameters()->setEnvironment(env);
}

View File

@@ -198,7 +198,7 @@ void tst_Environment::environmentSetNewWindows()
env.set("bar", "baz");
QCOMPARE(env.toStringList(), QStringList({"Foo=bar", "Hi=HO", "bar=baz"}));
QCOMPARE(env.toStringList(), QStringList({"bar=baz", "Foo=bar", "Hi=HO"}));
}
void tst_Environment::environmentSetNewUnix()