/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 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 "cmIfCommand.h"
#include "cmStringCommand.h"

#include <stdlib.h> // required for atof
#include <list>
#include <cmsys/RegularExpression.hxx>


static std::string cmIfCommandError(
  cmMakefile* mf, std::vector<std::string> const& args)
{
  cmLocalGenerator* lg = mf->GetLocalGenerator();
  std::string err = "given arguments:\n ";
  for(std::vector<std::string>::const_iterator i = args.begin();
      i != args.end(); ++i)
    {
    err += " ";
    err += lg->EscapeForCMake(i->c_str());
    }
  err += "\n";
  return err;
}

//=========================================================================
bool cmIfFunctionBlocker::
IsFunctionBlocked(const cmListFileFunction& lff,
                  cmMakefile &mf,
                  cmExecutionStatus &inStatus)
{
  // we start by recording all the functions
  if (!cmSystemTools::Strucmp(lff.Name.c_str(),"if"))
    {
    this->ScopeDepth++;
    }
  if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif"))
    {
    this->ScopeDepth--;
    // if this is the endif for this if statement, then start executing
    if (!this->ScopeDepth)
      {
      // Remove the function blocker for this scope or bail.
      cmsys::auto_ptr<cmFunctionBlocker>
        fb(mf.RemoveFunctionBlocker(this, lff));
      if(!fb.get()) { return false; }

      // execute the functions for the true parts of the if statement
      cmExecutionStatus status;
      int scopeDepth = 0;
      for(unsigned int c = 0; c < this->Functions.size(); ++c)
        {
        // keep track of scope depth
        if (!cmSystemTools::Strucmp(this->Functions[c].Name.c_str(),"if"))
          {
          scopeDepth++;
          }
        if (!cmSystemTools::Strucmp(this->Functions[c].Name.c_str(),"endif"))
          {
          scopeDepth--;
          }
        // watch for our state change
        if (scopeDepth == 0 &&
            !cmSystemTools::Strucmp(this->Functions[c].Name.c_str(),"else"))
          {
          this->IsBlocking = this->HasRun;
          this->HasRun = true;
          }
        else if (scopeDepth == 0 && !cmSystemTools::Strucmp
                 (this->Functions[c].Name.c_str(),"elseif"))
          {
          if (this->HasRun)
            {
            this->IsBlocking = true;
            }
          else
            {
            // Place this call on the call stack.
            cmMakefileCall stack_manager(&mf, this->Functions[c], status);
            static_cast<void>(stack_manager);

            std::string errorString;

            std::vector<std::string> expandedArguments;
            mf.ExpandArguments(this->Functions[c].Arguments,
                               expandedArguments);

            cmake::MessageType messType;
            bool isTrue =
              cmIfCommand::IsTrue(expandedArguments, errorString,
                                  &mf, messType);

            if (errorString.size())
              {
              std::string err = cmIfCommandError(&mf, expandedArguments);
              err += errorString;
              mf.IssueMessage(messType, err);
              if (messType == cmake::FATAL_ERROR)
                {
                cmSystemTools::SetFatalErrorOccured();
                return true;
                }
              }

            if (isTrue)
              {
              this->IsBlocking = false;
              this->HasRun = true;
              }
            }
          }

        // should we execute?
        else if (!this->IsBlocking)
          {
          status.Clear();
          mf.ExecuteCommand(this->Functions[c],status);
          if (status.GetReturnInvoked())
            {
            inStatus.SetReturnInvoked(true);
            return true;
            }
          if (status.GetBreakInvoked())
            {
            inStatus.SetBreakInvoked(true);
            return true;
            }
          }
        }
      return true;
      }
    }

  // record the command
  this->Functions.push_back(lff);

  // always return true
  return true;
}

//=========================================================================
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
                                       cmMakefile&)
{
  if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif"))
    {
    // if the endif has arguments, then make sure
    // they match the arguments of the matching if
    if (lff.Arguments.size() == 0 ||
        lff.Arguments == this->Args)
      {
      return true;
      }
    }

  return false;
}

