diff options
Diffstat (limited to 'libbuild2/config/module.hxx')
-rw-r--r-- | libbuild2/config/module.hxx | 98 |
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 |