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