From 9689e2bafcf9af511df1f357aa3f6ec8545d0010 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 8 Feb 2022 14:32:41 +0200 Subject: Don't skip empty see-through target groups --- libbuild2/target.hxx | 20 +++++++++++++++----- libbuild2/target.ixx | 19 +++++++++++++++++++ libbuild2/target.txx | 33 --------------------------------- 3 files changed, 34 insertions(+), 38 deletions(-) diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index 4ce871b..76c01b6 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -1144,10 +1144,19 @@ namespace build2 // See-through group members iteration mode. Ad hoc members must always // be entered explicitly. // + // Note that if the group is empty, then we see the group itself (rather + // than nothing). Failed that, an empty group would never be executed (e.g., + // during clean) since there is no member to trigger the group execution. + // Other than that, it feels like seeing the group in this cases should be + // harmless (i.e., rules are generally prepared to see prerequisites they + // don't recognize). + // enum class members_mode { - always, // Iterate over members, assert if not resolvable. - maybe, // Iterate over members if resolvable, group otherwise. + always, // Iterate over members if not empty, group if empty, assert if + // not resolvable. + maybe, // Iterate over members if resolvable and not empty, group + // otherwise. never // Iterate over group (can still use enter_group()). }; @@ -1200,9 +1209,10 @@ namespace build2 leave_group (); // Iterate over this group's members. Return false if the member - // information is not available. Similar to leave_group(), you should - // increment the iterator after calling this function (provided it - // returned true). + // information is not available (note: return true if the group is + // empty). Similar to leave_group(), you should increment the iterator + // after calling this function provided group() returns true (see + // below). // bool enter_group (); diff --git a/libbuild2/target.ixx b/libbuild2/target.ixx index cfc3847..fddf1b2 100644 --- a/libbuild2/target.ixx +++ b/libbuild2/target.ixx @@ -456,6 +456,25 @@ namespace build2 } template + inline void prerequisite_members_range::iterator:: + switch_mode () + { + g_ = resolve_members (*i_); + + if (g_.members != nullptr) + { + // See empty see through groups as groups. + // + for (j_ = 1; j_ <= g_.count && g_.members[j_ - 1] == nullptr; ++j_) ; + + if (j_ > g_.count) + g_.count = 0; + } + else + assert (r_->mode_ != members_mode::always); // Group can't be resolved. + } + + template inline auto prerequisite_members_range::iterator:: operator++ () -> iterator& { diff --git a/libbuild2/target.txx b/libbuild2/target.txx index 5b48ad1..1363935 100644 --- a/libbuild2/target.txx +++ b/libbuild2/target.txx @@ -8,39 +8,6 @@ namespace build2 { - // prerequisite_members_range - // - template - void prerequisite_members_range::iterator:: - switch_mode () - { - // A group could be empty, so we may have to iterate. - // - do - { - g_ = resolve_members (*i_); - - // Group could not be resolved. - // - if (g_.members == nullptr) - { - assert (r_->mode_ != members_mode::always); - return; - } - - // Skip empty see through groups. - // - for (j_ = 1; j_ <= g_.count && g_.members[j_ - 1] == nullptr; ++j_) ; - if (j_ <= g_.count) - break; - - g_.count = 0; - } - while (++i_ != r_->e_ && i_->type.see_through); - } - - // - // template const char* target_extension_fix (const target_key& tk, const scope*) -- cgit v1.1