From e3e597180487328a54721e2afb95e33ed853d586 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 1 Feb 2017 16:36:24 +0200 Subject: Pass const scope& where modification should not happen --- build2/config/init.cxx | 7 ++-- build2/config/operation.cxx | 95 +++++++++++++++++++++++++++++---------------- 2 files changed, 66 insertions(+), 36 deletions(-) (limited to 'build2/config') diff --git a/build2/config/init.cxx b/build2/config/init.cxx index a73c394..682d817 100644 --- a/build2/config/init.cxx +++ b/build2/config/init.cxx @@ -75,7 +75,7 @@ namespace build2 { // Assume missing version is 0. // - auto p (extract_variable (f, c_v)); + auto p (extract_variable (rs, f, c_v)); uint64_t v (p.second ? cast (p.first) : 0); if (v != module::version) @@ -127,9 +127,10 @@ namespace build2 // { // We need this rule for out-of-any-project dependencies (e.g., - // libraries imported from /usr/lib). + // libraries imported from /usr/lib). Registring it on the global + // scope smells a bit but seems harmless. // - global_scope->rules.insert ( + rs.global ().rules.insert ( configure_id, 0, "config.file", file_rule::instance); auto& r (rs.rules); diff --git a/build2/config/operation.cxx b/build2/config/operation.cxx index 63e6d9b..75f5abc 100644 --- a/build2/config/operation.cxx +++ b/build2/config/operation.cxx @@ -61,8 +61,10 @@ namespace build2 } } + using project_set = set; // Use pointers to get comparison. + static void - save_config (scope& root, const set& projects) + save_config (const scope& root, const project_set& projects) { const dir_path& out_root (root.out_path ()); path f (out_root / config_file); @@ -137,7 +139,7 @@ namespace build2 // root. // bool found (false); - scope* r (&root); + const scope* r (&root); while ((r = r->parent_scope ()->root_scope ()) != nullptr) { if (l.belongs (*r)) @@ -282,7 +284,7 @@ namespace build2 } static void - configure_project (action a, scope& root, set& projects) + configure_project (action a, const scope& root, project_set& projects) { tracer trace ("configure_project"); @@ -331,7 +333,7 @@ namespace build2 { const dir_path& pd (p.second); dir_path out_nroot (out_root / pd); - scope& nroot (scopes.find (out_nroot)); + const scope& nroot (scopes.find (out_nroot)); // @@ Strictly speaking we need to check whether the config // module was loaded for this subproject. @@ -358,7 +360,7 @@ namespace build2 // callbacks here since the meta operation is configure and we // know what we are doing. // - set projects; + project_set projects; // Note that we cannot do this in parallel. We cannot parallelize the // outer loop because we should match for a single action at a time. @@ -371,7 +373,7 @@ namespace build2 for (void* v: ts) { target& t (*static_cast (v)); - scope* rs (t.base_scope ().root_scope ()); + const scope* rs (t.base_scope ().root_scope ()); if (rs == nullptr) fail << "out of project target " << t; @@ -423,7 +425,45 @@ namespace build2 } static void - disfigure_load (scope&, + load_project (scope& root) + { + if (auto l = root.vars[var_subprojects]) + { + const dir_path& out_root (root.out_path ()); + const dir_path& src_root (root.src_path ()); + + for (auto p: cast (l)) + { + const dir_path& pd (p.second); + + // Create and bootstrap subproject's root scope. + // + dir_path out_nroot (out_root / pd); + + // The same logic for src_root as in create_bootstrap_inner(). + // + scope& nroot (create_root (root, out_nroot, dir_path ())); + + if (!bootstrapped (nroot)) + { + bootstrap_out (nroot); + + value& val (nroot.assign (var_src_root)); + + if (!val) + val = is_src_root (out_nroot) ? out_nroot : (src_root / pd); + + setup_root (nroot); + bootstrap_src (nroot); + } + + load_project (nroot); + } + } + } + + static void + disfigure_load (scope& root, const path& bf, const dir_path&, const dir_path&, @@ -431,17 +471,23 @@ namespace build2 { tracer trace ("disfigure_load"); l6 ([&]{trace << "skipping " << bf;}); + + // Since we don't load buildfiles during disfigure but still want to + // disfigure all the subprojects (see disfigure_project() below), we + // bootstrap all known subprojects. + // + load_project (root); } static void - disfigure_search (scope& root, + disfigure_search (const scope& root, const target_key&, const location&, action_targets& ts) { tracer trace ("disfigure_search"); l6 ([&]{trace << "collecting " << root.out_path ();}); - ts.push_back (&root); + ts.push_back (const_cast (&root)); //@@ MT TMP action_targets } static void @@ -450,7 +496,7 @@ namespace build2 } static bool - disfigure_project (action a, scope& root, set& projects) + disfigure_project (action a, const scope& root, project_set& projects) { tracer trace ("disfigure_project"); @@ -473,27 +519,9 @@ namespace build2 for (auto p: cast (l)) { const dir_path& pd (p.second); - - // Create and bootstrap subproject's root scope. - // dir_path out_nroot (out_root / pd); - - // The same logic for src_root as in create_bootstrap_inner(). - // - scope& nroot (create_root (out_nroot, dir_path ())); - - if (!bootstrapped (nroot)) - { - bootstrap_out (nroot); - - value& val (nroot.assign (var_src_root)); - - if (!val) - val = is_src_root (out_nroot) ? out_nroot : (src_root / pd); - - setup_root (nroot); - bootstrap_src (nroot); - } + const scope& nroot (scopes.find (out_nroot)); + assert (nroot.out_path () == out_nroot); // See disfigure_load(). m = disfigure_project (a, nroot, projects) || m; @@ -565,13 +593,14 @@ namespace build2 { tracer trace ("disfigure_execute"); - set projects; + project_set projects; - // Note: doing everything in the load phase. + // Note: doing everything in the load phase (disfigure_project () does + // modify the model). // for (void* v: ts) { - scope& root (*static_cast (v)); + const scope& root (*static_cast (v)); if (!disfigure_project (a, root, projects)) { -- cgit v1.1