From 026c827b978761bf0cb618ff9429df8508cd3190 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 19 May 2022 13:10:54 +0200 Subject: Make $config.origin() also available internally as config::origin() --- libbuild2/config/functions.cxx | 38 ++++++++++---------------------------- libbuild2/config/utility.cxx | 33 +++++++++++++++++++++++++++++++++ libbuild2/config/utility.hxx | 16 ++++++++++++++++ 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/libbuild2/config/functions.cxx b/libbuild2/config/functions.cxx index 3e1b8a3..84c1b03 100644 --- a/libbuild2/config/functions.cxx +++ b/libbuild2/config/functions.cxx @@ -23,8 +23,8 @@ namespace build2 // $config.origin() // - // Return the origin of the specified configuration variable value. - // Possible result values and their semantics are as follows: + // Return the origin of the value of the specified configuration + // variable. Possible result values and their semantics are as follows: // // undefined // The variable is undefined. @@ -60,33 +60,15 @@ namespace build2 if (s == nullptr) fail << "config.origin() called out of project" << endf; - string n (convert (move (name))); + switch (origin (*s, convert (move (name))).first) + { + case variable_origin::undefined: return "undefined"; + case variable_origin::default_: return "default"; + case variable_origin::buildfile: return "buildfile"; + case variable_origin::override_: return "override"; + } - // Make sure this is a config.* variable. This could matter since we - // reply 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 (n.compare (0, 7, "config.") != 0) - fail << "non-config.* variable passed to config.origin()" << endf; - - const variable* var (s->ctx.var_pool.find (n)); - - if (var == nullptr) - return "undefined"; - - pair org (s->lookup_original (*var)); - pair ovr (var->overrides == nullptr - ? org - : s->lookup_override (*var, org)); - - if (!ovr.first.defined ()) - return "undefined"; - - if (org.first != ovr.first) - return "override"; - - return org.first->extra ? "default" : "buildfile"; + return ""; // Should not reach. }; // $config.save() diff --git a/libbuild2/config/utility.cxx b/libbuild2/config/utility.cxx index a78b263..7437c5b 100644 --- a/libbuild2/config/utility.cxx +++ b/libbuild2/config/utility.cxx @@ -156,5 +156,38 @@ namespace build2 else return false; } + + pair + origin (const scope& rs, const string& n) + { + // Make sure this is a config.* variable. This could matter since we + // reply 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 (n.compare (0, 7, "config.") != 0) + throw invalid_argument ("config.* variable expected"); + + const variable* var (rs.ctx.var_pool.find (n)); + + if (var == nullptr) + return make_pair (variable_origin::undefined, lookup ()); + + pair org (rs.lookup_original (*var)); + pair 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 + ? variable_origin::default_ + : variable_origin::buildfile, + org.first); + } } } diff --git a/libbuild2/config/utility.hxx b/libbuild2/config/utility.hxx index cb82ea6..5a00d00 100644 --- a/libbuild2/config/utility.hxx +++ b/libbuild2/config/utility.hxx @@ -501,6 +501,22 @@ namespace build2 // LIBBUILD2_SYMEXPORT bool unconfigured (scope& rs, const string& var, bool value); + + // Return the origin of the value of the specified configuration variable + // plus the value itself. See $config.origin() for details. + // + // Throws invalid_argument if the passed variable is not config.*. + // + enum class variable_origin + { + undefined, // Undefined. + default_, // Default value from the config directive. + buildfile, // Value from a buildfile, normally config.build. + override_ // Value from a command line override. + }; + + LIBBUILD2_SYMEXPORT pair + origin (const scope& rs, const string& name); } } -- cgit v1.1