From 9d6583056a82829f4512e6ba6a471a9b3e86a4a5 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 31 Jan 2017 15:17:28 +0200 Subject: Redo variable pattern-typing to match in more specific order --- build2/variable.cxx | 69 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 12 deletions(-) (limited to 'build2/variable.cxx') diff --git a/build2/variable.cxx b/build2/variable.cxx index 963eb0e..78f7c04 100644 --- a/build2/variable.cxx +++ b/build2/variable.cxx @@ -982,9 +982,29 @@ namespace build2 const variable_visibility*& v, const bool*& o) { - if (t == nullptr) t = p.type; else assert ( t == p.type); - if (v == nullptr) v = &p.visibility; else assert (*v == p.visibility); - if (o == nullptr) o = &p.overridable; else assert (*o == p.overridable); + if (p.type) + { + if (t == nullptr) + t = *p.type; + else if (p.match) + assert (t == *p.type); + } + + if (p.visibility) + { + if (v == nullptr) + v = &*p.visibility; + else if (p.match) + assert (*v == *p.visibility); + } + + if (p.overridable) + { + if (o == nullptr) + o = &*p.overridable; + else if (p.match) + assert (*o == *p.overridable); + } } const variable& variable_pool:: @@ -999,6 +1019,8 @@ namespace build2 // if (n.find ('.') != string::npos) { + // Reverse means from the "largest" (most specific). + // for (const pattern& p: reverse_iterate (patterns_)) { if (match_pattern (n, p.prefix, p.suffix, p.multi)) @@ -1034,9 +1056,11 @@ namespace build2 void variable_pool:: insert_pattern (const string& p, - const build2::value_type* t, - bool o, - variable_visibility v) + optional t, + optional o, + optional v, + bool retro, + bool match) { assert (!global_ || phase == run_phase::load); @@ -1066,17 +1090,38 @@ namespace build2 sfx.assign (p, w, sn); } + auto i ( + patterns_.insert ( + pattern {move (pfx), move (sfx), multi, match, t, v, o})); + // Apply retrospectively to existing variables. // - for (auto& p: map_) + if (retro) { - variable& var (p.second); + for (auto& p: map_) + { + variable& var (p.second); - if (match_pattern (var.name, pfx, sfx, multi)) - update (var, t, &v, &o); // Not changing the key. - } + if (match_pattern (var.name, i->prefix, i->suffix, i->multi)) + { + // Make sure that none of the existing more specific patterns + // match. + // + auto j (i), e (patterns_.end ()); + for (++j; j != e; ++j) + { + if (match_pattern (var.name, j->prefix, j->suffix, j->multi)) + break; + } - patterns_.push_back (pattern {move (pfx), move (sfx), multi, t, v, o}); + if (j == e) + update (var, + t ? *t : nullptr, + v ? &*v : nullptr, + o ? &*o : nullptr); // Not changing the key. + } + } + } } variable_pool variable_pool::instance (true); -- cgit v1.1