aboutsummaryrefslogtreecommitdiff
path: root/build2/test/script/parser.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-02-16 13:42:23 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-03-01 19:26:07 +0300
commita64b2ae2099346471ead988d5f2d383d55a9bf89 (patch)
tree04e1a43a484461ef88e6a804c1aa3751a58cdd95 /build2/test/script/parser.cxx
parent9b4e51f72d640262161e38981a8b9255a7b47f6c (diff)
Add set builtin
Diffstat (limited to 'build2/test/script/parser.cxx')
-rw-r--r--build2/test/script/parser.cxx54
1 files changed, 47 insertions, 7 deletions
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx
index 59580a3..2ea42b5 100644
--- a/build2/test/script/parser.cxx
+++ b/build2/test/script/parser.cxx
@@ -3034,7 +3034,8 @@ namespace build2
? scope_->assign (var)
: scope_->append (var));
- apply_value_attributes (&var, lhs, move (rhs), kind);
+ build2::parser::apply_value_attributes (
+ &var, lhs, move (rhs), kind);
// If we changes any of the test.* values, then reset the $*,
// $N special aliases.
@@ -3203,13 +3204,23 @@ namespace build2
// only look for buildfile variables.
//
// Otherwise, every variable that is ever set in a script has been
- // pre-entered during pre-parse. Which means that if one is not found
- // in the script pool then it can only possibly be set in the
- // buildfile.
+ // pre-entered during pre-parse or introduced with the set builtin
+ // during test execution. Which means that if one is not found in the
+ // script pool then it can only possibly be set in the buildfile.
//
- const variable* pvar (scope_ != nullptr
- ? script_->var_pool.find (name)
- : nullptr);
+ // Note that we need to acquire the variable pool lock. The pool can
+ // be changed from multiple threads by the set builtin. The obtained
+ // variable pointer can safelly be used with no locking as the variable
+ // pool is an associative container (underneath) and we are only adding
+ // new variables into it.
+ //
+ const variable* pvar (nullptr);
+
+ if (scope_ != nullptr)
+ {
+ slock sl (script_->var_pool_mutex);
+ pvar = script_->var_pool.find (name);
+ }
return pvar != nullptr
? scope_->find (*pvar)
@@ -3269,6 +3280,35 @@ namespace build2
base_parser::lexer_ = l;
}
+ void parser::
+ apply_value_attributes (const variable* var,
+ value& lhs,
+ value&& rhs,
+ const string& attributes,
+ token_type kind,
+ const path& name)
+ {
+ path_ = &name;
+
+ istringstream is (attributes);
+ lexer l (is, name, lexer_mode::attribute);
+ set_lexer (&l);
+
+ token t;
+ type tt;
+ next (t, tt);
+
+ if (tt != type::lsbrace && tt != type::eos)
+ fail (t) << "expected '[' instead of " << t;
+
+ attributes_push (t, tt, true);
+
+ if (tt != type::eos)
+ fail (t) << "trailing junk after ']'";
+
+ build2::parser::apply_value_attributes (var, lhs, move (rhs), kind);
+ }
+
// parser::parsed_doc
//
parser::parsed_doc::