packaging: Initial packaging
[platform/upstream/cmake.git] / Source / cmDefinitions.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
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"
13
14 //----------------------------------------------------------------------------
15 cmDefinitions::Def cmDefinitions::NoDef;
16
17 //----------------------------------------------------------------------------
18 cmDefinitions::cmDefinitions(cmDefinitions* parent): Up(parent)
19 {
20 }
21
22 //----------------------------------------------------------------------------
23 void cmDefinitions::Reset(cmDefinitions* parent)
24 {
25   this->Up = parent;
26   this->Map.clear();
27 }
28
29 //----------------------------------------------------------------------------
30 cmDefinitions::Def const&
31 cmDefinitions::GetInternal(const char* key)
32 {
33   MapType::const_iterator i = this->Map.find(key);
34   if(i != this->Map.end())
35     {
36     return i->second;
37     }
38   else if(cmDefinitions* up = this->Up)
39     {
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;
43     }
44   return this->NoDef;
45 }
46
47 //----------------------------------------------------------------------------
48 cmDefinitions::Def const&
49 cmDefinitions::SetInternal(const char* key, Def const& def)
50 {
51   if(this->Up || def.Exists)
52     {
53     // In lower scopes we store keys, defined or not.
54     MapType::iterator i = this->Map.find(key);
55     if(i == this->Map.end())
56       {
57       i = this->Map.insert(MapType::value_type(key, def)).first;
58       }
59     else
60       {
61       i->second = def;
62       }
63     return i->second;
64     }
65   else
66     {
67     // In the top-most scope we need not store undefined keys.
68     this->Map.erase(key);
69     return this->NoDef;
70     }
71 }
72
73 //----------------------------------------------------------------------------
74 const char* cmDefinitions::Get(const char* key)
75 {
76   Def const& def = this->GetInternal(key);
77   return def.Exists? def.c_str() : 0;
78 }
79
80 //----------------------------------------------------------------------------
81 const char* cmDefinitions::Set(const char* key, const char* value)
82 {
83   Def const& def = this->SetInternal(key, Def(value));
84   return def.Exists? def.c_str() : 0;
85 }
86
87 //----------------------------------------------------------------------------
88 std::set<cmStdString> cmDefinitions::LocalKeys() const
89 {
90   std::set<cmStdString> keys;
91   // Consider local definitions.
92   for(MapType::const_iterator mi = this->Map.begin();
93       mi != this->Map.end(); ++mi)
94     {
95     if (mi->second.Exists)
96       {
97       keys.insert(mi->first);
98       }
99     }
100   return keys;
101 }
102
103 //----------------------------------------------------------------------------
104 cmDefinitions cmDefinitions::Closure() const
105 {
106   return cmDefinitions(ClosureTag(), this);
107 }
108
109 //----------------------------------------------------------------------------
110 cmDefinitions::cmDefinitions(ClosureTag const&, cmDefinitions const* root):
111   Up(0)
112 {
113   std::set<cmStdString> undefined;
114   this->ClosureImpl(undefined, root);
115 }
116
117 //----------------------------------------------------------------------------
118 void cmDefinitions::ClosureImpl(std::set<cmStdString>& undefined,
119                                 cmDefinitions const* defs)
120 {
121   // Consider local definitions.
122   for(MapType::const_iterator mi = defs->Map.begin();
123       mi != defs->Map.end(); ++mi)
124     {
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())
128       {
129       if(mi->second.Exists)
130         {
131         this->Map.insert(*mi);
132         }
133       else
134         {
135         undefined.insert(mi->first);
136         }
137       }
138     }
139
140   // Traverse parents.
141   if(cmDefinitions const* up = defs->Up)
142     {
143     this->ClosureImpl(undefined, up);
144     }
145 }
146
147 //----------------------------------------------------------------------------
148 std::set<cmStdString> cmDefinitions::ClosureKeys() const
149 {
150   std::set<cmStdString> defined;
151   std::set<cmStdString> undefined;
152   this->ClosureKeys(defined, undefined);
153   return defined;
154 }
155
156 //----------------------------------------------------------------------------
157 void cmDefinitions::ClosureKeys(std::set<cmStdString>& defined,
158                                 std::set<cmStdString>& undefined) const
159 {
160   // Consider local definitions.
161   for(MapType::const_iterator mi = this->Map.begin();
162       mi != this->Map.end(); ++mi)
163     {
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())
167       {
168       std::set<cmStdString>& m = mi->second.Exists? defined : undefined;
169       m.insert(mi->first);
170       }
171     }
172
173   // Traverse parents.
174   if(cmDefinitions const* up = this->Up)
175     {
176     up->ClosureKeys(defined, undefined);
177     }
178 }