diff options
-rw-r--r-- | Source/cmCommandArgumentParserHelper.cxx | 30 | ||||
-rw-r--r-- | Source/cmCommandArgumentParserHelper.h | 4 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 60 | ||||
-rw-r--r-- | Source/cmMakefile.h | 5 | ||||
-rw-r--r-- | Tests/StringFileTest/InputFile.h.in | 4 | ||||
-rw-r--r-- | Tests/StringFileTest/StringFile.cxx | 2 |
6 files changed, 68 insertions, 37 deletions
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index 30e91a7..f1efa68 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -38,7 +38,6 @@ cmCommandArgumentParserHelper::cmCommandArgumentParserHelper() this->NoEscapeMode = false; this->ReplaceAtSyntax = false; - this->AtOnly = false; } @@ -72,18 +71,6 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, { return this->ExpandVariable(var); } - if(this->AtOnly) - { - std::string ref = "$"; - ref += key; - ref += "{"; - if(var) - { - ref += var; - } - ref += "}"; - return this->AddString(ref.c_str()); - } if ( strcmp(key, "ENV") == 0 ) { char *ptr = getenv(var); @@ -105,21 +92,8 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, return 0; } -char* cmCommandArgumentParserHelper::ExpandVariable(const char* var, - bool doingAt) +char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) { - // if we are in AtOnly mode, and we are not expanding an @ variable - // then put back the ${var} unexpanded - if(!doingAt && this->AtOnly) - { - std::string ref = "${"; - if(var) - { - ref += var; - } - ref += "}"; - return this->AddString(ref.c_str()); - } if(!var) { return 0; @@ -151,7 +125,7 @@ char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var) if(this->ReplaceAtSyntax) { // try to expand the variable - char* ret = this->ExpandVariable(var, true); + char* ret = this->ExpandVariable(var); // if the return was 0 and we want to replace empty strings // then return an empty string if(!ret && this->RemoveEmpty) diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h index d49952a..c5cfc1e 100644 --- a/Source/cmCommandArgumentParserHelper.h +++ b/Source/cmCommandArgumentParserHelper.h @@ -58,7 +58,7 @@ public: char* CombineUnions(char* in1, char* in2); char* ExpandSpecialVariable(const char* key, const char* var); - char* ExpandVariable(const char* var, bool doingAt=false); + char* ExpandVariable(const char* var); char* ExpandVariableForAt(const char* var); void SetResult(const char* value); @@ -71,7 +71,6 @@ public: void SetNoEscapeMode(bool b) { this->NoEscapeMode = b; } void SetReplaceAtSyntax(bool b) { this->ReplaceAtSyntax = b; } void SetRemoveEmpty(bool b) { this->RemoveEmpty = b; } - void SetAtOnly(bool b) { this->AtOnly = b; } const char* GetError() { return this->ErrorString.c_str(); } char EmptyVariable[1]; @@ -107,7 +106,6 @@ private: bool NoEscapeMode; bool ReplaceAtSyntax; bool RemoveEmpty; - bool AtOnly; }; #endif diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 38b6d1f..30a0b7b 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -87,7 +87,7 @@ cmMakefile::cmMakefile() this->AddDefaultDefinitions(); this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)"); this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)"); - + this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)"); this->PreOrder = false; } @@ -1745,7 +1745,7 @@ std::vector<std::string> cmMakefile } -const char *cmMakefile::ExpandVariablesInString(std::string& source) const +const char *cmMakefile::ExpandVariablesInString(std::string& source) { return this->ExpandVariablesInString(source, false, false); } @@ -1757,12 +1757,65 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source, const char* filename, long line, bool removeEmpty, - bool replaceAt) const + bool replaceAt) { if ( source.empty() || source.find_first_of("$@\\") == source.npos) { return source.c_str(); } + + // Special-case the @ONLY mode. + if(atOnly) + { + if(!noEscapes || !removeEmpty || !replaceAt) + { + // This case should never be called. At-only is for + // configure-file/string which always does no escapes. + abort(); + } + + // Store an original copy of the input. + std::string input = source; + + // Start with empty output. + source = ""; + + // Look for one @VAR@ at a time. + const char* in = input.c_str(); + while(this->cmAtVarRegex.find(in)) + { + // Get the range of the string to replace. + const char* first = in + this->cmAtVarRegex.start(); + const char* last = in + this->cmAtVarRegex.end(); + + // Store the unchanged part of the string now. + source.append(in, first-in); + + // Lookup the definition of VAR. + std::string var(first+1, last-first-2); + if(const char* val = this->GetDefinition(var.c_str())) + { + // Store the value in the output escaping as requested. + if(escapeQuotes) + { + source.append(cmSystemTools::EscapeQuotes(val)); + } + else + { + source.append(val); + } + } + + // Continue looking for @VAR@ further along the string. + in = last; + } + + // Append the rest of the unchanged part of the string. + source.append(in); + + return source.c_str(); + } + // This method replaces ${VAR} and @VAR@ where VAR is looked up // with GetDefinition(), if not found in the map, nothing is expanded. // It also supports the $ENV{VAR} syntax where VAR is looked up in @@ -1775,7 +1828,6 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source, parser.SetNoEscapeMode(noEscapes); parser.SetReplaceAtSyntax(replaceAt); parser.SetRemoveEmpty(removeEmpty); - parser.SetAtOnly(atOnly); int res = parser.ParseString(source.c_str(), 0); if ( res ) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 0c4341a..93b8f02 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -570,14 +570,14 @@ public: * entry in the this->Definitions map. Also @var@ is * expanded to match autoconf style expansions. */ - const char *ExpandVariablesInString(std::string& source) const; + const char *ExpandVariablesInString(std::string& source); const char *ExpandVariablesInString(std::string& source, bool escapeQuotes, bool noEscapes, bool atOnly = false, const char* filename = 0, long line = -1, bool removeEmpty = false, - bool replaceAt = true) const; + bool replaceAt = true); /** * Remove any remaining variables in the string. Anything with ${var} or @@ -807,6 +807,7 @@ private: cmsys::RegularExpression cmDefineRegex; cmsys::RegularExpression cmDefine01Regex; + cmsys::RegularExpression cmAtVarRegex; cmPropertyMap Properties; diff --git a/Tests/StringFileTest/InputFile.h.in b/Tests/StringFileTest/InputFile.h.in index c7c1995..3e70a36 100644 --- a/Tests/StringFileTest/InputFile.h.in +++ b/Tests/StringFileTest/InputFile.h.in @@ -5,6 +5,10 @@ /* This should be configured to a commented undef with the curlies in place */ #cmakedefine TEST_NOT_DEFINED ${TEST_NOT_DEFINED} +/* This complicated line should be configured unchanged: */ +static const char* configvar = +"@$@$junk =~ s/#$xyz#/$foo_bar{$wibble}->{$xyz}/;@@"; + int CheckMethod(const char* var, const char* val ) { if ( !var ) diff --git a/Tests/StringFileTest/StringFile.cxx b/Tests/StringFileTest/StringFile.cxx index 0601aa0..609ebaf 100644 --- a/Tests/StringFileTest/StringFile.cxx +++ b/Tests/StringFileTest/StringFile.cxx @@ -24,6 +24,8 @@ int main(int, char*[]) res += CheckMethod(tuvar, "CMAKE"); res += CheckMethod(tlvar, "cmake"); res += CheckMethod(relpath, "../../X11R6/bin/xnest"); + res += CheckMethod(configvar, + "@$@$junk =~ s/#$xyz#/$foo_bar{$wibble}->{$xyz}/;@@"); return res; } |