diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2001-07-27 20:29:50 (GMT) |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2001-07-27 20:29:50 (GMT) |
commit | 8bad4180c7908426b50809f5ba5948e408330cee (patch) | |
tree | 8bdb1417a6d734e58ae5abd218acf92798d46cfb /Source/cmMakefile.cxx | |
parent | 4878ed3d2937b717f31eb398db0121ec1f246d80 (diff) | |
download | CMake-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.cxx | 116 |
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 |