aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/target.cxx30
-rw-r--r--libbuild2/target.hxx10
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.
//