diff options
Diffstat (limited to 'libbuild2/parser.cxx')
-rw-r--r-- | libbuild2/parser.cxx | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index def4654..90c865b 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -49,7 +49,8 @@ namespace build2 class parser::enter_scope { public: - enter_scope (): p_ (nullptr), r_ (nullptr), s_ (nullptr), b_ (nullptr) {} + enter_scope () + : p_ (nullptr), r_ (nullptr), s_ (nullptr), b_ (nullptr) {} enter_scope (parser& p, dir_path&& d) : p_ (&p), r_ (p.root_), s_ (p.scope_), b_ (p.pbase_) @@ -75,7 +76,15 @@ namespace build2 if (n) d.normalize (); - p.switch_scope (d); + e_ = p.switch_scope (d); + } + + // As above but for already absolute and normalized directory. + // + enter_scope (parser& p, const dir_path& d, bool) + : p_ (&p), r_ (p.root_), s_ (p.scope_), b_ (p.pbase_) + { + e_ = p.switch_scope (d); } ~enter_scope () @@ -101,6 +110,7 @@ namespace build2 r_ = x.r_; s_ = x.s_; b_ = x.b_; + e_ = move (x.e_); x.p_ = nullptr; } return *this; @@ -114,6 +124,7 @@ namespace build2 scope* r_; scope* s_; const dir_path* b_; // Pattern base. + auto_project_env e_; }; class parser::enter_target @@ -269,6 +280,13 @@ namespace build2 pbase_ = scope_->src_path_; + // Note that root_ may not be a project root (see parse_export_stub()). + // + auto_project_env penv ( + stage_ != stage::boot && root_ != nullptr && root_->root_extra != nullptr + ? auto_project_env (*root_) + : auto_project_env ()); + if (path_->path != nullptr) enter_buildfile (*path_->path); // Note: needs scope_. @@ -2076,10 +2094,7 @@ namespace build2 // out the absolute buildfile path since we may switch the project // root and src_root with it (i.e., include into a sub-project). // - scope* ors (root_); - scope* ocs (scope_); - const dir_path* opb (pbase_); - switch_scope (out_base); + enter_scope sg (*this, out_base, true /* absolute & normalized */); if (root_ == nullptr) fail (l) << "out of project include from " << out_base; @@ -2095,9 +2110,6 @@ namespace build2 if (!root_->buildfiles.insert (p).second) // Note: may be "new" root. { l5 ([&]{trace (l) << "skipping already included " << p;}); - pbase_ = opb; - scope_ = ocs; - root_ = ors; continue; } @@ -2113,10 +2125,6 @@ namespace build2 { fail (l) << "unable to read buildfile " << p << ": " << e; } - - pbase_ = opb; - scope_ = ocs; - root_ = ors; } next_after_newline (t, tt); @@ -6896,11 +6904,13 @@ namespace build2 assert (pre_parse_); } - void parser:: + auto_project_env parser:: switch_scope (const dir_path& d) { tracer trace ("parser::switch_scope", &path_); + auto_project_env r; + // Switching the project during bootstrap can result in bizarre nesting // with unexpected loading order (e.g., config.build are loaded from inner // to outter rather than the expected reverse). On the other hand, it can @@ -6917,6 +6927,10 @@ namespace build2 if (proj && p.second != root_) { root_ = p.second; + + if (root_ != nullptr) + r = auto_project_env (*root_); + l5 ([&] { if (root_ != nullptr) @@ -6925,6 +6939,8 @@ namespace build2 trace << "switching to out of project scope"; }); } + + return r; } void parser:: |