summaryrefslogtreecommitdiff
path: root/Source/cmIfCommand.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2009-10-27 09:07:39 -0400
committerBrad King <brad.king@kitware.com>2009-10-27 09:07:39 -0400
commitcb185d93d29d27eaafd321f657f4ba12d9beaeb8 (patch)
treecaba9c82f1ce3f68a16a577dfff0deb4eda7506a /Source/cmIfCommand.cxx
parent9f43fa602d53d131adffd1a3bb8188b549a96a01 (diff)
downloadcmake-cb185d93d29d27eaafd321f657f4ba12d9beaeb8.tar.gz
Fix if() command and CMP0012 OLD/NEW behavior
The commit "modified the if command to address bug 9123 some" changed the if() command behavior with respect to named boolean constants. It introduced policy CMP0012 to provide compatibility. However, it also changed behavior with respect to numbers (like '2') but did not cover the change with the policy. Also, the behavior it created for numbers is confusing ('2' is false). This commit teaches if() to recognize numbers again, and treats them like the C language does in terms of boolean conversion. We also fix the CMP0012 check to trigger in all cases where the result of boolean coersion differs from that produced by CMake 2.6.4.
Diffstat (limited to 'Source/cmIfCommand.cxx')
-rw-r--r--Source/cmIfCommand.cxx166
1 files changed, 93 insertions, 73 deletions
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 5c8f07aa38..dfdbc8634e 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);
}
//=========================================================================