ENH: #include: allow recursive substitution

This commit is contained in:
mattijs
2012-10-12 17:37:38 +01:00
parent 0c9d650367
commit f17c43948b
3 changed files with 258 additions and 5 deletions

View File

@ -74,10 +74,8 @@ Foam::fileName Foam::functionEntries::includeEntry::includeFileName
) )
{ {
fileName fName(is); fileName fName(is);
// Substitute dictionary entries // Substitute dictionary and environment variables
stringOps::inplaceExpand(fName, dict); stringOps::inplaceExpand(fName, dict, true, true);
// Substitute remaining environment variables
fName.expand();
if (fName.empty() || fName.isAbsolute()) if (fName.empty() || fName.isAbsolute())
{ {

View File

@ -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 Foam::string& Foam::stringOps::inplaceExpand
( (
string& s, string& s,

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License 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 //- Inplace expand occurences of variables according to the dictionary
// Expansion includes: // Expansion includes:
// -# variables // -# variables