From 10efe3b079caf5237e01d31b09f7947c77c7458f Mon Sep 17 00:00:00 2001 From: Ken Martin Date: Wed, 22 Mar 2006 14:06:52 -0500 Subject: ENH: added some new functionality --- Source/cmGetDirectoryPropertyCommand.h | 3 ++- Source/cmGetSourceFilePropertyCommand.cxx | 5 +++++ Source/cmGetSourceFilePropertyCommand.h | 2 +- Source/cmIfCommand.cxx | 28 +++++++++++++++++++++------ Source/cmIfCommand.h | 4 +++- Source/cmMakefile.cxx | 32 ++++++++++++++++++++++++++++++- Source/cmMakefile.h | 5 ++++- Source/cmSourceFile.cxx | 7 +++++++ 8 files changed, 75 insertions(+), 11 deletions(-) diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h index 6892221..b146488 100644 --- a/Source/cmGetDirectoryPropertyCommand.h +++ b/Source/cmGetDirectoryPropertyCommand.h @@ -62,7 +62,8 @@ public: "stored in the variable VAR. If the property is not found, " "CMake will report an error. The properties include: VARIABLES, " "CACHE_VARIABLES, COMMANDS, MACROS, INCLUDE_DIRECTORIES, " - "LINK_DIRECTORIES, DEFINITIONS, INCLUDE_REGULAR_EXPRESSION and " + "LINK_DIRECTORIES, DEFINITIONS, INCLUDE_REGULAR_EXPRESSION, " + "LISTFILE_STACK, PARENT_DIRECTORY, and " "DEFINITION varname. If the DIRECTORY argument is provided then " "the property of the provided directory will be retrieved " "instead of the current directory. You can only get properties " diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index 3c149a4..4d444bc 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -31,6 +31,11 @@ bool cmGetSourceFilePropertyCommand::InitialPass( const char* file = args[1].c_str(); cmSourceFile* sf = this->Makefile->GetSource(file); + // for the location we must create a source file first + if (!sf && args[2] == "LOCATION") + { + sf = this->Makefile->GetOrCreateSource(file); + } if(sf) { const char *prop = sf->GetProperty(args[2].c_str()); diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h index b720ab1..aefbe23 100644 --- a/Source/cmGetSourceFilePropertyCommand.h +++ b/Source/cmGetSourceFilePropertyCommand.h @@ -57,7 +57,7 @@ public: "stored in the variable VAR. If the property is not found, VAR " "will be set to \"NOTFOUND\". Use SET_SOURCE_FILES_PROPERTIES to set " "property values. Source file properties usually control how the " - "file is built."; + "file is built. One property that is always there is LOCATION"; } cmTypeMacro(cmGetSourceFilePropertyCommand, cmCommand); diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index c7b8d2a..bd608f8 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -156,17 +156,17 @@ namespace // order of operations, -// EXISTS COMMAND DEFINED +// 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 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. +// 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 &args, @@ -243,6 +243,22 @@ bool cmIfCommand::IsTrue(const std::vector &args, IncrementArguments(newArgs,argP1,argP2); reducible = 1; } + // does a file exist + if (*arg == "IS_DIRECTORY" && argP1 != newArgs.end()) + { + if(cmSystemTools::FileIsDirectory((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()) { diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index d9813be..fa1df27 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -121,9 +121,11 @@ public: " 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 that can be invoked.\n" + "True if the given name is a file or directory.\n" " IF(EXISTS file-name)\n" " IF(EXISTS directory-name)\n" + "True if the given name is a directory.\n" + " IF(IS_DIRECTORY directory-name)\n" "True if the named file or directory exists.\n" " IF(variable MATCHES regex)\n" " IF(string MATCHES regex)\n" diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 2c94ab6..08223cb 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -391,6 +391,9 @@ bool cmMakefile::ReadListFile(const char* filename_in, const char *external_in) } } + // push the listfile onto the stack + this->ListFileStack.push_back(filenametoread); + cmListFile cacheFile; if( !cacheFile.ParseFile(filenametoread, requireProjectCommand) ) { @@ -405,6 +408,8 @@ bool cmMakefile::ReadListFile(const char* filename_in, const char *external_in) this->ExecuteCommand(cacheFile.Functions[i]); if ( cmSystemTools::GetFatalErrorOccured() ) { + // pop the listfile off the stack + this->ListFileStack.pop_back(); this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentFile.c_str()); return true; } @@ -428,6 +433,10 @@ bool cmMakefile::ReadListFile(const char* filename_in, const char *external_in) } this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentFile.c_str()); + + // pop the listfile off the stack + this->ListFileStack.pop_back(); + return true; } @@ -2430,8 +2439,29 @@ void cmMakefile::SetProperty(const char* prop, const char* value) this->Properties[prop] = value; } -const char *cmMakefile::GetProperty(const char* prop) const +const char *cmMakefile::GetProperty(const char* prop) { + // watch for specific properties + if (!strcmp("PARENT_DIRECTORY",prop)) + { + return this->LocalGenerator->GetParent() + ->GetMakefile()->GetStartDirectory(); + } + // watch for specific properties + if (!strcmp("LISTFILE_STACK",prop)) + { + std::string tmp; + for (std::deque::iterator i = this->ListFileStack.begin(); + i != this->ListFileStack.end(); ++i) + { + if (i != this->ListFileStack.begin()) + { + tmp += ";"; + } + tmp += *i; + } + this->SetProperty("LISTFILE_STACK",tmp.c_str()); + } std::map::const_iterator i = this->Properties.find(prop); if (i != this->Properties.end()) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index f480c5a..0e00f92 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -661,7 +661,7 @@ public: ///! Set/Get a property of this directory void SetProperty(const char *prop, const char *value); - const char *GetProperty(const char *prop) const; + const char *GetProperty(const char *prop); bool GetPropertyAsBool(const char *prop) const; typedef std::map DefinitionMap; @@ -755,6 +755,9 @@ private: // should this makefile be processed before or after processing the parent bool PreOrder; + + // stack of list files being read + std::deque ListFileStack; }; diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index ac9f28b..303ff78 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -179,6 +179,13 @@ void cmSourceFile::SetProperty(const char* prop, const char* value) const char *cmSourceFile::GetProperty(const char* prop) const { + // watch for special "computed" properties that are dependent on other + // properties or variables, always recompute them + if (!strcmp(prop,"LOCATION")) + { + return this->FullPath.c_str(); + } + std::map::const_iterator i = this->Properties.find(prop); if (i != this->Properties.end()) -- cgit v0.12