aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/version/rule.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/version/rule.cxx')
-rw-r--r--libbuild2/version/rule.cxx71
1 files changed, 53 insertions, 18 deletions
diff --git a/libbuild2/version/rule.cxx b/libbuild2/version/rule.cxx
index 919dfcf..65c1117 100644
--- a/libbuild2/version/rule.cxx
+++ b/libbuild2/version/rule.cxx
@@ -46,12 +46,31 @@ namespace build2
// in_rule
//
+
+ // Wrap the in::rule's perform_update recipe into a data-carrying recipe.
+ //
+ // To optimize this a bit further (i.e., to avoid the dynamic memory
+ // allocation) we are going to call in::rule::perform_update() directly
+ // (after all it's virtual and thus part of the in_rule's interface).
+ //
+ struct match_data
+ {
+ const module& mod;
+ const in_rule& rule;
+
+ target_state
+ operator() (action a, const target& t)
+ {
+ return rule.perform_update (a, t);
+ }
+ };
+
bool in_rule::
- match (action a, target& xt, const string&) const
+ match (action a, target& xt) const
{
tracer trace ("version::in_rule::match");
- file& t (static_cast<file&> (xt));
+ file& t (xt.as<file> ());
const scope& rs (t.root_scope ());
bool fm (false); // Found manifest.
@@ -74,14 +93,26 @@ namespace build2
if (!fi)
l5 ([&]{trace << "no in file prerequisite for target " << t;});
- bool r (fm && fi);
-
- // If we match, lookup and cache the module for the update operation.
+ // If we match, derive the file name early as recommended by the in
+ // rule.
//
- if (r && a == perform_update_id)
- t.data (rs.find_module<module> (module::name));
+ if (fm && fi)
+ t.derive_path ();
- return r;
+ return fm && fi;
+ }
+
+ recipe in_rule::
+ apply (action a, target& t) const
+ {
+ recipe r (rule::apply (a, t));
+
+ // Lookup and cache the module for the update operation.
+ //
+ return a == perform_update_id
+ ? match_data {*t.root_scope ().find_module<module> (module::name),
+ *this}
+ : move (r);
}
string in_rule::
@@ -89,12 +120,16 @@ namespace build2
action a,
const target& t,
const string& n,
+ optional<uint64_t> flags,
+ const substitution_map* smap,
const optional<string>& null) const
{
+ assert (!flags);
+
// Note that this code will be executed during up-to-date check for each
// substitution so let's try not to do anything overly sub-optimal here.
//
- const module& m (*t.data<const module*> ());
+ const module& m (t.data<match_data> (a).mod);
// Split it into the package name and the variable/condition name.
//
@@ -110,7 +145,7 @@ namespace build2
a,
t,
p == string::npos ? n : string (n, p + 1),
- null);
+ nullopt, smap, null);
}
string pn (n, 0, p);
@@ -212,13 +247,13 @@ namespace build2
if (mav->snapshot ())
{
- r += (p ? "(" : "");
+ if (p) r += '(';
r += cmp (vm, " < ", mav->version) + " || (";
r += cmp (vm, " == ", mav->version) + " && ";
- r += cmp (sm, (mao ? " < " : " <= "), mav->snapshot_sn) + ")";
+ r += cmp (sm, (mao ? " < " : " <= "), mav->snapshot_sn) + ')';
- r += (p ? ")" : "");
+ if (p) r += ')';
}
else
r = cmp (vm, (mao ? " < " : " <= "), mav->version);
@@ -232,13 +267,13 @@ namespace build2
if (miv->snapshot ())
{
- r += (p ? "(" : "");
+ if (p) r += '(';
r += cmp (vm, " > ", miv->version) + " || (";
r += cmp (vm, " == ", miv->version) + " && ";
- r += cmp (sm, (mio ? " > " : " >= "), miv->snapshot_sn) + ")";
+ r += cmp (sm, (mio ? " > " : " >= "), miv->snapshot_sn) + ')';
- r += (p ? ")" : "");
+ if (p) r += ')';
}
else
r = cmp (vm, (mio ? " > " : " >= "), miv->version);
@@ -298,7 +333,7 @@ namespace build2
// manifest_install_rule
//
bool manifest_install_rule::
- match (action a, target& t, const string&) const
+ match (action a, target& t) const
{
// We only match project's manifest.
//
@@ -311,7 +346,7 @@ namespace build2
if (s.root_scope () != &s || s.src_path () != t.dir)
return false;
- return file_rule::match (a, t, "");
+ return file_rule::match (a, t);
}
auto_rmfile manifest_install_rule::