diff --git a/src/OpenFOAM/db/dictionary/functionEntries/includeEntry/includeEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/includeEntry/includeEntry.C index bce5e22aa22d157cb6b8f6d5d726f1a6406e61e0..ee191e4eeb302b24b6b8652f5abe0d9fc4bbb680 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/includeEntry/includeEntry.C +++ b/src/OpenFOAM/db/dictionary/functionEntries/includeEntry/includeEntry.C @@ -74,10 +74,8 @@ Foam::fileName Foam::functionEntries::includeEntry::includeFileName ) { fileName fName(is); - // Substitute dictionary entries - stringOps::inplaceExpand(fName, dict); - // Substitute remaining environment variables - fName.expand(); + // Substitute dictionary and environment variables + stringOps::inplaceExpand(fName, dict, true, true); if (fName.empty() || fName.isAbsolute()) { diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C index 194309cd3c367f992d34645901f76d889025e2f8..f44ffe3a6b7eb7bcc317d4709fa46acbb4af42c4 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C @@ -248,6 +248,218 @@ Foam::string Foam::stringOps::expand } +Foam::string Foam::stringOps::getVariable +( + const word& name, + const dictionary& dict, + const bool allowEnvVars, + const bool allowEmpty +) +{ + string value; + + const entry* ePtr = dict.lookupScopedEntryPtr + ( + name, + true, + false + ); + if (ePtr) + { + OStringStream buf; + // Force floating point numbers to be printed with at least + // some decimal digits. + buf << fixed; + buf.precision(IOstream::defaultPrecision()); + + // fail for non-primitiveEntry + dynamicCast<const primitiveEntry> + ( + *ePtr + ).write(buf, true); + + value = buf.str(); + } + else if (allowEnvVars) + { + value = getEnv(name); + + if (value.empty()) + { + FatalIOErrorIn + ( + "stringOps::getVariable\n" + "(\n" + " const word&,\n" + " const dictionary&,\n" + " const bool,\n" + " const bool\n" + ")\n", + dict + ) << "Cannot find dictionary or environment variable " + << name << exit(FatalIOError); + } + } + else + { + FatalIOErrorIn + ( + "stringOps::getVariable\n" + "(\n" + " const word&,\n" + " const dictionary&,\n" + " const bool,\n" + " const bool\n" + ")\n", + dict + ) << "Cannot find environment variable " + << name << exit(FatalIOError); + } + + return value; +} + + +Foam::string Foam::stringOps::expand +( + const string& s, + string::size_type& index, + const dictionary& dict, + const bool allowEnvVars, + const bool allowEmpty +) +{ + string newString; + + while (index < s.size()) + { + if (s[index] == '$' && s[index+1] == '{') + { + // Recurse to parse variable name + index += 2; + string val = expand(s, index, dict, allowEnvVars, allowEmpty); + newString.append(val); + } + else if (s[index] == '}') + { + return getVariable(newString, dict, allowEnvVars, allowEmpty); + } + else + { + newString.append(string(s[index])); + } + index++; + } + return newString; +} + + +Foam::string& Foam::stringOps::inplaceExpand +( + string& s, + const dictionary& dict, + const bool allowEnvVars, + const bool allowEmpty, + 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] != '\\') + { + if (s[begVar+1] == '{') + { + // Recursive variable expansion mode + label stringStart = begVar; + begVar += 2; + string varValue + ( + expand + ( + s, + begVar, + dict, + allowEnvVars, + allowEmpty + ) + ); + + s.std::string::replace + ( + stringStart, + begVar - stringStart + 1, + varValue + ); + } + else + { + string::iterator iter = s.begin() + begVar + 1; + + // more generous in accepting keywords than for env variables + string::size_type endVar = begVar; + while + ( + iter != s.end() + && + ( + isalnum(*iter) + || *iter == '.' + || *iter == ':' + || *iter == '_' + ) + ) + { + ++iter; + ++endVar; + } + + const word varName + ( + s.substr + ( + begVar + 1, + endVar - begVar + ), + false + ); + + string varValue + ( + getVariable + ( + varName, + dict, + allowEnvVars, + allowEmpty + ) + ); + + s.std::string::replace + ( + begVar, + varName.size()+1, + varValue + ); + begVar += varValue.size(); + } + } + else + { + ++begVar; + } + } + return s; +} + + Foam::string& Foam::stringOps::inplaceExpand ( string& s, diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H index 98c279d7ba910a052924f0a8b0e21adf0d1e13ed..3a72467bc9ce68b82d4dd38de5b561a70836279d 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -134,6 +134,49 @@ namespace stringOps ); + //- Get dictionary or (optionally) environment variable + string getVariable + ( + const word& name, + const dictionary& dict, + const bool allowEnvVars, + const bool allowEmpty + ); + + + //- Recursively expands (dictionary or environment) variable + // starting at index in string. Updates index. + string expand + ( + const string& s, + string::size_type& index, + const dictionary& dict, + const bool allowEnvVars, + const bool allowEmpty + ); + + + //- Inplace expand occurences of variables according to the dictionary + // and optionally environment variables + // Expansion includes: + // -# variables + // - "$VAR", "${VAR}" + // + // with the "${}" syntax doing a recursive substitution. + // Any unknown entries are left as-is + // + // \note the leading sigil can be changed to avoid conflicts with other + // string expansions + string& inplaceExpand + ( + string& s, + const dictionary& dict, + const bool allowEnvVars, + const bool allowEmpty, + const char sigil = '$' + ); + + //- Inplace expand occurences of variables according to the dictionary // Expansion includes: // -# variables