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
GetInternal(const std::string & key,StackIter begin,StackIter end,bool raise)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
Get(const std::string & key,StackIter begin,StackIter end)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
Raise(const std::string & key,StackIter begin,StackIter end)44 void cmDefinitions::Raise(const std::string& key, StackIter begin,
45 StackIter end)
46 {
47 cmDefinitions::GetInternal(key, begin, end, true);
48 }
49
HasKey(const std::string & key,StackIter begin,StackIter end)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
MakeClosure(StackIter begin,StackIter end)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
ClosureKeys(StackIter begin,StackIter end)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
Set(const std::string & key,cm::string_view value)101 void cmDefinitions::Set(const std::string& key, cm::string_view value)
102 {
103 this->Map[key] = Def(value);
104 }
105
Unset(const std::string & key)106 void cmDefinitions::Unset(const std::string& key)
107 {
108 this->Map[key] = Def();
109 }
110