changeset 2921:0a4428aad512

variable substitution with default value
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 07 Nov 2018 12:59:03 +0100
parents ad0e7def3338
children 40131f0c25b5
files Core/Toolbox.cpp UnitTestsSources/UnitTestsMain.cpp
diffstat 2 files changed, 58 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Toolbox.cpp	Wed Nov 07 11:13:30 2018 +0100
+++ b/Core/Toolbox.cpp	Wed Nov 07 12:59:03 2018 +0100
@@ -1514,12 +1514,54 @@
       Out operator()(const boost::smatch& what,
                      Out out) const
       {
-        Dictionary::const_iterator found = dictionary_.find(what[1]);
+        if (!what[1].str().empty())
+        {
+          // Variable without a default value
+          Dictionary::const_iterator found = dictionary_.find(what[1]);
     
-        if (found != dictionary_.end())
+          if (found != dictionary_.end())
+          {
+            const std::string& value = found->second;
+            out = std::copy(value.begin(), value.end(), out);
+          }
+        }
+        else
         {
-          const std::string& value = found->second;
-          out = std::copy(value.begin(), value.end(), out);
+          // Variable with a default value
+          std::string key;
+          std::string defaultValue;
+          
+          if (!what[2].str().empty())
+          {
+            key = what[2].str();
+            defaultValue = what[3].str();
+          }
+          else if (!what[4].str().empty())
+          {
+            key = what[4].str();
+            defaultValue = what[5].str();
+          }
+          else if (!what[6].str().empty())
+          {
+            key = what[6].str();
+            defaultValue = what[7].str();
+          }
+          else
+          {
+            throw OrthancException(ErrorCode_InternalError);
+          }
+
+          Dictionary::const_iterator found = dictionary_.find(key);
+    
+          if (found == dictionary_.end())
+          {
+            out = std::copy(defaultValue.begin(), defaultValue.end(), out);
+          }
+          else
+          {
+            const std::string& value = found->second;
+            out = std::copy(value.begin(), value.end(), out);
+          }
         }
     
         return out;
@@ -1531,7 +1573,10 @@
   std::string Toolbox::SubstituteVariables(const std::string& source,
                                            const std::map<std::string, std::string>& dictionary)
   {
-    const boost::regex pattern("\\${(.*?)}");
+    const boost::regex pattern("\\${([^:]*?)}|"                 // ${what[1]}
+                               "\\${([^:]*?):-([^'\"]*?)}|"     // ${what[2]:-what[3]}
+                               "\\${([^:]*?):-\"([^\"]*?)\"}|"  // ${what[4]:-"what[5]"}
+                               "\\${([^:]*?):-'([^']*?)'}");    // ${what[6]:-'what[7]'}
 
     VariableFormatter formatter(dictionary);
 
--- a/UnitTestsSources/UnitTestsMain.cpp	Wed Nov 07 11:13:30 2018 +0100
+++ b/UnitTestsSources/UnitTestsMain.cpp	Wed Nov 07 12:59:03 2018 +0100
@@ -1173,12 +1173,20 @@
               "Hello ${WORLD}\r\nWorld ${HELLO}\r\nDone ${WORLD}\r\n",
               env));
 
+  ASSERT_EQ("world A a B world C 'c' D {\"a\":\"b\"} E ",
+            Toolbox::SubstituteVariables(
+              "${WORLD} A ${WORLD2:-a} B ${WORLD:-b} C ${WORLD2:-\"'c'\"} D ${WORLD2:-'{\"a\":\"b\"}'} E ${WORLD2:-}",
+              env));
+  
   SystemToolbox::GetEnvironmentVariables(env);
   ASSERT_TRUE(env.find("NOPE") == env.end());
 
   // The "PATH" environment variable should always be available on
   // machines running the unit tests
   ASSERT_TRUE(env.find("PATH") != env.end());
+
+  ASSERT_EQ("A" + env["PATH"] + "B",
+            Toolbox::SubstituteVariables("A${PATH}B", env));
 }