1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmDefinitions.h"
14 //----------------------------------------------------------------------------
15 cmDefinitions::Def cmDefinitions::NoDef;
17 //----------------------------------------------------------------------------
18 cmDefinitions::cmDefinitions(cmDefinitions* parent): Up(parent)
22 //----------------------------------------------------------------------------
23 void cmDefinitions::Reset(cmDefinitions* parent)
29 //----------------------------------------------------------------------------
30 cmDefinitions::Def const&
31 cmDefinitions::GetInternal(const char* key)
33 MapType::const_iterator i = this->Map.find(key);
34 if(i != this->Map.end())
38 else if(cmDefinitions* up = this->Up)
40 // Query the parent scope and store the result locally.
41 Def def = up->GetInternal(key);
42 return this->Map.insert(MapType::value_type(key, def)).first->second;
47 //----------------------------------------------------------------------------
48 cmDefinitions::Def const&
49 cmDefinitions::SetInternal(const char* key, Def const& def)
51 if(this->Up || def.Exists)
53 // In lower scopes we store keys, defined or not.
54 MapType::iterator i = this->Map.find(key);
55 if(i == this->Map.end())
57 i = this->Map.insert(MapType::value_type(key, def)).first;
67 // In the top-most scope we need not store undefined keys.
73 //----------------------------------------------------------------------------
74 const char* cmDefinitions::Get(const char* key)
76 Def const& def = this->GetInternal(key);
77 return def.Exists? def.c_str() : 0;
80 //----------------------------------------------------------------------------
81 const char* cmDefinitions::Set(const char* key, const char* value)
83 Def const& def = this->SetInternal(key, Def(value));
84 return def.Exists? def.c_str() : 0;
87 //----------------------------------------------------------------------------
88 std::set<cmStdString> cmDefinitions::LocalKeys() const
90 std::set<cmStdString> keys;
91 // Consider local definitions.
92 for(MapType::const_iterator mi = this->Map.begin();
93 mi != this->Map.end(); ++mi)
95 if (mi->second.Exists)
97 keys.insert(mi->first);
103 //----------------------------------------------------------------------------
104 cmDefinitions cmDefinitions::Closure() const
106 return cmDefinitions(ClosureTag(), this);
109 //----------------------------------------------------------------------------
110 cmDefinitions::cmDefinitions(ClosureTag const&, cmDefinitions const* root):
113 std::set<cmStdString> undefined;
114 this->ClosureImpl(undefined, root);
117 //----------------------------------------------------------------------------
118 void cmDefinitions::ClosureImpl(std::set<cmStdString>& undefined,
119 cmDefinitions const* defs)
121 // Consider local definitions.
122 for(MapType::const_iterator mi = defs->Map.begin();
123 mi != defs->Map.end(); ++mi)
125 // Use this key if it is not already set or unset.
126 if(this->Map.find(mi->first) == this->Map.end() &&
127 undefined.find(mi->first) == undefined.end())
129 if(mi->second.Exists)
131 this->Map.insert(*mi);
135 undefined.insert(mi->first);
141 if(cmDefinitions const* up = defs->Up)
143 this->ClosureImpl(undefined, up);
147 //----------------------------------------------------------------------------
148 std::set<cmStdString> cmDefinitions::ClosureKeys() const
150 std::set<cmStdString> defined;
151 std::set<cmStdString> undefined;
152 this->ClosureKeys(defined, undefined);
156 //----------------------------------------------------------------------------
157 void cmDefinitions::ClosureKeys(std::set<cmStdString>& defined,
158 std::set<cmStdString>& undefined) const
160 // Consider local definitions.
161 for(MapType::const_iterator mi = this->Map.begin();
162 mi != this->Map.end(); ++mi)
164 // Use this key if it is not already set or unset.
165 if(defined.find(mi->first) == defined.end() &&
166 undefined.find(mi->first) == undefined.end())
168 std::set<cmStdString>& m = mi->second.Exists? defined : undefined;
174 if(cmDefinitions const* up = this->Up)
176 up->ClosureKeys(defined, undefined);