From c5feaaf745421f2ecda672585c462cf4c807d25d Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 31 May 2021 12:37:59 +0200 Subject: Only pass target to recipe_text() if recipe is not shared --- libbuild2/build/script/parser.cxx | 24 +++++++++++++++--------- libbuild2/build/script/parser.hxx | 5 +++-- libbuild2/build/script/parser.test.cxx | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) (limited to 'libbuild2/build') diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx index 372c622..063ec68 100644 --- a/libbuild2/build/script/parser.cxx +++ b/libbuild2/build/script/parser.cxx @@ -27,7 +27,7 @@ namespace build2 // script parser:: - pre_parse (const target& tg, const adhoc_actions& as, + pre_parse (const scope& bs, const target* tg, const adhoc_actions& as, istream& is, const path_name& pn, uint64_t line, optional diag, const location& diag_loc) { @@ -40,9 +40,9 @@ namespace build2 // The script shouldn't be able to modify the target/scopes. // - target_ = const_cast (&tg); + target_ = const_cast (tg); actions_ = &as; - scope_ = const_cast (&tg.base_scope ()); + scope_ = const_cast (tg != nullptr ? &tg->base_scope () : &bs); root_ = scope_->root_scope (); pbase_ = scope_->src_path_; @@ -583,10 +583,16 @@ namespace build2 parse_names_result pr; { - // During pre-parse, if the script name is not set manually, we - // suspend pre-parse, parse the command names for real and try to - // deduce the script name from the result. Otherwise, we continue to - // pre-parse and bail out after parsing the names. + // During pre-parse, if the script name is not set manually and we + // have the target, we suspend pre-parse, parse the command names + // for real and try to deduce the script name from the result. + // Otherwise, we continue to pre-parse and bail out after parsing + // the names. + // + // @@ TODO: maybe we could recognize literal names even if target + // is NULL (see the tests for some ugly recipes). But will need + // to be careful to still pick up ambiguity between literal and + // skipped due to target being NULL. // // Note that the later is not just an optimization since expansion // that wouldn't fail during execution may fail in this special @@ -607,7 +613,7 @@ namespace build2 // // This is also the reason why we add a diag frame. // - if (pre_parse_ && diag_weight_ != 4) + if (pre_parse_ && (diag_weight_ != 4 && target_ != nullptr)) { pre_parse_ = false; // Make parse_names() perform expansions. pre_parse_suspended_ = true; @@ -638,7 +644,7 @@ namespace build2 pre_parse_ = true; } - if (pre_parse_ && diag_weight_ == 4) + if (pre_parse_ && (diag_weight_ == 4 || target_ == nullptr)) return nullopt; } diff --git a/libbuild2/build/script/parser.hxx b/libbuild2/build/script/parser.hxx index 15429e3..af43e35 100644 --- a/libbuild2/build/script/parser.hxx +++ b/libbuild2/build/script/parser.hxx @@ -32,10 +32,11 @@ namespace build2 parser (context& c): build2::script::parser (c) {} // Note that the returned script object references the passed path - // name. + // name. Target is NULL if this recipe is shared among multiple + // targets. // script - pre_parse (const target&, const adhoc_actions& acts, + pre_parse (const scope&, const target*, const adhoc_actions& acts, istream&, const path_name&, uint64_t line, optional diag_name, const location& diag_loc); diff --git a/libbuild2/build/script/parser.test.cxx b/libbuild2/build/script/parser.test.cxx index 29711ef..c1ba1d1 100644 --- a/libbuild2/build/script/parser.test.cxx +++ b/libbuild2/build/script/parser.test.cxx @@ -208,7 +208,7 @@ namespace build2 parser p (ctx); path_name nm ("buildfile"); - script s (p.pre_parse (tt, acts, + script s (p.pre_parse (tt.base_scope (), &tt, acts, cin, nm, 11 /* line */, (m != mode::diag -- cgit v1.1