diff options
-rw-r--r-- | libbuild2/target.cxx | 30 | ||||
-rw-r--r-- | libbuild2/target.hxx | 10 |
2 files changed, 34 insertions, 6 deletions
diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx index b4c3968..bef7dce 100644 --- a/libbuild2/target.cxx +++ b/libbuild2/target.cxx @@ -143,7 +143,8 @@ namespace build2 pair<lookup, size_t> target:: lookup_original (const variable& var, bool target_only, - const scope* bs) const + const scope* bs, + bool locked) const { pair<lookup_type, size_t> r (lookup_type (), 0); @@ -204,9 +205,14 @@ namespace build2 { if (!target_only) { - target_key tk (key ()); - target_key g1k (g1 != nullptr ? g1->key () : target_key {}); - target_key g2k (g2 != nullptr ? g2->key () : target_key {}); + auto key = [locked] (const target* t) + { + return locked ? t->key_locked () : t->key (); + }; + + target_key tk (key (this)); + target_key g1k (g1 != nullptr ? key (g1) : target_key {}); + target_key g2k (g2 != nullptr ? key (g2) : target_key {}); if (bs == nullptr) bs = &base_scope (); @@ -247,6 +253,22 @@ namespace build2 return r; } + value& target:: + append_locked (const variable& var) + { + auto l (lookup_original (var, false, nullptr, true /* locked */).first); + + if (l.defined () && l.belongs (*this)) // Existing var in this target. + return vars.modify (l); // Ok since this is original. + + value& r (assign (var)); // NULL. + + if (l.defined ()) + r = *l; // Copy value (and type) from the outer scope. + + return r; + } + pair<lookup, size_t> target::opstate:: lookup_original (const variable& var, bool target_only) const { diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index 46c0949..5283ab8 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -782,12 +782,14 @@ namespace build2 // If target_only is true, then only look in target and its target group // without continuing in scopes. As an optimization, the caller can also - // pass the base scope of the target, if already known. + // pass the base scope of the target, if already known. If locked is true, + // assume the targets mutex is locked. // pair<lookup_type, size_t> lookup_original (const variable&, bool target_only = false, - const scope* bs = nullptr) const; + const scope* bs = nullptr, + bool locked = false) const; // Return a value suitable for assignment. See scope for details. // @@ -802,6 +804,10 @@ namespace build2 value& append (const variable&); + // As above but assume the targets mutex is locked. + // + value& + append_locked (const variable&); // Rule hints. // |