From e05f7c7383cc48823bd408c0bc5187191a9a1c48 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 23 May 2023 09:23:16 +0200 Subject: Explicit group: static members --- libbuild2/build/script/parser.cxx | 20 +++++++++++--------- libbuild2/build/script/parser.hxx | 18 ++++++++++++------ libbuild2/build/script/runner.cxx | 27 ++++++++++++++++++++++----- libbuild2/build/script/script.cxx | 24 ++++++++++++++++++++---- 4 files changed, 65 insertions(+), 24 deletions(-) (limited to 'libbuild2/build/script') diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx index e7268f9..c71f218 100644 --- a/libbuild2/build/script/parser.cxx +++ b/libbuild2/build/script/parser.cxx @@ -61,7 +61,7 @@ namespace build2 pbase_ = scope_->src_path_; - file_based_ = tt.is_a (); + file_based_ = tt.is_a () || tt.is_a (); perform_update_ = find (as.begin (), as.end (), perform_update_id) != as.end (); @@ -748,8 +748,8 @@ namespace build2 } if (!file_based_) - fail (l) << "'depdb' builtin can only be used for file-based " - << "targets"; + fail (l) << "'depdb' builtin can only be used for file- or " + << "file group-based targets"; if (!diag_preamble_.empty ()) fail (diag_loc ()) << "'diag' builtin call before 'depdb' call" << @@ -1287,7 +1287,7 @@ namespace build2 } void parser:: - exec_depdb_preamble (action a, const scope& bs, const file& t, + exec_depdb_preamble (action a, const scope& bs, const target& t, environment& e, const script& s, runner& r, lines_iterator begin, lines_iterator end, depdb& dd, @@ -1314,7 +1314,7 @@ namespace build2 action a; const scope& bs; - const file& t; + const target& t; environment& env; const script& scr; @@ -1360,7 +1360,7 @@ namespace build2 // exec_depdb_dyndep (t, tt, li, ll, - data.a, data.bs, const_cast (data.t), + data.a, data.bs, const_cast (data.t), data.dd, *data.dyn_targets, *data.update, @@ -1645,7 +1645,7 @@ namespace build2 void parser:: exec_depdb_dyndep (token& lt, build2::script::token_type& ltt, size_t li, const location& ll, - action a, const scope& bs, file& t, + action a, const scope& bs, target& t, depdb& dd, paths& dyn_targets, bool& update, @@ -2455,6 +2455,8 @@ namespace build2 // if (ops.drop_cycles ()) { + // @@ TODO: expl + for (const target* m (&t); m != nullptr; m = m->adhoc_member) { if (ft == m) @@ -2874,7 +2876,7 @@ namespace build2 // that there are only real targets to start with. // optional> dts; - for (const target* m (&t); m != nullptr; m = m->adhoc_member) + for (const target* m (&t); m != nullptr; m = m->adhoc_member) // @@ TODO: expl { if (m->decl != target_decl::real) dts = vector (); @@ -2914,7 +2916,7 @@ namespace build2 // if (dts) { - for (target* p (&t); p->adhoc_member != nullptr; ) + for (target* p (&t); p->adhoc_member != nullptr; ) // @@ TODO: expl { target* m (p->adhoc_member); diff --git a/libbuild2/build/script/parser.hxx b/libbuild2/build/script/parser.hxx index b615a90..856ad64 100644 --- a/libbuild2/build/script/parser.hxx +++ b/libbuild2/build/script/parser.hxx @@ -103,8 +103,10 @@ namespace build2 // runner's enter() function is called before the first preamble/body // command execution and leave() -- after the last command. // + // Note: target must be file or group. + // void - execute_depdb_preamble (action a, const scope& base, const file& t, + execute_depdb_preamble (action a, const scope& base, const target& t, environment& e, const script& s, runner& r, depdb& dd) { @@ -219,8 +221,10 @@ namespace build2 names exec_special (token&, build2::script::token_type&, bool skip_first); + // Note: target must be file or group. + // void - exec_depdb_preamble (action, const scope& base, const file&, + exec_depdb_preamble (action, const scope& base, const target&, environment&, const script&, runner&, lines_iterator begin, lines_iterator end, depdb&, @@ -230,10 +234,12 @@ namespace build2 bool* deferred_failure = nullptr, dyndep_byproduct* = nullptr); + // Note: target must be file or group. + // void exec_depdb_dyndep (token&, build2::script::token_type&, size_t line_index, const location&, - action, const scope& base, file&, + action, const scope& base, target&, depdb&, paths& dyn_targets, bool& update, @@ -276,9 +282,9 @@ namespace build2 script* script_; const small_vector* actions_; // Non-NULL during pre-parse. - // True if this script is for file-based targets and performing update - // is one of the actions, respectively. Only set for the pre-parse - // mode. + // True if this script is for file- or file group-based targets and + // performing update is one of the actions, respectively. Only set for + // the pre-parse mode. // bool file_based_; bool perform_update_; diff --git a/libbuild2/build/script/runner.cxx b/libbuild2/build/script/runner.cxx index c52ef66..e08ebbf 100644 --- a/libbuild2/build/script/runner.cxx +++ b/libbuild2/build/script/runner.cxx @@ -28,12 +28,29 @@ namespace build2 // for (auto i (env.cleanups.begin ()); i != env.cleanups.end (); ) { - const target* m (&env.target); - for (; m != nullptr; m = m->adhoc_member) + const target* m (nullptr); + if (const group* g = env.target.is_a ()) { - if (const path_target* pm = m->is_a ()) - if (i->path == pm->path ()) - break; + for (const target* gm: g->members) + { + if (const path_target* pm = gm->is_a ()) + { + if (i->path == pm->path ()) + { + m = gm; + break; + } + } + } + } + else + { + for (m = &env.target; m != nullptr; m = m->adhoc_member) + { + if (const path_target* pm = m->is_a ()) + if (i->path == pm->path ()) + break; + } } if (m != nullptr) diff --git a/libbuild2/build/script/script.cxx b/libbuild2/build/script/script.cxx index 9d9b5a8..0f31e7f 100644 --- a/libbuild2/build/script/script.cxx +++ b/libbuild2/build/script/script.cxx @@ -58,11 +58,27 @@ namespace build2 { // $> // + // What should it contain for an explicit group? While it may seem + // that just the members should be enough (and analogous to the ad + // hoc case), this won't let us get the group name for diagnostics. + // So the group name followed by all the members seems like the + // logical choice. + // names ns; - for (const target_type* m (&target); - m != nullptr; - m = m->adhoc_member) - m->as_name (ns); + + if (const group* g = target.is_a ()) + { + g->as_name (ns); + for (const target_type* m: g->members) + m->as_name (ns); + } + else + { + for (const target_type* m (&target); + m != nullptr; + m = m->adhoc_member) + m->as_name (ns); + } assign (var_ts) = move (ns); } -- cgit v1.1