Browse Source

ENH: add functions and raise scope

Ken Martin 18 years ago
parent
commit
f4b1c3880b
6 changed files with 75 additions and 21 deletions
  1. 8 0
      Source/cmBootstrapCommands.cxx
  2. 0 2
      Source/cmCommands.cxx
  3. 58 17
      Source/cmMakefile.cxx
  4. 6 1
      Source/cmMakefile.h
  5. 2 1
      Source/cmake.cxx
  6. 1 0
      Tests/CMakeLists.txt

+ 8 - 0
Source/cmBootstrapCommands.cxx

@@ -36,7 +36,9 @@
 #include "cmElseCommand.cxx"
 #include "cmEnableTestingCommand.cxx"
 #include "cmEndForEachCommand.cxx"
+#include "cmEndFunctionCommand.cxx"
 #include "cmEndIfCommand.cxx"
+#include "cmEndMacroCommand.cxx"
 #include "cmExecProgramCommand.cxx"
 #include "cmExternalMakefileProjectGenerator.cxx"
 #include "cmFindBase.cxx"
@@ -47,6 +49,7 @@
 #include "cmFindPathCommand.cxx"
 #include "cmFindProgramCommand.cxx"
 #include "cmForEachCommand.cxx"
+#include "cmFunctionCommand.cxx"
 #include "cmGetCMakePropertyCommand.cxx"
 #include "cmGetFilenameComponentCommand.cxx"
 #include "cmGetSourceFilePropertyCommand.cxx"
@@ -66,6 +69,7 @@
 #include "cmMessageCommand.cxx"
 #include "cmOptionCommand.cxx"
 #include "cmProjectCommand.cxx"
+#include "cmRaiseScopeCommand.cxx"
 #include "cmSetCommand.cxx"
 #include "cmSetPropertiesCommand.cxx"
 #include "cmSetSourceFilesPropertiesCommand.cxx"
@@ -95,7 +99,9 @@ void GetBootstrapCommands(std::list<cmCommand*>& commands)
   commands.push_back(new cmElseCommand);
   commands.push_back(new cmEnableTestingCommand);  
   commands.push_back(new cmEndForEachCommand);
+  commands.push_back(new cmEndFunctionCommand);
   commands.push_back(new cmEndIfCommand);
+  commands.push_back(new cmEndMacroCommand);
   commands.push_back(new cmExecProgramCommand);
   commands.push_back(new cmFileCommand);
   commands.push_back(new cmFindFileCommand);
@@ -104,6 +110,7 @@ void GetBootstrapCommands(std::list<cmCommand*>& commands)
   commands.push_back(new cmFindPathCommand);
   commands.push_back(new cmFindProgramCommand);
   commands.push_back(new cmForEachCommand);
+  commands.push_back(new cmFunctionCommand);
   commands.push_back(new cmGetCMakePropertyCommand);
   commands.push_back(new cmGetFilenameComponentCommand);
   commands.push_back(new cmGetSourceFilePropertyCommand);
@@ -122,6 +129,7 @@ void GetBootstrapCommands(std::list<cmCommand*>& commands)
   commands.push_back(new cmMessageCommand);
   commands.push_back(new cmOptionCommand);
   commands.push_back(new cmProjectCommand);
+  commands.push_back(new cmRaiseScopeCommand);
   commands.push_back(new cmSetCommand);
   commands.push_back(new cmSetPropertiesCommand);
   commands.push_back(new cmSetSourceFilesPropertiesCommand);

+ 0 - 2
Source/cmCommands.cxx

@@ -21,7 +21,6 @@
 #include "cmDefinePropertyCommand.cxx"
 #include "cmElseIfCommand.cxx"
 #include "cmEnableLanguageCommand.cxx"
-#include "cmEndMacroCommand.cxx"
 #include "cmEndWhileCommand.cxx"
 #include "cmExecuteProcessCommand.cxx"
 #include "cmExportCommand.cxx"
