[Cmake-commits] CMake branch, next, updated. v3.0.1-5172-gc9890b4
Nils Gladitz
nilsgladitz at gmail.com
Thu Sep 4 16:34:13 EDT 2014
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".
The branch, next has been updated
via c9890b40693c28d37b607b33c9c00fe4ce9d02c4 (commit)
via c85ac500ab26a00b47e6f4df93b537b53ece5eef (commit)
from f63493a09ea51b547c62ded01c7ad23b58a7e0b7 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c9890b40693c28d37b607b33c9c00fe4ce9d02c4
commit c9890b40693c28d37b607b33c9c00fe4ce9d02c4
Merge: f63493a c85ac50
Author: Nils Gladitz <nilsgladitz at gmail.com>
AuthorDate: Thu Sep 4 16:34:08 2014 -0400
Commit: CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Sep 4 16:34:08 2014 -0400
Merge topic 'if-sanity' into next
c85ac500 If: Introduce policy CMP0054 - don't dereference quoted variables in if()
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c85ac500ab26a00b47e6f4df93b537b53ece5eef
commit c85ac500ab26a00b47e6f4df93b537b53ece5eef
Author: Nils Gladitz <nilsgladitz at gmail.com>
AuthorDate: Thu Sep 4 20:21:28 2014 +0200
Commit: Nils Gladitz <nilsgladitz at gmail.com>
CommitDate: Thu Sep 4 22:33:44 2014 +0200
If: Introduce policy CMP0054 - don't dereference quoted variables in if()
diff --git a/Help/command/if.rst b/Help/command/if.rst
index a45b995..3e4178d 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -199,3 +199,7 @@ above-documented signature accepts ``<variable|string>``:
* The left and right hand arguments to ``AND`` and ``OR`` are independently
tested to see if they are boolean constants, if so they are used as
such, otherwise they are assumed to be variables and are dereferenced.
+
+To prevent ambiguity potential variables names can be quoted.
+A quoted variable name will be interpreted as a string and not dereferenced.
+See CMake Policy :policy:`CMP0054`.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 136cf5c..f1717a0 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -105,3 +105,4 @@ All Policies
/policy/CMP0051
/policy/CMP0052
/policy/CMP0053
+ /policy/CMP0054
diff --git a/Help/policy/CMP0054.rst b/Help/policy/CMP0054.rst
new file mode 100644
index 0000000..bf0e95f
--- /dev/null
+++ b/Help/policy/CMP0054.rst
@@ -0,0 +1,16 @@
+CMP0054
+-------
+
+Don't dereference quoted variables in if() arguments.
+
+CMake 3.1 no longer dereferences variables in if() arguments when
+they are quoted.
+
+The ``OLD`` behavior for this policy is to dereference variables even
+if they are quoted. The ``NEW`` behavior is to omit dereferencing
+of variables that are quoted.
+
+This policy was introduced in CMake version 3.1.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set
+it to ``OLD`` or ``NEW`` explicitly.
diff --git a/Source/cmBootstrapCommands2.cxx b/Source/cmBootstrapCommands2.cxx
index be72526..b5d4dc2 100644
--- a/Source/cmBootstrapCommands2.cxx
+++ b/Source/cmBootstrapCommands2.cxx
@@ -14,6 +14,7 @@
// This is sort of a boot strapping approach since you would
// like to have CMake to build CMake.
#include "cmCommands.h"
+#include "cmExpandedCommandArgument.cxx"
#include "cmGeneratorExpressionEvaluationFile.cxx"
#include "cmGetCMakePropertyCommand.cxx"
#include "cmGetDirectoryPropertyCommand.cxx"
diff --git a/Source/cmExpandedCommandArgument.cxx b/Source/cmExpandedCommandArgument.cxx
new file mode 100644
index 0000000..4477cf5
--- /dev/null
+++ b/Source/cmExpandedCommandArgument.cxx
@@ -0,0 +1,51 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmExpandedCommandArgument.h"
+
+cmExpandedCommandArgument::cmExpandedCommandArgument():
+ Quoted(false)
+{
+
+}
+
+cmExpandedCommandArgument::cmExpandedCommandArgument(
+ std::string const& value, bool quoted):
+ Value(value), Quoted(quoted)
+{
+
+}
+
+std::string const& cmExpandedCommandArgument::GetValue() const
+{
+ return this->Value;
+}
+
+bool cmExpandedCommandArgument::WasQuoted() const
+{
+ return this->Quoted;
+}
+
+bool cmExpandedCommandArgument::operator== (std::string const& value) const
+{
+ return this->Value == value;
+}
+
+bool cmExpandedCommandArgument::empty() const
+{
+ return this->Value.empty();
+}
+
+const char* cmExpandedCommandArgument::c_str() const
+{
+ return this->Value.c_str();
+}
diff --git a/Source/cmExpandedCommandArgument.h b/Source/cmExpandedCommandArgument.h
new file mode 100644
index 0000000..f4e1517
--- /dev/null
+++ b/Source/cmExpandedCommandArgument.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmExpandedCommandArgument_h
+#define cmExpandedCommandArgument_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmExpandedCommandArgument
+ * \brief Represents an expanded command argument
+ *
+ * cmCommandArgument stores a string representing an expanded
+ * command argument and context information.
+ */
+
+class cmExpandedCommandArgument
+{
+public:
+ cmExpandedCommandArgument();
+ cmExpandedCommandArgument(std::string const& value, bool quoted);
+
+ std::string const& GetValue() const;
+
+ bool WasQuoted() const;
+
+ bool operator== (std::string const& value) const;
+
+ bool empty() const;
+
+ const char* c_str() const;
+
+private:
+ std::string Value;
+ bool Quoted;
+};
+
+#endif
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 1141b01..8c92a6a 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -18,15 +18,15 @@
static std::string cmIfCommandError(
- cmMakefile* mf, std::vector<std::string> const& args)
+ cmMakefile* mf, std::vector<cmExpandedCommandArgument> const& args)
{
cmLocalGenerator* lg = mf->GetLocalGenerator();
std::string err = "given arguments:\n ";
- for(std::vector<std::string>::const_iterator i = args.begin();
+ for(std::vector<cmExpandedCommandArgument>::const_iterator i = args.begin();
i != args.end(); ++i)
{
err += " ";
- err += lg->EscapeForCMake(*i);
+ err += lg->EscapeForCMake(i->GetValue());
}
err += "\n";
return err;
@@ -103,7 +103,7 @@ IsFunctionBlocked(const cmListFileFunction& lff,
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
mf.ExpandArguments(this->Functions[c].Arguments,
expandedArguments);
@@ -185,7 +185,7 @@ bool cmIfCommand
{
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
this->Makefile->ExpandArguments(args, expandedArguments);
cmake::MessageType status;
@@ -225,8 +225,10 @@ bool cmIfCommand
namespace
{
+ typedef std::list<cmExpandedCommandArgument> cmArgumentList;
+
//=========================================================================
- bool GetBooleanValue(std::string& arg, cmMakefile* mf)
+ bool GetBooleanValue(cmExpandedCommandArgument& arg, cmMakefile* mf)
{
// Check basic constants.
if (arg == "0")
@@ -261,13 +263,14 @@ namespace
}
// Check definition.
- const char* def = mf->GetDefinition(arg);
+ const char* def = cmIfCommand::GetDefinitionIfUnquoted(mf, arg);
return !cmSystemTools::IsOff(def);
}
//=========================================================================
// Boolean value behavior from CMake 2.6.4 and below.
- bool GetBooleanValueOld(std::string const& arg, cmMakefile* mf, bool one)
+ bool GetBooleanValueOld(cmExpandedCommandArgument const& arg,
+ cmMakefile* mf, bool one)
{
if(one)
{
@@ -277,12 +280,15 @@ namespace
else if(arg == "1")
{ return true; }
else
- { return !cmSystemTools::IsOff(mf->GetDefinition(arg)); }
+ {
+ const char* def = cmIfCommand::GetDefinitionIfUnquoted(mf, arg);
+ return !cmSystemTools::IsOff(def);
+ }
}
else
{
// Old GetVariableOrNumber behavior.
- const char* def = mf->GetDefinition(arg);
+ const char* def = cmIfCommand::GetDefinitionIfUnquoted(mf, arg);
if(!def && atoi(arg.c_str()))
{
def = arg.c_str();
@@ -294,7 +300,7 @@ namespace
//=========================================================================
// returns the resulting boolean value
bool GetBooleanValueWithAutoDereference(
- std::string &newArg,
+ cmExpandedCommandArgument &newArg,
cmMakefile *makefile,
std::string &errorString,
cmPolicies::PolicyStatus Policy12Status,
@@ -321,7 +327,7 @@ namespace
case cmPolicies::WARN:
{
cmPolicies* policies = makefile->GetPolicies();
- errorString = "An argument named \"" + newArg
+ errorString = "An argument named \"" + newArg.GetValue()
+ "\" appears in a conditional statement. "
+ policies->GetPolicyWarning(cmPolicies::CMP0012);
status = cmake::AUTHOR_WARNING;
@@ -332,7 +338,7 @@ namespace
case cmPolicies::REQUIRED_ALWAYS:
{
cmPolicies* policies = makefile->GetPolicies();
- errorString = "An argument named \"" + newArg
+ errorString = "An argument named \"" + newArg.GetValue()
+ "\" appears in a conditional statement. "
+ policies->GetRequiredPolicyError(cmPolicies::CMP0012);
status = cmake::FATAL_ERROR;
@@ -345,9 +351,9 @@ namespace
}
//=========================================================================
- void IncrementArguments(std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
+ void IncrementArguments(cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2)
{
if (argP1 != newArgs.end())
{
@@ -363,18 +369,18 @@ namespace
//=========================================================================
// helper function to reduce code duplication
void HandlePredicate(bool value, int &reducible,
- std::list<std::string>::iterator &arg,
- std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2)
{
if(value)
{
- *arg = "1";
+ *arg = cmExpandedCommandArgument("1", true);
}
else
{
- *arg = "0";
+ *arg = cmExpandedCommandArgument("0", true);
}
newArgs.erase(argP1);
argP1 = arg;
@@ -385,18 +391,18 @@ namespace
//=========================================================================
// helper function to reduce code duplication
void HandleBinaryOp(bool value, int &reducible,
- std::list<std::string>::iterator &arg,
- std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2)
{
if(value)
{
- *arg = "1";
+ *arg = cmExpandedCommandArgument("1", true);
}
else
{
- *arg = "0";
+ *arg = cmExpandedCommandArgument("0", true);
}
newArgs.erase(argP2);
newArgs.erase(argP1);
@@ -407,7 +413,7 @@ namespace
//=========================================================================
// level 0 processes parenthetical expressions
- bool HandleLevel0(std::list<std::string> &newArgs,
+ bool HandleLevel0(cmArgumentList &newArgs,
cmMakefile *makefile,
std::string &errorString,
cmake::MessageType &status)
@@ -416,13 +422,13 @@ namespace
do
{
reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
+ cmArgumentList::iterator arg = newArgs.begin();
while (arg != newArgs.end())
{
if (*arg == "(")
{
// search for the closing paren for this opening one
- std::list<std::string>::iterator argClose;
+ cmArgumentList::iterator argClose;
argClose = arg;
argClose++;
unsigned int depth = 1;
@@ -445,10 +451,10 @@ namespace
return false;
}
// store the reduced args in this vector
- std::vector<std::string> newArgs2;
+ std::vector<cmExpandedCommandArgument> newArgs2;
// copy to the list structure
- std::list<std::string>::iterator argP1 = arg;
+ cmArgumentList::iterator argP1 = arg;
argP1++;
for(; argP1 != argClose; argP1++)
{
@@ -461,11 +467,11 @@ namespace
cmIfCommand::IsTrue(newArgs2, errorString, makefile, status);
if(value)
{
- *arg = "1";
+ *arg = cmExpandedCommandArgument("1", true);
}
else
{
- *arg = "0";
+ *arg = cmExpandedCommandArgument("0", true);
}
argP1 = arg;
argP1++;
@@ -481,7 +487,7 @@ namespace
//=========================================================================
// level one handles most predicates except for NOT
- bool HandleLevel1(std::list<std::string> &newArgs,
+ bool HandleLevel1(cmArgumentList &newArgs,
cmMakefile *makefile,
std::string &, cmake::MessageType &)
{
@@ -489,9 +495,9 @@ namespace
do
{
reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
while (arg != newArgs.end())
{
argP1 = arg;
@@ -500,35 +506,35 @@ namespace
if (*arg == "EXISTS" && argP1 != newArgs.end())
{
HandlePredicate(
- cmSystemTools::FileExists((argP1)->c_str()),
+ cmSystemTools::FileExists(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// does a directory with this name exist
if (*arg == "IS_DIRECTORY" && argP1 != newArgs.end())
{
HandlePredicate(
- cmSystemTools::FileIsDirectory((argP1)->c_str()),
+ cmSystemTools::FileIsDirectory(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// does a symlink with this name exist
if (*arg == "IS_SYMLINK" && argP1 != newArgs.end())
{
HandlePredicate(
- cmSystemTools::FileIsSymlink((argP1)->c_str()),
+ cmSystemTools::FileIsSymlink(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// is the given path an absolute path ?
if (*arg == "IS_ABSOLUTE" && argP1 != newArgs.end())
{
HandlePredicate(
- cmSystemTools::FileIsFullPath((argP1)->c_str()),
+ cmSystemTools::FileIsFullPath(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// does a command exist
if (*arg == "COMMAND" && argP1 != newArgs.end())
{
HandlePredicate(
- makefile->CommandExists((argP1)->c_str()),
+ makefile->CommandExists(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// does a policy exist
@@ -536,30 +542,31 @@ namespace
{
cmPolicies::PolicyID pid;
HandlePredicate(
- makefile->GetPolicies()->GetPolicyID((argP1)->c_str(), pid),
- reducible, arg, newArgs, argP1, argP2);
+ makefile->GetPolicies()->GetPolicyID(
+ argP1->c_str(), pid),
+ reducible, arg, newArgs, argP1, argP2);
}
// does a target exist
if (*arg == "TARGET" && argP1 != newArgs.end())
{
HandlePredicate(
- makefile->FindTargetToUse(*argP1)?true:false,
+ makefile->FindTargetToUse(argP1->GetValue())?true:false,
reducible, arg, newArgs, argP1, argP2);
}
// is a variable defined
if (*arg == "DEFINED" && argP1 != newArgs.end())
{
- size_t argP1len = argP1->size();
+ size_t argP1len = argP1->GetValue().size();
bool bdef = false;
- if(argP1len > 4 && argP1->substr(0, 4) == "ENV{" &&
- argP1->operator[](argP1len-1) == '}')
+ if(argP1len > 4 && argP1->GetValue().substr(0, 4) == "ENV{" &&
+ argP1->GetValue().operator[](argP1len-1) == '}')
{
- std::string env = argP1->substr(4, argP1len-5);
+ std::string env = argP1->GetValue().substr(4, argP1len-5);
bdef = cmSystemTools::GetEnv(env.c_str())?true:false;
}
else
{
- bdef = makefile->IsDefinitionSet(*(argP1));
+ bdef = makefile->IsDefinitionSet(argP1->GetValue());
}
HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
}
@@ -572,7 +579,7 @@ namespace
//=========================================================================
// level two handles most binary operations except for AND OR
- bool HandleLevel2(std::list<std::string> &newArgs,
+ bool HandleLevel2(cmArgumentList &newArgs,
cmMakefile *makefile,
std::string &errorString,
cmake::MessageType &status)
@@ -583,9 +590,9 @@ namespace
do
{
reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
while (arg != newArgs.end())
{
argP1 = arg;
@@ -594,7 +601,7 @@ namespace
*(argP1) == "MATCHES")
{
def = cmIfCommand::GetVariableOrString(*arg, makefile);
- const char* rex = (argP2)->c_str();
+ const char* rex = argP2->c_str();
makefile->ClearMatches();
cmsys::RegularExpression regEntry;
if ( !regEntry.compile(rex) )
@@ -608,11 +615,11 @@ namespace
if (regEntry.find(def))
{
makefile->StoreMatches(regEntry);
- *arg = "1";
+ *arg = cmExpandedCommandArgument("1", true);
}
else
{
- *arg = "0";
+ *arg = cmExpandedCommandArgument("0", true);
}
newArgs.erase(argP2);
newArgs.erase(argP1);
@@ -623,7 +630,7 @@ namespace
if (argP1 != newArgs.end() && *arg == "MATCHES")
{
- *arg = "0";
+ *arg = cmExpandedCommandArgument("0", true);
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
@@ -710,8 +717,8 @@ namespace
*(argP1) == "IS_NEWER_THAN")
{
int fileIsNewer=0;
- bool success=cmSystemTools::FileTimeCompare(arg->c_str(),
- (argP2)->c_str(),
+ bool success=cmSystemTools::FileTimeCompare(arg->GetValue(),
+ (argP2)->GetValue(),
&fileIsNewer);
HandleBinaryOp(
(success==false || fileIsNewer==1 || fileIsNewer==0),
@@ -727,7 +734,7 @@ namespace
//=========================================================================
// level 3 handles NOT
- bool HandleLevel3(std::list<std::string> &newArgs,
+ bool HandleLevel3(cmArgumentList &newArgs,
cmMakefile *makefile,
std::string &errorString,
cmPolicies::PolicyStatus Policy12Status,
@@ -737,16 +744,17 @@ namespace
do
{
reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
while (arg != newArgs.end())
{
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
if (argP1 != newArgs.end() && *arg == "NOT")
{
- bool rhs = GetBooleanValueWithAutoDereference(*argP1, makefile,
+ bool rhs = GetBooleanValueWithAutoDereference(*argP1,
+ makefile,
errorString,
Policy12Status,
status);
@@ -761,7 +769,7 @@ namespace
//=========================================================================
// level 4 handles AND OR
- bool HandleLevel4(std::list<std::string> &newArgs,
+ bool HandleLevel4(cmArgumentList &newArgs,
cmMakefile *makefile,
std::string &errorString,
cmPolicies::PolicyStatus Policy12Status,
@@ -773,9 +781,9 @@ namespace
do
{
reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
while (arg != newArgs.end())
{
argP1 = arg;
@@ -835,7 +843,7 @@ namespace
// directly. AND OR take variables or the values 0 or 1.
-bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
+bool cmIfCommand::IsTrue(const std::vector<cmExpandedCommandArgument> &args,
std::string &errorString, cmMakefile *makefile,
cmake::MessageType &status)
{
@@ -848,7 +856,7 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
}
// store the reduced args in this vector
- std::list<std::string> newArgs;
+ cmArgumentList newArgs;
// copy to the list structure
for(unsigned int i = 0; i < args.size(); ++i)
@@ -907,13 +915,49 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
}
//=========================================================================
-const char* cmIfCommand::GetVariableOrString(const std::string& str,
- const cmMakefile* mf)
+const char* cmIfCommand::GetDefinitionIfUnquoted(
+ const cmMakefile* mf,
+ cmExpandedCommandArgument const& argument)
+{
+ const char* def = mf->GetDefinition(argument.GetValue());
+
+ if(def && argument.WasQuoted())
+ {
+ cmOStringStream e;
+ switch(mf->GetPolicyStatus(cmPolicies::CMP0054))
+ {
+ case cmPolicies::WARN:
+ e << (mf->GetPolicies()->GetPolicyWarning(
+ cmPolicies::CMP0054)) << "\n";
+ e << "Quoted variables like '" << argument.GetValue() <<
+ "' are no longer dereferenced.";
+
+ mf->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ break;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ def = 0;
+ break;
+ }
+ }
+
+ return def;
+}
+
+//=========================================================================
+const char* cmIfCommand::GetVariableOrString(
+ const cmExpandedCommandArgument& argument,
+ const cmMakefile* mf)
{
- const char* def = mf->GetDefinition(str);
+ const char* def = cmIfCommand::GetDefinitionIfUnquoted(mf, argument);
+
if(!def)
{
- def = str.c_str();
+ def = argument.c_str();
}
+
return def;
}
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index 814c052..2749754 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -73,14 +73,19 @@ public:
// this is a shared function for both If and Else to determine if the
// arguments were valid, and if so, was the response true. If there is
// an error, the errorString will be set.
- static bool IsTrue(const std::vector<std::string> &args,
+ static bool IsTrue(const std::vector<cmExpandedCommandArgument> &args,
std::string &errorString, cmMakefile *mf,
cmake::MessageType &status);
+ // Filter the given variable definition based on policy CMP0054.
+ static const char* GetDefinitionIfUnquoted(
+ const cmMakefile* mf, cmExpandedCommandArgument const& argument);
+
// Get a definition from the makefile. If it doesn't exist,
// return the original string.
- static const char* GetVariableOrString(const std::string& str,
- const cmMakefile* mf);
+ static const char* GetVariableOrString(
+ const cmExpandedCommandArgument& argument,
+ const cmMakefile* mf);
cmTypeMacro(cmIfCommand, cmCommand);
};
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 04b2d27..7c89507 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -3292,6 +3292,7 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
this->FunctionBlockerBarriers.pop_back();
}
+//----------------------------------------------------------------------------
bool cmMakefile::ExpandArguments(
std::vector<cmListFileArgument> const& inArgs,
std::vector<std::string>& outArgs) const
@@ -3328,6 +3329,47 @@ bool cmMakefile::ExpandArguments(
}
//----------------------------------------------------------------------------
+bool cmMakefile::ExpandArguments(
+ std::vector<cmListFileArgument> const& inArgs,
+ std::vector<cmExpandedCommandArgument>& outArgs) const
+{
+ std::vector<cmListFileArgument>::const_iterator i;
+ std::string value;
+ outArgs.reserve(inArgs.size());
+ for(i = inArgs.begin(); i != inArgs.end(); ++i)
+ {
+ // No expansion in a bracket argument.
+ if(i->Delim == cmListFileArgument::Bracket)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(i->Value, true));
+ continue;
+ }
+ // Expand the variables in the argument.
+ value = i->Value;
+ this->ExpandVariablesInString(value, false, false, false,
+ i->FilePath, i->Line,
+ false, false);
+
+ // If the argument is quoted, it should be one argument.
+ // Otherwise, it may be a list of arguments.
+ if(i->Delim == cmListFileArgument::Quoted)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(value, true));
+ }
+ else
+ {
+ std::vector<std::string> stringArgs;
+ cmSystemTools::ExpandListArgument(value, stringArgs);
+ for(size_t j = 0; j < stringArgs.size(); ++j)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(stringArgs[j], false));
+ }
+ }
+ }
+ return !cmSystemTools::GetFatalErrorOccured();
+}
+
+//----------------------------------------------------------------------------
void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
{
if(!this->CallStack.empty())
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index d728a62..d4df717 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -21,6 +21,7 @@
#include "cmTarget.h"
#include "cmNewLineStyle.h"
#include "cmGeneratorTarget.h"
+#include "cmExpandedCommandArgument.h"
#include "cmake.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -770,6 +771,10 @@ public:
*/
bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
std::vector<std::string>& outArgs) const;
+
+ bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
+ std::vector<cmExpandedCommandArgument>& outArgs) const;
+
/**
* Get the instance
*/
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 693945d..1b3daf1 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -359,6 +359,11 @@ cmPolicies::cmPolicies()
CMP0053, "CMP0053",
"Simplify variable reference and escape sequence evaluation.",
3,1,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0054, "CMP0054",
+ "Don't dereference quoted variables in if() arguments.",
+ 3,1,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 5d69d14..9fefe59 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -109,6 +109,7 @@ public:
/// INTERFACE_INCLUDE_DIRECTORIES
CMP0053, ///< Simplify variable reference and escape sequence evaluation
+ CMP0054, ///< Don't dereference quoted variables in if() arguments
/** \brief Always the last entry.
*
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 7d2eead..3060ccc 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -34,7 +34,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
mf.ExpandArguments(this->Args, expandedArguments);
cmake::MessageType messageType;
bool isTrue =
diff --git a/Tests/RunCMake/CMP0054/CMP0054-NEW-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-NEW-stderr.txt
new file mode 100644
index 0000000..f5a8fbe
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-NEW-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-NEW.cmake b/Tests/RunCMake/CMP0054/CMP0054-NEW.cmake
new file mode 100644
index 0000000..d4f8de0
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-NEW.cmake
@@ -0,0 +1,21 @@
+cmake_policy(SET CMP0054 NEW)
+
+set(FOO "BAR")
+
+if("FOO" STREQUAL "BAR")
+ message(FATAL_ERROR "The given literals should not match")
+endif()
+
+if(NOT FOO STREQUAL "BAR")
+ message(FATAL_ERROR "The given variable should match the literal")
+endif()
+
+set(MYTRUE ON)
+
+if(NOT MYTRUE)
+ message(FATAL_ERROR "Expected MYTRUE to evaluate true")
+endif()
+
+if("MYTRUE")
+ message(FATAL_ERROR "Expected quoted MYTRUE to evaluate false")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-OLD-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-OLD-stderr.txt
new file mode 100644
index 0000000..f5a8fbe
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-OLD-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-OLD.cmake b/Tests/RunCMake/CMP0054/CMP0054-OLD.cmake
new file mode 100644
index 0000000..3730af4
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-OLD.cmake
@@ -0,0 +1,21 @@
+cmake_policy(SET CMP0054 OLD)
+
+set(FOO "BAR")
+
+if(NOT "FOO" STREQUAL "BAR")
+ message(FATAL_ERROR "The given literals should match")
+endif()
+
+if(NOT FOO STREQUAL "BAR")
+ message(FATAL_ERROR "The given literals should match")
+endif()
+
+set(MYTRUE ON)
+
+if(NOT MYTRUE)
+ message(FATAL_ERROR "Expected MYTRUE to evaluate true")
+endif()
+
+if(NOT "MYTRUE")
+ message(FATAL_ERROR "Expected quoted MYTRUE to evaluate true as well")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
new file mode 100644
index 0000000..d256463
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0054-WARN.cmake:3 \(if\):
+ Policy CMP0054 is not set: Don't dereference quoted variables in if\(\)
+ arguments. Run "cmake --help-policy CMP0054" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Quoted variables like 'FOO' are no longer dereferenced.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake b/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake
new file mode 100644
index 0000000..37855fc
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake
@@ -0,0 +1,5 @@
+set(FOO "BAR")
+
+if(NOT "FOO" STREQUAL "BAR")
+ message(FATAL_ERROR "The given literals should match")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMakeLists.txt b/Tests/RunCMake/CMP0054/CMakeLists.txt
new file mode 100644
index 0000000..2897109
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0054/RunCMakeTest.cmake b/Tests/RunCMake/CMP0054/RunCMakeTest.cmake
new file mode 100644
index 0000000..4cc7649
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0054-OLD)
+run_cmake(CMP0054-NEW)
+run_cmake(CMP0054-WARN)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 3cd9947..8f09c5f 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -47,6 +47,7 @@ add_RunCMake_test(CMP0049)
add_RunCMake_test(CMP0050)
add_RunCMake_test(CMP0051)
add_RunCMake_test(CMP0053)
+add_RunCMake_test(CMP0054)
add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange)
-----------------------------------------------------------------------
Summary of changes:
hooks/post-receive
--
CMake
More information about the Cmake-commits
mailing list