aboutsummaryrefslogtreecommitdiff
path: root/build2/context.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-03-29 17:14:01 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-03-29 17:14:01 +0200
commitf7bba792a10864f0a64a2a579306e3b20602c1dc (patch)
treeaf9e663a74500fc2784a210799e9deadf2f883eb /build2/context.cxx
parent96f2131e593e206f0e458409f22adfff8c1b5356 (diff)
Reset build state for each meta-operation
Diffstat (limited to 'build2/context.cxx')
-rw-r--r--build2/context.cxx68
1 files changed, 54 insertions, 14 deletions
diff --git a/build2/context.cxx b/build2/context.cxx
index 8941f3e..96532c4 100644
--- a/build2/context.cxx
+++ b/build2/context.cxx
@@ -4,6 +4,8 @@
#include <build2/context>
+#include <sstream>
+
#include <butl/triplet>
#include <build2/rule>
@@ -12,6 +14,12 @@
#include <build2/version>
#include <build2/diagnostics>
+// For command line variable parsing.
+//
+#include <build2/token>
+#include <build2/lexer>
+#include <build2/parser>
+
using namespace std;
using namespace butl;
@@ -31,19 +39,21 @@ namespace build2
uint64_t dependency_count;
void
- reset ()
+ reset (const strings& cmd_vars)
{
tracer trace ("reset");
- extension_pool.clear ();
- project_name_pool.clear ();
+ l6 ([&]{trace << "resetting build state";});
targets.clear ();
scopes.clear ();
var_pool.clear ();
- // Reset meta/operation tables. Note that the order should match
- // the id constants in <build2/operation>.
+ extension_pool.clear ();
+ project_name_pool.clear ();
+
+ // Reset meta/operation tables. Note that the order should match the id
+ // constants in <build2/operation>.
//
meta_operation_table.clear ();
meta_operation_table.insert ("perform");
@@ -58,6 +68,45 @@ namespace build2
operation_table.insert ("test");
operation_table.insert ("install");
+ // Create global scope. For Win32 this is not a "real" root path.
+ // On POSIX, however, this is a real path. See the comment in
+ // <build2/path-map> for details.
+ //
+ scope& gs (*scopes.insert (dir_path ("/"), nullptr, true, false)->second);
+ global_scope = &gs;
+
+ // Parse and enter the command line variables. We do it before entering
+ // any other variables so that all the variables that are overriden are
+ // marked as such first. Then, as we enter variables, we can verify that
+ // the override is alowed.
+ //
+ for (const string& v: cmd_vars)
+ {
+ istringstream is (v);
+ is.exceptions (istringstream::failbit | istringstream::badbit);
+ lexer l (is, path ("<cmdline>"));
+
+ // This should be a name followed by =, +=, or =+.
+ //
+ token t (l.next ());
+ token_type tt (l.next ().type);
+
+ if (t.type != token_type::name ||
+ (tt != token_type::assign &&
+ tt != token_type::prepend &&
+ tt != token_type::append))
+ {
+ fail << "expected variable assignment instead of '" << v << "'" <<
+ info << "use double '--' to treat this argument as buildspec";
+ }
+
+ parser p;
+ t = p.parse_variable (l, gs, t.value, tt);
+
+ if (t.type != token_type::eos)
+ fail << "unexpected " << t << " in variable assignment '" << v << "'";
+ }
+
// Enter builtin variables.
//
{
@@ -78,15 +127,6 @@ namespace build2
v.find<string> ("extension");
}
- // Create global scope. For Win32 this is not a "real" root path.
- // On POSIX, however, this is a real path. See the comment in
- // <build2/path-map> for details.
- //
- global_scope = scopes.insert (
- dir_path ("/"), nullptr, true, false)->second;
-
- scope& gs (*global_scope);
-
gs.assign<dir_path> ("build.work") = work;
gs.assign<dir_path> ("build.home") = home;