From b439803cc5e09188c7b523333f6b71de3ba57dbf Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 16 Jul 2016 10:51:35 +0200 Subject: Add support for prepend/append in target type/pattern-specific vars Semantically, these are similar to variable overrides and are essentially treated as "templates" that are applied on lookup to the "stem" value that is specific to the target type/name. For example: x = [string] a file{f*}: x =+ b sub/: { file{*}: x += c print $(file{foo}:x) # abc print $(file{bar}:x) # ac } --- build2/variable | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'build2/variable') diff --git a/build2/variable b/build2/variable index 5b9189c..cc99dc6 100644 --- a/build2/variable +++ b/build2/variable @@ -712,11 +712,13 @@ namespace build2 return operator[] (var_pool.find (name)); } + // If typed is false, leave the value untyped even if the variable is. + // const value* - find (const variable&) const; + find (const variable&, bool typed = true) const; value* - find (const variable&); + find (const variable&, bool typed = true); // Return a value suitable for assignment. See scope for details. // @@ -737,15 +739,16 @@ namespace build2 } // As above but also return an indication of whether the new value (which - // will be NULL) was actually inserted. + // will be NULL) was actually inserted. Similar to find(), if typed is + // false, leave the value untyped even if the variable is. // pair, bool> - insert (const variable&); + insert (const variable&, bool typed = true); pair, bool> - insert (const string& name) + insert (const string& name, bool typed = true) { - return insert (var_pool.find (name)); + return insert (var_pool.find (name), typed); } pair @@ -773,11 +776,6 @@ namespace build2 // Target type/pattern-specific variables. // - // @@ In quite a few places we assume that we can store a reference - // to the returned value (e.g., install::lookup_install()). If - // we "instantiate" the value on the fly, then we will need to - // consider its lifetime. - // using variable_pattern_map = std::map; using variable_type_map_base = std::map, variable_pattern_map>; @@ -786,6 +784,19 @@ namespace build2 { lookup find (const target_type&, const string& tname, const variable&) const; + + // In many places we assume that we can store a reference to the returned + // variable value (e.g., install::lookup_install()). As a result, in case + // of append/prepent where we calculate the value dynamically, we have to + // cache it. + // + // The key is the combination of the "original value idenity" (as a + // pointer to the value in variable_pattern_map) and the "target identity" + // (as target type and target name). The target name, unfortunately, has + // to be stored by value (maybe will pool them at some point). + // + mutable + std::map, value> cache; }; // Override cache. -- cgit v1.1