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;" " $HOME kjhkjhkjh \" \\$HOME/tyetyery $; ${FOAM_RUN} \n $; hkjh;"
" $(DONOTSUBST) some other <${USER}> with '${__UNKNOWN:-some default}'" " $(DONOTSUBST) some other <${USER}> with '${__UNKNOWN:-some default}'"
" value " " value "
" or with '${HOME:+Home was set}' via :+ alternative"
" or with '${__UNKNOWN:+unknown}' empty"
); );
dictionary dict; 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 Foam::string Foam::stringOps::expand
( (
const string& original, const string& original,
@ -66,7 +105,8 @@ Foam::string& Foam::stringOps::inplaceExpand
string::size_type endVar = begVar; string::size_type endVar = begVar;
string::size_type delim = 0; 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; string::size_type altPos = string::npos;
if (s[begVar+1] == '{') if (s[begVar+1] == '{')
@ -74,14 +114,11 @@ Foam::string& Foam::stringOps::inplaceExpand
endVar = s.find('}', begVar); endVar = s.find('}', begVar);
delim = 1; delim = 1;
// looks like ${parameter:-word} // check for ${parameter:-word} or ${parameter:+word}
if (endVar != string::npos) if (endVar != string::npos)
{ {
altPos = s.find(":-", begVar); altPos = begVar;
if (altPos != string::npos && altPos > endVar) altType = findParameterAlternative(s, altPos, endVar);
{
altPos = string::npos;
}
} }
} }
else else
@ -134,7 +171,7 @@ Foam::string& Foam::stringOps::inplaceExpand
std::string altValue; std::string altValue;
if (altPos != string::npos) if (altPos != string::npos)
{ {
// had ":-" default value // had ":-" or ":+" alternative value
altValue = s.substr altValue = s.substr
( (
altPos + 2, altPos + 2,
@ -148,17 +185,32 @@ Foam::string& Foam::stringOps::inplaceExpand
if (fnd != HashTable<string, word, string::hash>::end()) if (fnd != HashTable<string, word, string::hash>::end())
{ {
s.std::string::replace if (altPos != string::npos && altType == '+')
( {
begVar, // was found, use ":+" alternative
endVar - begVar + 1, s.std::string::replace
*fnd (
); begVar,
begVar += (*fnd).size(); endVar - begVar + 1,
altValue
);
begVar += altValue.size();
}
else
{
// was found, use value
s.std::string::replace
(
begVar,
endVar - begVar + 1,
*fnd
);
begVar += (*fnd).size();
}
} }
else if (altPos != string::npos) else if (altPos != string::npos && altType == '-')
{ {
// use alternative provided // was not found, use ":-" alternative
s.std::string::replace s.std::string::replace
( (
begVar, begVar,
@ -169,12 +221,8 @@ Foam::string& Foam::stringOps::inplaceExpand
} }
else else
{ {
s.std::string::replace // substitute with nothing, also for ":+" alternative
( s.std::string::erase(begVar, endVar - begVar + 1);
begVar,
endVar - begVar + 1,
""
);
} }
} }
} }
@ -351,7 +399,8 @@ Foam::string& Foam::stringOps::inplaceExpand
string::size_type endVar = begVar; string::size_type endVar = begVar;
string::size_type delim = 0; 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; string::size_type altPos = string::npos;
if (s[begVar+1] == '{') if (s[begVar+1] == '{')
@ -359,14 +408,11 @@ Foam::string& Foam::stringOps::inplaceExpand
endVar = s.find('}', begVar); endVar = s.find('}', begVar);
delim = 1; delim = 1;
// looks like ${parameter:-word} // check for ${parameter:-word} or ${parameter:+word}
if (endVar != string::npos) if (endVar != string::npos)
{ {
altPos = s.find(":-", begVar); altPos = begVar;
if (altPos != string::npos && altPos > endVar) altType = findParameterAlternative(s, altPos, endVar);
{
altPos = string::npos;
}
} }
} }
else else
@ -413,7 +459,7 @@ Foam::string& Foam::stringOps::inplaceExpand
std::string altValue; std::string altValue;
if (altPos != string::npos) if (altPos != string::npos)
{ {
// had ":-" default value // had ":-" or ":+" alternative value
altValue = s.substr altValue = s.substr
( (
altPos + 2, altPos + 2,
@ -424,34 +470,53 @@ Foam::string& Foam::stringOps::inplaceExpand
const string varValue = getEnv(varName); const string varValue = getEnv(varName);
if (varValue.size()) if (varValue.size())
{ {
// direct replacement if (altPos != string::npos && altType == '+')
s.std::string::replace {
( // was found, use ":+" alternative
begVar, s.std::string::replace
endVar - begVar + 1, (
varValue begVar,
); endVar - begVar + 1,
begVar += varValue.size(); altValue
);
begVar += altValue.size();
}
else
{
// was found, use value
s.std::string::replace
(
begVar,
endVar - begVar + 1,
varValue
);
begVar += varValue.size();
}
} }
else if (altPos != string::npos) else if (altPos != string::npos)
{ {
// use alternative provided // use ":-" or ":+" alternative values
s.std::string::replace if (altType == '-')
( {
begVar, // was not found, use ":-" alternative
endVar - begVar + 1, s.std::string::replace
altValue (
); begVar,
begVar += altValue.size(); 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) else if (allowEmpty)
{ {
s.std::string::replace s.std::string::erase(begVar, endVar - begVar + 1);
(
begVar,
endVar - begVar + 1,
""
);
} }
else else
{ {
@ -459,7 +524,7 @@ Foam::string& Foam::stringOps::inplaceExpand
( (
"stringOps::inplaceExpand(string&, const bool)" "stringOps::inplaceExpand(string&, const bool)"
) )
<< "Unknown variable name " << varName << '.' << "Unknown variable name '" << varName << "'"
<< exit(FatalError); << exit(FatalError);
} }
} }

View File

@ -62,6 +62,13 @@ namespace stringOps
// If parameter is unset or null, the \c defValue is substituted. // If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter 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. // Any unknown entries are removed silently.
// //
// Malformed entries (eg, brace mismatch, sigil followed by bad character) // 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. // If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter 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. // Any unknown entries are removed silently.
// //
// Malformed entries (eg, brace mismatch, sigil followed by bad character) // 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. // If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter 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. // Any unknown entries are removed silently, if allowEmpty is true.
// //
// Malformed entries (eg, brace mismatch, sigil followed by bad character) // 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. // If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter 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. // Any unknown entries are removed silently, if allowEmpty is true.
// //
// Malformed entries (eg, brace mismatch, sigil followed by bad character) // Malformed entries (eg, brace mismatch, sigil followed by bad character)