| /*============================================================================ |
| CMake - Cross Platform Makefile Generator |
| Copyright 2000-2009 Kitware, Inc., Insight Software Consortium |
| |
| Distributed under the OSI-approved BSD License (the "License"); |
| see accompanying file Copyright.txt for details. |
| |
| This software is distributed WITHOUT ANY WARRANTY; without even the |
| implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the License for more information. |
| ============================================================================*/ |
| #include "cmDefinitions.h" |
| |
| #include <assert.h> |
| |
| //---------------------------------------------------------------------------- |
| cmDefinitions::Def cmDefinitions::NoDef; |
| |
| //---------------------------------------------------------------------------- |
| cmDefinitions::Def const& cmDefinitions::GetInternal( |
| const std::string& key, StackIter begin, StackIter end, bool raise) |
| { |
| assert(begin != end); |
| MapType::iterator i = begin->Map.find(key); |
| if (i != begin->Map.end()) |
| { |
| i->second.Used = true; |
| return i->second; |
| } |
| StackIter it = begin; |
| ++it; |
| if (it == end) |
| { |
| return cmDefinitions::NoDef; |
| } |
| Def const& def = cmDefinitions::GetInternal(key, it, end, raise); |
| if (!raise) |
| { |
| return def; |
| } |
| return begin->Map.insert(MapType::value_type(key, def)).first->second; |
| } |
| |
| //---------------------------------------------------------------------------- |
| const char* cmDefinitions::Get(const std::string& key, |
| StackIter begin, StackIter end) |
| { |
| Def const& def = cmDefinitions::GetInternal(key, begin, end, false); |
| return def.Exists? def.c_str() : 0; |
| } |
| |
| void cmDefinitions::Raise(const std::string& key, |
| StackIter begin, StackIter end) |
| { |
| cmDefinitions::GetInternal(key, begin, end, true); |
| } |
| |
| bool cmDefinitions::HasKey(const std::string& key, |
| StackIter begin, StackIter end) |
| { |
| for (StackIter it = begin; it != end; ++it) |
| { |
| MapType::const_iterator i = it->Map.find(key); |
| if (i != it->Map.end()) |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| //---------------------------------------------------------------------------- |
| void cmDefinitions::Set(const std::string& key, const char* value) |
| { |
| Def def(value); |
| this->Map[key] = def; |
| } |
| |
| //---------------------------------------------------------------------------- |
| std::vector<std::string> cmDefinitions::UnusedKeys() const |
| { |
| std::vector<std::string> keys; |
| keys.reserve(this->Map.size()); |
| // Consider local definitions. |
| for(MapType::const_iterator mi = this->Map.begin(); |
| mi != this->Map.end(); ++mi) |
| { |
| if (!mi->second.Used) |
| { |
| keys.push_back(mi->first); |
| } |
| } |
| return keys; |
| } |
| |
| //---------------------------------------------------------------------------- |
| cmDefinitions cmDefinitions::MakeClosure(StackIter begin, |
| StackIter end) |
| { |
| cmDefinitions closure; |
| std::set<std::string> undefined; |
| for (StackIter it = begin; it != end; ++it) |
| { |
| // 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(closure.Map.find(mi->first) == closure.Map.end() && |
| undefined.find(mi->first) == undefined.end()) |
| { |
| if(mi->second.Exists) |
| { |
| closure.Map.insert(*mi); |
| } |
| else |
| { |
| undefined.insert(mi->first); |
| } |
| } |
| } |
| } |
| return closure; |
| } |
| |
| //---------------------------------------------------------------------------- |
| std::vector<std::string> |
| cmDefinitions::ClosureKeys(StackIter begin, StackIter end) |
| { |
| std::set<std::string> bound; |
| std::vector<std::string> defined; |
| |
| for (StackIter it = begin; it != end; ++it) |
| { |
| defined.reserve(defined.size() + it->Map.size()); |
| 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(bound.insert(mi->first).second && mi->second.Exists) |
| { |
| defined.push_back(mi->first); |
| } |
| } |
| } |
| |
| return defined; |
| } |