//=========================================================================
bool cmIfCommand
::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
                    cmExecutionStatus &)
{
  std::string errorString;

  std::vector<std::string> expandedArguments;
  this->Makefile->ExpandArguments(args, expandedArguments);

  cmake::MessageType status;
  bool isTrue =
    cmIfCommand::IsTrue(expandedArguments,errorString,
                        this->Makefile, status);

  if (errorString.size())
    {
    std::string err = cmIfCommandError(this->Makefile, expandedArguments);
    err += errorString;
    if (status == cmake::FATAL_ERROR)
      {
      this->SetError(err.c_str());
      cmSystemTools::SetFatalErrorOccured();
      return false;
      }
    else
      {
      this->Makefile->IssueMessage(status, err);
      }
    }

  cmIfFunctionBlocker *f = new cmIfFunctionBlocker();
  // if is isn't true block the commands
  f->ScopeDepth = 1;
  f->IsBlocking = !isTrue;
  if (isTrue)
    {
    f->HasRun = true;
    }
  f->Args = args;
  this->Makefile->AddFunctionBlocker(f);

  return true;
}

namespace
{
  //=========================================================================
  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);
    }
  }

  //=========================================================================
  // returns the resulting boolean value
  bool GetBooleanValueWithAutoDereference(
    std::string &newArg,
    cmMakefile *makefile,
    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;
      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;
  }

  //=========================================================================
  void IncrementArguments(std::list<std::string> &newArgs,
                          std::list<std::string>::iterator &argP1,
                          std::list<std::string>::iterator &argP2)
  {
    if (argP1  != newArgs.end())
      {
      argP1++;
      argP2 = argP1;
      if (argP1  != newArgs.end())
        {
        argP2++;
        }
      }
  }

  //=========================================================================
  // 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)
  {
    if(value)
      {
      *arg = "1";
      }
    else
      {
      *arg = "0";
      }
    newArgs.erase(argP1);
    argP1 = arg;
    IncrementArguments(newArgs,argP1,argP2);
    reducible = 1;
  }

  //=========================================================================
  // 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)
  {
    if(value)
      {
      *arg = "1";
      }
    else
      {
      *arg = "0";
      }
    newArgs.erase(argP2);
    newArgs.erase(argP1);
    argP1 = arg;
    IncrementArguments(newArgs,argP1,argP2);
    reducible = 1;
  }

  //=========================================================================
  enum Op { OpLess, OpEqual, OpGreater };
  bool HandleVersionCompare(Op op, const char* lhs_str, const char* rhs_str)
  {
  // Parse out up to 4 components.
  unsigned int lhs[4] = {0,0,0,0};
  unsigned int rhs[4] = {0,0,0,0};
  sscanf(lhs_str, "%u.%u.%u.%u", &lhs[0], &lhs[1], &lhs[2], &lhs[3]);
  sscanf(rhs_str, "%u.%u.%u.%u", &rhs[0], &rhs[1], &rhs[2], &rhs[3]);

  // Do component-wise comparison.
  for(unsigned int i=0; i < 4; ++i)
    {
    if(lhs[i] < rhs[i])
      {
      // lhs < rhs, so true if operation is LESS
      return op == OpLess;
      }
    else if(lhs[i] > rhs[i])
      {
      // lhs > rhs, so true if operation is GREATER
      return op == OpGreater;
      }
    }
  // lhs == rhs, so true if operation is EQUAL
  return op == OpEqual;
  }

  //=========================================================================
  // level 0 processes parenthetical expressions
  bool HandleLevel0(std::list<std::string> &newArgs,
                    cmMakefile *makefile,
                    std::string &errorString,
                    cmake::MessageType &status)
  {
  int reducible;
  do
    {
    reducible = 0;
    std::list<std::string>::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;
        argClose = arg;
        argClose++;
        unsigned int depth = 1;
        while (argClose != newArgs.end() && depth)
          {
          if (*argClose == "(")
            {
              depth++;
            }
          if (*argClose == ")")
            {
              depth--;
            }
          argClose++;
          }
        if (depth)
          {
          errorString = "mismatched parenthesis in condition";
          status = cmake::FATAL_ERROR;
          return false;
          }
        // store the reduced args in this vector
        std::vector<std::string> newArgs2;

        // copy to the list structure
        std::list<std::string>::iterator argP1 = arg;
        argP1++;
        for(; argP1 != argClose; argP1++)
          {
          newArgs2.push_back(*argP1);
          }
        newArgs2.pop_back();
        // now recursively invoke IsTrue to handle the values inside the
        // parenthetical expression
        bool value =
          cmIfCommand::IsTrue(newArgs2, errorString, makefile, status);
        if(value)
          {
          *arg = "1";
          }
        else
          {
          *arg = "0";
          }
        argP1 = arg;
        argP1++;
        // remove the now evaluated parenthetical expression
        newArgs.erase(argP1,argClose);
        }
      ++arg;
      }
    }
  while (reducible);
  return true;
  }

  //=========================================================================
  // level one handles most predicates except for NOT
  bool HandleLevel1(std::list<std::string> &newArgs,
                    cmMakefile *makefile,
                    std::string &, cmake::MessageType &)
  {
  int reducible;
  do
    {
    reducible = 0;
    std::list<std::string>::iterator arg = newArgs.begin();
    std::list<std::string>::iterator argP1;
    std::list<std::string>::iterator argP2;
    while (arg != newArgs.end())
      {
      argP1 = arg;
      IncrementArguments(newArgs,argP1,argP2);
      // does a file exist
      if (*arg == "EXISTS" && argP1  != newArgs.end())
        {
        HandlePredicate(
          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()),
          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()),
          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()),
          reducible, arg, newArgs, argP1, argP2);
        }
      // does a command exist
      if (*arg == "COMMAND" && argP1  != newArgs.end())
        {
        HandlePredicate(
          makefile->CommandExists((argP1)->c_str()),
          reducible, arg, newArgs, argP1, argP2);
        }
      // does a policy exist
      if (*arg == "POLICY" && argP1 != newArgs.end())
        {
        cmPolicies::PolicyID pid;
        HandlePredicate(
          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)->c_str())? true:false,
          reducible, arg, newArgs, argP1, argP2);
        }
      // is a variable defined
      if (*arg == "DEFINED" && argP1  != newArgs.end())
        {
        size_t argP1len = argP1->size();
        bool bdef = false;
        if(argP1len > 4 && argP1->substr(0, 4) == "ENV{" &&
           argP1->operator[](argP1len-1) == '}')
          {
          std::string env = argP1->substr(4, argP1len-5);
          bdef = cmSystemTools::GetEnv(env.c_str())?true:false;
          }
        else
          {
          bdef = makefile->IsDefinitionSet((argP1)->c_str());
          }
        HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
        }
      ++arg;
      }
    }
  while (reducible);
  return true;
  }

  //=========================================================================
  // level two handles most binary operations except for AND  OR
  bool HandleLevel2(std::list<std::string> &newArgs,
                    cmMakefile *makefile,
                    std::string &errorString,
                    cmake::MessageType &status)
  {
  int reducible;
  const char *def;
  const char *def2;
  do
    {
    reducible = 0;
    std::list<std::string>::iterator arg = newArgs.begin();
    std::list<std::string>::iterator argP1;
    std::list<std::string>::iterator argP2;
    while (arg != newArgs.end())
      {
      argP1 = arg;
      IncrementArguments(newArgs,argP1,argP2);
      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
        *(argP1) == "MATCHES")
        {
        def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
        const char* rex = (argP2)->c_str();
        cmStringCommand::ClearMatches(makefile);
        cmsys::RegularExpression regEntry;
        if ( !regEntry.compile(rex) )
          {
          cmOStringStream error;
          error << "Regular expression \"" << rex << "\" cannot compile";
          errorString = error.str();
          status = cmake::FATAL_ERROR;
          return false;
          }
        if (regEntry.find(def))
          {
          cmStringCommand::StoreMatches(makefile, regEntry);
          *arg = "1";
          }
        else
          {
          *arg = "0";
          }
        newArgs.erase(argP2);
        newArgs.erase(argP1);
        argP1 = arg;
        IncrementArguments(newArgs,argP1,argP2);
        reducible = 1;
        }

      if (argP1 != newArgs.end() && *arg == "MATCHES")
        {
        *arg = "0";
        newArgs.erase(argP1);
        argP1 = arg;
        IncrementArguments(newArgs,argP1,argP2);
        reducible = 1;
        }

      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
        (*(argP1) == "LESS" || *(argP1) == "GREATER" ||
         *(argP1) == "EQUAL"))
        {
        def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
        def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
        double lhs;
        double rhs;
        bool result;
        if(sscanf(def, "%lg", &lhs) != 1 ||
           sscanf(def2, "%lg", &rhs) != 1)
          {
          result = false;
          }
        else if (*(argP1) == "LESS")
          {
          result = (lhs < rhs);
          }
        else if (*(argP1) == "GREATER")
          {
          result = (lhs > rhs);
          }
        else
          {
          result = (lhs == rhs);
          }
        HandleBinaryOp(result,
          reducible, arg, newArgs, argP1, argP2);
        }

      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
        (*(argP1) == "STRLESS" ||
         *(argP1) == "STREQUAL" ||
         *(argP1) == "STRGREATER"))
        {
        def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
        def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
        int val = strcmp(def,def2);
        bool result;
        if (*(argP1) == "STRLESS")
          {
          result = (val < 0);
          }
        else if (*(argP1) == "STRGREATER")
          {
          result = (val > 0);
          }
        else // strequal
          {
          result = (val == 0);
          }
        HandleBinaryOp(result,
          reducible, arg, newArgs, argP1, argP2);
        }

      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
        (*(argP1) == "VERSION_LESS" || *(argP1) == "VERSION_GREATER" ||
         *(argP1) == "VERSION_EQUAL"))
        {
        def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
        def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
        Op op = OpEqual;
        if(*argP1 == "VERSION_LESS")
          {
          op = OpLess;
          }
        else if(*argP1 == "VERSION_GREATER")
          {
          op = OpGreater;
          }
        bool result = HandleVersionCompare(op, def, def2);
        HandleBinaryOp(result,
          reducible, arg, newArgs, argP1, argP2);
        }

      // is file A newer than file B
      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
          *(argP1) == "IS_NEWER_THAN")
        {
        int fileIsNewer=0;
        bool success=cmSystemTools::FileTimeCompare(arg->c_str(),
            (argP2)->c_str(),
            &fileIsNewer);
        HandleBinaryOp(
          (success==false || fileIsNewer==1 || fileIsNewer==0),
          reducible, arg, newArgs, argP1, argP2);
        }

      ++arg;
      }
    }
  while (reducible);
  return true;
  }

  //=========================================================================
  // level 3 handles NOT
  bool HandleLevel3(std::list<std::string> &newArgs,
                    cmMakefile *makefile,
                    std::string &errorString,
                    cmPolicies::PolicyStatus Policy12Status,
                    cmake::MessageType &status)
  {
  int reducible;
  do
    {
    reducible = 0;
    std::list<std::string>::iterator arg = newArgs.begin();
    std::list<std::string>::iterator argP1;
    std::list<std::string>::iterator argP2;
    while (arg != newArgs.end())
      {
      argP1 = arg;
      IncrementArguments(newArgs,argP1,argP2);
      if (argP1 != newArgs.end() && *arg == "NOT")
        {
        bool rhs = GetBooleanValueWithAutoDereference(*argP1, makefile,
                                                      errorString,
                                                      Policy12Status,
                                                      status);
        HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2);
        }
      ++arg;
      }
    }
  while (reducible);
  return true;
  }

  //=========================================================================
  // level 4 handles AND OR
  bool HandleLevel4(std::list<std::string> &newArgs,
                    cmMakefile *makefile,
                    std::string &errorString,
                    cmPolicies::PolicyStatus Policy12Status,
                    cmake::MessageType &status)
  {
  int reducible;
  bool lhs;
  bool rhs;
  do
    {
    reducible = 0;
    std::list<std::string>::iterator arg = newArgs.begin();
    std::list<std::string>::iterator argP1;
    std::list<std::string>::iterator argP2;
    while (arg != newArgs.end())
      {
      argP1 = arg;
      IncrementArguments(newArgs,argP1,argP2);
      if (argP1 != newArgs.end() && *(argP1) == "AND" &&
        argP2 != newArgs.end())
        {
        lhs = GetBooleanValueWithAutoDereference(*arg, makefile,
                                                 errorString,
                                                 Policy12Status,
                                                 status);
        rhs = GetBooleanValueWithAutoDereference(*argP2, makefile,
                                                 errorString,
                                                 Policy12Status,
                                                 status);
        HandleBinaryOp((lhs && rhs),
          reducible, arg, newArgs, argP1, argP2);
        }

      if (argP1 != newArgs.end() && *(argP1) == "OR" &&
        argP2 != newArgs.end())
        {
        lhs = GetBooleanValueWithAutoDereference(*arg, makefile,
                                                 errorString,
                                                 Policy12Status,
                                                 status);
        rhs = GetBooleanValueWithAutoDereference(*argP2, makefile,
                                                 errorString,
                                                 Policy12Status,
                                                 status);
        HandleBinaryOp((lhs || rhs),
          reducible, arg, newArgs, argP1, argP2);
        }
      ++arg;
      }
    }
  while (reducible);
  return true;
  }
}


