aboutsummaryrefslogtreecommitdiff
path: root/build2/variable.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-07-16 10:51:35 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-07-16 10:51:35 +0200
commitb439803cc5e09188c7b523333f6b71de3ba57dbf (patch)
tree0ed119a6910c441124b8c053d0df48c8f1127fad /build2/variable.cxx
parent5fac16471ba789965a72ffbbea406b75d8a680dc (diff)
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 }
Diffstat (limited to 'build2/variable.cxx')
-rw-r--r--build2/variable.cxx29
1 files changed, 18 insertions, 11 deletions
diff --git a/build2/variable.cxx b/build2/variable.cxx
index 67efc95..58076d4 100644
--- a/build2/variable.cxx
+++ b/build2/variable.cxx
@@ -680,42 +680,42 @@ namespace build2
// variable_map
//
const value* variable_map::
- find (const variable& var) const
+ find (const variable& var, bool typed) const
{
auto i (m_.find (var));
const value* r (i != m_.end () ? &i->second : nullptr);
// First access after being assigned a type?
//
- if (r != nullptr && var.type != nullptr && r->type != var.type)
+ if (r != nullptr && typed && var.type != nullptr && r->type != var.type)
typify (const_cast<value&> (*r), *var.type, &var);
return r;
}
value* variable_map::
- find (const variable& var)
+ find (const variable& var, bool typed)
{
auto i (m_.find (var));
value* r (i != m_.end () ? &i->second : nullptr);
// First access after being assigned a type?
//
- if (r != nullptr && var.type != nullptr && r->type != var.type)
+ if (r != nullptr && typed && var.type != nullptr && r->type != var.type)
typify (*r, *var.type, &var);
return r;
}
pair<reference_wrapper<value>, bool> variable_map::
- insert (const variable& var)
+ insert (const variable& var, bool typed)
{
- auto r (m_.emplace (var, value (var.type)));
+ auto r (m_.emplace (var, value (typed ? var.type : nullptr)));
value& v (r.first->second);
// First access after being assigned a type?
//
- if (!r.second && var.type != nullptr && v.type != var.type)
+ if (typed && !r.second && var.type != nullptr && v.type != var.type)
typify (v, *var.type, &var);
return make_pair (reference_wrapper<value> (v), r.second);
@@ -772,13 +772,20 @@ namespace build2
name.compare (nn - pn, pn, p, w, pn) != 0)
continue;
+ //@@ TODO: should we detect ambiguity? 'foo-*' '*-foo' and 'foo-foo'?
+ // Right now the last defined will be used.
+
// Ok, this pattern matches. But is there a variable?
//
- if (const value* v = j->second.find (var))
+ // Since we store append/prepend values untyped, instruct find() not
+ // to automatically type it. And if it is assignment, then typify it
+ // ourselves.
+ //
+ if (const value* v = j->second.find (var, false))
{
- //@@ TODO: should we detect ambiguity? 'foo-*' '*-foo' and
- // 'foo-foo'? Right now the last defined will be used.
- //
+ if (v->extra == 0 && var.type != nullptr && v->type != var.type)
+ typify (const_cast<value&> (*v), *var.type, &var);
+
return lookup (v, &j->second);
}
}