diff options
Diffstat (limited to 'libbuild2/version/rule.cxx')
-rw-r--r-- | libbuild2/version/rule.cxx | 71 |
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:: |