diff options
Diffstat (limited to 'Source/cmDefinitions.cxx')
-rw-r--r-- | Source/cmDefinitions.cxx | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx new file mode 100644 index 0000000..13bfc6a --- /dev/null +++ b/Source/cmDefinitions.cxx @@ -0,0 +1,167 @@ +/*========================================================================= + + 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 "cmDefinitions.h" + +//---------------------------------------------------------------------------- +cmDefinitions::Def cmDefinitions::NoDef; + +//---------------------------------------------------------------------------- +cmDefinitions::cmDefinitions(cmDefinitions* parent): Up(parent) +{ +} + +//---------------------------------------------------------------------------- +void cmDefinitions::Reset(cmDefinitions* parent) +{ + this->Up = parent; + this->Map.clear(); +} + +//---------------------------------------------------------------------------- +cmDefinitions::Def const& +cmDefinitions::GetInternal(const char* key) +{ + MapType::const_iterator i = this->Map.find(key); + if(i != this->Map.end()) + { + return i->second; + } + else 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 this->NoDef; +} + +//---------------------------------------------------------------------------- +cmDefinitions::Def const& +cmDefinitions::SetInternal(const char* key, Def const& def) +{ + if(this->Up || def.Exists) + { + // In lower scopes we store keys, defined or not. + MapType::iterator i = this->Map.find(key); + if(i == this->Map.end()) + { + i = this->Map.insert(MapType::value_type(key, def)).first; + } + else + { + i->second = def; + } + return i->second; + } + else + { + // In the top-most scope we need not store undefined keys. + this->Map.erase(key); + return this->NoDef; + } +} + +//---------------------------------------------------------------------------- +const char* cmDefinitions::Get(const char* key) +{ + Def const& def = this->GetInternal(key); + return def.Exists? def.c_str() : 0; +} + +//---------------------------------------------------------------------------- +const char* cmDefinitions::Set(const char* key, const char* value) +{ + Def const& def = this->SetInternal(key, Def(value)); + return def.Exists? def.c_str() : 0; +} + +//---------------------------------------------------------------------------- +cmDefinitions cmDefinitions::Closure() const +{ + return cmDefinitions(ClosureTag(), this); +} + +//---------------------------------------------------------------------------- +cmDefinitions::cmDefinitions(ClosureTag const&, cmDefinitions const* root): + Up(0) +{ + std::set<cmStdString> undefined; + this->ClosureImpl(undefined, root); +} + +//---------------------------------------------------------------------------- +void cmDefinitions::ClosureImpl(std::set<cmStdString>& undefined, + cmDefinitions const* defs) +{ + // Consider local definitions. + for(MapType::const_iterator mi = defs->Map.begin(); + mi != defs->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()) + { + if(mi->second.Exists) + { + this->Map.insert(*mi); + } + else + { + undefined.insert(mi->first); + } + } + } + + // Traverse parents. + if(cmDefinitions const* up = defs->Up) + { + this->ClosureImpl(undefined, up); + } +} + +//---------------------------------------------------------------------------- +std::set<cmStdString> cmDefinitions::ClosureKeys() const +{ + std::set<cmStdString> defined; + std::set<cmStdString> undefined; + this->ClosureKeys(defined, undefined); + return defined; +} + +//---------------------------------------------------------------------------- +void cmDefinitions::ClosureKeys(std::set<cmStdString>& defined, + std::set<cmStdString>& undefined) const +{ + // Consider local definitions. + for(MapType::const_iterator mi = this->Map.begin(); + mi != this->Map.end(); ++mi) + { + // 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<cmStdString>& m = mi->second.Exists? defined : undefined; + m.insert(mi->first); + } + } + + // Traverse parents. + if(cmDefinitions const* up = this->Up) + { + up->ClosureKeys(defined, undefined); + } +} |