diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2021-05-24 10:50:28 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2021-05-28 10:10:44 +0200 |
commit | 726aaab07a785b904dd1265bffa603bdd2a7665b (patch) | |
tree | ec28756d501ef3411b02a10a24dde76535e6581c /libbuild2/variable.cxx | |
parent | e1f472e471533330db05a42d5bcd4e99b211da0c (diff) |
Tie loose ends in target type/pattern-specific matching
Diffstat (limited to 'libbuild2/variable.cxx')
-rw-r--r-- | libbuild2/variable.cxx | 61 |
1 files changed, 56 insertions, 5 deletions
diff --git a/libbuild2/variable.cxx b/libbuild2/variable.cxx index 451cb76..6de0cfb 100644 --- a/libbuild2/variable.cxx +++ b/libbuild2/variable.cxx @@ -7,6 +7,7 @@ #include <libbutl/path-pattern.mxx> +#include <libbuild2/target.hxx> #include <libbuild2/diagnostics.hxx> using namespace std; @@ -1791,13 +1792,57 @@ namespace build2 // variable_type_map // lookup variable_type_map:: - find (const target_type& type, - const string& name, - const variable& var) const + find (const target_key& tk, + const variable& var, + optional<string>& oname) const { + // Compute and cache "effective" name that we will be matching. + // + auto name = [&tk, &oname] () -> const string& + { + if (!oname) + { + const target_type& tt (*tk.type); + + // Note that if the name is not empty, then we always use that, even + // if the type is dir/fsdir. + // + if (tk.name->empty () && (tt.is_a<dir> () || tt.is_a<fsdir> ())) + { + oname = tk.dir->leaf ().string (); + } + // If we have the extension and the type expects the extension to be + // always specified explicitly by the user, then add it to the name. + // + // Overall, we have the following cases: + // + // 1. Extension is fixed: man1{}. + // + // 2. Extension is always specified by the user: file{}. + // + // 3. Default extension that may be overridden by the user: hxx{}. + // + // 4. Extension assigned by the rule but may be overridden by the + // user: obje{}. + // + // By default we only match the extension for (2). + // + else if (tk.ext && !tk.ext->empty () && + (tt.fixed_extension == &target_extension_none || + tt.fixed_extension == &target_extension_must)) + { + oname = *tk.name + '.' + *tk.ext; + } + else + oname = string (); // Use tk.name as is. + } + + return oname->empty () ? *tk.name : *oname; + }; + // Search across target type hierarchy. // - for (auto tt (&type); tt != nullptr; tt = tt->base) + for (auto tt (tk.type); tt != nullptr; tt = tt->base) { auto i (map_.find (*tt)); @@ -1820,7 +1865,7 @@ namespace build2 // if (pat != "*") { - if (!butl::path_match (name, pat)) + if (!butl::path_match (name (), pat)) continue; } @@ -1840,6 +1885,12 @@ namespace build2 if (v->extra == 0 && var.type != nullptr) vm.typify (*v, var); + // Make sure the effective name is computed if this is + // append/prepend (it is used as a cache key). + // + if (v->extra != 0) + name (); + return lookup (*v, p.second, vm); } } |