diff --git a/applications/test/string/Test-string.C b/applications/test/string/Test-string.C
index d117f50c41..e9639c4736 100644
--- a/applications/test/string/Test-string.C
+++ b/applications/test/string/Test-string.C
@@ -22,11 +22,13 @@ License
along with OpenFOAM. If not, see .
Description
+ Test some string functionality
\*---------------------------------------------------------------------------*/
#include "string.H"
#include "stringOps.H"
+#include "dictionary.H"
#include "IOstreams.H"
using namespace Foam;
@@ -38,9 +40,19 @@ int main(int argc, char *argv[])
{
string test
(
- " $HOME kjhkjhkjh \" \\$HOME/tyetyery ${FOAM_RUN} \n ; hkjh ;$ "
+ " $HOME kjhkjhkjh \" \\$HOME/tyetyery ${FOAM_RUN} \n ; hkjh ;$ with "
+ " $(DONOTSUBST) some other ${USER} entries "
);
+ dictionary dict;
+ dict.add("HOME", "myHome");
+
+ dictionary subDict;
+ subDict.add("value1", "test1");
+ subDict.add("value2", "test2");
+ dict.add("FOAM_RUN", subDict);
+
+
Info<< "string:" << test << nl << "hash:"
<< unsigned(string::hash()(test)) << endl;
@@ -73,7 +85,10 @@ int main(int argc, char *argv[])
Info<< string(test).replaceAll("kj", "zzz") << endl;
Info<< string(test).replaceAll("kj", "z") << endl;
- Info<< string(test).expand() << endl;
+ Info<< "expanded: " << string(test).expand() << endl;
+
+ Info<<"dictionary-based substitution: " << dict << endl;
+ Info<< "expandDict: " << stringOps::expandDict(test, dict) << endl;
string test2("~OpenFOAM/controlDict");
Info<< test2 << " => " << test2.expand() << endl;
diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
index 49142b10ec..f0a55ee1bd 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
+++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
@@ -24,7 +24,9 @@ License
\*---------------------------------------------------------------------------*/
#include "stringOps.H"
+#include "typeInfo.H"
#include "OSspecific.H"
+#include "OStringStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -73,10 +75,17 @@ Foam::string& Foam::stringOps::inplaceExpand
{
string::iterator iter = s.begin() + begVar + 1;
+ // more generous in accepting keywords than for env variables
while
(
iter != s.end()
- && (isalnum(*iter) || *iter == '_')
+ &&
+ (
+ isalnum(*iter)
+ || *iter == '.'
+ || *iter == ':'
+ || *iter == '_'
+ )
)
{
++iter;
@@ -86,10 +95,14 @@ Foam::string& Foam::stringOps::inplaceExpand
if (endVar != string::npos && endVar != begVar)
{
- string varName = s.substr
+ const word varName
(
- begVar + 1 + delim,
- endVar - begVar - 2*delim
+ s.substr
+ (
+ begVar + 1 + delim,
+ endVar - begVar - 2*delim
+ ),
+ false
);
HashTable::const_iterator fnd =
@@ -130,6 +143,130 @@ Foam::string& Foam::stringOps::inplaceExpand
}
+Foam::string Foam::stringOps::expandDict
+(
+ const string& original,
+ const dictionary& dict,
+ const char sigil
+)
+{
+ string s(original);
+ return inplaceExpandDict(s, dict, sigil);
+}
+
+
+Foam::string& Foam::stringOps::inplaceExpandDict
+(
+ string& s,
+ const dictionary& dict,
+ const char sigil
+)
+{
+ string::size_type begVar = 0;
+
+ // Expand $VAR or ${VAR}
+ // Repeat until nothing more is found
+ while
+ (
+ (begVar = s.find(sigil, begVar)) != string::npos
+ && begVar < s.size()-1
+ )
+ {
+ if (begVar == 0 || s[begVar-1] != '\\')
+ {
+ // Find end of first occurrence
+ string::size_type endVar = begVar;
+ string::size_type delim = 0;
+
+ if (s[begVar+1] == '{')
+ {
+ endVar = s.find('}', begVar);
+ delim = 1;
+ }
+ else
+ {
+ string::iterator iter = s.begin() + begVar + 1;
+
+ // more generous in accepting keywords than for env variables
+ while
+ (
+ iter != s.end()
+ &&
+ (
+ isalnum(*iter)
+ || *iter == '.'
+ || *iter == ':'
+ || *iter == '_'
+ )
+ )
+ {
+ ++iter;
+ ++endVar;
+ }
+ }
+
+ if (endVar != string::npos && endVar != begVar)
+ {
+ const word varName
+ (
+ s.substr
+ (
+ begVar + 1 + delim,
+ endVar - begVar - 2*delim
+ ),
+ false
+ );
+
+
+ // lookup the variable name in the given dictionary
+ const entry* ePtr = dict.lookupEntryPtr(varName, true, true);
+
+ // if defined - copy its entries
+ if (ePtr != NULL)
+ {
+ OStringStream buf;
+ if (ePtr->isDict())
+ {
+ ePtr->dict().write(buf, false);
+ }
+ else
+ {
+ // fail for other types
+ dynamicCast
+ (
+ *ePtr
+ ).write(buf, true);
+ }
+
+ s.std::string::replace
+ (
+ begVar,
+ endVar - begVar + 1,
+ buf.str()
+ );
+ begVar += buf.str().size();
+ }
+ else
+ {
+ // not defined - leave untouched.
+ begVar = endVar;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ ++begVar;
+ }
+ }
+
+ return s;
+}
+
+
Foam::string Foam::stringOps::expandEnv
(
const string& original,
diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H
index 6d416dd6e8..6d0ded9012 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H
+++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H
@@ -36,6 +36,7 @@ SourceFiles
#define stringOps_H
#include "string.H"
+#include "dictionary.H"
#include "HashTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -54,6 +55,8 @@ namespace stringOps
// -# variables
// - "$VAR", "${VAR}"
//
+ // Any unknown entries are removed
+ //
// \note the leading sigil can be changed to avoid conflicts with other
// string expansions
string expand
@@ -69,6 +72,8 @@ namespace stringOps
// -# variables
// - "$VAR", "${VAR}"
//
+ // Any unknown entries are removed
+ //
// \note the leading sigil can be changed to avoid conflicts with other
// string expansions
string& inplaceExpand
@@ -78,6 +83,39 @@ namespace stringOps
const char sigil = '$'
);
+ //- Expand occurences of variables according to the dictionary
+ // Expansion includes:
+ // -# variables
+ // - "$VAR", "${VAR}"
+ //
+ // Any unknown entries are left as-is
+ //
+ // \note the leading sigil can be changed to avoid conflicts with other
+ // string expansions
+ string expandDict
+ (
+ const string&,
+ const dictionary& dict,
+ const char sigil = '$'
+ );
+
+
+ //- Inplace expand occurences of variables according to the dictionary
+ // Expansion includes:
+ // -# variables
+ // - "$VAR", "${VAR}"
+ //
+ // Any unknown entries are left as-is
+ //
+ // \note the leading sigil can be changed to avoid conflicts with other
+ // string expansions
+ string& inplaceExpandDict
+ (
+ string&,
+ const dictionary& dict,
+ const char sigil = '$'
+ );
+
//- Expand initial tildes and all occurences of environment variables
// Expansion includes:
@@ -90,6 +128,7 @@ namespace stringOps
// - leading "~user" : home directory for specified user
// - leading "~OpenFOAM" : site/user OpenFOAM configuration directory
//
+ // Any unknown entries are removed silently if allowEmptyVar is true
// \sa
// Foam::findEtcFile
string expandEnv
@@ -111,6 +150,7 @@ namespace stringOps
// - leading "~user" : home directory for specified user
// - leading "~OpenFOAM" : site/user OpenFOAM configuration directory
//
+ // Any unknown entries are removed silently if allowEmptyVar is true
// \sa
// Foam::findEtcFile
string& inplaceExpandEnv
@@ -140,7 +180,6 @@ namespace stringOps
string& inplaceTrim(string&);
-
} // End namespace stringOps