From f7bba792a10864f0a64a2a579306e3b20602c1dc Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 29 Mar 2016 17:14:01 +0200 Subject: Reset build state for each meta-operation --- build2/context.cxx | 68 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 14 deletions(-) (limited to 'build2/context.cxx') 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 +#include + #include #include @@ -12,6 +14,12 @@ #include #include +// For command line variable parsing. +// +#include +#include +#include + 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 . + extension_pool.clear (); + project_name_pool.clear (); + + // Reset meta/operation tables. Note that the order should match the id + // constants in . // 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 + // 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 ("")); + + // 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 ("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 - // for details. - // - global_scope = scopes.insert ( - dir_path ("/"), nullptr, true, false)->second; - - scope& gs (*global_scope); - gs.assign ("build.work") = work; gs.assign ("build.home") = home; -- cgit v1.1