aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-01-04 17:44:39 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-01-04 17:44:39 +0200
commita63e1809afd9a837821d6e8376cb14a36e7fc26e (patch)
tree92a79a14dbab94c7893dee8994d03ab645690852
parentaab54ca12373bc7df1323017e4fb0b9594dcb835 (diff)
Treat any testscript line that starts with dot as directive
Even though we currently only recognize the include directive, we reserve any line that begins with a dot for future.
-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