summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2007-06-06 20:20:02 (GMT)
committerBrad King <brad.king@kitware.com>2007-06-06 20:20:02 (GMT)
commitdb0f26e85264b47dabaa1d400ad2fec1eb848eac (patch)
tree9a1077fe904c820fa6ec3a4bb7af33a18ce03714
parentd016b69af3304965f4ce7fd1953e9901def528a4 (diff)
downloadCMake-db0f26e85264b47dabaa1d400ad2fec1eb848eac.zip
CMake-db0f26e85264b47dabaa1d400ad2fec1eb848eac.tar.gz
CMake-db0f26e85264b47dabaa1d400ad2fec1eb848eac.tar.bz2
BUG: Fixed @ONLY configuration to not try to parse ${} syntax at all. This fixes the original fix to bug#4393 and adds a test.
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx30
-rw-r--r--Source/cmCommandArgumentParserHelper.h4
-rw-r--r--Source/cmMakefile.cxx60
-rw-r--r--Source/cmMakefile.h5
-rw-r--r--Tests/StringFileTest/InputFile.h.in4
-rw-r--r--Tests/StringFileTest/StringFile.cxx2
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;
}