/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmDefinitions.h" #include "cm_string_view.hxx" #include #include #include #include cmDefinitions::Def cmDefinitions::NoDef; cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key, StackIter begin, StackIter end, bool raise) { assert(begin != end); { auto it = begin->Map.find(cm::String::borrow(key)); if (it != begin->Map.end()) { it->second.Used = true; return it->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.emplace(key, def).first->second; } const std::string* cmDefinitions::Get(const std::string& key, StackIter begin, StackIter end) { Def const& def = cmDefinitions::GetInternal(key, begin, end, false); return def.Value ? def.Value.str_if_stable() : nullptr; } 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) { if (it->Map.find(cm::String::borrow(key)) != it->Map.end()) { return true; } } return false; } cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end) { cmDefinitions closure; std::unordered_set undefined; for (StackIter it = begin; it != end; ++it) { // Consider local definitions. for (auto const& mi : it->Map) { // Use this key if it is not already set or unset. if (closure.Map.find(mi.first) == closure.Map.end() && undefined.find(mi.first.view()) == undefined.end()) { if (mi.second.Value) { closure.Map.insert(mi); } else { undefined.emplace(mi.first.view()); } } } } return closure; } std::vector cmDefinitions::ClosureKeys(StackIter begin, StackIter end) { std::vector defined; std::unordered_set bound; for (StackIter it = begin; it != end; ++it) { defined.reserve(defined.size() + it->Map.size()); for (auto const& mi : it->Map) { // Use this key if it is not already set or unset. if (bound.emplace(mi.first.view()).second && mi.second.Value) { defined.push_back(*mi.first.str_if_stable()); } } } return defined; } void cmDefinitions::Set(const std::string& key, cm::string_view value) { this->Map[key] = Def(value); } void cmDefinitions::Unset(const std::string& key) { this->Map[key] = Def(); } std::vector cmDefinitions::UnusedKeys() const { std::vector keys; keys.reserve(this->Map.size()); // Consider local definitions. for (auto const& mi : this->Map) { if (!mi.second.Used) { keys.push_back(*mi.first.str_if_stable()); } } return keys; }