summaryrefslogtreecommitdiffstats
path: root/Source/cmMakefile.cxx
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2001-07-27 20:29:50 (GMT)
committerBill Hoffman <bill.hoffman@kitware.com>2001-07-27 20:29:50 (GMT)
commit8bad4180c7908426b50809f5ba5948e408330cee (patch)
tree8bdb1417a6d734e58ae5abd218acf92798d46cfb /Source/cmMakefile.cxx
parent4878ed3d2937b717f31eb398db0121ec1f246d80 (diff)
downloadCMake-8bad4180c7908426b50809f5ba5948e408330cee.zip
CMake-8bad4180c7908426b50809f5ba5948e408330cee.tar.gz
CMake-8bad4180c7908426b50809f5ba5948e408330cee.tar.bz2
ENH: Re-implemented ExpandVariablesInString to significantly improve performance.
Diffstat (limited to 'Source/cmMakefile.cxx')
-rw-r--r--Source/cmMakefile.cxx116
1 files changed, 100 insertions, 16 deletions
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index f9db806..a420d2e 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -824,25 +824,109 @@ void cmMakefile::ExpandVariablesInString(std::string& source) const
void cmMakefile::ExpandVariablesInString(std::string& source,
bool escapeQuotes) const
{
- for(DefinitionMap::const_iterator i = m_Definitions.begin();
- i != m_Definitions.end(); ++i)
+ // This method replaces ${VAR} and @VAR@ where VAR is looked up
+ // in the m_Definitions map, if not found in the map, nothing is expanded.
+
+ // start by look for $ or @ in the string
+ std::string::size_type markerPos = source.find_first_of("$@");
+ // if not found then leave quick as nothing needs to be expanded
+ if(markerPos == std::string::npos && markerPos > source.size()-1)
+ {
+ return;
+ }
+ // current position
+ std::string::size_type currentPos =0; // start at 0
+ std::string result; // string with replacements
+ // go until the the end of the string
+ while(markerPos != std::string::npos)
{
- std::string replace = (*i).second;
- if (escapeQuotes)
+ // grab string from currentPos to the start of the variable
+ // and add it to the result
+ result += source.substr(currentPos, markerPos - currentPos);
+ char endVariableMarker; // what is the end of the variable @ or }
+ int markerStartSize = 1; // size of the start marker 1 or 2
+ if(source[markerPos] == '$' )
+ {
+ // ${var} case
+ if(source[markerPos+1] == '{')
+ {
+ endVariableMarker = '}';
+ markerStartSize = 2;
+ }
+ else
+ {
+ // bogus $ with no { so add $ to result and move on
+ result += '$'; // add bogus $ back into string
+ currentPos = markerPos+1; // move on
+ endVariableMarker = ' '; // set end var to space so we can tell bogus
+ }
+ }
+ else
{
- replace = cmSystemTools::EscapeQuotes(replace.c_str());
+ // @VAR case
+ endVariableMarker = '@';
}
- std::string variable = "${";
- variable += (*i).first;
- variable += "}";
- cmSystemTools::ReplaceString(source, variable.c_str(),
- replace.c_str());
- variable = "@";
- variable += (*i).first;
- variable += "@";
- cmSystemTools::ReplaceString(source, variable.c_str(),
- replace.c_str());
- }
+ // if it was a valid variable (started with @ or ${ )
+ if(endVariableMarker != ' ')
+ {
+ markerPos += markerStartSize; // move past marker
+ // find the end variable marker starting at the markerPos
+ std::string::size_type endVariablePos =
+ source.find(endVariableMarker, markerPos);
+ if(endVariablePos == std::string::npos)
+ {
+ // no end marker found so add the bogus start
+ if(endVariableMarker == '@')
+ {
+ result += '@';
+ }
+ else
+ {
+ result += "${";
+ }
+ currentPos = markerPos;
+ }
+ else
+ {
+ // good variable remove it
+ std::string var = source.substr(markerPos, endVariablePos - markerPos);
+ DefinitionMap::const_iterator pos = m_Definitions.find(var.c_str());
+ // if found add to result, if not, then it gets blanked
+ if(pos != m_Definitions.end())
+ {
+ if (escapeQuotes)
+ {
+ result += cmSystemTools::EscapeQuotes((*pos).second.c_str());
+ }
+ else
+ {
+ result += (*pos).second;
+ }
+ }
+ else
+ {
+ // if no definition is found then add the var back
+ if(endVariableMarker == '@')
+ {
+ result += "@";
+ result += var;
+ result += "@";
+ }
+ else
+ {
+ result += "${";
+ result += var;
+ result += "}";
+ }
+ }
+ // lookup var, and replace it
+ currentPos = endVariablePos+1;
+ }
+ }
+ markerPos = source.find_first_of("$@", currentPos);
+ }
+ result += source.substr(currentPos); // pick up the rest of the string
+ source = result;
}
void cmMakefile::RemoveVariablesInString(std::string& source) const