ENH: support alternative values in string expansion

- syntax as per Bourne/Korn shell
      ${parameter:+altValue}

  If parameter is unset or null, nothing is substituted.
  Otherwise the \c altValue is substituted.
This commit is contained in:
Mark Olesen
2011-03-18 10:12:38 +01:00
parent a82e6efa88
commit 2a925aeff3
3 changed files with 149 additions and 54 deletions

View File

@ -43,6 +43,8 @@ int main(int argc, char *argv[])
" $HOME kjhkjhkjh \" \\$HOME/tyetyery $; ${FOAM_RUN} \n $; hkjh;"
" $(DONOTSUBST) some other <${USER}> with '${__UNKNOWN:-some default}'"
" value "
" or with '${HOME:+Home was set}' via :+ alternative"
" or with '${__UNKNOWN:+unknown}' empty"
);
dictionary dict;

View File

@ -31,6 +31,45 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//! \cond fileScope
// Find the type/position of the ":-" or ":+" alternative values
//
static inline int findParameterAlternative
(
const std::string& s,
std::string::size_type& pos,
std::string::size_type endPos
)
{
while (pos != std::string::npos)
{
pos = s.find(':', pos);
if (pos != std::string::npos)
{
if (pos < endPos)
{
// in-range: check for '+' or '-' following the ':'
const int altType = s[pos+1];
if (altType == '+' || altType == '-')
{
return altType;
}
++pos; // unknown/unsupported - continue at next position
}
else
{
// out-of-range: abort
pos = std::string::npos;
}
}
}
return 0;
}
//! \endcond
Foam::string Foam::stringOps::expand
(
const string& original,
@ -66,7 +105,8 @@ Foam::string& Foam::stringOps::inplaceExpand
string::size_type endVar = begVar;
string::size_type delim = 0;
// The position of the ":-" default value
// The type/position of the ":-" or ":+" alternative values
int altType = 0;
string::size_type altPos = string::npos;
if (s[begVar+1] == '{')
@ -74,14 +114,11 @@ Foam::string& Foam::stringOps::inplaceExpand
endVar = s.find('}', begVar);
delim = 1;
// looks like ${parameter:-word}
// check for ${parameter:-word} or ${parameter:+word}
if (endVar != string::npos)
{
altPos = s.find(":-", begVar);
if (altPos != string::npos && altPos > endVar)
{
altPos = string::npos;
}
altPos = begVar;
altType = findParameterAlternative(s, altPos, endVar);
}
}
else
@ -134,7 +171,7 @@ Foam::string& Foam::stringOps::inplaceExpand
std::string altValue;
if (altPos != string::npos)
{
// had ":-" default value
// had ":-" or ":+" alternative value
altValue = s.substr
(
altPos + 2,
@ -148,17 +185,9 @@ Foam::string& Foam::stringOps::inplaceExpand
if (fnd != HashTable<string, word, string::hash>::end())
{
s.std::string::replace
(
begVar,
endVar - begVar + 1,
*fnd
);
begVar += (*fnd).size();
}
else if (altPos != string::npos)
if (altPos != string::npos && altType == '+')
{
// use alternative provided
// was found, use ":+" alternative
s.std::string::replace
(
begVar,
@ -169,12 +198,31 @@ Foam::string& Foam::stringOps::inplaceExpand
}
else
{
// was found, use value
s.std::string::replace
(
begVar,
endVar - begVar + 1,
""
*fnd
);
begVar += (*fnd).size();
}
}
else if (altPos != string::npos && altType == '-')
{
// was not found, use ":-" alternative
s.std::string::replace
(
begVar,
endVar - begVar + 1,
altValue
);
begVar += altValue.size();
}
else
{
// substitute with nothing, also for ":+" alternative
s.std::string::erase(begVar, endVar - begVar + 1);
}
}
}
@ -351,7 +399,8 @@ Foam::string& Foam::stringOps::inplaceExpand
string::size_type endVar = begVar;
string::size_type delim = 0;
// The position of the ":-" default value
// The type/position of the ":-" or ":+" alternative values
int altType = 0;
string::size_type altPos = string::npos;
if (s[begVar+1] == '{')
@ -359,14 +408,11 @@ Foam::string& Foam::stringOps::inplaceExpand
endVar = s.find('}', begVar);
delim = 1;
// looks like ${parameter:-word}
// check for ${parameter:-word} or ${parameter:+word}
if (endVar != string::npos)
{
altPos = s.find(":-", begVar);
if (altPos != string::npos && altPos > endVar)
{
altPos = string::npos;
}
altPos = begVar;
altType = findParameterAlternative(s, altPos, endVar);
}
}
else
@ -413,7 +459,7 @@ Foam::string& Foam::stringOps::inplaceExpand
std::string altValue;
if (altPos != string::npos)
{
// had ":-" default value
// had ":-" or ":+" alternative value
altValue = s.substr
(
altPos + 2,
@ -424,18 +470,9 @@ Foam::string& Foam::stringOps::inplaceExpand
const string varValue = getEnv(varName);
if (varValue.size())
{
// direct replacement
s.std::string::replace
(
begVar,
endVar - begVar + 1,
varValue
);
begVar += varValue.size();
}
else if (altPos != string::npos)
if (altPos != string::npos && altType == '+')
{
// use alternative provided
// was found, use ":+" alternative
s.std::string::replace
(
begVar,
@ -444,14 +481,42 @@ Foam::string& Foam::stringOps::inplaceExpand
);
begVar += altValue.size();
}
else if (allowEmpty)
else
{
// was found, use value
s.std::string::replace
(
begVar,
endVar - begVar + 1,
""
varValue
);
begVar += varValue.size();
}
}
else if (altPos != string::npos)
{
// use ":-" or ":+" alternative values
if (altType == '-')
{
// was not found, use ":-" alternative
s.std::string::replace
(
begVar,
endVar - begVar + 1,
altValue
);
begVar += altValue.size();
}
else
{
// was not found, ":+" alternative implies
// substitute with nothing
s.std::string::erase(begVar, endVar - begVar + 1);
}
}
else if (allowEmpty)
{
s.std::string::erase(begVar, endVar - begVar + 1);
}
else
{
@ -459,7 +524,7 @@ Foam::string& Foam::stringOps::inplaceExpand
(
"stringOps::inplaceExpand(string&, const bool)"
)
<< "Unknown variable name " << varName << '.'
<< "Unknown variable name '" << varName << "'"
<< exit(FatalError);
}
}

