Răsfoiți Sursa

ENH: added some new functionality

Ken Martin 19 ani în urmă
părinte
comite
10efe3b079

+ 2 - 1
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 "

+ 5 - 0
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());

+ 1 - 1
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);

+ 22 - 6
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<std::string> &args,
@@ -243,6 +243,22 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &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())
         {

+ 3 - 1
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"

+ 31 - 1
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<cmStdString>::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<cmStdString,cmStdString>::const_iterator i = 
     this->Properties.find(prop);
   if (i != this->Properties.end())

+ 4 - 1
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<cmStdString, cmStdString> 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<cmStdString> ListFileStack;
 };
 
 

+ 7 - 0
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<cmStdString,cmStdString>::const_iterator i = 
     this->Properties.find(prop);
   if (i != this->Properties.end())