diff options
-rw-r--r-- | build/algorithm.cxx | 2 | ||||
-rw-r--r-- | build/context | 3 | ||||
-rw-r--r-- | build/context.cxx | 2 | ||||
-rw-r--r-- | build/prefix-map | 4 | ||||
-rw-r--r-- | build/prefix-map.txx | 5 | ||||
-rw-r--r-- | build/scope | 31 | ||||
-rw-r--r-- | build/scope.cxx | 66 | ||||
-rw-r--r-- | build/variable | 19 | ||||
-rw-r--r-- | tests/build/prefix-map/driver.cxx | 42 |
9 files changed, 134 insertions, 40 deletions
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<iterator, iterator> - find (const key_type&); + find_prefix (const key_type&); std::pair<const_iterator, const_iterator> - find (const key_type&) const; + find_prefix (const key_type&) const; }; template <typename M, typename prefix_map_common<M>::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 <typename M> auto prefix_map_common<M>:: - find (const key_type& k) -> std::pair<iterator, iterator> + find_prefix (const key_type& k) -> std::pair<iterator, iterator> { std::pair<iterator, iterator> r; r.first = this->lower_bound (k); @@ -24,7 +24,8 @@ namespace build template <typename M> auto prefix_map_common<M>:: - find (const key_type& k) const -> std::pair<const_iterator, const_iterator> + find_prefix (const key_type& k) const -> + std::pair<const_iterator, const_iterator> { std::pair<const_iterator, const_iterator> 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 <build/path> #include <build/path-map> +#include <build/variable> #include <build/prerequisite> 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<scope> { 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<scope> 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 <build/prefix-map> + +namespace build +{ + // @@ TODO: + // - pool names? + // + + typedef prefix_map<std::string, std::string, '.'> variable_map; +} + +#endif // BUILD_VARIABLE diff --git a/tests/build/prefix-map/driver.cxx b/tests/build/prefix-map/driver.cxx index 77edb6c..d365df2 100644 --- a/tests/build/prefix-map/driver.cxx +++ b/tests/build/prefix-map/driver.cxx @@ -20,12 +20,12 @@ main () const pm m ('.'); { - auto r (m.find ("")); + auto r (m.find_prefix ("")); assert (r.first == r.second); } { - auto r (m.find ("foo")); + auto r (m.find_prefix ("foo")); assert (r.first == r.second); } } @@ -34,33 +34,33 @@ main () pm m {{{"foo", 1}}, '.'}; { - auto r (m.find ("")); + auto r (m.find_prefix ("")); assert (r.first != r.second && r.first->second == 1 && ++r.first == r.second); } { - auto r (m.find ("fo")); + auto r (m.find_prefix ("fo")); assert (r.first == r.second); } { - auto r (m.find ("fox")); + auto r (m.find_prefix ("fox")); assert (r.first == r.second); } { - auto r (m.find ("fooo")); + auto r (m.find_prefix ("fooo")); assert (r.first == r.second); } { - auto r (m.find ("foo.bar")); + auto r (m.find_prefix ("foo.bar")); assert (r.first == r.second); } { - auto r (m.find ("foo")); + auto r (m.find_prefix ("foo")); assert (r.first != r.second && r.first->second == 1 && ++r.first == r.second); } @@ -70,40 +70,40 @@ main () pm m {{{"foo", 1}, {"bar", 2}}, '.'}; { - auto r (m.find ("")); + auto r (m.find_prefix ("")); assert (r.first != r.second && r.first->second == 2 && ++r.first != r.second && r.first->second == 1 && ++r.first == r.second); } { - auto r (m.find ("fo")); + auto r (m.find_prefix ("fo")); assert (r.first == r.second); } { - auto r (m.find ("fox")); + auto r (m.find_prefix ("fox")); assert (r.first == r.second); } { - auto r (m.find ("fooo")); + auto r (m.find_prefix ("fooo")); assert (r.first == r.second); } { - auto r (m.find ("foo.bar")); + auto r (m.find_prefix ("foo.bar")); assert (r.first == r.second); } { - auto r (m.find ("foo")); + auto r (m.find_prefix ("foo")); assert (r.first != r.second && r.first->second == 1 && ++r.first == r.second); } { - auto r (m.find ("bar")); + auto r (m.find_prefix ("bar")); assert (r.first != r.second && r.first->second == 2 && ++r.first == r.second); } @@ -117,34 +117,34 @@ main () '.'); { - auto r (m.find ("fo")); + auto r (m.find_prefix ("fo")); assert (r.first == r.second); } { - auto r (m.find ("fox")); + auto r (m.find_prefix ("fox")); assert (r.first == r.second); } { - auto r (m.find ("fooo")); + auto r (m.find_prefix ("fooo")); assert (r.first == r.second); } { - auto r (m.find ("foo.bar")); + auto r (m.find_prefix ("foo.bar")); assert (r.first != r.second && r.first->second == 4 && ++r.first == r.second); } { - auto r (m.find ("foo.fox")); + auto r (m.find_prefix ("foo.fox")); assert (r.first != r.second && r.first->second == 5 && ++r.first == r.second); } { - auto r (m.find ("foo")); + auto r (m.find_prefix ("foo")); assert (r.first != r.second && r.first->second == 2 && ++r.first != r.second && r.first->second == 4 && ++r.first != r.second && r.first->second == 5 && |