View File

@ -62,6 +62,13 @@ namespace stringOps
// If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter is substituted.
//
// Supports alternative values as per the Bourne/Korn shell.
// \code
// "${parameter:+altValue}"
// \endcode
// If parameter is unset or null, nothing is substituted.
// Otherwise the \c altValue is substituted.
//
// Any unknown entries are removed silently.
//
// Malformed entries (eg, brace mismatch, sigil followed by bad character)
@ -89,6 +96,13 @@ namespace stringOps
// If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter is substituted.
//
// Supports alternative values as per the Bourne/Korn shell.
// \code
// "${parameter:+altValue}"
// \endcode
// If parameter is unset or null, nothing is substituted.
// Otherwise the \c altValue is substituted.
//
// Any unknown entries are removed silently.
//
// Malformed entries (eg, brace mismatch, sigil followed by bad character)
@ -155,6 +169,13 @@ namespace stringOps
// If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter is substituted.
//
// Supports alternative values as per the Bourne/Korn shell.
// \code
// "${parameter:+altValue}"
// \endcode
// If parameter is unset or null, nothing is substituted.
// Otherwise the \c altValue is substituted.
//
// Any unknown entries are removed silently, if allowEmpty is true.
//
// Malformed entries (eg, brace mismatch, sigil followed by bad character)
@ -187,6 +208,13 @@ namespace stringOps
// If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter is substituted.
//
// Supports alternative values as per the Bourne/Korn shell.
// \code
// "${parameter:+altValue}"
// \endcode
// If parameter is unset or null, nothing is substituted.
// Otherwise the \c altValue is substituted.
//
// Any unknown entries are removed silently, if allowEmpty is true.
//
// Malformed entries (eg, brace mismatch, sigil followed by bad character)