@@ -72,7 +71,6 @@ void GetPredefinedCommands(std::list<cmCommand*>&
   commands.push_back(new cmDefinePropertyCommand);
   commands.push_back(new cmElseIfCommand);
   commands.push_back(new cmEnableLanguageCommand);
-  commands.push_back(new cmEndMacroCommand);
   commands.push_back(new cmEndWhileCommand);
   commands.push_back(new cmExecuteProcessCommand);
   commands.push_back(new cmExportCommand);

+ 58 - 17
Source/cmMakefile.cxx

@@ -42,6 +42,8 @@
 // default is not to be building executables
 cmMakefile::cmMakefile()
 {
+  this->DefinitionStack.push_back(DefinitionMap());
+
   // Setup the default include file regular expression (match everything).
   this->IncludeFileRegularExpression = "^.*$";
   // Setup the default include complaint regular expression (match nothing).
@@ -120,7 +122,7 @@ cmMakefile::cmMakefile(const cmMakefile& mf)
   this->SourceGroups = mf.SourceGroups;
 #endif
 
-  this->Definitions = mf.Definitions;
+  this->DefinitionStack.push_back(mf.DefinitionStack.back());
   this->LocalGenerator = mf.LocalGenerator;
   this->FunctionBlockers = mf.FunctionBlockers;
   this->DataMap = mf.DataMap;
@@ -1046,7 +1048,7 @@ void cmMakefile::InitializeFromParent()
   cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
 
   // copy the definitions
-  this->Definitions = parent->Definitions;
+  this->DefinitionStack.front() = parent->DefinitionStack.back();
 
   // copy include paths
   this->IncludeDirectories = parent->IncludeDirectories;
@@ -1225,7 +1227,7 @@ void cmMakefile::AddDefinition(const char* name, const char* value)
 #endif
 
   this->TemporaryDefinitionKey = name;
-  this->Definitions[this->TemporaryDefinitionKey] = value;
+  this->DefinitionStack.back()[this->TemporaryDefinitionKey] = value;
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
   cmVariableWatch* vv = this->GetVariableWatch();
@@ -1274,7 +1276,7 @@ void cmMakefile::AddCacheDefinition(const char* name, const char* value,
     }
   this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
   // if there was a definition then remove it
-  this->Definitions.erase( DefinitionMap::key_type(name));
+  this->DefinitionStack.back().erase( DefinitionMap::key_type(name));
 }
 
 
@@ -1282,13 +1284,17 @@ void cmMakefile::AddDefinition(const char* name, bool value)
 {
   if(value)
     {
-    this->Definitions.erase( DefinitionMap::key_type(name));
-    this->Definitions.insert(DefinitionMap::value_type(name, "ON"));
+    this->DefinitionStack.back()
+      .erase( DefinitionMap::key_type(name));
+    this->DefinitionStack.back()
+      .insert(DefinitionMap::value_type(name, "ON"));
     }
   else
     {
-    this->Definitions.erase( DefinitionMap::key_type(name));
-    this->Definitions.insert(DefinitionMap::value_type(name, "OFF"));
+    this->DefinitionStack.back()
+      .erase( DefinitionMap::key_type(name));
+    this->DefinitionStack.back()
+      .insert(DefinitionMap::value_type(name, "OFF"));
     }
 #ifdef CMAKE_BUILD_WITH_CMAKE
   cmVariableWatch* vv = this->GetVariableWatch();
@@ -1319,7 +1325,7 @@ void cmMakefile::AddCacheDefinition(const char* name,
 
 void cmMakefile::RemoveDefinition(const char* name)
 {
-  this->Definitions.erase(DefinitionMap::key_type(name));
+  this->DefinitionStack.back().erase(DefinitionMap::key_type(name));
 #ifdef CMAKE_BUILD_WITH_CMAKE
   cmVariableWatch* vv = this->GetVariableWatch();
   if ( vv )
@@ -1653,8 +1659,9 @@ const char* cmMakefile::GetRequiredDefinition(const char* name) const
 bool cmMakefile::IsDefinitionSet(const char* name) const
 {
   const char* def = 0;
-  DefinitionMap::const_iterator pos = this->Definitions.find(name);
-  if(pos != this->Definitions.end())
+  DefinitionMap::const_iterator pos = 
+    this->DefinitionStack.back().find(name);
+  if(pos != this->DefinitionStack.back().end())
     {
     def = (*pos).second.c_str();
     }
@@ -1686,8 +1693,9 @@ const char* cmMakefile::GetDefinition(const char* name) const
     }
 #endif
   const char* def = 0;
-  DefinitionMap::const_iterator pos = this->Definitions.find(name);
-  if(pos != this->Definitions.end())
+  DefinitionMap::const_iterator pos = 
+    this->DefinitionStack.back().find(name);
+  if(pos != this->DefinitionStack.back().end())
     {
     def = (*pos).second.c_str();
     }
@@ -1708,8 +1716,9 @@ const char* cmMakefile::GetDefinition(const char* name) const
       {
       // are unknown access allowed
       DefinitionMap::const_iterator pos2 =
-        this->Definitions.find("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
-      if (pos2 != this->Definitions.end() &&
+        this->DefinitionStack.back()
+        .find("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
+      if (pos2 != this->DefinitionStack.back().end() &&
           cmSystemTools::IsOn((*pos2).second.c_str()))
         {
         vv->VariableAccessed(name,
@@ -1743,8 +1752,8 @@ std::vector<std::string> cmMakefile
   if ( !cacheonly )
     {
     DefinitionMap::const_iterator it;
-    for ( it = this->Definitions.begin();
-          it != this->Definitions.end(); it ++ )
+    for ( it = this->DefinitionStack.back().begin();
+          it != this->DefinitionStack.back().end(); it ++ )
       {
       definitions[it->first] = 1;
       }
@@ -2822,6 +2831,38 @@ std::string cmMakefile::GetListFileStack()
   return tmp.str();
 }
 
+
+void cmMakefile::PushScope()
+{
+  this->DefinitionStack.push_back(this->DefinitionStack.back());
+}
+
+void cmMakefile::PopScope()
+{
+  this->DefinitionStack.pop_back();
+}
+
+void cmMakefile::RaiseScope(const char *var)
+{
+  const char *varDef = this->GetDefinition(var);
+
+  // multiple scopes in this directory?
+  if (this->DefinitionStack.size() > 1)
+    {
+    this->DefinitionStack[this->DefinitionStack.size()-2][var] = varDef;
+    }
+  // otherwise do the parent
+  else
+    {
+    cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
+    if (parent)
+      {
+      parent->AddDefinition(var,varDef);
+      }
+    }
+}
+
+
 // define properties
 void cmMakefile::DefineProperties(cmake *cm)
 {

+ 6 - 1
Source/cmMakefile.h

@@ -737,6 +737,11 @@ public:
   // Define the properties
   static void DefineProperties(cmake *cm);
 
+  // push and pop variable scopes
+  void PushScope();
+  void PopScope();
+  void RaiseScope(const char *var);
+
 protected:
   // add link libraries and directories to the target
   void AddGlobalLinkInformation(const char* name, cmTarget& target);
@@ -787,7 +792,7 @@ protected:
   std::vector<cmSourceGroup> SourceGroups;
 #endif
 
-  DefinitionMap Definitions;
+  std::vector<DefinitionMap> DefinitionStack;
   std::vector<cmCommand*> UsedCommands;
   cmLocalGenerator* LocalGenerator;
   bool IsFunctionBlocked(const cmListFileFunction& lff);

+ 2 - 1
Source/cmake.cxx

@@ -224,7 +224,8 @@ void cmake::CleanupCommandsAndMacros()
   for(RegisteredCommandsMap::iterator j = this->Commands.begin();
       j != this->Commands.end(); ++j)
     {
-    if ( !j->second->IsA("cmMacroHelperCommand") )
+    if ( !j->second->IsA("cmMacroHelperCommand") && 
+         !j->second->IsA("cmFunctionHelperCommand"))
       {
       commands.push_back(j->second);
       }

+ 1 - 0
Tests/CMakeLists.txt

@@ -45,6 +45,7 @@ IF(BUILD_TESTING)
   ADD_TEST_MACRO(LoadCommand LoadedCommand)
   ADD_TEST_MACRO(LinkLine LinkLine)
   ADD_TEST_MACRO(MacroTest miniMacroTest)
+  ADD_TEST_MACRO(FunctionTest miniFunctionTest)
   ADD_TEST_MACRO(Properties Properties)
   ADD_TEST_MACRO(Assembler HelloAsm)
   ADD_TEST_MACRO(SourceGroups SourceGroups)