resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmDefinitions.cxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include "cmDefinitions.h"
4
5 #include <cassert>
6 #include <functional>
7 #include <unordered_set>
8 #include <utility>
9
10 #include <cm/string_view>
11
12 cmDefinitions::Def cmDefinitions::NoDef;
13
14 cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key,
15                                                      StackIter begin,
16                                                      StackIter end, bool raise)
17 {
18   assert(begin != end);
19   {
20     auto it = begin->Map.find(cm::String::borrow(key));
21     if (it != begin->Map.end()) {
22       return it->second;
23     }
24   }
25   StackIter it = begin;
26   ++it;
27   if (it == end) {
28     return cmDefinitions::NoDef;
29   }
30   Def const& def = cmDefinitions::GetInternal(key, it, end, raise);
31   if (!raise) {
32     return def;
33   }
34   return begin->Map.emplace(key, def).first->second;
35 }
36
37 cmValue cmDefinitions::Get(const std::string& key, StackIter begin,
38                            StackIter end)
39 {
40   Def const& def = cmDefinitions::GetInternal(key, begin, end, false);
41   return def.Value ? cmValue(def.Value.str_if_stable()) : nullptr;
42 }
43
44 void cmDefinitions::Raise(const std::string& key, StackIter begin,
45                           StackIter end)
46 {
47   cmDefinitions::GetInternal(key, begin, end, true);
48 }
49
50 bool cmDefinitions::HasKey(const std::string& key, StackIter begin,
51                            StackIter end)
52 {
53   for (StackIter it = begin; it != end; ++it) {
54     if (it->Map.find(cm::String::borrow(key)) != it->Map.end()) {
55       return true;
56     }
57   }
58   return false;
59 }
60
61 cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end)
62 {
63   cmDefinitions closure;
64   std::unordered_set<cm::string_view> undefined;
65   for (StackIter it = begin; it != end; ++it) {
66     // Consider local definitions.
67     for (auto const& mi : it->Map) {
68       // Use this key if it is not already set or unset.
69       if (closure.Map.find(mi.first) == closure.Map.end() &&
70           undefined.find(mi.first.view()) == undefined.end()) {
71         if (mi.second.Value) {
72           closure.Map.insert(mi);
73         } else {
74           undefined.emplace(mi.first.view());
75         }
76       }
77     }
78   }
79   return closure;
80 }
81
82 std::vector<std::string> cmDefinitions::ClosureKeys(StackIter begin,
83                                                     StackIter end)
84 {
85   std::vector<std::string> defined;
86   std::unordered_set<cm::string_view> bound;
87
88   for (StackIter it = begin; it != end; ++it) {
89     defined.reserve(defined.size() + it->Map.size());
90     for (auto const& mi : it->Map) {
91       // Use this key if it is not already set or unset.
92       if (bound.emplace(mi.first.view()).second && mi.second.Value) {
93         defined.push_back(*mi.first.str_if_stable());
94       }
95     }
96   }
97
98   return defined;
99 }
100
101 void cmDefinitions::Set(const std::string& key, cm::string_view value)
102 {
103   this->Map[key] = Def(value);
104 }
105
106 void cmDefinitions::Unset(const std::string& key)
107 {
108   this->Map[key] = Def();
109 }