aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/build/script
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-05-31 12:37:59 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-05-31 13:00:43 +0200
commitad7b8477f177355e50b411b7296ae2e392d7a4be (patch)
tree61339754654e5bb11db585c2954e237d607afac5 /libbuild2/build/script
parent73a64baac30f5c478201e9f86dc4dd5ef85f0192 (diff)
Only pass target to recipe_text() if recipe is not shared
Diffstat (limited to 'libbuild2/build/script')
-rw-r--r--libbuild2/build/script/parser.cxx24
-rw-r--r--libbuild2/build/script/parser.hxx5
-rw-r--r--libbuild2/build/script/parser.test.cxx2
3 files changed, 19 insertions, 12 deletions
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<string> 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<target*> (&tg);
+ target_ = const_cast<target*> (tg);
actions_ = &as;
- scope_ = const_cast<scope*> (&tg.base_scope ());
+ scope_ = const_cast<scope*> (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<string> 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