From 3b72fc3e387d3f28fc5dc599f31792ba9eb4fe2d Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@Germany>
Date: Wed, 2 Mar 2011 14:11:30 +0100
Subject: [PATCH] ENH: support default values in string expansion

- syntax as per Bourne/Korn shell
      ${parameter:-defValue}

  If parameter is unset or null, the \c defValue is substituted.
  Otherwise, the value of parameter is substituted.
---
 applications/test/string/Test-string.C        |  5 +-
 .../primitives/strings/stringOps/stringOps.C  | 81 ++++++++++++++++++-
 .../primitives/strings/stringOps/stringOps.H  | 51 +++++++++++-
 3 files changed, 129 insertions(+), 8 deletions(-)

diff --git a/applications/test/string/Test-string.C b/applications/test/string/Test-string.C
index e7ed6103323..6d9bfd7babb 100644
--- a/applications/test/string/Test-string.C
+++ b/applications/test/string/Test-string.C
@@ -40,8 +40,9 @@ int main(int argc, char *argv[])
 {
     string test
     (
-        "  $HOME kjhkjhkjh \" \\$HOME/tyetyery ${FOAM_RUN} \n ; hkjh ;$ with "
-        " $(DONOTSUBST) some other ${USER} entries   "
+        "  $HOME kjhkjhkjh \" \\$HOME/tyetyery $; ${FOAM_RUN} \n $; hkjh;"
+        " $(DONOTSUBST) some other <${USER}> with '${__UNKNOWN:-some default}'"
+        " value "
     );
 
     dictionary dict;
diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
index d8f665a58c7..2fbadd3a6ae 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
+++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
@@ -66,10 +66,23 @@ Foam::string& Foam::stringOps::inplaceExpand
             string::size_type endVar = begVar;
             string::size_type delim = 0;
 
+            // The position of the ":-" default value
+            string::size_type altPos = string::npos;
+
             if (s[begVar+1] == '{')
             {
                 endVar = s.find('}', begVar);
                 delim = 1;
+
+                // looks like ${parameter:-word}
+                if (endVar != string::npos)
+                {
+                    altPos = s.find(":-", begVar);
+                    if (altPos != string::npos && altPos > endVar)
+                    {
+                        altPos = string::npos;
+                    }
+                }
             }
             else
             {
@@ -110,11 +123,26 @@ Foam::string& Foam::stringOps::inplaceExpand
                     s.substr
                     (
                         begVar + 1 + delim,
-                        endVar - begVar - 2*delim
+                        (
+                            (altPos == string::npos ? endVar : altPos)
+                          - begVar - 2*delim
+                        )
                     ),
                     false
                 );
 
+                std::string altValue;
+                if (altPos != string::npos)
+                {
+                    // had ":-" default value
+                    altValue = s.substr
+                    (
+                        altPos + 2,
+                        endVar - altPos - 2*delim
+                    );
+                }
+
+
                 HashTable<string, word, string::hash>::const_iterator fnd =
                     mapping.find(varName);
 
@@ -128,6 +156,17 @@ Foam::string& Foam::stringOps::inplaceExpand
                     );
                     begVar += (*fnd).size();
                 }
+                else if (altPos != string::npos)
+                {
+                    // use alternative provided
+                    s.std::string::replace
+                    (
+                        begVar,
+                        endVar - begVar + 1,
+                        altValue
+                    );
+                    begVar += altValue.size();
+                }
                 else
                 {
                     s.std::string::replace
@@ -312,10 +351,23 @@ Foam::string& Foam::stringOps::inplaceExpand
             string::size_type endVar = begVar;
             string::size_type delim = 0;
 
+            // The position of the ":-" default value
+            string::size_type altPos = string::npos;
+
             if (s[begVar+1] == '{')
             {
                 endVar = s.find('}', begVar);
                 delim = 1;
+
+                // looks like ${parameter:-word}
+                if (endVar != string::npos)
+                {
+                    altPos = s.find(":-", begVar);
+                    if (altPos != string::npos && altPos > endVar)
+                    {
+                        altPos = string::npos;
+                    }
+                }
             }
             else
             {
@@ -350,11 +402,25 @@ Foam::string& Foam::stringOps::inplaceExpand
                     s.substr
                     (
                         begVar + 1 + delim,
-                        endVar - begVar - 2*delim
+                        (
+                            (altPos == string::npos ? endVar : altPos)
+                          - begVar - 2*delim
+                        )
                     ),
                     false
                 );
 
+                std::string altValue;
+                if (altPos != string::npos)
+                {
+                    // had ":-" default value
+                    altValue = s.substr
+                    (
+                        altPos + 2,
+                        endVar - altPos - 2*delim
+                    );
+                }
+
                 const string varValue = getEnv(varName);
                 if (varValue.size())
                 {
@@ -367,6 +433,17 @@ Foam::string& Foam::stringOps::inplaceExpand
                     );
                     begVar += varValue.size();
                 }
