aboutsummaryrefslogtreecommitdiff
path: root/build/target.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-07-31 12:52:20 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-07-31 12:52:20 +0200
commitbbd0f3bb21442a2833916110cbe8e9a07e9f4c1f (patch)
treed25de6f2bcfa4b6cabe1fd55a1b8f508005de4c1 /build/target.cxx
parent729b56300c441a0d63c7d2013eb5a881211d352b (diff)
Essential install module functionality
Diffstat (limited to 'build/target.cxx')
-rw-r--r--build/target.cxx122
1 files changed, 88 insertions, 34 deletions
diff --git a/build/target.cxx b/build/target.cxx
index cdcc6b0..c1c5ef4 100644
--- a/build/target.cxx
+++ b/build/target.cxx
@@ -76,59 +76,68 @@ namespace build
value_proxy target::
operator[] (const variable& var) const
{
- auto i (vars.find (var));
+ auto find = [&var] (const variable_map& vars)
+ {
+ auto i (vars.find (var));
+ return i != vars.end () ? &const_cast<value_ptr&> (i->second) : nullptr;
+ };
- if (i != vars.end ())
- // @@ Same issue as in variable_map: need ro_value_proxy.
- return value_proxy (&const_cast<value_ptr&> (i->second), &vars);
+ if (auto p = find (vars))
+ return value_proxy (p, &vars);
if (group != nullptr)
- return (*group)[var];
+ {
+ if (auto p = find (group->vars))
+ return value_proxy (p, &group->vars);
+ }
// Cannot simply delegate to scope's operator[] since we also
// need to check target type/pattern-specific variables.
//
- const target_type& btt (type ());
-
for (const scope* s (&base_scope ()); s != nullptr; s = s->parent_scope ())
{
if (!s->target_vars.empty ())
{
- // Search across target type hierarchy.
- //
- for (auto tt (&btt); tt != nullptr; tt = tt->base)
+ auto find_specific = [&find, s] (const target& t) -> value_proxy
{
- auto i (s->target_vars.find (*tt));
-
- if (i == s->target_vars.end ())
- continue;
+ // Search across target type hierarchy.
+ //
+ for (auto tt (&t.type ()); tt != nullptr; tt = tt->base)
+ {
+ auto i (s->target_vars.find (*tt));
- //@@ TODO: match pattern. For now, we only handle '*'.
+ if (i == s->target_vars.end ())
+ continue;
- auto j (i->second.find ("*"));
+ //@@ TODO: match pattern. For now, we only handle '*'.
- if (j == i->second.end ())
- continue;
+ auto j (i->second.find ("*"));
- auto k (j->second.find (var));
+ if (j == i->second.end ())
+ continue;
- if (k != j->second.end ())
- {
- // Note that we use the scope's vars, not from target_vars.
- // We use it to identify whether the variable belongs to a
- // specific scope/target.
- //
- return value_proxy (&const_cast<value_ptr&> (k->second), &s->vars);
+ if (auto p = find (j->second))
+ return value_proxy (p, &j->second);
}
+
+ return value_proxy ();
+ };
+
+ if (auto p = find_specific (*this))
+ return p;
+
+ if (group != nullptr)
+ {
+ if (auto p = find_specific (*group))
+ return p;
}
}
- auto i (s->vars.find (var));
- if (i != s->vars.end ())
- return value_proxy (&const_cast<value_ptr&> (i->second), &s->vars);
+ if (auto p = find (s->vars))
+ return value_proxy (p, &s->vars);
}
- return value_proxy (nullptr, nullptr);
+ return value_proxy ();
}
value_proxy target::
@@ -387,6 +396,7 @@ namespace build
false
};
+ template <typename T>
static target*
file_factory (dir_path d, string n, const string* e)
{
@@ -394,9 +404,9 @@ namespace build
// wasn't specified, set it to empty rather than unspecified.
// In other words, we always treat file{foo} as file{foo.}.
//
- return new file (move (d),
- move (n),
- (e != nullptr ? e : &extension_pool.find ("")));
+ return new T (move (d),
+ move (n),
+ (e != nullptr ? e : &extension_pool.find ("")));
}
constexpr const char file_ext[] = "";
@@ -405,7 +415,7 @@ namespace build
typeid (file),
"file",
&path_target::static_type,
- &file_factory,
+ &file_factory<file>,
&target_extension_fix<file_ext>,
&search_file,
false
@@ -443,4 +453,48 @@ namespace build
&search_target,
false
};
+
+ constexpr const char doc_ext[] = "";
+ const target_type doc::static_type
+ {
+ typeid (doc),
+ "doc",
+ &file::static_type,
+ &file_factory<doc>,
+ &target_extension_fix<doc_ext>,
+ &search_file,
+ false
+ };
+
+ static target*
+ man_factory (dir_path d, string n, const string* e)
+ {
+ if (e == nullptr)
+ fail << "man target '" << n << "' must include extension (man section)";
+
+ return new man (move (d), move (n), e);
+ }
+
+ const target_type man::static_type
+ {
+ typeid (man),
+ "man",
+ &doc::static_type,
+ &man_factory,
+ nullptr, // Should be specified explicitly.
+ &search_file,
+ false
+ };
+
+ constexpr const char man1_ext[] = "1";
+ const target_type man1::static_type
+ {
+ typeid (man1),
+ "man1",
+ &man::static_type,
+ &file_factory<man1>,
+ &target_extension_fix<man1_ext>,
+ &search_file,
+ false
+ };
}