BUG: string expand bombed out on first unknown construct

- eg,
       "$USER $(PWD) $USER"  ->  "username $(PWD) $USER"
  instead of
       "$USER $(PWD) $USER"  ->  "username $(PWD) username"

  this is noticable in some dynamicCode usages

STYLE: consolidate all string expand code into stringOps
This commit is contained in:
Mark Olesen 2011-03-02 13:46:15 +01:00
parent e65f566d68
commit 01ea4623f9
3 changed files with 43 additions and 150 deletions

View File

@ -88,7 +88,7 @@ int main(int argc, char *argv[])
Info<< "expanded: " << string(test).expand() << endl;
Info<<"dictionary-based substitution: " << dict << endl;
Info<< "expandDict: " << stringOps::expandDict(test, dict) << endl;
Info<< "expand dict: " << stringOps::expand(test, dict) << endl;
string test2("~OpenFOAM/controlDict");
Info<< test2 << " => " << test2.expand() << endl;

View File

@ -24,14 +24,16 @@ License
\*---------------------------------------------------------------------------*/
#include "string.H"
#include "OSspecific.H"
#include "stringOps.H"
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
const char* const Foam::string::typeName = "string";
int Foam::string::debug(debug::debugSwitch(string::typeName, 0));
int Foam::string::debug(Foam::debug::debugSwitch(string::typeName, 0));
const Foam::string Foam::string::null;
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Count and return the number of a given character in the string
@ -43,7 +45,7 @@ Foam::string::size_type Foam::string::count(const char c) const
{
if (*iter == c)
{
cCount++;
++cCount;
}
}
@ -95,136 +97,7 @@ Foam::string& Foam::string::replaceAll
Foam::string& Foam::string::expand(const bool allowEmpty)
{
size_type begVar = 0;
// Expand $VARS
// Repeat until nothing more is found
while
(
(begVar = find('$', begVar)) != npos
&& begVar < size()-1
)
{
if (begVar == 0 || operator[](begVar-1) != '\\')
{
// Find end of first occurrence
size_type endVar = begVar;
size_type delim = 0;
if (operator[](begVar+1) == '{')
{
endVar = find('}', begVar);
delim = 1;
}
else
{
iterator iter = begin() + begVar + 1;
while
(
iter != end()
&& (isalnum(*iter) || *iter == '_')
)
{
++iter;
++endVar;
}
}
if (endVar != npos && endVar != begVar)
{
const string varName = substr
(
begVar + 1 + delim,
endVar - begVar - 2*delim
);
const string varValue = getEnv(varName);
if (varValue.size())
{
std::string::replace
(
begVar,
endVar - begVar + 1,
varValue
);
begVar += varValue.size();
}
else if (allowEmpty)
{
std::string::replace
(
begVar,
endVar - begVar + 1,
""
);
}
else
{
FatalErrorIn("string::expand(const bool, const bool)")
<< "Unknown variable name " << varName << '.'
<< exit(FatalError);
}
}
else
{
break;
}
}
else
{
++begVar;
}
}
if (size())
{
if (operator[](0) == '~')
{
// Expand initial ~
// ~/ => home directory
// ~OpenFOAM => site/user OpenFOAM configuration directory
// ~user => home directory for specified user
word user;
fileName file;
if ((begVar = find('/')) != npos)
{
user = substr(1, begVar - 1);
file = substr(begVar + 1);
}
else
{
user = substr(1);
}
// NB: be a bit lazy and expand ~unknownUser as an
// empty string rather than leaving it untouched.
// otherwise add extra test
if (user == "OpenFOAM")
{
*this = findEtcFile(file);
}
else
{
*this = home(user)/file;
}
}
else if (operator[](0) == '.')
{
// Expand a lone '.' and an initial './' into cwd
if (size() == 1)
{
*this = cwd();
}
else if (operator[](1) == '/')
{
std::string::replace(0, 1, cwd());
}
}
}
stringOps::inplaceExpand(*this, allowEmpty);
return *this;
}

View File

@ -93,7 +93,17 @@ Foam::string& Foam::stringOps::inplaceExpand
}
}
if (endVar != string::npos && endVar != begVar)
if (endVar == string::npos)
{
// likely parsed '${...' without closing '}' - abort
break;
}
else if (endVar == begVar)
{
// parsed '${}' or $badChar - skip over
begVar = endVar + 1;
}
else
{
const word varName
(
@ -128,10 +138,6 @@ Foam::string& Foam::stringOps::inplaceExpand
);
}
}
else
{
break;
}
}
else
{
@ -205,7 +211,17 @@ Foam::string& Foam::stringOps::inplaceExpand
}
}
if (endVar != string::npos && endVar != begVar)
if (endVar == string::npos)
{
// likely parsed '${...' without closing '}' - abort
break;
}
else if (endVar == begVar)
{
// parsed '${}' or $badChar - skip over
begVar = endVar + 1;
}
else
{
const word varName
(
@ -249,13 +265,9 @@ Foam::string& Foam::stringOps::inplaceExpand
else
{
// not defined - leave original string untouched
begVar = endVar;
begVar = endVar + 1;
}
}
else
{
break;
}
}
else
{
@ -320,7 +332,18 @@ Foam::string& Foam::stringOps::inplaceExpand
}
}
if (endVar != string::npos && endVar != begVar)
if (endVar == string::npos)
{
// likely parsed '${...' without closing '}' - abort
break;
}
else if (endVar == begVar)
{
// parsed '${}' or $badChar - skip over
begVar = endVar + 1;
}
else
{
const word varName
(
@ -335,6 +358,7 @@ Foam::string& Foam::stringOps::inplaceExpand
const string varValue = getEnv(varName);
if (varValue.size())
{
// direct replacement
s.std::string::replace
(
begVar,
@ -362,10 +386,6 @@ Foam::string& Foam::stringOps::inplaceExpand
<< exit(FatalError);
}
}
else
{
break;
}
}
else
{