aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-06-03 12:23:34 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-06-03 12:23:34 +0200
commitef130e855b5ac0f4acbb8b5b6fcd14069df8afe5 (patch)
tree6bdbe9f549ccc6358ae214b6b24e1af243d019cf
parent88b0aed33748ba4a3b3635063999cbf98a434672 (diff)
Reset value::extra on variable_map value change/version increment
The reset on each modification semantics is used to implement the default value distinction as currently done in the config module but later probably will be done for ?= and $origin().
-rw-r--r--libbuild2/config/utility.txx2
-rw-r--r--libbuild2/parser.cxx2
-rw-r--r--libbuild2/variable.cxx8
-rw-r--r--libbuild2/variable.hxx19
-rw-r--r--libbuild2/variable.txx1
5 files changed, 25 insertions, 7 deletions
diff --git a/libbuild2/config/utility.txx b/libbuild2/config/utility.txx
index b88f76c..0362d6a 100644
--- a/libbuild2/config/utility.txx
+++ b/libbuild2/config/utility.txx
@@ -58,7 +58,7 @@ namespace build2
if (!l.defined () || (def_ovr && !l.belongs (rs)))
{
value& v (rs.assign (var) = std::forward<T> (def_val)); // VC14
- v.extra = true; // Default value flag.
+ v.extra = 1; // Default value flag.
n = (sflags & save_default_commented) == 0; // Absence means default.
l = lookup (v, var, rs);
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx
index 19c1751..cc3fba7 100644
--- a/libbuild2/parser.cxx
+++ b/libbuild2/parser.cxx
@@ -4532,7 +4532,7 @@ namespace build2
// Note that the pattern is preserved if insert fails with regex_error.
//
p = scope_->target_vars[ptt].insert (pt, move (pat)).insert (
- var, kind == type::assign);
+ var, kind == type::assign, false /* reset_extra */);
}
catch (const regex_error& e)
{
diff --git a/libbuild2/variable.cxx b/libbuild2/variable.cxx
index 0f2a3de..74fad14 100644
--- a/libbuild2/variable.cxx
+++ b/libbuild2/variable.cxx
@@ -1761,13 +1761,16 @@ namespace build2
auto* r (const_cast<value_data*> (p.first));
if (r != nullptr)
+ {
+ r->extra = 0;
r->version++;
+ }
return pair<value_data*, const variable&> (r, p.second);
}
pair<value&, bool> variable_map::
- insert (const variable& var, bool typed)
+ insert (const variable& var, bool typed, bool reset_extra)
{
assert (!global_ || ctx->phase == run_phase::load);
@@ -1776,6 +1779,9 @@ namespace build2
if (!p.second)
{
+ if (reset_extra)
+ r.extra = 0;
+
// Check if this is the first access after being assigned a type.
//
// Note: we still need atomic in case this is not a global state.
diff --git a/libbuild2/variable.hxx b/libbuild2/variable.hxx
index d00243e..9c1e02c 100644
--- a/libbuild2/variable.hxx
+++ b/libbuild2/variable.hxx
@@ -276,7 +276,13 @@ namespace build2
// Extra data that is associated with the value that can be used to store
// flags, etc. It is initialized to 0 and copied (but not assigned) from
// one value to another but is otherwise untouched (not even when the
- // value is reset to NULL).
+ // value is reset to NULL) unless it is part of variable_map::value_data,
+ // in which case it is reset to 0 on each modification (version
+ // increment; however, see reset_extra flag in variable_map::insert()).
+ //
+ // (The reset on each modification semantics is used to implement the
+ // default value distinction as currently done in the config module but
+ // later probably will be done for ?= and $origin()).
//
// Note: if deciding to use for something make sure it is not overlapping
// with an existing usage.
@@ -1506,7 +1512,10 @@ namespace build2
using value::value;
using value::operator=;
- size_t version = 0; // Incremented on each modification (variable_cache).
+ // Incremented on each modification, at which point we also reset
+ // value::extra to 0.
+ //
+ size_t version = 0;
};
// Note that we guarantee ascending iteration order (e.g., for predictable
@@ -1606,6 +1615,7 @@ namespace build2
{
assert (l.vars == this);
value& r (const_cast<value&> (*l.value));
+ r.extra = 0;
static_cast<value_data&> (r).version++;
return r;
}
@@ -1629,10 +1639,11 @@ namespace build2
// As above but also return an indication of whether the new value (which
// will be NULL) was actually inserted. Similar to find(), if typed is
- // false, leave the value untyped even if the variable is.
+ // false, leave the value untyped even if the variable is. If reset_extra
+ // is false, then don't reset the existing value's value::extra.
//
pair<value&, bool>
- insert (const variable&, bool typed = true);
+ insert (const variable&, bool typed = true, bool reset_extra = true);
// Note: does not deal with aliases.
//
diff --git a/libbuild2/variable.txx b/libbuild2/variable.txx
index b1c4112..d75befb 100644
--- a/libbuild2/variable.txx
+++ b/libbuild2/variable.txx
@@ -1070,6 +1070,7 @@ namespace build2
e.stem_version = sver;
+ e.value.extra = 0; // For consistency (we don't really use it).
e.value.version++; // Value changed.
}
else