diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 358442d85..f7bac8bb5 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -20,6 +20,7 @@ cmGlobalGenerator.cxx cmGlobalUnixMakefileGenerator.cxx cmLocalGenerator.cxx cmLocalUnixMakefileGenerator.cxx +cmVariableWatch.cxx cmake.h cmakewizard.h cmMakeDepend.h @@ -39,6 +40,7 @@ cmGlobalGenerator.h cmGlobalUnixMakefileGenerator.h cmLocalGenerator.h cmLocalUnixMakefileGenerator.h +cmVariableWatch.h ) # configure the .h file diff --git a/Source/Makefile.in b/Source/Makefile.in index 8b069e918..1d8bd9afb 100644 --- a/Source/Makefile.in +++ b/Source/Makefile.in @@ -32,6 +32,7 @@ cmTarget.o \ cmCustomCommand.o \ cmCacheManager.o \ cmListFileCache.o \ +cmVariableWatch.o \ cmSourceGroup.o DEPENDS = cmConfigure.h @CMAKE_ROOT_DIR@/Source/*.h @@ -56,6 +57,7 @@ cmCommands.o : $(DEPENDS) $(srcdir)/*Command*.cxx cmTarget.o : $(DEPENDS) cmCacheManager.o : $(DEPENDS) cmSourceGroup.o : $(DEPENDS) +cmVariableWatch.o : $(DEPENDS) cmake: ${OBJS} diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 8c44fb88d..c26d5ab12 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -26,6 +26,7 @@ #include "cmCacheManager.h" #include "cmFunctionBlocker.h" #include "cmListFileCache.h" +#include "cmVariableWatch.h" #include "cmake.h" #include // required for sprintf @@ -558,6 +559,11 @@ void cmMakefile::AddDefinition(const char* name, const char* value) } m_Definitions.erase( DefinitionMap::key_type(name)); m_Definitions.insert(DefinitionMap::value_type(name, value)); + cmVariableWatch* vv = this->GetVariableWatch(); + if ( vv ) + { + vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS); + } } @@ -582,6 +588,11 @@ void cmMakefile::AddDefinition(const char* name, bool value) m_Definitions.erase( DefinitionMap::key_type(name)); m_Definitions.insert(DefinitionMap::value_type(name, "OFF")); } + cmVariableWatch* vv = this->GetVariableWatch(); + if ( vv ) + { + vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS); + } } @@ -594,6 +605,11 @@ void cmMakefile::AddCacheDefinition(const char* name, bool value, const char* do void cmMakefile::RemoveDefinition(const char* name) { m_Definitions.erase(DefinitionMap::key_type(name)); + cmVariableWatch* vv = this->GetVariableWatch(); + if ( vv ) + { + vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS); + } } void cmMakefile::SetProjectName(const char* p) @@ -860,7 +876,7 @@ std::string cmMakefile::GetParentListFileName(const char *currentFileName) void cmMakefile::ExpandVariables() { - // Now expand varibles in the include and link strings + // Now expand variables in the include and link strings for(std::vector::iterator d = m_IncludeDirectories.begin(); d != m_IncludeDirectories.end(); ++d) { @@ -886,12 +902,29 @@ bool cmMakefile::IsOn(const char* name) const const char* cmMakefile::GetDefinition(const char* name) const { + const char* def = 0; DefinitionMap::const_iterator pos = m_Definitions.find(name); if(pos != m_Definitions.end()) { - return (*pos).second.c_str(); + def = (*pos).second.c_str(); } - return this->GetCacheManager()->GetCacheValue(name); + else + { + def = this->GetCacheManager()->GetCacheValue(name); + } + cmVariableWatch* vv = this->GetVariableWatch(); + if ( vv ) + { + if ( def ) + { + vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS); + } + else + { + vv->VariableAccessed(name, cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS); + } + } + return def; } @@ -1430,6 +1463,25 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir, return ret; } +cmake *cmMakefile::GetCMakeInstance() const +{ + if ( m_LocalGenerator && m_LocalGenerator->GetGlobalGenerator() ) + { + return m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance(); + } + return 0; +} + +cmVariableWatch *cmMakefile::GetVariableWatch() const +{ + if ( this->GetCMakeInstance() && + this->GetCMakeInstance()->GetVariableWatch() ) + { + return this->GetCMakeInstance()->GetVariableWatch(); + } + return 0; +} + cmCacheManager *cmMakefile::GetCacheManager() const { return m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance()->GetCacheManager(); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 399b2ac11..558066b99 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -30,6 +30,7 @@ class cmCommand; class cmLocalGenerator; class cmMakeDepend; class cmSourceFile; +class cmVariableWatch; /** \class cmMakefile * \brief Process the input CMakeLists.txt file. @@ -531,6 +532,8 @@ public: * given a current CMakeLists file name */ cmCacheManager *GetCacheManager() const; + cmake *GetCMakeInstance() const; + cmVariableWatch* GetVariableWatch() const; //! Determine wether this is a local or global build. bool GetLocal() const; diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx new file mode 100644 index 000000000..74548fbfe --- /dev/null +++ b/Source/cmVariableWatch.cxx @@ -0,0 +1,59 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmVariableWatch.h" + +cmVariableWatch::cmVariableWatch() +{ +} + +cmVariableWatch::~cmVariableWatch() +{ +} + +void cmVariableWatch::AddWatch(const std::string& variable, + WatchMethod method, void* client_data /*=0*/) +{ + cmVariableWatch::Pair p; + p.m_Method = method; + p.m_ClientData = client_data; + cmVariableWatch::VectorOfPairs* vp = &m_WatchMap[variable]; + cmVariableWatch::VectorOfPairs::size_type cc; + for ( cc = 0; cc < vp->size(); cc ++ ) + { + cmVariableWatch::Pair* pair = &(*vp)[cc]; + if ( pair->m_Method == method ) + { + (*vp)[cc] = p; + return; + } + } + vp->push_back(p); +} + +void cmVariableWatch::VariableAccessed(const std::string& variable, int access_type) const +{ + cmVariableWatch::StringToVectorOfPairs::const_iterator mit = m_WatchMap.find(variable); + if ( mit != m_WatchMap.end() ) + { + const cmVariableWatch::VectorOfPairs* vp = &mit->second; + cmVariableWatch::VectorOfPairs::const_iterator it; + for ( it = vp->begin(); it != vp->end(); it ++ ) + { + it->m_Method(variable, access_type, it->m_ClientData); + } + } +} diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h new file mode 100644 index 000000000..88fdd5404 --- /dev/null +++ b/Source/cmVariableWatch.h @@ -0,0 +1,72 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmVariableWatch_h +#define cmVariableWatch_h + +#include "cmStandardIncludes.h" + +/** \class cmVariableWatch + * \brief Helper class for watching of variable accesses. + * + * Calls function when variable is accessed + */ +class cmVariableWatch +{ +public: + typedef void (WatchMethod)(const std::string& variable, int access_type, void* client_data); + + cmVariableWatch(); + ~cmVariableWatch(); + + /** + * Add watch to the variable + */ + void AddWatch(const std::string& variable, WatchMethod method, void* client_data=0); + + /** + * This method is called when variable is accessed + */ + void VariableAccessed(const std::string& variable, int access_type) const; + + /** + * Different access types. + */ + enum + { + VARIABLE_READ_ACCESS, + UNKNOWN_VARIABLE_READ_ACCESS, + VARIABLE_MODIFIED_ACCESS, + VARIABLE_REMOVED_ACCESS, + NO_ACCESS + }; + +protected: + struct Pair + { + WatchMethod* m_Method; + void* m_ClientData; + Pair() : m_Method(0), m_ClientData(0) {} + }; + + typedef std::vector< Pair > VectorOfPairs; + typedef std::map StringToVectorOfPairs; + + StringToVectorOfPairs m_WatchMap; +}; + + +#endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 5a4fa1f6c..e6b1fe609 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -21,6 +21,7 @@ #include "cmLocalGenerator.h" #include "cmCommands.h" #include "cmCommand.h" +#include "cmVariableWatch.h" // include the generator #if defined(_WIN32) && !defined(__CYGWIN__) @@ -62,6 +63,7 @@ cmake::cmake() m_GlobalGenerator = 0; m_ProgressCallback = 0; m_ProgressCallbackClientData = 0; + m_VariableWatch = new cmVariableWatch; this->AddDefaultCommands(); } @@ -79,6 +81,7 @@ cmake::~cmake() { delete (*j).second; } + delete m_VariableWatch; } bool cmake::CommandExists(const char* name) const diff --git a/Source/cmake.h b/Source/cmake.h index 602f15276..d6ecbe53f 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -45,6 +45,7 @@ class cmLocalGenerator; class cmCacheManager; class cmMakefile; class cmCommand; +class cmVariableWatch; class cmake { @@ -227,6 +228,10 @@ class cmake ///! this is called by generators to update the progress void UpdateProgress(const char *msg, float prog); + + ///! Get the variable watch object + cmVariableWatch* GetVariableWatch() { return m_VariableWatch; } + protected: typedef std::map RegisteredCommandsMap; RegisteredCommandsMap m_Commands; @@ -252,6 +257,8 @@ protected: */ int AddCMakePaths(const char *arg0); + cmVariableWatch* m_VariableWatch; + private: ProgressCallback m_ProgressCallback; void* m_ProgressCallbackClientData;