[Cmake-commits] [cmake-commits] king committed cmIfCommand.cxx 1.101 1.102 cmIfCommand.h 1.59 1.60 cmPolicies.cxx 1.49 1.50 cmPolicies.h 1.28 1.29

cmake-commits at cmake.org cmake-commits at cmake.org
Tue Oct 27 09:07:46 EDT 2009


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv17265/Source

Modified Files:
	cmIfCommand.cxx cmIfCommand.h cmPolicies.cxx cmPolicies.h 
Log Message:
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.


Index: cmPolicies.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -C 2 -d -r1.28 -r1.29
*** cmPolicies.h	8 Oct 2009 18:56:15 -0000	1.28
--- cmPolicies.h	27 Oct 2009 13:07:39 -0000	1.29
***************
*** 48,52 ****
      CMP0010, // Bad variable reference syntax is an error
      CMP0011, // Strong policy scope for include and find_package
!     CMP0012, // Strong handling of boolean constants
      CMP0013, // Duplicate binary directories not allowed
      CMP0014, // Input directories must have CMakeLists.txt
--- 48,52 ----
      CMP0010, // Bad variable reference syntax is an error
      CMP0011, // Strong policy scope for include and find_package
!     CMP0012, // Recognize numbers and boolean constants in if()
      CMP0013, // Duplicate binary directories not allowed
      CMP0014, // Input directories must have CMakeLists.txt

Index: cmPolicies.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.cxx,v
retrieving revision 1.49
retrieving revision 1.50
diff -C 2 -d -r1.49 -r1.50
*** cmPolicies.cxx	8 Oct 2009 18:56:15 -0000	1.49
--- cmPolicies.cxx	27 Oct 2009 13:07:38 -0000	1.50
***************
*** 359,375 ****
      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, "
      "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.",
      2,8,0, cmPolicies::WARN);
  
--- 359,380 ----
      this->DefinePolicy(
      CMP0012, "CMP0012",
!     "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.  "
!     "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);
  

Index: cmIfCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmIfCommand.cxx,v
retrieving revision 1.101
retrieving revision 1.102
diff -C 2 -d -r1.101 -r1.102
*** cmIfCommand.cxx	27 Oct 2009 13:01:33 -0000	1.101
--- cmIfCommand.cxx	27 Oct 2009 13:07:32 -0000	1.102
***************
*** 214,295 ****
  {
    //=========================================================================
!   // 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)
    {
!     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")
      {
!       result = false;
!       return true;
      }
!     if (newArg == "1")
      {
!       result = true;
!       return true;
      }
  
!     // old behavior is to dereference the var
!     if (Policy12Status == cmPolicies::OLD)
      {
!       return false;
      }
  
!     // now test for values that may be the name of a variable
!     // warn if used
!     if (cmSystemTools::IsOn(newArg.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;
        }
!     if (cmSystemTools::IsOff(newArg.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;
        }
!     return false;
    }
  
--- 214,280 ----
  {
    //=========================================================================
!   bool GetBooleanValue(std::string& arg, cmMakefile* mf)
    {
!   // Check basic constants.
!   if (arg == "0")
      {
!     return false;
      }
!   if (arg == "1")
      {
!     return true;
      }
  
!   // Check named constants.
!   if (cmSystemTools::IsOn(arg.c_str()))
      {
!     return true;
!     }
!   if (cmSystemTools::IsOff(arg.c_str()))
!     {
!     return false;
      }
  
!   // Check for numbers.
!   if(!arg.empty())
!     {
!     char* end;
!     double d = strtod(arg.c_str(), &end);
!     if(*end == '\0')
        {
!       // The whole string is a number.  Use C conversion to bool.
!       return d? true:false;
        }
!     }
! 
!   // 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()))
        {
!       def = arg.c_str();
        }
!     return !cmSystemTools::IsOff(def);
!     }
    }
  
***************
*** 301,314 ****
      std::string &errorString,
      cmPolicies::PolicyStatus Policy12Status,
!     cmake::MessageType &status)
    {
!     bool result = false;
!     if (GetBooleanValue(newArg, makefile, result,
!                         errorString, Policy12Status, status))
      {
!       return result;
      }
!     const char *def = makefile->GetDefinition(newArg.c_str());
!     return !cmSystemTools::IsOff(def);
    }
  
--- 286,334 ----
      std::string &errorString,
      cmPolicies::PolicyStatus Policy12Status,
!     cmake::MessageType &status,
!     bool oneArg = false)
    {
!   // Use the policy if it is set.
!   if (Policy12Status == cmPolicies::NEW)
      {
!     return GetBooleanValue(newArg, makefile);
      }
!   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;
    }
  
***************
*** 899,903 ****
                                              errorString,
                                              Policy12Status,
!                                             status);
  }
  
--- 919,923 ----
                                              errorString,
                                              Policy12Status,
!                                             status, true);
  }
  

Index: cmIfCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmIfCommand.h,v
retrieving revision 1.59
retrieving revision 1.60
diff -C 2 -d -r1.59 -r1.60
*** cmIfCommand.h	21 Oct 2009 17:11:16 -0000	1.59
--- cmIfCommand.h	27 Oct 2009 13:07:36 -0000	1.60
***************
*** 122,135 ****
        "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(COMMAND command-name)\n"
        "True if the given name is a command, macro or function that can be "
--- 122,143 ----
        "will be evaluated. Then NOT operators and finally AND, OR operators "
        "will be evaluated. Possible expressions are:\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 "



More information about the Cmake-commits mailing list