From e1d2e3b63934c1e193429f1d6c4e04abc0e85d56 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 26 Feb 2015 15:40:29 +0200 Subject: Support for scope parents, initial variable support --- build/algorithm.cxx | 2 +- build/context | 3 --- build/context.cxx | 2 -- build/prefix-map | 4 ++-- build/prefix-map.txx | 5 ++-- build/scope | 31 +++++++++++++++++------- build/scope.cxx | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ build/variable | 19 +++++++++++++++ 8 files changed, 113 insertions(+), 19 deletions(-) create mode 100644 build/variable (limited to 'build') diff --git a/build/algorithm.cxx b/build/algorithm.cxx index d418cda..16bc1bc 100644 --- a/build/algorithm.cxx +++ b/build/algorithm.cxx @@ -47,7 +47,7 @@ namespace build const auto& rules (i->second); // Hint map. string hint; // @@ TODO - auto rs (rules.find (hint)); + auto rs (rules.find_prefix (hint)); for (auto i (rs.first); i != rs.second; ++i) { diff --git a/build/context b/build/context index 4f5b029..c177603 100644 --- a/build/context +++ b/build/context @@ -21,9 +21,6 @@ namespace build extern path src_base; extern path out_base; - class scope; - extern scope* root_scope; - // Return the src/out directory corresponding to the given out/src. The // passed directory should be a sub-directory of out/src_root. // diff --git a/build/context.cxx b/build/context.cxx index a298d41..79753ec 100644 --- a/build/context.cxx +++ b/build/context.cxx @@ -20,8 +20,6 @@ namespace build path src_base; path out_base; - scope* root_scope; - path src_out (const path& o) { diff --git a/build/prefix-map b/build/prefix-map index 1b00337..d98c842 100644 --- a/build/prefix-map +++ b/build/prefix-map @@ -108,10 +108,10 @@ namespace build : map_type (std::move (init), compare_type (delimiter)) {} std::pair - find (const key_type&); + find_prefix (const key_type&); std::pair - find (const key_type&) const; + find_prefix (const key_type&) const; }; template ::char_type D = 0> diff --git a/build/prefix-map.txx b/build/prefix-map.txx index 0da911d..a8bf028 100644 --- a/build/prefix-map.txx +++ b/build/prefix-map.txx @@ -6,7 +6,7 @@ namespace build { template auto prefix_map_common:: - find (const key_type& k) -> std::pair + find_prefix (const key_type& k) -> std::pair { std::pair r; r.first = this->lower_bound (k); @@ -24,7 +24,8 @@ namespace build template auto prefix_map_common:: - find (const key_type& k) const -> std::pair + find_prefix (const key_type& k) const -> + std::pair { std::pair r; r.first = this->lower_bound (k); diff --git a/build/scope b/build/scope index 58f7933..6d96b0a 100644 --- a/build/scope +++ b/build/scope @@ -7,6 +7,7 @@ #include #include +#include #include namespace build @@ -19,6 +20,9 @@ namespace build const path_type& path () const {return i_->first;} // Absolute and normalized. + scope& + parent () const {return *parent_;} + private: friend class scope_map; @@ -27,32 +31,41 @@ namespace build scope () = default; void - init (const iterator& i) {i_ = i;} + init (const iterator& i, scope* p) {i_ = i; parent_ = p;} + + void + parent (scope& p) {parent_ = &p;} public: + variable_map variables; prerequisite_set prerequisites; private: iterator i_; + scope* parent_; }; class scope_map: path_map { public: + // Note that we assume the first insertion into the map is that + // of the root scope. + // + scope& - operator[] (const path& k) - { - auto i (emplace (k, scope ())); - auto& r (i.first->second); + operator[] (const path&); - if (i.second) - r.init (i.first); + // Find the most qualified scope that encompasses this path. + // + scope& + find (const path&); - return r; - } + private: + typedef path_map base; }; extern scope_map scopes; + extern scope* root_scope; } #endif // BUILD_SCOPE diff --git a/build/scope.cxx b/build/scope.cxx index 0f99b0e..7165663 100644 --- a/build/scope.cxx +++ b/build/scope.cxx @@ -9,4 +9,70 @@ using namespace std; namespace build { scope_map scopes; + scope* root_scope; + + scope& scope_map:: + operator[] (const path& k) + { + auto er (emplace (k, scope ())); + scope& s (er.first->second); + + if (er.second) + { + scope* p (nullptr); + + // Update scopes of which we are a new parent. + // + for (auto r (find_prefix (k)); r.first != r.second; ++r.first) + { + scope& c (r.first->second); + + // The first scope of which we are a parent is the least + // (shortest) one which means there is no other scope + // between it and our parent. + // + if (p == nullptr) + p = &c; + else if (p != &c) // A scope with an intermediate parent. + continue; + + c.parent (s); + } + + // We couldn't get the parent from one of its old children + // so we have to find it ourselves (unless this is is the + // root scope). + // + if (p == nullptr && size () != 1) + p = &find (k); + + s.init (er.first, p); + } + + return s; + } + + // Find the most qualified scope that encompasses this path. + // + scope& scope_map:: + find (const path& k) + { + // Normally we would have a scope for the full path so try + // that before making any copies. + // + auto i (base::find (k)); + + if (i != end ()) + return i->second; + + for (path d (k.directory ());; d = d.directory ()) + { + auto i (base::find (k)); + + if (i != end ()) + return i->second; + + assert (d.empty ()); // We should have the root scope. + } + } } diff --git a/build/variable b/build/variable new file mode 100644 index 0000000..caceb2b --- /dev/null +++ b/build/variable @@ -0,0 +1,19 @@ +// file : build/variable -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD_VARIABLE +#define BUILD_VARIABLE + +#include + +namespace build +{ + // @@ TODO: + // - pool names? + // + + typedef prefix_map variable_map; +} + +#endif // BUILD_VARIABLE -- cgit v1.1