+                else if (altPos != string::npos)
+                {
+                    // use alternative provided
+                    s.std::string::replace
+                    (
+                        begVar,
+                        endVar - begVar + 1,
+                        altValue
+                    );
+                    begVar += altValue.size();
+                }
                 else if (allowEmpty)
                 {
                     s.std::string::replace
diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H
index cfd79937395..63a4679c9bf 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H
+++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H
@@ -55,7 +55,17 @@ namespace stringOps
     //  -# variables
     //    - "$VAR", "${VAR}"
     //
-    //  Any unknown entries are removed
+    //  Supports default values as per the Bourne/Korn shell.
+    //  \code
+    //      "${parameter:-defValue}"
+    //  \endcode
+    //  If parameter is unset or null, the \c defValue is substituted.
+    //  Otherwise, the value of parameter is substituted.
+    //
+    //  Any unknown entries are removed silently.
+    //
+    //  Malformed entries (eg, brace mismatch, sigil followed by bad character)
+    //  are left as is.
     //
     //  \note the leading sigil can be changed to avoid conflicts with other
     //  string expansions
@@ -72,7 +82,17 @@ namespace stringOps
     //  -# variables
     //    - "$VAR", "${VAR}"
     //
-    //  Any unknown entries are removed
+    //  Supports default values as per the Bourne/Korn shell.
+    //  \code
+    //      "${parameter:-defValue}"
+    //  \endcode
+    //  If parameter is unset or null, the \c defValue is substituted.
+    //  Otherwise, the value of parameter is substituted.
+    //
+    //  Any unknown entries are removed silently.
+    //
+    //  Malformed entries (eg, brace mismatch, sigil followed by bad character)
+    //  are left as is.
     //
     //  \note the leading sigil can be changed to avoid conflicts with other
     //  string expansions
@@ -128,7 +148,18 @@ namespace stringOps
     //    - leading "~user" : home directory for specified user
     //    - leading "~OpenFOAM" : site/user OpenFOAM configuration directory
     //
-    //  Any unknown entries are removed silently if allowEmpty is true
+    //  Supports default values as per the Bourne/Korn shell.
+    //  \code
+    //      "${parameter:-defValue}"
+    //  \endcode
+    //  If parameter is unset or null, the \c defValue is substituted.
+    //  Otherwise, the value of parameter is substituted.
+    //
+    //  Any unknown entries are removed silently, if allowEmpty is true.
+    //
+    //  Malformed entries (eg, brace mismatch, sigil followed by bad character)
+    //  are left as is.
+    //
     //  \sa
     //  Foam::findEtcFile
     string expand
@@ -149,7 +180,19 @@ namespace stringOps
     //    - leading "~user" : home directory for specified user
     //    - leading "~OpenFOAM" : site/user OpenFOAM configuration directory
     //
-    //  Any unknown entries are removed silently if allowEmpty is true
+    //  Supports default values as per the Bourne/Korn shell.
+    //  \code
+    //      "${parameter:-defValue}"
+    //  \endcode
+    //  If parameter is unset or null, the \c defValue is substituted.
+    //  Otherwise, the value of parameter is substituted.
+    //
+    //  Any unknown entries are removed silently, if allowEmpty is true.
+    //
+    //  Malformed entries (eg, brace mismatch, sigil followed by bad character)
+    //  are left as is.
+    //
+    //  Any unknown entries are removed silently if allowEmpty is true.
     //  \sa
     //  Foam::findEtcFile
     string& inplaceExpand
-- 
GitLab