aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/config/module.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/config/module.hxx')
-rw-r--r--libbuild2/config/module.hxx98
1 files changed, 91 insertions, 7 deletions
diff --git a/libbuild2/config/module.hxx b/libbuild2/config/module.hxx
index 857a30c..8d3ff67 100644
--- a/libbuild2/config/module.hxx
+++ b/libbuild2/config/module.hxx
@@ -4,9 +4,9 @@
#ifndef LIBBUILD2_CONFIG_MODULE_HXX
#define LIBBUILD2_CONFIG_MODULE_HXX
-#include <map>
+#include <cstring> // strncmp()
-#include <libbutl/prefix-map.mxx>
+#include <libbutl/prefix-map.hxx>
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
@@ -28,10 +28,19 @@ namespace build2
// 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;
optional<uint64_t> flags;
+ save_variable_function* save;
};
struct saved_variables: vector<saved_variable>
@@ -43,7 +52,7 @@ namespace build2
const_iterator
find (const variable& var) const
{
- return std::find_if (
+ return find_if (
begin (),
end (),
[&var] (const saved_variable& v) {return var == v.var;});
@@ -55,7 +64,7 @@ namespace build2
// Priority order with INT32_MIN being the highest. Modules with the
// same priority are saved in the order inserted.
//
- std::multimap<std::int32_t, const_iterator> order;
+ multimap<std::int32_t, const_iterator> order;
pair<iterator, bool>
insert (string name, int prio = 0)
@@ -69,14 +78,77 @@ namespace build2
}
};
- struct module: build2::module
+ // List of environment variable names that effect this project.
+ //
+ // Note that on Windows environment variable names are case-insensitive.
+ //
+ struct saved_environment: vector<string>
+ {
+ // Compare environment variable names.
+ //
+ static inline bool
+ compare (const string& x,
+ const string& y,
+ size_t xn = string::npos,
+ size_t yn = string::npos)
+ {
+ if (xn == string::npos) xn = x.size ();
+ if (yn == string::npos) yn = y.size ();
+
+ return xn == yn &&
+#ifdef _WIN32
+ icasecmp (x.c_str (), y.c_str (), xn) == 0
+#else
+ strncmp (x.c_str (), y.c_str (), xn) == 0
+#endif
+ ;
+ }
+
+ iterator
+ find (const string& v)
+ {
+ return find_if (
+ begin (),
+ end (),
+ [&v] (const string& v1) {return compare (v, v1);});
+ }
+
+ const_iterator
+ find (const string& v) const
+ {
+ return find_if (
+ begin (),
+ end (),
+ [&v] (const string& v1) {return compare (v, v1);});
+ }
+
+ void
+ insert (string v)
+ {
+ if (find (v) == end ())
+ push_back (move (v));
+ }
+
+ void
+ erase (const string& v)
+ {
+ auto i (find (v));
+ if (i != end ())
+ vector<string>::erase (i);
+ }
+ };
+
+ class module: public build2::module
{
+ public:
config::saved_modules saved_modules;
// Return true if variable/module were newly inserted.
//
bool
- save_variable (const variable&, optional<uint64_t> flags);
+ save_variable (const variable&,
+ optional<uint64_t> flags,
+ save_variable_function* = nullptr);
static void
save_variable (scope&, const variable&, optional<uint64_t>);
@@ -88,7 +160,7 @@ namespace build2
save_module (scope&, const char*, int);
const saved_variable*
- find_variable (const variable& var)
+ find_variable (const variable& var) const
{
auto i (saved_modules.find_sup (var.name));
if (i != saved_modules.end ())
@@ -101,6 +173,18 @@ namespace build2
return nullptr;
}
+ void
+ save_environment (const char* var)
+ {
+ saved_environment.insert (var);
+ }
+
+ static void
+ save_environment (scope&, const char*);
+
+ config::saved_environment saved_environment;
+ strings old_environment;
+
// Configure/disfigure hooks.
//
static bool