This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake".
The branch, next has been updated via 1102fd70366672c8e0f3842f095bebda5ccbc8e9 (commit) via 98048bd728af60b73d398350da50c8d6087b218a (commit) from c82487f42eb97fcf0d0ed517f7724c8bc58cb082 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1102fd70366672c8e0f3842f095bebda5ccbc8e9 commit 1102fd70366672c8e0f3842f095bebda5ccbc8e9 Merge: c82487f 98048bd Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Tue Apr 28 18:17:19 2015 -0400 Commit: CMake Topic Stage <kwro...@kitware.com> CommitDate: Tue Apr 28 18:17:19 2015 -0400 Merge topic 'refactor-cmDefinitions' into next 98048bd7 Revert topic. diff --cc Source/cmMakefile.cxx index 1853754,c77a90c..0935383 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@@ -51,150 -53,15 +53,32 @@@ public }; // default is not to be building executables -cmMakefile::cmMakefile(): Internal(new Internals) +cmMakefile::cmMakefile(cmLocalGenerator* localGenerator) + : Internal(new Internals), + LocalGenerator(localGenerator), + StateSnapshot(localGenerator->GetGlobalGenerator() + ->GetCMakeInstance()->GetState()) { - this->Internal->PushDefinitions(); - this->Internal->VarInitStack.push(std::set<std::string>()); - this->Internal->VarUsageStack.push(std::set<std::string>()); + const cmDefinitions& defs = cmDefinitions(); + const std::set<std::string> globalKeys = defs.LocalKeys(); + this->Internal->VarStack.push(defs); + this->Internal->VarInitStack.push(globalKeys); + this->Internal->VarUsageStack.push(globalKeys); this->Internal->IsSourceFileTryCompile = false; + if (this->LocalGenerator->GetParent()) + { + cmMakefile* parentMf = this->LocalGenerator->GetParent()->GetMakefile(); + this->StateSnapshot = + this->GetState()->CreateSnapshot(parentMf->StateSnapshot); + } + else + { + this->StateSnapshot = + this->GetState()->CreateSnapshot(this->StateSnapshot); + } + + // Initialize these first since AddDefaultDefinitions calls AddDefinition this->WarnUnused = false; this->CheckSystemVars = false; http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=98048bd728af60b73d398350da50c8d6087b218a commit 98048bd728af60b73d398350da50c8d6087b218a Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Wed Apr 29 00:16:20 2015 +0200 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Wed Apr 29 00:16:29 2015 +0200 Revert topic. diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx index bf517e3..fe32dd5 100644 --- a/Source/cmDefinitions.cxx +++ b/Source/cmDefinitions.cxx @@ -11,105 +11,160 @@ ============================================================================*/ #include "cmDefinitions.h" -#include <assert.h> +//---------------------------------------------------------------------------- +cmDefinitions::Def cmDefinitions::NoDef; + +//---------------------------------------------------------------------------- +cmDefinitions::cmDefinitions(cmDefinitions* parent) + : Up(parent) +{ +} //---------------------------------------------------------------------------- -std::pair<const char*, bool> cmDefinitions::Get(const std::string& key) +void cmDefinitions::Reset(cmDefinitions* parent) +{ + this->Up = parent; + this->Map.clear(); +} + +//---------------------------------------------------------------------------- +cmDefinitions::Def const& +cmDefinitions::GetInternal(const std::string& key) { MapType::const_iterator i = this->Map.find(key); - std::pair<const char*, bool> result((const char*)0, false); if(i != this->Map.end()) { - result = std::make_pair(i->second.Exists ? i->second.c_str() : 0, true); + return i->second; + } + if(cmDefinitions* up = this->Up) + { + // Query the parent scope and store the result locally. + Def def = up->GetInternal(key); + return this->Map.insert(MapType::value_type(key, def)).first->second; } - return result; + return this->NoDef; } //---------------------------------------------------------------------------- -void cmDefinitions::Set(const std::string& key, const char* value) +cmDefinitions::Def const& +cmDefinitions::SetInternal(const std::string& key, Def const& def) { - Def def(value); - this->Map[key] = def; + if(this->Up || def.Exists) + { + // In lower scopes we store keys, defined or not. + return (this->Map[key] = def); + } + else + { + // In the top-most scope we need not store undefined keys. + this->Map.erase(key); + return this->NoDef; + } } -void cmDefinitions::Erase(const std::string& key) +//---------------------------------------------------------------------------- +const char* cmDefinitions::Get(const std::string& key) { - this->Map.erase(key); + Def const& def = this->GetInternal(key); + return def.Exists? def.c_str() : 0; } //---------------------------------------------------------------------------- -std::vector<std::string> cmDefinitions::LocalKeys() const +const char* cmDefinitions::Set(const std::string& key, const char* value) { - std::vector<std::string> keys; - keys.reserve(this->Map.size()); + Def const& def = this->SetInternal(key, Def(value)); + return def.Exists? def.c_str() : 0; +} + +//---------------------------------------------------------------------------- +std::set<std::string> cmDefinitions::LocalKeys() const +{ + std::set<std::string> keys; // Consider local definitions. for(MapType::const_iterator mi = this->Map.begin(); mi != this->Map.end(); ++mi) { if (mi->second.Exists) { - keys.push_back(mi->first); + keys.insert(mi->first); } } return keys; } //---------------------------------------------------------------------------- -cmDefinitions cmDefinitions::MakeClosure( - std::vector<cmDefinitions const*>::iterator begin, - std::vector<cmDefinitions const*>::iterator end) +cmDefinitions cmDefinitions::Closure() const +{ + return cmDefinitions(ClosureTag(), this); +} + +//---------------------------------------------------------------------------- +cmDefinitions::cmDefinitions(ClosureTag const&, cmDefinitions const* root): + Up(0) { std::set<std::string> undefined; - cmDefinitions closure; - closure.MakeClosure(undefined, begin, end); - return closure; + this->ClosureImpl(undefined, root); } //---------------------------------------------------------------------------- -void -cmDefinitions::MakeClosure(std::set<std::string>& undefined, - std::vector<cmDefinitions const*>::iterator begin, - std::vector<cmDefinitions const*>::iterator end) +void cmDefinitions::ClosureImpl(std::set<std::string>& undefined, + cmDefinitions const* defs) { - for (std::vector<cmDefinitions const*>::const_iterator it = begin; - it != end; ++it) + // Consider local definitions. + for(MapType::const_iterator mi = defs->Map.begin(); + mi != defs->Map.end(); ++mi) { - // Consider local definitions. - for(MapType::const_iterator mi = (*it)->Map.begin(); - mi != (*it)->Map.end(); ++mi) + // Use this key if it is not already set or unset. + if(this->Map.find(mi->first) == this->Map.end() && + undefined.find(mi->first) == undefined.end()) { - // Use this key if it is not already set or unset. - if(this->Map.find(mi->first) == this->Map.end() && - undefined.find(mi->first) == undefined.end()) + if(mi->second.Exists) { - if(mi->second.Exists) - { - this->Map.insert(*mi); - } - else - { - undefined.insert(mi->first); - } + this->Map.insert(*mi); + } + else + { + undefined.insert(mi->first); } } } + + // Traverse parents. + if(cmDefinitions const* up = defs->Up) + { + this->ClosureImpl(undefined, up); + } } //---------------------------------------------------------------------------- -std::vector<std::string> -cmDefinitions::Keys(std::vector<std::string>& undefined) const +std::set<std::string> cmDefinitions::ClosureKeys() const { - std::vector<std::string> defined; - defined.reserve(this->Map.size()); + std::set<std::string> defined; + std::set<std::string> undefined; + this->ClosureKeys(defined, undefined); + return defined; +} + +//---------------------------------------------------------------------------- +void cmDefinitions::ClosureKeys(std::set<std::string>& defined, + std::set<std::string>& undefined) const +{ + // Consider local definitions. for(MapType::const_iterator mi = this->Map.begin(); mi != this->Map.end(); ++mi) { - std::vector<std::string>& m = mi->second.Exists? defined : undefined; - m.push_back(mi->first); + // Use this key if it is not already set or unset. + if(defined.find(mi->first) == defined.end() && + undefined.find(mi->first) == undefined.end()) + { + std::set<std::string>& m = mi->second.Exists? defined : undefined; + m.insert(mi->first); + } + } + + // Traverse parents. + if(cmDefinitions const* up = this->Up) + { + up->ClosureKeys(defined, undefined); } - std::sort(defined.begin(), defined.end()); - std::sort(undefined.begin(), undefined.end()); - undefined.erase(std::unique(undefined.begin(), undefined.end()), - undefined.end()); - return defined; } diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index 6c57c36..a2f053f 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -21,27 +21,37 @@ * \brief Store a scope of variable definitions for CMake language. * * This stores the state of variable definitions (set or unset) for - * one scope. Sets are always local. + * one scope. Sets are always local. Gets search parent scopes + * transitively and save results locally. */ class cmDefinitions { public: - std::pair<const char*, bool> Get(const std::string& key); + /** Construct with the given parent scope. */ + cmDefinitions(cmDefinitions* parent = 0); - /** Set (or unset if null) a value associated with a key. */ - void Set(const std::string& key, const char* value); + /** Reset object as if newly constructed. */ + void Reset(cmDefinitions* parent = 0); + + /** Returns the parent scope, if any. */ + cmDefinitions* GetParent() const { return this->Up; } - void Erase(const std::string& key); + /** Get the value associated with a key; null if none. + Store the result locally if it came from a parent. */ + const char* Get(const std::string& key); + + /** Set (or unset if null) a value associated with a key. */ + const char* Set(const std::string& key, const char* value); /** Get the set of all local keys. */ - std::vector<std::string> LocalKeys() const; + std::set<std::string> LocalKeys() const; - std::vector<std::string> - Keys(std::vector<std::string>& undefinedKeys) const; + /** Compute the closure of all defined keys with values. + This flattens the scope. The result has no parent. */ + cmDefinitions Closure() const; - static cmDefinitions MakeClosure( - std::vector<cmDefinitions const*>::iterator begin, - std::vector<cmDefinitions const*>::iterator end); + /** Compute the set of all defined keys. */ + std::set<std::string> ClosureKeys() const; private: // String with existence boolean. @@ -56,6 +66,10 @@ private: Def(Def const& d): std_string(d), Exists(d.Exists) {} bool Exists; }; + static Def NoDef; + + // Parent scope, if any. + cmDefinitions* Up; // Local definitions, set or unset. #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -65,9 +79,19 @@ private: #endif MapType Map; - void MakeClosure(std::set<std::string>& undefined, - std::vector<cmDefinitions const*>::iterator begin, - std::vector<cmDefinitions const*>::iterator end); + // Internal query and update methods. + Def const& GetInternal(const std::string& key); + Def const& SetInternal(const std::string& key, Def const& def); + + // Implementation of Closure() method. + struct ClosureTag {}; + cmDefinitions(ClosureTag const&, cmDefinitions const* root); + void ClosureImpl(std::set<std::string>& undefined, + cmDefinitions const* defs); + + // Implementation of ClosureKeys() method. + void ClosureKeys(std::set<std::string>& defined, + std::set<std::string>& undefined) const; }; #endif diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index b46c99f..c77a90c 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -38,144 +38,28 @@ #include <cmsys/FStream.hxx> #include <cmsys/auto_ptr.hxx> +#include <stack> +#include <list> #include <ctype.h> // for isspace #include <assert.h> class cmMakefile::Internals { public: - std::vector<cmDefinitions> VarStack; + std::stack<cmDefinitions, std::list<cmDefinitions> > VarStack; std::stack<std::set<std::string> > VarInitStack; std::stack<std::set<std::string> > VarUsageStack; bool IsSourceFileTryCompile; - - void PushDefinitions() - { - this->VarStack.resize(this->VarStack.size() + 1); - } - - void InitializeDefinitions(cmMakefile* parent) - { - std::vector<cmDefinitions const*> defPtrs; - for (std::vector<cmDefinitions>::iterator it = - parent->Internal->VarStack.begin(); - it != parent->Internal->VarStack.end(); ++it) - { - defPtrs.push_back(&*it); - } - std::reverse(defPtrs.begin(), defPtrs.end()); - this->VarStack.back() = cmDefinitions::MakeClosure(defPtrs.begin(), - defPtrs.end()); - } - - const char* GetDefinition(std::string const& name) - { - std::pair<const char*, bool> result((const char*)0, false); - std::vector<cmDefinitions>::reverse_iterator it = this->VarStack.rbegin(); - for ( ; it != this->VarStack.rend(); ++it) - { - result = it->Get(name); - if(result.second) - { - break; - } - } - std::vector<cmDefinitions>::reverse_iterator last = it; - // Store the result in intermediate scopes. - for (it = this->VarStack.rbegin(); it != last; ++it) - { - it->Set(name, result.first); - } - return result.first; - } - - void SetDefinition(std::string const& name, std::string const& value) - { - this->VarStack.back().Set(name, value.c_str()); - } - - void RemoveDefinition(std::string const& name) - { - if (this->VarStack.size() > 1) - { - // In lower scopes we store keys, defined or not. - this->VarStack.back().Set(name, 0); - } - else - { - this->VarStack.back().Erase(name); - } - } - - std::vector<std::string> LocalKeys() const - { - return this->VarStack.back().LocalKeys(); - } - - std::vector<std::string> ClosureKeys() const - { - std::vector<std::string> closureKeys; - std::vector<std::string> undefinedKeys; - for (std::vector<cmDefinitions>::const_iterator it - = this->VarStack.begin(); it != this->VarStack.end(); ++it) - { - std::vector<std::string> const& localKeys = it->Keys(undefinedKeys); - closureKeys.insert(closureKeys.end(), - localKeys.begin(), localKeys.end()); - std::vector<std::string>::iterator newIt = - closureKeys.end() - localKeys.size(); - std::inplace_merge(closureKeys.begin(), newIt, closureKeys.end()); - } - closureKeys.erase(std::unique(closureKeys.begin(), - closureKeys.end()), closureKeys.end()); - return closureKeys; - } - - void PopDefinitions() - { - this->VarStack.pop_back(); - } - - bool RaiseScope(std::string const& var, const char* varDef, cmMakefile* mf) - { - if(this->VarStack.size() > 1) - { - // First localize the definition in the current scope. - this->GetDefinition(var); - - // Now update the definition in the parent scope. - cmDefinitions& up = this->VarStack[this->VarStack.size() - 2]; - up.Set(var, varDef); - } - else if(cmLocalGenerator* plg = mf->GetLocalGenerator()->GetParent()) - { - // Update the definition in the parent directory top scope. This - // directory's scope was initialized by the closure of the parent - // scope, so we do not need to localize the definition first. - cmMakefile* parent = plg->GetMakefile(); - if (varDef) - { - parent->AddDefinition(var, varDef); - } - else - { - parent->RemoveDefinition(var); - } - } - else - { - return false; - } - return true; - } }; // default is not to be building executables cmMakefile::cmMakefile(): Internal(new Internals) { - this->Internal->PushDefinitions(); - this->Internal->VarInitStack.push(std::set<std::string>()); - this->Internal->VarUsageStack.push(std::set<std::string>()); + const cmDefinitions& defs = cmDefinitions(); + const std::set<std::string> globalKeys = defs.LocalKeys(); + this->Internal->VarStack.push(defs); + this->Internal->VarInitStack.push(globalKeys); + this->Internal->VarUsageStack.push(globalKeys); this->Internal->IsSourceFileTryCompile = false; // Initialize these first since AddDefaultDefinitions calls AddDefinition @@ -1615,7 +1499,7 @@ void cmMakefile::InitializeFromParent() cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile(); // Initialize definitions with the closure of the parent scope. - this->Internal->InitializeDefinitions(parent); + this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure(); this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetCurrentSourceDirectory()); @@ -1815,7 +1699,7 @@ void cmMakefile::AddDefinition(const std::string& name, const char* value) return; } - this->Internal->SetDefinition(name, value); + this->Internal->VarStack.top().Set(name, value); if (!this->Internal->VarUsageStack.empty() && this->VariableInitialized(name)) { @@ -1885,13 +1769,13 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, this->GetState()->AddCacheEntry(name, haveVal ? val.c_str() : 0, doc, type); // if there was a definition then remove it - this->Internal->RemoveDefinition(name); + this->Internal->VarStack.top().Set(name, 0); } void cmMakefile::AddDefinition(const std::string& name, bool value) { - this->Internal->SetDefinition(name, value ? "ON" : "OFF"); + this->Internal->VarStack.top().Set(name, value? "ON" : "OFF"); if (!this->Internal->VarUsageStack.empty() && this->VariableInitialized(name)) { @@ -1915,8 +1799,9 @@ void cmMakefile::CheckForUnusedVariables() const { return; } - const std::vector<std::string>& locals = this->Internal->LocalKeys(); - std::vector<std::string>::const_iterator it = locals.begin(); + const cmDefinitions& defs = this->Internal->VarStack.top(); + const std::set<std::string>& locals = defs.LocalKeys(); + std::set<std::string>::const_iterator it = locals.begin(); for (; it != locals.end(); ++it) { this->CheckForUnused("out of scope", *it); @@ -1989,7 +1874,7 @@ void cmMakefile::CheckForUnused(const char* reason, void cmMakefile::RemoveDefinition(const std::string& name) { - this->Internal->RemoveDefinition(name); + this->Internal->VarStack.top().Set(name, 0); if (!this->Internal->VarUsageStack.empty() && this->VariableInitialized(name)) { @@ -2462,7 +2347,7 @@ const char* cmMakefile::GetRequiredDefinition(const std::string& name) const bool cmMakefile::IsDefinitionSet(const std::string& name) const { - const char* def = this->Internal->GetDefinition(name); + const char* def = this->Internal->VarStack.top().Get(name); this->Internal->VarUsageStack.top().insert(name); if(!def) { @@ -2488,7 +2373,7 @@ const char* cmMakefile::GetDefinition(const std::string& name) const { this->Internal->VarUsageStack.top().insert(name); } - const char* def = this->Internal->GetDefinition(name); + const char* def = this->Internal->VarStack.top().Get(name); if(!def) { def = this->GetState()->GetInitializedCacheValue(name); @@ -2528,7 +2413,9 @@ std::vector<std::string> cmMakefile std::vector<std::string> res; if ( !cacheonly ) { - res = this->Internal->ClosureKeys(); + std::set<std::string> definitions = + this->Internal->VarStack.top().ClosureKeys(); + res.insert(res.end(), definitions.begin(), definitions.end()); } std::vector<std::string> cacheKeys = this->GetState()->GetCacheEntryKeys(); @@ -4442,9 +4329,10 @@ std::string cmMakefile::GetListFileStack() const void cmMakefile::PushScope() { - this->Internal->PushDefinitions(); + cmDefinitions* parent = &this->Internal->VarStack.top(); const std::set<std::string>& init = this->Internal->VarInitStack.top(); const std::set<std::string>& usage = this->Internal->VarUsageStack.top(); + this->Internal->VarStack.push(cmDefinitions(parent)); this->Internal->VarInitStack.push(init); this->Internal->VarUsageStack.push(usage); @@ -4465,12 +4353,13 @@ void cmMakefile::PopScope() this->PopLoopBlockBarrier(); + cmDefinitions* current = &this->Internal->VarStack.top(); std::set<std::string> init = this->Internal->VarInitStack.top(); std::set<std::string> usage = this->Internal->VarUsageStack.top(); - const std::vector<std::string>& locals = this->Internal->LocalKeys(); + const std::set<std::string>& locals = current->LocalKeys(); // Remove initialization and usage information for variables in the local // scope. - std::vector<std::string>::const_iterator it = locals.begin(); + std::set<std::string>::const_iterator it = locals.begin(); for (; it != locals.end(); ++it) { init.erase(*it); @@ -4483,8 +4372,7 @@ void cmMakefile::PopScope() usage.erase(*it); } } - - this->Internal->PopDefinitions(); + this->Internal->VarStack.pop(); this->Internal->VarInitStack.pop(); this->Internal->VarUsageStack.pop(); // Push initialization and usage up to the parent scope. @@ -4499,7 +4387,31 @@ void cmMakefile::RaiseScope(const std::string& var, const char *varDef) return; } - if (!this->Internal->RaiseScope(var, varDef, this)) + cmDefinitions& cur = this->Internal->VarStack.top(); + if(cmDefinitions* up = cur.GetParent()) + { + // First localize the definition in the current scope. + cur.Get(var); + + // Now update the definition in the parent scope. + up->Set(var, varDef); + } + else if(cmLocalGenerator* plg = this->LocalGenerator->GetParent()) + { + // Update the definition in the parent directory top scope. This + // directory's scope was initialized by the closure of the parent + // scope, so we do not need to localize the definition first. + cmMakefile* parent = plg->GetMakefile(); + if (varDef) + { + parent->AddDefinition(var, varDef); + } + else + { + parent->RemoveDefinition(var); + } + } + else { std::ostringstream m; m << "Cannot set \"" << var << "\": current scope has no parent."; ----------------------------------------------------------------------- Summary of changes: Source/cmDefinitions.cxx | 157 +++++++++++++++++++++++++------------ Source/cmDefinitions.h | 52 +++++++++---- Source/cmMakefile.cxx | 192 +++++++++++++--------------------------------- 3 files changed, 196 insertions(+), 205 deletions(-) hooks/post-receive -- CMake _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org http://public.kitware.com/mailman/listinfo/cmake-commits