aboutsummaryrefslogtreecommitdiff
path: root/build2/module.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/module.cxx')
-rw-r--r--build2/module.cxx114
1 files changed, 114 insertions, 0 deletions
diff --git a/build2/module.cxx b/build2/module.cxx
new file mode 100644
index 0000000..288569f
--- /dev/null
+++ b/build2/module.cxx
@@ -0,0 +1,114 @@
+// file : build2/module.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <build2/module>
+
+#include <utility> // make_pair()
+
+#include <build2/scope>
+#include <build2/variable>
+#include <build2/diagnostics>
+
+using namespace std;
+
+namespace build2
+{
+ available_module_map builtin_modules;
+
+ void
+ boot_module (const string& name, scope& rs, const location& loc)
+ {
+ // First see if this modules has already been loaded for this project.
+ //
+ loaded_module_map& lm (rs.modules);
+ auto i (lm.find (name));
+
+ if (i != lm.end ())
+ {
+ module_state& s (i->second);
+
+ // The only valid situation here is if the module has already been
+ // bootstrapped.
+ //
+ assert (s.boot);
+ return;
+ }
+
+ // Otherwise search for this module.
+ //
+ auto j (builtin_modules.find (name));
+
+ if (j == builtin_modules.end ())
+ fail (loc) << "unknown module " << name;
+
+ const module_functions& mf (j->second);
+
+ if (mf.boot == nullptr)
+ fail (loc) << "module " << name << " shouldn't be loaded in bootstrap";
+
+ i = lm.emplace (name, module_state {true, mf.init, nullptr, loc}).first;
+ mf.boot (rs, loc, i->second.module);
+ }
+
+ bool
+ load_module (bool opt,
+ const string& name,
+ scope& rs,
+ scope& bs,
+ const location& loc)
+ {
+ // First see if this modules has already been loaded for this project.
+ //
+ loaded_module_map& lm (rs.modules);
+ auto i (lm.find (name));
+ bool f (i == lm.end ());
+
+ if (f)
+ {
+ // Otherwise search for this module.
+ //
+ auto j (builtin_modules.find (name));
+
+ if (j == builtin_modules.end ())
+ {
+ if (!opt)
+ fail (loc) << "unknown module " << name;
+ }
+ else
+ {
+ const module_functions& mf (j->second);
+
+ if (mf.boot != nullptr)
+ fail (loc) << "module " << name << " should be loaded in bootstrap";
+
+ i = lm.emplace (
+ name, module_state {false, mf.init, nullptr, loc}).first;
+ }
+ }
+ else
+ {
+ module_state& s (i->second);
+
+ if (s.boot)
+ {
+ s.boot = false;
+ f = true; // This is a first call to init.
+ }
+ }
+
+ bool l (i != lm.end ());
+ bool c (l && i->second.init (rs, bs, loc, i->second.module, f, opt));
+
+ const variable& lv (var_pool.find (name + ".loaded",
+ variable_visibility::project,
+ bool_type));
+ const variable& cv (var_pool.find (name + ".configured",
+ variable_visibility::project,
+ bool_type));
+ bs.assign (lv) = l;
+ bs.assign (cv) = c;
+
+ return l && c;
+ }
+}