diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp index 75f4ea6eecd..fa61313144f 100644 --- a/src/libs/utils/environment.cpp +++ b/src/libs/utils/environment.cpp @@ -40,10 +40,15 @@ Q_GLOBAL_STATIC_WITH_ARGS(Environment, staticSystemEnvironment, Q_GLOBAL_STATIC(QVector, environmentProviders) +NameValueItems Environment::diff(const Environment &other, bool checkAppendPrepend) const +{ + return m_dict.diff(other.m_dict, checkAppendPrepend); +} + QProcessEnvironment Environment::toProcessEnvironment() const { QProcessEnvironment result; - for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) { + for (auto it = m_dict.m_values.constBegin(); it != m_dict.m_values.constEnd(); ++it) { if (it.value().second) result.insert(it.key().name, expandedValueForKey(key(it))); } @@ -52,28 +57,28 @@ QProcessEnvironment Environment::toProcessEnvironment() const void Environment::appendOrSetPath(const FilePath &value) { - QTC_CHECK(value.osType() == m_osType); + QTC_CHECK(value.osType() == osType()); if (value.isEmpty()) return; appendOrSet("PATH", value.nativePath(), - QString(OsSpecificAspects::pathListSeparator(m_osType))); + QString(OsSpecificAspects::pathListSeparator(osType()))); } void Environment::prependOrSetPath(const FilePath &value) { - QTC_CHECK(value.osType() == m_osType); + QTC_CHECK(value.osType() == osType()); if (value.isEmpty()) return; prependOrSet("PATH", value.nativePath(), - QString(OsSpecificAspects::pathListSeparator(m_osType))); + QString(OsSpecificAspects::pathListSeparator(osType()))); } void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep) { QTC_ASSERT(!key.contains('='), return ); - const auto it = findKey(key); - if (it == m_values.end()) { - m_values.insert(DictKey(key, nameCaseSensitivity()), qMakePair(value, true)); + const auto it = m_dict.findKey(key); + if (it == m_dict.m_values.end()) { + m_dict.m_values.insert(DictKey(key, m_dict.nameCaseSensitivity()), qMakePair(value, true)); } else { // Append unless it is already there const QString toAppend = sep + value; @@ -85,9 +90,9 @@ void Environment::appendOrSet(const QString &key, const QString &value, const QS void Environment::prependOrSet(const QString &key, const QString &value, const QString &sep) { QTC_ASSERT(!key.contains('='), return ); - const auto it = findKey(key); - if (it == m_values.end()) { - m_values.insert(DictKey(key, nameCaseSensitivity()), qMakePair(value, true)); + const auto it = m_dict.findKey(key); + if (it == m_dict.m_values.end()) { + m_dict.m_values.insert(DictKey(key, m_dict.nameCaseSensitivity()), qMakePair(value, true)); } else { // Prepend unless it is already there const QString toPrepend = value + sep; @@ -98,8 +103,8 @@ void Environment::prependOrSet(const QString &key, const QString &value, const Q void Environment::prependOrSetLibrarySearchPath(const FilePath &value) { - QTC_CHECK(value.osType() == m_osType); - switch (m_osType) { + QTC_CHECK(value.osType() == osType()); + switch (osType()) { case OsTypeWindows: { const QChar sep = ';'; prependOrSet("PATH", value.nativePath(), QString(sep)); @@ -137,8 +142,8 @@ Environment Environment::systemEnvironment() void Environment::setupEnglishOutput() { - set("LC_MESSAGES", "en_US.utf8"); - set("LANGUAGE", "en_US:en"); + m_dict.set("LC_MESSAGES", "en_US.utf8"); + m_dict.set("LANGUAGE", "en_US:en"); } static FilePath searchInDirectory(const QStringList &execs, @@ -166,7 +171,7 @@ QStringList Environment::appendExeExtensions(const QString &executable) const { QStringList execs(executable); const QFileInfo fi(executable); - if (m_osType == OsTypeWindows) { + if (osType() == OsTypeWindows) { // Check all the executable extensions on windows: // PATHEXT is only used if the executable has no extension if (fi.suffix().isEmpty()) { @@ -202,7 +207,7 @@ bool Environment::isSameExecutable(const QString &exe1, const QString &exe2) con QString Environment::expandedValueForKey(const QString &key) const { - return expandVariables(value(key)); + return expandVariables(m_dict.value(key)); } static FilePath searchInDirectoriesHelper(const Environment &env, @@ -308,7 +313,7 @@ FilePaths Environment::path() const FilePaths Environment::pathListValue(const QString &varName) const { const QStringList pathComponents = expandedValueForKey(varName).split( - OsSpecificAspects::pathListSeparator(m_osType), Qt::SkipEmptyParts); + OsSpecificAspects::pathListSeparator(osType()), Qt::SkipEmptyParts); return transform(pathComponents, &FilePath::fromUserInput); } @@ -333,12 +338,12 @@ QString Environment::expandVariables(const QString &input) const { QString result = input; - if (m_osType == OsTypeWindows) { + if (osType() == OsTypeWindows) { for (int vStart = -1, i = 0; i < result.length(); ) { if (result.at(i++) == '%') { if (vStart > 0) { - const auto it = findKey(result.mid(vStart, i - vStart - 1)); - if (it != m_values.constEnd()) { + const auto it = m_dict.findKey(result.mid(vStart, i - vStart - 1)); + if (it != m_dict.m_values.constEnd()) { result.replace(vStart - 1, i - vStart + 1, it->first); i = vStart - 1 + it->first.length(); vStart = -1; diff --git a/src/libs/utils/environment.h b/src/libs/utils/environment.h index 06ab65725c1..7aa42ab2ad9 100644 --- a/src/libs/utils/environment.h +++ b/src/libs/utils/environment.h @@ -40,13 +40,27 @@ QT_END_NAMESPACE namespace Utils { -class QTCREATOR_UTILS_EXPORT Environment final : public NameValueDictionary +class QTCREATOR_UTILS_EXPORT Environment final { public: - using NameValueDictionary::NameValueDictionary; + Environment() : m_dict(HostOsInfo::hostOs()) {} + explicit Environment(OsType osType) : m_dict(osType) {} + explicit Environment(const QStringList &env, OsType osType = HostOsInfo::hostOs()) + : m_dict(env, osType) {} + explicit Environment(const NameValuePairs &nameValues) : m_dict(nameValues) {} + explicit Environment(const NameValueDictionary &dict) : m_dict(dict) {} - static Environment systemEnvironment(); + QString value(const QString &key) const { return m_dict.value(key); } + bool hasKey(const QString &key) const { return m_dict.hasKey(key); } + void set(const QString &key, const QString &value, bool enabled = true) { m_dict.set(key, value, enabled); } + void unset(const QString &key) { m_dict.unset(key); } + void modify(const NameValueItems &items) { m_dict.modify(items); } + + int size() const { return m_dict.size(); } + void clear() { return m_dict.clear(); } + + QStringList toStringList() const { return m_dict.toStringList(); } QProcessEnvironment toProcessEnvironment() const; void appendOrSet(const QString &key, const QString &value, const QString &sep = QString()); @@ -81,8 +95,38 @@ public: FilePath expandVariables(const FilePath &input) const; QStringList expandVariables(const QStringList &input) const; + OsType osType() const { return m_dict.osType(); } + QString userName() const; + + using const_iterator = NameValueMap::const_iterator; // FIXME: avoid + NameValueDictionary toDictionary() const { return m_dict; } // FIXME: avoid + NameValueItems diff(const Environment &other, bool checkAppendPrepend = false) const; // FIXME: avoid + + QString key(const_iterator it) const { return m_dict.key(it); } // FIXME: avoid + QString value(const_iterator it) const { return m_dict.value(it); } // FIXME: avoid + bool isEnabled(const_iterator it) const { return m_dict.isEnabled(it); } // FIXME: avoid + + const_iterator constBegin() const { return m_dict.constBegin(); } // FIXME: avoid + const_iterator constEnd() const { return m_dict.constEnd(); } // FIXME: avoid + const_iterator constFind(const QString &name) const { return m_dict.constFind(name); } // FIXME: avoid + + friend bool operator!=(const Environment &first, const Environment &second) + { + return first.m_dict != second.m_dict; + } + + friend bool operator==(const Environment &first, const Environment &second) + { + return first.m_dict == second.m_dict; + } + + static Environment systemEnvironment(); + static void modifySystemEnvironment(const EnvironmentItems &list); // use with care!!! static void setSystemEnvironment(const Environment &environment); // don't use at all!!! + +private: + NameValueDictionary m_dict; }; class QTCREATOR_UTILS_EXPORT EnvironmentChange final diff --git a/src/libs/utils/environmentmodel.cpp b/src/libs/utils/environmentmodel.cpp index a5cb1b4958a..d7938a4fdae 100644 --- a/src/libs/utils/environmentmodel.cpp +++ b/src/libs/utils/environmentmodel.cpp @@ -28,12 +28,15 @@ #include "environment.h" namespace Utils { -const Environment &EnvironmentModel::baseEnvironment() const + +Environment EnvironmentModel::baseEnvironment() const { - return static_cast(baseNameValueDictionary()); + return Environment(baseNameValueDictionary()); } + void EnvironmentModel::setBaseEnvironment(const Environment &env) { - setBaseNameValueDictionary(env); + setBaseNameValueDictionary(env.toDictionary()); } + } // namespace Utils diff --git a/src/libs/utils/environmentmodel.h b/src/libs/utils/environmentmodel.h index 5457bdb0497..b64518b6ae9 100644 --- a/src/libs/utils/environmentmodel.h +++ b/src/libs/utils/environmentmodel.h @@ -36,7 +36,7 @@ class QTCREATOR_UTILS_EXPORT EnvironmentModel : public NameValueModel Q_OBJECT public: - const Environment &baseEnvironment() const; + Environment baseEnvironment() const; void setBaseEnvironment(const Environment &env); }; diff --git a/src/libs/utils/namevaluedictionary.h b/src/libs/utils/namevaluedictionary.h index 30721915c67..7e302796705 100644 --- a/src/libs/utils/namevaluedictionary.h +++ b/src/libs/utils/namevaluedictionary.h @@ -101,6 +101,7 @@ public: } protected: + friend class Environment; NameValueMap::iterator findKey(const QString &key); const_iterator findKey(const QString &key) const;