aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-08-26 10:01:32 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-08-26 10:01:32 +0200
commit97e00dccb4a9d3abc3c896b33560ed6aed0a1763 (patch)
treebd17e1fc480ea56232a0b4c6f22bb691bc61ee1d
parent8e0e8edb727a5367d991880b033eb13060f4c8eb (diff)
Factor target name processing code from parser to scope
-rw-r--r--libbuild2/parser.cxx54
-rw-r--r--libbuild2/scope.cxx59
-rw-r--r--libbuild2/scope.hxx21
-rw-r--r--libbuild2/scope.ixx7
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<const target_type*, optional<string>>
- 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<const target_type&, optional<string>> 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<const target_type&, optional<string>> (
+ *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<const target_type*, optional<string>>
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<const target_type&, optional<string>>
+ 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)
{