aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/algorithm.ixx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-12-03 10:59:34 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-12-03 10:59:34 +0200
commit548bdfb7bdd7c4761b58bed18b0032afc05b3ce4 (patch)
tree60394a7ffbfc7ff1509c9f9f62be6d66d8bea2ae /libbuild2/algorithm.ixx
parenta34582df17e2ca4a4e1b204152c82d935bca7467 (diff)
Add match_rule() in addition to match_recipe()
Diffstat (limited to 'libbuild2/algorithm.ixx')
-rw-r--r--libbuild2/algorithm.ixx36
1 files changed, 32 insertions, 4 deletions
diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx
index 97a8519..eb20ad0 100644
--- a/libbuild2/algorithm.ixx
+++ b/libbuild2/algorithm.ixx
@@ -221,14 +221,16 @@ namespace build2
}
inline target_lock
- lock (action a, const target& t)
+ lock (action a, const target& t, bool m)
{
- // We don't allow locking a target that has already been matched.
+ // We don't allow locking a target that has already been matched unless
+ // explicitly requested by the caller.
//
target_lock r (lock_impl (a, t, scheduler::work_none));
assert (!r ||
r.offset == target::offset_touched ||
- r.offset == target::offset_tried);
+ r.offset == target::offset_tried ||
+ (m && r.offset == target::offset_matched));
return r;
}
@@ -371,6 +373,17 @@ namespace build2
return r;
}
+ // Clear rule match-specific target data.
+ //
+ inline void
+ clear_target (action a, target& t)
+ {
+ t[a].vars.clear ();
+ t.prerequisite_targets[a].clear ();
+ if (a.inner ())
+ t.clear_data ();
+ }
+
inline void
set_recipe (target_lock& l, recipe&& r)
{
@@ -414,13 +427,28 @@ namespace build2
inline void
match_recipe (target_lock& l, recipe r)
{
- assert (l.target != nullptr && l.target->ctx.phase == run_phase::match);
+ assert (l.target != nullptr &&
+ l.offset != target::offset_matched &&
+ l.target->ctx.phase == run_phase::match);
+ clear_target (l.action, *l.target);
(*l.target)[l.action].rule = nullptr; // No rule.
set_recipe (l, move (r));
l.offset = target::offset_applied;
}
+ inline void
+ match_rule (target_lock& l, const rule_match& r)
+ {
+ assert (l.target != nullptr &&
+ l.offset != target::offset_matched &&
+ l.target->ctx.phase == run_phase::match);
+
+ clear_target (l.action, *l.target);
+ (*l.target)[l.action].rule = &r;
+ l.offset = target::offset_matched;
+ }
+
inline recipe
match_delegate (action a, target& t, const rule& dr, bool try_match)
{