//=========================================================================
// order of operations,
// 1.   ( )   -- parenthetical groups
// 2.  IS_DIRECTORY EXISTS COMMAND DEFINED etc predicates
// 3. MATCHES LESS GREATER EQUAL STRLESS STRGREATER STREQUAL etc binary ops
// 4. NOT
// 5. AND OR
//
// There is an issue on whether the arguments should be values of references,
// for example IF (FOO AND BAR) should that compare the strings FOO and BAR
// or should it really do IF (${FOO} AND ${BAR}) Currently IS_DIRECTORY
// EXISTS COMMAND and DEFINED all take values. EQUAL, LESS and GREATER can
// take numeric values or variable names. STRLESS and STRGREATER take
// variable names but if the variable name is not found it will use the name
// directly. AND OR take variables or the values 0 or 1.


bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
                         std::string &errorString, cmMakefile *makefile,
                         cmake::MessageType &status)
{
  errorString = "";

  // handle empty invocation
  if (args.size() < 1)
    {
    return false;
    }

  // store the reduced args in this vector
  std::list<std::string> newArgs;

  // copy to the list structure
  for(unsigned int i = 0; i < args.size(); ++i)
    {
    newArgs.push_back(args[i]);
    }

  // now loop through the arguments and see if we can reduce any of them
  // we do this multiple times. Once for each level of precedence
  // parens
  if (!HandleLevel0(newArgs, makefile, errorString, status))
    {
    return false;
    }
  //predicates
  if (!HandleLevel1(newArgs, makefile, errorString, status))
    {
    return false;
    }
  // binary ops
  if (!HandleLevel2(newArgs, makefile, errorString, status))
    {
    return false;
    }

  // used to store the value of policy CMP0012 for performance
  cmPolicies::PolicyStatus Policy12Status =
    makefile->GetPolicyStatus(cmPolicies::CMP0012);

  // NOT
  if (!HandleLevel3(newArgs, makefile, errorString,
                    Policy12Status, status))
    {
    return false;
    }
  // AND OR
  if (!HandleLevel4(newArgs, makefile, errorString,
                    Policy12Status, status))
    {
    return false;
    }

  // now at the end there should only be one argument left
  if (newArgs.size() != 1)
    {
    errorString = "Unknown arguments specified";
    return false;
    }

  return GetBooleanValueWithAutoDereference(*(newArgs.begin()),
                                            makefile,
                                            errorString,
                                            Policy12Status,
                                            status, true);
}

//=========================================================================
const char* cmIfCommand::GetVariableOrString(const char* str,
                                             const cmMakefile* mf)
{
  const char* def = mf->GetDefinition(str);
  if(!def)
    {
    def = str;
    }
  return def;
}
