diff options
author | Ken Martin <ken.martin@kitware.com> | 2004-05-01 14:08:14 (GMT) |
---|---|---|
committer | Ken Martin <ken.martin@kitware.com> | 2004-05-01 14:08:14 (GMT) |
commit | 50db27739c1203c82fb290ee7e42726eebb6ccce (patch) | |
tree | 7475a3e3c4fd141234f4c14783b7e75cdcde3d04 /Source/cmIfCommand.cxx | |
parent | 7965cfb3395a72ef8712fe22e575b7c788e81d53 (diff) | |
download | CMake-50db27739c1203c82fb290ee7e42726eebb6ccce.zip CMake-50db27739c1203c82fb290ee7e42726eebb6ccce.tar.gz CMake-50db27739c1203c82fb290ee7e42726eebb6ccce.tar.bz2 |
better if expression support
Diffstat (limited to 'Source/cmIfCommand.cxx')
-rw-r--r-- | Source/cmIfCommand.cxx | 392 |
1 files changed, 273 insertions, 119 deletions
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 1d9bbf9..c094cdd 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -16,7 +16,7 @@ =========================================================================*/ #include "cmIfCommand.h" #include <stdlib.h> // required for atof - +#include <deque> #include <cmsys/RegularExpression.hxx> bool cmIfFunctionBlocker:: @@ -131,167 +131,307 @@ bool cmIfCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args) return true; } +// order of operations, +// EXISTS COMMAND DEFINED +// MATCHES LESS GREATER EQUAL STRLESS STRGREATER +// 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 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, bool &isValid, const cmMakefile *makefile) { // check for the different signatures - bool isTrue = true; isValid = false; const char *def; const char *def2; + + // store the reduced args in this vector + std::deque<std::string> newArgs; + int reducible = 1; + unsigned int i; - if(args.size() < 1 ) - { - isValid = true; - return false; + // copy to the list structure + for(i = 0; i < args.size(); ++i) + { + newArgs.push_back(args[i]); } - - if (args.size() == 1) + + // 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 { - def = makefile->GetDefinition(args[0].c_str()); - if(cmSystemTools::IsOff(def)) + reducible = 0; + std::deque<std::string>::iterator arg = newArgs.begin(); + while (arg != newArgs.end()) { - isTrue = false; + // does a file exist + if (*arg == "EXISTS" && arg + 1 != newArgs.end()) + { + if(cmSystemTools::FileExists((arg + 1)->c_str())) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + newArgs.erase(arg+1); + reducible = 1; + } + // does a command exist + if (*arg == "COMMAND" && arg + 1 != newArgs.end()) + { + if(makefile->CommandExists((arg + 1)->c_str())) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + newArgs.erase(arg+1); + reducible = 1; + } + // is a variable defined + if (*arg == "DEFINED" && arg + 1 != newArgs.end()) + { + def = makefile->GetDefinition((arg + 1)->c_str()); + if(def) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + newArgs.erase(arg+1); + reducible = 1; + } + ++arg; } - isValid = true; } - - if (args.size() == 2 && (args[0] == "NOT")) + 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 { - def = makefile->GetDefinition(args[1].c_str()); - if(!cmSystemTools::IsOff(def)) + reducible = 0; + std::deque<std::string>::iterator arg = newArgs.begin(); + while (arg != newArgs.end()) { - isTrue = false; - } - isValid = true; + if (arg + 1 != newArgs.end() && arg + 2 != newArgs.end() && + *(arg + 1) == "MATCHES") + { + def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile); + cmsys::RegularExpression regEntry((arg+2)->c_str()); + if (regEntry.find(def)) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + newArgs.erase(arg+2); + newArgs.erase(arg+1); + reducible = 1; + } - } + if (arg + 1 != newArgs.end() && *arg == "MATCHES") + { + *arg = "0"; + newArgs.erase(arg+1); + reducible = 1; + } - if (args.size() == 2 && (args[0] == "COMMAND")) - { - if(!makefile->CommandExists(args[1].c_str())) - { - isTrue = false; - } - isValid = true; - } + if (arg + 1 != newArgs.end() && arg + 2 != newArgs.end() && + (*(arg + 1) == "LESS" || *(arg + 1) == "GREATER" || + *(arg + 1) == "EQUAL")) + { + def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile); + def2 = cmIfCommand::GetVariableOrString((arg + 2)->c_str(), makefile); + if (*(arg + 1) == "LESS") + { + if(atof(def) < atof(def2)) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + } + else if (*(arg + 1) == "GREATER") + { + if(atof(def) > atof(def2)) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + } + else + { + if(atof(def) == atof(def2)) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + } + newArgs.erase(arg+2); + newArgs.erase(arg+1); + reducible = 1; + } - if (args.size() == 2 && (args[0] == "EXISTS")) - { - if(!cmSystemTools::FileExists(args[1].c_str())) - { - isTrue = false; - } - isValid = true; - } + if (arg + 1 != newArgs.end() && arg + 2 != newArgs.end() && + (*(arg + 1) == "STRLESS" || *(arg + 1) == "STRGREATER")) + { + def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile); + def2 = cmIfCommand::GetVariableOrString((arg + 2)->c_str(), makefile); + if (*(arg + 1) == "STRLESS") + { + if(strcmp(def,def2) < 0) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + } + else + { + if(strcmp(def,def2) > 0) + { + *arg = "1"; + } + else + { + *arg = "0"; + } + } + newArgs.erase(arg+2); + newArgs.erase(arg+1); + reducible = 1; + } - if (args.size() == 2 && (args[0] == "MATCHES")) - { - if(!cmSystemTools::FileExists(args[1].c_str())) - { - isTrue = false; + ++arg; } - isValid = true; } + while (reducible); - if (args.size() == 3 && (args[1] == "AND")) + + // 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 { - def = makefile->GetDefinition(args[0].c_str()); - def2 = makefile->GetDefinition(args[2].c_str()); - if(cmSystemTools::IsOff(def) || cmSystemTools::IsOff(def2)) + reducible = 0; + std::deque<std::string>::iterator arg = newArgs.begin(); + while (arg != newArgs.end()) { - isTrue = false; + if (arg + 1 != newArgs.end() && *arg == "NOT") + { + def = cmIfCommand::GetVariableOrNumber((arg + 1)->c_str(), makefile); + if(!cmSystemTools::IsOff(def)) + { + *arg = "0"; + } + else + { + *arg = "1"; + } + newArgs.erase(arg+1); + reducible = 1; + } + ++arg; } - isValid = true; } + while (reducible); - if (args.size() == 3 && (args[1] == "OR")) + // 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 { - def = makefile->GetDefinition(args[0].c_str()); - def2 = makefile->GetDefinition(args[2].c_str()); - if(cmSystemTools::IsOff(def) && cmSystemTools::IsOff(def2)) + reducible = 0; + std::deque<std::string>::iterator arg = newArgs.begin(); + while (arg != newArgs.end()) { - isTrue = false; - } - isValid = true; - } + if (arg + 1 != newArgs.end() && *(arg + 1) == "AND" && + arg + 2 != newArgs.end()) + { + def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile); + def2 = cmIfCommand::GetVariableOrNumber((arg + 2)->c_str(), makefile); + if(cmSystemTools::IsOff(def) || cmSystemTools::IsOff(def2)) + { + *arg = "0"; + } + else + { + *arg = "1"; + } + newArgs.erase(arg+2); + newArgs.erase(arg+1); + reducible = 1; + } - if (args.size() == 3 && (args[1] == "MATCHES")) - { - def = cmIfCommand::GetVariableOrString(args[0].c_str(), makefile); - cmsys::RegularExpression regEntry(args[2].c_str()); - - // check for black line or comment - if (!regEntry.find(def)) - { - isTrue = false; - } - isValid = true; - } + if (arg + 1 != newArgs.end() && *(arg + 1) == "OR" && + arg + 2 != newArgs.end()) + { + def = cmIfCommand::GetVariableOrNumber(arg->c_str(), makefile); + def2 = cmIfCommand::GetVariableOrNumber((arg + 2)->c_str(), makefile); + if(cmSystemTools::IsOff(def) && cmSystemTools::IsOff(def2)) + { + *arg = "0"; + } + else + { + *arg = "1"; + } + newArgs.erase(arg+2); + newArgs.erase(arg+1); + reducible = 1; + } - if (args.size() == 3 && (args[1] == "LESS")) - { - def = cmIfCommand::GetVariableOrString(args[0].c_str(), makefile); - def2 = cmIfCommand::GetVariableOrString(args[2].c_str(), makefile); - if (!def) - { - def = args[0].c_str(); - } - if (!def2) - { - def2 = args[2].c_str(); - } - if(atof(def) >= atof(def2)) - { - isTrue = false; + ++arg; } - isValid = true; } + while (reducible); - if (args.size() == 3 && (args[1] == "GREATER")) + // now at the end there should only be one argument left + if (newArgs.size() == 1) { - def = cmIfCommand::GetVariableOrString(args[0].c_str(), makefile); - def2 = cmIfCommand::GetVariableOrString(args[2].c_str(), makefile); - if(atof(def) <= atof(def2)) - { - isTrue = false; - } isValid = true; - } - - if (args.size() == 3 && (args[1] == "EQUAL")) - { - def = cmIfCommand::GetVariableOrString(args[0].c_str(), makefile); - def2 = cmIfCommand::GetVariableOrString(args[2].c_str(), makefile); - if(atof(def) != atof(def2)) + if (newArgs[0] == "0") { - isTrue = false; + return false; } - isValid = true; - } - - if (args.size() == 3 && (args[1] == "STRLESS")) - { - def = cmIfCommand::GetVariableOrString(args[0].c_str(), makefile); - def2 = cmIfCommand::GetVariableOrString(args[2].c_str(), makefile); - if(strcmp(def,def2) >= 0) + if (newArgs[0] == "1") { - isTrue = false; + return true; } - isValid = true; - } - - if (args.size() == 3 && (args[1] == "STRGREATER")) - { - def = cmIfCommand::GetVariableOrString(args[0].c_str(), makefile); - def2 = cmIfCommand::GetVariableOrString(args[2].c_str(), makefile); - if(strcmp(def,def2) <= 0) + def = makefile->GetDefinition(args[0].c_str()); + if(cmSystemTools::IsOff(def)) { - isTrue = false; + return false; } - isValid = true; } - return isTrue; + + return true; } const char* cmIfCommand::GetVariableOrString(const char* str, @@ -304,3 +444,17 @@ const char* cmIfCommand::GetVariableOrString(const char* str, } return def; } + +const char* cmIfCommand::GetVariableOrNumber(const char* str, + const cmMakefile* mf) +{ + const char* def = mf->GetDefinition(str); + if(!def) + { + if (atoi(str)) + { + def = str; + } + } + return def; +} |