From 97e00dccb4a9d3abc3c896b33560ed6aed0a1763 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 26 Aug 2019 10:01:32 +0200 Subject: Factor target name processing code from parser to scope --- libbuild2/parser.cxx | 54 ++++------------------------------------------- libbuild2/scope.cxx | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libbuild2/scope.hxx | 21 +++++++++++++++++++ libbuild2/scope.ixx | 7 +++++++ 4 files changed, 91 insertions(+), 50 deletions(-) diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 2af5762..5e5b029 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -128,8 +128,8 @@ namespace build2 const location& loc, tracer& tr) { - auto r (process_target (p, n, o, loc)); - return p.ctx.targets.insert (*r.first, // target type + auto r (p.scope_->find_target_type (n, o, loc)); + return p.ctx.targets.insert (r.first, // target type move (n.dir), move (o.dir), move (n.value), @@ -147,8 +147,8 @@ namespace build2 const location& loc, tracer& tr) { - auto r (process_target (p, n, o, loc)); - return p.ctx.targets.find (*r.first, // target type + auto r (p.scope_->find_target_type (n, o, loc)); + return p.ctx.targets.find (r.first, // target type n.dir, o.dir, n.value, @@ -156,52 +156,6 @@ namespace build2 tr); } - static pair> - process_target (parser& p, - name& n, // If n.pair, then o is out dir. - name& o, - const location& loc) - { - auto r (p.scope_->find_target_type (n, loc)); - - if (r.first == nullptr) - p.fail (loc) << "unknown target type " << n.type; - - bool src (n.pair); // If out-qualified, then it is from src. - if (src) - { - assert (n.pair == '@'); - - if (!o.directory ()) - p.fail (loc) << "expected directory after '@'"; - } - - dir_path& d (n.dir); - - const dir_path& sd (p.scope_->src_path ()); - const dir_path& od (p.scope_->out_path ()); - - if (d.empty ()) - d = src ? sd : od; // Already dormalized. - else - { - if (d.relative ()) - d = (src ? sd : od) / d; - - d.normalize (); - } - - dir_path out; - if (src && sd != od) // If in-source build, then out must be empty. - { - out = o.dir.relative () ? od / o.dir : move (o.dir); - out.normalize (); - } - o.dir = move (out); // Result. - - return r; - } - ~enter_target () { if (p_ != nullptr) diff --git a/libbuild2/scope.cxx b/libbuild2/scope.cxx index 8d5e37a..3974989 100644 --- a/libbuild2/scope.cxx +++ b/libbuild2/scope.cxx @@ -729,6 +729,65 @@ namespace build2 return make_pair (tt, move (ext)); } + pair> scope:: + find_target_type (name& n, name& o, const location& loc) const + { + auto r (find_target_type (n, loc)); + + if (r.first == nullptr) + fail (loc) << "unknown target type " << n.type; + + bool src (n.pair); // If out-qualified, then it is from src. + if (src) + { + assert (n.pair == '@'); + + if (!o.directory ()) + fail (loc) << "expected directory after '@'"; + } + + dir_path& d (n.dir); + + const dir_path& sd (src_path ()); + const dir_path& od (out_path ()); + + if (d.empty ()) + d = src ? sd : od; // Already dormalized. + else + { + if (d.relative ()) + d = (src ? sd : od) / d; + + d.normalize (); + } + + dir_path out; + if (src && sd != od) // If in-source build, then out must be empty. + { + out = o.dir.relative () ? od / o.dir : move (o.dir); + out.normalize (); + } + o.dir = move (out); // Result. + + return pair> ( + *r.first, move (r.second)); + } + + target_key scope:: + find_target_key (names& ns, const location& loc) const + { + if (size_t n = ns.size ()) + { + if (n == (ns[0].pair ? 2 : 1)) + { + name dummy; + return find_target_key (ns[0], n == 2 ? ns[1] : dummy, loc); + } + } + + fail (loc) << "invalid target name: " << ns; + } + static target* derived_tt_factory (context& c, const target_type& t, dir_path d, dir_path o, string n) diff --git a/libbuild2/scope.hxx b/libbuild2/scope.hxx index 08eb06b..b29a981 100644 --- a/libbuild2/scope.hxx +++ b/libbuild2/scope.hxx @@ -248,6 +248,27 @@ namespace build2 pair> find_target_type (name&, const location&) const; + // As above but process the potentially out-qualified target name further + // by completing (relative to this scope) and normalizing the directories + // and also issuing appropriate diagnostics if the target type is unknown. + // If the first argument has the pair flag true, then the second should be + // the out directory. + // + pair> + find_target_type (name&, name&, const location&) const; + + // As above, but return the result as a target key (with its members + // shallow-pointing to processed parts in the two names). + // + target_key + find_target_key (name&, name&, const location&) const; + + // As above, but the names are passed as a vector. Issue appropriate + // diagnostics if the wrong number of names is passed. + // + target_key + find_target_key (names&, const location&) const; + // Dynamically derive a new target type from an existing one. Return the // reference to the target type and an indicator of whether it was // actually created. diff --git a/libbuild2/scope.ixx b/libbuild2/scope.ixx index 14907d3..5ce0a73 100644 --- a/libbuild2/scope.ixx +++ b/libbuild2/scope.ixx @@ -52,6 +52,13 @@ namespace build2 return false; } + inline target_key scope:: + find_target_key (name& n, name& o, const location& loc) const + { + auto p (find_target_type (n, o, loc)); + return target_key {&p.first, &n.dir, &o.dir, &n.value, move (p.second)}; + } + inline dir_path src_out (const dir_path& out, const scope& r) { -- cgit v1.1