aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-10-07 08:17:49 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-10-08 15:05:21 +0200
commit8384a087afc7e29e900a3ce96d55ab2f5c2a74c2 (patch)
treedeff3d99e33bfc7abecb3ef0422ccb2dd6c3d43b
parent734bf117f0eb596fc40579810613a6e13c43d3c4 (diff)
Expose custom save function in config module
It can generally be useful, for example, to complete relative paths before saving them to config.build (if abs_dir_path does not fit).
-rw-r--r--libbuild2/config/init.cxx5
-rw-r--r--libbuild2/config/module.cxx11
-rw-r--r--libbuild2/config/module.hxx23
-rw-r--r--libbuild2/config/operation.cxx2
-rw-r--r--libbuild2/config/utility.cxx16
-rw-r--r--libbuild2/config/utility.hxx58
-rw-r--r--libbuild2/config/utility.ixx17
7 files changed, 90 insertions, 42 deletions
diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx
index 2f134c4..b8ba31d 100644
--- a/libbuild2/config/init.cxx
+++ b/libbuild2/config/init.cxx
@@ -38,7 +38,10 @@ namespace build2
// the entire values.
//
static pair<names_view, const char*>
- save_environment (const value& d, const value* b, names& storage)
+ save_environment (const scope&,
+ const value& d,
+ const value* b,
+ names& storage)
{
if (b == nullptr)
return make_pair (reverse (d, storage, true /* reduce */), "=");
diff --git a/libbuild2/config/module.cxx b/libbuild2/config/module.cxx
index 713d30c..faae865 100644
--- a/libbuild2/config/module.cxx
+++ b/libbuild2/config/module.cxx
@@ -14,7 +14,7 @@ namespace build2
bool module::
save_variable (const variable& var,
optional<uint64_t> flags,
- save_variable_function* save)
+ save_variable_function* func)
{
const string& n (var.name);
@@ -45,15 +45,18 @@ namespace build2
return false;
}
- sv.push_back (saved_variable {var, flags, save});
+ sv.push_back (saved_variable {var, flags, func});
return true;
}
void module::
- save_variable (scope& rs, const variable& var, optional<uint64_t> flags)
+ save_variable (scope& rs,
+ const variable& var,
+ optional<uint64_t> flags,
+ save_variable_function* func)
{
if (module* m = rs.find_module<module> (module::name))
- m->save_variable (var, flags);
+ m->save_variable (var, flags, func);
}
void module::
diff --git a/libbuild2/config/module.hxx b/libbuild2/config/module.hxx
index 8d3ff67..77109ce 100644
--- a/libbuild2/config/module.hxx
+++ b/libbuild2/config/module.hxx
@@ -22,20 +22,12 @@ namespace build2
namespace config
{
// An ordered list of build system modules each with an ordered list of
- // config.* variables and their "save flags" (see save_variable()) that
- // are used (as opposed to just being specified) in this configuration.
- // Populated by the config utility functions (required(), optional()) and
- // saved in the order populated. If flags are absent, then this variable
- // was marked as "unsaved" (always transient).
+ // config.* variables and their save flags/function (see save_variable())
+ // that are used (as opposed to just being specified) in this
+ // configuration. Populated by the config utility functions (required(),
+ // optional()) and saved in the order populated. If flags are absent, then
+ // this variable was marked as "unsaved" (always transient).
//
- // The optional save function can be used to implement custom variable
- // saving, for example, as a difference appended to the base value. The
- // second half of the result is the assignment operator to use.
- //
- using save_variable_function =
- pair<names_view, const char*> (const value&,
- const value* base,
- names& storage);
struct saved_variable
{
reference_wrapper<const variable> var;
@@ -151,7 +143,10 @@ namespace build2
save_variable_function* = nullptr);
static void
- save_variable (scope&, const variable&, optional<uint64_t>);
+ save_variable (scope&,
+ const variable&,
+ optional<uint64_t>,
+ save_variable_function*);
bool
save_module (const char* name, int prio = 0);
diff --git a/libbuild2/config/operation.cxx b/libbuild2/config/operation.cxx
index b1716cf..6e7ef18 100644
--- a/libbuild2/config/operation.cxx
+++ b/libbuild2/config/operation.cxx
@@ -558,7 +558,7 @@ namespace build2
storage.clear ();
pair<names_view, const char*> p (
sv.save != nullptr
- ? sv.save (v, base, storage)
+ ? sv.save (rs, v, base, storage)
: make_pair (reverse (v, storage, true /* reduce */), "="));
// Might becomes empty after a custom save function had at it.
diff --git a/libbuild2/config/utility.cxx b/libbuild2/config/utility.cxx
index 6574367..aa0d5af 100644
--- a/libbuild2/config/utility.cxx
+++ b/libbuild2/config/utility.cxx
@@ -7,7 +7,14 @@ using namespace std;
namespace build2
{
- void (*config_save_variable) (scope&, const variable&, optional<uint64_t>);
+ void
+ (*config_save_variable) (scope&,
+ const variable&,
+ optional<uint64_t>,
+ pair<names_view, const char*> (*)(const scope&,
+ const value&,
+ const value*,
+ names&));
void (*config_save_environment) (scope&, const char*);
void (*config_save_module) (scope&, const char*, int);
const string& (*config_preprocess_create) (context&,
@@ -21,7 +28,10 @@ namespace build2
namespace config
{
pair<lookup, bool>
- lookup_config_impl (scope& rs, const variable& var, uint64_t sflags)
+ lookup_config_impl (scope& rs,
+ const variable& var,
+ uint64_t sflags,
+ save_variable_function* sfunc)
{
// This is a stripped-down version of the default value case.
@@ -71,7 +81,7 @@ namespace build2
}
if (l.defined ())
- save_variable (rs, var, sflags);
+ save_variable (rs, var, sflags, sfunc);
return pair<lookup, bool> (l, n);
}
diff --git a/libbuild2/config/utility.hxx b/libbuild2/config/utility.hxx
index 1e2ff53..3b67c6c 100644
--- a/libbuild2/config/utility.hxx
+++ b/libbuild2/config/utility.hxx
@@ -29,13 +29,22 @@ namespace build2
// disfigure hooks (for example, for second-level configuration). These are
// accessed through the config module entry points (which are NULL for
// transient configurations). Note also that the exact interpretation of the
- // save flags and module order depends on the config module implementation
- // (which may ignore them as not applicable). An implementation may also
- // define custom save flags (for example, accessible through the config.save
- // attribute). Such flags should start from 0x100000000.
+ // save flags/function and module order depends on the config module
+ // implementation (which may ignore them as not applicable). An
+ // implementation may also define custom save flags (for example, accessible
+ // through the config.save attribute). Such flags should start from
+ // 0x100000000.
+ //
+ // See below for the save function (last argument) semantics.
//
LIBBUILD2_SYMEXPORT extern void
- (*config_save_variable) (scope&, const variable&, optional<uint64_t>);
+ (*config_save_variable) (scope&,
+ const variable&,
+ optional<uint64_t>,
+ pair<names_view, const char*> (*)(const scope&,
+ const value&,
+ const value*,
+ names&));
LIBBUILD2_SYMEXPORT extern void
(*config_save_environment) (scope&, const char*);
@@ -75,11 +84,27 @@ namespace build2
const uint64_t save_false_omitted = 0x08; // Treat false as undefined.
const uint64_t save_base = 0x10; // Custom save with base.
+ // The optional save function can be used to implement custom variable
+ // saving, for example, as a difference appended to the base value or to
+ // complete relative paths (if abs_dir_path does not fit). The base
+ // argument is the value of this variable from the outer scope (if any)
+ // and is only calculated if the save_base flag is specified. The second
+ // half of the result is the assignment operator to use.
+ //
+ using save_variable_function =
+ pair<names_view, const char*> (const scope& rs,
+ const value&,
+ const value* base,
+ names& storage);
+
inline void
- save_variable (scope& rs, const variable& var, uint64_t flags = 0)
+ save_variable (scope& rs,
+ const variable& var,
+ uint64_t flags = 0,
+ save_variable_function* func = nullptr)
{
if (config_save_variable != nullptr)
- config_save_variable (rs, var, flags);
+ config_save_variable (rs, var, flags, func);
}
// Mark a variable as "unsaved" (always transient).
@@ -91,7 +116,7 @@ namespace build2
unsave_variable (scope& rs, const variable& var)
{
if (config_save_variable != nullptr)
- config_save_variable (rs, var, nullopt);
+ config_save_variable (rs, var, nullopt, nullptr);
}
// Mark an environment variable to be saved during hermetic configuration.
@@ -256,35 +281,40 @@ namespace build2
lookup
lookup_config (scope& rs,
const variable&,
- uint64_t save_flags = 0);
+ uint64_t save_flags = 0,
+ save_variable_function* = nullptr);
lookup
lookup_config (bool& new_value,
scope& rs,
const variable&,
- uint64_t save_flags = 0);
+ uint64_t save_flags = 0,
+ save_variable_function* = nullptr);
// Note that the variable is expected to have already been entered.
//
inline lookup
lookup_config (scope& rs,
const string& var,
- uint64_t save_flags = 0)
+ uint64_t save_flags = 0,
+ save_variable_function* func = nullptr)
{
// Note: go straight for the public variable pool.
//
- return lookup_config (rs, rs.ctx.var_pool[var], save_flags);
+ return lookup_config (rs, rs.ctx.var_pool[var], save_flags, func);
}
inline lookup
lookup_config (bool& new_value,
scope& rs,
const string& var,
- uint64_t save_flags = 0)
+ uint64_t save_flags = 0,
+ save_variable_function* func = nullptr)
{
// Note: go straight for the public variable pool.
//
- return lookup_config (new_value, rs, rs.ctx.var_pool[var], save_flags);
+ return lookup_config (
+ new_value, rs, rs.ctx.var_pool[var], save_flags, func);
}
// Lookup a config.* variable value and, if the value is undefined, set it
diff --git a/libbuild2/config/utility.ixx b/libbuild2/config/utility.ixx
index d8348bd..87f628c 100644
--- a/libbuild2/config/utility.ixx
+++ b/libbuild2/config/utility.ixx
@@ -6,25 +6,32 @@ namespace build2
namespace config
{
LIBBUILD2_SYMEXPORT pair<lookup, bool>
- lookup_config_impl (scope&, const variable&, uint64_t);
+ lookup_config_impl (scope&,
+ const variable&,
+ uint64_t,
+ save_variable_function*);
template <typename T>
pair<lookup, bool>
lookup_config_impl (scope&, const variable&, T&&, uint64_t, bool);
inline lookup
- lookup_config (scope& rs, const variable& var, uint64_t sflags)
+ lookup_config (scope& rs,
+ const variable& var,
+ uint64_t sflags,
+ save_variable_function* func)
{
- return lookup_config_impl (rs, var, sflags).first;
+ return lookup_config_impl (rs, var, sflags, func).first;
}
inline lookup
lookup_config (bool& new_value,
scope& rs,
const variable& var,
- uint64_t sflags)
+ uint64_t sflags,
+ save_variable_function* func)
{
- auto r (lookup_config_impl (rs, var, sflags));
+ auto r (lookup_config_impl (rs, var, sflags, func));
new_value = new_value || r.second;
return r.first;
}