aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/test/script/lexer2
-rw-r--r--build2/test/script/lexer.cxx5
-rw-r--r--build2/test/script/parser9
-rw-r--r--build2/test/script/parser.cxx23
-rw-r--r--unit-tests/test/script/lexer/script-line.test5
5 files changed, 35 insertions, 9 deletions
diff --git a/build2/test/script/lexer b/build2/test/script/lexer
index f3d8fa9..99f87c0 100644
--- a/build2/test/script/lexer
+++ b/build2/test/script/lexer
@@ -25,7 +25,7 @@ namespace build2
enum
{
script_line = base_type::value_next,
- variable_line,
+ variable_line, // Auto-expires at the end of the line.
test_line,
command_line,
here_line
diff --git a/build2/test/script/lexer.cxx b/build2/test/script/lexer.cxx
index 3367d52..324e577 100644
--- a/build2/test/script/lexer.cxx
+++ b/build2/test/script/lexer.cxx
@@ -119,6 +119,11 @@ namespace build2
{
case '\n':
{
+ // Expire variable value mode at the end of the line.
+ //
+ if (m == lexer_mode::variable_line)
+ state_.pop ();
+
return make_token (type::newline);
}
diff --git a/build2/test/script/parser b/build2/test/script/parser
index 55dc003..ea0cadb 100644
--- a/build2/test/script/parser
+++ b/build2/test/script/parser
@@ -39,7 +39,8 @@ namespace build2
//
// Each parse function receives the token/type from which it should
// start consuming. On return the token/type should contain the first
- // token that has not been consumed.
+ // token that has not been consumed. For *_line() functions this is
+ // the newline.
//
protected:
void
@@ -60,6 +61,12 @@ namespace build2
string
parse_here_document (token&, token_type&, const string&);
+ // Customization hooks.
+ //
+ protected:
+ virtual lookup
+ lookup_variable (name&&, string&&, const location&) override;
+
protected:
using base_parser = build2::parser;
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx
index 827aae7..4948679 100644
--- a/build2/test/script/parser.cxx
+++ b/build2/test/script/parser.cxx
@@ -48,7 +48,7 @@ namespace build2
void parser::
parse_script (token& t, token_type& tt)
{
- while (tt != type::eos)
+ for (; tt != type::eos; next (t, tt))
{
parse_script_line (t, tt);
}
@@ -120,6 +120,9 @@ namespace build2
//
value rhs (variable_value (t, tt, lexer_mode::variable_line));
+ if (tt != type::newline)
+ fail (t) << "unexpected " << t;
+
value& lhs (kind == type::assign
? script_->assign (var)
: script_->append (var));
@@ -505,7 +508,7 @@ namespace build2
// Parse here-document fragments in the order they were mentioned on
// the command line.
//
- if (!hd.empty ())
+ for (redirect& r: hd)
{
// Switch to the here-line mode which is like double-quoted but
// recognized the newline as a separator.
@@ -515,13 +518,10 @@ namespace build2
// The end marker is temporarily stored as the redirect's value.
//
- for (redirect& r: hd)
- r.value = parse_here_document (t, tt, r.value);
+ r.value = parse_here_document (t, tt, r.value);
expire_mode ();
}
- else
- next (t, tt);
// Now that we have all the pieces, run the test.
//
@@ -600,9 +600,18 @@ namespace build2
if (tt == type::eos)
fail (t) << "missing here-document end marker '" << em << "'";
- next (t, tt);
return r;
}
+
+ lookup parser::
+ lookup_variable (name&& qual, string&& name, const location& l)
+ {
+ if (!qual.empty ())
+ fail (l) << "qualified variable name";
+
+ const variable& var (script_->var_pool.insert (move (name)));
+ return script_->find (var);
+ }
}
}
}
diff --git a/unit-tests/test/script/lexer/script-line.test b/unit-tests/test/script/lexer/script-line.test
index 3bd1f0e..79dd9a6 100644
--- a/unit-tests/test/script/lexer/script-line.test
+++ b/unit-tests/test/script/lexer/script-line.test
@@ -1,2 +1,7 @@
foo
bar
+$cxx.target.class
+foo = baz
+$foo
+fox = $foo-$cxx.target.class
+$fox