[Cmake-commits] [cmake-commits] martink committed cmIfCommand.cxx 1.85 1.86 cmListFileCache.cxx 1.46 1.47
cmake-commits at cmake.org
cmake-commits at cmake.org
Thu Jun 26 13:01:37 EDT 2008
Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv10873/Source
Modified Files:
cmIfCommand.cxx cmListFileCache.cxx
Log Message:
ENH: support parenthesis as arguments and in conditionals feature request #6191
Index: cmListFileCache.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmListFileCache.cxx,v
retrieving revision 1.46
retrieving revision 1.47
diff -C 2 -d -r1.46 -r1.47
*** cmListFileCache.cxx 27 Apr 2008 11:01:05 -0000 1.46
--- cmListFileCache.cxx 26 Jun 2008 17:01:35 -0000 1.47
***************
*** 243,251 ****
// Arguments.
unsigned long lastLine = cmListFileLexer_GetCurrentLine(lexer);
while((token = cmListFileLexer_Scan(lexer)))
{
! if(token->type == cmListFileLexer_Token_ParenRight)
{
! return true;
}
else if(token->type == cmListFileLexer_Token_Identifier ||
--- 243,266 ----
// Arguments.
unsigned long lastLine = cmListFileLexer_GetCurrentLine(lexer);
+ unsigned long parenDepth = 0;
while((token = cmListFileLexer_Scan(lexer)))
{
! if(token->type == cmListFileLexer_Token_ParenLeft)
{
! parenDepth++;
! cmListFileArgument a("(",
! false, filename, token->line);
! function.Arguments.push_back(a);
! }
! else if(token->type == cmListFileLexer_Token_ParenRight)
! {
! if (parenDepth == 0)
! {
! return true;
! }
! parenDepth--;
! cmListFileArgument a(")",
! false, filename, token->line);
! function.Arguments.push_back(a);
}
else if(token->type == cmListFileLexer_Token_Identifier ||
Index: cmIfCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmIfCommand.cxx,v
retrieving revision 1.85
retrieving revision 1.86
diff -C 2 -d -r1.85 -r1.86
*** cmIfCommand.cxx 20 Mar 2008 22:25:59 -0000 1.85
--- cmIfCommand.cxx 26 Jun 2008 17:01:34 -0000 1.86
***************
*** 22,27 ****
#include <cmsys/RegularExpression.hxx>
bool cmIfFunctionBlocker::
! IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
cmExecutionStatus &inStatus)
{
--- 22,29 ----
#include <cmsys/RegularExpression.hxx>
+ //=========================================================================
bool cmIfFunctionBlocker::
! IsFunctionBlocked(const cmListFileFunction& lff,
! cmMakefile &mf,
cmExecutionStatus &inStatus)
{
***************
*** 141,144 ****
--- 143,147 ----
}
+ //=========================================================================
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
cmMakefile&)
***************
*** 158,163 ****
}
! void cmIfFunctionBlocker::
! ScopeEnded(cmMakefile &mf)
{
std::string errmsg = "The end of a CMakeLists file was reached with an "
--- 161,166 ----
}
! //=========================================================================
! void cmIfFunctionBlocker::ScopeEnded(cmMakefile &mf)
{
std::string errmsg = "The end of a CMakeLists file was reached with an "
***************
*** 176,179 ****
--- 179,183 ----
}
+ //=========================================================================
bool cmIfCommand
::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
***************
*** 222,225 ****
--- 226,230 ----
namespace
{
+ //=========================================================================
void IncrementArguments(std::list<std::string> &newArgs,
std::list<std::string>::iterator &argP1,
***************
*** 236,289 ****
}
}
- }
-
-
- // order of operations,
- // IS_DIRECTORY EXISTS COMMAND DEFINED
- // MATCHES LESS GREATER EQUAL STRLESS STRGREATER STREQUAL
- // 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,
! char **errorString, cmMakefile *makefile)
! {
! // check for the different signatures
! const char *def;
! const char *def2;
! const char* msg = "Unknown arguments specified";
! *errorString = new char[strlen(msg) + 1];
! strcpy(*errorString, msg);
!
! // handle empty invocation
! if (args.size() < 1)
! {
! delete [] *errorString;
! *errorString = 0;
! return false;
! }
! // store the reduced args in this vector
! std::list<std::string> newArgs;
int reducible;
- unsigned int i;
-
- // copy to the list structure
- for(i = 0; i < args.size(); ++i)
- {
- newArgs.push_back(args[i]);
- }
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
-
- // 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
do
{
--- 241,297 ----
}
}
+ //=========================================================================
+ // 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;
! }
! //=========================================================================
! // level 0 processes parenthetical expressions
! bool HandleLevel0(std::list<std::string> &newArgs,
! cmMakefile *makefile,
! char **errorString)
! {
int reducible;
do
{
***************
*** 292,317 ****
while (arg != newArgs.end())
{
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! // does a file exist
! if (*arg == "EXISTS" && argP1 != newArgs.end())
{
! if(cmSystemTools::FileExists((argP1)->c_str()))
{
! *arg = "1";
}
! else
{
! *arg = "0";
}
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
! }
! // does a directory with this name exist
! if (*arg == "IS_DIRECTORY" && argP1 != newArgs.end())
! {
! if(cmSystemTools::FileIsDirectory((argP1)->c_str()))
{
*arg = "1";
--- 300,346 ----
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)
{
! cmOStringStream error;
! error << "mismatched parenthesis in condition";
! delete [] *errorString;
! *errorString = new char[error.str().size() + 1];
! strcpy(*errorString, error.str().c_str());
! 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);
! if(value)
{
*arg = "1";
***************
*** 321,360 ****
*arg = "0";
}
- newArgs.erase(argP1);
argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
// is the given path an absolute path ?
if (*arg == "IS_ABSOLUTE" && argP1 != newArgs.end())
{
! if(cmSystemTools::FileIsFullPath((argP1)->c_str()))
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
// does a command exist
if (*arg == "COMMAND" && argP1 != newArgs.end())
{
! if(makefile->CommandExists((argP1)->c_str()))
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
// does a policy exist
--- 350,409 ----
*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,
! char **)
! {
! 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);
}
// 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
***************
*** 362,377 ****
{
cmPolicies::PolicyID pid;
! if(makefile->GetPolicies()->GetPolicyID((argP1)->c_str(), pid))
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
// is a variable defined
--- 411,417 ----
{
cmPolicies::PolicyID pid;
! HandlePredicate(
! makefile->GetPolicies()->GetPolicyID((argP1)->c_str(), pid),
! reducible, arg, newArgs, argP1, argP2);
}
// is a variable defined
***************
*** 390,405 ****
bdef = makefile->IsDefinitionSet((argP1)->c_str());
}
! if(bdef)
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
++arg;
--- 430,434 ----
bdef = makefile->IsDefinitionSet((argP1)->c_str());
}
! HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
}
++arg;
***************
*** 407,419 ****
}
while (reducible);
!
! // 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
do
{
reducible = 0;
std::list<std::string>::iterator arg = newArgs.begin();
!
while (arg != newArgs.end())
{
--- 436,457 ----
}
while (reducible);
+ return true;
+ }
! //=========================================================================
! // level two handles most binary operations except for AND OR
! bool HandleLevel2(std::list<std::string> &newArgs,
! cmMakefile *makefile,
! char **errorString)
! {
! 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())
{
***************
*** 469,515 ****
double lhs;
double rhs;
if(sscanf(def, "%lg", &lhs) != 1 ||
sscanf(def2, "%lg", &rhs) != 1)
{
! *arg = "0";
}
else if (*(argP1) == "LESS")
{
! if(lhs < rhs)
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
}
else if (*(argP1) == "GREATER")
{
! if(lhs > rhs)
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
}
else
{
! if(lhs == rhs)
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
}
! newArgs.erase(argP2);
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
--- 507,530 ----
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);
}
***************
*** 522,526 ****
def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
int val = strcmp(def,def2);
! int result;
if (*(argP1) == "STRLESS")
{
--- 537,541 ----
def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
int val = strcmp(def,def2);
! bool result;
if (*(argP1) == "STRLESS")
{
***************
*** 535,551 ****
result = (val == 0);
}
! if(result)
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
! newArgs.erase(argP2);
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
--- 550,555 ----
result = (val == 0);
}
! HandleBinaryOp(result,
! reducible, arg, newArgs, argP1, argP2);
}
***************
*** 558,574 ****
(argP2)->c_str(),
&fileIsNewer);
! if(success==false || fileIsNewer==1 || fileIsNewer==0)
! {
! *arg = "1";
! }
! else
! {
! *arg = "0";
! }
! newArgs.erase(argP2);
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
--- 562,568 ----
(argP2)->c_str(),
&fileIsNewer);
! HandleBinaryOp(
! (success==false || fileIsNewer==1 || fileIsNewer==0),
! reducible, arg, newArgs, argP1, argP2);
}
***************
*** 577,588 ****
}
while (reducible);
!
! // 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
do
{
reducible = 0;
std::list<std::string>::iterator arg = newArgs.begin();
while (arg != newArgs.end())
{
--- 571,591 ----
}
while (reducible);
+ return true;
+ }
! //=========================================================================
! // level 3 handles NOT
! bool HandleLevel3(std::list<std::string> &newArgs,
! cmMakefile *makefile,
! char **)
! {
! int reducible;
! const char *def;
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())
{
***************
*** 592,607 ****
{
def = cmIfCommand::GetVariableOrNumber((argP1)->c_str(), makefile);
! if(!cmSystemTools::IsOff(def))
! {
! *arg = "0";
! }
! else
! {
! *arg = "1";
! }
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
++arg;
--- 595,600 ----
{
def = cmIfCommand::GetVariableOrNumber((argP1)->c_str(), makefile);
! HandlePredicate(cmSystemTools::IsOff(def),
! reducible, arg, newArgs, argP1, argP2);
}
++arg;
***************
*** 609,619 ****
}
while (reducible);
! // 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
do
{
reducible = 0;
std::list<std::string>::iterator arg = newArgs.begin();
while (arg != newArgs.end())
{
--- 602,623 ----
}
while (reducible);
+ return true;
+ }
! //=========================================================================
! // level 4 handles AND OR
! bool HandleLevel4(std::list<std::string> &newArgs,
! cmMakefile *makefile,
! char **)
! {
! 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())
{
***************
*** 625,641 ****
def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile);
def2 = cmIfCommand::GetVariableOrNumber((argP2)->c_str(), makefile);
! if(cmSystemTools::IsOff(def) || cmSystemTools::IsOff(def2))
! {
! *arg = "0";
! }
! else
! {
! *arg = "1";
! }
! newArgs.erase(argP2);
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
--- 629,635 ----
def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile);
def2 = cmIfCommand::GetVariableOrNumber((argP2)->c_str(), makefile);
! HandleBinaryOp(
! !(cmSystemTools::IsOff(def) || cmSystemTools::IsOff(def2)),
! reducible, arg, newArgs, argP1, argP2);
}
***************
*** 645,667 ****
def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile);
def2 = cmIfCommand::GetVariableOrNumber((argP2)->c_str(), makefile);
! if(cmSystemTools::IsOff(def) && cmSystemTools::IsOff(def2))
! {
! *arg = "0";
! }
! else
! {
! *arg = "1";
! }
! newArgs.erase(argP2);
! newArgs.erase(argP1);
! argP1 = arg;
! IncrementArguments(newArgs,argP1,argP2);
! reducible = 1;
}
-
++arg;
}
}
while (reducible);
// now at the end there should only be one argument left
--- 639,720 ----
def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile);
def2 = cmIfCommand::GetVariableOrNumber((argP2)->c_str(), makefile);
! HandleBinaryOp(
! !(cmSystemTools::IsOff(def) && cmSystemTools::IsOff(def2)),
! 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,
+ char **errorString, cmMakefile *makefile)
+ {
+ // check for the different signatures
+ const char *def;
+ const char* msg = "Unknown arguments specified";
+ *errorString = new char[strlen(msg) + 1];
+ strcpy(*errorString, msg);
+
+ // handle empty invocation
+ if (args.size() < 1)
+ {
+ delete [] *errorString;
+ *errorString = 0;
+ 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
+ if (!HandleLevel0(newArgs, makefile, errorString)) // parens
+ {
+ return false;
+ }
+ if (!HandleLevel1(newArgs, makefile, errorString)) //predicates
+ {
+ return false;
+ }
+ if (!HandleLevel2(newArgs, makefile, errorString)) // binary ops
+ {
+ return false;
+ }
+ if (!HandleLevel3(newArgs, makefile, errorString)) // NOT
+ {
+ return false;
+ }
+ if (!HandleLevel4(newArgs, makefile, errorString)) // AND OR
+ {
+ return false;
+ }
// now at the end there should only be one argument left
***************
*** 688,691 ****
--- 741,745 ----
}
+ //=========================================================================
const char* cmIfCommand::GetVariableOrString(const char* str,
const cmMakefile* mf)
***************
*** 699,702 ****
--- 753,757 ----
}
+ //=========================================================================
const char* cmIfCommand::GetVariableOrNumber(const char* str,
const cmMakefile* mf)
More information about the Cmake-commits
mailing list