summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmIfCommand.cxx166
-rw-r--r--Source/cmIfCommand.h28
-rw-r--r--Source/cmPolicies.cxx25
-rw-r--r--Source/cmPolicies.h2
4 files changed, 127 insertions, 94 deletions
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 5c8f07a..dfdbc86 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -213,84 +213,69 @@ bool cmIfCommand
namespace
{
//=========================================================================
- // returns true if succesfull, the resulting bool parsed is stored in result
- bool GetBooleanValue(std::string &newArg,
- cmMakefile *makefile,
- bool &result,
- std::string &errorString,
- cmPolicies::PolicyStatus Policy12Status,
- cmake::MessageType &status)
+ bool GetBooleanValue(std::string& arg, cmMakefile* mf)
{
- if (Policy12Status != cmPolicies::OLD &&
- Policy12Status != cmPolicies::WARN)
- {
- // please note IsOn(var) does not always equal !IsOff(var)
- // that is why each is called
- if (cmSystemTools::IsOn(newArg.c_str()))
- {
- result = true;
- return true;
- }
- if (cmSystemTools::IsOff(newArg.c_str()))
- {
- result = false;
- return true;
- }
- return false;
- }
-
- // Old policy is more complex...
- // 0 and 1 are very common, test for them first quickly
- if (newArg == "0")
+ // Check basic constants.
+ if (arg == "0")
{
- result = false;
- return true;
+ return false;
}
- if (newArg == "1")
+ if (arg == "1")
{
- result = true;
- return true;
+ return true;
}
- // old behavior is to dereference the var
- if (Policy12Status == cmPolicies::OLD)
+ // Check named constants.
+ if (cmSystemTools::IsOn(arg.c_str()))
{
- return false;
+ return true;
+ }
+ if (cmSystemTools::IsOff(arg.c_str()))
+ {
+ return false;
}
- // now test for values that may be the name of a variable
- // warn if used
- if (cmSystemTools::IsOn(newArg.c_str()))
+ // Check for numbers.
+ if(!arg.empty())
+ {
+ char* end;
+ double d = strtod(arg.c_str(), &end);
+ if(*end == '\0')
{
- // only warn if the value would change
- const char *def = makefile->GetDefinition(newArg.c_str());
- if (cmSystemTools::IsOff(def))
- {
- cmPolicies* policies = makefile->GetPolicies();
- errorString = "A variable or argument named \""
- + newArg
- + "\" appears in a conditional statement. "
- + policies->GetPolicyWarning(cmPolicies::CMP0012);
- status = cmake::AUTHOR_WARNING;
- }
- return false;
+ // The whole string is a number. Use C conversion to bool.
+ return d? true:false;
}
- if (cmSystemTools::IsOff(newArg.c_str()))
+ }
+
+ // Check definition.
+ const char* def = mf->GetDefinition(arg.c_str());
+ return !cmSystemTools::IsOff(def);
+ }
+
+ //=========================================================================
+ // Boolean value behavior from CMake 2.6.4 and below.
+ bool GetBooleanValueOld(std::string const& arg, cmMakefile* mf, bool one)
+ {
+ if(one)
+ {
+ // Old IsTrue behavior for single argument.
+ if(arg == "0")
+ { return false; }
+ else if(arg == "1")
+ { return true; }
+ else
+ { return !cmSystemTools::IsOff(mf->GetDefinition(arg.c_str())); }
+ }
+ else
+ {
+ // Old GetVariableOrNumber behavior.
+ const char* def = mf->GetDefinition(arg.c_str());
+ if(!def && atoi(arg.c_str()))
{
- // only warn if the value would change
- const char *def = makefile->GetDefinition(newArg.c_str());
- if (!cmSystemTools::IsOff(def))
- {
- cmPolicies* policies = makefile->GetPolicies();
- errorString = "A variable or argument named \""
- + newArg
- + "\" appears in a conditional statement. "
- + policies->GetPolicyWarning(cmPolicies::CMP0012);
- status = cmake::AUTHOR_WARNING;
- }
- return false;
+ def = arg.c_str();
}
- return false;
+ return !cmSystemTools::IsOff(def);
+ }
}
//=========================================================================
@@ -300,16 +285,51 @@ namespace
cmMakefile *makefile,
std::string &errorString,
cmPolicies::PolicyStatus Policy12Status,
- cmake::MessageType &status)
+ cmake::MessageType &status,
+ bool oneArg = false)
{
- bool result = false;
- if (GetBooleanValue(newArg, makefile, result,
- errorString, Policy12Status, status))
+ // Use the policy if it is set.
+ if (Policy12Status == cmPolicies::NEW)
{
- return result;
+ return GetBooleanValue(newArg, makefile);
}
- const char *def = makefile->GetDefinition(newArg.c_str());
- return !cmSystemTools::IsOff(def);
+ else if (Policy12Status == cmPolicies::OLD)
+ {
+ return GetBooleanValueOld(newArg, makefile, oneArg);
+ }
+
+ // Check policy only if old and new results differ.
+ bool newResult = GetBooleanValue(newArg, makefile);
+ bool oldResult = GetBooleanValueOld(newArg, makefile, oneArg);
+ if(newResult != oldResult)
+ {
+ switch(Policy12Status)
+ {
+ case cmPolicies::WARN:
+ {
+ cmPolicies* policies = makefile->GetPolicies();
+ errorString = "An argument named \"" + newArg
+ + "\" appears in a conditional statement. "
+ + policies->GetPolicyWarning(cmPolicies::CMP0012);
+ status = cmake::AUTHOR_WARNING;
+ }
+ case cmPolicies::OLD:
+ return oldResult;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ cmPolicies* policies = makefile->GetPolicies();
+ errorString = "An argument named \"" + newArg
+ + "\" appears in a conditional statement. "
+ + policies->GetRequiredPolicyError(cmPolicies::CMP0012);
+ status = cmake::FATAL_ERROR;
+ }
+ case cmPolicies::NEW:
+ break;
+ }
+ }
+ return newResult;
}
//=========================================================================
@@ -898,7 +918,7 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
makefile,
errorString,
Policy12Status,
- status);
+ status, true);
}
//=========================================================================
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index f480220..107a892 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -121,16 +121,24 @@ public:
"Then any EQUAL, LESS, GREATER, STRLESS, STRGREATER, STREQUAL, MATCHES "
"will be evaluated. Then NOT operators and finally AND, OR operators "
"will be evaluated. Possible expressions are:\n"
- " if(variable)\n"
- "True if the variable's value is not empty, 0, N, NO, OFF, FALSE, "
- "NOTFOUND, or <variable>-NOTFOUND.\n"
- " if(NOT variable)\n"
- "True if the variable's value is empty, 0, N, NO, OFF, FALSE, "
- "NOTFOUND, or <variable>-NOTFOUND.\n"
- " if(variable1 AND variable2)\n"
- "True if both variables would be considered true individually.\n"
- " if(variable1 OR variable2)\n"
- "True if either variable would be considered true individually.\n"
+ " if(<constant>)\n"
+ "True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number. "
+ "False if the constant is 0, OFF, NO, FALSE, N, IGNORE, \"\", "
+ "or ends in the suffix '-NOTFOUND'. "
+ "Named boolean constants are case-insensitive."
+ "\n"
+ " if(<variable>)\n"
+ "True if the variable's value is not a false constant."
+ "\n"
+ " if(NOT <expression>)\n"
+ "True if the expression is not true."
+ "\n"
+ " if(<expr1> AND <expr2>)\n"
+ "True if both expressions would be considered true individually."
+ "\n"
+ " if(<expr1> OR <expr2>)\n"
+ "True if either expression would be considered true individually."
+ "\n"
" if(COMMAND command-name)\n"
"True if the given name is a command, macro or function that can be "
"invoked.\n"
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 0d35b65..6b35b5b 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -358,19 +358,24 @@ cmPolicies::cmPolicies()
this->DefinePolicy(
CMP0012, "CMP0012",
- "The if() command can recognize named boolean constants.",
- "In CMake versions 2.6.4 and lower the only boolean constants were 0 "
- "and 1. Other boolean constants such as true, false, yes, no, "
+ "if() recognizes numbers and boolean constants.",
+ "In CMake versions 2.6.4 and lower the if() command implicitly "
+ "dereferenced arguments corresponding to variables, even those named "
+ "like numbers or boolean constants, except for 0 and 1. "
+ "Numbers and boolean constants such as true, false, yes, no, "
"on, off, y, n, notfound, ignore (all case insensitive) were recognized "
"in some cases but not all. "
"For example, the code \"if(TRUE)\" might have evaluated as false. "
- "In later versions of cmake these values are "
- "treated as boolean constants more consistently and should not be used "
- "as variable names. "
- "The OLD behavior for this policy is to allow variables to have names "
- "such as true and to dereference them. "
- "The NEW behavior for this policy is to treat strings like true as a "
- "boolean constant.",
+ "Numbers such as 2 were recognized only in "
+ "boolean expressions like \"if(NOT 2)\" (leading to false) "
+ "but not as a single-argument like \"if(2)\" (also leading to false). "
+ "Later versions of CMake prefer to treat numbers and boolean constants "
+ "literally, so they should not be used as variable names."
+ "\n"
+ "The OLD behavior for this policy is to implicitly dereference variables "
+ "named like numbers and boolean constants. "
+ "The NEW behavior for this policy is to recognize numbers and "
+ "boolean constants without dereferencing variables with such names.",
2,8,0, cmPolicies::WARN);
this->DefinePolicy(
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index cf808bd..4d1c3fc 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -47,7 +47,7 @@ public:
CMP0009, // GLOB_RECURSE should not follow symlinks by default
CMP0010, // Bad variable reference syntax is an error
CMP0011, // Strong policy scope for include and find_package
- CMP0012, // Strong handling of boolean constants
+ CMP0012, // Recognize numbers and boolean constants in if()
CMP0013, // Duplicate binary directories not allowed
CMP0014, // Input directories must have CMakeLists.txt