aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/config
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-03-19 09:27:22 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-03-19 09:27:22 +0200
commitcbcb0b03501ce346ca3778624dcf908e851e6e2e (patch)
treeec7cf219ea6772ed5ea03de35eefd5e781d7906a /libbuild2/config
parent14b34a239fa23e1a28519ab87f450c0a440d4f85 (diff)
Tweak lookup_config() semantics some more
Diffstat (limited to 'libbuild2/config')
-rw-r--r--libbuild2/config/utility.cxx28
-rw-r--r--libbuild2/config/utility.hxx14
2 files changed, 36 insertions, 6 deletions
diff --git a/libbuild2/config/utility.cxx b/libbuild2/config/utility.cxx
index cf0f73b..b3f94be 100644
--- a/libbuild2/config/utility.cxx
+++ b/libbuild2/config/utility.cxx
@@ -33,9 +33,31 @@ namespace build2
if (var.overrides != nullptr)
{
- pair<lookup, size_t> ovr (rs.lookup_override (var, move (org)));
-
- if (l != ovr.first) // Overriden?
+ // This is tricky: if we didn't find the original, pretend we have set
+ // the default value for the purpose of override lookup in order to
+ // have consistent semantics with the default value case (see notes in
+ // that implementation for background).
+ //
+ // In particular, this makes sure we can first do the lookup without
+ // the default value and then, if there is no value, call the version
+ // with the default value and end up with the same result if we called
+ // the default value version straight away.
+ //
+ // Note that we need to detect both when the default value is not
+ // overridden as well as when the override is based on it (e.g., via
+ // append; think config.cxx+=-m32).
+ //
+ // @@ Maybe a callback that computes the default value on demand is a
+ // better way?
+ //
+ variable_map::value_data v; // NULL value, but must be with version.
+ if (!l.defined ())
+ org = make_pair (lookup (v, var, rs), 1); // As default value case.
+
+ scope::override_info li (rs.lookup_override_info (var, move (org)));
+ pair<lookup, size_t>& ovr (li.lookup);
+
+ if (l.defined () ? l != ovr.first : !li.original) // Overriden?
{
// Override is always treated as new.
//
diff --git a/libbuild2/config/utility.hxx b/libbuild2/config/utility.hxx
index bf4728f..cbfe588 100644
--- a/libbuild2/config/utility.hxx
+++ b/libbuild2/config/utility.hxx
@@ -91,10 +91,16 @@ namespace build2
//
// Unlike the rest of the lookup_config() versions, this one leaves the
// unspecified value as undefined rather than setting it to a default
- // value. This can be useful when we don't have a default value or if we
- // want the mentioning of the variable to be omitted from persistent
+ // value. This can be useful when we don't have a default value or in case
+ // we want the mentioning of the variable to be omitted from persistent
// storage (e.g., a config file) if the default value is used.
//
+ // Note also that we can first do the lookup without the default value and
+ // then, if there is no value, call the version with the default value and
+ // end up with the same result if we called the default value version
+ // straight away. This is useful when computing the default value is
+ // expensive.
+ //
// @@ Should we pass flags and interpret save_null_omitted to treat null
// as undefined? Sounds logical.
//
@@ -135,7 +141,9 @@ namespace build2
// The second version in addition sets the new_value argument as described
// above. Note, however, that if the save_default_commented flag is
// specified, then the default value is never considered "new" since for
- // such variables absence of a value means it is the default value.
+ // such variables absence of a value means it is the default value. This
+ // flag is normally used for dynamically adjusting (e.g., hinted) default
+ // values.
//
// If override is true and the variable doesn't come from this root scope
// or from the command line (i.e., it is inherited from the amalgamation),