[Cmake-commits] CMake branch, next, updated. v3.0.1-5205-g283ae77
Brad King
brad.king at kitware.com
Mon Sep 8 12:41:36 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 283ae77d7d74e9fb1e9c5f2f52cfa6f18aa9491a (commit)
via b565eb750eaa74dfb9a67289f782010502cb1ba2 (commit)
from c4ee3ce9e88b3ae8a422787d18ce0b1cb499a014 (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=283ae77d7d74e9fb1e9c5f2f52cfa6f18aa9491a
commit 283ae77d7d74e9fb1e9c5f2f52cfa6f18aa9491a
Merge: c4ee3ce b565eb7
Author: Brad King <brad.king at kitware.com>
AuthorDate: Mon Sep 8 12:41:35 2014 -0400
Commit: CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Sep 8 12:41:35 2014 -0400
Merge topic 'if-sanity' into next
b565eb75 If: Introduce policy CMP0054 - don't dereference quoted variables in if()
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b565eb750eaa74dfb9a67289f782010502cb1ba2
commit b565eb750eaa74dfb9a67289f782010502cb1ba2
Author: Nils Gladitz <nilsgladitz at gmail.com>
AuthorDate: Thu Sep 4 20:21:28 2014 +0200
Commit: Brad King <brad.king at kitware.com>
CommitDate: Mon Sep 8 12:42:45 2014 -0400
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..79e5d21 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -199,3 +199,9 @@ 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 variable or keyword names can be
+specified in a :ref:`Quoted Argument` or a :ref:`Bracket Argument`.
+A quoted or bracketed variable or keyword will be interpreted as a
+string and not dereferenced or interpreted.
+See 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..dffee5e
--- /dev/null
+++ b/Help/policy/CMP0054.rst
@@ -0,0 +1,18 @@
+CMP0054
+-------
+
+Only interpret :command:`if` arguments as variables or keywords when unquoted.
+
+CMake 3.1 and above no longer dereference variables or interpret keywords
+in an :command:`if` command argument when it is a :ref:`Quoted Argument`
+or a :ref:`Bracket Argument`.
+
+The ``OLD`` behavior for this policy is to dereference variables and
+interpret keywords even if they are quoted or bracketed.
+The ``NEW`` behavior is to not dereference variables or interpret keywords
+that have been quoted or bracketed.
+
+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/Help/release/dev/if-sanity.rst b/Help/release/dev/if-sanity.rst
new file mode 100644
index 0000000..6645bc4
--- /dev/null
+++ b/Help/release/dev/if-sanity.rst
@@ -0,0 +1,6 @@
+if-sanity
+---------
+
+* The :command:`if` command no longer automatically dereferences
+ variables named in quoted or bracket arguments. See policy
+ :policy:`CMP0054`.
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..b1a68b5 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,51 @@ bool cmIfCommand
namespace
{
+ typedef std::list<cmExpandedCommandArgument> cmArgumentList;
+
+ //=========================================================================
+ bool IsKeyword(std::string const& keyword,
+ cmExpandedCommandArgument& argument,
+ cmMakefile* mf)
+ {
+ bool isKeyword = argument.GetValue() == keyword;
+
+ if(isKeyword && argument.WasQuoted())
+ {
+ cmOStringStream e;
+ switch(mf->GetPolicyStatus(cmPolicies::CMP0054))
+ {
+ case cmPolicies::WARN:
+ {
+ bool hasBeenReported = mf->HasCMP0054AlreadyBeenReported(
+ mf->GetBacktrace()[0]);
+
+ if(!hasBeenReported)
+ {
+ e << (mf->GetPolicies()->GetPolicyWarning(
+ cmPolicies::CMP0054)) << "\n";
+ e << "Quoted keywords like \"" << argument.GetValue() <<
+ "\" are no longer interpreted as keywords.";
+
+ mf->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ }
+ break;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ isKeyword = false;
+ break;
+ }
+ }
+
+ return isKeyword;
+ }
+
//=========================================================================
- bool GetBooleanValue(std::string& arg, cmMakefile* mf)
+ bool GetBooleanValue(cmExpandedCommandArgument& arg, cmMakefile* mf)
{
// Check basic constants.
if (arg == "0")
@@ -261,13 +304,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 +321,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 +341,7 @@ namespace
//=========================================================================
// returns the resulting boolean value
bool GetBooleanValueWithAutoDereference(
- std::string &newArg,
+ cmExpandedCommandArgument &newArg,
cmMakefile *makefile,
std::string &errorString,
cmPolicies::PolicyStatus Policy12Status,
@@ -321,7 +368,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 +379,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 +392,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 +410,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 +432,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 +454,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,23 +463,23 @@ namespace
do
{
reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
+ cmArgumentList::iterator arg = newArgs.begin();
while (arg != newArgs.end())
{
- if (*arg == "(")
+ if (IsKeyword("(", *arg, makefile))
{
// 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;
while (argClose != newArgs.end() && depth)
{
- if (*argClose == "(")
+ if (IsKeyword("(", *argClose, makefile))
{
depth++;
}
- if (*argClose == ")")
+ if (IsKeyword(")", *argClose, makefile))
{
depth--;
}
@@ -445,10 +492,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 +508,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 +528,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,77 +536,78 @@ 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);
// does a file exist
- if (*arg == "EXISTS" && argP1 != newArgs.end())
+ if (IsKeyword("EXISTS", *arg, makefile) && 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())
+ if (IsKeyword("IS_DIRECTORY", *arg, makefile) && 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())
+ if (IsKeyword("IS_SYMLINK", *arg, makefile) && 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())
+ if (IsKeyword("IS_ABSOLUTE", *arg, makefile) && 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())
+ if (IsKeyword("COMMAND", *arg, makefile) && argP1 != newArgs.end())
{
HandlePredicate(
- makefile->CommandExists((argP1)->c_str()),
+ makefile->CommandExists(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// does a policy exist
- if (*arg == "POLICY" && argP1 != newArgs.end())
+ if (IsKeyword("POLICY", *arg, makefile) && argP1 != newArgs.end())
{
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())
+ if (IsKeyword("TARGET", *arg, makefile) && 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())
+ if (IsKeyword("DEFINED", *arg, makefile) && 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 +620,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,18 +631,18 @@ 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() && argP2 != newArgs.end() &&
- *(argP1) == "MATCHES")
+ IsKeyword("MATCHES", *argP1, makefile))
{
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 +656,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);
@@ -621,9 +669,9 @@ namespace
reducible = 1;
}
- if (argP1 != newArgs.end() && *arg == "MATCHES")
+ if (argP1 != newArgs.end() && IsKeyword("MATCHES", *arg, makefile))
{
- *arg = "0";
+ *arg = cmExpandedCommandArgument("0", true);
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
@@ -631,8 +679,9 @@ namespace
}
if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "LESS" || *(argP1) == "GREATER" ||
- *(argP1) == "EQUAL"))
+ (IsKeyword("LESS", *argP1, makefile) ||
+ IsKeyword("GREATER", *argP1, makefile) ||
+ IsKeyword("EQUAL", *argP1, makefile)))
{
def = cmIfCommand::GetVariableOrString(*arg, makefile);
def2 = cmIfCommand::GetVariableOrString(*argP2, makefile);
@@ -661,9 +710,9 @@ namespace
}
if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "STRLESS" ||
- *(argP1) == "STREQUAL" ||
- *(argP1) == "STRGREATER"))
+ (IsKeyword("STRLESS", *argP1, makefile) ||
+ IsKeyword("STREQUAL", *argP1, makefile) ||
+ IsKeyword("STRGREATER", *argP1, makefile)))
{
def = cmIfCommand::GetVariableOrString(*arg, makefile);
def2 = cmIfCommand::GetVariableOrString(*argP2, makefile);
@@ -686,8 +735,9 @@ namespace
}
if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "VERSION_LESS" || *(argP1) == "VERSION_GREATER" ||
- *(argP1) == "VERSION_EQUAL"))
+ (IsKeyword("VERSION_LESS", *argP1, makefile) ||
+ IsKeyword("VERSION_GREATER", *argP1, makefile) ||
+ IsKeyword("VERSION_EQUAL", *argP1, makefile)))
{
def = cmIfCommand::GetVariableOrString(*arg, makefile);
def2 = cmIfCommand::GetVariableOrString(*argP2, makefile);
@@ -707,11 +757,11 @@ namespace
// is file A newer than file B
if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- *(argP1) == "IS_NEWER_THAN")
+ IsKeyword("IS_NEWER_THAN", *argP1, makefile))
{
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 +777,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 +787,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")
+ if (argP1 != newArgs.end() && IsKeyword("NOT", *arg, makefile))
{
- bool rhs = GetBooleanValueWithAutoDereference(*argP1, makefile,
+ bool rhs = GetBooleanValueWithAutoDereference(*argP1,
+ makefile,
errorString,
Policy12Status,
status);
@@ -761,7 +812,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,14 +824,14 @@ 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() && *(argP1) == "AND" &&
+ if (argP1 != newArgs.end() && IsKeyword("AND", *argP1, makefile) &&
argP2 != newArgs.end())
{
lhs = GetBooleanValueWithAutoDereference(*arg, makefile,
@@ -795,7 +846,7 @@ namespace
reducible, arg, newArgs, argP1, argP2);
}
- if (argP1 != newArgs.end() && *(argP1) == "OR" &&
+ if (argP1 != newArgs.end() && IsKeyword("OR", *argP1, makefile) &&
argP2 != newArgs.end())
{
lhs = GetBooleanValueWithAutoDereference(*arg, makefile,
@@ -835,7 +886,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 +899,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 +958,57 @@ 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(str);
+ const char* def = mf->GetDefinition(argument.GetValue());
+
+ if(def && argument.WasQuoted())
+ {
+ cmOStringStream e;
+ switch(mf->GetPolicyStatus(cmPolicies::CMP0054))
+ {
+ case cmPolicies::WARN:
+ {
+ bool hasBeenReported = mf->HasCMP0054AlreadyBeenReported(
+ mf->GetBacktrace()[0]);
+
+ if(!hasBeenReported)
+ {
+ 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 = 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..3017d15 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())
@@ -4938,12 +4980,14 @@ void cmMakefile::PopPolicyBarrier(bool reportError)
this->PolicyBarriers.pop_back();
}
+//----------------------------------------------------------------------------
bool cmMakefile::SetPolicyVersion(const char *version)
{
return this->GetCMakeInstance()->GetPolicies()->
ApplyPolicyVersion(this,version);
}
+//----------------------------------------------------------------------------
cmPolicies *cmMakefile::GetPolicies() const
{
if (!this->GetCMakeInstance())
@@ -4954,6 +4998,23 @@ cmPolicies *cmMakefile::GetPolicies() const
}
//----------------------------------------------------------------------------
+bool cmMakefile::HasCMP0054AlreadyBeenReported(
+ cmListFileContext context) const
+{
+ cmCMP0054Id id(context);
+
+ bool alreadyReported =
+ this->CMP0054ReportedIds.find(id) != this->CMP0054ReportedIds.end();
+
+ if(!alreadyReported)
+ {
+ this->CMP0054ReportedIds.insert(id);
+ }
+
+ return alreadyReported;
+}
+
+//----------------------------------------------------------------------------
void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
{
/* Record the setting of every policy. */
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index d728a62..164290a 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)
@@ -375,7 +376,35 @@ public:
/**
* Get the Policies Instance
*/
- cmPolicies *GetPolicies() const;
+ cmPolicies *GetPolicies() const;
+
+ struct cmCMP0054Id
+ {
+ cmCMP0054Id(cmListFileContext const& context):
+ Context(context)
+ {
+
+ }
+
+ bool operator< (cmCMP0054Id const& id) const
+ {
+ if(this->Context.FilePath != id.Context.FilePath)
+ return this->Context.FilePath < id.Context.FilePath;
+
+ return this->Context.Line < id.Context.Line;
+ }
+
+ cmListFileContext Context;
+ };
+
+ mutable std::set<cmCMP0054Id> CMP0054ReportedIds;
+
+ /**
+ * Determine if the given context, name pair has already been reported
+ * in context of CMP0054.
+ */
+ bool HasCMP0054AlreadyBeenReported(
+ cmListFileContext context) const;
/**
* Add an auxiliary directory to the build.
@@ -770,6 +799,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..a420f59 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",
+ "Only interpret if() arguments as variables or keywords when unquoted.",
+ 3,1,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 5d69d14..7c73da8 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -109,6 +109,8 @@ public:
/// INTERFACE_INCLUDE_DIRECTORIES
CMP0053, ///< Simplify variable reference and escape sequence evaluation
+ CMP0054, ///< Only interpret if() arguments as variables
+ /// or keywords when unquoted.
/** \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..23a9124
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-NEW.cmake
@@ -0,0 +1,47 @@
+cmake_policy(SET CMP0054 NEW)
+
+set(FOO "BAR")
+set(BAZ "ZZZ")
+set(MYTRUE ON)
+set(MYNUMBER 3)
+set(MYVERSION 3.0)
+
+function(assert_unquoted PREFIX FIRST)
+ string(REPLACE ";" " " ARGN_SP "${ARGN}")
+ if(${PREFIX} ${FIRST} ${ARGN})
+ message(FATAL_ERROR "Assertion failed [${PREFIX} ${FIRST} ${ARGN_SP}]")
+ endif()
+endfunction()
+
+function(assert_quoted PREFIX FIRST)
+ string(REPLACE ";" " " ARGN_SP "${ARGN}")
+ if(${PREFIX} "${FIRST}" ${ARGN})
+ message(FATAL_ERROR "Assertion failed [${PREFIX} \"${FIRST}\" ${ARGN_SP}]")
+ endif()
+endfunction()
+
+function(assert FIRST)
+ assert_unquoted(NOT ${FIRST} ${ARGN})
+ assert_quoted("" ${FIRST} ${ARGN})
+endfunction()
+
+assert(MYTRUE)
+
+assert(FOO MATCHES "^BAR$")
+
+assert(MYNUMBER LESS 4)
+assert(MYNUMBER GREATER 2)
+assert(MYNUMBER EQUAL 3)
+
+assert(FOO STRLESS CCC)
+assert(BAZ STRGREATER CCC)
+assert(FOO STREQUAL BAR)
+
+assert_unquoted(NOT MYVERSION VERSION_LESS 3.1)
+assert_unquoted("" MYVERSION VERSION_LESS 2.9)
+
+assert_quoted(NOT MYVERSION VERSION_LESS 2.9)
+assert_quoted(NOT MYVERSION VERSION_LESS 3.1)
+
+assert(MYVERSION VERSION_GREATER 2.9)
+assert(MYVERSION VERSION_EQUAL 3.0)
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..0c4cede
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-OLD.cmake
@@ -0,0 +1,47 @@
+cmake_policy(SET CMP0054 OLD)
+
+set(FOO "BAR")
+set(BAZ "ZZZ")
+set(MYTRUE ON)
+set(MYNUMBER 3)
+set(MYVERSION 3.0)
+
+function(assert_unquoted PREFIX FIRST)
+ string(REPLACE ";" " " ARGN_SP "${ARGN}")
+ if(${PREFIX} ${FIRST} ${ARGN})
+ message(FATAL_ERROR "Assertion failed [${PREFIX} ${FIRST} ${ARGN_SP}]")
+ endif()
+endfunction()
+
+function(assert_quoted PREFIX FIRST)
+ string(REPLACE ";" " " ARGN_SP "${ARGN}")
+ if(${PREFIX} "${FIRST}" ${ARGN})
+ message(FATAL_ERROR "Assertion failed [${PREFIX} \"${FIRST}\" ${ARGN_SP}]")
+ endif()
+endfunction()
+
+function(assert FIRST)
+ assert_unquoted(NOT ${FIRST} ${ARGN})
+ assert_quoted(NOT ${FIRST} ${ARGN})
+endfunction()
+
+assert(MYTRUE)
+
+assert(FOO MATCHES "^BAR$")
+
+assert(MYNUMBER LESS 4)
+assert(MYNUMBER GREATER 2)
+assert(MYNUMBER EQUAL 3)
+
+assert(FOO STRLESS CCC)
+assert(BAZ STRGREATER CCC)
+assert(FOO STREQUAL BAR)
+
+assert_unquoted(NOT MYVERSION VERSION_LESS 3.1)
+assert_unquoted("" MYVERSION VERSION_LESS 2.9)
+
+assert_quoted("" MYVERSION VERSION_LESS 2.9)
+assert_quoted(NOT MYVERSION VERSION_LESS 3.1)
+
+assert(MYVERSION VERSION_GREATER 2.9)
+assert(MYVERSION VERSION_EQUAL 3.0)
diff --git a/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
new file mode 100644
index 0000000..a32636c
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0054-WARN.cmake:3 \(if\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. 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/CMP0054-duplicate-warnings-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings-stderr.txt
new file mode 100644
index 0000000..950d939
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings-stderr.txt
@@ -0,0 +1,22 @@
+CMake Warning \(dev\) at CMP0054-duplicate-warnings.cmake:4 \(if\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. 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\):
+ CMP0054-duplicate-warnings.cmake:8 \(generate_warning\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at CMP0054-duplicate-warnings.cmake:11 \(if\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. 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-duplicate-warnings.cmake b/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings.cmake
new file mode 100644
index 0000000..04fbe14
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings.cmake
@@ -0,0 +1,12 @@
+set(FOO "BAR")
+
+function(generate_warning)
+ if("FOO" STREQUAL "BAR")
+ endif()
+endfunction()
+
+generate_warning()
+generate_warning()
+
+if("FOO" STREQUAL "BAR")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-result.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-stderr.txt
new file mode 100644
index 0000000..429803e
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at CMP0054-keywords-NEW.cmake:21 \(if\):
+ if given arguments:
+
+ "NOT" "1"
+
+ Unknown arguments specified
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW.cmake b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW.cmake
new file mode 100644
index 0000000..b60ece9
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW.cmake
@@ -0,0 +1,23 @@
+cmake_policy(SET CMP0054 NEW)
+
+function(assert KEYWORD)
+ if("${KEYWORD}" STREQUAL "${KEYWORD}")
+ else()
+ message(FATAL_ERROR
+ "Assertion failed [\"${KEYWORD}\" STREQUAL \"${KEYWORD}\"]")
+ endif()
+endfunction()
+
+assert("NOT")
+assert("COMMAND")
+assert("POLICY")
+assert("TARGET")
+assert("EXISTS")
+assert("IS_DIRECTORY")
+assert("IS_SYMLINK")
+assert("IS_ABSOLUTE")
+assert("DEFINED")
+
+if("NOT" 1)
+ message(FATAL_ERROR "[\"NOT\" 1] evaluated true")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD-stderr.txt
new file mode 100644
index 0000000..f5a8fbe
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD.cmake b/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD.cmake
new file mode 100644
index 0000000..a2a7f51
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD.cmake
@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0054 OLD)
+
+if(NOT 1)
+ message(FATAL_ERROR "[NOT 1] evaluated true")
+endif()
+
+if("NOT" 1)
+ message(FATAL_ERROR "[\"NOT\" 1] evaluated true")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt
new file mode 100644
index 0000000..351db3a
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0054-keywords-WARN.cmake:1 \(if\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ Quoted keywords like "NOT" are no longer interpreted as keywords.
+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-keywords-WARN.cmake b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake
new file mode 100644
index 0000000..ee0a623
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake
@@ -0,0 +1,3 @@
+if("NOT" 1)
+ message(FATAL_ERROR "[\"NOT\" 1] evaluated true")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope-stderr.txt
new file mode 100644
index 0000000..f5a8fbe
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope.cmake b/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope.cmake
new file mode 100644
index 0000000..b6b243c
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope.cmake
@@ -0,0 +1,53 @@
+set(FOO BAR)
+
+cmake_policy(SET CMP0054 NEW)
+
+function(function_defined_new_called_old)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+endfunction()
+
+macro(macro_defined_new_called_old)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+endmacro()
+
+cmake_policy(SET CMP0054 OLD)
+
+function_defined_new_called_old()
+macro_defined_new_called_old()
+
+function(function_defined_old_called_new)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+endfunction()
+
+macro(macro_defined_old_called_new)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+endmacro()
+
+cmake_policy(SET CMP0054 NEW)
+
+function_defined_old_called_new()
+macro_defined_old_called_new()
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..8df382f
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCMake)
+
+run_cmake(CMP0054-OLD)
+run_cmake(CMP0054-NEW)
+run_cmake(CMP0054-WARN)
+run_cmake(CMP0054-keywords-NEW)
+run_cmake(CMP0054-keywords-OLD)
+run_cmake(CMP0054-keywords-WARN)
+run_cmake(CMP0054-duplicate-warnings)
+run_cmake(CMP0054-policy-command-scope)
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