diff options
Diffstat (limited to 'libbuild2/config/utility.cxx')
-rw-r--r-- | libbuild2/config/utility.cxx | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/libbuild2/config/utility.cxx b/libbuild2/config/utility.cxx index 75c9de9..6574367 100644 --- a/libbuild2/config/utility.cxx +++ b/libbuild2/config/utility.cxx @@ -8,6 +8,7 @@ using namespace std; namespace build2 { void (*config_save_variable) (scope&, const variable&, optional<uint64_t>); + void (*config_save_environment) (scope&, const char*); void (*config_save_module) (scope&, const char*, int); const string& (*config_preprocess_create) (context&, values&, @@ -20,7 +21,7 @@ namespace build2 namespace config { pair<lookup, bool> - lookup_config_impl (scope& rs, const variable& var) + lookup_config_impl (scope& rs, const variable& var, uint64_t sflags) { // This is a stripped-down version of the default value case. @@ -31,7 +32,7 @@ namespace build2 // Treat an inherited value that was set to default as new. // - if (l.defined () && l->extra) + if (l.defined () && l->extra == 1) n = true; if (var.overrides != nullptr) @@ -70,7 +71,7 @@ namespace build2 } if (l.defined ()) - save_variable (rs, var); + save_variable (rs, var, sflags); return pair<lookup, bool> (l, n); } @@ -80,7 +81,9 @@ namespace build2 const string& n, initializer_list<const char*> ig) { - auto& vp (rs.var_pool ()); + // Note: go straight for the public variable pool. + // + auto& vp (rs.ctx.var_pool); // Search all outer scopes for any value in this namespace. // @@ -90,7 +93,7 @@ namespace build2 // any original values, they will be "visible"; see find_override() for // details. // - const variable& ns (vp.insert ("config." + n)); + const string ns ("config." + n); for (scope* s (&rs); s != nullptr; s = s->parent_scope ()) { for (auto p (s->vars.lookup_namespace (ns)); @@ -106,13 +109,14 @@ namespace build2 auto match_tail = [&ns, v] (const char* t) { - return v->name.compare (ns.name.size () + 1, string::npos, t) == 0; + return v->name.compare (ns.size () + 1, string::npos, t) == 0; }; // Ignore config.*.configured and user-supplied names. // - if (!match_tail ("configured") && - find_if (ig.begin (), ig.end (), match_tail) == ig.end ()) + if (v->name.size () <= ns.size () || + (!match_tail ("configured") && + find_if (ig.begin (), ig.end (), match_tail) == ig.end ())) return true; } } @@ -126,7 +130,7 @@ namespace build2 // Pattern-typed as bool. // const variable& var ( - rs.var_pool ().insert ("config." + n + ".configured")); + rs.var_pool (true).insert ("config." + n + ".configured")); save_variable (rs, var); @@ -140,7 +144,7 @@ namespace build2 // Pattern-typed as bool. // const variable& var ( - rs.var_pool ().insert ("config." + n + ".configured")); + rs.var_pool (true).insert ("config." + n + ".configured")); save_variable (rs, var); @@ -154,5 +158,56 @@ namespace build2 else return false; } + + pair<variable_origin, lookup> + origin (const scope& rs, const string& n) + { + // Note: go straight for the public variable pool. + // + const variable* var (rs.ctx.var_pool.find (n)); + + if (var == nullptr) + { + if (n.compare (0, 7, "config.") != 0) + throw invalid_argument ("config.* variable expected"); + + return make_pair (variable_origin::undefined, lookup ()); + } + + return origin (rs, *var); + } + + pair<variable_origin, lookup> + origin (const scope& rs, const variable& var) + { + // Make sure this is a config.* variable. This could matter since we + // rely on the semantics of value::extra. We could also detect + // special variables like config.booted, some config.config.*, etc., + // (see config_save() for details) but that seems harmless. + // + if (var.name.compare (0, 7, "config.") != 0) + throw invalid_argument ("config.* variable expected"); + + return origin (rs, var, rs.lookup_original (var)); + } + + pair<variable_origin, lookup> + origin (const scope& rs, const variable& var, pair<lookup, size_t> org) + { + pair<lookup, size_t> ovr (var.overrides == nullptr + ? org + : rs.lookup_override (var, org)); + + if (!ovr.first.defined ()) + return make_pair (variable_origin::undefined, lookup ()); + + if (org.first != ovr.first) + return make_pair (variable_origin::override_, ovr.first); + + return make_pair (org.first->extra == 1 + ? variable_origin::default_ + : variable_origin::buildfile, + org.first); + } } } |