aboutsummaryrefslogtreecommitdiff
path: root/build2/target.txx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/target.txx')
-rw-r--r--build2/target.txx81
1 files changed, 77 insertions, 4 deletions
diff --git a/build2/target.txx b/build2/target.txx
index f885e80..dd087c0 100644
--- a/build2/target.txx
+++ b/build2/target.txx
@@ -46,13 +46,43 @@ namespace build2
return string (ext);
}
- template <const char* var, const char* def>
- optional<string>
- target_extension_var (const target_key& tk, const scope& s, bool)
+ template <const char* ext>
+ bool
+ target_pattern_fix (const target_type&, const scope&, string& v, bool r)
+ {
+ size_t p (path::traits::find_extension (v));
+
+ if (r)
+ {
+ // If we get called to reverse then it means we've added the extension
+ // in the first place. So simply strip it.
+ //
+ assert (p != string::npos);
+ v.resize (p);
+ }
+ //
+ // We only add our extension if there isn't one already.
+ //
+ else if (p == string::npos)
+ {
+ v += '.';
+ v += ext;
+ return true;
+ }
+
+ return false;
+ }
+
+ inline optional<string>
+ target_extension_var (const target_type& tt,
+ const string& tn,
+ const scope& s,
+ const char* var,
+ const char* def)
{
// Include target type/pattern-specific variables.
//
- if (auto l = s.find (var_pool[var], tk))
+ if (auto l = s.find (var_pool[var], tt, tn))
{
// Help the user here and strip leading '.' from the extension.
//
@@ -62,4 +92,47 @@ namespace build2
return def != nullptr ? optional<string> (def) : nullopt;
}
+
+ template <const char* var, const char* def>
+ optional<string>
+ target_extension_var (const target_key& tk, const scope& s, bool)
+ {
+ return target_extension_var (*tk.type, *tk.name, s, var, def);
+ }
+
+ template <const char* var, const char* def>
+ bool
+ target_pattern_var (const target_type& tt, const scope& s, string& v, bool r)
+ {
+ size_t p (path::traits::find_extension (v));
+
+ if (r)
+ {
+ // If we get called to reverse then it means we've added the extension
+ // in the first place. So simply strip it.
+ //
+ assert (p != string::npos);
+ v.resize (p);
+ }
+ //
+ // We only add our extension if there isn't one already.
+ //
+ else if (p == string::npos)
+ {
+ // Use empty name as a target since we only want target type/pattern-
+ // specific variables that match any target (e.g., '*' but not '*.txt').
+ //
+ if (auto e = target_extension_var (tt, string (), s, var, def))
+ {
+ if (!e->empty ()) // Don't add empty extension (means no extension).
+ {
+ v += '.';
+ v += *e;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
}