From c8db57e6639f2452379b50b3b43f9d8aac5a04ac Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@digia.com>
Date: Fri, 12 Sep 2014 12:57:00 +0200
Subject: [PATCH] VariableManager: Allow variables that are triggered by a
 prefix

E.g. "Env:<some environment var>".

Remove the special handling for the "Env:" varibale that was coded
into the VaribaleManager.

Change-Id: If8b074b66eeaa97903b41634f9a3c86dd73087d4
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
---
 src/plugins/coreplugin/variablemanager.cpp | 53 ++++++++++++++++++----
 src/plugins/coreplugin/variablemanager.h   |  5 +-
 2 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/src/plugins/coreplugin/variablemanager.cpp b/src/plugins/coreplugin/variablemanager.cpp
index bb5920f659d..ff1814c4654 100644
--- a/src/plugins/coreplugin/variablemanager.cpp
+++ b/src/plugins/coreplugin/variablemanager.cpp
@@ -58,6 +58,7 @@ class VariableManagerPrivate
 {
 public:
     QHash<QByteArray, VariableManager::StringFunction> m_map;
+    QHash<QByteArray, VariableManager::PrefixFunction> m_prefixMap;
     VMMapExpander m_macroExpander;
     QMap<QByteArray, QString> m_descriptions;
 };
@@ -177,6 +178,10 @@ VariableManager::VariableManager()
 {
     d = new VariableManagerPrivate;
     variableManagerInstance = this;
+
+    registerPrefix("Env", QCoreApplication::translate("Core::VariableManager", "Access environment variables."),
+                   [](const QString &value)
+                   { return QString::fromLocal8Bit(qgetenv(value.toLocal8Bit())); });
 }
 
 /*!
@@ -194,16 +199,25 @@ VariableManager::~VariableManager()
  */
 QString VariableManager::value(const QByteArray &variable, bool *found)
 {
-    if (variable.startsWith("Env:")) {
-        QByteArray ba = qgetenv(variable.data() + 4);
+    StringFunction sf = d->m_map.value(variable);
+    if (sf) {
         if (found)
-            *found = !ba.isNull();
-        return QString::fromLocal8Bit(ba);
+            *found = true;
+        return sf();
+    }
+
+    for (auto it = d->m_prefixMap.constBegin(); it != d->m_prefixMap.constEnd(); ++it) {
+        if (variable.startsWith(it.key())) {
+            PrefixFunction pf = it.value();
+            if (found)
+                *found = true;
+            return pf(QString::fromUtf8(variable.mid(it.key().count())));
+        }
     }
     if (found)
-        *found = d->m_map.contains(variable);
-    StringFunction f = d->m_map.value(variable);
-    return f ? f() : QString();
+        *found = false;
+
+    return QString();
 }
 
 /*!
@@ -231,11 +245,30 @@ Utils::AbstractMacroExpander *VariableManager::macroExpander()
     return &d->m_macroExpander;
 }
 
+/*!
+ * Makes the given string-valued \a prefix known to the variable manager,
+ * together with a localized \a description.
+ *
+ * The \a value PrefixFunction will be called and gets the full variable name
+ * with the prefix stripped as input.
+ *
+ * \sa registerVariables(), registerIntVariable(), registerFileVariables()
+ */
+void VariableManager::registerPrefix(const QByteArray &prefix, const QString &description,
+                                     const VariableManager::PrefixFunction &value)
+{
+    QByteArray tmp = prefix;
+    if (!tmp.endsWith(':'))
+        tmp.append(':');
+    d->m_descriptions.insert(tmp + "<value>", description);
+    d->m_prefixMap.insert(tmp, value);
+}
+
 /*!
  * Makes the given string-valued \a variable known to the variable manager,
  * together with a localized \a description.
  *
- * \sa registerFileVariables(), registerIntVariable()
+ * \sa registerFileVariables(), registerIntVariable(), registerPrefix()
  */
 void VariableManager::registerVariable(const QByteArray &variable,
     const QString &description, const StringFunction &value)
@@ -248,7 +281,7 @@ void VariableManager::registerVariable(const QByteArray &variable,
  * Makes the given integral-valued \a variable known to the variable manager,
  * together with a localized \a description.
  *
- * \sa registerVariable(), registerFileVariables()
+ * \sa registerVariable(), registerFileVariables(), registerPrefix()
  */
 void VariableManager::registerIntVariable(const QByteArray &variable,
     const QString &description, const VariableManager::IntFunction &value)
@@ -265,6 +298,8 @@ void VariableManager::registerIntVariable(const QByteArray &variable,
  * For example \c{registerFileVariables("CurrentDocument", tr("Current Document"))} registers
  * variables such as \c{CurrentDocument:FilePath} with description
  * "Current Document: Full path including file name."
+ *
+ * \sa registerVariable(), registerIntVariable(), registerPrefix()
  */
 void VariableManager::registerFileVariables(const QByteArray &prefix,
     const QString &heading, const StringFunction &base)
diff --git a/src/plugins/coreplugin/variablemanager.h b/src/plugins/coreplugin/variablemanager.h
index a9d08b65baf..49290efc7d9 100644
--- a/src/plugins/coreplugin/variablemanager.h
+++ b/src/plugins/coreplugin/variablemanager.h
@@ -51,10 +51,13 @@ public:
     static QString expandedString(const QString &stringWithVariables);
     static Utils::AbstractMacroExpander *macroExpander();
 
-
+    typedef std::function<QString(QString)> PrefixFunction;
     typedef std::function<QString()> StringFunction;
     typedef std::function<int()> IntFunction;
 
+    static void registerPrefix(const QByteArray &prefix,
+        const QString &description, const PrefixFunction &value);
+
     static void registerVariable(const QByteArray &variable,
         const QString &description, const StringFunction &value);
 
-- 
GitLab