aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/test/script/lexer.cxx7
-rw-r--r--build2/test/script/parser.cxx56
-rw-r--r--build2/test/script/token2
-rw-r--r--build2/test/script/token.cxx2
-rw-r--r--unit-tests/test/script/lexer/first-token.test5
-rw-r--r--unit-tests/test/script/parser/buildfile6
-rw-r--r--unit-tests/test/script/parser/directive.test70
-rw-r--r--unit-tests/test/script/parser/include.test50
8 files changed, 119 insertions, 79 deletions
diff --git a/build2/test/script/lexer.cxx b/build2/test/script/lexer.cxx
index ce6ed5d..bcd5885 100644
--- a/build2/test/script/lexer.cxx
+++ b/build2/test/script/lexer.cxx
@@ -41,10 +41,10 @@ namespace build2
case lexer_mode::first_token:
{
// First token on the script line. Like command_line but
- // recognizes leading '+-{}' as tokens as well as variable
+ // recognizes leading '.+-{}' as tokens as well as variable
// assignments as separators.
//
- // Note that to recognize only leading '+-{}' we shouldn't add
+ // Note that to recognize only leading '.+-{}' we shouldn't add
// them to the separator strings.
//
s1 = ":;=+!|&<> $(#\t\n";
@@ -431,12 +431,13 @@ namespace build2
}
}
- // Plus/minus and left/right curly braces.
+ // Dot, plus/minus, and left/right curly braces.
//
if (m == lexer_mode::first_token)
{
switch (c)
{
+ case '.': return make_token (type::dot);
case '+': return make_token (type::plus);
case '-': return make_token (type::minus);
case '{': return make_token (type::lcbrace);
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx
index 99e4a66..dd5c5c7 100644
--- a/build2/test/script/parser.cxx
+++ b/build2/test/script/parser.cxx
@@ -174,7 +174,7 @@ namespace build2
//
for (;;)
{
- // Start lexing each line recognizing leading ':+-{}'.
+ // Start lexing each line recognizing leading '.+-{}'.
//
tt = peek (lexer_mode::first_token);
@@ -304,6 +304,31 @@ namespace build2
switch (tt)
{
+ case type::dot:
+ {
+ // Directive.
+ //
+ next (t, tt); // Skip dot.
+ next (t, tt); // Get the directive name.
+
+ if (tt != type::word || t.qtype != quote_type::unquoted)
+ fail (t) << "expected directive name instead of " << t;
+
+ // Make sure we are not inside a test (i.e., after semi).
+ //
+ if (ls != nullptr)
+ fail (ll) << "directive after ';'";
+
+ const string& n (t.value);
+
+ if (n == "include")
+ pre_parse_directive (t, tt);
+ else
+ fail (t) << "unknown directive '" << n << "'";
+
+ assert (tt == type::newline);
+ return false;
+ }
case type::plus:
case type::minus:
{
@@ -331,23 +356,19 @@ namespace build2
}
default:
{
- // Either directive, variable assignment, or test command.
+ // Either variable assignment or test command.
//
replay_save (); // Start saving tokens from the current one.
next (t, tt);
- // Decide whether this is a variable assignment, directive or a
- // command.
- //
- // It is a directive if the first token is an unquoted directive
- // name.
+ // Decide whether this is a variable assignment or a command.
//
// It is an assignment if the first token is an unquoted name and
// the next token is an assign/append/prepend operator. Assignment
// to a computed variable name must use the set builtin.
//
- // Note also that directives/special commands take precedence over
- // variable assignments.
+ // Note also thatspecial commands take precedence over variable
+ // assignments.
//
lt = line_type::cmd; // Default.
@@ -355,20 +376,7 @@ namespace build2
{
const string& n (t.value);
- if (n == ".include")
- {
- replay_stop (); // Stop replay and discard the data.
-
- // Make sure we are not inside a test (i.e., after semi).
- //
- if (ls != nullptr)
- fail (ll) << "directive after ';'";
-
- pre_parse_directive (t, tt);
- assert (tt == type::newline);
- return false;
- }
- else if (n == "if") lt = line_type::cmd_if;
+ if (n == "if") lt = line_type::cmd_if;
else if (n == "if!") lt = line_type::cmd_ifn;
else if (n == "elif") lt = line_type::cmd_elif;
else if (n == "elif!") lt = line_type::cmd_elifn;
@@ -941,7 +949,7 @@ namespace build2
if (tt != type::newline)
fail (t) << t << " after directive";
- if (d == ".include")
+ if (d == "include")
pre_parse_include_line (move (args), move (l));
else
assert (false); // Unhandled directive.
diff --git a/build2/test/script/token b/build2/test/script/token
index 117ccaa..2950353 100644
--- a/build2/test/script/token
+++ b/build2/test/script/token
@@ -26,6 +26,8 @@ namespace build2
semi = base_type::value_next, // ;
+ dot, // .
+
plus, // +
minus, // -
diff --git a/build2/test/script/token.cxx b/build2/test/script/token.cxx
index 5552994..9e1833c 100644
--- a/build2/test/script/token.cxx
+++ b/build2/test/script/token.cxx
@@ -25,6 +25,8 @@ namespace build2
{
case token_type::semi: os << q << ';' << q; break;
+ case token_type::dot: os << q << '.' << q; break;
+
case token_type::plus: os << q << '+' << q; break;
case token_type::minus: os << q << '-' << q; break;
diff --git a/unit-tests/test/script/lexer/first-token.test b/unit-tests/test/script/lexer/first-token.test
index d42e0b2..8a6d39b 100644
--- a/unit-tests/test/script/lexer/first-token.test
+++ b/unit-tests/test/script/lexer/first-token.test
@@ -2,6 +2,11 @@
#
test.arguments = first-token
+$* <"." >>EOO # dot
+.
+<newline>
+EOO
+
$* <";" >>EOO # semi
;
<newline>
diff --git a/unit-tests/test/script/parser/buildfile b/unit-tests/test/script/parser/buildfile
index db75a4f..41fe34d 100644
--- a/unit-tests/test/script/parser/buildfile
+++ b/unit-tests/test/script/parser/buildfile
@@ -15,8 +15,8 @@ test/{target script/{token lexer parser regex script}} \
scheduler
exe{driver}: cxx{driver} ../../../../build2/cxx{$src} $libs \
-test{cleanup command-if command-re-parse description exit expansion \
- here-document here-string include pipe-expr pre-parse redirect \
- scope scope-if setup-teardown}
+test{cleanup command-if command-re-parse description directive exit \
+ expansion here-document here-string include pipe-expr pre-parse \
+ redirect scope scope-if setup-teardown}
include ../../../../build2/
diff --git a/unit-tests/test/script/parser/directive.test b/unit-tests/test/script/parser/directive.test
new file mode 100644
index 0000000..07cb65c
--- /dev/null
+++ b/unit-tests/test/script/parser/directive.test
@@ -0,0 +1,70 @@
+: not-directive
+:
+$* <<EOI >>EOO
+x = x
+".include" foo.test
+\.include foo.test
+EOI
+.include foo.test
+.include foo.test
+EOO
+
+: expected-name
+:
+$* <<EOI 2>>EOE != 0
+.$
+EOI
+testscript:1:2: error: expected directive name instead of '$'
+EOE
+
+: unknown-name
+:
+$* <<EOI 2>>EOE != 0
+.bogus
+EOI
+testscript:1:2: error: unknown directive 'bogus'
+EOE
+
+: separated
+:
+touch foo.test;
+$* <<EOI
+. include foo.test
+EOI
+
+: not-separated
+:
+touch foo.test;
+$* <<EOI
+x = foo.test
+.include$x
+EOI
+
+: var-expansion
+:
+cat <<EOI >>>"foo-$(build.version).test";
+cmd
+EOI
+$* <<EOI >>EOO
+.include "foo-$(build.version).test"
+EOI
+cmd
+EOO
+
+: after-semi
+:
+$* <<EOI 2>>EOE != 0
+cmd;
+.include foo.test
+EOI
+testscript:2:1: error: directive after ';'
+EOE
+
+: semi-after
+:
+$* <<EOI 2>>EOE != 0
+.include foo.test;
+cmd
+EOI
+testscript:1:18: error: ';' after directive
+EOE
diff --git a/unit-tests/test/script/parser/include.test b/unit-tests/test/script/parser/include.test
index 1639d37..7910919 100644
--- a/unit-tests/test/script/parser/include.test
+++ b/unit-tests/test/script/parser/include.test
@@ -1,22 +1,3 @@
-: not-directive
-:
-$* <<EOI >>EOO
-x = x
-".include" foo.test
-.include'' foo.test
-EOI
-.include foo.test
-.include foo.test
-EOO
-
-: not-separated
-:
-touch foo.test;
-$* <<EOI
-x = foo.test
-.include$x
-EOI
-
: none
:
$* <<EOI
@@ -102,41 +83,12 @@ EOI
}
EOO
-: var-expansion
-:
-cat <<EOI >>>"foo-$(build.version).test";
-cmd
-EOI
-$* <<EOI >>EOO
-.include "foo-$(build.version).test"
-EOI
-cmd
-EOO
-
-: after-semi
-:
-$* <<EOI 2>>EOE != 0
-cmd;
-.include foo.test
-EOI
-testscript:2:1: error: directive after ';'
-EOE
-
-: semi-after
-:
-$* <<EOI 2>>EOE != 0
-.include foo.test;
-cmd
-EOI
-testscript:1:18: error: ';' after directive
-EOE
-
: invalid-path
:
$* <<EOI 2>>EOE != 0
.include ""
EOI
-testscript:1:1: error: invalid testscript include path ''
+testscript:1:2: error: invalid testscript include path ''
EOE
: unable-open