aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-09-15 10:25:15 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-09-15 10:25:15 +0200
commitb8d4cb75ca4f6214a0cac22c96691e770d5940d9 (patch)
tree88823f4c2aa070849fc8a089fc6d40af58bc0523
parentef2fdd0e104494c1a5beee51521563d013a3b3cc (diff)
Do variable lookup in ad hoc target groups
-rw-r--r--libbuild2/scope.cxx33
-rw-r--r--libbuild2/scope.hxx3
-rw-r--r--libbuild2/target.cxx29
-rw-r--r--libbuild2/target.hxx9
4 files changed, 52 insertions, 22 deletions
diff --git a/libbuild2/scope.cxx b/libbuild2/scope.cxx
index 39aba8f..93f21db 100644
--- a/libbuild2/scope.cxx
+++ b/libbuild2/scope.cxx
@@ -46,10 +46,12 @@ namespace build2
pair<lookup, size_t> scope::
lookup_original (const variable& var,
const target_key* tk,
- const target_key* gk,
+ const target_key* g1k,
+ const target_key* g2k,
size_t start_d) const
{
assert (tk != nullptr || var.visibility != variable_visibility::target);
+ assert (g2k == nullptr || g1k != nullptr);
size_t d (0);
@@ -61,7 +63,8 @@ namespace build2
auto pre_app = [&var, this] (lookup_type& l,
const scope* s,
const target_key* tk,
- const target_key* gk,
+ const target_key* g1k,
+ const target_key* g2k,
string n)
{
const value& v (*l);
@@ -76,7 +79,7 @@ namespace build2
// group, then we shouldn't be looking for stem in the target's
// variables. In other words, once we "jump" to group, we stay there.
//
- lookup_type stem (s->lookup_original (var, tk, gk, 2).first);
+ lookup_type stem (s->lookup_original (var, tk, g1k, g2k, 2).first);
// Check the cache.
//
@@ -140,7 +143,8 @@ namespace build2
// the copy.
//
optional<string> tn;
- optional<string> gn;
+ optional<string> g1n;
+ optional<string> g2n;
for (const scope* s (this); s != nullptr; )
{
@@ -159,7 +163,7 @@ namespace build2
if (l.defined ())
{
if (l->extra != 0) // Prepend/append?
- pre_app (l, s, tk, gk, move (*tn));
+ pre_app (l, s, tk, g1k, g2k, move (*tn));
return make_pair (move (l), d);
}
@@ -170,17 +174,30 @@ namespace build2
//
if (++d >= start_d)
{
- if (f && gk != nullptr)
+ if (f && g1k != nullptr)
{
- lookup_type l (s->target_vars.find (*gk, var, gn));
+ lookup_type l (s->target_vars.find (*g1k, var, g1n));
if (l.defined ())
{
if (l->extra != 0) // Prepend/append?
- pre_app (l, s, gk, nullptr, move (*gn));
+ pre_app (l, s, g1k, g2k, nullptr, move (*g1n));
return make_pair (move (l), d);
}
+
+ if (g2k != nullptr)
+ {
+ l = s->target_vars.find (*g2k, var, g2n);
+
+ if (l.defined ())
+ {
+ if (l->extra != 0) // Prepend/append?
+ pre_app (l, s, g2k, nullptr, nullptr, move (*g2n));
+
+ return make_pair (move (l), d);
+ }
+ }
}
}
}
diff --git a/libbuild2/scope.hxx b/libbuild2/scope.hxx
index b83f699..97c7be5 100644
--- a/libbuild2/scope.hxx
+++ b/libbuild2/scope.hxx
@@ -181,7 +181,8 @@ namespace build2
pair<lookup_type, size_t>
lookup_original (const variable&,
const target_key* tk = nullptr,
- const target_key* gk = nullptr,
+ const target_key* g1k = nullptr,
+ const target_key* g2k = nullptr,
size_t start_depth = 1) const;
pair<lookup_type, size_t>
diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx
index 24ad01e..7db5c66 100644
--- a/libbuild2/target.cxx
+++ b/libbuild2/target.cxx
@@ -159,22 +159,29 @@ namespace build2
r.first = lookup_type (*p.first, p.second, vars);
}
- const target* g (nullptr);
+ const target* g1 (nullptr);
+ const target* g2 (nullptr);
if (!r.first)
{
++r.second;
- // Skip looking up in the ad hoc group, which is semantically the
- // first/primary member.
+ // In case of an ad hoc group, we may have to look in two groups.
//
- if ((g = group == nullptr
- ? nullptr
- : group->adhoc_group () ? group->group : group))
+ if ((g1 = group) != nullptr)
{
- auto p (g->vars.lookup (var));
+ auto p (g1->vars.lookup (var));
if (p.first != nullptr)
- r.first = lookup_type (*p.first, p.second, g->vars);
+ r.first = lookup_type (*p.first, p.second, g1->vars);
+ else
+ {
+ if ((g2 = g1->group) != nullptr)
+ {
+ auto p (g2->vars.lookup (var));
+ if (p.first != nullptr)
+ r.first = lookup_type (*p.first, p.second, g2->vars);
+ }
+ }
}
}
@@ -185,14 +192,16 @@ namespace build2
if (!target_only)
{
target_key tk (key ());
- target_key gk (g != nullptr ? g->key () : target_key {});
+ target_key g1k (g1 != nullptr ? g1->key () : target_key {});
+ target_key g2k (g2 != nullptr ? g2->key () : target_key {});
if (bs == nullptr)
bs = &base_scope ();
auto p (bs->lookup_original (var,
&tk,
- g != nullptr ? &gk : nullptr));
+ g1 != nullptr ? &g1k : nullptr,
+ g2 != nullptr ? &g2k : nullptr));
r.first = move (p.first);
r.second = r.first ? r.second + p.second : p.second;
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index 21b5dab..8193f35 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -266,9 +266,6 @@ namespace build2
// - Ad hoc group cannot have sub-groups (of any kind) though an ad hoc
// group can be a sub-group of an explicit group.
//
- // - Member variable lookup skips the ad hoc group (since the group is the
- // first member, this is normally what we want).
- //
// Note that ad hoc groups can be part of explicit groups. In a sense, we
// have a two-level grouping: an explicit group with its members each of
// which can be an ad hoc group. For example, lib{} contains libs{} which
@@ -279,6 +276,9 @@ namespace build2
//
const_ptr<target> adhoc_member = nullptr;
+ // Return true if this target is an ad hoc group (that is, its primary
+ // member).
+ //
bool
adhoc_group () const
{
@@ -288,6 +288,9 @@ namespace build2
(group == nullptr || group->adhoc_member == nullptr);
}
+ // Return true if this target is an ad hoc group member (that is, its
+ // secondary member).
+ //
bool
adhoc_group_member () const
{