ENH: support parenthesis as arguments and in conditionals feature request #6191

This commit is contained in:
Ken Martin 2008-06-26 13:01:35 -04:00
parent d8e05b43a1
commit 19e891532a
11 changed files with 346 additions and 228 deletions

View File

@ -21,8 +21,10 @@
#include <list> #include <list>
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
//=========================================================================
bool cmIfFunctionBlocker:: bool cmIfFunctionBlocker::
IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile &mf,
cmExecutionStatus &inStatus) cmExecutionStatus &inStatus)
{ {
// Prevent recusion and don't let this blocker block its own // Prevent recusion and don't let this blocker block its own
@ -140,6 +142,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
return true; return true;
} }
//=========================================================================
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
cmMakefile&) cmMakefile&)
{ {
@ -157,8 +160,8 @@ bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
return false; return false;
} }
void cmIfFunctionBlocker:: //=========================================================================
ScopeEnded(cmMakefile &mf) void cmIfFunctionBlocker::ScopeEnded(cmMakefile &mf)
{ {
std::string errmsg = "The end of a CMakeLists file was reached with an " std::string errmsg = "The end of a CMakeLists file was reached with an "
"IF statement that was not closed properly.\nWithin the directory: "; "IF statement that was not closed properly.\nWithin the directory: ";
@ -175,6 +178,7 @@ ScopeEnded(cmMakefile &mf)
cmSystemTools::Message(errmsg.c_str(), "Warning"); cmSystemTools::Message(errmsg.c_str(), "Warning");
} }
//=========================================================================
bool cmIfCommand bool cmIfCommand
::InvokeInitialPass(const std::vector<cmListFileArgument>& args, ::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
cmExecutionStatus &) cmExecutionStatus &)
@ -221,6 +225,7 @@ bool cmIfCommand
namespace namespace
{ {
//=========================================================================
void IncrementArguments(std::list<std::string> &newArgs, void IncrementArguments(std::list<std::string> &newArgs,
std::list<std::string>::iterator &argP1, std::list<std::string>::iterator &argP1,
std::list<std::string>::iterator &argP2) std::list<std::string>::iterator &argP2)
@ -235,60 +240,140 @@ namespace
} }
} }
} }
//=========================================================================
// 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;
} }
//=========================================================================
// order of operations, // helper function to reduce code duplication
// IS_DIRECTORY EXISTS COMMAND DEFINED void HandleBinaryOp(bool value, int &reducible,
// MATCHES LESS GREATER EQUAL STRLESS STRGREATER STREQUAL std::list<std::string>::iterator &arg,
// AND OR std::list<std::string> &newArgs,
// std::list<std::string>::iterator &argP1,
// There is an issue on whether the arguments should be values of references, std::list<std::string>::iterator &argP2)
// 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 if(value)
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; *arg = "1";
*errorString = 0; }
return false; else
{
*arg = "0";
}
newArgs.erase(argP2);
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
// store the reduced args in this vector //=========================================================================
std::list<std::string> newArgs; // level 0 processes parenthetical expressions
bool HandleLevel0(std::list<std::string> &newArgs,
cmMakefile *makefile,
char **errorString)
{
int reducible; 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 do
{ {
reducible = 0; reducible = 0;
std::list<std::string>::iterator arg = newArgs.begin(); 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)
{
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";
}
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,
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()) while (arg != newArgs.end())
{ {
argP1 = arg; argP1 = arg;
@ -296,83 +381,38 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
// does a file exist // does a file exist
if (*arg == "EXISTS" && argP1 != newArgs.end()) if (*arg == "EXISTS" && argP1 != newArgs.end())
{ {
if(cmSystemTools::FileExists((argP1)->c_str())) HandlePredicate(
{ cmSystemTools::FileExists((argP1)->c_str()),
*arg = "1"; reducible, arg, newArgs, argP1, argP2);
}
else
{
*arg = "0";
}
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
// does a directory with this name exist // does a directory with this name exist
if (*arg == "IS_DIRECTORY" && argP1 != newArgs.end()) if (*arg == "IS_DIRECTORY" && argP1 != newArgs.end())
{ {
if(cmSystemTools::FileIsDirectory((argP1)->c_str())) HandlePredicate(
{ cmSystemTools::FileIsDirectory((argP1)->c_str()),
*arg = "1"; reducible, arg, newArgs, argP1, argP2);
}
else
{
*arg = "0";
}
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
// is the given path an absolute path ? // is the given path an absolute path ?
if (*arg == "IS_ABSOLUTE" && argP1 != newArgs.end()) if (*arg == "IS_ABSOLUTE" && argP1 != newArgs.end())
{ {
if(cmSystemTools::FileIsFullPath((argP1)->c_str())) HandlePredicate(
{ cmSystemTools::FileIsFullPath((argP1)->c_str()),
*arg = "1"; reducible, arg, newArgs, argP1, argP2);
}
else
{
*arg = "0";
}
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
// does a command exist // does a command exist
if (*arg == "COMMAND" && argP1 != newArgs.end()) if (*arg == "COMMAND" && argP1 != newArgs.end())
{ {
if(makefile->CommandExists((argP1)->c_str())) HandlePredicate(
{ makefile->CommandExists((argP1)->c_str()),
*arg = "1"; reducible, arg, newArgs, argP1, argP2);
}
else
{
*arg = "0";
}
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
// does a policy exist // does a policy exist
if (*arg == "POLICY" && argP1 != newArgs.end()) if (*arg == "POLICY" && argP1 != newArgs.end())
{ {
cmPolicies::PolicyID pid; cmPolicies::PolicyID pid;
if(makefile->GetPolicies()->GetPolicyID((argP1)->c_str(), pid)) HandlePredicate(
{ makefile->GetPolicies()->GetPolicyID((argP1)->c_str(), pid),
*arg = "1"; reducible, arg, newArgs, argP1, argP2);
}
else
{
*arg = "0";
}
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
// is a variable defined // is a variable defined
if (*arg == "DEFINED" && argP1 != newArgs.end()) if (*arg == "DEFINED" && argP1 != newArgs.end())
@ -389,32 +429,30 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
{ {
bdef = makefile->IsDefinitionSet((argP1)->c_str()); bdef = makefile->IsDefinitionSet((argP1)->c_str());
} }
if(bdef) HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
{
*arg = "1";
}
else
{
*arg = "0";
}
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
++arg; ++arg;
} }
} }
while (reducible); while (reducible);
return true;
}
//=========================================================================
// now loop through the arguments and see if we can reduce any of them // level two handles most binary operations except for AND OR
// we do this multiple times. Once for each level of precedence bool HandleLevel2(std::list<std::string> &newArgs,
cmMakefile *makefile,
char **errorString)
{
int reducible;
const char *def;
const char *def2;
do do
{ {
reducible = 0; reducible = 0;
std::list<std::string>::iterator arg = newArgs.begin(); std::list<std::string>::iterator arg = newArgs.begin();
std::list<std::string>::iterator argP1;
std::list<std::string>::iterator argP2;
while (arg != newArgs.end()) while (arg != newArgs.end())
{ {
argP1 = arg; argP1 = arg;
@ -468,49 +506,26 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile); def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
double lhs; double lhs;
double rhs; double rhs;
bool result;
if(sscanf(def, "%lg", &lhs) != 1 || if(sscanf(def, "%lg", &lhs) != 1 ||
sscanf(def2, "%lg", &rhs) != 1) sscanf(def2, "%lg", &rhs) != 1)
{ {
*arg = "0"; result = false;
} }
else if (*(argP1) == "LESS") else if (*(argP1) == "LESS")
{ {
if(lhs < rhs) result = (lhs < rhs);
{
*arg = "1";
}
else
{
*arg = "0";
}
} }
else if (*(argP1) == "GREATER") else if (*(argP1) == "GREATER")
{ {
if(lhs > rhs) result = (lhs > rhs);
{
*arg = "1";
} }
else else
{ {
*arg = "0"; result = (lhs == rhs);
} }
} HandleBinaryOp(result,
else reducible, arg, newArgs, argP1, argP2);
{
if(lhs == rhs)
{
*arg = "1";
}
else
{
*arg = "0";
}
}
newArgs.erase(argP2);
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
if (argP1 != newArgs.end() && argP2 != newArgs.end() && if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
@ -521,7 +536,7 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile); def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile); def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
int val = strcmp(def,def2); int val = strcmp(def,def2);
int result; bool result;
if (*(argP1) == "STRLESS") if (*(argP1) == "STRLESS")
{ {
result = (val < 0); result = (val < 0);
@ -534,19 +549,8 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
{ {
result = (val == 0); result = (val == 0);
} }
if(result) HandleBinaryOp(result,
{ reducible, arg, newArgs, argP1, argP2);
*arg = "1";
}
else
{
*arg = "0";
}
newArgs.erase(argP2);
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
// is file A newer than file B // is file A newer than file B
@ -557,33 +561,32 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
bool success=cmSystemTools::FileTimeCompare(arg->c_str(), bool success=cmSystemTools::FileTimeCompare(arg->c_str(),
(argP2)->c_str(), (argP2)->c_str(),
&fileIsNewer); &fileIsNewer);
if(success==false || fileIsNewer==1 || fileIsNewer==0) HandleBinaryOp(
{ (success==false || fileIsNewer==1 || fileIsNewer==0),
*arg = "1"; reducible, arg, newArgs, argP1, argP2);
}
else
{
*arg = "0";
}
newArgs.erase(argP2);
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
++arg; ++arg;
} }
} }
while (reducible); while (reducible);
return true;
}
//=========================================================================
// now loop through the arguments and see if we can reduce any of them // level 3 handles NOT
// we do this multiple times. Once for each level of precedence bool HandleLevel3(std::list<std::string> &newArgs,
cmMakefile *makefile,
char **)
{
int reducible;
const char *def;
do do
{ {
reducible = 0; reducible = 0;
std::list<std::string>::iterator arg = newArgs.begin(); std::list<std::string>::iterator arg = newArgs.begin();
std::list<std::string>::iterator argP1;
std::list<std::string>::iterator argP2;
while (arg != newArgs.end()) while (arg != newArgs.end())
{ {
argP1 = arg; argP1 = arg;
@ -591,30 +594,31 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
if (argP1 != newArgs.end() && *arg == "NOT") if (argP1 != newArgs.end() && *arg == "NOT")
{ {
def = cmIfCommand::GetVariableOrNumber((argP1)->c_str(), makefile); def = cmIfCommand::GetVariableOrNumber((argP1)->c_str(), makefile);
if(!cmSystemTools::IsOff(def)) HandlePredicate(cmSystemTools::IsOff(def),
{ reducible, arg, newArgs, argP1, argP2);
*arg = "0";
}
else
{
*arg = "1";
}
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
++arg; ++arg;
} }
} }
while (reducible); while (reducible);
return true;
}
// 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 // level 4 handles AND OR
bool HandleLevel4(std::list<std::string> &newArgs,
cmMakefile *makefile,
char **)
{
int reducible;
const char *def;
const char *def2;
do do
{ {
reducible = 0; reducible = 0;
std::list<std::string>::iterator arg = newArgs.begin(); std::list<std::string>::iterator arg = newArgs.begin();
std::list<std::string>::iterator argP1;
std::list<std::string>::iterator argP2;
while (arg != newArgs.end()) while (arg != newArgs.end())
{ {
argP1 = arg; argP1 = arg;
@ -624,19 +628,9 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
{ {
def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile); def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile);
def2 = cmIfCommand::GetVariableOrNumber((argP2)->c_str(), makefile); def2 = cmIfCommand::GetVariableOrNumber((argP2)->c_str(), makefile);
if(cmSystemTools::IsOff(def) || cmSystemTools::IsOff(def2)) HandleBinaryOp(
{ !(cmSystemTools::IsOff(def) || cmSystemTools::IsOff(def2)),
*arg = "0"; reducible, arg, newArgs, argP1, argP2);
}
else
{
*arg = "1";
}
newArgs.erase(argP2);
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
} }
if (argP1 != newArgs.end() && *(argP1) == "OR" && if (argP1 != newArgs.end() && *(argP1) == "OR" &&
@ -644,25 +638,84 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
{ {
def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile); def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile);
def2 = cmIfCommand::GetVariableOrNumber((argP2)->c_str(), makefile); def2 = cmIfCommand::GetVariableOrNumber((argP2)->c_str(), makefile);
if(cmSystemTools::IsOff(def) && cmSystemTools::IsOff(def2)) HandleBinaryOp(
{ !(cmSystemTools::IsOff(def) && cmSystemTools::IsOff(def2)),
*arg = "0"; reducible, arg, newArgs, argP1, argP2);
} }
else
{
*arg = "1";
}
newArgs.erase(argP2);
newArgs.erase(argP1);
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
}
++arg; ++arg;
} }
} }
while (reducible); 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 // now at the end there should only be one argument left
if (newArgs.size() == 1) if (newArgs.size() == 1)
@ -687,6 +740,7 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
return true; return true;
} }
//=========================================================================
const char* cmIfCommand::GetVariableOrString(const char* str, const char* cmIfCommand::GetVariableOrString(const char* str,
const cmMakefile* mf) const cmMakefile* mf)
{ {
@ -698,6 +752,7 @@ const char* cmIfCommand::GetVariableOrString(const char* str,
return def; return def;
} }
//=========================================================================
const char* cmIfCommand::GetVariableOrNumber(const char* str, const char* cmIfCommand::GetVariableOrNumber(const char* str,
const cmMakefile* mf) const cmMakefile* mf)
{ {

View File

@ -242,12 +242,27 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
// Arguments. // Arguments.
unsigned long lastLine = cmListFileLexer_GetCurrentLine(lexer); unsigned long lastLine = cmListFileLexer_GetCurrentLine(lexer);
unsigned long parenDepth = 0;
while((token = cmListFileLexer_Scan(lexer))) while((token = cmListFileLexer_Scan(lexer)))
{ {
if(token->type == cmListFileLexer_Token_ParenRight) 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; return true;
} }
parenDepth--;
cmListFileArgument a(")",
false, filename, token->line);
function.Arguments.push_back(a);
}
else if(token->type == cmListFileLexer_Token_Identifier || else if(token->type == cmListFileLexer_Token_Identifier ||
token->type == cmListFileLexer_Token_ArgumentUnquoted) token->type == cmListFileLexer_Token_ArgumentUnquoted)
{ {

View File

@ -336,6 +336,12 @@ if (NOT ELSEIF_RESULT EQUAL 2)
set (ELSEIF_RESULT 0) set (ELSEIF_RESULT 0)
endif (NOT ELSEIF_RESULT EQUAL 2) endif (NOT ELSEIF_RESULT EQUAL 2)
# test handling of parenthetical groups in conditionals
if (2 GREATER 1 AND (4 LESS 3 OR 5 LESS 6) AND NOT (7 GREATER 8))
set(CONDITIONAL_PARENTHESES 1)
endif()
# #
# Configure file # Configure file
# (plug vars to #define so that they can be tested) # (plug vars to #define so that they can be tested)

View File

@ -369,6 +369,12 @@ int main()
cmFailed("ELSEIF did not work"); cmFailed("ELSEIF did not work");
#endif #endif
#ifdef CONDITIONAL_PARENTHESES
cmPassed("CONDITIONAL_PARENTHESES did work");
#else
cmFailed("CONDITIONAL_PARENTHESES did not work");
#endif
if(file2() != 1) if(file2() != 1)
{ {
cmFailed("Call to file2 function from library failed."); cmFailed("Call to file2 function from library failed.");

View File

@ -81,3 +81,7 @@
// test elseif // test elseif
#cmakedefine ELSEIF_RESULT #cmakedefine ELSEIF_RESULT
// test parenthesis in conditionals
#cmakedefine CONDITIONAL_PARENTHESES

View File

@ -336,6 +336,12 @@ if (NOT ELSEIF_RESULT EQUAL 2)
set (ELSEIF_RESULT 0) set (ELSEIF_RESULT 0)
endif (NOT ELSEIF_RESULT EQUAL 2) endif (NOT ELSEIF_RESULT EQUAL 2)
# test handling of parenthetical groups in conditionals
if (2 GREATER 1 AND (4 LESS 3 OR 5 LESS 6) AND NOT (7 GREATER 8))
set(CONDITIONAL_PARENTHESES 1)
endif()
# #
# Configure file # Configure file
# (plug vars to #define so that they can be tested) # (plug vars to #define so that they can be tested)

View File

@ -369,6 +369,12 @@ int main()
cmFailed("ELSEIF did not work"); cmFailed("ELSEIF did not work");
#endif #endif
#ifdef CONDITIONAL_PARENTHESES
cmPassed("CONDITIONAL_PARENTHESES did work");
#else
cmFailed("CONDITIONAL_PARENTHESES did not work");
#endif
if(file2() != 1) if(file2() != 1)
{ {
cmFailed("Call to file2 function from library failed."); cmFailed("Call to file2 function from library failed.");

View File

@ -81,3 +81,7 @@
// test elseif // test elseif
#cmakedefine ELSEIF_RESULT #cmakedefine ELSEIF_RESULT
// test parenthesis in conditionals
#cmakedefine CONDITIONAL_PARENTHESES

View File

@ -336,6 +336,12 @@ if (NOT ELSEIF_RESULT EQUAL 2)
set (ELSEIF_RESULT 0) set (ELSEIF_RESULT 0)
endif (NOT ELSEIF_RESULT EQUAL 2) endif (NOT ELSEIF_RESULT EQUAL 2)
# test handling of parenthetical groups in conditionals
if (2 GREATER 1 AND (4 LESS 3 OR 5 LESS 6) AND NOT (7 GREATER 8))
set(CONDITIONAL_PARENTHESES 1)
endif()
# #
# Configure file # Configure file
# (plug vars to #define so that they can be tested) # (plug vars to #define so that they can be tested)

View File

@ -369,6 +369,12 @@ int main()
cmFailed("ELSEIF did not work"); cmFailed("ELSEIF did not work");
#endif #endif
#ifdef CONDITIONAL_PARENTHESES
cmPassed("CONDITIONAL_PARENTHESES did work");
#else
cmFailed("CONDITIONAL_PARENTHESES did not work");
#endif
if(file2() != 1) if(file2() != 1)
{ {
cmFailed("Call to file2 function from library failed."); cmFailed("Call to file2 function from library failed.");

View File

@ -81,3 +81,7 @@
// test elseif // test elseif
#cmakedefine ELSEIF_RESULT #cmakedefine ELSEIF_RESULT
// test parenthesis in conditionals
#cmakedefine CONDITIONAL_PARENTHESES