aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/test
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-09-29 09:46:58 +0200
committerKaren Arutyunov <karen@codesynthesis.com>2022-09-29 13:45:03 +0300
commitd7cb460833e6dde3e3b958b993eee3eee4ae3bf0 (patch)
treed96f782c0c3e79b4ce21a510498517c4b1386b35 /libbuild2/test
parente086480b76d995beb23b9b91bda335702f7f0d2a (diff)
Fix variable append logic in script
Diffstat (limited to 'libbuild2/test')
-rw-r--r--libbuild2/test/script/parser+for.test.testscript4
-rw-r--r--libbuild2/test/script/parser.cxx46
2 files changed, 36 insertions, 14 deletions
diff --git a/libbuild2/test/script/parser+for.test.testscript b/libbuild2/test/script/parser+for.test.testscript
index 92fc714..70c1c89 100644
--- a/libbuild2/test/script/parser+for.test.testscript
+++ b/libbuild2/test/script/parser+for.test.testscript
@@ -87,9 +87,7 @@
cmd $x
end
EOI
- error: type mismatch in variable x
- info: value type is dir_path
- info: variable type is string
+ testscript:1:1: error: conflicting variable x type string and value type dir_path
EOE
: scope-var
diff --git a/libbuild2/test/script/parser.cxx b/libbuild2/test/script/parser.cxx
index 0ba5a79..f302aee 100644
--- a/libbuild2/test/script/parser.cxx
+++ b/libbuild2/test/script/parser.cxx
@@ -1549,19 +1549,27 @@ namespace build2
// Note that we rely on "small function object" optimization for the
// exec_*() lambdas.
//
- auto exec_assign = [this] (const variable& var,
- value&& val,
- type kind,
- const location& l)
+ auto exec_set = [this] (const variable& var,
+ token& t, build2::script::token_type& tt,
+ const location&)
{
+ next (t, tt);
+ type kind (tt); // Assignment kind.
+
+ // We cannot reuse the value mode (see above for details).
+ //
+ mode (lexer_mode::variable_line);
+ value rhs (parse_variable_line (t, tt));
+
+ assert (tt == type::newline);
+
+ // Assign.
+ //
value& lhs (kind == type::assign
? scope_->assign (var)
: scope_->append (var));
- if (kind == type::assign)
- lhs = move (val);
- else
- append_value (&var, lhs, move (val), l);
+ apply_value_attributes (&var, lhs, move (rhs), kind);
if (script_->test_command_var (var.name))
scope_->reset_special ();
@@ -1601,6 +1609,22 @@ namespace build2
return runner_->run_cond (*scope_, ce, ii, li, ll);
};
+ auto exec_for = [this] (const variable& var,
+ value&& val,
+ const location& l)
+ {
+ value& lhs (scope_->assign (var));
+
+ // To match the function semantics also pass the value's type
+ // attribute, restoring it from RHS. Note that the value can't be
+ // NULL.
+ //
+ apply_value (&var, lhs, move (val), type::assign, l, val.type);
+
+ if (script_->test_command_var (var.name))
+ scope_->reset_special ();
+ };
+
size_t li (1);
if (test* t = dynamic_cast<test*> (scope_))
@@ -1608,7 +1632,7 @@ namespace build2
ct = command_type::test;
exec_lines (t->tests_.begin (), t->tests_.end (),
- exec_assign, exec_cmd, exec_cond,
+ exec_set, exec_cmd, exec_cond, exec_for,
nullptr /* iteration_index */, li);
}
else if (group* g = dynamic_cast<group*> (scope_))
@@ -1617,7 +1641,7 @@ namespace build2
bool exec_scope (
exec_lines (g->setup_.begin (), g->setup_.end (),
- exec_assign, exec_cmd, exec_cond,
+ exec_set, exec_cmd, exec_cond, exec_for,
nullptr /* iteration_index */, li));
if (exec_scope)
@@ -1788,7 +1812,7 @@ namespace build2
ct = command_type::teardown;
exec_lines (g->tdown_.begin (), g->tdown_.end (),
- exec_assign, exec_cmd, exec_cond,
+ exec_set, exec_cmd, exec_cond, exec_for,
nullptr /* iteration_index */, li);
}
else