aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/config/functions.cxx38
-rw-r--r--libbuild2/config/utility.cxx33
-rw-r--r--libbuild2/config/utility.hxx16
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<string> (move (name)));
+ switch (origin (*s, convert<string> (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<lookup, size_t> org (s->lookup_original (*var));
- pair<lookup, size_t> 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<variable_origin, lookup>
+ 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<lookup, size_t> org (rs.lookup_original (*var));
+ 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
+ ? 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<variable_origin, lookup>
+ origin (const scope& rs, const string& name);
}
}